Version 2.12.0-106.0.dev
Merge commit '1bfcc2d8da7a5a5f8f5a41dcb346ea1ddbd4191d' into 'dev'
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index f616daa..9ecfe27 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -11,14 +11,14 @@
"constraint, update this by running tools/generate_package_config.dart."
],
"configVersion": 2,
- "generated": "2020-11-15T14:18:10.587065",
+ "generated": "2020-11-30T16:23:50.740805",
"generator": "tools/generate_package_config.dart",
"packages": [
{
"name": "_fe_analyzer_shared",
"rootUri": "../pkg/_fe_analyzer_shared",
"packageUri": "lib/",
- "languageVersion": "2.2"
+ "languageVersion": "2.6"
},
{
"name": "_fe_analyzer_shared_assigned_variables",
@@ -101,7 +101,7 @@
"name": "args",
"rootUri": "../third_party/pkg/args",
"packageUri": "lib/",
- "languageVersion": "2.3"
+ "languageVersion": "2.12"
},
{
"name": "async",
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b7199e2..b0d0877 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -25,6 +25,11 @@
constructors, a name which can be associated with the port and displayed in
tooling.
+#### `dart:collection`
+
+* `LinkedList` made it explicit that elements are compared by identity,
+ and updated `contains` to take advantage of this.
+
### Dart VM
* **Breaking Change** [#42312][]: `Dart_WeakPersistentHandle`s will no longer
diff --git a/DEPS b/DEPS
index a5eac9a..7ca29d6 100644
--- a/DEPS
+++ b/DEPS
@@ -68,7 +68,7 @@
"gperftools_revision": "180bfa10d7cb38e8b3784d60943d50e8fcef0dcb",
# Revisions of /third_party/* dependencies.
- "args_tag": "1.6.0",
+ "args_rev": "139140125126661fac88c9aa5882165936d01c91",
"async_rev": "695b3ac280f107c84adf7488743abfdfaaeea68f",
"bazel_worker_rev": "060c55a933d39798681a4f533b161b81dc48d77e",
"benchmark_harness_rev": "ec6b646f5443faa871e126ac1ba248c94ca06257",
@@ -301,7 +301,7 @@
"@" + Var("gperftools_revision"),
Var("dart_root") + "/third_party/pkg/args":
- Var("dart_git") + "args.git" + "@" + Var("args_tag"),
+ Var("dart_git") + "args.git" + "@" + Var("args_rev"),
Var("dart_root") + "/third_party/pkg/async":
Var("dart_git") + "async.git" + "@" + Var("async_rev"),
Var("dart_root") + "/third_party/pkg/bazel_worker":
diff --git a/pkg/_fe_analyzer_shared/lib/src/base/errors.dart b/pkg/_fe_analyzer_shared/lib/src/base/errors.dart
index 322861f..2e138d8 100644
--- a/pkg/_fe_analyzer_shared/lib/src/base/errors.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/base/errors.dart
@@ -16,6 +16,11 @@
*/
final String name;
+ /**
+ * The unique name of this error code.
+ */
+ final String uniqueName;
+
final String _message;
final String _correction;
@@ -37,34 +42,34 @@
* template. The correction associated with the error will be created from the
* given [correction] template.
*/
- const ErrorCode(this.name, String message,
- [String correction, this.hasPublishedDocs = false])
- : isUnresolvedIdentifier = false,
- _message = message,
- _correction = correction;
-
- /**
- * Initialize a newly created error code to have the given [name]. The message
- * associated with the error will be created from the given [message]
- * template. The correction associated with the error will be created from the
- * given [correction] template.
- */
- const ErrorCode.temporary(this.name, String message,
- {String correction,
- this.isUnresolvedIdentifier = false,
- this.hasPublishedDocs = false})
- : _message = message,
- _correction = correction;
-
- const ErrorCode.temporary2({
+ const ErrorCode({
String correction,
this.hasPublishedDocs = false,
- this.isUnresolvedIdentifier = false,
+ this.isUnresolvedIdentifier: false,
@required String message,
@required this.name,
- @required String uniqueName,
+ @required this.uniqueName,
}) : _correction = correction,
- _message = message;
+ _message = message,
+ assert(hasPublishedDocs != null),
+ assert(isUnresolvedIdentifier != null);
+
+ @Deprecated('Use the default constructor')
+ const ErrorCode.temporary2({
+ String correction,
+ bool hasPublishedDocs = false,
+ bool isUnresolvedIdentifier = false,
+ @required String message,
+ @required String name,
+ @required String uniqueName,
+ }) : this(
+ correction: correction,
+ hasPublishedDocs: hasPublishedDocs,
+ isUnresolvedIdentifier: isUnresolvedIdentifier,
+ message: message,
+ name: name,
+ uniqueName: uniqueName,
+ );
/**
* The template used to create the correction to be displayed for this error,
@@ -94,11 +99,6 @@
ErrorType get type;
/**
- * The unique name of this error code.
- */
- String get uniqueName => "$runtimeType.$name";
-
- /**
* Return a URL that can be used to access documentation for diagnostics with
* this code, or `null` if there is no published documentation.
*/
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/errors.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/errors.dart
index 2d539c0..5e87329 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/errors.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/errors.dart
@@ -5,94 +5,8 @@
import '../base/errors.dart';
import '../messages/codes.dart';
import 'error_token.dart';
-import 'token_constants.dart';
import 'token.dart' show Token, TokenType;
-
-/**
- * The error codes used for errors detected by the scanner.
- */
-class ScannerErrorCode extends ErrorCode {
- /**
- * Parameters:
- * 0: the token that was expected but not found
- */
- static const ScannerErrorCode EXPECTED_TOKEN =
- const ScannerErrorCode('EXPECTED_TOKEN', "Expected to find '{0}'.");
-
- /**
- * Parameters:
- * 0: the illegal character
- */
- static const ScannerErrorCode ILLEGAL_CHARACTER =
- const ScannerErrorCode('ILLEGAL_CHARACTER', "Illegal character '{0}'.");
-
- static const ScannerErrorCode MISSING_DIGIT =
- const ScannerErrorCode('MISSING_DIGIT', "Decimal digit expected.");
-
- static const ScannerErrorCode MISSING_HEX_DIGIT = const ScannerErrorCode(
- 'MISSING_HEX_DIGIT', "Hexadecimal digit expected.");
-
- static const ScannerErrorCode MISSING_IDENTIFIER =
- const ScannerErrorCode('MISSING_IDENTIFIER', "Expected an identifier.");
-
- static const ScannerErrorCode MISSING_QUOTE =
- const ScannerErrorCode('MISSING_QUOTE', "Expected quote (' or \").");
-
- /**
- * Parameters:
- * 0: the path of the file that cannot be read
- */
- static const ScannerErrorCode UNABLE_GET_CONTENT = const ScannerErrorCode(
- 'UNABLE_GET_CONTENT', "Unable to get content of '{0}'.");
-
- static const ScannerErrorCode UNEXPECTED_DOLLAR_IN_STRING =
- const ScannerErrorCode(
- 'UNEXPECTED_DOLLAR_IN_STRING',
- "A '\$' has special meaning inside a string, and must be followed by "
- "an identifier or an expression in curly braces ({}).",
- correction: "Try adding a backslash (\\) to escape the '\$'.");
-
- /**
- * Parameters:
- * 0: the unsupported operator
- */
- static const ScannerErrorCode UNSUPPORTED_OPERATOR = const ScannerErrorCode(
- 'UNSUPPORTED_OPERATOR', "The '{0}' operator is not supported.");
-
- static const ScannerErrorCode UNTERMINATED_MULTI_LINE_COMMENT =
- const ScannerErrorCode(
- 'UNTERMINATED_MULTI_LINE_COMMENT', "Unterminated multi-line comment.",
- correction: "Try terminating the comment with '*/', or "
- "removing any unbalanced occurrences of '/*'"
- " (because comments nest in Dart).");
-
- static const ScannerErrorCode UNTERMINATED_STRING_LITERAL =
- const ScannerErrorCode(
- 'UNTERMINATED_STRING_LITERAL', "Unterminated string literal.");
-
- /**
- * Initialize a newly created error code to have the given [name]. The message
- * associated with the error will be created from the given [message]
- * template. The correction associated with the error will be created from the
- * given [correction] template.
- */
- const ScannerErrorCode(String name, String message, {String correction})
- : super.temporary(name, message, correction: correction);
-
- @override
- ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
-
- @override
- ErrorType get type => ErrorType.SYNTACTIC_ERROR;
-}
-
-/**
- * Used to report a scan error at the given offset.
- * The [errorCode] is the error code indicating the nature of the error.
- * The [arguments] are any arguments needed to complete the error message.
- */
-typedef ReportError(
- ScannerErrorCode errorCode, int offset, List<Object> arguments);
+import 'token_constants.dart';
/**
* Translates the given error [token] into an analyzer error and reports it
@@ -190,3 +104,94 @@
// Otherwise keep looking.
}
}
+
+/**
+ * Used to report a scan error at the given offset.
+ * The [errorCode] is the error code indicating the nature of the error.
+ * The [arguments] are any arguments needed to complete the error message.
+ */
+typedef ReportError(
+ ScannerErrorCode errorCode, int offset, List<Object> arguments);
+
+/**
+ * The error codes used for errors detected by the scanner.
+ */
+class ScannerErrorCode extends ErrorCode {
+ /**
+ * Parameters:
+ * 0: the token that was expected but not found
+ */
+ static const ScannerErrorCode EXPECTED_TOKEN =
+ const ScannerErrorCode('EXPECTED_TOKEN', "Expected to find '{0}'.");
+
+ /**
+ * Parameters:
+ * 0: the illegal character
+ */
+ static const ScannerErrorCode ILLEGAL_CHARACTER =
+ const ScannerErrorCode('ILLEGAL_CHARACTER', "Illegal character '{0}'.");
+
+ static const ScannerErrorCode MISSING_DIGIT =
+ const ScannerErrorCode('MISSING_DIGIT', "Decimal digit expected.");
+
+ static const ScannerErrorCode MISSING_HEX_DIGIT = const ScannerErrorCode(
+ 'MISSING_HEX_DIGIT', "Hexadecimal digit expected.");
+
+ static const ScannerErrorCode MISSING_IDENTIFIER =
+ const ScannerErrorCode('MISSING_IDENTIFIER', "Expected an identifier.");
+
+ static const ScannerErrorCode MISSING_QUOTE =
+ const ScannerErrorCode('MISSING_QUOTE', "Expected quote (' or \").");
+
+ /**
+ * Parameters:
+ * 0: the path of the file that cannot be read
+ */
+ static const ScannerErrorCode UNABLE_GET_CONTENT = const ScannerErrorCode(
+ 'UNABLE_GET_CONTENT', "Unable to get content of '{0}'.");
+
+ static const ScannerErrorCode UNEXPECTED_DOLLAR_IN_STRING =
+ const ScannerErrorCode(
+ 'UNEXPECTED_DOLLAR_IN_STRING',
+ "A '\$' has special meaning inside a string, and must be followed by "
+ "an identifier or an expression in curly braces ({}).",
+ correction: "Try adding a backslash (\\) to escape the '\$'.");
+
+ /**
+ * Parameters:
+ * 0: the unsupported operator
+ */
+ static const ScannerErrorCode UNSUPPORTED_OPERATOR = const ScannerErrorCode(
+ 'UNSUPPORTED_OPERATOR', "The '{0}' operator is not supported.");
+
+ static const ScannerErrorCode UNTERMINATED_MULTI_LINE_COMMENT =
+ const ScannerErrorCode(
+ 'UNTERMINATED_MULTI_LINE_COMMENT', "Unterminated multi-line comment.",
+ correction: "Try terminating the comment with '*/', or "
+ "removing any unbalanced occurrences of '/*'"
+ " (because comments nest in Dart).");
+
+ static const ScannerErrorCode UNTERMINATED_STRING_LITERAL =
+ const ScannerErrorCode(
+ 'UNTERMINATED_STRING_LITERAL', "Unterminated string literal.");
+
+ /**
+ * Initialize a newly created error code to have the given [name]. The message
+ * associated with the error will be created from the given [message]
+ * template. The correction associated with the error will be created from the
+ * given [correction] template.
+ */
+ const ScannerErrorCode(String name, String message, {String correction})
+ : super(
+ correction: correction,
+ message: message,
+ name: name,
+ uniqueName: 'ScannerErrorCode.$name',
+ );
+
+ @override
+ ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
+
+ @override
+ ErrorType get type => ErrorType.SYNTACTIC_ERROR;
+}
diff --git a/pkg/_fe_analyzer_shared/pubspec.yaml b/pkg/_fe_analyzer_shared/pubspec.yaml
index 3ea3d4c..a62ab70 100644
--- a/pkg/_fe_analyzer_shared/pubspec.yaml
+++ b/pkg/_fe_analyzer_shared/pubspec.yaml
@@ -4,7 +4,7 @@
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/_fe_analyzer_shared
environment:
- sdk: '>=2.2.2 <3.0.0'
+ sdk: '>=2.6.0 <3.0.0'
dependencies:
meta: ^1.0.2
dev_dependencies:
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_mini_ast.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_mini_ast.dart
new file mode 100644
index 0000000..c62864d
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_mini_ast.dart
@@ -0,0 +1,1491 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// This file implements the AST of a Dart-like language suitable for testing
+/// flow analysis. Callers may use the top level methods in this file to create
+/// AST nodes and then feed them to [Harness.run] to run them through flow
+/// analysis testing.
+import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
+import 'package:meta/meta.dart';
+import 'package:test/test.dart';
+
+const Expression nullLiteral = const _NullLiteral();
+
+Statement assert_(Expression condition, [Expression message]) =>
+ new _Assert(condition, message);
+
+Statement block(List<Statement> statements) => new _Block(statements);
+
+Expression booleanLiteral(bool value) => _BooleanLiteral(value);
+
+/// Wrapper allowing creation of a statement that can be used as the target of
+/// `break` or `continue` statements. [callback] will be invoked to create the
+/// statement, and it will be passed a [BranchTargetPlaceholder] that can be
+/// passed to [break_] or [continue_].
+Statement branchTarget(Statement Function(BranchTargetPlaceholder) callback) {
+ var branchTargetPlaceholder = BranchTargetPlaceholder._();
+ var stmt = callback(branchTargetPlaceholder);
+ branchTargetPlaceholder._target = stmt;
+ return stmt;
+}
+
+Statement break_(BranchTargetPlaceholder branchTargetPlaceholder) =>
+ new _Break(branchTargetPlaceholder);
+
+SwitchCase case_(List<Statement> body, {bool hasLabel = false}) =>
+ SwitchCase._(hasLabel, body);
+
+CatchClause catch_(
+ {Var exception, Var stackTrace, @required List<Statement> body}) =>
+ CatchClause._(body, exception, stackTrace);
+
+/// Creates a pseudo-statement whose function is to verify that flow analysis
+/// considers [variable]'s assigned state to be [expectedAssignedState].
+Statement checkAssigned(Var variable, bool expectedAssignedState) =>
+ new _CheckAssigned(variable, expectedAssignedState);
+
+/// Creates a pseudo-statement whose function is to verify that flow analysis
+/// considers [variable] to be un-promoted.
+Statement checkNotPromoted(Var variable) => new _CheckPromoted(variable, null);
+
+/// Creates a pseudo-statement whose function is to verify that flow analysis
+/// considers [variable]'s assigned state to be promoted to [expectedTypeStr].
+Statement checkPromoted(Var variable, String expectedTypeStr) =>
+ new _CheckPromoted(variable, expectedTypeStr);
+
+/// Creates a pseudo-statement whose function is to verify that flow analysis
+/// considers the current location's reachability state to be
+/// [expectedReachable].
+Statement checkReachable(bool expectedReachable) =>
+ new _CheckReachable(expectedReachable);
+
+/// Creates a pseudo-statement whose function is to verify that flow analysis
+/// considers [variable]'s unassigned state to be [expectedUnassignedState].
+Statement checkUnassigned(Var variable, bool expectedUnassignedState) =>
+ new _CheckUnassigned(variable, expectedUnassignedState);
+
+Statement continue_(BranchTargetPlaceholder branchTargetPlaceholder) =>
+ new _Continue(branchTargetPlaceholder);
+
+Statement declare(Var variable, {@required bool initialized}) =>
+ new _Declare(variable, initialized);
+
+Statement do_(List<Statement> body, Expression condition) =>
+ _Do(body, condition);
+
+/// Creates a pseudo-expression having type [typeStr] that otherwise has no
+/// effect on flow analysis.
+Expression expr(String typeStr) =>
+ new _PlaceholderExpression(new Type(typeStr));
+
+/// Creates a conventional `for` statement. Optional boolean [forCollection]
+/// indicates that this `for` statement is actually a collection element, so
+/// `null` should be passed to [for_bodyBegin].
+Statement for_(Statement initializer, Expression condition, Expression updater,
+ List<Statement> body,
+ {bool forCollection = false}) =>
+ new _For(initializer, condition, updater, body, forCollection);
+
+/// Creates a "for each" statement where the identifier being assigned to by the
+/// iteration is not a local variable.
+///
+/// This models code like:
+/// var x; // Top level variable
+/// f(Iterable iterable) {
+/// for (x in iterable) { ... }
+/// }
+Statement forEachWithNonVariable(Expression iterable, List<Statement> body) =>
+ new _ForEach(null, iterable, body, false);
+
+/// Creates a "for each" statement where the identifier being assigned to by the
+/// iteration is a variable that is being declared by the "for each" statement.
+///
+/// This models code like:
+/// f(Iterable iterable) {
+/// for (var x in iterable) { ... }
+/// }
+Statement forEachWithVariableDecl(
+ Var variable, Expression iterable, List<Statement> body) {
+ assert(variable != null);
+ return new _ForEach(variable, iterable, body, true);
+}
+
+/// Creates a "for each" statement where the identifier being assigned to by the
+/// iteration is a local variable that is declared elsewhere in the function.
+///
+/// This models code like:
+/// f(Iterable iterable) {
+/// var x;
+/// for (x in iterable) { ... }
+/// }
+Statement forEachWithVariableSet(
+ Var variable, Expression iterable, List<Statement> body) {
+ assert(variable != null);
+ return new _ForEach(variable, iterable, body, false);
+}
+
+Statement if_(Expression condition, List<Statement> ifTrue,
+ [List<Statement> ifFalse]) =>
+ new _If(condition, ifTrue, ifFalse);
+
+Statement labeled(Statement body) => new _LabeledStatement(body);
+
+Statement localFunction(List<Statement> body) => _LocalFunction(body);
+
+Statement return_() => new _Return();
+
+Statement switch_(Expression expression, List<SwitchCase> cases,
+ {@required bool isExhaustive}) =>
+ new _Switch(expression, cases, isExhaustive);
+
+Statement tryCatch(List<Statement> body, List<CatchClause> catches) =>
+ new _TryCatch(body, catches);
+
+Statement tryFinally(List<Statement> body, List<Statement> finally_) =>
+ new _TryFinally(body, finally_);
+
+Statement while_(Expression condition, List<Statement> body) =>
+ new _While(condition, body);
+
+/// Placeholder used by [branchTarget] to tie `break` and `continue` statements
+/// to their branch targets.
+class BranchTargetPlaceholder {
+ Statement _target;
+
+ /*late*/ BranchTargetPlaceholder._();
+}
+
+/// Representation of a single catch clause in a try/catch statement. Use
+/// [catch_] to create instances of this class.
+class CatchClause implements _Visitable<void> {
+ final List<Statement> _body;
+ final Var _exception;
+ final Var _stackTrace;
+
+ CatchClause._(this._body, this._exception, this._stackTrace);
+
+ String toString() {
+ String initialPart;
+ if (_stackTrace != null) {
+ initialPart = 'catch (${_exception.name}, ${_stackTrace.name})';
+ } else if (_exception != null) {
+ initialPart = 'catch (${_exception.name})';
+ } else {
+ initialPart = 'on ...';
+ }
+ return '$initialPart ${block(_body)}';
+ }
+
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+ _body._preVisit(assignedVariables);
+ }
+
+ void _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ flow.tryCatchStatement_catchBegin(_exception, _stackTrace);
+ _body._visit(h, flow);
+ flow.tryCatchStatement_catchEnd();
+ }
+}
+
+/// Representation of an expression in the pseudo-Dart language used for flow
+/// analysis testing. Methods in this class may be used to create more complex
+/// expressions based on this one.
+abstract class Expression implements _Visitable<Type> {
+ const Expression();
+
+ /// If `this` is an expression `x`, creates the expression `x!`.
+ Expression get nonNullAssert => new _NonNullAssert(this);
+
+ /// If `this` is an expression `x`, creates the expression `(x)`.
+ Expression get parenthesized => new _WrappedExpression(null, this, null);
+
+ /// If `this` is an expression `x`, creates the statement `x;`.
+ Statement get stmt => new _ExpressionStatement(this);
+
+ /// If `this` is an expression `x`, creates the expression `x && other`.
+ Expression and(Expression other) => new _Logical(this, other, isAnd: true);
+
+ /// If `this` is an expression `x`, creates the expression `x as typeStr`.
+ Expression as_(String typeStr) => new _As(this, Type(typeStr));
+
+ /// If `this` is an expression `x`, creates the expression
+ /// `x ? ifTrue : ifFalse`.
+ Expression conditional(Expression ifTrue, Expression ifFalse) =>
+ new _Conditional(this, ifTrue, ifFalse);
+
+ /// If `this` is an expression `x`, creates the expression `x == other`.
+ Expression eq(Expression other) => new _Equal(this, other, false);
+
+ /// If `this` is an expression `x`, creates the expression `x ?? other`.
+ Expression ifNull(Expression other) => new _IfNull(this, other);
+
+ /// If `this` is an expression `x`, creates the expression `x is typeStr`.
+ ///
+ /// With [isInverted] set to `true`, creates the expression `x is! typeStr`.
+ Expression is_(String typeStr, {bool isInverted = false}) =>
+ new _Is(this, Type(typeStr), isInverted);
+
+ /// If `this` is an expression `x`, creates the expression `x is! typeStr`.
+ Expression isNot(String typeStr) => _Is(this, Type(typeStr), true);
+
+ /// If `this` is an expression `x`, creates the expression `x != other`.
+ Expression notEq(Expression other) => _Equal(this, other, true);
+
+ /// If `this` is an expression `x`, creates the expression `x?.other`.
+ ///
+ /// Note that in the real Dart language, the RHS of a null aware access isn't
+ /// strictly speaking an expression. However for flow analysis it suffices to
+ /// model it as an expression.
+ Expression nullAwareAccess(Expression other, {bool isCascaded = false}) =>
+ _NullAwareAccess(this, other, isCascaded);
+
+ /// If `this` is an expression `x`, creates the expression `x || other`.
+ Expression or(Expression other) => new _Logical(this, other, isAnd: false);
+
+ /// If `this` is an expression `x`, creates a pseudo-expression that models
+ /// evaluation of `x` followed by execution of [stmt]. This can be used to
+ /// test that flow analysis is in the correct state after an expression is
+ /// visited.
+ Expression thenStmt(Statement stmt) =>
+ new _WrappedExpression(null, this, stmt);
+}
+
+/// Test harness for creating flow analysis tests. This class implements all
+/// the [TypeOperations] needed by flow analysis, as well as other methods
+/// needed for testing.
+class Harness extends TypeOperations<Var, Type> {
+ static const Map<String, bool> _coreSubtypes = const {
+ 'double <: Object': true,
+ 'double <: num': true,
+ 'double <: num?': true,
+ 'double <: int': false,
+ 'double <: int?': false,
+ 'int <: double': false,
+ 'int <: int?': true,
+ 'int <: Iterable': false,
+ 'int <: List': false,
+ 'int <: Null': false,
+ 'int <: num': true,
+ 'int <: num?': true,
+ 'int <: num*': true,
+ 'int <: Never?': false,
+ 'int <: Object': true,
+ 'int <: Object?': true,
+ 'int <: String': false,
+ 'int? <: int': false,
+ 'int? <: Null': false,
+ 'int? <: num': false,
+ 'int? <: num?': true,
+ 'int? <: Object': false,
+ 'int? <: Object?': true,
+ 'Null <: int': false,
+ 'Null <: Object': false,
+ 'num <: int': false,
+ 'num <: Iterable': false,
+ 'num <: List': false,
+ 'num <: num?': true,
+ 'num <: num*': true,
+ 'num <: Object': true,
+ 'num <: Object?': true,
+ 'num? <: int?': false,
+ 'num? <: num': false,
+ 'num? <: num*': true,
+ 'num? <: Object': false,
+ 'num? <: Object?': true,
+ 'num* <: num': true,
+ 'num* <: num?': true,
+ 'num* <: Object': true,
+ 'num* <: Object?': true,
+ 'Iterable <: int': false,
+ 'Iterable <: num': false,
+ 'Iterable <: Object': true,
+ 'Iterable <: Object?': true,
+ 'List <: int': false,
+ 'List <: Iterable': true,
+ 'List <: Object': true,
+ 'Never <: int': true,
+ 'Never <: int?': true,
+ 'Never <: Null': true,
+ 'Never? <: int': false,
+ 'Never? <: int?': true,
+ 'Never? <: num?': true,
+ 'Never? <: Object?': true,
+ 'Null <: int?': true,
+ 'Object <: int': false,
+ 'Object <: int?': false,
+ 'Object <: List': false,
+ 'Object <: num': false,
+ 'Object <: num?': false,
+ 'Object <: Object?': true,
+ 'Object? <: Object': false,
+ 'Object? <: int': false,
+ 'Object? <: int?': false,
+ 'String <: int': false,
+ 'String <: int?': false,
+ 'String <: num?': false,
+ 'String <: Object?': true,
+ };
+
+ static final Map<String, Type> _coreFactors = {
+ 'Object? - int': Type('Object?'),
+ 'Object? - int?': Type('Object'),
+ 'Object? - num?': Type('Object'),
+ 'Object? - Object?': Type('Never?'),
+ 'Object? - String': Type('Object?'),
+ 'Object - int': Type('Object'),
+ 'int - Object': Type('Never'),
+ 'int - String': Type('int'),
+ 'int - int': Type('Never'),
+ 'int - int?': Type('Never'),
+ 'int? - int': Type('Never?'),
+ 'int? - int?': Type('Never'),
+ 'int? - String': Type('int?'),
+ 'Null - int': Type('Null'),
+ 'num - int': Type('num'),
+ 'num? - num': Type('Never?'),
+ 'num? - int': Type('num?'),
+ 'num? - int?': Type('num'),
+ 'num? - Object': Type('Never?'),
+ 'num? - String': Type('num?'),
+ 'Object - int?': Type('Object'),
+ 'Object - num': Type('Object'),
+ 'Object - num?': Type('Object'),
+ 'Object - num*': Type('Object'),
+ 'Object - Iterable': Type('Object'),
+ 'Object? - Object': Type('Never?'),
+ 'Object? - Iterable': Type('Object?'),
+ 'Object? - num': Type('Object?'),
+ 'Iterable - List': Type('Iterable'),
+ 'num* - Object': Type('Never'),
+ };
+
+ final Map<String, bool> _subtypes = Map.of(_coreSubtypes);
+
+ final Map<String, Type> _factorResults = Map.of(_coreFactors);
+
+ Node _currentSwitch;
+
+ /// Updates the harness so that when a [factor] query is invoked on types
+ /// [from] and [what], [result] will be returned.
+ void addFactor(Type from, Type what, Type result) {
+ var query = '$from - $what';
+ _factorResults[query] = result;
+ }
+
+ /// Updates the harness so that when an [isSubtypeOf] query is invoked on
+ /// types [leftType] and [rightType], [isSubtype] will be returned.
+ void addSubtype(Type leftType, Type rightType, bool isSubtype) {
+ var query = '$leftType <: $rightType';
+ _subtypes[query] = isSubtype;
+ }
+
+ @override
+ TypeClassification classifyType(Type type) {
+ if (isSubtypeOf(type, Type('Object'))) {
+ return TypeClassification.nonNullable;
+ } else if (isSubtypeOf(type, Type('Null'))) {
+ return TypeClassification.nullOrEquivalent;
+ } else {
+ return TypeClassification.potentiallyNullable;
+ }
+ }
+
+ @override
+ Type factor(Type from, Type what) {
+ var query = '$from - $what';
+ return _factorResults[query] ?? fail('Unknown factor query: $query');
+ }
+
+ @override
+ bool isNever(Type type) {
+ return type.type == 'Never';
+ }
+
+ @override
+ bool isSameType(Type type1, Type type2) {
+ return type1.type == type2.type;
+ }
+
+ @override
+ bool isSubtypeOf(Type leftType, Type rightType) {
+ if (leftType.type == rightType.type) return true;
+ var query = '$leftType <: $rightType';
+ return _subtypes[query] ?? fail('Unknown subtype query: $query');
+ }
+
+ @override
+ Type promoteToNonNull(Type type) {
+ if (type.type.endsWith('?')) {
+ return Type(type.type.substring(0, type.type.length - 1));
+ } else if (type.type == 'Null') {
+ return Type('Never');
+ } else {
+ return type;
+ }
+ }
+
+ /// Runs the given [statements] through flow analysis, checking any assertions
+ /// they contain.
+ void run(List<Statement> statements) {
+ var assignedVariables = AssignedVariables<Node, Var>();
+ statements._preVisit(assignedVariables);
+ var flow = FlowAnalysis<Node, Statement, Expression, Var, Type>(
+ this, assignedVariables);
+ statements._visit(this, flow);
+ flow.finish();
+ }
+
+ @override
+ Type tryPromoteToType(Type to, Type from) {
+ if (isSubtypeOf(to, from)) {
+ return to;
+ } else {
+ return null;
+ }
+ }
+
+ @override
+ Type variableType(Var variable) {
+ return variable.type;
+ }
+
+ Type _getIteratedType(Type iterableType) {
+ var typeStr = iterableType.type;
+ if (typeStr.startsWith('List<') && typeStr.endsWith('>')) {
+ return Type(typeStr.substring(5, typeStr.length - 1));
+ } else {
+ throw UnimplementedError('TODO(paulberry): getIteratedType($typeStr)');
+ }
+ }
+
+ Type _lub(Type type1, Type type2) {
+ if (isSameType(type1, type2)) {
+ return type1;
+ } else if (isSameType(promoteToNonNull(type1), type2)) {
+ return type1;
+ } else if (isSameType(promoteToNonNull(type2), type1)) {
+ return type2;
+ } else if (type1.type == 'Null' &&
+ !isSameType(promoteToNonNull(type2), type2)) {
+ // type2 is already nullable
+ return type2;
+ } else if (type2.type == 'Null' &&
+ !isSameType(promoteToNonNull(type1), type1)) {
+ // type1 is already nullable
+ return type1;
+ } else {
+ throw UnimplementedError(
+ 'TODO(paulberry): least upper bound of $type1 and $type2');
+ }
+ }
+}
+
+/// Representation of an expression or statement in the pseudo-Dart language
+/// used for flow analysis testing.
+class Node {
+ Node._();
+}
+
+/// Representation of a statement in the pseudo-Dart language used for flow
+/// analysis testing.
+abstract class Statement extends Node implements _Visitable<void> {
+ Statement._() : super._();
+
+ /// If `this` is a statement `x`, creates a pseudo-expression that models
+ /// execution of `x` followed by evaluation of [expr]. This can be used to
+ /// test that flow analysis is in the correct state before an expression is
+ /// visited.
+ Expression thenExpr(Expression expr) => _WrappedExpression(this, expr, null);
+}
+
+/// Representation of a single case clause in a switch statement. Use [case_]
+/// to create instances of this class.
+class SwitchCase implements _Visitable<void> {
+ final bool _hasLabel;
+ final List<Statement> _body;
+
+ SwitchCase._(this._hasLabel, this._body);
+
+ String toString() =>
+ [if (_hasLabel) '<label>:', 'case <value>:', ..._body].join(' ');
+
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+ _body._preVisit(assignedVariables);
+ }
+
+ void _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ flow.switchStatement_beginCase(_hasLabel, h._currentSwitch);
+ _body._visit(h, flow);
+ }
+}
+
+/// Representation of a type in the pseudo-Dart language used for flow analysis
+/// testing. This is essentially a thin wrapper around a string representation
+/// of the type.
+class Type {
+ final String type;
+
+ Type(this.type);
+
+ @override
+ bool operator ==(Object other) {
+ // The flow analysis engine should not compare types using operator==. It
+ // should compare them using TypeOperations.
+ fail('Unexpected use of operator== on types');
+ }
+
+ @override
+ String toString() => type;
+}
+
+/// Representation of a local variable in the pseudo-Dart language used for flow
+/// analysis testing.
+class Var {
+ final String name;
+ final Type type;
+
+ Var(this.name, String typeStr) : type = Type(typeStr);
+
+ /// Creates an expression representing a read of this variable.
+ Expression get read => new _VariableRead(this);
+
+ @override
+ String toString() => '$type $name';
+
+ /// Creates an expression representing a write to this variable.
+ Expression write(Expression value) => new _Write(this, value);
+}
+
+class _As extends Expression {
+ final Expression target;
+ final Type type;
+
+ _As(this.target, this.type);
+
+ @override
+ String toString() => '$target as $type';
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+ target._preVisit(assignedVariables);
+ }
+
+ @override
+ Type _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ target._visit(h, flow);
+ flow.asExpression_end(target, type);
+ return type;
+ }
+}
+
+class _Assert extends Statement {
+ final Expression condition;
+ final Expression message;
+
+ _Assert(this.condition, this.message) : super._();
+
+ @override
+ String toString() =>
+ 'assert($condition${message == null ? '' : ', $message'});';
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+ condition._preVisit(assignedVariables);
+ message?._preVisit(assignedVariables);
+ }
+
+ @override
+ void _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ flow.assert_begin();
+ flow.assert_afterCondition(condition.._visit(h, flow));
+ message?._visit(h, flow);
+ flow.assert_end();
+ }
+}
+
+class _Block extends Statement {
+ final List<Statement> statements;
+
+ _Block(this.statements) : super._();
+
+ @override
+ String toString() =>
+ statements.isEmpty ? '{}' : '{ ${statements.join(' ')} }';
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+ statements._preVisit(assignedVariables);
+ }
+
+ @override
+ void _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ statements._visit(h, flow);
+ }
+}
+
+class _BooleanLiteral extends Expression {
+ final bool value;
+
+ _BooleanLiteral(this.value);
+
+ @override
+ String toString() => '$value';
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+ @override
+ Type _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ flow.booleanLiteral(this, value);
+ return Type('bool');
+ }
+}
+
+class _Break extends Statement {
+ final BranchTargetPlaceholder branchTargetPlaceholder;
+
+ _Break(this.branchTargetPlaceholder) : super._();
+
+ @override
+ String toString() => 'break;';
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+ @override
+ void _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ assert(branchTargetPlaceholder._target != null);
+ flow.handleBreak(branchTargetPlaceholder._target);
+ }
+}
+
+class _CheckAssigned extends Statement {
+ final Var variable;
+ final bool expectedAssignedState;
+
+ _CheckAssigned(this.variable, this.expectedAssignedState) : super._();
+
+ @override
+ String toString() {
+ var verb = expectedAssignedState ? 'is' : 'is not';
+ return 'check $variable $verb definitely assigned;';
+ }
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+ @override
+ void _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ expect(flow.isAssigned(variable), expectedAssignedState);
+ }
+}
+
+class _CheckPromoted extends Statement {
+ final Var variable;
+ final String expectedTypeStr;
+
+ _CheckPromoted(this.variable, this.expectedTypeStr) : super._();
+
+ @override
+ String toString() {
+ var predicate = expectedTypeStr == null
+ ? 'not promoted'
+ : 'promoted to $expectedTypeStr';
+ return 'check $variable $predicate;';
+ }
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+ @override
+ void _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ var promotedType = flow.promotedType(variable);
+ if (expectedTypeStr == null) {
+ expect(promotedType, isNull);
+ } else {
+ expect(promotedType.type, expectedTypeStr);
+ }
+ }
+}
+
+class _CheckReachable extends Statement {
+ final bool expectedReachable;
+
+ _CheckReachable(this.expectedReachable) : super._();
+
+ @override
+ String toString() => 'check reachable;';
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+ @override
+ void _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ expect(flow.isReachable, expectedReachable);
+ }
+}
+
+class _CheckUnassigned extends Statement {
+ final Var variable;
+ final bool expectedUnassignedState;
+
+ _CheckUnassigned(this.variable, this.expectedUnassignedState) : super._();
+
+ @override
+ String toString() {
+ var verb = expectedUnassignedState ? 'is' : 'is not';
+ return 'check $variable $verb definitely unassigned;';
+ }
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+ @override
+ void _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ expect(flow.isUnassigned(variable), expectedUnassignedState);
+ }
+}
+
+class _Conditional extends Expression {
+ final Expression condition;
+ final Expression ifTrue;
+ final Expression ifFalse;
+
+ _Conditional(this.condition, this.ifTrue, this.ifFalse);
+
+ @override
+ String toString() => '$condition ? $ifTrue : $ifFalse';
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+ condition._preVisit(assignedVariables);
+ ifTrue._preVisit(assignedVariables);
+ ifFalse._preVisit(assignedVariables);
+ }
+
+ @override
+ Type _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ flow.conditional_conditionBegin();
+ flow.conditional_thenBegin(condition.._visit(h, flow));
+ var ifTrueType = ifTrue._visit(h, flow);
+ flow.conditional_elseBegin(ifTrue);
+ var ifFalseType = ifFalse._visit(h, flow);
+ flow.conditional_end(this, ifFalse);
+ return h._lub(ifTrueType, ifFalseType);
+ }
+}
+
+class _Continue extends Statement {
+ final BranchTargetPlaceholder branchTargetPlaceholder;
+
+ _Continue(this.branchTargetPlaceholder) : super._();
+
+ @override
+ String toString() => 'continue;';
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+ @override
+ void _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ assert(branchTargetPlaceholder._target != null);
+ flow.handleContinue(branchTargetPlaceholder._target);
+ }
+}
+
+class _Declare extends Statement {
+ final Var variable;
+ final bool initialized;
+
+ _Declare(this.variable, this.initialized) : super._();
+
+ @override
+ String toString() => '$variable${initialized ? ' = ...' : ''};';
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+ @override
+ void _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ flow.declare(variable, initialized);
+ }
+}
+
+class _Do extends Statement {
+ final List<Statement> body;
+ final Expression condition;
+
+ _Do(this.body, this.condition) : super._();
+
+ @override
+ String toString() => 'do ${block(body)} while ($condition);';
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+ assignedVariables.beginNode();
+ body._preVisit(assignedVariables);
+ condition._preVisit(assignedVariables);
+ assignedVariables.endNode(this);
+ }
+
+ @override
+ void _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ flow.doStatement_bodyBegin(this);
+ body._visit(h, flow);
+ flow.doStatement_conditionBegin();
+ condition._visit(h, flow);
+ flow.doStatement_end(condition);
+ }
+}
+
+class _Equal extends Expression {
+ final Expression lhs;
+ final Expression rhs;
+ final bool isInverted;
+
+ _Equal(this.lhs, this.rhs, this.isInverted);
+
+ @override
+ String toString() => '$lhs ${isInverted ? '!=' : '=='} $rhs';
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+ lhs._preVisit(assignedVariables);
+ rhs._preVisit(assignedVariables);
+ }
+
+ @override
+ Type _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ var lhsType = lhs._visit(h, flow);
+ flow.equalityOp_rightBegin(lhs, lhsType);
+ var rhsType = rhs._visit(h, flow);
+ flow.equalityOp_end(this, rhs, rhsType, notEqual: isInverted);
+ return Type('bool');
+ }
+}
+
+class _ExpressionStatement extends Statement {
+ final Expression expr;
+
+ _ExpressionStatement(this.expr) : super._();
+
+ @override
+ String toString() => '$expr;';
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+ expr._preVisit(assignedVariables);
+ }
+
+ @override
+ void _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ expr._visit(h, flow);
+ }
+}
+
+class _For extends Statement {
+ final Statement initializer;
+ final Expression condition;
+ final Expression updater;
+ final List<Statement> body;
+ final bool forCollection;
+
+ _For(this.initializer, this.condition, this.updater, this.body,
+ this.forCollection)
+ : super._();
+
+ @override
+ String toString() {
+ var buffer = StringBuffer('for (');
+ if (initializer == null) {
+ buffer.write(';');
+ } else {
+ buffer.write(initializer);
+ }
+ if (condition == null) {
+ buffer.write(';');
+ } else {
+ buffer.write(' $condition;');
+ }
+ if (updater != null) {
+ buffer.write(' $updater');
+ }
+ buffer.write(') ${block(body)}');
+ return buffer.toString();
+ }
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+ initializer?._preVisit(assignedVariables);
+ assignedVariables.beginNode();
+ condition?._preVisit(assignedVariables);
+ body._preVisit(assignedVariables);
+ updater?._preVisit(assignedVariables);
+ assignedVariables.endNode(this);
+ }
+
+ @override
+ void _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ initializer?._visit(h, flow);
+ flow.for_conditionBegin(this);
+ condition?._visit(h, flow);
+ flow.for_bodyBegin(forCollection ? null : this, condition);
+ body._visit(h, flow);
+ flow.for_updaterBegin();
+ updater?._visit(h, flow);
+ flow.for_end();
+ }
+}
+
+class _ForEach extends Statement {
+ final Var variable;
+ final Expression iterable;
+ final List<Statement> body;
+ final bool declaresVariable;
+
+ _ForEach(this.variable, this.iterable, this.body, this.declaresVariable)
+ : super._();
+
+ @override
+ String toString() {
+ String declarationPart;
+ if (variable == null) {
+ declarationPart = '<identifier>';
+ } else if (declaresVariable) {
+ declarationPart = variable.toString();
+ } else {
+ declarationPart = variable.name;
+ }
+ return 'for ($declarationPart in $iterable) ${block(body)}';
+ }
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+ iterable._preVisit(assignedVariables);
+ if (variable != null) {
+ if (declaresVariable) {
+ assignedVariables.declare(variable);
+ } else {
+ assignedVariables.write(variable);
+ }
+ }
+ assignedVariables.beginNode();
+ body._preVisit(assignedVariables);
+ assignedVariables.endNode(this);
+ }
+
+ @override
+ void _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ var iteratedType = h._getIteratedType(iterable._visit(h, flow));
+ flow.forEach_bodyBegin(this, variable, iteratedType);
+ body._visit(h, flow);
+ flow.forEach_end();
+ }
+}
+
+class _If extends Statement {
+ final Expression condition;
+ final List<Statement> ifTrue;
+ final List<Statement> ifFalse;
+
+ _If(this.condition, this.ifTrue, this.ifFalse) : super._();
+
+ @override
+ String toString() =>
+ 'if ($condition) ${block(ifTrue)}' +
+ (ifFalse == null ? '' : 'else ${block(ifFalse)}');
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+ condition._preVisit(assignedVariables);
+ ifTrue._preVisit(assignedVariables);
+ ifFalse?._preVisit(assignedVariables);
+ }
+
+ @override
+ void _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ flow.ifStatement_conditionBegin();
+ flow.ifStatement_thenBegin(condition.._visit(h, flow));
+ ifTrue._visit(h, flow);
+ if (ifFalse == null) {
+ flow.ifStatement_end(false);
+ } else {
+ flow.ifStatement_elseBegin();
+ ifFalse._visit(h, flow);
+ flow.ifStatement_end(true);
+ }
+ }
+}
+
+class _IfNull extends Expression {
+ final Expression lhs;
+ final Expression rhs;
+
+ _IfNull(this.lhs, this.rhs);
+
+ @override
+ String toString() => '$lhs ?? $rhs';
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+ lhs._preVisit(assignedVariables);
+ rhs._preVisit(assignedVariables);
+ }
+
+ @override
+ Type _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ var lhsType = lhs._visit(h, flow);
+ flow.ifNullExpression_rightBegin(lhs, lhsType);
+ var rhsType = rhs._visit(h, flow);
+ flow.ifNullExpression_end();
+ return h._lub(h.promoteToNonNull(lhsType), rhsType);
+ }
+}
+
+class _Is extends Expression {
+ final Expression target;
+ final Type type;
+ final bool isInverted;
+
+ _Is(this.target, this.type, this.isInverted);
+
+ @override
+ String toString() => '$target is${isInverted ? '!' : ''} $type';
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+ target._preVisit(assignedVariables);
+ }
+
+ @override
+ Type _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ flow.isExpression_end(this, target.._visit(h, flow), isInverted, type);
+ return Type('bool');
+ }
+}
+
+class _LabeledStatement extends Statement {
+ final Statement body;
+
+ _LabeledStatement(this.body) : super._();
+
+ @override
+ String toString() => 'labeled: $body';
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+ body._preVisit(assignedVariables);
+ }
+
+ @override
+ void _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ flow.labeledStatement_begin(this);
+ body._visit(h, flow);
+ flow.labeledStatement_end();
+ }
+}
+
+class _LocalFunction extends Statement {
+ final List<Statement> body;
+
+ _LocalFunction(this.body) : super._();
+
+ @override
+ String toString() => '() ${block(body)}';
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+ assignedVariables.beginNode();
+ body._preVisit(assignedVariables);
+ assignedVariables.endNode(this, isClosureOrLateVariableInitializer: true);
+ }
+
+ @override
+ void _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ flow.functionExpression_begin(this);
+ body._visit(h, flow);
+ flow.functionExpression_end();
+ }
+}
+
+class _Logical extends Expression {
+ final Expression lhs;
+ final Expression rhs;
+ final bool isAnd;
+
+ _Logical(this.lhs, this.rhs, {@required this.isAnd});
+
+ @override
+ String toString() => '$lhs ${isAnd ? '&&' : '||'} $rhs';
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+ lhs._preVisit(assignedVariables);
+ rhs._preVisit(assignedVariables);
+ }
+
+ @override
+ Type _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ flow.logicalBinaryOp_begin();
+ flow.logicalBinaryOp_rightBegin(lhs.._visit(h, flow), isAnd: isAnd);
+ flow.logicalBinaryOp_end(this, rhs.._visit(h, flow), isAnd: isAnd);
+ return Type('bool');
+ }
+}
+
+class _NonNullAssert extends Expression {
+ final Expression operand;
+
+ _NonNullAssert(this.operand);
+
+ @override
+ String toString() => '$operand!';
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+ operand._preVisit(assignedVariables);
+ }
+
+ @override
+ Type _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ var type = operand._visit(h, flow);
+ flow.nonNullAssert_end(operand);
+ return h.promoteToNonNull(type);
+ }
+}
+
+class _NullAwareAccess extends Expression {
+ final Expression lhs;
+ final Expression rhs;
+ final bool isCascaded;
+
+ _NullAwareAccess(this.lhs, this.rhs, this.isCascaded);
+
+ @override
+ String toString() => '$lhs?.${isCascaded ? '.' : ''}($rhs)';
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+ lhs._preVisit(assignedVariables);
+ rhs._preVisit(assignedVariables);
+ }
+
+ @override
+ Type _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ var lhsType = lhs._visit(h, flow);
+ flow.nullAwareAccess_rightBegin(isCascaded ? null : lhs, lhsType);
+ var rhsType = rhs._visit(h, flow);
+ flow.nullAwareAccess_end();
+ return h._lub(rhsType, Type('Null'));
+ }
+}
+
+class _NullLiteral extends Expression {
+ const _NullLiteral();
+
+ @override
+ String toString() => 'null';
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+ @override
+ Type _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ flow.nullLiteral(this);
+ return Type('Null');
+ }
+}
+
+class _PlaceholderExpression extends Expression {
+ final Type type;
+
+ _PlaceholderExpression(this.type);
+
+ @override
+ String toString() => '(expr with type $type)';
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+ @override
+ Type _visit(Harness h,
+ FlowAnalysis<Node, Statement, Expression, Var, Type> flow) =>
+ type;
+}
+
+class _Return extends Statement {
+ _Return() : super._();
+
+ @override
+ String toString() => 'return;';
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+ @override
+ void _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ flow.handleExit();
+ }
+}
+
+class _Switch extends Statement {
+ final Expression expression;
+ final List<SwitchCase> cases;
+ final bool isExhaustive;
+
+ _Switch(this.expression, this.cases, this.isExhaustive) : super._();
+
+ @override
+ String toString() {
+ var exhaustiveness = isExhaustive ? 'exhaustive' : 'non-exhaustive';
+ String body;
+ if (cases.isEmpty) {
+ body = '{}';
+ } else {
+ var contents = cases.join(' ');
+ body = '{ $contents }';
+ }
+ return 'switch<$exhaustiveness> ($expression) $body';
+ }
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+ expression._preVisit(assignedVariables);
+ assignedVariables.beginNode();
+ cases._preVisit(assignedVariables);
+ assignedVariables.endNode(this);
+ }
+
+ @override
+ void _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ expression._visit(h, flow);
+ flow.switchStatement_expressionEnd(this);
+ var oldSwitch = h._currentSwitch;
+ h._currentSwitch = this;
+ cases._visit(h, flow);
+ h._currentSwitch = oldSwitch;
+ flow.switchStatement_end(isExhaustive);
+ }
+}
+
+class _TryCatch extends Statement {
+ final List<Statement> body;
+ final List<CatchClause> catches;
+
+ _TryCatch(this.body, this.catches) : super._();
+
+ @override
+ String toString() => 'try ${block(body)} ${catches.join(' ')}';
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+ assignedVariables.beginNode();
+ body._preVisit(assignedVariables);
+ assignedVariables.endNode(this);
+ catches._preVisit(assignedVariables);
+ }
+
+ @override
+ void _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ flow.tryCatchStatement_bodyBegin();
+ body._visit(h, flow);
+ flow.tryCatchStatement_bodyEnd(this);
+ catches._visit(h, flow);
+ flow.tryCatchStatement_end();
+ }
+}
+
+class _TryFinally extends Statement {
+ final List<Statement> body;
+ final List<Statement> finally_;
+ final Node _bodyNode = Node._();
+ final Node _finallyNode = Node._();
+
+ _TryFinally(this.body, this.finally_) : super._();
+
+ @override
+ String toString() => 'try ${block(body)} finally ${block(finally_)}';
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+ assignedVariables.beginNode();
+ body._preVisit(assignedVariables);
+ assignedVariables.endNode(_bodyNode);
+ assignedVariables.beginNode();
+ finally_._preVisit(assignedVariables);
+ assignedVariables.endNode(_finallyNode);
+ }
+
+ @override
+ void _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ flow.tryFinallyStatement_bodyBegin();
+ body._visit(h, flow);
+ flow.tryFinallyStatement_finallyBegin(_bodyNode);
+ finally_._visit(h, flow);
+ flow.tryFinallyStatement_end(_finallyNode);
+ }
+}
+
+class _VariableRead extends Expression {
+ final Var variable;
+
+ _VariableRead(this.variable);
+
+ @override
+ String toString() => variable.name;
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {}
+
+ @override
+ Type _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ return flow.variableRead(this, variable) ?? variable.type;
+ }
+}
+
+abstract class _Visitable<T> {
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables);
+
+ T _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow);
+}
+
+class _While extends Statement {
+ final Expression condition;
+ final List<Statement> body;
+
+ _While(this.condition, this.body) : super._();
+
+ @override
+ String toString() => 'while ($condition) ${block(body)}';
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+ assignedVariables.beginNode();
+ condition?._preVisit(assignedVariables);
+ body._preVisit(assignedVariables);
+ assignedVariables.endNode(this);
+ }
+
+ @override
+ void _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ flow.whileStatement_conditionBegin(this);
+ condition?._visit(h, flow);
+ flow.whileStatement_bodyBegin(this, condition);
+ body._visit(h, flow);
+ flow.whileStatement_end();
+ }
+}
+
+class _WrappedExpression extends Expression {
+ final Statement before;
+ final Expression expr;
+ final Statement after;
+
+ _WrappedExpression(this.before, this.expr, this.after);
+
+ @override
+ String toString() {
+ var s = StringBuffer('(');
+ if (before != null) {
+ s.write('($before) ');
+ }
+ s.write(expr);
+ if (after != null) {
+ s.write(' ($after)');
+ }
+ s.write(')');
+ return s.toString();
+ }
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+ before?._preVisit(assignedVariables);
+ expr._preVisit(assignedVariables);
+ after?._preVisit(assignedVariables);
+ }
+
+ @override
+ Type _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ before?._visit(h, flow);
+ var type = expr._visit(h, flow);
+ after?._visit(h, flow);
+ flow.forwardExpression(this, expr);
+ return type;
+ }
+}
+
+class _Write extends Expression {
+ final Var variable;
+ final Expression rhs;
+
+ _Write(this.variable, this.rhs);
+
+ @override
+ String toString() => '${variable.name} = $rhs';
+
+ @override
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+ assignedVariables.write(variable);
+ rhs._preVisit(assignedVariables);
+ }
+
+ @override
+ Type _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ var type = rhs._visit(h, flow);
+ flow.write(variable, type);
+ return type;
+ }
+}
+
+extension on List<_Visitable<void>> {
+ void _preVisit(AssignedVariables<Node, Var> assignedVariables) {
+ for (var element in this) {
+ element._preVisit(assignedVariables);
+ }
+ }
+
+ void _visit(
+ Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
+ for (var element in this) {
+ element._visit(h, flow);
+ }
+ }
+}
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
index 02d3307..b7e5b8e 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
@@ -3,152 +3,139 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
-import 'package:meta/meta.dart';
import 'package:test/test.dart';
+import 'flow_analysis_mini_ast.dart';
+
main() {
group('API', () {
test('asExpression_end promotes variables', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- h.run((flow) {
- h.declare(x, initialized: true);
- var expr = _Expression();
- flow.variableRead(expr, x);
- flow.asExpression_end(expr, _Type('int'));
- expect(flow.promotedType(x).type, 'int');
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ x.read.as_('int').stmt,
+ checkPromoted(x, 'int'),
+ ]);
});
test('asExpression_end handles other expressions', () {
- var h = _Harness();
- h.run((flow) {
- var expr = _Expression();
- flow.asExpression_end(expr, _Type('int'));
- });
+ var h = Harness();
+ h.run([
+ expr('Object').as_('int').stmt,
+ ]);
});
test('assert_afterCondition promotes', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- h.run((flow) {
- flow.assert_begin();
- var expr = h.eqNull(x, _Type('int?'))();
- flow.assert_afterCondition(expr);
- expect(flow.promotedType(x).type, 'int');
- flow.assert_end();
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ assert_(x.read.eq(nullLiteral),
+ checkPromoted(x, 'int').thenExpr(expr('String'))),
+ ]);
});
test('assert_end joins previous and ifTrue states', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var y = h.addVar('x', 'int?');
- var z = h.addVar('x', 'int?');
- h.assignedVariables((vars) {
- vars.write(x);
- vars.write(z);
- });
- h.run((flow) {
- h.promote(x, 'int');
- h.promote(z, 'int');
- flow.assert_begin();
- flow.write(x, _Type('int?'));
- flow.write(z, _Type('int?'));
- var expr =
- h.and(h.notNull(x, _Type('int?')), h.notNull(y, _Type('int?')))();
- flow.assert_afterCondition(expr);
- flow.assert_end();
+ var h = Harness();
+ var x = Var('x', 'int?');
+ var y = Var('x', 'int?');
+ var z = Var('x', 'int?');
+ h.run([
+ x.read.as_('int').stmt,
+ z.read.as_('int').stmt,
+ assert_(block([
+ x.write(expr('int?')).stmt,
+ z.write(expr('int?')).stmt,
+ ]).thenExpr(x.read.notEq(nullLiteral).and(y.read.notEq(nullLiteral)))),
// x should be promoted because it was promoted before the assert, and
// it is re-promoted within the assert (if it passes)
- expect(flow.promotedType(x).type, 'int');
+ checkPromoted(x, 'int'),
// y should not be promoted because it was not promoted before the
// assert.
- expect(flow.promotedType(y), null);
+ checkNotPromoted(y),
// z should not be promoted because it is demoted in the assert
// condition.
- expect(flow.promotedType(z), null);
- });
+ checkNotPromoted(z),
+ ]);
});
test('conditional_thenBegin promotes true branch', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.conditional_conditionBegin();
- flow.conditional_thenBegin(h.notNull(x, _Type('int?'))());
- expect(flow.promotedType(x).type, 'int');
- flow.conditional_elseBegin(_Expression());
- expect(flow.promotedType(x), isNull);
- flow.conditional_end(_Expression(), _Expression());
- expect(flow.promotedType(x), isNull);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ x.read
+ .notEq(nullLiteral)
+ .conditional(checkPromoted(x, 'int').thenExpr(expr('int')),
+ checkNotPromoted(x).thenExpr(expr('int')))
+ .stmt,
+ checkNotPromoted(x),
+ ]);
});
test('conditional_elseBegin promotes false branch', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.conditional_conditionBegin();
- flow.conditional_thenBegin(h.eqNull(x, _Type('int?'))());
- expect(flow.promotedType(x), isNull);
- flow.conditional_elseBegin(_Expression());
- expect(flow.promotedType(x).type, 'int');
- flow.conditional_end(_Expression(), _Expression());
- expect(flow.promotedType(x), isNull);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ x.read
+ .eq(nullLiteral)
+ .conditional(checkNotPromoted(x).thenExpr(expr('Null')),
+ checkPromoted(x, 'int').thenExpr(expr('Null')))
+ .stmt,
+ checkNotPromoted(x),
+ ]);
});
test('conditional_end keeps promotions common to true and false branches',
() {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var y = h.addVar('y', 'int?');
- var z = h.addVar('z', 'int?');
- h.run((flow) {
- h.declare(x, initialized: true);
- h.declare(y, initialized: true);
- h.declare(z, initialized: true);
- flow.conditional_conditionBegin();
- flow.conditional_thenBegin(_Expression());
- h.promote(x, 'int');
- h.promote(y, 'int');
- flow.conditional_elseBegin(_Expression());
- h.promote(x, 'int');
- h.promote(z, 'int');
- flow.conditional_end(_Expression(), _Expression());
- expect(flow.promotedType(x).type, 'int');
- expect(flow.promotedType(y), isNull);
- expect(flow.promotedType(z), isNull);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ var y = Var('y', 'int?');
+ var z = Var('z', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ declare(y, initialized: true),
+ declare(z, initialized: true),
+ expr('bool')
+ .conditional(
+ block([
+ x.read.as_('int').stmt,
+ y.read.as_('int').stmt,
+ ]).thenExpr(expr('Null')),
+ block([
+ x.read.as_('int').stmt,
+ z.read.as_('int').stmt,
+ ]).thenExpr(expr('Null')))
+ .stmt,
+ checkPromoted(x, 'int'),
+ checkNotPromoted(y),
+ checkNotPromoted(z),
+ ]);
});
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.addVar('x', 'int?');
- var y = h.addVar('y', 'int?');
- var z = h.addVar('z', 'int?');
- h.run((flow) {
- h.declare(x, initialized: true);
- h.declare(y, initialized: true);
- h.declare(z, initialized: true);
- h.if_(
- h.conditional(
- h.expr,
- h.and(h.notNull(x, _Type('int?')), h.notNull(y, _Type('int?'))),
- h.and(
- h.notNull(x, _Type('int?')), h.notNull(z, _Type('int?')))),
- () {
- expect(flow.promotedType(x).type, 'int');
- expect(flow.promotedType(y), isNull);
- expect(flow.promotedType(z), isNull);
- });
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ var y = Var('y', 'int?');
+ var z = Var('z', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ declare(y, initialized: true),
+ declare(z, initialized: true),
+ if_(
+ expr('bool').conditional(
+ x.read.notEq(nullLiteral).and(y.read.notEq(nullLiteral)),
+ x.read.notEq(nullLiteral).and(z.read.notEq(nullLiteral))),
+ [
+ checkPromoted(x, 'int'),
+ checkNotPromoted(y),
+ checkNotPromoted(z),
+ ]),
+ ]);
});
test('conditional joins false states', () {
@@ -156,1087 +143,845 @@
// } else {
// promotes x, but not y or z
// }
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var y = h.addVar('y', 'int?');
- var z = h.addVar('z', 'int?');
- h.run((flow) {
- h.declare(x, initialized: true);
- h.declare(y, initialized: true);
- h.declare(z, initialized: true);
- h.ifElse(
- h.conditional(
- h.expr,
- h.or(h.eqNull(x, _Type('int?')), h.eqNull(y, _Type('int?'))),
- h.or(h.eqNull(x, _Type('int?')), h.eqNull(z, _Type('int?')))),
- () {}, () {
- expect(flow.promotedType(x).type, 'int');
- expect(flow.promotedType(y), isNull);
- expect(flow.promotedType(z), isNull);
- });
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ var y = Var('y', 'int?');
+ var z = Var('z', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ declare(y, initialized: true),
+ declare(z, initialized: true),
+ if_(
+ expr('bool').conditional(
+ x.read.eq(nullLiteral).or(y.read.eq(nullLiteral)),
+ x.read.eq(nullLiteral).or(z.read.eq(nullLiteral))),
+ [],
+ [
+ checkPromoted(x, 'int'),
+ checkNotPromoted(y),
+ checkNotPromoted(z),
+ ]),
+ ]);
});
test('equalityOp(x != null) promotes true branch', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.ifStatement_conditionBegin();
- var varExpr = _Expression();
- flow.variableRead(varExpr, x);
- flow.equalityOp_rightBegin(varExpr, _Type('int?'));
- var nullExpr = _Expression();
- flow.nullLiteral(nullExpr);
- var expr = _Expression();
- flow.equalityOp_end(expr, nullExpr, _Type('Null'), notEqual: true);
- flow.ifStatement_thenBegin(expr);
- expect(flow.isReachable, true);
- expect(flow.promotedType(x).type, 'int');
- flow.ifStatement_elseBegin();
- expect(flow.isReachable, true);
- expect(flow.promotedType(x), isNull);
- flow.ifStatement_end(true);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ if_(x.read.notEq(nullLiteral), [
+ checkReachable(true),
+ checkPromoted(x, 'int'),
+ ], [
+ checkReachable(true),
+ checkNotPromoted(x),
+ ]),
+ ]);
});
test('equalityOp(x != null) when x is non-nullable', () {
- var h = _Harness();
- var x = h.addVar('x', 'int');
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.ifStatement_conditionBegin();
- var varExpr = _Expression();
- flow.variableRead(varExpr, x);
- flow.equalityOp_rightBegin(varExpr, _Type('int'));
- var nullExpr = _Expression();
- flow.nullLiteral(nullExpr);
- var expr = _Expression();
- flow.equalityOp_end(expr, nullExpr, _Type('Null'), notEqual: true);
- flow.ifStatement_thenBegin(expr);
- expect(flow.isReachable, true);
- expect(flow.promotedType(x), isNull);
- flow.ifStatement_elseBegin();
- expect(flow.isReachable, true);
- expect(flow.promotedType(x), isNull);
- flow.ifStatement_end(true);
- });
+ var h = Harness();
+ var x = Var('x', 'int');
+ h.run([
+ declare(x, initialized: true),
+ if_(x.read.notEq(nullLiteral), [
+ checkReachable(true),
+ checkNotPromoted(x),
+ ], [
+ checkReachable(true),
+ checkNotPromoted(x),
+ ])
+ ]);
});
test('equalityOp(<expr> == <expr>) has no special effect', () {
- var h = _Harness();
- h.run((flow) {
- flow.ifStatement_conditionBegin();
- flow.equalityOp_rightBegin(_Expression(), _Type('int?'));
- var expr = _Expression();
- flow.equalityOp_end(expr, _Expression(), _Type('int?'),
- notEqual: false);
- flow.ifStatement_thenBegin(expr);
- expect(flow.isReachable, true);
- flow.ifStatement_elseBegin();
- expect(flow.isReachable, true);
- flow.ifStatement_end(true);
- });
+ var h = Harness();
+ h.run([
+ if_(expr('int?').eq(expr('int?')), [
+ checkReachable(true),
+ ], [
+ checkReachable(true),
+ ]),
+ ]);
});
test('equalityOp(<expr> != <expr>) has no special effect', () {
- var h = _Harness();
- h.run((flow) {
- flow.ifStatement_conditionBegin();
- flow.equalityOp_rightBegin(_Expression(), _Type('int?'));
- var expr = _Expression();
- flow.equalityOp_end(expr, _Expression(), _Type('int?'), notEqual: true);
- flow.ifStatement_thenBegin(expr);
- expect(flow.isReachable, true);
- flow.ifStatement_elseBegin();
- expect(flow.isReachable, true);
- flow.ifStatement_end(true);
- });
+ var h = Harness();
+ h.run([
+ if_(expr('int?').notEq(expr('int?')), [
+ checkReachable(true),
+ ], [
+ checkReachable(true),
+ ]),
+ ]);
});
test('equalityOp(x != <null expr>) does not promote', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.ifStatement_conditionBegin();
- var varExpr = _Expression();
- flow.variableRead(varExpr, x);
- flow.equalityOp_rightBegin(varExpr, _Type('int?'));
- var nullExpr = _Expression();
- var expr = _Expression();
- flow.equalityOp_end(expr, nullExpr, _Type('Null'), notEqual: true);
- flow.ifStatement_thenBegin(expr);
- expect(flow.promotedType(x), isNull);
- flow.ifStatement_elseBegin();
- expect(flow.promotedType(x), isNull);
- flow.ifStatement_end(true);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ if_(x.read.notEq(expr('Null')), [
+ checkNotPromoted(x),
+ ], [
+ checkNotPromoted(x),
+ ]),
+ ]);
});
test('equalityOp(x == null) promotes false branch', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.ifStatement_conditionBegin();
- var varExpr = _Expression();
- flow.variableRead(varExpr, x);
- flow.equalityOp_rightBegin(varExpr, _Type('int?'));
- var nullExpr = _Expression();
- flow.nullLiteral(nullExpr);
- var expr = _Expression();
- flow.equalityOp_end(expr, nullExpr, _Type('Null'), notEqual: false);
- flow.ifStatement_thenBegin(expr);
- expect(flow.isReachable, true);
- expect(flow.promotedType(x), isNull);
- flow.ifStatement_elseBegin();
- expect(flow.isReachable, true);
- expect(flow.promotedType(x).type, 'int');
- flow.ifStatement_end(true);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ if_(x.read.eq(nullLiteral), [
+ checkReachable(true),
+ checkNotPromoted(x),
+ ], [
+ checkReachable(true),
+ checkPromoted(x, 'int'),
+ ]),
+ ]);
});
test('equalityOp(x == null) when x is non-nullable', () {
- var h = _Harness();
- var x = h.addVar('x', 'int');
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.ifStatement_conditionBegin();
- var varExpr = _Expression();
- flow.variableRead(varExpr, x);
- flow.equalityOp_rightBegin(varExpr, _Type('int'));
- var nullExpr = _Expression();
- flow.nullLiteral(nullExpr);
- var expr = _Expression();
- flow.equalityOp_end(expr, nullExpr, _Type('Null'), notEqual: false);
- flow.ifStatement_thenBegin(expr);
- expect(flow.isReachable, true);
- expect(flow.promotedType(x), isNull);
- flow.ifStatement_elseBegin();
- expect(flow.isReachable, true);
- expect(flow.promotedType(x), isNull);
- flow.ifStatement_end(true);
- });
+ var h = Harness();
+ var x = Var('x', 'int');
+ h.run([
+ declare(x, initialized: true),
+ if_(x.read.eq(nullLiteral), [
+ checkReachable(true),
+ checkNotPromoted(x),
+ ], [
+ checkReachable(true),
+ checkNotPromoted(x),
+ ])
+ ]);
});
test('equalityOp(null != x) promotes true branch', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.ifStatement_conditionBegin();
- var nullExpr = _Expression();
- flow.nullLiteral(nullExpr);
- flow.equalityOp_rightBegin(nullExpr, _Type('Null'));
- var varExpr = _Expression();
- flow.variableRead(varExpr, x);
- var expr = _Expression();
- flow.equalityOp_end(expr, varExpr, _Type('int?'), notEqual: true);
- flow.ifStatement_thenBegin(expr);
- expect(flow.promotedType(x).type, 'int');
- flow.ifStatement_elseBegin();
- expect(flow.promotedType(x), isNull);
- flow.ifStatement_end(true);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ if_(nullLiteral.notEq(x.read), [
+ checkPromoted(x, 'int'),
+ ], [
+ checkNotPromoted(x),
+ ]),
+ ]);
});
test('equalityOp(<null expr> != x) does not promote', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.ifStatement_conditionBegin();
- var nullExpr = _Expression();
- flow.equalityOp_rightBegin(nullExpr, _Type('Null'));
- var varExpr = _Expression();
- flow.variableRead(varExpr, x);
- var expr = _Expression();
- flow.equalityOp_end(expr, varExpr, _Type('int?'), notEqual: true);
- flow.ifStatement_thenBegin(expr);
- expect(flow.promotedType(x), isNull);
- flow.ifStatement_elseBegin();
- expect(flow.promotedType(x), isNull);
- flow.ifStatement_end(true);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ if_(expr('Null').notEq(x.read), [
+ checkNotPromoted(x),
+ ], [
+ checkNotPromoted(x),
+ ]),
+ ]);
});
test('equalityOp(null == x) promotes false branch', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.ifStatement_conditionBegin();
- var nullExpr = _Expression();
- flow.nullLiteral(nullExpr);
- flow.equalityOp_rightBegin(nullExpr, _Type('Null'));
- var varExpr = _Expression();
- flow.variableRead(varExpr, x);
- var expr = _Expression();
- flow.equalityOp_end(expr, varExpr, _Type('int?'), notEqual: false);
- flow.ifStatement_thenBegin(expr);
- expect(flow.promotedType(x), isNull);
- flow.ifStatement_elseBegin();
- expect(flow.promotedType(x).type, 'int');
- flow.ifStatement_end(true);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ if_(nullLiteral.eq(x.read), [
+ checkNotPromoted(x),
+ ], [
+ checkPromoted(x, 'int'),
+ ]),
+ ]);
});
test('equalityOp(null == null) equivalent to true', () {
- var h = _Harness();
- h.run((flow) {
- flow.ifStatement_conditionBegin();
- var null1 = _Expression();
- flow.equalityOp_rightBegin(null1, _Type('Null'));
- var null2 = _Expression();
- var expr = _Expression();
- flow.equalityOp_end(expr, null2, _Type('Null'));
- flow.ifStatement_thenBegin(expr);
- expect(flow.isReachable, true);
- flow.ifStatement_elseBegin();
- expect(flow.isReachable, false);
- flow.ifStatement_end(true);
- });
+ var h = Harness();
+ h.run([
+ if_(expr('Null').eq(expr('Null')), [
+ checkReachable(true),
+ ], [
+ checkReachable(false),
+ ]),
+ ]);
});
test('equalityOp(null != null) equivalent to false', () {
- var h = _Harness();
- h.run((flow) {
- flow.ifStatement_conditionBegin();
- var null1 = _Expression();
- flow.equalityOp_rightBegin(null1, _Type('Null'));
- var null2 = _Expression();
- var expr = _Expression();
- flow.equalityOp_end(expr, null2, _Type('Null'), notEqual: true);
- flow.ifStatement_thenBegin(expr);
- expect(flow.isReachable, false);
- flow.ifStatement_elseBegin();
- expect(flow.isReachable, true);
- flow.ifStatement_end(true);
- });
+ var h = Harness();
+ h.run([
+ if_(expr('Null').notEq(expr('Null')), [
+ checkReachable(false),
+ ], [
+ checkReachable(true),
+ ]),
+ ]);
});
test('equalityOp(null == non-null) is not equivalent to false', () {
- var h = _Harness();
- h.run((flow) {
- flow.ifStatement_conditionBegin();
- var null1 = _Expression();
- flow.equalityOp_rightBegin(null1, _Type('Null'));
- var null2 = _Expression();
- var expr = _Expression();
- flow.equalityOp_end(expr, null2, _Type('int'));
- flow.ifStatement_thenBegin(expr);
- expect(flow.isReachable, true);
- flow.ifStatement_elseBegin();
- expect(flow.isReachable, true);
- flow.ifStatement_end(true);
- });
+ var h = Harness();
+ h.run([
+ if_(expr('Null').eq(expr('int')), [
+ checkReachable(true),
+ ], [
+ checkReachable(true),
+ ]),
+ ]);
});
test('equalityOp(null != non-null) is not equivalent to true', () {
- var h = _Harness();
- h.run((flow) {
- flow.ifStatement_conditionBegin();
- var null1 = _Expression();
- flow.equalityOp_rightBegin(null1, _Type('Null'));
- var null2 = _Expression();
- var expr = _Expression();
- flow.equalityOp_end(expr, null2, _Type('int'), notEqual: true);
- flow.ifStatement_thenBegin(expr);
- expect(flow.isReachable, true);
- flow.ifStatement_elseBegin();
- expect(flow.isReachable, true);
- flow.ifStatement_end(true);
- });
+ var h = Harness();
+ h.run([
+ if_(expr('Null').notEq(expr('int')), [
+ checkReachable(true),
+ ], [
+ checkReachable(true),
+ ]),
+ ]);
});
test('equalityOp(non-null == null) is not equivalent to false', () {
- var h = _Harness();
- h.run((flow) {
- flow.ifStatement_conditionBegin();
- var null1 = _Expression();
- flow.equalityOp_rightBegin(null1, _Type('int'));
- var null2 = _Expression();
- var expr = _Expression();
- flow.equalityOp_end(expr, null2, _Type('Null'));
- flow.ifStatement_thenBegin(expr);
- expect(flow.isReachable, true);
- flow.ifStatement_elseBegin();
- expect(flow.isReachable, true);
- flow.ifStatement_end(true);
- });
+ var h = Harness();
+ h.run([
+ if_(expr('int').eq(expr('Null')), [
+ checkReachable(true),
+ ], [
+ checkReachable(true),
+ ]),
+ ]);
});
test('equalityOp(non-null != null) is not equivalent to true', () {
- var h = _Harness();
- h.run((flow) {
- flow.ifStatement_conditionBegin();
- var null1 = _Expression();
- flow.equalityOp_rightBegin(null1, _Type('int'));
- var null2 = _Expression();
- var expr = _Expression();
- flow.equalityOp_end(expr, null2, _Type('Null'), notEqual: true);
- flow.ifStatement_thenBegin(expr);
- expect(flow.isReachable, true);
- flow.ifStatement_elseBegin();
- expect(flow.isReachable, true);
- flow.ifStatement_end(true);
- });
+ var h = Harness();
+ h.run([
+ if_(expr('int').notEq(expr('Null')), [
+ checkReachable(true),
+ ], [
+ checkReachable(true),
+ ]),
+ ]);
});
test('conditionEqNull() does not promote write-captured vars', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var functionNode = _Node();
- h.assignedVariables(
- (vars) => vars.function(functionNode, () => vars.write(x)));
- h.run((flow) {
- h.declare(x, initialized: true);
- h.if_(h.notNull(x, _Type('int?')), () {
- expect(flow.promotedType(x).type, 'int');
- });
- h.function(functionNode, () {
- flow.write(x, _Type('int?'));
- });
- h.if_(h.notNull(x, _Type('int?')), () {
- expect(flow.promotedType(x), isNull);
- });
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ if_(x.read.notEq(nullLiteral), [
+ checkPromoted(x, 'int'),
+ ]),
+ localFunction([
+ x.write(expr('int?')).stmt,
+ ]),
+ if_(x.read.notEq(nullLiteral), [
+ checkNotPromoted(x),
+ ]),
+ ]);
});
test('doStatement_bodyBegin() un-promotes', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var doStatement = _Statement();
- h.assignedVariables(
- (vars) => vars.nest(doStatement, () => vars.write(x)));
- h.run((flow) {
- h.declare(x, initialized: true);
- h.promote(x, 'int');
- expect(flow.promotedType(x).type, 'int');
- flow.doStatement_bodyBegin(doStatement);
- expect(flow.promotedType(x), isNull);
- flow.doStatement_conditionBegin();
- flow.doStatement_end(_Expression());
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ x.read.as_('int').stmt,
+ checkPromoted(x, 'int'),
+ branchTarget((t) => do_([
+ checkNotPromoted(x),
+ x.write(expr('Null')).stmt,
+ ], expr('bool'))),
+ ]);
});
test('doStatement_bodyBegin() handles write captures in the loop', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var doStatement = _Statement();
- var functionNode = _Node();
- h.assignedVariables((vars) => vars.nest(
- doStatement, () => vars.function(functionNode, () => vars.write(x))));
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.doStatement_bodyBegin(doStatement);
- h.promote(x, 'int');
- // The promotion should have no effect, because the second time through
- // the loop, x has been write-captured.
- expect(flow.promotedType(x), isNull);
- h.function(functionNode, () {
- flow.write(x, _Type('int?'));
- });
- flow.doStatement_conditionBegin();
- flow.doStatement_end(_Expression());
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ do_([
+ x.read.as_('int').stmt,
+ // The promotion should have no effect, because the second time
+ // through the loop, x has been write-captured.
+ checkNotPromoted(x),
+ localFunction([
+ x.write(expr('int?')).stmt,
+ ]),
+ ], expr('bool')),
+ ]);
});
test('doStatement_conditionBegin() joins continue state', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var stmt = _Statement();
- h.assignedVariables((vars) => vars.nest(stmt, () {}));
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.doStatement_bodyBegin(stmt);
- h.if_(h.notNull(x, _Type('int?')), () {
- flow.handleContinue(stmt);
- });
- flow.handleExit();
- expect(flow.isReachable, false);
- expect(flow.promotedType(x), isNull);
- flow.doStatement_conditionBegin();
- expect(flow.isReachable, true);
- expect(flow.promotedType(x).type, 'int');
- flow.doStatement_end(_Expression());
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ branchTarget((t) => do_(
+ [
+ if_(x.read.notEq(nullLiteral), [
+ continue_(t),
+ ]),
+ return_(),
+ checkReachable(false),
+ checkNotPromoted(x),
+ ],
+ block([
+ checkReachable(true),
+ checkPromoted(x, 'int'),
+ ]).thenExpr(expr('bool')))),
+ ]);
});
test('doStatement_end() promotes', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var stmt = _Statement();
- h.assignedVariables((vars) => vars.nest(stmt, () {}));
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.doStatement_bodyBegin(stmt);
- flow.doStatement_conditionBegin();
- expect(flow.promotedType(x), isNull);
- flow.doStatement_end(h.eqNull(x, _Type('int?'))());
- expect(flow.promotedType(x).type, 'int');
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ branchTarget((t) =>
+ do_([], checkNotPromoted(x).thenExpr(x.read.eq(nullLiteral)))),
+ checkPromoted(x, 'int'),
+ ]);
});
test('finish checks proper nesting', () {
- var h = _Harness();
- var expr = _Expression();
- var flow = h.createFlow();
+ var h = Harness();
+ var e = expr('Null');
+ var flow = FlowAnalysis<Node, Statement, Expression, Var, Type>(
+ h, AssignedVariables<Node, Var>());
flow.ifStatement_conditionBegin();
- flow.ifStatement_thenBegin(expr);
+ flow.ifStatement_thenBegin(e);
expect(() => flow.finish(), _asserts);
});
test('for_conditionBegin() un-promotes', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var forStatement = _Statement();
- h.assignedVariables(
- (vars) => vars.nest(forStatement, () => vars.write(x)));
- h.run((flow) {
- h.declare(x, initialized: true);
- h.promote(x, 'int');
- expect(flow.promotedType(x).type, 'int');
- flow.for_conditionBegin(forStatement);
- expect(flow.promotedType(x), isNull);
- flow.for_bodyBegin(_Statement(), _Expression());
- flow.write(x, _Type('int?'));
- flow.for_updaterBegin();
- flow.for_end();
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ x.read.as_('int').stmt,
+ checkPromoted(x, 'int'),
+ for_(null, checkNotPromoted(x).thenExpr(expr('bool')), null, [
+ x.write(expr('int?')).stmt,
+ ]),
+ ]);
});
test('for_conditionBegin() handles write captures in the loop', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var forStatement = _Statement();
- var functionNode = _Node();
- h.assignedVariables((vars) => vars.nest(forStatement,
- () => vars.function(functionNode, () => vars.write(x))));
- h.run((flow) {
- h.declare(x, initialized: true);
- h.promote(x, 'int');
- expect(flow.promotedType(x).type, 'int');
- flow.for_conditionBegin(forStatement);
- h.promote(x, 'int');
- expect(flow.promotedType(x), isNull);
- h.function(functionNode, () {
- flow.write(x, _Type('int?'));
- });
- flow.for_bodyBegin(_Statement(), _Expression());
- flow.for_updaterBegin();
- flow.for_end();
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ x.read.as_('int').stmt,
+ checkPromoted(x, 'int'),
+ for_(
+ null,
+ block([
+ x.read.as_('int').stmt,
+ checkNotPromoted(x),
+ localFunction([
+ x.write(expr('int?')).stmt,
+ ]),
+ ]).thenExpr(expr('bool')),
+ null,
+ []),
+ ]);
});
test('for_conditionBegin() handles not-yet-seen variables', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var y = h.addVar('y', 'int?');
- var forStatement = _Statement();
- h.assignedVariables(
- (vars) => vars.nest(forStatement, () => vars.write(x)));
- h.run((flow) {
- h.declare(y, initialized: true);
- h.promote(y, 'int');
- flow.for_conditionBegin(forStatement);
- flow.declare(x, true);
- flow.for_bodyBegin(_Statement(), _Expression());
- flow.for_updaterBegin();
- flow.for_end();
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ var y = Var('y', 'int?');
+ h.run([
+ declare(y, initialized: true),
+ y.read.as_('int').stmt,
+ for_(null, declare(x, initialized: true).thenExpr(expr('bool')), null, [
+ x.write(expr('Null')).stmt,
+ ]),
+ ]);
});
test('for_bodyBegin() handles empty condition', () {
- var h = _Harness();
- var stmt = _Statement();
- h.assignedVariables((vars) => vars.nest(stmt, () {}));
- h.run((flow) {
- flow.for_conditionBegin(stmt);
- flow.for_bodyBegin(stmt, null);
- flow.for_updaterBegin();
- expect(flow.isReachable, isTrue);
- flow.for_end();
- expect(flow.isReachable, isFalse);
- });
+ var h = Harness();
+ h.run([
+ for_(null, null, checkReachable(true).thenExpr(expr('Null')), []),
+ checkReachable(false),
+ ]);
});
test('for_bodyBegin() promotes', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var stmt = _Statement();
- h.assignedVariables((vars) => vars.nest(stmt, () {}));
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.for_conditionBegin(stmt);
- flow.for_bodyBegin(stmt, h.notNull(x, _Type('int?'))());
- expect(flow.promotedType(x).type, 'int');
- flow.for_updaterBegin();
- flow.for_end();
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ for_(declare(x, initialized: true), x.read.notEq(nullLiteral), null, [
+ checkPromoted(x, 'int'),
+ ]),
+ ]);
});
test('for_bodyBegin() can be used with a null statement', () {
// This is needed for collection elements that are for-loops.
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var node = _Node();
- h.assignedVariables((vars) => vars.nest(node, () {}));
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.for_conditionBegin(node);
- flow.for_bodyBegin(null, h.notNull(x, _Type('int?'))());
- flow.for_updaterBegin();
- flow.for_end();
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ for_(declare(x, initialized: true), x.read.notEq(nullLiteral), null, [],
+ forCollection: true),
+ ]);
});
test('for_updaterBegin() joins current and continue states', () {
// To test that the states are properly joined, we have three variables:
// x, y, and z. We promote x and y in the continue path, and x and z in
// the current path. Inside the updater, only x should be promoted.
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var y = h.addVar('y', 'int?');
- var z = h.addVar('z', 'int?');
- var stmt = _Statement();
- h.assignedVariables((vars) => vars.nest(stmt, () {}));
- h.run((flow) {
- h.declare(x, initialized: true);
- h.declare(y, initialized: true);
- h.declare(z, initialized: true);
- flow.for_conditionBegin(stmt);
- flow.for_bodyBegin(stmt, h.expr());
- h.if_(h.expr, () {
- h.promote(x, 'int');
- h.promote(y, 'int');
- flow.handleContinue(stmt);
- });
- h.promote(x, 'int');
- h.promote(z, 'int');
- flow.for_updaterBegin();
- expect(flow.promotedType(x).type, 'int');
- expect(flow.promotedType(y), isNull);
- expect(flow.promotedType(z), isNull);
- flow.for_end();
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ var y = Var('y', 'int?');
+ var z = Var('z', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ declare(y, initialized: true),
+ declare(z, initialized: true),
+ branchTarget((t) => for_(
+ null,
+ expr('bool'),
+ block([
+ checkPromoted(x, 'int'),
+ checkNotPromoted(y),
+ checkNotPromoted(z),
+ ]).thenExpr(expr('Null')),
+ [
+ if_(expr('bool'), [
+ x.read.as_('int').stmt,
+ y.read.as_('int').stmt,
+ continue_(t),
+ ]),
+ x.read.as_('int').stmt,
+ z.read.as_('int').stmt,
+ ])),
+ ]);
});
test('for_end() joins break and condition-false states', () {
// To test that the states are properly joined, we have three variables:
// x, y, and z. We promote x and y in the break path, and x and z in the
// condition-false path. After the loop, only x should be promoted.
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var y = h.addVar('y', 'int?');
- var z = h.addVar('z', 'int?');
- var stmt = _Statement();
- h.assignedVariables((vars) => vars.nest(stmt, () {}));
- h.run((flow) {
- h.declare(x, initialized: true);
- h.declare(y, initialized: true);
- h.declare(z, initialized: true);
- flow.for_conditionBegin(stmt);
- flow.for_bodyBegin(stmt,
- h.or(h.eqNull(x, _Type('int?')), h.eqNull(z, _Type('int?')))());
- h.if_(h.expr, () {
- h.promote(x, 'int');
- h.promote(y, 'int');
- flow.handleBreak(stmt);
- });
- flow.for_updaterBegin();
- flow.for_end();
- expect(flow.promotedType(x).type, 'int');
- expect(flow.promotedType(y), isNull);
- expect(flow.promotedType(z), isNull);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ var y = Var('y', 'int?');
+ var z = Var('z', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ declare(y, initialized: true),
+ declare(z, initialized: true),
+ branchTarget((t) => for_(
+ null, x.read.eq(nullLiteral).or(z.read.eq(nullLiteral)), null, [
+ if_(expr('bool'), [
+ x.read.as_('int').stmt,
+ y.read.as_('int').stmt,
+ break_(t),
+ ]),
+ ])),
+ checkPromoted(x, 'int'),
+ checkNotPromoted(y),
+ checkNotPromoted(z),
+ ]);
});
test('forEach_bodyBegin() un-promotes', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var forStatement = _Statement();
- h.assignedVariables(
- (vars) => vars.nest(forStatement, () => vars.write(x)));
- h.run((flow) {
- h.declare(x, initialized: true);
- h.promote(x, 'int');
- expect(flow.promotedType(x).type, 'int');
- flow.forEach_bodyBegin(forStatement, null, _Type('int?'));
- expect(flow.promotedType(x), isNull);
- flow.write(x, _Type('int?'));
- flow.forEach_end();
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ x.read.as_('int').stmt,
+ checkPromoted(x, 'int'),
+ forEachWithNonVariable(expr('List<int?>'), [
+ checkNotPromoted(x),
+ x.write(expr('int?')).stmt,
+ ]),
+ ]);
});
test('forEach_bodyBegin() handles write captures in the loop', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var forStatement = _Statement();
- var functionNode = _Node();
- h.assignedVariables((vars) => vars.nest(forStatement,
- () => vars.function(functionNode, () => vars.write(x))));
- h.run((flow) {
- h.declare(x, initialized: true);
- h.promote(x, 'int');
- expect(flow.promotedType(x).type, 'int');
- flow.forEach_bodyBegin(forStatement, null, _Type('int?'));
- h.promote(x, 'int');
- expect(flow.promotedType(x), isNull);
- h.function(functionNode, () {
- flow.write(x, _Type('int?'));
- });
- flow.forEach_end();
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ x.read.as_('int').stmt,
+ checkPromoted(x, 'int'),
+ forEachWithNonVariable(expr('List<int?>'), [
+ x.read.as_('int').stmt,
+ checkNotPromoted(x),
+ localFunction([
+ x.write(expr('int?')).stmt,
+ ]),
+ ]),
+ ]);
});
test('forEach_bodyBegin() writes to loop variable', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var forStatement = _Statement();
- h.assignedVariables(
- (vars) => vars.nest(forStatement, () => vars.write(x)));
- h.run((flow) {
- h.declare(x, initialized: false);
- expect(flow.isAssigned(x), false);
- flow.forEach_bodyBegin(forStatement, x, _Type('int?'));
- expect(flow.isAssigned(x), true);
- flow.forEach_end();
- expect(flow.isAssigned(x), false);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: false),
+ checkAssigned(x, false),
+ forEachWithVariableSet(x, expr('List<int?>'), [
+ checkAssigned(x, true),
+ ]),
+ checkAssigned(x, false),
+ ]);
});
test('forEach_bodyBegin() pushes conservative join state', () {
- var h = _Harness();
- var x = h.addVar('x', 'int');
- var forStatement = _Statement();
- h.assignedVariables(
- (vars) => vars.nest(forStatement, () => vars.write(x)));
- h.run((flow) {
- h.declare(x, initialized: false);
- expect(flow.isUnassigned(x), true);
- flow.forEach_bodyBegin(forStatement, null, _Type('int'));
- // Since a write to x occurs somewhere in the loop, x should no longer
- // be considered unassigned.
- expect(flow.isUnassigned(x), false);
- flow.handleBreak(forStatement);
- flow.write(x, _Type('int'));
- flow.forEach_end();
+ var h = Harness();
+ var x = Var('x', 'int');
+ h.run([
+ declare(x, initialized: false),
+ checkUnassigned(x, true),
+ branchTarget((t) => forEachWithNonVariable(expr('List<int>'), [
+ // Since a write to x occurs somewhere in the loop, x should no
+ // longer be considered unassigned.
+ checkUnassigned(x, false),
+ break_(t), x.write(expr('int')).stmt,
+ ])),
// Even though the write to x is unreachable (since it occurs after a
// break), x should still be considered "possibly assigned" because of
// the conservative join done at the top of the loop.
- expect(flow.isUnassigned(x), false);
- });
+ checkUnassigned(x, false),
+ ]);
});
test('forEach_end() restores state before loop', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var stmt = _Statement();
- h.assignedVariables((vars) => vars.nest(stmt, () {}));
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.forEach_bodyBegin(stmt, null, _Type('int?'));
- h.promote(x, 'int');
- expect(flow.promotedType(x).type, 'int');
- flow.forEach_end();
- expect(flow.promotedType(x), isNull);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ forEachWithNonVariable(expr('List<int?>'), [
+ x.read.as_('int').stmt,
+ checkPromoted(x, 'int'),
+ ]),
+ checkNotPromoted(x),
+ ]);
});
test('functionExpression_begin() cancels promotions of self-captured vars',
() {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var y = h.addVar('y', 'int?');
- var functionNode = _Node();
- h.assignedVariables(
- (vars) => vars.function(functionNode, () => vars.write(x)));
- h.run((flow) {
- h.declare(x, initialized: true);
- h.declare(y, initialized: true);
- h.promote(x, 'int');
- h.promote(y, 'int');
- expect(flow.promotedType(x).type, 'int');
- expect(flow.promotedType(y).type, 'int');
- flow.functionExpression_begin(functionNode);
- // x is unpromoted within the local function
- expect(flow.promotedType(x), isNull);
- expect(flow.promotedType(y).type, 'int');
- flow.write(x, _Type('int?'));
- h.promote(x, 'int');
- flow.functionExpression_end();
+ var h = Harness();
+ var x = Var('x', 'int?');
+ var y = Var('y', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ declare(y, initialized: true),
+ x.read.as_('int').stmt,
+ y.read.as_('int').stmt,
+ checkPromoted(x, 'int'),
+ checkPromoted(y, 'int'),
+ localFunction([
+ // x is unpromoted within the local function
+ checkNotPromoted(x), checkPromoted(y, 'int'),
+ x.write(expr('int?')).stmt, x.read.as_('int').stmt,
+ ]),
// x is unpromoted after the local function too
- expect(flow.promotedType(x), isNull);
- expect(flow.promotedType(y).type, 'int');
- });
+ checkNotPromoted(x), checkPromoted(y, 'int'),
+ ]);
});
test('functionExpression_begin() cancels promotions of other-captured vars',
() {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var y = h.addVar('y', 'int?');
- var functionNode1 = _Node();
- var functionNode2 = _Node();
- h.assignedVariables((vars) {
- vars.function(functionNode1, () {});
- vars.function(functionNode2, () => vars.write(x));
- });
- h.run((flow) {
- h.declare(x, initialized: true);
- h.declare(y, initialized: true);
- h.promote(x, 'int');
- h.promote(y, 'int');
- expect(flow.promotedType(x).type, 'int');
- expect(flow.promotedType(y).type, 'int');
- flow.functionExpression_begin(functionNode1);
- // x is unpromoted within the local function, because the write
- // might have been captured by the time the local function executes.
- expect(flow.promotedType(x), isNull);
- expect(flow.promotedType(y).type, 'int');
- // And any effort to promote x fails, because there is no way of knowing
- // when the captured write might occur.
- h.promote(x, 'int');
- expect(flow.promotedType(x), isNull);
- expect(flow.promotedType(y).type, 'int');
- flow.functionExpression_end();
+ var h = Harness();
+ var x = Var('x', 'int?');
+ var y = Var('y', 'int?');
+ h.run([
+ declare(x, initialized: true), declare(y, initialized: true),
+ x.read.as_('int').stmt, y.read.as_('int').stmt,
+ checkPromoted(x, 'int'), checkPromoted(y, 'int'),
+ localFunction([
+ // x is unpromoted within the local function, because the write
+ // might have been captured by the time the local function executes.
+ checkNotPromoted(x), checkPromoted(y, 'int'),
+ // And any effort to promote x fails, because there is no way of
+ // knowing when the captured write might occur.
+ x.read.as_('int').stmt,
+ checkNotPromoted(x), checkPromoted(y, 'int'),
+ ]),
// x is still promoted after the local function, though, because the
// write hasn't been captured yet.
- expect(flow.promotedType(x).type, 'int');
- expect(flow.promotedType(y).type, 'int');
- flow.functionExpression_begin(functionNode2);
- // x is unpromoted inside this local function too.
- expect(flow.promotedType(x), isNull);
- expect(flow.promotedType(y).type, 'int');
- flow.write(x, _Type('int?'));
- flow.functionExpression_end();
+ checkPromoted(x, 'int'), checkPromoted(y, 'int'),
+ localFunction([
+ // x is unpromoted inside this local function too.
+ checkNotPromoted(x), checkPromoted(y, 'int'),
+ x.write(expr('int?')).stmt,
+ ]),
// And since the second local function captured x, it remains
// unpromoted.
- expect(flow.promotedType(x), isNull);
- expect(flow.promotedType(y).type, 'int');
- });
+ checkNotPromoted(x), checkPromoted(y, 'int'),
+ ]);
});
test('functionExpression_begin() cancels promotions of written vars', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var y = h.addVar('y', 'int?');
- var node = _Node();
- h.assignedVariables((vars) {
- vars.function(node, () {});
- vars.write(x);
- });
- h.run((flow) {
- h.declare(x, initialized: true);
- h.declare(y, initialized: true);
- h.promote(x, 'int');
- h.promote(y, 'int');
- expect(flow.promotedType(x).type, 'int');
- expect(flow.promotedType(y).type, 'int');
- flow.functionExpression_begin(node);
- // x is unpromoted within the local function, because the write
- // might have happened by the time the local function executes.
- expect(flow.promotedType(x), isNull);
- expect(flow.promotedType(y).type, 'int');
- // But it can be re-promoted because the write isn't captured.
- h.promote(x, 'int');
- expect(flow.promotedType(x).type, 'int');
- expect(flow.promotedType(y).type, 'int');
- flow.functionExpression_end();
+ var h = Harness();
+ var x = Var('x', 'int?');
+ var y = Var('y', 'int?');
+ h.run([
+ declare(x, initialized: true), declare(y, initialized: true),
+ x.read.as_('int').stmt, y.read.as_('int').stmt,
+ checkPromoted(x, 'int'), checkPromoted(y, 'int'),
+ localFunction([
+ // x is unpromoted within the local function, because the write
+ // might have happened by the time the local function executes.
+ checkNotPromoted(x), checkPromoted(y, 'int'),
+ // But it can be re-promoted because the write isn't captured.
+ x.read.as_('int').stmt,
+ checkPromoted(x, 'int'), checkPromoted(y, 'int'),
+ ]),
// x is still promoted after the local function, though, because the
// write hasn't occurred yet.
- expect(flow.promotedType(x).type, 'int');
- expect(flow.promotedType(y).type, 'int');
- flow.write(x, _Type('int?'));
+ checkPromoted(x, 'int'), checkPromoted(y, 'int'),
+ x.write(expr('int?')).stmt,
// x is unpromoted now.
- expect(flow.promotedType(x), isNull);
- expect(flow.promotedType(y).type, 'int');
- });
+ checkNotPromoted(x), checkPromoted(y, 'int'),
+ ]);
});
test('functionExpression_begin() handles not-yet-seen variables', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var functionNode = _Node();
- h.assignedVariables(
- (vars) => vars.function(functionNode, () => vars.write(x)));
- h.run((flow) {
- flow.functionExpression_begin(functionNode);
- flow.functionExpression_end();
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ localFunction([]),
// x is declared after the local function, so the local function
// cannot possibly write to x.
- h.declare(x, initialized: true);
- h.promote(x, 'int');
- expect(flow.promotedType(x).type, 'int');
- });
+ declare(x, initialized: true), x.read.as_('int').stmt,
+ checkPromoted(x, 'int'), x.write(expr('Null')).stmt,
+ ]);
});
test('functionExpression_begin() handles not-yet-seen write-captured vars',
() {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var y = h.addVar('y', 'int?');
- var functionNode1 = _Node();
- var functionNode2 = _Node();
- h.assignedVariables((vars) {
- vars.function(functionNode1, () {});
- vars.function(functionNode2, () => vars.write(x));
- });
- h.run((flow) {
- h.declare(y, initialized: true);
- h.promote(y, 'int');
- flow.functionExpression_begin(functionNode1);
- h.promote(x, 'int');
- // Promotion should not occur, because x might be write-captured by the
- // time this code is reached.
- expect(flow.promotedType(x), isNull);
- flow.functionExpression_end();
- flow.functionExpression_begin(functionNode2);
- h.declare(x, initialized: true);
- flow.functionExpression_end();
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ var y = Var('y', 'int?');
+ h.run([
+ declare(y, initialized: true),
+ y.read.as_('int').stmt,
+ localFunction([
+ x.read.as_('int').stmt,
+ // Promotion should not occur, because x might be write-captured by
+ // the time this code is reached.
+ checkNotPromoted(x),
+ ]),
+ localFunction([
+ declare(x, initialized: true),
+ x.write(expr('Null')).stmt,
+ ]),
+ ]);
});
test(
'functionExpression_end does not propagate "definitely unassigned" '
'data', () {
- var h = _Harness();
- var x = h.addVar('x', 'int');
- var functionNode = _Node();
- h.assignedVariables((vars) {
- vars.function(functionNode, () {});
- vars.write(x);
- });
- h.run((flow) {
- flow.declare(x, false);
- expect(flow.isUnassigned(x), true);
- flow.functionExpression_begin(functionNode);
- // The function expression could be called at any time, so x might be
- // assigned now.
- expect(flow.isUnassigned(x), false);
- flow.functionExpression_end();
+ var h = Harness();
+ var x = Var('x', 'int');
+ h.run([
+ declare(x, initialized: false),
+ checkUnassigned(x, true),
+ localFunction([
+ // The function expression could be called at any time, so x might
+ // be assigned now.
+ checkUnassigned(x, false),
+ ]),
// But now that we are back outside the function expression, we once
// again know that x is unassigned.
- expect(flow.isUnassigned(x), true);
- flow.write(x, _Type('int'));
- expect(flow.isUnassigned(x), false);
- });
+ checkUnassigned(x, true),
+ x.write(expr('int')).stmt,
+ checkUnassigned(x, false),
+ ]);
});
test('handleBreak handles deep nesting', () {
- var h = _Harness();
- var whileStatement = _Statement();
- h.assignedVariables((vars) {
- vars.nest(whileStatement, () {});
- });
- h.run((flow) {
- flow.whileStatement_conditionBegin(whileStatement);
- flow.whileStatement_bodyBegin(whileStatement, h.booleanLiteral(true)());
- h.if_(h.expr, () {
- h.if_(h.expr, () {
- flow.handleBreak(whileStatement);
- });
- });
- flow.handleExit();
- expect(flow.isReachable, false);
- flow.whileStatement_end();
- expect(flow.isReachable, true);
- });
+ var h = Harness();
+ h.run([
+ branchTarget((t) => while_(booleanLiteral(true), [
+ if_(expr('bool'), [
+ if_(expr('bool'), [
+ break_(t),
+ ]),
+ ]),
+ return_(),
+ checkReachable(false),
+ ])),
+ checkReachable(true),
+ ]);
});
test('handleBreak handles mixed nesting', () {
- var h = _Harness();
- var whileStatement = _Statement();
- h.assignedVariables((vars) {
- vars.nest(whileStatement, () {});
- });
- h.run((flow) {
- flow.whileStatement_conditionBegin(whileStatement);
- flow.whileStatement_bodyBegin(whileStatement, h.booleanLiteral(true)());
- h.if_(h.expr, () {
- h.if_(h.expr, () {
- flow.handleBreak(whileStatement);
- });
- flow.handleBreak(whileStatement);
- });
- flow.handleBreak(whileStatement);
- expect(flow.isReachable, false);
- flow.whileStatement_end();
- expect(flow.isReachable, true);
- });
+ var h = Harness();
+ h.run([
+ branchTarget((t) => while_(booleanLiteral(true), [
+ if_(expr('bool'), [
+ if_(expr('bool'), [
+ break_(t),
+ ]),
+ break_(t),
+ ]),
+ break_(t),
+ checkReachable(false),
+ ])),
+ checkReachable(true),
+ ]);
});
test('handleContinue handles deep nesting', () {
- var h = _Harness();
- var doStatement = _Statement();
- h.assignedVariables((vars) {
- vars.nest(doStatement, () {});
- });
- h.run((flow) {
- flow.doStatement_bodyBegin(doStatement);
- h.if_(h.expr, () {
- h.if_(h.expr, () {
- flow.handleContinue(doStatement);
- });
- });
- flow.handleExit();
- expect(flow.isReachable, false);
- flow.doStatement_conditionBegin();
- expect(flow.isReachable, true);
- flow.doStatement_end(h.booleanLiteral(true)());
- expect(flow.isReachable, false);
- });
+ var h = Harness();
+ h.run([
+ branchTarget((t) => do_([
+ if_(expr('bool'), [
+ if_(expr('bool'), [
+ continue_(t),
+ ]),
+ ]),
+ return_(),
+ checkReachable(false),
+ ], checkReachable(true).thenExpr(booleanLiteral(true)))),
+ checkReachable(false),
+ ]);
});
test('handleContinue handles mixed nesting', () {
- var h = _Harness();
- var doStatement = _Statement();
- h.assignedVariables((vars) {
- vars.nest(doStatement, () {});
- });
- h.run((flow) {
- flow.doStatement_bodyBegin(doStatement);
- h.if_(h.expr, () {
- h.if_(h.expr, () {
- flow.handleContinue(doStatement);
- });
- flow.handleContinue(doStatement);
- });
- flow.handleContinue(doStatement);
- expect(flow.isReachable, false);
- flow.doStatement_conditionBegin();
- expect(flow.isReachable, true);
- flow.doStatement_end(h.booleanLiteral(true)());
- expect(flow.isReachable, false);
- });
+ var h = Harness();
+ h.run([
+ branchTarget((t) => do_([
+ if_(expr('bool'), [
+ if_(expr('bool'), [
+ continue_(t),
+ ]),
+ continue_(t),
+ ]),
+ continue_(t),
+ checkReachable(false),
+ ], checkReachable(true).thenExpr(booleanLiteral(true)))),
+ checkReachable(false),
+ ]);
});
test('ifNullExpression allows ensure guarding', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- h.assignedVariables((vars) => vars.write(x));
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.ifNullExpression_rightBegin(h.variableRead(x)(), _Type('int?'));
- expect(flow.isReachable, true);
- flow.write(x, _Type('int'));
- expect(flow.promotedType(x).type, 'int');
- flow.ifNullExpression_end();
- expect(flow.isReachable, true);
- expect(flow.promotedType(x).type, 'int');
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ x.read
+ .ifNull(block([
+ checkReachable(true),
+ x.write(expr('int')).stmt,
+ checkPromoted(x, 'int'),
+ ]).thenExpr(expr('int?')))
+ .thenStmt(block([
+ checkReachable(true),
+ checkPromoted(x, 'int'),
+ ]))
+ .stmt,
+ ]);
});
test('ifNullExpression allows promotion of tested var', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.ifNullExpression_rightBegin(h.variableRead(x)(), _Type('int?'));
- expect(flow.isReachable, true);
- h.promote(x, 'int');
- expect(flow.promotedType(x).type, 'int');
- flow.ifNullExpression_end();
- expect(flow.isReachable, true);
- expect(flow.promotedType(x).type, 'int');
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ x.read
+ .ifNull(block([
+ checkReachable(true),
+ x.read.as_('int').stmt,
+ checkPromoted(x, 'int'),
+ ]).thenExpr(expr('int?')))
+ .thenStmt(block([
+ checkReachable(true),
+ checkPromoted(x, 'int'),
+ ]))
+ .stmt,
+ ]);
});
test('ifNullExpression discards promotions unrelated to tested expr', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.ifNullExpression_rightBegin(h.expr(), _Type('int?'));
- expect(flow.isReachable, true);
- h.promote(x, 'int');
- expect(flow.promotedType(x).type, 'int');
- flow.ifNullExpression_end();
- expect(flow.isReachable, true);
- expect(flow.promotedType(x), null);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ expr('int?')
+ .ifNull(block([
+ checkReachable(true),
+ x.read.as_('int').stmt,
+ checkPromoted(x, 'int'),
+ ]).thenExpr(expr('int?')))
+ .thenStmt(block([
+ checkReachable(true),
+ checkNotPromoted(x),
+ ]))
+ .stmt,
+ ]);
});
test('ifNullExpression does not detect when RHS is unreachable', () {
- var h = _Harness();
- h.run((flow) {
- flow.ifNullExpression_rightBegin(h.expr(), _Type('int'));
- expect(flow.isReachable, true);
- flow.ifNullExpression_end();
- expect(flow.isReachable, true);
- });
+ var h = Harness();
+ h.run([
+ expr('int')
+ .ifNull(checkReachable(true).thenExpr(expr('int')))
+ .thenStmt(checkReachable(true))
+ .stmt,
+ ]);
});
test('ifNullExpression determines reachability correctly for `Null` type',
() {
- var h = _Harness();
- h.run((flow) {
- flow.ifNullExpression_rightBegin(h.expr(), _Type('Null'));
- expect(flow.isReachable, true);
- flow.ifNullExpression_end();
- expect(flow.isReachable, true);
- });
+ var h = Harness();
+ h.run([
+ expr('Null')
+ .ifNull(checkReachable(true).thenExpr(expr('Null')))
+ .thenStmt(checkReachable(true))
+ .stmt,
+ ]);
});
test('ifStatement with early exit promotes in unreachable code', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.handleExit();
- expect(flow.isReachable, false);
- flow.ifStatement_conditionBegin();
- flow.ifStatement_thenBegin(h.eqNull(x, _Type('int?'))());
- flow.handleExit();
- flow.ifStatement_end(false);
- expect(flow.isReachable, false);
- expect(flow.promotedType(x).type, 'int');
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ return_(),
+ checkReachable(false),
+ if_(x.read.eq(nullLiteral), [
+ return_(),
+ ]),
+ checkReachable(false),
+ checkPromoted(x, 'int'),
+ ]);
});
test('ifStatement_end(false) keeps else branch if then branch exits', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.ifStatement_conditionBegin();
- flow.ifStatement_thenBegin(h.eqNull(x, _Type('int?'))());
- flow.handleExit();
- flow.ifStatement_end(false);
- expect(flow.promotedType(x).type, 'int');
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ if_(x.read.eq(nullLiteral), [
+ return_(),
+ ]),
+ checkPromoted(x, 'int'),
+ ]);
});
void _checkIs(String declaredType, String tryPromoteType,
String expectedPromotedTypeThen, String expectedPromotedTypeElse,
{bool inverted = false}) {
- var h = _Harness();
- var x = h.addVar('x', declaredType);
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.ifStatement_conditionBegin();
- var read = _Expression();
- flow.variableRead(read, x);
- var expr = _Expression();
- flow.isExpression_end(expr, read, inverted, _Type(tryPromoteType));
- flow.ifStatement_thenBegin(expr);
- expect(flow.isReachable, true);
- if (expectedPromotedTypeThen == null) {
- expect(flow.promotedType(x), isNull);
- } else {
- expect(flow.promotedType(x).type, expectedPromotedTypeThen);
- }
- flow.ifStatement_elseBegin();
- expect(flow.isReachable, true);
- if (expectedPromotedTypeElse == null) {
- expect(flow.promotedType(x), isNull);
- } else {
- expect(flow.promotedType(x).type, expectedPromotedTypeElse);
- }
- flow.ifStatement_end(true);
- });
+ var h = Harness();
+ var x = Var('x', declaredType);
+ h.run([
+ declare(x, initialized: true),
+ if_(x.read.is_(tryPromoteType, isInverted: inverted), [
+ checkReachable(true),
+ checkPromoted(x, expectedPromotedTypeThen),
+ ], [
+ checkReachable(true),
+ checkPromoted(x, expectedPromotedTypeElse),
+ ])
+ ]);
}
test('isExpression_end promotes to a subtype', () {
@@ -1265,755 +1010,681 @@
});
test('isExpression_end does nothing if applied to a non-variable', () {
- var h = _Harness();
- h.run((flow) {
- flow.ifStatement_conditionBegin();
- var subExpr = _Expression();
- var expr = _Expression();
- flow.isExpression_end(expr, subExpr, false, _Type('int'));
- flow.ifStatement_thenBegin(expr);
- expect(flow.isReachable, true);
- flow.ifStatement_elseBegin();
- expect(flow.isReachable, true);
- flow.ifStatement_end(true);
- });
+ var h = Harness();
+ h.run([
+ if_(expr('Null').is_('int'), [
+ checkReachable(true),
+ ], [
+ checkReachable(true),
+ ]),
+ ]);
});
test('isExpression_end does nothing if applied to a non-variable, inverted',
() {
- var h = _Harness();
- h.run((flow) {
- flow.ifStatement_conditionBegin();
- var subExpr = _Expression();
- var expr = _Expression();
- flow.isExpression_end(expr, subExpr, true, _Type('int'));
- flow.ifStatement_thenBegin(expr);
- expect(flow.isReachable, true);
- flow.ifStatement_elseBegin();
- expect(flow.isReachable, true);
- flow.ifStatement_end(true);
- });
+ var h = Harness();
+ h.run([
+ if_(expr('Null').isNot('int'), [
+ checkReachable(true),
+ ], [
+ checkReachable(true),
+ ]),
+ ]);
});
test('isExpression_end() does not promote write-captured vars', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var functionNode = _Node();
- h.assignedVariables(
- (vars) => vars.function(functionNode, () => vars.write(x)));
- h.run((flow) {
- h.declare(x, initialized: true);
- h.if_(h.isType(h.variableRead(x), 'int'), () {
- expect(flow.promotedType(x).type, 'int');
- });
- h.function(functionNode, () {
- flow.write(x, _Type('int?'));
- });
- h.if_(h.isType(h.variableRead(x), 'int'), () {
- expect(flow.promotedType(x), isNull);
- });
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ if_(x.read.is_('int'), [
+ checkPromoted(x, 'int'),
+ ]),
+ localFunction([
+ x.write(expr('int?')).stmt,
+ ]),
+ if_(x.read.is_('int'), [
+ checkNotPromoted(x),
+ ]),
+ ]);
});
test('isExpression_end() handles not-yet-seen variables', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- h.assignedVariables(
- (vars) => vars.function(_Node(), () => vars.write(x)));
- h.run((flow) {
- h.if_(h.isType(h.variableRead(x), 'int'), () {
- expect(flow.promotedType(x).type, 'int');
- });
- h.declare(x, initialized: true);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ if_(x.read.is_('int'), [
+ checkPromoted(x, 'int'),
+ ]),
+ declare(x, initialized: true),
+ localFunction([
+ x.write(expr('Null')).stmt,
+ ]),
+ ]);
});
test('labeledBlock without break', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var block = _Statement();
- h.run((flow) {
- h.declare(x, initialized: true);
-
- h.ifIsNotType(x, 'int', () {
- h.labeledBlock(block, () {
- flow.handleExit();
- });
- });
- expect(flow.promotedType(x).type, 'int');
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ if_(x.read.isNot('int'), [
+ labeled(return_()),
+ ]),
+ checkPromoted(x, 'int'),
+ ]);
});
test('labeledBlock with break joins', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var block = _Statement();
- h.run((flow) {
- h.declare(x, initialized: true);
-
- h.ifIsNotType(x, 'int', () {
- h.labeledBlock(block, () {
- h.if_(h.expr, () {
- flow.handleBreak(block);
- });
- flow.handleExit();
- });
- });
- expect(flow.promotedType(x), isNull);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ if_(x.read.isNot('int'), [
+ branchTarget((t) => labeled(block([
+ if_(expr('bool'), [
+ break_(t),
+ ]),
+ return_(),
+ ]))),
+ ]),
+ checkNotPromoted(x),
+ ]);
});
test('logicalBinaryOp_rightBegin(isAnd: true) promotes in RHS', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.logicalBinaryOp_begin();
- flow.logicalBinaryOp_rightBegin(h.notNull(x, _Type('int?'))(),
- isAnd: true);
- expect(flow.promotedType(x).type, 'int');
- flow.logicalBinaryOp_end(_Expression(), _Expression(), isAnd: true);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ x.read
+ .notEq(nullLiteral)
+ .and(checkPromoted(x, 'int').thenExpr(expr('bool')))
+ .stmt,
+ ]);
});
test('logicalBinaryOp_rightEnd(isAnd: true) keeps promotions from RHS', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.ifStatement_conditionBegin();
- flow.logicalBinaryOp_begin();
- flow.logicalBinaryOp_rightBegin(_Expression(), isAnd: true);
- var wholeExpr = _Expression();
- flow.logicalBinaryOp_end(wholeExpr, h.notNull(x, _Type('int?'))(),
- isAnd: true);
- flow.ifStatement_thenBegin(wholeExpr);
- expect(flow.promotedType(x).type, 'int');
- flow.ifStatement_end(false);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ if_(expr('bool').and(x.read.notEq(nullLiteral)), [
+ checkPromoted(x, 'int'),
+ ]),
+ ]);
});
test('logicalBinaryOp_rightEnd(isAnd: false) keeps promotions from RHS',
() {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.ifStatement_conditionBegin();
- flow.logicalBinaryOp_begin();
- flow.logicalBinaryOp_rightBegin(_Expression(), isAnd: false);
- var wholeExpr = _Expression();
- flow.logicalBinaryOp_end(wholeExpr, h.eqNull(x, _Type('int?'))(),
- isAnd: false);
- flow.ifStatement_thenBegin(wholeExpr);
- flow.ifStatement_elseBegin();
- expect(flow.promotedType(x).type, 'int');
- flow.ifStatement_end(true);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ if_(expr('bool').or(x.read.eq(nullLiteral)), [], [
+ checkPromoted(x, 'int'),
+ ]),
+ ]);
});
test('logicalBinaryOp_rightBegin(isAnd: false) promotes in RHS', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.logicalBinaryOp_begin();
- flow.logicalBinaryOp_rightBegin(h.eqNull(x, _Type('int?'))(),
- isAnd: false);
- expect(flow.promotedType(x).type, 'int');
- flow.logicalBinaryOp_end(_Expression(), _Expression(), isAnd: false);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ x.read
+ .eq(nullLiteral)
+ .or(checkPromoted(x, 'int').thenExpr(expr('bool')))
+ .stmt,
+ ]);
});
test('logicalBinaryOp(isAnd: true) joins promotions', () {
// if (x != null && y != null) {
// promotes x and y
// }
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var y = h.addVar('y', 'int?');
- h.run((flow) {
- h.declare(x, initialized: true);
- h.declare(y, initialized: true);
- h.if_(h.and(h.notNull(x, _Type('int?')), h.notNull(y, _Type('int?'))),
- () {
- expect(flow.promotedType(x).type, 'int');
- expect(flow.promotedType(y).type, 'int');
- });
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ var y = Var('y', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ declare(y, initialized: true),
+ if_(x.read.notEq(nullLiteral).and(y.read.notEq(nullLiteral)), [
+ checkPromoted(x, 'int'),
+ checkPromoted(y, 'int'),
+ ]),
+ ]);
});
test('logicalBinaryOp(isAnd: false) joins promotions', () {
// if (x == null || y == null) {} else {
// promotes x and y
// }
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var y = h.addVar('y', 'int?');
- h.run((flow) {
- h.declare(x, initialized: true);
- h.declare(y, initialized: true);
- h.ifElse(
- h.or(h.eqNull(x, _Type('int?')), h.eqNull(y, _Type('int?'))), () {},
- () {
- expect(flow.promotedType(x).type, 'int');
- expect(flow.promotedType(y).type, 'int');
- });
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ var y = Var('y', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ declare(y, initialized: true),
+ if_(x.read.eq(nullLiteral).or(y.read.eq(nullLiteral)), [], [
+ checkPromoted(x, 'int'),
+ checkPromoted(y, 'int'),
+ ]),
+ ]);
});
test('nonNullAssert_end(x) promotes', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- h.run((flow) {
- h.declare(x, initialized: true);
- var varExpr = _Expression();
- flow.variableRead(varExpr, x);
- flow.nonNullAssert_end(varExpr);
- expect(flow.promotedType(x).type, 'int');
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ x.read.nonNullAssert.stmt,
+ checkPromoted(x, 'int'),
+ ]);
});
test('nullAwareAccess temporarily promotes', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- h.run((flow) {
- h.declare(x, initialized: true);
- var varExpr = _Expression();
- flow.variableRead(varExpr, x);
- flow.nullAwareAccess_rightBegin(varExpr, _Type('int?'));
- expect(flow.isReachable, true);
- expect(flow.promotedType(x).type, 'int');
- flow.nullAwareAccess_end();
- expect(flow.promotedType(x), isNull);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ x.read
+ .nullAwareAccess(block([
+ checkReachable(true),
+ checkPromoted(x, 'int'),
+ ]).thenExpr(expr('Null')))
+ .stmt,
+ checkNotPromoted(x),
+ ]);
});
test('nullAwareAccess does not promote the target of a cascade', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- h.run((flow) {
- h.declare(x, initialized: true);
- var varExpr = _Expression();
- flow.variableRead(varExpr, x);
- flow.nullAwareAccess_rightBegin(null, _Type('int?'));
- expect(flow.isReachable, true);
- expect(flow.promotedType(x), isNull);
- flow.nullAwareAccess_end();
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ x.read
+ .nullAwareAccess(
+ block([
+ checkReachable(true),
+ checkNotPromoted(x),
+ ]).thenExpr(expr('Null')),
+ isCascaded: true)
+ .stmt,
+ ]);
});
test('nullAwareAccess preserves demotions', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- h.assignedVariables((vars) => vars.write(x));
- h.run((flow) {
- h.declare(x, initialized: true);
- h.promote(x, 'int');
- var lhs = _Expression();
- flow.nullAwareAccess_rightBegin(lhs, _Type('int'));
- expect(flow.isReachable, true);
- expect(flow.promotedType(x).type, 'int');
- flow.write(x, _Type('int?'));
- expect(flow.promotedType(x), isNull);
- flow.nullAwareAccess_end();
- expect(flow.promotedType(x), isNull);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ x.read.as_('int').stmt,
+ expr('int')
+ .nullAwareAccess(block([
+ checkReachable(true),
+ checkPromoted(x, 'int'),
+ ]).thenExpr(x.write(expr('int?'))).thenStmt(checkNotPromoted(x)))
+ .stmt,
+ checkNotPromoted(x),
+ ]);
});
test('nullAwareAccess_end ignores shorting if target is non-nullable', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.nullAwareAccess_rightBegin(_Expression(), _Type('int'));
- expect(flow.isReachable, true);
- h.promote(x, 'int');
- expect(flow.promotedType(x).type, 'int');
- flow.nullAwareAccess_end();
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ expr('int')
+ .nullAwareAccess(block([
+ checkReachable(true),
+ x.read.as_('int').stmt,
+ checkPromoted(x, 'int'),
+ ]).thenExpr(expr('Null')))
+ .stmt,
// Since the null-shorting path was reachable, promotion of `x` should
// be cancelled.
- expect(flow.promotedType(x), isNull);
- });
+ checkNotPromoted(x),
+ ]);
});
test('parenthesizedExpression preserves promotion behaviors', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- h.run((flow) {
- h.if_(
- h.parenthesized(h.notEqual(
- h.parenthesized(h.variableRead(x)),
- _Type('int?'),
- h.parenthesized(h.nullLiteral),
- _Type('Null'))), () {
- expect(flow.promotedType(x).type, 'int');
- });
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ if_(
+ x.read.parenthesized.notEq(nullLiteral.parenthesized).parenthesized,
+ [
+ checkPromoted(x, 'int'),
+ ]),
+ ]);
});
test('promote promotes to a subtype and sets type of interest', () {
- var h = _Harness();
- var x = h.addVar('x', 'num?');
- h.assignedVariables((vars) {
- vars.write(x);
- });
- h.run((flow) {
- flow.declare(x, true);
- expect(flow.promotedType(x), isNull);
- flow.promote(x, _Type('num'));
- expect(flow.promotedType(x).type, 'num');
+ var h = Harness();
+ var x = Var('x', 'num?');
+ h.run([
+ declare(x, initialized: true),
+ checkNotPromoted(x),
+ x.read.as_('num').stmt,
+ checkPromoted(x, 'num'),
// Check that it's a type of interest by promoting and de-promoting.
- h.if_(h.isType(h.variableRead(x), 'int'), () {
- expect(flow.promotedType(x).type, 'int');
- flow.write(x, _Type('num'));
- expect(flow.promotedType(x).type, 'num');
- });
- });
+ if_(x.read.is_('int'), [
+ checkPromoted(x, 'int'),
+ x.write(expr('num')).stmt,
+ checkPromoted(x, 'num'),
+ ]),
+ ]);
});
test('promote does not promote to a non-subtype', () {
- var h = _Harness();
- var x = h.addVar('x', 'num?');
- h.run((flow) {
- flow.declare(x, true);
- expect(flow.promotedType(x), isNull);
- flow.promote(x, _Type('String'));
- expect(flow.promotedType(x), isNull);
- });
+ var h = Harness();
+ var x = Var('x', 'num?');
+ h.run([
+ declare(x, initialized: true),
+ checkNotPromoted(x),
+ x.read.as_('String').stmt,
+ checkNotPromoted(x),
+ ]);
});
test('promote does not promote if variable is write-captured', () {
- var h = _Harness();
- var x = h.addVar('x', 'num?');
- var functionNode = _Node();
- h.assignedVariables(
- (vars) => vars.function(functionNode, () => vars.write(x)));
- h.run((flow) {
- flow.declare(x, true);
- expect(flow.promotedType(x), isNull);
- flow.functionExpression_begin(functionNode);
- flow.write(x, _Type('num'));
- flow.functionExpression_end();
- flow.promote(x, _Type('num'));
- expect(flow.promotedType(x), isNull);
- });
+ var h = Harness();
+ var x = Var('x', 'num?');
+ h.run([
+ declare(x, initialized: true),
+ checkNotPromoted(x),
+ localFunction([
+ x.write(expr('num')).stmt,
+ ]),
+ x.read.as_('num').stmt,
+ checkNotPromoted(x),
+ ]);
});
test('promotedType handles not-yet-seen variables', () {
// Note: this is needed for error recovery in the analyzer.
- var h = _Harness();
- var x = h.addVar('x', 'int');
- h.run((flow) {
- expect(flow.promotedType(x), isNull);
- h.declare(x, initialized: true);
- });
+ var h = Harness();
+ var x = Var('x', 'int');
+ h.run([
+ checkNotPromoted(x),
+ declare(x, initialized: true),
+ ]);
});
test('switchStatement_beginCase(false) restores previous promotions', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var switchStatement = _Statement();
- h.assignedVariables(
- (vars) => vars.nest(switchStatement, () => vars.write(x)));
- h.run((flow) {
- h.declare(x, initialized: true);
- h.promote(x, 'int');
- flow.switchStatement_expressionEnd(_Statement());
- flow.switchStatement_beginCase(false, switchStatement);
- expect(flow.promotedType(x).type, 'int');
- flow.write(x, _Type('int?'));
- expect(flow.promotedType(x), isNull);
- flow.switchStatement_beginCase(false, switchStatement);
- expect(flow.promotedType(x).type, 'int');
- flow.write(x, _Type('int?'));
- expect(flow.promotedType(x), isNull);
- flow.switchStatement_end(false);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ x.read.as_('int').stmt,
+ switch_(
+ expr('Null'),
+ [
+ case_([
+ checkPromoted(x, 'int'),
+ x.write(expr('int?')).stmt,
+ checkNotPromoted(x),
+ ]),
+ case_([
+ checkPromoted(x, 'int'),
+ x.write(expr('int?')).stmt,
+ checkNotPromoted(x),
+ ]),
+ ],
+ isExhaustive: false),
+ ]);
});
test('switchStatement_beginCase(false) does not un-promote', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var switchStatement = _Statement();
- h.assignedVariables(
- (vars) => vars.nest(switchStatement, () => vars.write(x)));
- h.run((flow) {
- h.declare(x, initialized: true);
- h.promote(x, 'int');
- flow.switchStatement_expressionEnd(_Statement());
- flow.switchStatement_beginCase(false, switchStatement);
- expect(flow.promotedType(x).type, 'int');
- flow.write(x, _Type('int?'));
- expect(flow.promotedType(x), isNull);
- flow.switchStatement_end(false);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ x.read.as_('int').stmt,
+ switch_(
+ expr('Null'),
+ [
+ case_([
+ checkPromoted(x, 'int'),
+ x.write(expr('int?')).stmt,
+ checkNotPromoted(x),
+ ])
+ ],
+ isExhaustive: false),
+ ]);
});
test('switchStatement_beginCase(false) handles write captures in cases',
() {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var switchStatement = _Statement();
- var functionNode = _Node();
- h.assignedVariables((vars) => vars.nest(switchStatement,
- () => vars.function(functionNode, () => vars.write(x))));
- h.run((flow) {
- h.declare(x, initialized: true);
- h.promote(x, 'int');
- flow.switchStatement_expressionEnd(_Statement());
- flow.switchStatement_beginCase(false, switchStatement);
- expect(flow.promotedType(x).type, 'int');
- h.function(functionNode, () {
- flow.write(x, _Type('int?'));
- });
- expect(flow.promotedType(x), isNull);
- flow.switchStatement_end(false);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ x.read.as_('int').stmt,
+ switch_(
+ expr('Null'),
+ [
+ case_([
+ checkPromoted(x, 'int'),
+ localFunction([
+ x.write(expr('int?')).stmt,
+ ]),
+ checkNotPromoted(x),
+ ]),
+ ],
+ isExhaustive: false),
+ ]);
});
test('switchStatement_beginCase(true) un-promotes', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var switchStatement = _Statement();
- h.assignedVariables(
- (vars) => vars.nest(switchStatement, () => vars.write(x)));
- h.run((flow) {
- h.declare(x, initialized: true);
- h.promote(x, 'int');
- flow.switchStatement_expressionEnd(_Statement());
- flow.switchStatement_beginCase(true, switchStatement);
- expect(flow.promotedType(x), isNull);
- flow.write(x, _Type('int?'));
- expect(flow.promotedType(x), isNull);
- flow.switchStatement_end(false);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ x.read.as_('int').stmt,
+ switch_(
+ expr('Null'),
+ [
+ case_([
+ checkNotPromoted(x),
+ x.write(expr('int?')).stmt,
+ checkNotPromoted(x),
+ ], hasLabel: true),
+ ],
+ isExhaustive: false),
+ ]);
});
test('switchStatement_beginCase(true) handles write captures in cases', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var switchStatement = _Statement();
- var functionNode = _Node();
- h.assignedVariables((vars) => vars.nest(switchStatement,
- () => vars.function(functionNode, () => vars.write(x))));
- h.run((flow) {
- h.declare(x, initialized: true);
- h.promote(x, 'int');
- flow.switchStatement_expressionEnd(_Statement());
- flow.switchStatement_beginCase(true, switchStatement);
- h.promote(x, 'int');
- expect(flow.promotedType(x), isNull);
- h.function(functionNode, () {
- flow.write(x, _Type('int?'));
- });
- expect(flow.promotedType(x), isNull);
- flow.switchStatement_end(false);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ x.read.as_('int').stmt,
+ switch_(
+ expr('Null'),
+ [
+ case_([
+ x.read.as_('int').stmt,
+ checkNotPromoted(x),
+ localFunction([
+ x.write(expr('int?')).stmt,
+ ]),
+ checkNotPromoted(x),
+ ], hasLabel: true),
+ ],
+ isExhaustive: false),
+ ]);
});
test('switchStatement_end(false) joins break and default', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var y = h.addVar('y', 'int?');
- var z = h.addVar('z', 'int?');
- var switchStatement = _Statement();
- h.assignedVariables(
- (vars) => vars.nest(switchStatement, () => vars.write(y)));
- h.run((flow) {
- h.declare(x, initialized: true);
- h.declare(y, initialized: true);
- h.declare(z, initialized: true);
- h.promote(y, 'int');
- h.promote(z, 'int');
- var stmt = _Statement();
- flow.switchStatement_expressionEnd(stmt);
- flow.switchStatement_beginCase(false, switchStatement);
- h.promote(x, 'int');
- flow.write(y, _Type('int?'));
- flow.handleBreak(stmt);
- flow.switchStatement_end(false);
- expect(flow.promotedType(x), isNull);
- expect(flow.promotedType(y), isNull);
- expect(flow.promotedType(z).type, 'int');
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ var y = Var('y', 'int?');
+ var z = Var('z', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ declare(y, initialized: true),
+ declare(z, initialized: true),
+ y.read.as_('int').stmt,
+ z.read.as_('int').stmt,
+ branchTarget((t) => switch_(
+ expr('Null'),
+ [
+ case_([
+ x.read.as_('int').stmt,
+ y.write(expr('int?')).stmt,
+ break_(t),
+ ]),
+ ],
+ isExhaustive: false)),
+ checkNotPromoted(x),
+ checkNotPromoted(y),
+ checkPromoted(z, 'int'),
+ ]);
});
test('switchStatement_end(true) joins breaks', () {
- var h = _Harness();
- var w = h.addVar('w', 'int?');
- var x = h.addVar('x', 'int?');
- var y = h.addVar('y', 'int?');
- var z = h.addVar('z', 'int?');
- var switchStatement = _Statement();
- h.assignedVariables((vars) => vars.nest(switchStatement, () {
- vars.write(x);
- vars.write(y);
- }));
- h.run((flow) {
- h.declare(w, initialized: true);
- h.declare(x, initialized: true);
- h.declare(y, initialized: true);
- h.declare(z, initialized: true);
- h.promote(x, 'int');
- h.promote(y, 'int');
- h.promote(z, 'int');
- var stmt = _Statement();
- flow.switchStatement_expressionEnd(stmt);
- flow.switchStatement_beginCase(false, switchStatement);
- h.promote(w, 'int');
- h.promote(y, 'int');
- flow.write(x, _Type('int?'));
- flow.handleBreak(stmt);
- flow.switchStatement_beginCase(false, switchStatement);
- h.promote(w, 'int');
- h.promote(x, 'int');
- flow.write(y, _Type('int?'));
- flow.handleBreak(stmt);
- flow.switchStatement_end(true);
- expect(flow.promotedType(w).type, 'int');
- expect(flow.promotedType(x), isNull);
- expect(flow.promotedType(y), isNull);
- expect(flow.promotedType(z).type, 'int');
- });
+ var h = Harness();
+ var w = Var('w', 'int?');
+ var x = Var('x', 'int?');
+ var y = Var('y', 'int?');
+ var z = Var('z', 'int?');
+ h.run([
+ declare(w, initialized: true),
+ declare(x, initialized: true),
+ declare(y, initialized: true),
+ declare(z, initialized: true),
+ x.read.as_('int').stmt,
+ y.read.as_('int').stmt,
+ z.read.as_('int').stmt,
+ branchTarget((t) => switch_(
+ expr('Null'),
+ [
+ case_([
+ w.read.as_('int').stmt,
+ y.read.as_('int').stmt,
+ x.write(expr('int?')).stmt,
+ break_(t),
+ ]),
+ case_([
+ w.read.as_('int').stmt,
+ x.read.as_('int').stmt,
+ y.write(expr('int?')).stmt,
+ break_(t),
+ ]),
+ ],
+ isExhaustive: true)),
+ checkPromoted(w, 'int'),
+ checkNotPromoted(x),
+ checkNotPromoted(y),
+ checkPromoted(z, 'int'),
+ ]);
});
test('switchStatement_end(true) allows fall-through of last case', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var stmt = _Statement();
- h.assignedVariables((vars) => vars.nest(stmt, () {}));
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.switchStatement_expressionEnd(stmt);
- flow.switchStatement_beginCase(false, stmt);
- h.promote(x, 'int');
- flow.handleBreak(stmt);
- flow.switchStatement_beginCase(false, stmt);
- flow.switchStatement_end(true);
- expect(flow.promotedType(x), isNull);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ branchTarget((t) => switch_(
+ expr('Null'),
+ [
+ case_([
+ x.read.as_('int').stmt,
+ break_(t),
+ ]),
+ case_([]),
+ ],
+ isExhaustive: true)),
+ checkNotPromoted(x),
+ ]);
});
test('tryCatchStatement_bodyEnd() restores pre-try state', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var y = h.addVar('y', 'int?');
- var stmt = _Statement();
- h.assignedVariables((vars) => vars.nest(stmt, () {}));
- h.run((flow) {
- h.declare(x, initialized: true);
- h.declare(y, initialized: true);
- h.promote(y, 'int');
- flow.tryCatchStatement_bodyBegin();
- h.promote(x, 'int');
- expect(flow.promotedType(x).type, 'int');
- expect(flow.promotedType(y).type, 'int');
- flow.tryCatchStatement_bodyEnd(stmt);
- flow.tryCatchStatement_catchBegin(null, null);
- expect(flow.promotedType(x), isNull);
- expect(flow.promotedType(y).type, 'int');
- flow.tryCatchStatement_catchEnd();
- flow.tryCatchStatement_end();
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ var y = Var('y', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ declare(y, initialized: true),
+ y.read.as_('int').stmt,
+ tryCatch([
+ x.read.as_('int').stmt,
+ checkPromoted(x, 'int'),
+ checkPromoted(y, 'int'),
+ ], [
+ catch_(body: [
+ checkNotPromoted(x),
+ checkPromoted(y, 'int'),
+ ])
+ ]),
+ ]);
});
test('tryCatchStatement_bodyEnd() un-promotes variables assigned in body',
() {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var body = _Statement();
- h.assignedVariables((vars) => vars.nest(body, () => vars.write(x)));
- h.run((flow) {
- h.declare(x, initialized: true);
- h.promote(x, 'int');
- expect(flow.promotedType(x).type, 'int');
- flow.tryCatchStatement_bodyBegin();
- flow.write(x, _Type('int?'));
- h.promote(x, 'int');
- expect(flow.promotedType(x).type, 'int');
- flow.tryCatchStatement_bodyEnd(body);
- flow.tryCatchStatement_catchBegin(null, null);
- expect(flow.promotedType(x), isNull);
- flow.tryCatchStatement_catchEnd();
- flow.tryCatchStatement_end();
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ x.read.as_('int').stmt,
+ checkPromoted(x, 'int'),
+ tryCatch([
+ x.write(expr('int?')).stmt,
+ x.read.as_('int').stmt,
+ checkPromoted(x, 'int'),
+ ], [
+ catch_(body: [
+ checkNotPromoted(x),
+ ]),
+ ]),
+ ]);
});
test('tryCatchStatement_bodyEnd() preserves write captures in body', () {
// Note: it's not necessary for the write capture to survive to the end of
// the try body, because an exception could occur at any time. We check
// this by putting an exit in the try body.
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var body = _Statement();
- var functionNode = _Node();
- h.assignedVariables((vars) => vars.nest(
- body, () => vars.function(functionNode, () => vars.write(x))));
- h.run((flow) {
- h.declare(x, initialized: true);
- h.promote(x, 'int');
- expect(flow.promotedType(x).type, 'int');
- flow.tryCatchStatement_bodyBegin();
- h.function(functionNode, () {
- flow.write(x, _Type('int?'));
- });
- flow.handleExit();
- flow.tryCatchStatement_bodyEnd(body);
- flow.tryCatchStatement_catchBegin(null, null);
- h.promote(x, 'int');
- expect(flow.promotedType(x), isNull);
- flow.tryCatchStatement_catchEnd();
- flow.tryCatchStatement_end();
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ x.read.as_('int').stmt,
+ checkPromoted(x, 'int'),
+ tryCatch([
+ localFunction([
+ x.write(expr('int?')).stmt,
+ ]),
+ return_(),
+ ], [
+ catch_(body: [
+ x.read.as_('int').stmt,
+ checkNotPromoted(x),
+ ])
+ ]),
+ ]);
});
test('tryCatchStatement_catchBegin() restores previous post-body state',
() {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var stmt = _Statement();
- h.assignedVariables((vars) => vars.nest(stmt, () {}));
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.tryCatchStatement_bodyBegin();
- flow.tryCatchStatement_bodyEnd(stmt);
- flow.tryCatchStatement_catchBegin(null, null);
- h.promote(x, 'int');
- expect(flow.promotedType(x).type, 'int');
- flow.tryCatchStatement_catchEnd();
- flow.tryCatchStatement_catchBegin(null, null);
- expect(flow.promotedType(x), isNull);
- flow.tryCatchStatement_catchEnd();
- flow.tryCatchStatement_end();
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ tryCatch([], [
+ catch_(body: [
+ x.read.as_('int').stmt,
+ checkPromoted(x, 'int'),
+ ]),
+ catch_(body: [
+ checkNotPromoted(x),
+ ]),
+ ]),
+ ]);
});
test('tryCatchStatement_catchBegin() initializes vars', () {
- var h = _Harness();
- var e = h.addVar('e', 'int');
- var st = h.addVar('st', 'StackTrace');
- var stmt = _Statement();
- h.assignedVariables((vars) => vars.nest(stmt, () {}));
- h.run((flow) {
- flow.tryCatchStatement_bodyBegin();
- flow.tryCatchStatement_bodyEnd(stmt);
- flow.tryCatchStatement_catchBegin(e, st);
- expect(flow.isAssigned(e), true);
- expect(flow.isAssigned(st), true);
- flow.tryCatchStatement_catchEnd();
- flow.tryCatchStatement_end();
- });
+ var h = Harness();
+ var e = Var('e', 'int');
+ var st = Var('st', 'StackTrace');
+ h.run([
+ tryCatch([], [
+ catch_(exception: e, stackTrace: st, body: [
+ checkAssigned(e, true),
+ checkAssigned(st, true),
+ ]),
+ ]),
+ ]);
});
test('tryCatchStatement_catchEnd() joins catch state with after-try state',
() {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var y = h.addVar('y', 'int?');
- var z = h.addVar('z', 'int?');
- var stmt = _Statement();
- h.assignedVariables((vars) => vars.nest(stmt, () {}));
- h.run((flow) {
- h.declare(x, initialized: true);
- h.declare(y, initialized: true);
- h.declare(z, initialized: true);
- flow.tryCatchStatement_bodyBegin();
- h.promote(x, 'int');
- h.promote(y, 'int');
- flow.tryCatchStatement_bodyEnd(stmt);
- flow.tryCatchStatement_catchBegin(null, null);
- h.promote(x, 'int');
- h.promote(z, 'int');
- flow.tryCatchStatement_catchEnd();
- flow.tryCatchStatement_end();
+ var h = Harness();
+ var x = Var('x', 'int?');
+ var y = Var('y', 'int?');
+ var z = Var('z', 'int?');
+ h.run([
+ declare(x, initialized: true), declare(y, initialized: true),
+ declare(z, initialized: true),
+ tryCatch([
+ x.read.as_('int').stmt,
+ y.read.as_('int').stmt,
+ ], [
+ catch_(body: [
+ x.read.as_('int').stmt,
+ z.read.as_('int').stmt,
+ ]),
+ ]),
// Only x should be promoted, because it's the only variable
// promoted in both the try body and the catch handler.
- expect(flow.promotedType(x).type, 'int');
- expect(flow.promotedType(y), isNull);
- expect(flow.promotedType(z), isNull);
- });
+ checkPromoted(x, 'int'), checkNotPromoted(y), checkNotPromoted(z),
+ ]);
});
test('tryCatchStatement_catchEnd() joins catch states', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var y = h.addVar('y', 'int?');
- var z = h.addVar('z', 'int?');
- var stmt = _Statement();
- h.assignedVariables((vars) => vars.nest(stmt, () {}));
- h.run((flow) {
- h.declare(x, initialized: true);
- h.declare(y, initialized: true);
- h.declare(z, initialized: true);
- flow.tryCatchStatement_bodyBegin();
- flow.handleExit();
- flow.tryCatchStatement_bodyEnd(stmt);
- flow.tryCatchStatement_catchBegin(null, null);
- h.promote(x, 'int');
- h.promote(y, 'int');
- flow.tryCatchStatement_catchEnd();
- flow.tryCatchStatement_catchBegin(null, null);
- h.promote(x, 'int');
- h.promote(z, 'int');
- flow.tryCatchStatement_catchEnd();
- flow.tryCatchStatement_end();
+ var h = Harness();
+ var x = Var('x', 'int?');
+ var y = Var('y', 'int?');
+ var z = Var('z', 'int?');
+ h.run([
+ declare(x, initialized: true), declare(y, initialized: true),
+ declare(z, initialized: true),
+ tryCatch([
+ return_(),
+ ], [
+ catch_(body: [
+ x.read.as_('int').stmt,
+ y.read.as_('int').stmt,
+ ]),
+ catch_(body: [
+ x.read.as_('int').stmt,
+ z.read.as_('int').stmt,
+ ]),
+ ]),
// Only x should be promoted, because it's the only variable promoted
// in both catch handlers.
- expect(flow.promotedType(x).type, 'int');
- expect(flow.promotedType(y), isNull);
- expect(flow.promotedType(z), isNull);
- });
+ checkPromoted(x, 'int'), checkNotPromoted(y), checkNotPromoted(z),
+ ]);
});
test('tryFinallyStatement_finallyBegin() restores pre-try state', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var y = h.addVar('y', 'int?');
- var body = _Node();
- var finallyBlock = _Node();
- h.assignedVariables((vars) {
- vars.nest(body, () {});
- vars.nest(finallyBlock, () {});
- });
- h.run((flow) {
- h.declare(x, initialized: true);
- h.declare(y, initialized: true);
- h.promote(y, 'int');
- flow.tryFinallyStatement_bodyBegin();
- h.promote(x, 'int');
- expect(flow.promotedType(x).type, 'int');
- expect(flow.promotedType(y).type, 'int');
- flow.tryFinallyStatement_finallyBegin(body);
- expect(flow.promotedType(x), isNull);
- expect(flow.promotedType(y).type, 'int');
- flow.tryFinallyStatement_end(finallyBlock);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ var y = Var('y', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ declare(y, initialized: true),
+ y.read.as_('int').stmt,
+ tryFinally([
+ x.read.as_('int').stmt,
+ checkPromoted(x, 'int'),
+ checkPromoted(y, 'int'),
+ ], [
+ checkNotPromoted(x),
+ checkPromoted(y, 'int'),
+ ]),
+ ]);
});
test(
'tryFinallyStatement_finallyBegin() un-promotes variables assigned in '
'body', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var body = _Node();
- var finallyBlock = _Node();
- h.assignedVariables((vars) {
- vars.nest(body, () => vars.write(x));
- vars.nest(finallyBlock, () {});
- });
- h.run((flow) {
- h.declare(x, initialized: true);
- h.promote(x, 'int');
- expect(flow.promotedType(x).type, 'int');
- flow.tryFinallyStatement_bodyBegin();
- flow.write(x, _Type('int?'));
- h.promote(x, 'int');
- expect(flow.promotedType(x).type, 'int');
- flow.tryFinallyStatement_finallyBegin(body);
- expect(flow.promotedType(x), isNull);
- flow.tryFinallyStatement_end(finallyBlock);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ x.read.as_('int').stmt,
+ checkPromoted(x, 'int'),
+ tryFinally([
+ x.write(expr('int?')).stmt,
+ x.read.as_('int').stmt,
+ checkPromoted(x, 'int'),
+ ], [
+ checkNotPromoted(x),
+ ]),
+ ]);
});
test('tryFinallyStatement_finallyBegin() preserves write captures in body',
@@ -2021,262 +1692,206 @@
// Note: it's not necessary for the write capture to survive to the end of
// the try body, because an exception could occur at any time. We check
// this by putting an exit in the try body.
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var body = _Statement();
- var functionNode = _Node();
- var finallyBlock = _Node();
- h.assignedVariables((vars) => vars.nest(body, () {
- vars.function(functionNode, () => vars.write(x));
- vars.nest(finallyBlock, () {});
- }));
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.tryFinallyStatement_bodyBegin();
- h.function(functionNode, () {
- flow.write(x, _Type('int?'));
- });
- flow.handleExit();
- flow.tryFinallyStatement_finallyBegin(body);
- h.promote(x, 'int');
- expect(flow.promotedType(x), isNull);
- flow.tryFinallyStatement_end(finallyBlock);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ tryFinally([
+ localFunction([
+ x.write(expr('int?')).stmt,
+ ]),
+ return_(),
+ ], [
+ x.read.as_('int').stmt,
+ checkNotPromoted(x),
+ ]),
+ ]);
});
test('tryFinallyStatement_end() restores promotions from try body', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var y = h.addVar('y', 'int?');
- var body = _Statement();
- var finallyBlock = _Node();
- h.assignedVariables((vars) => vars.nest(body, () {
- vars.nest(body, () {});
- vars.nest(finallyBlock, () {});
- }));
- h.run((flow) {
- h.declare(x, initialized: true);
- h.declare(y, initialized: true);
- flow.tryFinallyStatement_bodyBegin();
- h.promote(x, 'int');
- expect(flow.promotedType(x).type, 'int');
- flow.tryFinallyStatement_finallyBegin(body);
- expect(flow.promotedType(x), isNull);
- h.promote(y, 'int');
- expect(flow.promotedType(y).type, 'int');
- flow.tryFinallyStatement_end(finallyBlock);
+ var h = Harness();
+ var x = Var('x', 'int?');
+ var y = Var('y', 'int?');
+ h.run([
+ declare(x, initialized: true), declare(y, initialized: true),
+ tryFinally([
+ x.read.as_('int').stmt,
+ checkPromoted(x, 'int'),
+ ], [
+ checkNotPromoted(x),
+ y.read.as_('int').stmt,
+ checkPromoted(y, 'int'),
+ ]),
// Both x and y should now be promoted.
- expect(flow.promotedType(x).type, 'int');
- expect(flow.promotedType(y).type, 'int');
- });
+ checkPromoted(x, 'int'), checkPromoted(y, 'int'),
+ ]);
});
test(
'tryFinallyStatement_end() does not restore try body promotions for '
'variables assigned in finally', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var y = h.addVar('y', 'int?');
- var body = _Node();
- var finallyBlock = _Node();
- h.assignedVariables((vars) {
- vars.nest(body, () {});
- vars.nest(finallyBlock, () {
- vars.write(x);
- vars.write(y);
- });
- });
- h.run((flow) {
- h.declare(x, initialized: true);
- h.declare(y, initialized: true);
- flow.tryFinallyStatement_bodyBegin();
- h.promote(x, 'int');
- expect(flow.promotedType(x).type, 'int');
- flow.tryFinallyStatement_finallyBegin(body);
- expect(flow.promotedType(x), isNull);
- flow.write(x, _Type('int?'));
- flow.write(y, _Type('int?'));
- h.promote(y, 'int');
- expect(flow.promotedType(y).type, 'int');
- flow.tryFinallyStatement_end(finallyBlock);
+ var h = Harness();
+ var x = Var('x', 'int?');
+ var y = Var('y', 'int?');
+ h.run([
+ declare(x, initialized: true), declare(y, initialized: true),
+ tryFinally([
+ x.read.as_('int').stmt,
+ checkPromoted(x, 'int'),
+ ], [
+ checkNotPromoted(x),
+ x.write(expr('int?')).stmt,
+ y.write(expr('int?')).stmt,
+ y.read.as_('int').stmt,
+ checkPromoted(y, 'int'),
+ ]),
// x should not be re-promoted, because it might have been assigned a
// non-promoted value in the "finally" block. But y's promotion still
// stands, because y was promoted in the finally block.
- expect(flow.promotedType(x), isNull);
- expect(flow.promotedType(y).type, 'int');
- });
+ checkNotPromoted(x), checkPromoted(y, 'int'),
+ ]);
});
test('whileStatement_conditionBegin() un-promotes', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var whileStatement = _Statement();
- h.assignedVariables(
- (vars) => vars.nest(whileStatement, () => vars.write(x)));
- h.run((flow) {
- h.declare(x, initialized: true);
- h.promote(x, 'int');
- expect(flow.promotedType(x).type, 'int');
- flow.whileStatement_conditionBegin(whileStatement);
- expect(flow.promotedType(x), isNull);
- flow.whileStatement_bodyBegin(_Statement(), _Expression());
- flow.whileStatement_end();
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ x.read.as_('int').stmt,
+ checkPromoted(x, 'int'),
+ while_(checkNotPromoted(x).thenExpr(expr('bool')), [
+ x.write(expr('Null')).stmt,
+ ]),
+ ]);
});
test('whileStatement_conditionBegin() handles write captures in the loop',
() {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var whileStatement = _Statement();
- var functionNode = _Node();
- h.assignedVariables((vars) => vars.nest(whileStatement,
- () => vars.function(functionNode, () => vars.write(x))));
- h.run((flow) {
- h.declare(x, initialized: true);
- h.promote(x, 'int');
- expect(flow.promotedType(x).type, 'int');
- flow.whileStatement_conditionBegin(whileStatement);
- h.promote(x, 'int');
- expect(flow.promotedType(x), isNull);
- h.function(functionNode, () {
- flow.write(x, _Type('int?'));
- });
- flow.whileStatement_bodyBegin(_Statement(), _Expression());
- flow.whileStatement_end();
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ x.read.as_('int').stmt,
+ checkPromoted(x, 'int'),
+ while_(
+ block([
+ x.read.as_('int').stmt,
+ checkNotPromoted(x),
+ localFunction([
+ x.write(expr('int?')).stmt,
+ ]),
+ ]).thenExpr(expr('bool')),
+ []),
+ ]);
});
test('whileStatement_conditionBegin() handles not-yet-seen variables', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var y = h.addVar('y', 'int?');
- var whileStatement = _Statement();
- h.assignedVariables(
- (vars) => vars.nest(whileStatement, () => vars.write(x)));
- h.run((flow) {
- h.declare(y, initialized: true);
- h.promote(y, 'int');
- flow.whileStatement_conditionBegin(whileStatement);
- flow.declare(x, true);
- flow.whileStatement_bodyBegin(_Statement(), _Expression());
- flow.whileStatement_end();
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ var y = Var('y', 'int?');
+ h.run([
+ declare(y, initialized: true),
+ y.read.as_('int').stmt,
+ while_(declare(x, initialized: true).thenExpr(expr('bool')), [
+ x.write(expr('Null')).stmt,
+ ]),
+ ]);
});
test('whileStatement_bodyBegin() promotes', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var stmt = _Statement();
- h.assignedVariables((vars) => vars.nest(stmt, () {}));
- h.run((flow) {
- h.declare(x, initialized: true);
- flow.whileStatement_conditionBegin(stmt);
- flow.whileStatement_bodyBegin(stmt, h.notNull(x, _Type('int?'))());
- expect(flow.promotedType(x).type, 'int');
- flow.whileStatement_end();
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ while_(x.read.notEq(nullLiteral), [
+ checkPromoted(x, 'int'),
+ ]),
+ ]);
});
test('whileStatement_end() joins break and condition-false states', () {
// To test that the states are properly joined, we have three variables:
// x, y, and z. We promote x and y in the break path, and x and z in the
// condition-false path. After the loop, only x should be promoted.
- var h = _Harness();
- var x = h.addVar('x', 'int?');
- var y = h.addVar('y', 'int?');
- var z = h.addVar('z', 'int?');
- var stmt = _Statement();
- h.assignedVariables((vars) => vars.nest(stmt, () {}));
- h.run((flow) {
- h.declare(x, initialized: true);
- h.declare(y, initialized: true);
- h.declare(z, initialized: true);
- flow.whileStatement_conditionBegin(stmt);
- flow.whileStatement_bodyBegin(stmt,
- h.or(h.eqNull(x, _Type('int?')), h.eqNull(z, _Type('int?')))());
- h.if_(h.expr, () {
- h.promote(x, 'int');
- h.promote(y, 'int');
- flow.handleBreak(stmt);
- });
- flow.whileStatement_end();
- expect(flow.promotedType(x).type, 'int');
- expect(flow.promotedType(y), isNull);
- expect(flow.promotedType(z), isNull);
- });
+ var h = Harness();
+ var x = Var('x', 'int?');
+ var y = Var('y', 'int?');
+ var z = Var('z', 'int?');
+ h.run([
+ declare(x, initialized: true),
+ declare(y, initialized: true),
+ declare(z, initialized: true),
+ branchTarget(
+ (t) => while_(x.read.eq(nullLiteral).or(z.read.eq(nullLiteral)), [
+ if_(expr('bool'), [
+ x.read.as_('int').stmt,
+ y.read.as_('int').stmt,
+ break_(t),
+ ]),
+ ])),
+ checkPromoted(x, 'int'),
+ checkNotPromoted(y),
+ checkNotPromoted(z),
+ ]);
});
test('Infinite loop does not implicitly assign variables', () {
- var h = _Harness();
- var x = h.addVar('x', 'int');
- var whileStatement = _Statement();
- h.assignedVariables(
- (vars) => vars.nest(whileStatement, () => vars.write(x)));
- h.run((flow) {
- h.declare(x, initialized: false);
- var trueCondition = _Expression();
- flow.whileStatement_conditionBegin(whileStatement);
- flow.booleanLiteral(trueCondition, true);
- flow.whileStatement_bodyBegin(whileStatement, trueCondition);
- flow.whileStatement_end();
- expect(flow.isAssigned(x), false);
- });
+ var h = Harness();
+ var x = Var('x', 'int');
+ h.run([
+ declare(x, initialized: false),
+ while_(booleanLiteral(true), [
+ x.write(expr('Null')).stmt,
+ ]),
+ checkAssigned(x, false),
+ ]);
});
test('If(false) does not discard promotions', () {
- var h = _Harness();
- var x = h.addVar('x', 'Object');
- h.run((flow) {
- h.declare(x, initialized: true);
- h.promote(x, 'int');
- expect(flow.promotedType(x).type, 'int');
- // if (false) {
- flow.ifStatement_conditionBegin();
- var falseExpression = _Expression();
- flow.booleanLiteral(falseExpression, false);
- flow.ifStatement_thenBegin(falseExpression);
- expect(flow.promotedType(x).type, 'int');
- flow.ifStatement_end(false);
- });
+ var h = Harness();
+ var x = Var('x', 'Object');
+ h.run([
+ declare(x, initialized: true),
+ x.read.as_('int').stmt,
+ checkPromoted(x, 'int'),
+ if_(booleanLiteral(false), [
+ checkPromoted(x, 'int'),
+ ]),
+ ]);
});
test('Promotions do not occur when a variable is write-captured', () {
- var h = _Harness();
- var x = h.addVar('x', 'Object');
- var functionNode = _Node();
- h.assignedVariables(
- (vars) => vars.function(functionNode, () => vars.write(x)));
- h.run((flow) {
- h.declare(x, initialized: true);
- h.function(functionNode, () {});
- h.promote(x, 'int');
- expect(flow.promotedType(x), isNull);
- });
+ var h = Harness();
+ var x = Var('x', 'Object');
+ h.run([
+ declare(x, initialized: true),
+ localFunction([
+ x.write(expr('Object')).stmt,
+ ]),
+ x.read.as_('int').stmt,
+ checkNotPromoted(x),
+ ]);
});
test('Promotion cancellation of write-captured vars survives join', () {
- var h = _Harness();
- var x = h.addVar('x', 'Object');
- var functionNode = _Node();
- h.assignedVariables(
- (vars) => vars.function(functionNode, () => vars.write(x)));
- h.run((flow) {
- h.declare(x, initialized: true);
- h.ifElse(h.expr, () {
- h.function(functionNode, () {});
- }, () {
+ var h = Harness();
+ var x = Var('x', 'Object');
+ h.run([
+ declare(x, initialized: true),
+ if_(expr('bool'), [
+ localFunction([
+ x.write(expr('Object')).stmt,
+ ]),
+ ], [
// Promotion should work here because the write capture is in the
// other branch.
- h.promote(x, 'int');
- expect(flow.promotedType(x).type, 'int');
- });
+ x.read.as_('int').stmt, checkPromoted(x, 'int'),
+ ]),
// But the promotion should be cancelled now, after the join.
- expect(flow.promotedType(x), isNull);
+ checkNotPromoted(x),
// And further attempts to promote should fail due to the write capture.
- h.promote(x, 'int');
- expect(flow.promotedType(x), isNull);
- });
+ x.read.as_('int').stmt, checkNotPromoted(x),
+ ]);
});
});
@@ -2362,20 +1977,20 @@
});
group('State', () {
- var intVar = _Var('x', _Type('int'));
- var intQVar = _Var('x', _Type('int?'));
- var objectQVar = _Var('x', _Type('Object?'));
- var nullVar = _Var('x', _Type('Null'));
+ var intVar = Var('x', 'int');
+ var intQVar = Var('x', 'int?');
+ var objectQVar = Var('x', 'Object?');
+ var nullVar = Var('x', 'Null');
group('setUnreachable', () {
var unreachable =
- FlowModel<_Var, _Type>(Reachability.initial.setUnreachable());
- var reachable = FlowModel<_Var, _Type>(Reachability.initial);
+ FlowModel<Var, Type>(Reachability.initial.setUnreachable());
+ var reachable = FlowModel<Var, Type>(Reachability.initial);
test('unchanged', () {
expect(unreachable.setUnreachable(), same(unreachable));
});
test('changed', () {
- void _check(FlowModel<_Var, _Type> initial) {
+ void _check(FlowModel<Var, Type> initial) {
var s = initial.setUnreachable();
expect(s, isNot(same(initial)));
expect(s.reachable.overallReachable, false);
@@ -2387,33 +2002,33 @@
});
test('split', () {
- var s1 = FlowModel<_Var, _Type>(Reachability.initial);
+ var s1 = FlowModel<Var, Type>(Reachability.initial);
var s2 = s1.split();
expect(s2.reachable.parent, same(s1.reachable));
});
test('unsplit', () {
- var s1 = FlowModel<_Var, _Type>(Reachability.initial.split());
+ var s1 = FlowModel<Var, Type>(Reachability.initial.split());
var s2 = s1.unsplit();
expect(s2.reachable, same(Reachability.initial));
});
group('unsplitTo', () {
test('no change', () {
- var s1 = FlowModel<_Var, _Type>(Reachability.initial.split());
+ var s1 = FlowModel<Var, Type>(Reachability.initial.split());
var result = s1.unsplitTo(s1.reachable.parent);
expect(result, same(s1));
});
test('unsplit once, reachable', () {
- var s1 = FlowModel<_Var, _Type>(Reachability.initial.split());
+ var s1 = FlowModel<Var, Type>(Reachability.initial.split());
var s2 = s1.split();
var result = s2.unsplitTo(s1.reachable.parent);
expect(result.reachable, same(s1.reachable));
});
test('unsplit once, unreachable', () {
- var s1 = FlowModel<_Var, _Type>(Reachability.initial.split());
+ var s1 = FlowModel<Var, Type>(Reachability.initial.split());
var s2 = s1.split().setUnreachable();
var result = s2.unsplitTo(s1.reachable.parent);
expect(result.reachable.locallyReachable, false);
@@ -2421,7 +2036,7 @@
});
test('unsplit twice, reachable', () {
- var s1 = FlowModel<_Var, _Type>(Reachability.initial.split());
+ var s1 = FlowModel<Var, Type>(Reachability.initial.split());
var s2 = s1.split();
var s3 = s2.split();
var result = s3.unsplitTo(s1.reachable.parent);
@@ -2429,7 +2044,7 @@
});
test('unsplit twice, top unreachable', () {
- var s1 = FlowModel<_Var, _Type>(Reachability.initial.split());
+ var s1 = FlowModel<Var, Type>(Reachability.initial.split());
var s2 = s1.split();
var s3 = s2.split().setUnreachable();
var result = s3.unsplitTo(s1.reachable.parent);
@@ -2438,7 +2053,7 @@
});
test('unsplit twice, previous unreachable', () {
- var s1 = FlowModel<_Var, _Type>(Reachability.initial.split());
+ var s1 = FlowModel<Var, Type>(Reachability.initial.split());
var s2 = s1.split().setUnreachable();
var s3 = s2.split();
var result = s3.unsplitTo(s1.reachable.parent);
@@ -2449,30 +2064,30 @@
group('tryPromoteForTypeCheck', () {
test('unpromoted -> unchanged (same)', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial);
- var s2 = s1.tryPromoteForTypeCheck(h, intVar, _Type('int')).ifTrue;
+ var h = Harness();
+ var s1 = FlowModel<Var, Type>(Reachability.initial);
+ var s2 = s1.tryPromoteForTypeCheck(h, intVar, Type('int')).ifTrue;
expect(s2, same(s1));
});
test('unpromoted -> unchanged (supertype)', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial);
- var s2 = s1.tryPromoteForTypeCheck(h, intVar, _Type('Object')).ifTrue;
+ var h = Harness();
+ var s1 = FlowModel<Var, Type>(Reachability.initial);
+ var s2 = s1.tryPromoteForTypeCheck(h, intVar, Type('Object')).ifTrue;
expect(s2, same(s1));
});
test('unpromoted -> unchanged (unrelated)', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial);
- var s2 = s1.tryPromoteForTypeCheck(h, intVar, _Type('String')).ifTrue;
+ var h = Harness();
+ var s1 = FlowModel<Var, Type>(Reachability.initial);
+ var s2 = s1.tryPromoteForTypeCheck(h, intVar, Type('String')).ifTrue;
expect(s2, same(s1));
});
test('unpromoted -> subtype', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial);
- var s2 = s1.tryPromoteForTypeCheck(h, intQVar, _Type('int')).ifTrue;
+ var h = Harness();
+ var s1 = FlowModel<Var, Type>(Reachability.initial);
+ var s2 = s1.tryPromoteForTypeCheck(h, intQVar, Type('int')).ifTrue;
expect(s2.reachable.overallReachable, true);
expect(s2.variableInfo, {
intQVar: _matchVariableModel(chain: ['int'], ofInterest: ['int'])
@@ -2480,40 +2095,40 @@
});
test('promoted -> unchanged (same)', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial)
- .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+ var h = Harness();
+ var s1 = FlowModel<Var, Type>(Reachability.initial)
+ .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
.ifTrue;
- var s2 = s1.tryPromoteForTypeCheck(h, objectQVar, _Type('int')).ifTrue;
+ var s2 = s1.tryPromoteForTypeCheck(h, objectQVar, Type('int')).ifTrue;
expect(s2, same(s1));
});
test('promoted -> unchanged (supertype)', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial)
- .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+ var h = Harness();
+ var s1 = FlowModel<Var, Type>(Reachability.initial)
+ .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
.ifTrue;
var s2 =
- s1.tryPromoteForTypeCheck(h, objectQVar, _Type('Object')).ifTrue;
+ s1.tryPromoteForTypeCheck(h, objectQVar, Type('Object')).ifTrue;
expect(s2, same(s1));
});
test('promoted -> unchanged (unrelated)', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial)
- .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+ var h = Harness();
+ var s1 = FlowModel<Var, Type>(Reachability.initial)
+ .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
.ifTrue;
var s2 =
- s1.tryPromoteForTypeCheck(h, objectQVar, _Type('String')).ifTrue;
+ s1.tryPromoteForTypeCheck(h, objectQVar, Type('String')).ifTrue;
expect(s2, same(s1));
});
test('promoted -> subtype', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial)
- .tryPromoteForTypeCheck(h, objectQVar, _Type('int?'))
+ var h = Harness();
+ var s1 = FlowModel<Var, Type>(Reachability.initial)
+ .tryPromoteForTypeCheck(h, objectQVar, Type('int?'))
.ifTrue;
- var s2 = s1.tryPromoteForTypeCheck(h, objectQVar, _Type('int')).ifTrue;
+ var s2 = s1.tryPromoteForTypeCheck(h, objectQVar, Type('int')).ifTrue;
expect(s2.reachable.overallReachable, true);
expect(s2.variableInfo, {
objectQVar: _matchVariableModel(
@@ -2523,29 +2138,29 @@
});
group('write', () {
- var objectQVar = _Var('x', _Type('Object?'));
+ var objectQVar = Var('x', 'Object?');
test('without declaration', () {
// This should not happen in valid code, but test that we don't crash.
- var h = _Harness();
- var s = FlowModel<_Var, _Type>(Reachability.initial)
- .write(objectQVar, _Type('Object?'), h);
+ var h = Harness();
+ var s = FlowModel<Var, Type>(Reachability.initial)
+ .write(objectQVar, Type('Object?'), h);
expect(s.variableInfo[objectQVar], isNull);
});
test('unchanged', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+ var h = Harness();
+ var s1 = FlowModel<Var, Type>(Reachability.initial)
.declare(objectQVar, true);
- var s2 = s1.write(objectQVar, _Type('Object?'), h);
+ var s2 = s1.write(objectQVar, Type('Object?'), h);
expect(s2, same(s1));
});
test('marks as assigned', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+ var h = Harness();
+ var s1 = FlowModel<Var, Type>(Reachability.initial)
.declare(objectQVar, false);
- var s2 = s1.write(objectQVar, _Type('int?'), h);
+ var s2 = s1.write(objectQVar, Type('int?'), h);
expect(s2.reachable.overallReachable, true);
expect(
s2.infoFor(objectQVar),
@@ -2557,13 +2172,13 @@
});
test('un-promotes fully', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+ var h = Harness();
+ var s1 = FlowModel<Var, Type>(Reachability.initial)
.declare(objectQVar, true)
- .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+ .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
.ifTrue;
expect(s1.variableInfo, contains(objectQVar));
- var s2 = s1.write(objectQVar, _Type('int?'), h);
+ var s2 = s1.write(objectQVar, Type('int?'), h);
expect(s2.reachable.overallReachable, true);
expect(s2.variableInfo, {
objectQVar: _matchVariableModel(
@@ -2575,12 +2190,12 @@
});
test('un-promotes partially, when no exact match', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+ var h = Harness();
+ var s1 = FlowModel<Var, Type>(Reachability.initial)
.declare(objectQVar, true)
- .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
+ .tryPromoteForTypeCheck(h, objectQVar, Type('num?'))
.ifTrue
- .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+ .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
.ifTrue;
expect(s1.variableInfo, {
objectQVar: _matchVariableModel(
@@ -2589,7 +2204,7 @@
assigned: true,
unassigned: false)
});
- var s2 = s1.write(objectQVar, _Type('num'), h);
+ var s2 = s1.write(objectQVar, Type('num'), h);
expect(s2.reachable.overallReachable, true);
expect(s2.variableInfo, {
objectQVar: _matchVariableModel(
@@ -2601,14 +2216,14 @@
});
test('un-promotes partially, when exact match', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+ var h = Harness();
+ var s1 = FlowModel<Var, Type>(Reachability.initial)
.declare(objectQVar, true)
- .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
+ .tryPromoteForTypeCheck(h, objectQVar, Type('num?'))
.ifTrue
- .tryPromoteForTypeCheck(h, objectQVar, _Type('num'))
+ .tryPromoteForTypeCheck(h, objectQVar, Type('num'))
.ifTrue
- .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+ .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
.ifTrue;
expect(s1.variableInfo, {
objectQVar: _matchVariableModel(
@@ -2617,7 +2232,7 @@
assigned: true,
unassigned: false)
});
- var s2 = s1.write(objectQVar, _Type('num'), h);
+ var s2 = s1.write(objectQVar, Type('num'), h);
expect(s2.reachable.overallReachable, true);
expect(s2.variableInfo, {
objectQVar: _matchVariableModel(
@@ -2629,12 +2244,12 @@
});
test('leaves promoted, when exact match', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+ var h = Harness();
+ var s1 = FlowModel<Var, Type>(Reachability.initial)
.declare(objectQVar, true)
- .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
+ .tryPromoteForTypeCheck(h, objectQVar, Type('num?'))
.ifTrue
- .tryPromoteForTypeCheck(h, objectQVar, _Type('num'))
+ .tryPromoteForTypeCheck(h, objectQVar, Type('num'))
.ifTrue;
expect(s1.variableInfo, {
objectQVar: _matchVariableModel(
@@ -2643,18 +2258,18 @@
assigned: true,
unassigned: false)
});
- var s2 = s1.write(objectQVar, _Type('num'), h);
+ var s2 = s1.write(objectQVar, Type('num'), h);
expect(s2.reachable.overallReachable, true);
expect(s2.variableInfo, same(s1.variableInfo));
});
test('leaves promoted, when writing a subtype', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+ var h = Harness();
+ var s1 = FlowModel<Var, Type>(Reachability.initial)
.declare(objectQVar, true)
- .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
+ .tryPromoteForTypeCheck(h, objectQVar, Type('num?'))
.ifTrue
- .tryPromoteForTypeCheck(h, objectQVar, _Type('num'))
+ .tryPromoteForTypeCheck(h, objectQVar, Type('num'))
.ifTrue;
expect(s1.variableInfo, {
objectQVar: _matchVariableModel(
@@ -2663,34 +2278,32 @@
assigned: true,
unassigned: false)
});
- var s2 = s1.write(objectQVar, _Type('int'), h);
+ var s2 = s1.write(objectQVar, Type('int'), h);
expect(s2.reachable.overallReachable, true);
expect(s2.variableInfo, same(s1.variableInfo));
});
group('Promotes to NonNull of a type of interest', () {
test('when declared type', () {
- var h = _Harness();
- var x = _Var('x', _Type('int?'));
+ var h = Harness();
+ var x = Var('x', 'int?');
- var s1 =
- FlowModel<_Var, _Type>(Reachability.initial).declare(x, true);
+ var s1 = FlowModel<Var, Type>(Reachability.initial).declare(x, true);
expect(s1.variableInfo, {
x: _matchVariableModel(chain: null),
});
- var s2 = s1.write(x, _Type('int'), h);
+ var s2 = s1.write(x, Type('int'), h);
expect(s2.variableInfo, {
x: _matchVariableModel(chain: ['int']),
});
});
test('when declared type, if write-captured', () {
- var h = _Harness();
- var x = h.addVar('x', 'int?');
+ var h = Harness();
+ var x = Var('x', 'int?');
- var s1 =
- FlowModel<_Var, _Type>(Reachability.initial).declare(x, true);
+ var s1 = FlowModel<Var, Type>(Reachability.initial).declare(x, true);
expect(s1.variableInfo, {
x: _matchVariableModel(chain: null),
});
@@ -2701,17 +2314,17 @@
});
// 'x' is write-captured, so not promoted
- var s3 = s2.write(x, _Type('int'), h);
+ var s3 = s2.write(x, Type('int'), h);
expect(s3.variableInfo, {
x: _matchVariableModel(chain: null, writeCaptured: true),
});
});
test('when promoted', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+ var h = Harness();
+ var s1 = FlowModel<Var, Type>(Reachability.initial)
.declare(objectQVar, true)
- .tryPromoteForTypeCheck(h, objectQVar, _Type('int?'))
+ .tryPromoteForTypeCheck(h, objectQVar, Type('int?'))
.ifTrue;
expect(s1.variableInfo, {
objectQVar: _matchVariableModel(
@@ -2719,7 +2332,7 @@
ofInterest: ['int?'],
),
});
- var s2 = s1.write(objectQVar, _Type('int'), h);
+ var s2 = s1.write(objectQVar, Type('int'), h);
expect(s2.variableInfo, {
objectQVar: _matchVariableModel(
chain: ['int?', 'int'],
@@ -2729,10 +2342,10 @@
});
test('when not promoted', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+ var h = Harness();
+ var s1 = FlowModel<Var, Type>(Reachability.initial)
.declare(objectQVar, true)
- .tryPromoteForTypeCheck(h, objectQVar, _Type('int?'))
+ .tryPromoteForTypeCheck(h, objectQVar, Type('int?'))
.ifFalse;
expect(s1.variableInfo, {
objectQVar: _matchVariableModel(
@@ -2740,7 +2353,7 @@
ofInterest: ['int?'],
),
});
- var s2 = s1.write(objectQVar, _Type('int'), h);
+ var s2 = s1.write(objectQVar, Type('int'), h);
expect(s2.variableInfo, {
objectQVar: _matchVariableModel(
chain: ['Object', 'int'],
@@ -2751,10 +2364,10 @@
});
test('Promotes to type of interest when not previously promoted', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+ var h = Harness();
+ var s1 = FlowModel<Var, Type>(Reachability.initial)
.declare(objectQVar, true)
- .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
+ .tryPromoteForTypeCheck(h, objectQVar, Type('num?'))
.ifFalse;
expect(s1.variableInfo, {
objectQVar: _matchVariableModel(
@@ -2762,7 +2375,7 @@
ofInterest: ['num?'],
),
});
- var s2 = s1.write(objectQVar, _Type('num?'), h);
+ var s2 = s1.write(objectQVar, Type('num?'), h);
expect(s2.variableInfo, {
objectQVar: _matchVariableModel(
chain: ['num?'],
@@ -2772,12 +2385,12 @@
});
test('Promotes to type of interest when previously promoted', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+ var h = Harness();
+ var s1 = FlowModel<Var, Type>(Reachability.initial)
.declare(objectQVar, true)
- .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
+ .tryPromoteForTypeCheck(h, objectQVar, Type('num?'))
.ifTrue
- .tryPromoteForTypeCheck(h, objectQVar, _Type('int?'))
+ .tryPromoteForTypeCheck(h, objectQVar, Type('int?'))
.ifFalse;
expect(s1.variableInfo, {
objectQVar: _matchVariableModel(
@@ -2785,7 +2398,7 @@
ofInterest: ['num?', 'int?'],
),
});
- var s2 = s1.write(objectQVar, _Type('int?'), h);
+ var s2 = s1.write(objectQVar, Type('int?'), h);
expect(s2.variableInfo, {
objectQVar: _matchVariableModel(
chain: ['num?', 'int?'],
@@ -2796,56 +2409,56 @@
group('Multiple candidate types of interest', () {
group('; choose most specific', () {
- _Harness h;
+ Harness h;
setUp(() {
- h = _Harness();
+ h = Harness();
// class A {}
// class B extends A {}
// class C extends B {}
- h.addSubtype(_Type('Object'), _Type('A'), false);
- h.addSubtype(_Type('Object'), _Type('A?'), false);
- h.addSubtype(_Type('Object'), _Type('B?'), false);
- h.addSubtype(_Type('A'), _Type('Object'), true);
- h.addSubtype(_Type('A'), _Type('Object?'), true);
- h.addSubtype(_Type('A'), _Type('A?'), true);
- h.addSubtype(_Type('A'), _Type('B'), false);
- h.addSubtype(_Type('A'), _Type('B?'), false);
- h.addSubtype(_Type('A?'), _Type('Object'), false);
- h.addSubtype(_Type('A?'), _Type('Object?'), true);
- h.addSubtype(_Type('A?'), _Type('A'), false);
- h.addSubtype(_Type('A?'), _Type('B?'), false);
- h.addSubtype(_Type('B'), _Type('Object'), true);
- h.addSubtype(_Type('B'), _Type('A'), true);
- h.addSubtype(_Type('B'), _Type('A?'), true);
- h.addSubtype(_Type('B'), _Type('B?'), true);
- h.addSubtype(_Type('B?'), _Type('Object'), false);
- h.addSubtype(_Type('B?'), _Type('Object?'), true);
- h.addSubtype(_Type('B?'), _Type('A'), false);
- h.addSubtype(_Type('B?'), _Type('A?'), true);
- h.addSubtype(_Type('B?'), _Type('B'), false);
- h.addSubtype(_Type('C'), _Type('Object'), true);
- h.addSubtype(_Type('C'), _Type('A'), true);
- h.addSubtype(_Type('C'), _Type('A?'), true);
- h.addSubtype(_Type('C'), _Type('B'), true);
- h.addSubtype(_Type('C'), _Type('B?'), true);
+ h.addSubtype(Type('Object'), Type('A'), false);
+ h.addSubtype(Type('Object'), Type('A?'), false);
+ h.addSubtype(Type('Object'), Type('B?'), false);
+ h.addSubtype(Type('A'), Type('Object'), true);
+ h.addSubtype(Type('A'), Type('Object?'), true);
+ h.addSubtype(Type('A'), Type('A?'), true);
+ h.addSubtype(Type('A'), Type('B'), false);
+ h.addSubtype(Type('A'), Type('B?'), false);
+ h.addSubtype(Type('A?'), Type('Object'), false);
+ h.addSubtype(Type('A?'), Type('Object?'), true);
+ h.addSubtype(Type('A?'), Type('A'), false);
+ h.addSubtype(Type('A?'), Type('B?'), false);
+ h.addSubtype(Type('B'), Type('Object'), true);
+ h.addSubtype(Type('B'), Type('A'), true);
+ h.addSubtype(Type('B'), Type('A?'), true);
+ h.addSubtype(Type('B'), Type('B?'), true);
+ h.addSubtype(Type('B?'), Type('Object'), false);
+ h.addSubtype(Type('B?'), Type('Object?'), true);
+ h.addSubtype(Type('B?'), Type('A'), false);
+ h.addSubtype(Type('B?'), Type('A?'), true);
+ h.addSubtype(Type('B?'), Type('B'), false);
+ h.addSubtype(Type('C'), Type('Object'), true);
+ h.addSubtype(Type('C'), Type('A'), true);
+ h.addSubtype(Type('C'), Type('A?'), true);
+ h.addSubtype(Type('C'), Type('B'), true);
+ h.addSubtype(Type('C'), Type('B?'), true);
- h.addFactor(_Type('Object'), _Type('A?'), _Type('Object'));
- h.addFactor(_Type('Object'), _Type('B?'), _Type('Object'));
- h.addFactor(_Type('Object?'), _Type('A'), _Type('Object?'));
- h.addFactor(_Type('Object?'), _Type('A?'), _Type('Object'));
- h.addFactor(_Type('Object?'), _Type('B?'), _Type('Object'));
+ h.addFactor(Type('Object'), Type('A?'), Type('Object'));
+ h.addFactor(Type('Object'), Type('B?'), Type('Object'));
+ h.addFactor(Type('Object?'), Type('A'), Type('Object?'));
+ h.addFactor(Type('Object?'), Type('A?'), Type('Object'));
+ h.addFactor(Type('Object?'), Type('B?'), Type('Object'));
});
test('; first', () {
- var x = _Var('x', _Type('Object?'));
+ var x = Var('x', 'Object?');
- var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+ var s1 = FlowModel<Var, Type>(Reachability.initial)
.declare(x, true)
- .tryPromoteForTypeCheck(h, x, _Type('B?'))
+ .tryPromoteForTypeCheck(h, x, Type('B?'))
.ifFalse
- .tryPromoteForTypeCheck(h, x, _Type('A?'))
+ .tryPromoteForTypeCheck(h, x, Type('A?'))
.ifFalse;
expect(s1.variableInfo, {
x: _matchVariableModel(
@@ -2854,7 +2467,7 @@
),
});
- var s2 = s1.write(x, _Type('C'), h);
+ var s2 = s1.write(x, Type('C'), h);
expect(s2.variableInfo, {
x: _matchVariableModel(
chain: ['Object', 'B'],
@@ -2864,13 +2477,13 @@
});
test('; second', () {
- var x = _Var('x', _Type('Object?'));
+ var x = Var('x', 'Object?');
- var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+ var s1 = FlowModel<Var, Type>(Reachability.initial)
.declare(x, true)
- .tryPromoteForTypeCheck(h, x, _Type('A?'))
+ .tryPromoteForTypeCheck(h, x, Type('A?'))
.ifFalse
- .tryPromoteForTypeCheck(h, x, _Type('B?'))
+ .tryPromoteForTypeCheck(h, x, Type('B?'))
.ifFalse;
expect(s1.variableInfo, {
x: _matchVariableModel(
@@ -2879,7 +2492,7 @@
),
});
- var s2 = s1.write(x, _Type('C'), h);
+ var s2 = s1.write(x, Type('C'), h);
expect(s2.variableInfo, {
x: _matchVariableModel(
chain: ['Object', 'B'],
@@ -2889,13 +2502,13 @@
});
test('; nullable and non-nullable', () {
- var x = _Var('x', _Type('Object?'));
+ var x = Var('x', 'Object?');
- var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+ var s1 = FlowModel<Var, Type>(Reachability.initial)
.declare(x, true)
- .tryPromoteForTypeCheck(h, x, _Type('A'))
+ .tryPromoteForTypeCheck(h, x, Type('A'))
.ifFalse
- .tryPromoteForTypeCheck(h, x, _Type('A?'))
+ .tryPromoteForTypeCheck(h, x, Type('A?'))
.ifFalse;
expect(s1.variableInfo, {
x: _matchVariableModel(
@@ -2904,7 +2517,7 @@
),
});
- var s2 = s1.write(x, _Type('B'), h);
+ var s2 = s1.write(x, Type('B'), h);
expect(s2.variableInfo, {
x: _matchVariableModel(
chain: ['Object', 'A'],
@@ -2916,12 +2529,12 @@
group('; ambiguous', () {
test('; no promotion', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+ var h = Harness();
+ var s1 = FlowModel<Var, Type>(Reachability.initial)
.declare(objectQVar, true)
- .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
+ .tryPromoteForTypeCheck(h, objectQVar, Type('num?'))
.ifFalse
- .tryPromoteForTypeCheck(h, objectQVar, _Type('num*'))
+ .tryPromoteForTypeCheck(h, objectQVar, Type('num*'))
.ifFalse;
expect(s1.variableInfo, {
objectQVar: _matchVariableModel(
@@ -2929,7 +2542,7 @@
ofInterest: ['num?', 'num*'],
),
});
- var s2 = s1.write(objectQVar, _Type('int'), h);
+ var s2 = s1.write(objectQVar, Type('int'), h);
// It's ambiguous whether to promote to num? or num*, so we don't
// promote.
expect(s2, same(s1));
@@ -2937,12 +2550,12 @@
});
test('exact match', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+ var h = Harness();
+ var s1 = FlowModel<Var, Type>(Reachability.initial)
.declare(objectQVar, true)
- .tryPromoteForTypeCheck(h, objectQVar, _Type('num?'))
+ .tryPromoteForTypeCheck(h, objectQVar, Type('num?'))
.ifFalse
- .tryPromoteForTypeCheck(h, objectQVar, _Type('num*'))
+ .tryPromoteForTypeCheck(h, objectQVar, Type('num*'))
.ifFalse;
expect(s1.variableInfo, {
objectQVar: _matchVariableModel(
@@ -2950,7 +2563,7 @@
ofInterest: ['num?', 'num*'],
),
});
- var s2 = s1.write(objectQVar, _Type('num?'), h);
+ var s2 = s1.write(objectQVar, Type('num?'), h);
// It's ambiguous whether to promote to num? or num*, but since the
// written type is exactly num?, we use that.
expect(s2.variableInfo, {
@@ -2965,15 +2578,15 @@
group('demotion, to NonNull', () {
test('when promoted via test', () {
- var x = _Var('x', _Type('Object?'));
+ var x = Var('x', 'Object?');
- var h = _Harness();
+ var h = Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+ var s1 = FlowModel<Var, Type>(Reachability.initial)
.declare(x, true)
- .tryPromoteForTypeCheck(h, x, _Type('num?'))
+ .tryPromoteForTypeCheck(h, x, Type('num?'))
.ifTrue
- .tryPromoteForTypeCheck(h, x, _Type('int?'))
+ .tryPromoteForTypeCheck(h, x, Type('int?'))
.ifTrue;
expect(s1.variableInfo, {
x: _matchVariableModel(
@@ -2982,7 +2595,7 @@
),
});
- var s2 = s1.write(x, _Type('double'), h);
+ var s2 = s1.write(x, Type('double'), h);
expect(s2.variableInfo, {
x: _matchVariableModel(
chain: ['num?', 'num'],
@@ -2993,10 +2606,10 @@
});
group('declare', () {
- var objectQVar = _Var('x', _Type('Object?'));
+ var objectQVar = Var('x', 'Object?');
test('initialized', () {
- var s = FlowModel<_Var, _Type>(Reachability.initial)
+ var s = FlowModel<Var, Type>(Reachability.initial)
.declare(objectQVar, true);
expect(s.variableInfo, {
objectQVar: _matchVariableModel(assigned: true, unassigned: false),
@@ -3004,7 +2617,7 @@
});
test('not initialized', () {
- var s = FlowModel<_Var, _Type>(Reachability.initial)
+ var s = FlowModel<Var, Type>(Reachability.initial)
.declare(objectQVar, false);
expect(s.variableInfo, {
objectQVar: _matchVariableModel(assigned: false, unassigned: true),
@@ -3014,15 +2627,15 @@
group('markNonNullable', () {
test('unpromoted -> unchanged', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial);
+ var h = Harness();
+ var s1 = FlowModel<Var, Type>(Reachability.initial);
var s2 = s1.tryMarkNonNullable(h, intVar).ifTrue;
expect(s2, same(s1));
});
test('unpromoted -> promoted', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial);
+ var h = Harness();
+ var s1 = FlowModel<Var, Type>(Reachability.initial);
var s2 = s1.tryMarkNonNullable(h, intQVar).ifTrue;
expect(s2.reachable.overallReachable, true);
expect(s2.infoFor(intQVar),
@@ -3030,18 +2643,18 @@
});
test('promoted -> unchanged', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial)
- .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+ var h = Harness();
+ var s1 = FlowModel<Var, Type>(Reachability.initial)
+ .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
.ifTrue;
var s2 = s1.tryMarkNonNullable(h, objectQVar).ifTrue;
expect(s2, same(s1));
});
test('promoted -> re-promoted', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial)
- .tryPromoteForTypeCheck(h, objectQVar, _Type('int?'))
+ var h = Harness();
+ var s1 = FlowModel<Var, Type>(Reachability.initial)
+ .tryPromoteForTypeCheck(h, objectQVar, Type('int?'))
.ifTrue;
var s2 = s1.tryMarkNonNullable(h, objectQVar).ifTrue;
expect(s2.reachable.overallReachable, true);
@@ -3052,8 +2665,8 @@
});
test('promote to Never', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial);
+ var h = Harness();
+ var s1 = FlowModel<Var, Type>(Reachability.initial);
var s2 = s1.tryMarkNonNullable(h, nullVar).ifTrue;
expect(s2.reachable.overallReachable, false);
expect(s2.infoFor(nullVar),
@@ -3064,21 +2677,21 @@
group('joinUnassigned', () {
group('other', () {
test('unchanged', () {
- var h = _Harness();
+ var h = Harness();
- var a = _Var('a', _Type('int'));
- var b = _Var('b', _Type('int'));
+ var a = Var('a', 'int');
+ var b = Var('b', 'int');
- var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+ var s1 = FlowModel<Var, Type>(Reachability.initial)
.declare(a, false)
.declare(b, false)
- .write(a, _Type('int'), h);
+ .write(a, Type('int'), h);
expect(s1.variableInfo, {
a: _matchVariableModel(assigned: true, unassigned: false),
b: _matchVariableModel(assigned: false, unassigned: true),
});
- var s2 = s1.write(a, _Type('int'), h);
+ var s2 = s1.write(a, Type('int'), h);
expect(s2.variableInfo, {
a: _matchVariableModel(assigned: true, unassigned: false),
b: _matchVariableModel(assigned: false, unassigned: true),
@@ -3089,24 +2702,24 @@
});
test('changed', () {
- var h = _Harness();
+ var h = Harness();
- var a = _Var('a', _Type('int'));
- var b = _Var('b', _Type('int'));
- var c = _Var('c', _Type('int'));
+ var a = Var('a', 'int');
+ var b = Var('b', 'int');
+ var c = Var('c', 'int');
- var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+ var s1 = FlowModel<Var, Type>(Reachability.initial)
.declare(a, false)
.declare(b, false)
.declare(c, false)
- .write(a, _Type('int'), h);
+ .write(a, Type('int'), h);
expect(s1.variableInfo, {
a: _matchVariableModel(assigned: true, unassigned: false),
b: _matchVariableModel(assigned: false, unassigned: true),
c: _matchVariableModel(assigned: false, unassigned: true),
});
- var s2 = s1.write(b, _Type('int'), h);
+ var s2 = s1.write(b, Type('int'), h);
expect(s2.variableInfo, {
a: _matchVariableModel(assigned: true, unassigned: false),
b: _matchVariableModel(assigned: true, unassigned: false),
@@ -3125,21 +2738,21 @@
group('conservativeJoin', () {
test('unchanged', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial)
+ var h = Harness();
+ var s1 = FlowModel<Var, Type>(Reachability.initial)
.declare(intQVar, true)
- .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+ .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
.ifTrue;
var s2 = s1.conservativeJoin([intQVar], []);
expect(s2, same(s1));
});
test('written', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial)
- .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+ var h = Harness();
+ var s1 = FlowModel<Var, Type>(Reachability.initial)
+ .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
.ifTrue
- .tryPromoteForTypeCheck(h, intQVar, _Type('int'))
+ .tryPromoteForTypeCheck(h, intQVar, Type('int'))
.ifTrue;
var s2 = s1.conservativeJoin([intQVar], []);
expect(s2.reachable.overallReachable, true);
@@ -3150,11 +2763,11 @@
});
test('write captured', () {
- var h = _Harness();
- var s1 = FlowModel<_Var, _Type>(Reachability.initial)
- .tryPromoteForTypeCheck(h, objectQVar, _Type('int'))
+ var h = Harness();
+ var s1 = FlowModel<Var, Type>(Reachability.initial)
+ .tryPromoteForTypeCheck(h, objectQVar, Type('int'))
.ifTrue
- .tryPromoteForTypeCheck(h, intQVar, _Type('int'))
+ .tryPromoteForTypeCheck(h, intQVar, Type('int'))
.ifTrue;
var s2 = s1.conservativeJoin([], [intQVar]);
expect(s2.reachable.overallReachable, true);
@@ -3168,8 +2781,8 @@
group('restrict', () {
test('reachability', () {
- var h = _Harness();
- var reachable = FlowModel<_Var, _Type>(Reachability.initial);
+ var h = Harness();
+ var reachable = FlowModel<Var, Type>(Reachability.initial);
var unreachable = reachable.setUnreachable();
expect(reachable.restrict(h, reachable, Set()), same(reachable));
expect(reachable.restrict(h, unreachable, Set()), same(unreachable));
@@ -3178,18 +2791,18 @@
});
test('assignments', () {
- var h = _Harness();
- var a = _Var('a', _Type('int'));
- var b = _Var('b', _Type('int'));
- var c = _Var('c', _Type('int'));
- var d = _Var('d', _Type('int'));
- var s0 = FlowModel<_Var, _Type>(Reachability.initial)
+ var h = Harness();
+ var a = Var('a', 'int');
+ var b = Var('b', 'int');
+ var c = Var('c', 'int');
+ var d = Var('d', 'int');
+ var s0 = FlowModel<Var, Type>(Reachability.initial)
.declare(a, false)
.declare(b, false)
.declare(c, false)
.declare(d, false);
- var s1 = s0.write(a, _Type('int'), h).write(b, _Type('int'), h);
- var s2 = s1.write(a, _Type('int'), h).write(c, _Type('int'), h);
+ var s1 = s0.write(a, Type('int'), h).write(b, Type('int'), h);
+ var s2 = s1.write(a, Type('int'), h).write(c, Type('int'), h);
var result = s2.restrict(h, s1, Set());
expect(result.infoFor(a).assigned, true);
expect(result.infoFor(b).assigned, true);
@@ -3198,12 +2811,12 @@
});
test('write captured', () {
- var h = _Harness();
- var a = _Var('a', _Type('int'));
- var b = _Var('b', _Type('int'));
- var c = _Var('c', _Type('int'));
- var d = _Var('d', _Type('int'));
- var s0 = FlowModel<_Var, _Type>(Reachability.initial)
+ var h = Harness();
+ var a = Var('a', 'int');
+ var b = Var('b', 'int');
+ var c = Var('c', 'int');
+ var d = Var('d', 'int');
+ var s0 = FlowModel<Var, Type>(Reachability.initial)
.declare(a, false)
.declare(b, false)
.declare(c, false)
@@ -3233,16 +2846,15 @@
test('promotion', () {
void _check(String thisType, String otherType, bool unsafe,
List<String> expectedChain) {
- var h = _Harness();
- var x = _Var('x', _Type('Object?'));
- var s0 =
- FlowModel<_Var, _Type>(Reachability.initial).declare(x, true);
+ var h = Harness();
+ var x = Var('x', 'Object?');
+ var s0 = FlowModel<Var, Type>(Reachability.initial).declare(x, true);
var s1 = thisType == null
? s0
- : s0.tryPromoteForTypeCheck(h, x, _Type(thisType)).ifTrue;
+ : s0.tryPromoteForTypeCheck(h, x, Type(thisType)).ifTrue;
var s2 = otherType == null
? s0
- : s0.tryPromoteForTypeCheck(h, x, _Type(otherType)).ifTrue;
+ : s0.tryPromoteForTypeCheck(h, x, Type(otherType)).ifTrue;
var result = s1.restrict(h, s2, unsafe ? [x].toSet() : Set());
if (expectedChain == null) {
expect(result.variableInfo, contains(x));
@@ -3270,8 +2882,8 @@
test('promotion chains', () {
// Verify that the given promotion chain matches the expected list of
// strings.
- void _checkChain(List<_Type> chain, List<String> expected) {
- var strings = (chain ?? <_Type>[]).map((t) => t.type).toList();
+ void _checkChain(List<Type> chain, List<String> expected) {
+ var strings = (chain ?? <Type>[]).map((t) => t.type).toList();
expect(strings, expected);
}
@@ -3286,25 +2898,25 @@
// block, the expected promotion chain is [expectedResult].
void _check(List<String> before, List<String> inTry,
List<String> inFinally, List<String> expectedResult) {
- var h = _Harness();
- var x = _Var('x', _Type('Object?'));
+ var h = Harness();
+ var x = Var('x', 'Object?');
var initialModel =
- FlowModel<_Var, _Type>(Reachability.initial).declare(x, true);
+ FlowModel<Var, Type>(Reachability.initial).declare(x, true);
for (var t in before) {
initialModel =
- initialModel.tryPromoteForTypeCheck(h, x, _Type(t)).ifTrue;
+ initialModel.tryPromoteForTypeCheck(h, x, Type(t)).ifTrue;
}
_checkChain(initialModel.infoFor(x).promotedTypes, before);
var tryModel = initialModel;
for (var t in inTry) {
- tryModel = tryModel.tryPromoteForTypeCheck(h, x, _Type(t)).ifTrue;
+ tryModel = tryModel.tryPromoteForTypeCheck(h, x, Type(t)).ifTrue;
}
var expectedTryChain = before.toList()..addAll(inTry);
_checkChain(tryModel.infoFor(x).promotedTypes, expectedTryChain);
var finallyModel = initialModel;
for (var t in inFinally) {
finallyModel =
- finallyModel.tryPromoteForTypeCheck(h, x, _Type(t)).ifTrue;
+ finallyModel.tryPromoteForTypeCheck(h, x, Type(t)).ifTrue;
}
var expectedFinallyChain = before.toList()..addAll(inFinally);
_checkChain(
@@ -3340,9 +2952,9 @@
});
test('variable present in one state but not the other', () {
- var h = _Harness();
- var x = _Var('x', _Type('Object?'));
- var s0 = FlowModel<_Var, _Type>(Reachability.initial);
+ var h = Harness();
+ var x = Var('x', 'Object?');
+ var s0 = FlowModel<Var, Type>(Reachability.initial);
var s1 = s0.declare(x, true);
expect(s0.restrict(h, s1, {}), same(s0));
expect(s0.restrict(h, s1, {x}), same(s0));
@@ -3353,25 +2965,25 @@
});
group('joinPromotionChains', () {
- var doubleType = _Type('double');
- var intType = _Type('int');
- var numType = _Type('num');
- var objectType = _Type('Object');
+ var doubleType = Type('double');
+ var intType = Type('int');
+ var numType = Type('num');
+ var objectType = Type('Object');
test('should handle nulls', () {
- var h = _Harness();
+ var h = Harness();
expect(VariableModel.joinPromotedTypes(null, null, h), null);
expect(VariableModel.joinPromotedTypes(null, [intType], h), null);
expect(VariableModel.joinPromotedTypes([intType], null, h), null);
});
test('should return null if there are no common types', () {
- var h = _Harness();
+ var h = Harness();
expect(VariableModel.joinPromotedTypes([intType], [doubleType], h), null);
});
test('should return common prefix if there are common types', () {
- var h = _Harness();
+ var h = Harness();
expect(
VariableModel.joinPromotedTypes(
[objectType, intType], [objectType, doubleType], h),
@@ -3383,7 +2995,7 @@
});
test('should return an input if it is a prefix of the other', () {
- var h = _Harness();
+ var h = Harness();
var prefix = [objectType, numType];
var largerChain = [objectType, numType, intType];
expect(VariableModel.joinPromotedTypes(prefix, largerChain, h),
@@ -3394,15 +3006,15 @@
});
test('should intersect', () {
- var h = _Harness();
+ var h = Harness();
// F <: E <: D <: C <: B <: A
- var A = _Type('A');
- var B = _Type('B');
- var C = _Type('C');
- var D = _Type('D');
- var E = _Type('E');
- var F = _Type('F');
+ var A = Type('A');
+ var B = Type('B');
+ var C = Type('C');
+ var D = Type('D');
+ var E = Type('E');
+ var F = Type('F');
h.addSubtype(A, B, false);
h.addSubtype(B, A, true);
h.addSubtype(B, C, false);
@@ -3420,7 +3032,7 @@
h.addSubtype(F, D, true);
h.addSubtype(F, E, true);
- void check(List<_Type> chain1, List<_Type> chain2, Matcher matcher) {
+ void check(List<Type> chain1, List<Type> chain2, Matcher matcher) {
expect(
VariableModel.joinPromotedTypes(chain1, chain2, h),
matcher,
@@ -3471,11 +3083,11 @@
});
group('joinTypesOfInterest', () {
- List<_Type> _makeTypes(List<String> typeNames) =>
- typeNames.map((t) => _Type(t)).toList();
+ List<Type> _makeTypes(List<String> typeNames) =>
+ typeNames.map((t) => Type(t)).toList();
test('simple prefix', () {
- var h = _Harness();
+ var h = Harness();
var s1 = _makeTypes(['double', 'int']);
var s2 = _makeTypes(['double', 'int', 'bool']);
var expected = _matchOfInterestSet(['double', 'int', 'bool']);
@@ -3484,7 +3096,7 @@
});
test('common prefix', () {
- var h = _Harness();
+ var h = Harness();
var s1 = _makeTypes(['double', 'int', 'String']);
var s2 = _makeTypes(['double', 'int', 'bool']);
var expected = _matchOfInterestSet(['double', 'int', 'String', 'bool']);
@@ -3493,7 +3105,7 @@
});
test('order mismatch', () {
- var h = _Harness();
+ var h = Harness();
var s1 = _makeTypes(['double', 'int']);
var s2 = _makeTypes(['int', 'double']);
var expected = _matchOfInterestSet(['double', 'int']);
@@ -3502,7 +3114,7 @@
});
test('small common prefix', () {
- var h = _Harness();
+ var h = Harness();
var s1 = _makeTypes(['int', 'double', 'String', 'bool']);
var s2 = _makeTypes(['int', 'List', 'bool', 'Future']);
var expected = _matchOfInterestSet(
@@ -3513,18 +3125,18 @@
});
group('join', () {
- var x = _Var('x', _Type('Object?'));
- var y = _Var('y', _Type('Object?'));
- var z = _Var('z', _Type('Object?'));
- var w = _Var('w', _Type('Object?'));
- var intType = _Type('int');
- var intQType = _Type('int?');
- var stringType = _Type('String');
- const emptyMap = const <_Var, VariableModel<_Var, _Type>>{};
+ var x = Var('x', 'Object?');
+ var y = Var('y', 'Object?');
+ var z = Var('z', 'Object?');
+ var w = Var('w', 'Object?');
+ var intType = Type('int');
+ var intQType = Type('int?');
+ var stringType = Type('String');
+ const emptyMap = const <Var, VariableModel<Var, Type>>{};
- VariableModel<_Var, _Type> model(List<_Type> promotionChain,
- {List<_Type> typesOfInterest, bool assigned = false}) =>
- VariableModel<_Var, _Type>(
+ VariableModel<Var, Type> model(List<Type> promotionChain,
+ {List<Type> typesOfInterest, bool assigned = false}) =>
+ VariableModel<Var, Type>(
promotionChain,
typesOfInterest ?? promotionChain ?? [],
assigned,
@@ -3534,7 +3146,7 @@
group('without input reuse', () {
test('promoted with unpromoted', () {
- var h = _Harness();
+ var h = Harness();
var p1 = {
x: model([intType]),
y: model(null)
@@ -3551,7 +3163,7 @@
});
group('should re-use an input if possible', () {
test('identical inputs', () {
- var h = _Harness();
+ var h = Harness();
var p = {
x: model([intType]),
y: model([stringType])
@@ -3560,18 +3172,18 @@
});
test('one input empty', () {
- var h = _Harness();
+ var h = Harness();
var p1 = {
x: model([intType]),
y: model([stringType])
};
- var p2 = <_Var, VariableModel<_Var, _Type>>{};
+ var p2 = <Var, VariableModel<Var, Type>>{};
expect(FlowModel.joinVariableInfo(h, p1, p2, emptyMap), same(emptyMap));
expect(FlowModel.joinVariableInfo(h, p2, p1, emptyMap), same(emptyMap));
});
test('promoted with unpromoted', () {
- var h = _Harness();
+ var h = Harness();
var p1 = {
x: model([intType])
};
@@ -3584,7 +3196,7 @@
});
test('related type chains', () {
- var h = _Harness();
+ var h = Harness();
var p1 = {
x: model([intQType, intType])
};
@@ -3599,7 +3211,7 @@
});
test('unrelated type chains', () {
- var h = _Harness();
+ var h = Harness();
var p1 = {
x: model([intType])
};
@@ -3614,7 +3226,7 @@
});
test('sub-map', () {
- var h = _Harness();
+ var h = Harness();
var xModel = model([intType]);
var p1 = {
x: xModel,
@@ -3626,7 +3238,7 @@
});
test('sub-map with matched subtype', () {
- var h = _Harness();
+ var h = Harness();
var p1 = {
x: model([intQType, intType]),
y: model([stringType])
@@ -3642,7 +3254,7 @@
});
test('sub-map with mismatched subtype', () {
- var h = _Harness();
+ var h = Harness();
var p1 = {
x: model([intQType]),
y: model([stringType])
@@ -3658,7 +3270,7 @@
});
test('assigned', () {
- var h = _Harness();
+ var h = Harness();
var unassigned = model(null, assigned: false);
var assigned = model(null, assigned: true);
var p1 = {x: assigned, y: assigned, z: unassigned, w: unassigned};
@@ -3675,7 +3287,7 @@
});
test('write captured', () {
- var h = _Harness();
+ var h = Harness();
var intQModel = model([intQType]);
var writeCapturedModel = intQModel.writeCapture();
var p1 = {
@@ -3702,14 +3314,14 @@
});
group('merge', () {
- var x = _Var('x', _Type('Object?'));
- var intType = _Type('int');
- var stringType = _Type('String');
- const emptyMap = const <_Var, VariableModel<_Var, _Type>>{};
+ var x = Var('x', 'Object?');
+ var intType = Type('int');
+ var stringType = Type('String');
+ const emptyMap = const <Var, VariableModel<Var, Type>>{};
- VariableModel<_Var, _Type> varModel(List<_Type> promotionChain,
+ VariableModel<Var, Type> varModel(List<Type> promotionChain,
{bool assigned = false}) =>
- VariableModel<_Var, _Type>(
+ VariableModel<Var, Type>(
promotionChain,
promotionChain ?? [],
assigned,
@@ -3718,14 +3330,14 @@
);
test('first is null', () {
- var h = _Harness();
+ var h = Harness();
var s1 = FlowModel.withInfo(Reachability.initial.split(), {});
var result = FlowModel.merge(h, null, s1, emptyMap);
expect(result.reachable, same(Reachability.initial));
});
test('second is null', () {
- var h = _Harness();
+ var h = Harness();
var splitPoint = Reachability.initial.split();
var afterSplit = splitPoint.split();
var s1 = FlowModel.withInfo(afterSplit, {});
@@ -3734,7 +3346,7 @@
});
test('both are reachable', () {
- var h = _Harness();
+ var h = Harness();
var splitPoint = Reachability.initial.split();
var afterSplit = splitPoint.split();
var s1 = FlowModel.withInfo(afterSplit, {
@@ -3749,7 +3361,7 @@
});
test('first is unreachable', () {
- var h = _Harness();
+ var h = Harness();
var splitPoint = Reachability.initial.split();
var afterSplit = splitPoint.split();
var s1 = FlowModel.withInfo(afterSplit.setUnreachable(), {
@@ -3764,7 +3376,7 @@
});
test('second is unreachable', () {
- var h = _Harness();
+ var h = Harness();
var splitPoint = Reachability.initial.split();
var afterSplit = splitPoint.split();
var s1 = FlowModel.withInfo(afterSplit, {
@@ -3779,7 +3391,7 @@
});
test('both are unreachable', () {
- var h = _Harness();
+ var h = Harness();
var splitPoint = Reachability.initial.split();
var afterSplit = splitPoint.split();
var s1 = FlowModel.withInfo(afterSplit.setUnreachable(), {
@@ -3796,16 +3408,16 @@
});
group('inheritTested', () {
- var x = _Var('x', _Type('Object?'));
- var intType = _Type('int');
- var stringType = _Type('String');
- const emptyMap = const <_Var, VariableModel<_Var, _Type>>{};
+ var x = Var('x', 'Object?');
+ var intType = Type('int');
+ var stringType = Type('String');
+ const emptyMap = const <Var, VariableModel<Var, Type>>{};
- VariableModel<_Var, _Type> model(List<_Type> typesOfInterest) =>
- VariableModel<_Var, _Type>(null, typesOfInterest, true, false, false);
+ VariableModel<Var, Type> model(List<Type> typesOfInterest) =>
+ VariableModel<Var, Type>(null, typesOfInterest, true, false, false);
test('inherits types of interest from other', () {
- var h = _Harness();
+ var h = Harness();
var m1 = FlowModel.withInfo(Reachability.initial, {
x: model([intType])
});
@@ -3817,7 +3429,7 @@
});
test('handles variable missing from other', () {
- var h = _Harness();
+ var h = Harness();
var m1 = FlowModel.withInfo(Reachability.initial, {
x: model([intType])
});
@@ -3826,7 +3438,7 @@
});
test('returns identical model when no changes', () {
- var h = _Harness();
+ var h = Harness();
var m1 = FlowModel.withInfo(Reachability.initial, {
x: model([intType])
});
@@ -3858,7 +3470,7 @@
Matcher _matchOfInterestSet(List<String> expectedTypes) {
return predicate(
- (List<_Type> x) => unorderedEquals(expectedTypes)
+ (List<Type> x) => unorderedEquals(expectedTypes)
.matches(x.map((t) => t.type).toList(), {}),
'interest set $expectedTypes');
}
@@ -3866,7 +3478,7 @@
Matcher _matchPromotionChain(List<String> expectedTypes) {
if (expectedTypes == null) return isNull;
return predicate(
- (List<_Type> x) =>
+ (List<Type> x) =>
equals(expectedTypes).matches(x.map((t) => t.type).toList(), {}),
'promotion chain $expectedTypes');
}
@@ -3885,7 +3497,7 @@
Matcher assignedMatcher = wrapMatcher(assigned);
Matcher unassignedMatcher = wrapMatcher(unassigned);
Matcher writeCapturedMatcher = wrapMatcher(writeCaptured);
- return predicate((VariableModel<_Var, _Type> model) {
+ return predicate((VariableModel<Var, Type> model) {
if (!chainMatcher.matches(model.promotedTypes, {})) return false;
if (!ofInterestMatcher.matches(model.tested, {})) return false;
if (!assignedMatcher.matches(model.assigned, {})) return false;
@@ -3899,459 +3511,3 @@
'unassigned: ${_describeMatcher(unassignedMatcher)}, '
'writeCaptured: ${_describeMatcher(writeCapturedMatcher)})');
}
-
-/// 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 _AssignedVariablesHarness {
- final AssignedVariables<_Node, _Var> _assignedVariables;
-
- _AssignedVariablesHarness(this._assignedVariables);
-
- void function(_Node node, void Function() callback) {
- _assignedVariables.beginNode();
- callback();
- _assignedVariables.endNode(node, isClosureOrLateVariableInitializer: true);
- }
-
- void nest(_Node node, void Function() callback) {
- _assignedVariables.beginNode();
- callback();
- _assignedVariables.endNode(node);
- }
-
- void write(_Var v) {
- _assignedVariables.write(v);
- }
-}
-
-class _Expression {
- static int _idCounter = 0;
-
- final int _id = _idCounter++;
-
- @override
- String toString() => 'E$_id';
-}
-
-class _Harness extends TypeOperations<_Var, _Type> {
- static const Map<String, bool> _coreSubtypes = const {
- 'double <: Object': true,
- 'double <: num': true,
- 'double <: num?': true,
- 'double <: int': false,
- 'double <: int?': false,
- 'int <: double': false,
- 'int <: int?': true,
- 'int <: Iterable': false,
- 'int <: List': false,
- 'int <: Null': false,
- 'int <: num': true,
- 'int <: num?': true,
- 'int <: num*': true,
- 'int <: Never?': false,
- 'int <: Object': true,
- 'int <: Object?': true,
- 'int <: String': false,
- 'int? <: int': false,
- 'int? <: Null': false,
- 'int? <: num': false,
- 'int? <: num?': true,
- 'int? <: Object': false,
- 'int? <: Object?': true,
- 'Null <: int': false,
- 'Null <: Object': false,
- 'num <: int': false,
- 'num <: Iterable': false,
- 'num <: List': false,
- 'num <: num?': true,
- 'num <: num*': true,
- 'num <: Object': true,
- 'num <: Object?': true,
- 'num? <: int?': false,
- 'num? <: num': false,
- 'num? <: num*': true,
- 'num? <: Object': false,
- 'num? <: Object?': true,
- 'num* <: num': true,
- 'num* <: num?': true,
- 'num* <: Object': true,
- 'num* <: Object?': true,
- 'Iterable <: int': false,
- 'Iterable <: num': false,
- 'Iterable <: Object': true,
- 'Iterable <: Object?': true,
- 'List <: int': false,
- 'List <: Iterable': true,
- 'List <: Object': true,
- 'Never <: int': true,
- 'Never <: int?': true,
- 'Never <: Null': true,
- 'Never? <: int': false,
- 'Never? <: int?': true,
- 'Never? <: num?': true,
- 'Never? <: Object?': true,
- 'Null <: int?': true,
- 'Object <: int': false,
- 'Object <: int?': false,
- 'Object <: List': false,
- 'Object <: num': false,
- 'Object <: num?': false,
- 'Object <: Object?': true,
- 'Object? <: Object': false,
- 'Object? <: int': false,
- 'Object? <: int?': false,
- 'String <: int': false,
- 'String <: int?': false,
- 'String <: num?': false,
- 'String <: Object?': true,
- };
-
- static final Map<String, _Type> _coreFactors = {
- 'Object? - int': _Type('Object?'),
- 'Object? - int?': _Type('Object'),
- 'Object? - num?': _Type('Object'),
- 'Object? - Object?': _Type('Never?'),
- 'Object? - String': _Type('Object?'),
- 'Object - int': _Type('Object'),
- 'int - Object': _Type('Never'),
- 'int - String': _Type('int'),
- 'int - int': _Type('Never'),
- 'int - int?': _Type('Never'),
- 'int? - int': _Type('Never?'),
- 'int? - int?': _Type('Never'),
- 'int? - String': _Type('int?'),
- 'Null - int': _Type('Null'),
- 'num - int': _Type('num'),
- 'num? - num': _Type('Never?'),
- 'num? - int': _Type('num?'),
- 'num? - int?': _Type('num'),
- 'num? - Object': _Type('Never?'),
- 'num? - String': _Type('num?'),
- 'Object - int?': _Type('Object'),
- 'Object - num': _Type('Object'),
- 'Object - num?': _Type('Object'),
- 'Object - num*': _Type('Object'),
- 'Object - Iterable': _Type('Object'),
- 'Object? - Object': _Type('Never?'),
- 'Object? - Iterable': _Type('Object?'),
- 'Object? - num': _Type('Object?'),
- 'Iterable - List': _Type('Iterable'),
- 'num* - Object': _Type('Never'),
- };
-
- final Map<String, bool> _subtypes = Map.of(_coreSubtypes);
-
- final Map<String, _Type> _factorResults = Map.of(_coreFactors);
-
- FlowAnalysis<_Node, _Statement, _Expression, _Var, _Type> _flow;
-
- final _assignedVariables = AssignedVariables<_Node, _Var>();
-
- /// Returns a [LazyExpression] representing an expression with now special
- /// flow analysis semantics.
- LazyExpression get expr => () => _Expression();
-
- LazyExpression get nullLiteral => () {
- var expr = _Expression();
- _flow.nullLiteral(expr);
- return expr;
- };
-
- void addFactor(_Type from, _Type what, _Type result) {
- var query = '$from - $what';
- _factorResults[query] = result;
- }
-
- void addSubtype(_Type leftType, _Type rightType, bool isSubtype) {
- var query = '$leftType <: $rightType';
- _subtypes[query] = isSubtype;
- }
-
- _Var addVar(String name, String type) {
- assert(_flow == null);
- return _Var(name, _Type(type));
- }
-
- /// 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_begin();
- _flow.logicalBinaryOp_rightBegin(lhs(), isAnd: true);
- _flow.logicalBinaryOp_end(expr, rhs(), isAnd: true);
- return expr;
- };
- }
-
- void assignedVariables(void Function(_AssignedVariablesHarness) callback) {
- callback(_AssignedVariablesHarness(_assignedVariables));
- }
-
- LazyExpression booleanLiteral(bool value) => () {
- var expr = _Expression();
- _flow.booleanLiteral(expr, value);
- return expr;
- };
-
- @override
- TypeClassification classifyType(_Type type) {
- if (isSubtypeOf(type, _Type('Object'))) {
- return TypeClassification.nonNullable;
- } else if (isSubtypeOf(type, _Type('Null'))) {
- return TypeClassification.nullOrEquivalent;
- } else {
- return TypeClassification.potentiallyNullable;
- }
- }
-
- /// 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_conditionBegin();
- _flow.conditional_thenBegin(cond());
- _flow.conditional_elseBegin(ifTrue());
- _flow.conditional_end(expr, ifFalse());
- return expr;
- };
- }
-
- FlowAnalysis<_Node, _Statement, _Expression, _Var, _Type> createFlow() =>
- FlowAnalysis<_Node, _Statement, _Expression, _Var, _Type>(
- this, _assignedVariables);
-
- void declare(_Var v, {@required bool initialized}) {
- _flow.declare(v, initialized);
- }
-
- /// Creates a [LazyExpression] representing an `== null` check performed on
- /// [variable].
- LazyExpression eqNull(_Var variable, _Type type) {
- return () {
- var varExpr = _Expression();
- _flow.variableRead(varExpr, variable);
- _flow.equalityOp_rightBegin(varExpr, type);
- var nullExpr = _Expression();
- _flow.nullLiteral(nullExpr);
- var expr = _Expression();
- _flow.equalityOp_end(expr, nullExpr, _Type('Null'), notEqual: false);
- return expr;
- };
- }
-
- @override
- _Type factor(_Type from, _Type what) {
- var query = '$from - $what';
- return _factorResults[query] ?? fail('Unknown factor query: $query');
- }
-
- /// Invokes flow analysis of a nested function.
- void function(_Node node, void body()) {
- _flow.functionExpression_begin(node);
- body();
- _flow.functionExpression_end();
- }
-
- /// Invokes flow analysis of an `if` statement with no `else` part.
- void if_(LazyExpression cond, void ifTrue()) {
- _flow.ifStatement_conditionBegin();
- _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_conditionBegin();
- _flow.ifStatement_thenBegin(cond());
- ifTrue();
- _flow.ifStatement_elseBegin();
- ifFalse();
- _flow.ifStatement_end(true);
- }
-
- /// Equivalent for `if (variable is! type) { ifTrue; }`
- void ifIsNotType(_Var variable, String type, void ifTrue()) {
- if_(isNotType(variableRead(variable), type), ifTrue);
- }
-
- @override
- bool isNever(_Type type) {
- return type.type == 'Never';
- }
-
- /// Creates a [LazyExpression] representing an `is!` check, checking whether
- /// [subExpression] has the given [type].
- LazyExpression isNotType(LazyExpression subExpression, String type) {
- return () {
- var expr = _Expression();
- _flow.isExpression_end(expr, subExpression(), true, _Type(type));
- return expr;
- };
- }
-
- @override
- bool isSameType(_Type type1, _Type type2) {
- return type1.type == type2.type;
- }
-
- @override
- bool isSubtypeOf(_Type leftType, _Type rightType) {
- if (leftType.type == rightType.type) return true;
- var query = '$leftType <: $rightType';
- return _subtypes[query] ?? fail('Unknown subtype query: $query');
- }
-
- /// Creates a [LazyExpression] representing an `is` check, checking whether
- /// [subExpression] has the given [type].
- LazyExpression isType(LazyExpression subExpression, String type) {
- return () {
- var expr = _Expression();
- _flow.isExpression_end(expr, subExpression(), false, _Type(type));
- return expr;
- };
- }
-
- /// Invokes flow analysis of a labeled block.
- void labeledBlock(_Statement node, void body()) {
- _flow.labeledStatement_begin(node);
- body();
- _flow.labeledStatement_end();
- }
-
- /// Creates a [LazyExpression] representing an equality check between two
- /// other expressions.
- LazyExpression notEqual(
- LazyExpression lhs, _Type lhsType, LazyExpression rhs, _Type rhsType) {
- return () {
- var expr = _Expression();
- _flow.equalityOp_rightBegin(lhs(), lhsType);
- _flow.equalityOp_end(expr, rhs(), rhsType, notEqual: true);
- return expr;
- };
- }
-
- /// Creates a [LazyExpression] representing a `!= null` check performed on
- /// [variable].
- LazyExpression notNull(_Var variable, _Type type) {
- return () {
- var varExpr = _Expression();
- _flow.variableRead(varExpr, variable);
- _flow.equalityOp_rightBegin(varExpr, type);
- var nullExpr = _Expression();
- _flow.nullLiteral(nullExpr);
- var expr = _Expression();
- _flow.equalityOp_end(expr, nullExpr, _Type('Null'), 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_begin();
- _flow.logicalBinaryOp_rightBegin(lhs(), isAnd: false);
- _flow.logicalBinaryOp_end(expr, rhs(), isAnd: false);
- return expr;
- };
- }
-
- /// Creates a [LazyExpression] representing a parenthesized subexpression.
- LazyExpression parenthesized(LazyExpression inner) {
- return () {
- var expr = _Expression();
- _flow.parenthesizedExpression(expr, inner());
- return expr;
- };
- }
-
- /// Causes [variable] to be promoted to [type].
- void promote(_Var variable, String type) {
- ifIsNotType(variable, type, _flow.handleExit);
- }
-
- @override
- _Type promoteToNonNull(_Type type) {
- if (type.type.endsWith('?')) {
- return _Type(type.type.substring(0, type.type.length - 1));
- } else if (type.type == 'Null') {
- return _Type('Never');
- } else {
- return type;
- }
- }
-
- void run(
- void callback(
- FlowAnalysis<_Node, _Statement, _Expression, _Var, _Type> flow)) {
- assert(_flow == null);
- _flow = createFlow();
- callback(_flow);
- _flow.finish();
- }
-
- @override
- _Type tryPromoteToType(_Type to, _Type from) {
- if (isSubtypeOf(to, from)) {
- return to;
- } else {
- return null;
- }
- }
-
- LazyExpression variableRead(_Var variable) {
- return () {
- var expr = _Expression();
- _flow.variableRead(expr, variable);
- return expr;
- };
- }
-
- @override
- _Type variableType(_Var variable) {
- return variable.type;
- }
-}
-
-class _Node {}
-
-class _Statement extends _Node {}
-
-class _Type {
- final String type;
-
- _Type(this.type);
-
- @override
- bool operator ==(Object other) {
- // The flow analysis engine should not compare types using operator==. It
- // should compare them using TypeOperations.
- fail('Unexpected use of operator== on types');
- }
-
- @override
- String toString() => type;
-}
-
-class _Var {
- final String name;
- final _Type type;
-
- _Var(this.name, this.type);
-
- @override
- String toString() => '$type $name';
-}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/modify_parameters.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/modify_parameters.dart
index 78ae593..b73a574 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/modify_parameters.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/modify_parameters.dart
@@ -59,6 +59,7 @@
var argumentList = data.argumentList;
var arguments = argumentList.arguments;
var argumentCount = arguments.length;
+ var templateContext = TemplateContext(argumentList.parent, fix.utils);
var newNamed = <AddParameter>[];
var indexToNewArgumentMap = <int, AddParameter>{};
var argumentsToInsert = <int>[];
@@ -72,6 +73,13 @@
argumentsToInsert.add(index);
} else if (modification.isRequired) {
newNamed.add(modification);
+ } else {
+ var requiredIfCondition =
+ modification.argumentValue?.requiredIfCondition;
+ if (requiredIfCondition != null &&
+ requiredIfCondition.evaluateIn(templateContext)) {
+ newNamed.add(modification);
+ }
}
} else if (modification is RemoveParameter) {
var argument = modification.parameter.argumentFrom(argumentList);
@@ -95,8 +103,7 @@
builder.write(parameter.name);
builder.write(': ');
}
- parameter.argumentValue
- .writeOn(builder, TemplateContext(argumentList.parent, fix.utils));
+ parameter.argumentValue.writeOn(builder, templateContext);
}
var insertionRanges = argumentsToInsert.contiguousSubRanges.toList();
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_error_code.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_error_code.dart
index 231b44c..508635c 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_error_code.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_error_code.dart
@@ -155,10 +155,18 @@
TransformSetErrorCode('yaml_syntax_error', "Parse error: {0}");
/// Initialize a newly created error code.
- const TransformSetErrorCode(String name, String message,
- {String correction, bool hasPublishedDocs = false})
- : super.temporary(name, message,
- correction: correction, hasPublishedDocs: hasPublishedDocs);
+ const TransformSetErrorCode(
+ String name,
+ String message, {
+ String correction,
+ bool hasPublishedDocs = false,
+ }) : super(
+ correction: correction,
+ hasPublishedDocs: hasPublishedDocs,
+ message: message,
+ name: name,
+ uniqueName: 'TransformSetErrorCode.$name',
+ );
@override
ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/flutter_use_case_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/flutter_use_case_test.dart
index ee53183..7932354 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/flutter_use_case_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/flutter_use_case_test.dart
@@ -599,6 +599,264 @@
''');
}
+ Future<void>
+ test_material_InputDecoration_defaultConstructor_matchFirstCase_deprecated() async {
+ setPackageContent('''
+class InputDecoration {
+ InputDecoration({
+ @deprecated bool hasFloatingPlaceholder: true,
+ FloatingLabelBehavior floatingLabelBehavior: FloatingLabelBehavior.auto,
+ });
+}
+enum FloatingLabelBehavior {always, auto, never}
+''');
+ addPackageDataFile('''
+version: 1
+transforms:
+ - title: 'Rename to floatingLabelBehavior'
+ date: 2020-09-24
+ element:
+ uris: ['$importUri']
+ constructor: ''
+ inClass: 'InputDecoration'
+ oneOf:
+ - if: "hasFloatingPlaceholder == 'true'"
+ changes:
+ - kind: 'addParameter'
+ index: 14
+ name: 'floatingLabelBehavior'
+ style: optional_named
+ argumentValue:
+ expression: '{% FloatingLabelBehavior %}.auto'
+ requiredIf: "hasFloatingPlaceholder == 'true'"
+ variables:
+ FloatingLabelBehavior:
+ kind: 'import'
+ uris: ['$importUri']
+ name: 'FloatingLabelBehavior'
+ - kind: 'removeParameter'
+ name: 'hasFloatingPlaceholder'
+ - if: "hasFloatingPlaceholder == 'false'"
+ changes:
+ - kind: 'addParameter'
+ index: 14
+ name: 'floatingLabelBehavior'
+ style: optional_named
+ argumentValue:
+ expression: '{% FloatingLabelBehavior %}.never'
+ requiredIf: "hasFloatingPlaceholder == 'false'"
+ variables:
+ FloatingLabelBehavior:
+ kind: 'import'
+ uris: ['$importUri']
+ name: 'FloatingLabelBehavior'
+ - kind: 'removeParameter'
+ name: 'hasFloatingPlaceholder'
+ - if: "hasFloatingPlaceholder != 'true' && hasFloatingPlaceholder != 'false'"
+ changes:
+ - kind: 'addParameter'
+ index: 14
+ name: 'floatingLabelBehavior'
+ style: optional_named
+ argumentValue:
+ expression: '{% hasFloatingPlaceholder %} ? {% FloatingLabelBehavior %}.auto : {% FloatingLabelBehavior %}.never'
+ requiredIf: "hasFloatingPlaceholder != 'true' && hasFloatingPlaceholder != 'false'"
+ variables:
+ FloatingLabelBehavior:
+ kind: 'import'
+ uris: ['$importUri']
+ name: 'FloatingLabelBehavior'
+ - kind: 'removeParameter'
+ name: 'hasFloatingPlaceholder'
+ variables:
+ hasFloatingPlaceholder:
+ kind: 'fragment'
+ value: 'arguments[hasFloatingPlaceholder]'
+''');
+ await resolveTestCode('''
+import '$importUri';
+
+InputDecoration f(bool b) => InputDecoration(hasFloatingPlaceholder: true);
+''');
+ await assertHasFix('''
+import '$importUri';
+
+InputDecoration f(bool b) => InputDecoration(floatingLabelBehavior: FloatingLabelBehavior.auto);
+''');
+ }
+
+ Future<void>
+ test_material_InputDecoration_defaultConstructor_matchSecondCase_deprecated() async {
+ setPackageContent('''
+class InputDecoration {
+ InputDecoration({
+ @deprecated bool hasFloatingPlaceholder: true,
+ FloatingLabelBehavior floatingLabelBehavior: FloatingLabelBehavior.auto,
+ });
+}
+enum FloatingLabelBehavior {always, auto, never}
+''');
+ addPackageDataFile('''
+version: 1
+transforms:
+ - title: 'Rename to floatingLabelBehavior'
+ date: 2020-09-24
+ element:
+ uris: ['$importUri']
+ constructor: ''
+ inClass: 'InputDecoration'
+ oneOf:
+ - if: "hasFloatingPlaceholder == 'true'"
+ changes:
+ - kind: 'addParameter'
+ index: 14
+ name: 'floatingLabelBehavior'
+ style: optional_named
+ argumentValue:
+ expression: '{% FloatingLabelBehavior %}.auto'
+ requiredIf: "hasFloatingPlaceholder == 'true'"
+ variables:
+ FloatingLabelBehavior:
+ kind: 'import'
+ uris: ['$importUri']
+ name: 'FloatingLabelBehavior'
+ - kind: 'removeParameter'
+ name: 'hasFloatingPlaceholder'
+ - if: "hasFloatingPlaceholder == 'false'"
+ changes:
+ - kind: 'addParameter'
+ index: 14
+ name: 'floatingLabelBehavior'
+ style: optional_named
+ argumentValue:
+ expression: '{% FloatingLabelBehavior %}.never'
+ requiredIf: "hasFloatingPlaceholder == 'false'"
+ variables:
+ FloatingLabelBehavior:
+ kind: 'import'
+ uris: ['$importUri']
+ name: 'FloatingLabelBehavior'
+ - kind: 'removeParameter'
+ name: 'hasFloatingPlaceholder'
+ - if: "hasFloatingPlaceholder != 'true' && hasFloatingPlaceholder != 'false'"
+ changes:
+ - kind: 'addParameter'
+ index: 14
+ name: 'floatingLabelBehavior'
+ style: optional_named
+ argumentValue:
+ expression: '{% hasFloatingPlaceholder %} ? {% FloatingLabelBehavior %}.auto : {% FloatingLabelBehavior %}.never'
+ requiredIf: "hasFloatingPlaceholder != 'true' && hasFloatingPlaceholder != 'false'"
+ variables:
+ FloatingLabelBehavior:
+ kind: 'import'
+ uris: ['$importUri']
+ name: 'FloatingLabelBehavior'
+ - kind: 'removeParameter'
+ name: 'hasFloatingPlaceholder'
+ variables:
+ hasFloatingPlaceholder:
+ kind: 'fragment'
+ value: 'arguments[hasFloatingPlaceholder]'
+''');
+ await resolveTestCode('''
+import '$importUri';
+
+InputDecoration f(bool b) => InputDecoration(hasFloatingPlaceholder: false);
+''');
+ await assertHasFix('''
+import '$importUri';
+
+InputDecoration f(bool b) => InputDecoration(floatingLabelBehavior: FloatingLabelBehavior.never);
+''');
+ }
+
+ Future<void>
+ test_material_InputDecoration_defaultConstructor_matchThirdCase_deprecated() async {
+ setPackageContent('''
+class InputDecoration {
+ InputDecoration({
+ @deprecated bool hasFloatingPlaceholder: true,
+ FloatingLabelBehavior floatingLabelBehavior: FloatingLabelBehavior.auto,
+ });
+}
+enum FloatingLabelBehavior {always, auto, never}
+''');
+ addPackageDataFile('''
+version: 1
+transforms:
+ - title: 'Rename to floatingLabelBehavior'
+ date: 2020-09-24
+ element:
+ uris: ['$importUri']
+ constructor: ''
+ inClass: 'InputDecoration'
+ oneOf:
+ - if: "hasFloatingPlaceholder == 'true'"
+ changes:
+ - kind: 'addParameter'
+ index: 14
+ name: 'floatingLabelBehavior'
+ style: optional_named
+ argumentValue:
+ expression: '{% FloatingLabelBehavior %}.auto'
+ requiredIf: "hasFloatingPlaceholder == 'true'"
+ variables:
+ FloatingLabelBehavior:
+ kind: 'import'
+ uris: ['$importUri']
+ name: 'FloatingLabelBehavior'
+ - kind: 'removeParameter'
+ name: 'hasFloatingPlaceholder'
+ - if: "hasFloatingPlaceholder == 'false'"
+ changes:
+ - kind: 'addParameter'
+ index: 14
+ name: 'floatingLabelBehavior'
+ style: optional_named
+ argumentValue:
+ expression: '{% FloatingLabelBehavior %}.never'
+ requiredIf: "hasFloatingPlaceholder == 'false'"
+ variables:
+ FloatingLabelBehavior:
+ kind: 'import'
+ uris: ['$importUri']
+ name: 'FloatingLabelBehavior'
+ - kind: 'removeParameter'
+ name: 'hasFloatingPlaceholder'
+ - if: "hasFloatingPlaceholder != 'true' && hasFloatingPlaceholder != 'false'"
+ changes:
+ - kind: 'addParameter'
+ index: 14
+ name: 'floatingLabelBehavior'
+ style: optional_named
+ argumentValue:
+ expression: '{% hasFloatingPlaceholder %} ? {% FloatingLabelBehavior %}.auto : {% FloatingLabelBehavior %}.never'
+ requiredIf: "hasFloatingPlaceholder != 'true' && hasFloatingPlaceholder != 'false'"
+ variables:
+ FloatingLabelBehavior:
+ kind: 'import'
+ uris: ['$importUri']
+ name: 'FloatingLabelBehavior'
+ - kind: 'removeParameter'
+ name: 'hasFloatingPlaceholder'
+ variables:
+ hasFloatingPlaceholder:
+ kind: 'fragment'
+ value: 'arguments[hasFloatingPlaceholder]'
+''');
+ await resolveTestCode('''
+import '$importUri';
+
+InputDecoration f(bool b) => InputDecoration(hasFloatingPlaceholder: b);
+''');
+ await assertHasFix('''
+import '$importUri';
+
+InputDecoration f(bool b) => InputDecoration(floatingLabelBehavior: b ? FloatingLabelBehavior.auto : FloatingLabelBehavior.never);
+''');
+ }
+
Future<void> test_material_Scaffold_of_matchFirstCase() async {
setPackageContent('''
class Scaffold {
@@ -817,10 +1075,7 @@
''');
}
- @failingTest
Future<void> test_material_showDialog_deprecated() async {
- // This test is failing because there is no way to specify that if a `child`
- // was previously provided that a `builder` should be provided.
setPackageContent('''
void showDialog({
@deprecated Widget child,
@@ -844,10 +1099,11 @@
style: optional_named
argumentValue:
expression: '(context) => {% widget %}'
+ requiredIf: "widget != ''"
variables:
widget:
- kind: argument
- name: 'child'
+ kind: fragment
+ value: 'arguments[child]'
- kind: 'removeParameter'
name: 'child'
''');
@@ -867,10 +1123,7 @@
''');
}
- @failingTest
Future<void> test_material_showDialog_removed() async {
- // This test is failing because there is no way to specify that if a `child`
- // was previously provided that a `builder` should be provided.
setPackageContent('''
void showDialog({
@deprecated Widget child,
@@ -894,10 +1147,11 @@
style: optional_named
argumentValue:
expression: '(context) => {% widget %}'
+ requiredIf: "widget != ''"
variables:
widget:
- kind: argument
- name: 'child'
+ kind: fragment
+ value: 'arguments[child]'
- kind: 'removeParameter'
name: 'child'
''');
diff --git a/pkg/analyzer/doc/design/summaries.md b/pkg/analyzer/doc/design/summaries.md
new file mode 100644
index 0000000..3b3d623
--- /dev/null
+++ b/pkg/analyzer/doc/design/summaries.md
@@ -0,0 +1,103 @@
+# Summaries in Dart analyzer
+
+The purpose of this document is to provide a high-level overview of the summaries linking, storage format, and reading
+in Dart analyzer.
+
+## Design Considerations
+
+There are a couple of considerations to keep in mind when discussing the design.
+
+**We want the linking to be done using AST.** Default values, constructor initializers, and field initializers should be
+stored in their resolved state, with elements and type, because we need them to perform constant evaluation.
+
+**We want separation between AST and resolution.** Files change rarely, usually the user changes just one file, and this
+affects resolution of this file and a multiple other files. But only the resolution, not AST. So, we want to keep pieces
+that are not affected by the change.
+
+**We want to read only as much as necessary to do resolution.** Libraries often have many classes, but when we resolve a
+file, we don’t need all these classes, only those that are actually referenced. So, we want the format to support
+loading individual classes, functions, etc.
+
+## High level view
+
+When the analyzer needs to resolve a file, it works in the following way:
+
+1. Find the library cycle that contains this file, and library cycles of its dependencies, down to SDK.
+
+2. Link these library cycles from SDK up to the target cycle.
+
+3. Add linked bundles to `LinkedElementFactory`.
+
+4. When we need a specific element, we call `LinkedElementFactory.elementOfReference`. It will request parent elements,
+ and eventually load the containing library, the containing class, method, etc.
+
+## Lazy loading
+
+We try to load only libraries that are necessary. When a `PackageBundleReader` is created, it decodes only the header of
+the bundle - with the list of library URIs contained in the bundle, and creates `LibraryReader`s.
+
+When `LinkedElementFactory.createLibraryElementForReading` is invoked, the corresponding `LibraryReader` is asked to
+load units, which are `UnitReader`s. Each `UnitReader` keeps track of the location of its AST and resolution portions
+in `astReader` and `resolutionReader`. When `UnitReader` is created, it reads the index of top-level declarations, and
+fills `Reference` subtree. For each `Reference` we set its `nodeAccessor`, a pointer to the `_UnitMemberReader`, which
+can be used to load the corresponding AST node. This is a way to present the index of the unit to `LinkedElementFactory`
+.
+
+To support lazy loading the package bundle has the index of libraries, the library has the index of units, the unit has
+the index of top-level declarations, the class / extension / mixin has the index of members.
+
+Any time when we need the element for a `Reference`, we call `elementOfReference` of `LinkedElementFactory`, which
+asks `Reference.nodeAccessor` for the AST node, and then creates the corresponding `Element` wrapper around it, and
+stores into `Reference.element`. For example for `ClassDeclaration` it will create `ClassElement`. No resolution is
+required yet.
+
+When `Reference.element` is already set, we just return it, we have already done loading AST node and creating the
+element for this `Reference`.
+
+When we link libraries, we don’t use `LinkedElementFactory` to read nodes and create elements, because we already have
+full ASTs, and we can create elements for all nodes in advance, and put them into corresponding `Reference` children.
+
+We say that we need the element for a `Reference` because resolution stores elements as such references - a pair of the
+name, and the parent reference. So, we may have an empty `Reference` first, without `element` and `nodeAccessor`, then
+when `elementOfReference` is invoked, it will fill both for a `Reference`. But its siblings will stay unfilled.
+
+When we ask an `Element` anything that requires resolution, we apply resolution to the whole AST node of the element.
+For example, when we ask `ClassElement` for `supertype`, we apply resolution to the `ClassDeclaration` header (but not
+to any member of the `ClassDeclaration`) - supertype, mixins, interfaces. We do this by calling `applyResolution`
+of `AstLinkedContext`. We get `AstLinkedContext` from the node, which implements `HasAstLinkedContext`.
+
+`AstBinaryWriter` writes two streams of information at once - the AST itself, and resolution. In the future we might
+split writing AST and resolution into separate writers.
+
+Resolution information is just a sequence of elements and types, which is stored when we visit the resolved AST
+in `AstBinaryWriter`. We use the helper `_ResolutionSink` to encode elements and types into bytes.
+
+Resolution is applied to unresolved AST using `ApplyResolutionVisitor`, which visits AST nodes in the same sequence
+as `AstBinaryWriter`, and takes either elements or types from the same (untyped, unmarked in any way) stream of
+resolution bytes. `LinkedResolutionReader` corresponds to `_ResolutionSink` - it decodes elements and types from bytes.
+
+Each raw element is represented by an integer, an index in the reference table. This table is collected during writing
+in `_BundleWriterReferences`, and stored by `BundleWriterResolution` during `BundleWriter.finish()`. During
+loading `BundleReader` creates `_ReferenceReader`, which lazily converts names and parent references into `Reference`
+instances in the given `LinkedElementFactory` (from which we just take `rootReference`, not actually any elements). Once
+we have `Reference` for the element that we need to decode, we actually ask `LinkedResolutionReader` for the element,
+see above.
+
+In addition to raw elements, there are “members” (which is not the best name) - which might be `Element`s which we want
+to convert to legacy because they are declared in a null safe library, but we want their legacy types; or actually
+members of a class with type parameters and with some `Substitution` applied to them; or both.
+
+Strings are encoded as integers, during writing using `StringIndexer`, and during loading using `_StringTable`. We
+use `SummaryDataReader` to load primitive types, and also strings.
+
+## Known limitations
+
+Currently `LibraryScope` and its basis `_LibraryImportScope` and `PrefixScope` - they all work by asking all elements
+from the imported libraries. Which means that we load all top-level nodes of these libraries (and all libraries that
+they export). Fortunately we don’t apply resolution to these elements until we try to access some property of these
+elements, e.g. the return type of a getter. But still, we probably don’t actually use all the imported elements, and we
+potentially could avoid loading all these AST nodes. A solution could be to work with `Reference`s instead.
+
+Similarly `InheritanceManager3` builds the whole interface of a class, and loads all members of the class and all
+members of all its superinterfaces. But again, we might only call a few methods, and might not need any superinterfaces.
+A solution might be to fill class interfaces on demand.
diff --git a/pkg/analyzer/lib/dart/sdk/build_sdk_summary.dart b/pkg/analyzer/lib/dart/sdk/build_sdk_summary.dart
index f3c9a79..1caa015 100644
--- a/pkg/analyzer/lib/dart/sdk/build_sdk_summary.dart
+++ b/pkg/analyzer/lib/dart/sdk/build_sdk_summary.dart
@@ -17,10 +17,9 @@
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/summarize_elements.dart';
import 'package:analyzer/src/summary2/link.dart';
import 'package:analyzer/src/summary2/linked_element_factory.dart';
+import 'package:analyzer/src/summary2/package_bundle_format.dart';
import 'package:analyzer/src/summary2/reference.dart';
import 'package:meta/meta.dart';
import 'package:pub_semver/pub_semver.dart';
@@ -85,7 +84,6 @@
AllowedExperiments allowedExperiments;
Version languageVersion;
- final PackageBundleAssembler bundleAssembler = PackageBundleAssembler();
_Builder(
this.context,
@@ -106,21 +104,24 @@
Reference.root(),
);
- var linkResult = link(elementFactory, inputLibraries);
- bundleAssembler.setBundle2(linkResult.bundle);
+ var linkResult = link(elementFactory, inputLibraries, false);
- var buffer = PackageBundleBuilder(
- bundle2: linkResult.bundle,
- sdk: PackageBundleSdkBuilder(
+ var bundleBuilder = PackageBundleBuilder();
+ for (var library in inputLibraries) {
+ bundleBuilder.addLibrary(
+ library.uriStr,
+ library.units.map((e) => e.uriStr).toList(),
+ );
+ }
+ return bundleBuilder.finish(
+ astBytes: linkResult.astBytes,
+ resolutionBytes: linkResult.resolutionBytes,
+ sdk: PackageBundleSdk(
+ languageVersionMajor: languageVersion.major,
+ languageVersionMinor: languageVersion.minor,
allowedExperimentsJson: allowedExperimentsJson,
- languageVersion: LinkedLanguageVersionBuilder(
- major: languageVersion.major,
- minor: languageVersion.minor,
- ),
),
- ).toBuffer();
-
- return buffer is Uint8List ? buffer : Uint8List.fromList(buffer);
+ );
}
void _addLibrary(Source source) {
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 38b3ce4..2357561 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -148,6 +148,7 @@
CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT,
CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME,
CompileTimeErrorCode.DUPLICATE_DEFINITION,
+ CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER,
CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT,
CompileTimeErrorCode.DUPLICATE_PART,
CompileTimeErrorCode.ENUM_CONSTANT_SAME_NAME_AS_ENCLOSING,
diff --git a/pkg/analyzer/lib/src/analysis_options/error/option_codes.dart b/pkg/analyzer/lib/src/analysis_options/error/option_codes.dart
index 43ae068..b67961f 100644
--- a/pkg/analyzer/lib/src/analysis_options/error/option_codes.dart
+++ b/pkg/analyzer/lib/src/analysis_options/error/option_codes.dart
@@ -31,7 +31,12 @@
/// Initialize a newly created error code to have the given [name].
const AnalysisOptionsErrorCode(String name, String message,
{String correction})
- : super.temporary(name, message, correction: correction);
+ : super(
+ correction: correction,
+ message: message,
+ name: name,
+ uniqueName: 'AnalysisOptionsErrorCode.$name',
+ );
@override
ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
@@ -78,7 +83,12 @@
/// Initialize a newly created hint code to have the given [name].
const AnalysisOptionsHintCode(String name, String message,
{String correction})
- : super.temporary(name, message, correction: correction);
+ : super(
+ correction: correction,
+ message: message,
+ name: name,
+ uniqueName: 'AnalysisOptionsHintCode.$name',
+ );
@override
ErrorSeverity get errorSeverity => ErrorSeverity.INFO;
@@ -200,7 +210,12 @@
/// Initialize a newly created warning code to have the given [name].
const AnalysisOptionsWarningCode(String name, String message,
{String correction})
- : super.temporary(name, message, correction: correction);
+ : super(
+ correction: correction,
+ message: message,
+ name: name,
+ uniqueName: 'AnalysisOptionsWarningCode.$name',
+ );
@override
ErrorSeverity get errorSeverity => ErrorSeverity.WARNING;
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 57c4895..38952f2 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -85,7 +85,7 @@
/// TODO(scheglov) Clean up the list of implicitly analyzed files.
class AnalysisDriver implements AnalysisDriverGeneric {
/// The version of data format, should be incremented on every format change.
- static const int DATA_VERSION = 113;
+ static const int DATA_VERSION = 114;
/// The length of the list returned by [_computeDeclaredVariablesSignature].
static const int _declaredVariablesSignatureLength = 4;
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index 7a5926e..aa961ed 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -35,7 +35,6 @@
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/package_bundle_reader.dart';
-import 'package:analyzer/src/summary2/informative_data.dart';
import 'package:analyzer/src/workspace/workspace.dart';
import 'package:convert/convert.dart';
import 'package:crypto/crypto.dart';
@@ -43,6 +42,7 @@
import 'package:pub_semver/pub_semver.dart';
var counterFileStateRefresh = 0;
+var counterUnlinkedBytes = 0;
var counterUnlinkedLinkedBytes = 0;
int fileObjectId = 0;
var timerFileStateRefresh = Stopwatch();
@@ -125,6 +125,7 @@
Set<String> _definedClassMemberNames;
Set<String> _definedTopLevelNames;
Set<String> _referencedNames;
+ List<int> _unlinkedSignature;
String _unlinkedKey;
AnalysisDriverUnlinkedUnit _driverUnlinkedUnit;
List<int> _apiSignature;
@@ -356,6 +357,9 @@
/// The [UnlinkedUnit2] of the file.
UnlinkedUnit2 get unlinked2 => _unlinked2;
+ /// The MD5 signature based on the content, feature sets, language version.
+ List<int> get unlinkedSignature => _unlinkedSignature;
+
/// Return the [uri] string.
String get uriStr => uri.toString();
@@ -414,7 +418,6 @@
}
// Prepare the unlinked bundle key.
- List<int> contentSignature;
{
var signature = ApiSignature();
signature.addUint32List(_fsState._saltForUnlinked);
@@ -422,8 +425,8 @@
signature.addLanguageVersion(packageLanguageVersion);
signature.addString(_contentHash);
signature.addBool(_exists);
- contentSignature = signature.toByteList();
- _unlinkedKey = '${hex.encode(contentSignature)}.unlinked2';
+ _unlinkedSignature = signature.toByteList();
+ _unlinkedKey = '${hex.encode(_unlinkedSignature)}.unlinked2';
}
// Prepare bytes of the unlinked bundle - existing or new.
@@ -445,6 +448,8 @@
subtypedNames: subtypedNames,
).toBuffer();
_fsState._byteStore.put(_unlinkedKey, bytes);
+ counterUnlinkedBytes += bytes.length;
+ counterUnlinkedLinkedBytes += bytes.length;
});
}
}
@@ -671,7 +676,6 @@
),
);
}
- var informativeData = createInformativeData(unit);
return UnlinkedUnit2Builder(
apiSignature: computeUnlinkedApiSignature(unit),
exports: exports,
@@ -680,7 +684,6 @@
hasLibraryDirective: hasLibraryDirective,
hasPartOfDirective: hasPartOfDirective,
lineStarts: unit.lineInfo.lineStarts,
- informativeData: informativeData,
);
}
@@ -820,6 +823,7 @@
FileSystemStateTestView get test => _testView;
/// Return the [FileState] instance that correspond to an unresolved URI.
+ /// TODO(scheglov) Remove it.
FileState get unresolvedFile {
if (_unresolvedFile == null) {
var featureSet = FeatureSet.latestLanguageVersion();
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_context.dart b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
index 1402523..dae3c73 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
@@ -16,17 +16,17 @@
import 'package:analyzer/src/generated/engine.dart'
show AnalysisContext, AnalysisOptions;
import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary/api_signature.dart';
import 'package:analyzer/src/summary/package_bundle_reader.dart';
+import 'package:analyzer/src/summary2/bundle_reader.dart';
import 'package:analyzer/src/summary2/link.dart' as link2;
-import 'package:analyzer/src/summary2/linked_bundle_context.dart';
import 'package:analyzer/src/summary2/linked_element_factory.dart';
import 'package:analyzer/src/summary2/reference.dart';
import 'package:meta/meta.dart';
var counterLinkedLibraries = 0;
var counterLoadedLibraries = 0;
-var timerBundleToBytes = Stopwatch();
+var timerBundleToBytes = Stopwatch(); // TODO(scheglov) use
var timerInputLibraries = Stopwatch();
var timerLinking = Stopwatch();
var timerLoad2 = Stopwatch();
@@ -100,8 +100,6 @@
/// Load data required to access elements of the given [targetLibrary].
void load2(FileState targetLibrary) {
timerLoad2.start();
- var inputBundles = <LinkedNodeBundle>[];
-
var librariesTotal = 0;
var librariesLoaded = 0;
var librariesLinked = 0;
@@ -119,14 +117,31 @@
librariesTotal += cycle.libraries.length;
+ if (cycle.isUnresolvedFile) {
+ return;
+ }
+
cycle.directDependencies.forEach(
(e) => loadBundle(e, '$debugPrefix '),
);
- var key = cycle.transitiveSignature + '.linked_bundle';
- var bytes = byteStore.get(key);
+ String astKey;
+ {
+ var signature = ApiSignature();
+ for (var library in cycle.libraries) {
+ for (var file in library.libraryFiles) {
+ signature.addBytes(file.unlinkedSignature);
+ }
+ }
+ astKey = '${signature.toHex()}.ast';
+ }
- if (bytes == null) {
+ var resolutionKey = cycle.transitiveSignature + '.linked_bundle';
+
+ var astBytes = byteStore.get(astKey);
+ var resolutionBytes = byteStore.get(resolutionKey);
+
+ if (astBytes == null || resolutionBytes == null) {
librariesLinkedTimer.start();
testView.linkedCycles.add(
@@ -212,49 +227,39 @@
link2.LinkResult linkResult;
try {
timerLinking.start();
- linkResult = link2.link(elementFactory, inputLibraries);
+ linkResult = link2.link(elementFactory, inputLibraries, true);
librariesLinked += cycle.libraries.length;
- counterLinkedLibraries += linkResult.bundle.libraries.length;
+ counterLinkedLibraries += inputLibraries.length;
timerLinking.stop();
} catch (exception, stackTrace) {
_throwLibraryCycleLinkException(cycle, exception, stackTrace);
}
- timerBundleToBytes.start();
- bytes = linkResult.bundle.toBuffer();
- timerBundleToBytes.stop();
+ astBytes = linkResult.astBytes;
+ resolutionBytes = linkResult.resolutionBytes;
- byteStore.put(key, bytes);
- bytesPut += bytes.length;
- counterUnlinkedLinkedBytes += bytes.length;
+ byteStore.put(astKey, astBytes);
+ byteStore.put(resolutionKey, resolutionBytes);
+ bytesPut += astBytes.length;
+ bytesPut += resolutionBytes.length;
+ counterUnlinkedLinkedBytes += astBytes.length;
+ counterUnlinkedLinkedBytes += resolutionBytes.length;
librariesLinkedTimer.stop();
} else {
// TODO(scheglov) Take / clear parsed units in files.
- bytesGet += bytes.length;
+ bytesGet += astBytes.length;
+ bytesGet += resolutionBytes.length;
librariesLoaded += cycle.libraries.length;
}
- var bundle = LinkedNodeBundle.fromBuffer(bytes);
- inputBundles.add(bundle);
elementFactory.addBundle(
- LinkedBundleContext(elementFactory, bundle),
+ BundleReader(
+ elementFactory: elementFactory,
+ astBytes: astBytes,
+ resolutionBytes: resolutionBytes,
+ ),
);
- counterLoadedLibraries += bundle.libraries.length;
-
- // Set informative data.
- for (var libraryFile in cycle.libraries) {
- for (var unitFile in libraryFile.libraryFiles) {
- elementFactory.setInformativeData(
- libraryFile.uriStr,
- unitFile.uriStr,
- unitFile.unlinked2.informativeData,
- );
- }
- }
-
- // We might have just linked dart:core, ensure the type provider.
- _createElementFactoryTypeProvider();
}
logger.run('Prepare linked bundles', () {
@@ -296,7 +301,11 @@
if (externalSummaries != null) {
for (var bundle in externalSummaries.bundles) {
elementFactory.addBundle(
- LinkedBundleContext(elementFactory, bundle.bundle2),
+ BundleReader(
+ elementFactory: elementFactory,
+ astBytes: bundle.astBytes,
+ resolutionBytes: bundle.resolutionBytes,
+ ),
);
}
}
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_graph.dart b/pkg/analyzer/lib/src/dart/analysis/library_graph.dart
index dfcfb0d..bb04579 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_graph.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_graph.dart
@@ -51,6 +51,10 @@
LibraryCycle.external() : transitiveSignature = '<external>';
+ bool get isUnresolvedFile {
+ return libraries.length == 1 && libraries[0].isUnresolved;
+ }
+
/// Invalidate this cycle and any cycles that directly or indirectly use it.
///
/// Practically invalidation means that we clear the library cycle in all the
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 961a12e..c906376 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -21,6 +21,7 @@
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/source.dart' show LineInfo, Source;
import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/summary2/linked_unit_context.dart';
/// Two or more string literals that are implicitly concatenated because of
/// being adjacent (separated only by whitespace).
@@ -724,6 +725,18 @@
identical(child, _leftHandSide);
}
+abstract class AstLinkedContext {
+ List<ClassMember> get classMembers;
+ int get codeLength;
+ int get codeOffset;
+ bool get isClassWithConstConstructor;
+ List<Directive> get unitDirectives;
+ void applyResolution(LinkedUnitContext unitContext);
+ int getVariableDeclarationCodeLength(VariableDeclaration node);
+ int getVariableDeclarationCodeOffset(VariableDeclaration node);
+ void readDocumentationComment();
+}
+
/// A node in the AST structure for a Dart program.
abstract class AstNodeImpl implements AstNode {
/// The parent of the node, or `null` if the node is the root of an AST
@@ -1418,6 +1431,7 @@
/// [ImplementsClause]?
/// '{' [ClassMember]* '}'
class ClassDeclarationImpl extends ClassOrMixinDeclarationImpl
+ with HasAstLinkedContext
implements ClassDeclaration {
/// The 'abstract' keyword, or `null` if the keyword was absent.
@override
@@ -1666,7 +1680,9 @@
///
/// mixinApplication ::=
/// [TypeName] [WithClause] [ImplementsClause]? ';'
-class ClassTypeAliasImpl extends TypeAliasImpl implements ClassTypeAlias {
+class ClassTypeAliasImpl extends TypeAliasImpl
+ with HasAstLinkedContext
+ implements ClassTypeAlias {
/// The type parameters for the class, or `null` if the class does not have
/// any type parameters.
TypeParameterListImpl _typeParameters;
@@ -2019,6 +2035,11 @@
@override
final FeatureSet featureSet;
+ /// Data that is read during loading this node from summary, but is not
+ /// fully applied yet. For example in many cases we don't need the
+ /// documentation comment, and it is expensive to decode strings.
+ Object summaryData;
+
/// Initialize a newly created compilation unit to have the given directives
/// and declarations. The [scriptTag] can be `null` if there is no script tag
/// in the compilation unit. The list of [directives] can be `null` if there
@@ -2370,6 +2391,7 @@
/// initializerList ::=
/// ':' [ConstructorInitializer] (',' [ConstructorInitializer])*
class ConstructorDeclarationImpl extends ClassMemberImpl
+ with HasAstLinkedContext
implements ConstructorDeclaration {
/// The token for the 'external' keyword, or `null` if the constructor is not
/// external.
@@ -3246,6 +3268,7 @@
/// The declaration of an enum constant.
class EnumConstantDeclarationImpl extends DeclarationImpl
+ with HasAstLinkedContext
implements EnumConstantDeclaration {
/// The name of the constant.
SimpleIdentifierImpl _name;
@@ -3298,6 +3321,7 @@
/// metadata 'enum' [SimpleIdentifier] '{' [SimpleIdentifier]
/// (',' [SimpleIdentifier])* (',')? '}'
class EnumDeclarationImpl extends NamedCompilationUnitMemberImpl
+ with HasAstLinkedContext
implements EnumDeclaration {
/// The 'enum' keyword.
@override
@@ -3376,6 +3400,7 @@
/// exportDirective ::=
/// [Annotation] 'export' [StringLiteral] [Combinator]* ';'
class ExportDirectiveImpl extends NamespaceDirectiveImpl
+ with HasAstLinkedContext
implements ExportDirective {
/// Initialize a newly created export directive. Either or both of the
/// [comment] and [metadata] can be `null` if the directive does not have the
@@ -3708,6 +3733,7 @@
///
/// Clients may not extend, implement or mix-in this class.
class ExtensionDeclarationImpl extends CompilationUnitMemberImpl
+ with HasAstLinkedContext
implements ExtensionDeclaration {
@override
Token extensionKeyword;
@@ -3911,7 +3937,9 @@
///
/// fieldDeclaration ::=
/// 'static'? [VariableDeclarationList] ';'
-class FieldDeclarationImpl extends ClassMemberImpl implements FieldDeclaration {
+class FieldDeclarationImpl extends ClassMemberImpl
+ with HasAstLinkedContext
+ implements FieldDeclaration {
@override
Token abstractKeyword;
@@ -4305,6 +4333,11 @@
/// | [DefaultFormalParameter]
abstract class FormalParameterImpl extends AstNodeImpl
implements FormalParameter {
+ /// Data that is read during loading this node from summary, but is not
+ /// fully applied yet. For example in many cases we don't need the
+ /// documentation comment, and it is expensive to decode strings.
+ Object summaryData;
+
@override
ParameterElement get declaredElement {
SimpleIdentifier identifier = this.identifier;
@@ -4740,6 +4773,7 @@
/// functionSignature ::=
/// [Type]? ('get' | 'set')? [SimpleIdentifier] [FormalParameterList]
class FunctionDeclarationImpl extends NamedCompilationUnitMemberImpl
+ with HasAstLinkedContext
implements FunctionDeclaration {
/// The token representing the 'external' keyword, or `null` if this is not an
/// external function.
@@ -5049,7 +5083,9 @@
///
/// functionPrefix ::=
/// [TypeName]? [SimpleIdentifier]
-class FunctionTypeAliasImpl extends TypeAliasImpl implements FunctionTypeAlias {
+class FunctionTypeAliasImpl extends TypeAliasImpl
+ with HasAstLinkedContext
+ implements FunctionTypeAlias {
/// The name of the return type of the function type being defined, or `null`
/// if no return type was given.
TypeAnnotationImpl _returnType;
@@ -5363,7 +5399,9 @@
/// functionTypeAlias ::=
/// metadata 'typedef' [SimpleIdentifier] [TypeParameterList]? =
/// [FunctionType] ';'
-class GenericTypeAliasImpl extends TypeAliasImpl implements GenericTypeAlias {
+class GenericTypeAliasImpl extends TypeAliasImpl
+ with HasAstLinkedContext
+ implements GenericTypeAlias {
/// The type being defined by the alias.
TypeAnnotationImpl _type;
@@ -5450,6 +5488,10 @@
}
}
+mixin HasAstLinkedContext {
+ AstLinkedContext linkedContext;
+}
+
/// A combinator that restricts the names being imported to those that are not
/// in a given list.
///
@@ -5719,6 +5761,7 @@
/// | [Annotation] 'import' [StringLiteral] 'deferred' 'as' identifier
// [Combinator]* ';'
class ImportDirectiveImpl extends NamespaceDirectiveImpl
+ with HasAstLinkedContext
implements ImportDirective {
/// The token representing the 'deferred' keyword, or `null` if the imported
/// is not deferred.
@@ -6543,6 +6586,11 @@
@override
Token semicolon;
+ /// Data that is read during loading this node from summary, but is not
+ /// fully applied yet. For example in many cases we don't need the
+ /// documentation comment, and it is expensive to decode strings.
+ Object summaryData;
+
/// Initialize a newly created library directive. Either or both of the
/// [comment] and [metadata] can be `null` if the directive does not have the
/// corresponding attribute.
@@ -6815,6 +6863,7 @@
/// [SimpleIdentifier]
/// | 'operator' [SimpleIdentifier]
class MethodDeclarationImpl extends ClassMemberImpl
+ with HasAstLinkedContext
implements MethodDeclaration {
/// The token for the 'external' keyword, or `null` if the constructor is not
/// external.
@@ -7154,6 +7203,7 @@
/// metadata? 'mixin' [SimpleIdentifier] [TypeParameterList]?
/// [RequiresClause]? [ImplementsClause]? '{' [ClassMember]* '}'
class MixinDeclarationImpl extends ClassOrMixinDeclarationImpl
+ with HasAstLinkedContext
implements MixinDeclaration {
@override
Token mixinKeyword;
@@ -9807,6 +9857,7 @@
/// ('final' | 'const') type? staticFinalDeclarationList ';'
/// | variableDeclaration ';'
class TopLevelVariableDeclarationImpl extends CompilationUnitMemberImpl
+ with HasAstLinkedContext
implements TopLevelVariableDeclaration {
/// The top-level variables being declared.
VariableDeclarationListImpl _variableList;
@@ -10188,6 +10239,11 @@
/// explicit upper bound.
TypeAnnotationImpl _bound;
+ /// Data that is read during loading this node from summary, but is not
+ /// fully applied yet. For example in many cases we don't need the
+ /// documentation comment, and it is expensive to decode strings.
+ Object summaryData;
+
/// Initialize a newly created type parameter. Either or both of the [comment]
/// and [metadata] can be `null` if the parameter does not have the
/// corresponding attribute. The [extendsKeyword] and [bound] can be `null` if
@@ -10412,6 +10468,12 @@
/// `null` if the initial value was not specified.
ExpressionImpl _initializer;
+ /// When this node is read as a part of summaries, we usually don't want
+ /// to read the [initializer], but we need to know if there is one in
+ /// the code. So, this flag might be set to `true` even though
+ /// [initializer] is `null`.
+ bool hasInitializer = false;
+
/// Initialize a newly created variable declaration. The [equals] and
/// [initializer] can be `null` if there is no initializer.
VariableDeclarationImpl(
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 2aebe9f..5b33ad7 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -41,9 +41,9 @@
import 'package:analyzer/src/generated/utilities_collection.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/generated/utilities_general.dart';
-import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary2/linked_unit_context.dart';
import 'package:analyzer/src/summary2/reference.dart';
+import 'package:analyzer/src/task/inference_error.dart';
import 'package:analyzer/src/util/comment.dart';
import 'package:meta/meta.dart';
@@ -464,11 +464,14 @@
/// A flag indicating whether the types associated with the instance members
/// of this class have been inferred.
- bool _hasBeenInferred = false;
+ bool hasBeenInferred = false;
/// This callback is set during mixins inference to handle reentrant calls.
List<InterfaceType> Function(ClassElementImpl) linkedMixinInferenceCallback;
+ /// TODO(scheglov) implement as modifier
+ bool _isSimplyBounded = true;
+
/// Initialize a newly created class element to have the given [name] at the
/// given [offset] in the file that contains the declaration of this element.
ClassElementImpl(String name, int offset) : super(name, offset);
@@ -481,6 +484,7 @@
} else if (linkedNode is ClassTypeAlias) {
linkedNode.name.staticElement = this;
}
+ hasBeenInferred = !linkedContext.isLinking;
}
@override
@@ -533,6 +537,7 @@
}
if (linkedNode != null) {
+ linkedContext.applyResolution(linkedNode);
var context = enclosingUnit.linkedContext;
var containerRef = reference.getChild('@constructor');
_constructors = context.getConstructors(linkedNode).map((node) {
@@ -594,6 +599,7 @@
if (linkedNode != null) {
if (linkedNode is ClassOrMixinDeclaration) {
+ linkedContext.applyResolution(linkedNode);
_createPropertiesAndAccessors();
assert(_fields != null);
return _fields;
@@ -605,20 +611,6 @@
return _fields ?? const <FieldElement>[];
}
- bool get hasBeenInferred {
- if (linkedNode != null) {
- return linkedContext.hasOverrideInferenceDone(linkedNode);
- }
- return _hasBeenInferred;
- }
-
- set hasBeenInferred(bool hasBeenInferred) {
- if (linkedNode != null) {
- return linkedContext.setOverrideInferenceDone(linkedNode);
- }
- _hasBeenInferred = hasBeenInferred;
- }
-
@override
bool get hasNonFinalField {
List<ClassElement> classesToVisit = <ClassElement>[];
@@ -694,6 +686,7 @@
}
if (linkedNode != null) {
+ linkedContext.applyResolution(linkedNode);
var context = enclosingUnit.linkedContext;
var implementsClause = context.getImplementsClause(linkedNode);
if (implementsClause != null) {
@@ -738,12 +731,18 @@
setModifier(Modifier.MIXIN_APPLICATION, isMixinApplication);
}
+ /// TODO(scheglov) implement as modifier
@override
bool get isSimplyBounded {
if (linkedNode != null) {
- return linkedContext.isSimplyBounded(linkedNode);
+ linkedContext.applyResolution(linkedNode);
}
- return super.isSimplyBounded;
+ return _isSimplyBounded;
+ }
+
+ /// TODO(scheglov) implement as modifier
+ set isSimplyBounded(bool isSimplyBounded) {
+ _isSimplyBounded = isSimplyBounded;
}
@override
@@ -769,6 +768,7 @@
}
if (linkedNode != null) {
+ linkedContext.applyResolution(linkedNode);
var context = enclosingUnit.linkedContext;
var containerRef = reference.getChild('@method');
return _methods = context
@@ -805,6 +805,7 @@
}
if (linkedNode != null) {
+ linkedContext.applyResolution(linkedNode);
var context = enclosingUnit.linkedContext;
var withClause = context.getWithClause(linkedNode);
if (withClause != null) {
@@ -854,6 +855,7 @@
}
if (linkedNode != null) {
+ linkedContext.applyResolution(linkedNode);
var type = linkedContext.getSuperclass(linkedNode)?.type;
if (_isInterfaceTypeClass(type)) {
return _supertype = type;
@@ -1055,11 +1057,9 @@
var fields = context.getFields(linkedNode);
for (var field in fields) {
var name = field.name.name;
- var fieldElement = FieldElementImpl.forLinkedNodeFactory(
- this,
- reference.getChild('@field').getChild(name),
- field,
- );
+ var fieldElement = field.declaredElement as FieldElementImpl;
+ fieldElement ??= FieldElementImpl.forLinkedNodeFactory(
+ this, reference.getChild('@field').getChild(name), field);
fieldList.add(fieldElement);
accessorList.add(fieldElement.getter);
@@ -1079,11 +1079,10 @@
? reference.getChild('@getter')
: reference.getChild('@setter');
- var accessorElement = PropertyAccessorElementImpl.forLinkedNode(
- this,
- containerRef.getChild(name),
- method,
- );
+ var accessorElement =
+ method.declaredElement as PropertyAccessorElementImpl;
+ accessorElement ??= PropertyAccessorElementImpl.forLinkedNode(
+ this, containerRef.getChild(name), method);
accessorList.add(accessorElement);
var fieldRef = reference.getChild('@field').getChild(name);
@@ -1324,9 +1323,13 @@
CompilationUnit linkedNode = this.linkedNode;
var containerRef = reference.getChild('@extension');
_extensions = <ExtensionElement>[];
+ var nextUnnamedExtensionId = 0;
for (var node in linkedNode.declarations) {
if (node is ExtensionDeclaration) {
- var refName = linkedContext.getExtensionRefName(node);
+ var nameIdentifier = node.name;
+ var refName = nameIdentifier != null
+ ? nameIdentifier.name
+ : 'extension-${nextUnnamedExtensionId++}';
var reference = containerRef.getChild(refName);
var element = node.declaredElement;
element ??= ExtensionElementImpl.forLinkedNode(this, reference, node);
@@ -1352,9 +1355,8 @@
if (_functions != null) return _functions;
if (linkedNode != null) {
- CompilationUnit linkedNode = this.linkedNode;
var containerRef = reference.getChild('@function');
- return _functions = linkedNode.declarations
+ return _functions = linkedContext.unit_withDeclarations.declarations
.whereType<FunctionDeclaration>()
.where((node) => !node.isGetter && !node.isSetter)
.map((node) {
@@ -1382,10 +1384,9 @@
if (_typeAliases != null) return _typeAliases;
if (linkedNode != null) {
- CompilationUnit linkedNode = this.linkedNode;
var containerRef = reference.getChild('@typeAlias');
_typeAliases = <FunctionTypeAliasElement>[];
- for (var node in linkedNode.declarations) {
+ for (var node in linkedContext.unit_withDeclarations.declarations) {
String name;
if (node is FunctionTypeAlias) {
name = node.name.name;
@@ -1464,12 +1465,14 @@
@override
List<TopLevelVariableElement> get topLevelVariables {
+ if (_variables != null) return _variables;
+
if (linkedNode != null) {
- if (_variables != null) return _variables;
_createPropertiesAndAccessors(this);
assert(_variables != null);
return _variables;
}
+
return _variables ?? const <TopLevelVariableElement>[];
}
@@ -1499,10 +1502,9 @@
if (_types != null) return _types;
if (linkedNode != null) {
- CompilationUnit linkedNode = this.linkedNode;
var containerRef = reference.getChild('@class');
_types = <ClassElement>[];
- for (var node in linkedNode.declarations) {
+ for (var node in linkedContext.unit_withDeclarations.declarations) {
if (node is ClassDeclaration) {
var name = node.name.name;
var reference = containerRef.getChild(name);
@@ -1647,18 +1649,20 @@
var variableList = <TopLevelVariableElement>[];
variableMap[unit] = variableList;
- var unitNode = unit.linkedContext.unit_withDeclarations;
+ // TODO(scheglov) Bad, we want to read only functions / variables.
+ var unitNode = context.unit_withDeclarations;
var unitDeclarations = unitNode.declarations;
var variables = context.topLevelVariables(unitNode);
for (var variable in variables) {
- var name = variable.name.name;
- var reference = unit.reference.getChild('@variable').getChild(name);
- var variableElement = TopLevelVariableElementImpl.forLinkedNodeFactory(
- unit,
- reference,
- variable,
- );
+ var variableElement =
+ variable.declaredElement as TopLevelVariableElementImpl;
+ if (variableElement == null) {
+ var name = variable.name.name;
+ var reference = unit.reference.getChild('@variable').getChild(name);
+ variableElement = TopLevelVariableElementImpl.forLinkedNodeFactory(
+ unit, reference, variable);
+ }
variableList.add(variableElement);
accessorList.add(variableElement.getter);
@@ -1678,14 +1682,13 @@
? unit.reference.getChild('@getter')
: unit.reference.getChild('@setter');
- var accessorElement = PropertyAccessorElementImpl.forLinkedNode(
- unit,
- containerRef.getChild(name),
- node,
- );
+ var accessorElement =
+ node.declaredElement as PropertyAccessorElementImpl;
+ accessorElement ??= PropertyAccessorElementImpl.forLinkedNode(
+ unit, containerRef.getChild(name), node);
accessorList.add(accessorElement);
- var fieldRef = unit.reference.getChild('@field').getChild(name);
+ var fieldRef = unit.reference.getChild('@variable').getChild(name);
TopLevelVariableElementImpl field = fieldRef.element;
if (field == null) {
field = TopLevelVariableElementImpl(name, -1);
@@ -1953,6 +1956,7 @@
if (_constantInitializers != null) return _constantInitializers;
if (linkedNode != null) {
+ linkedContext.applyResolution(linkedNode);
return _constantInitializers = linkedContext.getConstructorInitializers(
linkedNode,
);
@@ -2069,6 +2073,7 @@
if (_redirectedConstructor != null) return _redirectedConstructor;
if (linkedNode != null) {
+ linkedContext.applyResolution(linkedNode);
var context = enclosingUnit.linkedContext;
if (isFactory) {
var node = context.getConstructorRedirected(linkedNode);
@@ -2203,8 +2208,8 @@
if (_constantInitializer != null) return _constantInitializer;
if (linkedNode != null) {
- var context = enclosingUnit.linkedContext;
- return _constantInitializer = context.readInitializer(linkedNode);
+ linkedContext.applyResolution(linkedNode);
+ return _constantInitializer = linkedContext.getInitializer(linkedNode);
}
return _constantInitializer;
@@ -2967,11 +2972,14 @@
@override
List<ElementAnnotation> get metadata {
+ if (_metadata != null) return _metadata;
+
if (linkedNode != null) {
- if (_metadata != null) return _metadata;
+ linkedContext.applyResolution(linkedNode);
var metadata = linkedContext.getMetadata(linkedNode);
return _metadata = _buildAnnotations2(enclosingUnit, metadata);
}
+
return _metadata ?? const <ElementAnnotation>[];
}
@@ -3686,6 +3694,7 @@
if (_parameters != null) return _parameters;
if (linkedNode != null) {
+ linkedContext.applyResolution(linkedNode);
var context = enclosingUnit.linkedContext;
var containerRef = reference.getChild('@parameter');
var formalParameters = context.getFormalParameters(linkedNode);
@@ -3705,9 +3714,6 @@
ElementTypeProvider.current.getExecutableReturnType(this);
set returnType(DartType returnType) {
- if (linkedNode != null) {
- linkedContext.setReturnType(linkedNode, returnType);
- }
_returnType = returnType;
// We do this because of return type inference. At the moment when we
// create a local function element we don't know yet its return type,
@@ -3724,8 +3730,8 @@
if (_returnType != null) return _returnType;
if (linkedNode != null) {
- var context = enclosingUnit.linkedContext;
- return _returnType = context.getReturnType(linkedNode);
+ linkedContext.applyResolution(linkedNode);
+ return _returnType;
}
return _returnType;
}
@@ -3799,7 +3805,9 @@
ExportElementImpl.forLinkedNode(
LibraryElementImpl enclosing, ExportDirective linkedNode)
- : super.forLinkedNode(enclosing, null, linkedNode);
+ : super.forLinkedNode(enclosing, null, linkedNode) {
+ linkedNode.element = this;
+ }
@override
List<NamespaceCombinator> get combinators {
@@ -3831,7 +3839,7 @@
if (_exportedLibrary != null) return _exportedLibrary;
if (linkedNode != null) {
- return _exportedLibrary = linkedContext.directiveLibrary(linkedNode);
+ linkedContext.applyResolution(linkedNode);
}
return _exportedLibrary;
@@ -3971,7 +3979,8 @@
if (_extendedType != null) return _extendedType;
if (linkedNode != null) {
- return _extendedType = linkedContext.getExtendedType(linkedNode).type;
+ var linkedNode = this.linkedNode as ExtensionDeclaration;
+ return _extendedType = linkedNode.extendedType.type;
}
return _extendedType;
@@ -4135,11 +4144,9 @@
var fields = context.getFields(linkedNode);
for (var field in fields) {
var name = field.name.name;
- var fieldElement = FieldElementImpl.forLinkedNodeFactory(
- this,
- reference.getChild('@field').getChild(name),
- field,
- );
+ var fieldElement = field.declaredElement as FieldElementImpl;
+ fieldElement ??= FieldElementImpl.forLinkedNodeFactory(
+ this, reference.getChild('@field').getChild(name), field);
fieldList.add(fieldElement);
accessorList.add(fieldElement.getter);
@@ -4159,11 +4166,10 @@
? reference.getChild('@getter')
: reference.getChild('@setter');
- var accessorElement = PropertyAccessorElementImpl.forLinkedNode(
- this,
- containerRef.getChild(name),
- method,
- );
+ var accessorElement =
+ method.declaredElement as PropertyAccessorElementImpl;
+ accessorElement ??= PropertyAccessorElementImpl.forLinkedNode(
+ this, containerRef.getChild(name), method);
accessorList.add(accessorElement);
var fieldRef = reference.getChild('@field').getChild(name);
@@ -4198,6 +4204,10 @@
/// A concrete implementation of a [FieldElement].
class FieldElementImpl extends PropertyInducingElementImpl
implements FieldElement {
+ /// True if this field inherits from a covariant parameter. This happens
+ /// when it overrides a field in a supertype that is covariant.
+ bool inheritsCovariant = false;
+
/// Initialize a newly created synthetic field element to have the given
/// [name] at the given [offset].
FieldElementImpl(String name, int offset) : super(name, offset);
@@ -4205,6 +4215,9 @@
FieldElementImpl.forLinkedNode(
ElementImpl enclosing, Reference reference, AstNode linkedNode)
: super.forLinkedNode(enclosing, reference, linkedNode) {
+ if (linkedNode is VariableDeclaration) {
+ linkedNode.name.staticElement = this;
+ }
if (!linkedNode.isSynthetic) {
var enclosingRef = enclosing.reference;
@@ -4430,6 +4443,14 @@
/// The element representing the generic function type.
GenericFunctionTypeElementImpl _function;
+ /// TODO(scheglov) implement as modifier
+ @override
+ bool isSimplyBounded = true;
+
+ /// Is `true` if the element has direct or indirect reference to itself
+ /// from anywhere except a class element or type parameter bounds.
+ bool hasSelfReference = false;
+
/// Initialize a newly created type alias element to have the given [name].
FunctionTypeAliasElementImpl(String name, int offset) : super(name, offset);
@@ -4486,28 +4507,32 @@
GenericFunctionTypeElementImpl get function {
if (_function != null) return _function;
+ var linkedNode = this.linkedNode;
if (linkedNode != null) {
if (linkedNode is GenericTypeAlias) {
- var context = enclosingUnit.linkedContext;
- var function = context.getGeneticTypeAliasFunction(linkedNode);
+ var function = linkedNode.functionType as GenericFunctionTypeImpl;
if (function != null) {
- var reference = context.getGenericFunctionTypeReference(function);
- _function = reference.element;
- encloseElement(_function);
- return _function;
+ _function = function.declaredElement;
+ _function ??= GenericFunctionTypeElementImpl.forLinkedNode(
+ this,
+ reference.getChild('@function'),
+ function,
+ );
} else {
- return _function = GenericFunctionTypeElementImpl.forOffset(-1)
+ _function = GenericFunctionTypeElementImpl.forOffset(-1)
..typeParameters = const <TypeParameterElement>[]
..parameters = const <ParameterElement>[]
..returnType = DynamicTypeImpl.instance;
}
} else {
- return _function = GenericFunctionTypeElementImpl.forLinkedNode(
+ _function = GenericFunctionTypeElementImpl.forLinkedNode(
this,
reference.getChild('@function'),
linkedNode,
);
}
+ linkedContext.applyResolution(linkedNode);
+ return _function;
}
return _function;
@@ -4522,23 +4547,6 @@
_function = function;
}
- /// Return `true` if the element has direct or indirect reference to itself
- /// from anywhere except a class element or type parameter bounds.
- bool get hasSelfReference {
- if (linkedNode != null) {
- return linkedContext.getHasTypedefSelfReference(linkedNode);
- }
- return false;
- }
-
- @override
- bool get isSimplyBounded {
- if (linkedNode != null) {
- return linkedContext.isSimplyBounded(linkedNode);
- }
- return super.isSimplyBounded;
- }
-
@override
ElementKind get kind => ElementKind.FUNCTION_TYPE_ALIAS;
@@ -4658,7 +4666,11 @@
GenericFunctionTypeElementImpl.forLinkedNode(
ElementImpl enclosingElement, Reference reference, AstNode linkedNode)
- : super.forLinkedNode(enclosingElement, reference, linkedNode);
+ : super.forLinkedNode(enclosingElement, reference, linkedNode) {
+ if (linkedNode is GenericFunctionTypeImpl) {
+ linkedNode.declaredElement = this;
+ }
+ }
/// Initialize a newly created function element to have no name and the given
/// [nameOffset]. This is used for function expressions, that have no name.
@@ -4695,7 +4707,7 @@
return _parameters = ParameterElementImpl.forLinkedNodeList(
this,
context,
- reference.getChild('@parameter'),
+ null,
context.getFormalParameters(linkedNode),
);
}
@@ -4867,7 +4879,9 @@
ImportElementImpl.forLinkedNode(
LibraryElementImpl enclosing, ImportDirective linkedNode)
- : super.forLinkedNode(enclosing, null, linkedNode);
+ : super.forLinkedNode(enclosing, null, linkedNode) {
+ linkedNode.element = this;
+ }
@override
List<NamespaceCombinator> get combinators {
@@ -4902,7 +4916,7 @@
if (_importedLibrary != null) return _importedLibrary;
if (linkedNode != null) {
- return _importedLibrary = linkedContext.directiveLibrary(linkedNode);
+ linkedContext.applyResolution(linkedNode);
}
return _importedLibrary;
@@ -5179,7 +5193,7 @@
@override
String get documentationComment {
if (linkedNode != null) {
- var comment = linkedContext.getLibraryDocumentationComment(linkedNode);
+ var comment = linkedContext.getLibraryDocumentationComment();
return getCommentNodeRawText(comment);
}
return super.documentationComment;
@@ -5222,7 +5236,7 @@
if (_exportNamespace != null) return _exportNamespace;
if (linkedNode != null) {
- var elements = linkedContext.bundleContext.elementFactory;
+ var elements = linkedContext.elementFactory;
return _exportNamespace = elements.buildExportNamespace(source.uri);
}
@@ -5241,7 +5255,7 @@
var unit = linkedContext.unit_withDirectives;
return _exports = unit.directives
.whereType<ExportDirective>()
- .map((node) => ExportElementImpl.forLinkedNode(this, node))
+ .map((node) => node.element)
.toList();
}
@@ -5263,9 +5277,12 @@
var unit = linkedContext.unit_withDirectives;
for (var import in unit.directives) {
if (import is ImportDirective) {
- var uriStr = linkedContext.getSelectedUri(import);
- if (DartUriResolver.isDartExtUri(uriStr)) {
- return true;
+ var uriLiteral = import.uri;
+ if (uriLiteral is SimpleStringLiteral) {
+ var uriStr = uriLiteral.value;
+ if (DartUriResolver.isDartExtUri(uriStr)) {
+ return true;
+ }
}
}
}
@@ -5316,13 +5333,13 @@
var unit = linkedContext.unit_withDirectives;
_imports = unit.directives
.whereType<ImportDirective>()
- .map((node) => ImportElementImpl.forLinkedNode(this, node))
+ .map((node) => node.element)
.toList();
var hasCore = _imports.any((import) {
return import.importedLibrary?.isDartCore ?? false;
});
if (!hasCore) {
- var elements = linkedContext.bundleContext.elementFactory;
+ var elements = linkedContext.elementFactory;
_imports.add(
ImportElementImpl(-1)
..importedLibrary = elements.libraryOfUri('dart:core')
@@ -5444,7 +5461,7 @@
if (_metadata != null) return _metadata;
if (linkedNode != null) {
- var metadata = linkedContext.getLibraryMetadata(linkedNode);
+ var metadata = linkedContext.getLibraryMetadata();
return _metadata = _buildAnnotations2(definingCompilationUnit, metadata);
}
@@ -5682,6 +5699,15 @@
/// A concrete implementation of a [MethodElement].
class MethodElementImpl extends ExecutableElementImpl implements MethodElement {
+ /// Is `true` if this method is `operator==`, and there is no explicit
+ /// type specified for its formal parameter, in this method or in any
+ /// overridden methods other than the one declared in `Object`.
+ bool isOperatorEqualWithParameterTypeFromObject = false;
+
+ /// The error reported during type inference for this variable, or `null` if
+ /// this variable is not a subject of type inference, or there was no error.
+ TopLevelInferenceError typeInferenceError;
+
/// Initialize a newly created method element to have the given [name] at the
/// given [offset].
MethodElementImpl(String name, int offset) : super(name, offset);
@@ -5722,23 +5748,6 @@
first == 0x24);
}
- /// Return `true` if this method is `operator==`, and there is no explicit
- /// type specified for its formal parameter, in this method or in any
- /// overridden methods other than the one declared in `Object`.
- bool get isOperatorEqualWithParameterTypeFromObject {
- if (linkedNode != null) {
- return linkedContext.hasOperatorEqualParameterTypeFromObject(linkedNode);
- }
- return false;
- }
-
- /// See [isOperatorEqualWithParameterTypeFromObject].
- set isOperatorEqualWithParameterTypeFromObject(bool value) {
- if (linkedNode != null) {
- linkedContext.setOperatorEqualParameterTypeFromObject(linkedNode, value);
- }
- }
-
@override
bool get isStatic {
if (linkedNode != null) {
@@ -5764,18 +5773,6 @@
return super.name;
}
- /// Return the error reported during type inference for this method, or
- /// `null` if this method is not a subject of type inference, or there was
- /// no error.
- TopLevelInferenceError get typeInferenceError {
- if (linkedNode != null) {
- return linkedContext.getTypeInferenceError(linkedNode);
- }
-
- // We don't support type inference errors without linking.
- return null;
- }
-
@override
T accept<T>(ElementVisitor<T> visitor) => visitor.visitMethodElement(this);
}
@@ -5790,10 +5787,8 @@
/// the mixin.
List<InterfaceType> _superclassConstraints;
- /// Names of methods, getters, setters, and operators that this mixin
- /// declaration super-invokes. For setters this includes the trailing "=".
- /// The list will be empty if this class is not a mixin declaration.
- List<String> _superInvokedNames;
+ @override
+ List<String> superInvokedNames;
/// Initialize a newly created class element to have the given [name] at the
/// given [offset] in the file that contains the declaration of this element.
@@ -5818,9 +5813,11 @@
List<InterfaceType> get superclassConstraints {
if (_superclassConstraints != null) return _superclassConstraints;
- if (linkedNode != null) {
+ var linkedNode = this.linkedNode;
+ if (linkedNode is MixinDeclaration) {
+ linkedContext.applyResolution(linkedNode);
List<InterfaceType> constraints;
- var onClause = enclosingUnit.linkedContext.getOnClause(linkedNode);
+ var onClause = linkedNode.onClause;
if (onClause != null) {
constraints = onClause.superclassConstraints
.map((node) => node.type)
@@ -5842,22 +5839,6 @@
}
@override
- List<String> get superInvokedNames {
- if (_superInvokedNames != null) return _superInvokedNames;
-
- if (linkedNode != null) {
- return _superInvokedNames =
- linkedContext.getMixinSuperInvokedNames(linkedNode);
- }
-
- return _superInvokedNames ?? const <String>[];
- }
-
- set superInvokedNames(List<String> superInvokedNames) {
- _superInvokedNames = superInvokedNames;
- }
-
- @override
InterfaceType get supertype => null;
@override
@@ -6288,9 +6269,6 @@
@override
set type(DartType type) {
- if (linkedNode != null) {
- return linkedContext.setVariableType(linkedNode, type);
- }
_type = type;
}
}
@@ -6315,7 +6293,10 @@
/// The Dart code of the default value.
String _defaultValueCode;
- bool _inheritsCovariant = false;
+ /// True if this parameter inherits from a covariant parameter. This happens
+ /// when it overrides a method in a supertype that has a corresponding
+ /// covariant parameter.
+ bool inheritsCovariant = false;
/// Initialize a newly created parameter element to have the given [name] and
/// [nameOffset].
@@ -6324,6 +6305,7 @@
ParameterElementImpl.forLinkedNode(
ElementImpl enclosing, Reference reference, FormalParameter linkedNode)
: super.forLinkedNode(enclosing, reference, linkedNode) {
+ assert(linkedNode.isNamed || reference == null);
FormalParameterImpl.setDeclaredElement(linkedNode, this);
}
@@ -6354,28 +6336,13 @@
}
@override
- int get codeLength {
- if (linkedNode != null) {
- return linkedContext.getCodeLength(linkedNode);
- }
- return super.codeLength;
- }
-
- @override
- int get codeOffset {
- if (linkedNode != null) {
- return linkedContext.getCodeOffset(linkedNode);
- }
- return super.codeOffset;
- }
-
- @override
ParameterElement get declaration => this;
@override
String get defaultValueCode {
- if (linkedNode != null) {
- return linkedContext.getDefaultValueCode(linkedNode);
+ var linkedNode = this.linkedNode;
+ if (linkedNode is DefaultFormalParameter) {
+ return linkedNode.defaultValue?.toSource();
}
return _defaultValueCode;
@@ -6399,25 +6366,6 @@
return super.hasImplicitType;
}
- /// True if this parameter inherits from a covariant parameter. This happens
- /// when it overrides a method in a supertype that has a corresponding
- /// covariant parameter.
- bool get inheritsCovariant {
- if (linkedNode != null) {
- return linkedContext.getInheritsCovariant(linkedNode);
- }
- return _inheritsCovariant;
- }
-
- /// Record whether or not this parameter inherits from a covariant parameter.
- set inheritsCovariant(bool value) {
- if (linkedNode != null) {
- linkedContext.setInheritsCovariant(linkedNode, value);
- return;
- }
- _inheritsCovariant = value;
- }
-
@override
bool get isCovariant {
if (isExplicitlyCovariant || inheritsCovariant) {
@@ -6461,7 +6409,7 @@
@override
String get name {
if (linkedNode != null) {
- return reference.name;
+ return linkedContext.getFormalParameterName(linkedNode);
}
return super.name;
}
@@ -6498,11 +6446,10 @@
var context = enclosingUnit.linkedContext;
var formalParameters = context.getFormalParameters(linkedNode);
if (formalParameters != null) {
- var containerRef = reference.getChild('@parameter');
return _parameters = ParameterElementImpl.forLinkedNodeList(
this,
context,
- containerRef,
+ null,
formalParameters,
);
} else {
@@ -6523,19 +6470,6 @@
}
@override
- DartType get type => ElementTypeProvider.current.getVariableType(this);
-
- @override
- DartType get typeInternal {
- if (linkedNode != null) {
- if (_type != null) return _type;
- var context = enclosingUnit.linkedContext;
- return _type = context.getType(linkedNode);
- }
- return super.typeInternal;
- }
-
- @override
List<TypeParameterElement> get typeParameters {
if (_typeParameters != null) return _typeParameters;
@@ -6544,13 +6478,10 @@
if (typeParameters == null) {
return _typeParameters = const [];
}
- var containerRef = reference.getChild('@typeParameter');
return _typeParameters =
typeParameters.typeParameters.map<TypeParameterElement>((node) {
- var reference = containerRef.getChild(node.name.name);
var element = node.declaredElement;
- element ??=
- TypeParameterElementImpl.forLinkedNode(this, reference, node);
+ element ??= TypeParameterElementImpl.forLinkedNode(this, node);
return element;
}).toList();
}
@@ -6581,6 +6512,9 @@
safelyVisitChildren(parameters, visitor);
}
+ /// TODO(scheglov) Do we need this method at all?
+ /// We should create all parameter elements during applying resolution.
+ /// Or when we build elements before linking.
static List<ParameterElement> forLinkedNodeList(
ElementImpl enclosing,
LinkedUnitContext context,
@@ -6598,9 +6532,12 @@
if (node is DefaultFormalParameter) {
NormalFormalParameter parameterNode = node.parameter;
- var name = parameterNode.identifier?.name ?? '';
- var reference = containerRef.getChild(name);
- reference.node = node;
+ Reference reference;
+ if (node.isNamed) {
+ var name = parameterNode.identifier?.name ?? '';
+ reference = containerRef?.getChild(name);
+ reference?.node = node;
+ }
if (parameterNode is FieldFormalParameter) {
return DefaultFieldFormalParameterElementImpl.forLinkedNode(
enclosing,
@@ -6615,24 +6552,7 @@
);
}
} else {
- if (node.identifier == null) {
- return ParameterElementImpl.forLinkedNodeFactory(
- enclosing,
- containerRef.getChild(''),
- node,
- );
- } else {
- var name = node.identifier.name;
- var reference = containerRef.getChild(name);
- if (reference.hasElementFor(node)) {
- return reference.element as ParameterElement;
- }
- return ParameterElementImpl.forLinkedNodeFactory(
- enclosing,
- reference,
- node,
- );
- }
+ return ParameterElementImpl.forLinkedNodeFactory(enclosing, null, node);
}
}).toList();
}
@@ -6655,10 +6575,7 @@
bool get inheritsCovariant {
PropertyInducingElement variable = setter.variable;
if (variable is FieldElementImpl) {
- if (variable.linkedNode != null) {
- var context = variable.linkedContext;
- return context.getInheritsCovariant(variable.linkedNode);
- }
+ return variable.inheritsCovariant;
}
return false;
}
@@ -6667,10 +6584,7 @@
set inheritsCovariant(bool value) {
PropertyInducingElement variable = setter.variable;
if (variable is FieldElementImpl) {
- if (variable.linkedNode != null) {
- var context = variable.linkedContext;
- return context.setInheritsCovariant(variable.linkedNode, value);
- }
+ variable.inheritsCovariant = value;
}
}
@@ -6946,6 +6860,7 @@
: super.forVariable(property, reference: reference) {
property.getter = this;
enclosingElement = property.enclosingElement;
+ reference?.element = this;
}
@override
@@ -7083,6 +6998,10 @@
/// this property. After linking this field is always `null`.
PropertyInducingElementTypeInference typeInference;
+ /// The error reported during type inference for this variable, or `null` if
+ /// this variable is not a subject of type inference, or there was no error.
+ TopLevelInferenceError typeInferenceError;
+
/// Initialize a newly created synthetic element to have the given [name] and
/// [offset].
PropertyInducingElementImpl(String name, int offset) : super(name, offset);
@@ -7091,6 +7010,8 @@
ElementImpl enclosing, Reference reference, AstNode linkedNode)
: super.forLinkedNode(enclosing, reference, linkedNode);
+ bool get hasTypeInferred => _type != null;
+
@override
bool get isConstantEvaluated => true;
@@ -7105,23 +7026,12 @@
@override
DartType get type => ElementTypeProvider.current.getFieldType(this);
- /// Return the error reported during type inference for this variable, or
- /// `null` if this variable is not a subject of type inference, or there was
- /// no error.
- TopLevelInferenceError get typeInferenceError {
- if (linkedNode != null) {
- return linkedContext.getTypeInferenceError(linkedNode);
- }
-
- // We don't support type inference errors without linking.
- return null;
- }
-
@override
DartType get typeInternal {
+ if (_type != null) return _type;
+
if (linkedNode != null) {
- if (_type != null) return _type;
- _type = linkedContext.getType(linkedNode);
+ linkedContext.applyResolution(linkedNode);
// While performing inference during linking, the first step is to collect
// dependencies. During this step we resolve the expression, but we might
@@ -7195,7 +7105,7 @@
@override
int get end {
if (linkedNode != null) {
- return linkedContext.getCombinatorEnd(linkedNode);
+ return linkedNode.end;
}
return _end;
}
@@ -7256,6 +7166,9 @@
TopLevelVariableElementImpl.forLinkedNode(
ElementImpl enclosing, Reference reference, AstNode linkedNode)
: super.forLinkedNode(enclosing, reference, linkedNode) {
+ if (linkedNode is VariableDeclaration) {
+ linkedNode.name.staticElement = this;
+ }
if (!linkedNode.isSynthetic) {
var enclosingRef = enclosing.reference;
@@ -7317,7 +7230,7 @@
/// 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;
+ DartType defaultType;
/// The type representing the bound associated with this parameter, or `null`
/// if this parameter does not have an explicit bound.
@@ -7332,8 +7245,8 @@
TypeParameterElementImpl(String name, int offset) : super(name, offset);
TypeParameterElementImpl.forLinkedNode(
- ElementImpl enclosing, Reference reference, TypeParameter linkedNode)
- : super.forLinkedNode(enclosing, reference, linkedNode) {
+ ElementImpl enclosing, TypeParameter linkedNode)
+ : super.forLinkedNode(enclosing, null, linkedNode) {
linkedNode.name.staticElement = this;
}
@@ -7353,9 +7266,9 @@
DartType get boundInternal {
if (_bound != null) return _bound;
- if (linkedNode != null) {
- var context = enclosingUnit.linkedContext;
- return _bound = context.getTypeParameterBound(linkedNode)?.type;
+ var linkedNode = this.linkedNode;
+ if (linkedNode is TypeParameter) {
+ return _bound = linkedNode.bound?.type;
}
return _bound;
@@ -7380,29 +7293,10 @@
@override
TypeParameterElement get declaration => this;
- /// 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 get defaultType {
- if (_defaultType != null) return _defaultType;
-
- if (linkedNode != null) {
- return _defaultType = linkedContext.getDefaultType(linkedNode);
- }
- return null;
- }
-
- set defaultType(DartType defaultType) {
- _defaultType = defaultType;
- }
-
@override
String get displayName => name;
bool get isLegacyCovariant {
- if (linkedNode != null) {
- return linkedContext.getTypeParameterVariance(linkedNode) == null;
- }
return _variance == null;
}
@@ -7428,12 +7322,6 @@
}
Variance get variance {
- if (_variance != null) return _variance;
-
- if (linkedNode != null) {
- _variance = linkedContext.getTypeParameterVariance(linkedNode);
- }
-
return _variance ?? Variance.covariant;
}
@@ -7489,18 +7377,16 @@
if (_typeParameterElements != null) return _typeParameterElements;
if (linkedNode != null) {
+ linkedContext.applyResolution(linkedNode);
var typeParameters = linkedContext.getTypeParameters2(linkedNode);
if (typeParameters == null) {
return _typeParameterElements = const [];
}
- var containerRef = reference.getChild('@typeParameter');
return _typeParameterElements =
typeParameters.typeParameters.map<TypeParameterElement>((node) {
- var reference = containerRef.getChild(node.name.name);
- if (reference.hasElementFor(node)) {
- return reference.element as TypeParameterElement /*!*/;
- }
- return TypeParameterElementImpl.forLinkedNode(this, reference, node);
+ var element = node.declaredElement;
+ element ??= TypeParameterElementImpl.forLinkedNode(this, node);
+ return element;
}).toList();
}
@@ -7655,9 +7541,6 @@
DartType get type => ElementTypeProvider.current.getVariableType(this);
set type(DartType type) {
- if (linkedNode != null) {
- return linkedContext.setVariableType(linkedNode, type);
- }
_type = type;
}
diff --git a/pkg/analyzer/lib/src/dart/element/replacement_visitor.dart b/pkg/analyzer/lib/src/dart/element/replacement_visitor.dart
index c90174a..87503e9 100644
--- a/pkg/analyzer/lib/src/dart/element/replacement_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/element/replacement_visitor.dart
@@ -162,7 +162,7 @@
var typeParameter = node.typeFormals[i];
var bound = typeParameter.bound;
if (bound != null) {
- var newBound = bound.accept(this);
+ var newBound = visitTypeParameterBound(bound);
if (newBound != null) {
newTypeParameters ??= node.typeFormals.toList(growable: false);
newTypeParameters[i] = TypeParameterElementImpl.synthetic(
@@ -258,7 +258,7 @@
var typeParameter = node.typeFormals[i];
var bound = typeParameter.bound;
if (bound != null) {
- var newBound = bound.accept(this);
+ var newBound = visitTypeParameterBound(bound);
if (newBound != null) {
newTypeParameters ??= node.typeFormals.toList(growable: false);
newTypeParameters[i] = TypeParameterElementImpl.synthetic(
@@ -394,6 +394,10 @@
return argument.accept(this);
}
+ DartType visitTypeParameterBound(DartType type) {
+ return type.accept(this);
+ }
+
@override
DartType visitTypeParameterType(TypeParameterType type) {
var newNullability = visitNullability(type);
diff --git a/pkg/analyzer/lib/src/dart/element/type_system.dart b/pkg/analyzer/lib/src/dart/element/type_system.dart
index c38172a..d81326c 100644
--- a/pkg/analyzer/lib/src/dart/element/type_system.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_system.dart
@@ -20,6 +20,7 @@
import 'package:analyzer/src/dart/element/normalize.dart';
import 'package:analyzer/src/dart/element/nullability_eliminator.dart';
import 'package:analyzer/src/dart/element/replace_top_bottom_visitor.dart';
+import 'package:analyzer/src/dart/element/replacement_visitor.dart';
import 'package:analyzer/src/dart/element/runtime_type_equality.dart';
import 'package:analyzer/src/dart/element/subtype.dart';
import 'package:analyzer/src/dart/element/top_merge.dart';
@@ -597,6 +598,8 @@
if (type is FunctionType) {
appendParameters(type.returnType);
type.parameters.map((p) => p.type).forEach(appendParameters);
+ // TODO(scheglov) https://github.com/dart-lang/sdk/issues/44218
+ type.typeArguments.forEach(appendParameters);
} else if (type is InterfaceType) {
type.typeArguments.forEach(appendParameters);
}
@@ -1230,6 +1233,8 @@
typeParameters,
considerExtendsClause: false,
);
+ inferredTypes =
+ inferredTypes.map(_removeBoundsOfGenericFunctionTypes).toList();
var substitution = Substitution.fromPairs(typeParameters, inferredTypes);
for (int i = 0; i < srcTypes.length; i++) {
@@ -1785,6 +1790,15 @@
return currentType;
}
+ DartType _removeBoundsOfGenericFunctionTypes(DartType type) {
+ return _RemoveBoundsOfGenericFunctionTypeVisitor.run(
+ bottomType: isNonNullableByDefault
+ ? NeverTypeImpl.instance
+ : typeProvider.nullType,
+ type: type,
+ );
+ }
+
/// Starting from the given [type], search its class hierarchy for types of
/// the form Future<R>, and return a list of the resulting R's.
List<DartType> _searchTypeHierarchyForFutureTypeParameters(DartType type) {
@@ -1810,6 +1824,27 @@
}
}
+/// TODO(scheglov) Ask the language team how to deal with it.
+class _RemoveBoundsOfGenericFunctionTypeVisitor extends ReplacementVisitor {
+ final DartType _bottomType;
+
+ _RemoveBoundsOfGenericFunctionTypeVisitor._(this._bottomType);
+
+ @override
+ DartType visitTypeParameterBound(DartType type) {
+ return _bottomType;
+ }
+
+ static DartType run({
+ @required DartType bottomType,
+ @required DartType type,
+ }) {
+ var visitor = _RemoveBoundsOfGenericFunctionTypeVisitor._(bottomType);
+ var result = type.accept(visitor);
+ return result ?? type;
+ }
+}
+
class _TypeVariableEliminator extends Substitution {
final DartType _topType;
final DartType _bottomType;
diff --git a/pkg/analyzer/lib/src/dart/error/ffi_code.dart b/pkg/analyzer/lib/src/dart/error/ffi_code.dart
index f2711d9..eda16d1 100644
--- a/pkg/analyzer/lib/src/dart/error/ffi_code.dart
+++ b/pkg/analyzer/lib/src/dart/error/ffi_code.dart
@@ -170,10 +170,11 @@
* 1: the name of the class being extended, implemented, or mixed in
*/
static const FfiCode SUBTYPE_OF_FFI_CLASS_IN_EXTENDS = FfiCode(
- name: 'SUBTYPE_OF_FFI_CLASS',
- uniqueName: 'SUBTYPE_OF_FFI_CLASS_IN_EXTENDS',
- message: "The class '{0}' can't extend '{1}'.",
- correction: "Try extending 'Struct'.");
+ name: 'SUBTYPE_OF_FFI_CLASS',
+ message: "The class '{0}' can't extend '{1}'.",
+ correction: "Try extending 'Struct'.",
+ uniqueName: 'SUBTYPE_OF_FFI_CLASS_IN_EXTENDS',
+ );
/**
* Parameters:
@@ -181,10 +182,11 @@
* 1: the name of the class being extended, implemented, or mixed in
*/
static const FfiCode SUBTYPE_OF_FFI_CLASS_IN_IMPLEMENTS = FfiCode(
- name: 'SUBTYPE_OF_FFI_CLASS',
- uniqueName: 'SUBTYPE_OF_FFI_CLASS_IN_IMPLEMENTS',
- message: "The class '{0}' can't implement '{1}'.",
- correction: "Try extending 'Struct'.");
+ name: 'SUBTYPE_OF_FFI_CLASS',
+ message: "The class '{0}' can't implement '{1}'.",
+ correction: "Try extending 'Struct'.",
+ uniqueName: 'SUBTYPE_OF_FFI_CLASS_IN_IMPLEMENTS',
+ );
/**
* Parameters:
@@ -192,10 +194,11 @@
* 1: the name of the class being extended, implemented, or mixed in
*/
static const FfiCode SUBTYPE_OF_FFI_CLASS_IN_WITH = FfiCode(
- name: 'SUBTYPE_OF_FFI_CLASS',
- uniqueName: 'SUBTYPE_OF_FFI_CLASS_IN_WITH',
- message: "The class '{0}' can't mix in '{1}'.",
- correction: "Try extending 'Struct'.");
+ name: 'SUBTYPE_OF_FFI_CLASS',
+ message: "The class '{0}' can't mix in '{1}'.",
+ correction: "Try extending 'Struct'.",
+ uniqueName: 'SUBTYPE_OF_FFI_CLASS_IN_WITH',
+ );
/**
* Parameters:
@@ -203,12 +206,12 @@
* 1: the name of the class being extended, implemented, or mixed in
*/
static const FfiCode SUBTYPE_OF_STRUCT_CLASS_IN_EXTENDS = FfiCode(
- name: 'SUBTYPE_OF_STRUCT_CLASS',
- uniqueName: 'SUBTYPE_OF_STRUCT_CLASS_IN_EXTENDS',
- message:
- "The class '{0}' can't extend '{1}' because '{1}' is a subtype of "
- "'Struct'.",
- correction: "Try extending 'Struct' directly.");
+ name: 'SUBTYPE_OF_STRUCT_CLASS',
+ message: "The class '{0}' can't extend '{1}' because '{1}' is a subtype of "
+ "'Struct'.",
+ correction: "Try extending 'Struct' directly.",
+ uniqueName: 'SUBTYPE_OF_STRUCT_CLASS_IN_EXTENDS',
+ );
/**
* Parameters:
@@ -216,12 +219,13 @@
* 1: the name of the class being extended, implemented, or mixed in
*/
static const FfiCode SUBTYPE_OF_STRUCT_CLASS_IN_IMPLEMENTS = FfiCode(
- name: 'SUBTYPE_OF_STRUCT_CLASS',
- uniqueName: 'SUBTYPE_OF_STRUCT_CLASS_IN_IMPLEMENTS',
- message:
- "The class '{0}' can't implement '{1}' because '{1}' is a subtype of "
- "'Struct'.",
- correction: "Try extending 'Struct' directly.");
+ name: 'SUBTYPE_OF_STRUCT_CLASS',
+ message:
+ "The class '{0}' can't implement '{1}' because '{1}' is a subtype of "
+ "'Struct'.",
+ correction: "Try extending 'Struct' directly.",
+ uniqueName: 'SUBTYPE_OF_STRUCT_CLASS_IN_IMPLEMENTS',
+ );
/**
* Parameters:
@@ -229,15 +233,12 @@
* 1: the name of the class being extended, implemented, or mixed in
*/
static const FfiCode SUBTYPE_OF_STRUCT_CLASS_IN_WITH = FfiCode(
- name: 'SUBTYPE_OF_STRUCT_CLASS',
- uniqueName: 'SUBTYPE_OF_STRUCT_CLASS_IN_WITH',
- message:
- "The class '{0}' can't mix in '{1}' because '{1}' is a subtype of "
- "'Struct'.",
- correction: "Try extending 'Struct' directly.");
-
- @override
- final String uniqueName;
+ name: 'SUBTYPE_OF_STRUCT_CLASS',
+ message: "The class '{0}' can't mix in '{1}' because '{1}' is a subtype of "
+ "'Struct'.",
+ correction: "Try extending 'Struct' directly.",
+ uniqueName: 'SUBTYPE_OF_STRUCT_CLASS_IN_WITH',
+ );
/// Initialize a newly created error code to have the given [name]. If
/// [uniqueName] is provided, then it will be used to construct the unique
@@ -249,16 +250,19 @@
/// created from the given [correction] template.
///
/// If [hasPublishedDocs] is `true` then a URL for the docs will be generated.
- const FfiCode(
- {@required String message,
- @required String name,
- String correction,
- bool hasPublishedDocs,
- String uniqueName})
- : uniqueName =
- uniqueName == null ? 'FfiCode.$name' : 'FfiCode.$uniqueName',
- super.temporary(name, message,
- correction: correction, hasPublishedDocs: hasPublishedDocs);
+ const FfiCode({
+ String correction,
+ bool hasPublishedDocs = false,
+ @required String message,
+ @required String name,
+ String uniqueName,
+ }) : super(
+ correction: correction,
+ hasPublishedDocs: hasPublishedDocs,
+ message: message,
+ name: name,
+ uniqueName: uniqueName ?? 'FfiCode.$name',
+ );
@override
ErrorSeverity get errorSeverity => type.severity;
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index c72f379..402b9c7 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -293,27 +293,28 @@
* 1: message details
*/
static const HintCode DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE_WITH_MESSAGE =
- HintCodeWithUniqueName(
- 'DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE',
- 'HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE_WITH_MESSAGE',
- "'{0}' is deprecated and shouldn't be used. {1}.",
- correction: "Try replacing the use of the deprecated member with the "
- "replacement.",
- hasPublishedDocs: true);
+ HintCode(
+ 'DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE',
+ "'{0}' is deprecated and shouldn't be used. {1}.",
+ correction: "Try replacing the use of the deprecated member with the "
+ "replacement.",
+ hasPublishedDocs: true,
+ uniqueName: 'HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE_WITH_MESSAGE',
+ );
/**
* Parameters:
* 0: the name of the member
* 1: message details
*/
- static const HintCode DEPRECATED_MEMBER_USE_WITH_MESSAGE =
- HintCodeWithUniqueName(
- 'DEPRECATED_MEMBER_USE',
- 'HintCode.DEPRECATED_MEMBER_USE_WITH_MESSAGE',
- "'{0}' is deprecated and shouldn't be used. {1}.",
- correction: "Try replacing the use of the deprecated member with the "
- "replacement.",
- hasPublishedDocs: true);
+ static const HintCode DEPRECATED_MEMBER_USE_WITH_MESSAGE = HintCode(
+ 'DEPRECATED_MEMBER_USE',
+ "'{0}' is deprecated and shouldn't be used. {1}.",
+ correction: "Try replacing the use of the deprecated member with the "
+ "replacement.",
+ hasPublishedDocs: true,
+ uniqueName: 'HintCode.DEPRECATED_MEMBER_USE_WITH_MESSAGE',
+ );
/**
* `Function` should not be mixed in anymore.
@@ -721,13 +722,13 @@
/// valid language version override comment, it is reported.
///
/// [1] https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/feature-specification.md#individual-library-language-version-override
- static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_AT_SIGN =
- HintCodeWithUniqueName(
- 'INVALID_LANGUAGE_VERSION_OVERRIDE',
- 'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_AT_SIGN',
- "The Dart language version override number must begin with '@dart'",
- correction: "Specify a Dart language version override with a comment "
- "like '// @dart = 2.0'.");
+ static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_AT_SIGN = HintCode(
+ 'INVALID_LANGUAGE_VERSION_OVERRIDE',
+ "The Dart language version override number must begin with '@dart'",
+ correction: "Specify a Dart language version override with a comment "
+ "like '// @dart = 2.0'.",
+ uniqueName: 'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_AT_SIGN',
+ );
/// Invalid Dart language version comments don't follow the specification [1].
/// If a comment begins with "@dart" or "dart" (letters in any case),
@@ -739,32 +740,30 @@
/// valid language version override comment, it is reported.
///
/// [1] https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/feature-specification.md#individual-library-language-version-override
- static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_EQUALS =
- HintCodeWithUniqueName(
- 'INVALID_LANGUAGE_VERSION_OVERRIDE',
- 'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_EQUALS',
- "The Dart language version override comment must be specified with "
- "an '=' character",
- correction: "Specify a Dart language version override with a comment "
- "like '// @dart = 2.0'.");
-
- static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_GREATER =
- HintCodeWithUniqueName(
+ static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_EQUALS = HintCode(
'INVALID_LANGUAGE_VERSION_OVERRIDE',
- 'INVALID_LANGUAGE_VERSION_OVERRIDE_GREATER',
+ "The Dart language version override comment must be specified with "
+ "an '=' character",
+ correction: "Specify a Dart language version override with a comment "
+ "like '// @dart = 2.0'.",
+ uniqueName: 'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_EQUALS',
+ );
+
+ static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_GREATER = HintCode(
+ 'INVALID_LANGUAGE_VERSION_OVERRIDE',
"The language version override can't specify a version greater than the "
"latest known language version: {0}.{1}",
correction: "Try removing the language version override.",
+ uniqueName: 'INVALID_LANGUAGE_VERSION_OVERRIDE_GREATER',
);
- static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_LOCATION =
- HintCodeWithUniqueName(
+ static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_LOCATION = HintCode(
'INVALID_LANGUAGE_VERSION_OVERRIDE',
- 'INVALID_LANGUAGE_VERSION_OVERRIDE_LOCATION',
"The language version override must be before any declaration or "
"directive.",
correction:
"Try moving the language version override to the top of the file.",
+ uniqueName: 'INVALID_LANGUAGE_VERSION_OVERRIDE_LOCATION',
);
/// Invalid Dart language version comments don't follow the specification [1].
@@ -777,14 +776,14 @@
/// valid language version override comment, it is reported.
///
/// [1] https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/feature-specification.md#individual-library-language-version-override
- static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_LOWER_CASE =
- HintCodeWithUniqueName(
- 'INVALID_LANGUAGE_VERSION_OVERRIDE',
- 'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_LOWER_CASE',
- "The Dart language version override comment must be specified with "
- "the word 'dart' in all lower case",
- correction: "Specify a Dart language version override with a comment "
- "like '// @dart = 2.0'.");
+ static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_LOWER_CASE = HintCode(
+ 'INVALID_LANGUAGE_VERSION_OVERRIDE',
+ "The Dart language version override comment must be specified with "
+ "the word 'dart' in all lower case",
+ correction: "Specify a Dart language version override with a comment "
+ "like '// @dart = 2.0'.",
+ uniqueName: 'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_LOWER_CASE',
+ );
/// Invalid Dart language version comments don't follow the specification [1].
/// If a comment begins with "@dart" or "dart" (letters in any case),
@@ -796,14 +795,14 @@
/// valid language version override comment, it is reported.
///
/// [1] https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/feature-specification.md#individual-library-language-version-override
- static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_NUMBER =
- HintCodeWithUniqueName(
- 'INVALID_LANGUAGE_VERSION_OVERRIDE',
- 'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_NUMBER',
- "The Dart language version override comment must be specified with a "
- "version number, like '2.0', after the '=' character.",
- correction: "Specify a Dart language version override with a comment "
- "like '// @dart = 2.0'.");
+ static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_NUMBER = HintCode(
+ 'INVALID_LANGUAGE_VERSION_OVERRIDE',
+ "The Dart language version override comment must be specified with a "
+ "version number, like '2.0', after the '=' character.",
+ correction: "Specify a Dart language version override with a comment "
+ "like '// @dart = 2.0'.",
+ uniqueName: 'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_NUMBER',
+ );
/// Invalid Dart language version comments don't follow the specification [1].
/// If a comment begins with "@dart" or "dart" (letters in any case),
@@ -815,14 +814,14 @@
/// valid language version override comment, it is reported.
///
/// [1] https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/feature-specification.md#individual-library-language-version-override
- static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_PREFIX =
- HintCodeWithUniqueName(
- 'INVALID_LANGUAGE_VERSION_OVERRIDE',
- 'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_PREFIX',
- "The Dart language version override number can't be prefixed with "
- "a letter",
- correction: "Specify a Dart language version override with a comment "
- "like '// @dart = 2.0'.");
+ static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_PREFIX = HintCode(
+ 'INVALID_LANGUAGE_VERSION_OVERRIDE',
+ "The Dart language version override number can't be prefixed with "
+ "a letter",
+ correction: "Specify a Dart language version override with a comment "
+ "like '// @dart = 2.0'.",
+ uniqueName: 'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_PREFIX',
+ );
/// Invalid Dart language version comments don't follow the specification [1].
/// If a comment begins with "@dart" or "dart" (letters in any case),
@@ -835,13 +834,15 @@
///
/// [1] https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/feature-specification.md#individual-library-language-version-override
static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_TRAILING_CHARACTERS =
- HintCodeWithUniqueName(
- 'INVALID_LANGUAGE_VERSION_OVERRIDE',
- 'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_TRAILING_CHARACTERS',
- "The Dart language version override comment can't be followed by "
- "any non-whitespace characters",
- correction: "Specify a Dart language version override with a comment "
- "like '// @dart = 2.0'.");
+ HintCode(
+ 'INVALID_LANGUAGE_VERSION_OVERRIDE',
+ "The Dart language version override comment can't be followed by "
+ "any non-whitespace characters",
+ correction: "Specify a Dart language version override with a comment "
+ "like '// @dart = 2.0'.",
+ uniqueName:
+ 'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_TRAILING_CHARACTERS',
+ );
/// Invalid Dart language version comments don't follow the specification [1].
/// If a comment begins with "@dart" or "dart" (letters in any case),
@@ -854,13 +855,14 @@
///
/// [1] https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/feature-specification.md#individual-library-language-version-override
static const HintCode INVALID_LANGUAGE_VERSION_OVERRIDE_TWO_SLASHES =
- HintCodeWithUniqueName(
- 'INVALID_LANGUAGE_VERSION_OVERRIDE',
- 'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_TWO_SLASHES',
- 'The Dart language version override comment must be specified with '
- 'exactly two slashes.',
- correction: "Specify a Dart language version override with a comment "
- "like '// @dart = 2.0'.");
+ HintCode(
+ 'INVALID_LANGUAGE_VERSION_OVERRIDE',
+ 'The Dart language version override comment must be specified with '
+ 'exactly two slashes.',
+ correction: "Specify a Dart language version override with a comment "
+ "like '// @dart = 2.0'.",
+ uniqueName: 'HintCode.INVALID_LANGUAGE_VERSION_OVERRIDE_TWO_SLASHES',
+ );
/**
* No parameters.
@@ -1186,12 +1188,12 @@
* 0: the name of the parameter
* 1: message details
*/
- static const HintCode MISSING_REQUIRED_PARAM_WITH_DETAILS =
- HintCodeWithUniqueName(
- 'MISSING_REQUIRED_PARAM',
- 'HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS',
- "The parameter '{0}' is required. {1}.",
- hasPublishedDocs: true);
+ static const HintCode MISSING_REQUIRED_PARAM_WITH_DETAILS = HintCode(
+ 'MISSING_REQUIRED_PARAM',
+ "The parameter '{0}' is required. {1}.",
+ hasPublishedDocs: true,
+ uniqueName: 'HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS',
+ );
/**
* Parameters:
@@ -1453,13 +1455,14 @@
* 0: the name of the class defining the annotated constructor
*/
static const HintCode NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR_USING_NEW =
- HintCodeWithUniqueName(
- 'NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR',
- 'HintCode.NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR_USING_NEW',
- "This instance creation must be 'const', because the {0} constructor "
- "is marked as '@literal'.",
- correction: "Try replacing the 'new' keyword with 'const'.",
- hasPublishedDocs: true);
+ HintCode(
+ 'NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR',
+ "This instance creation must be 'const', because the {0} constructor "
+ "is marked as '@literal'.",
+ correction: "Try replacing the 'new' keyword with 'const'.",
+ hasPublishedDocs: true,
+ uniqueName: 'HintCode.NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR_USING_NEW',
+ );
/**
* When the left operand of a binary expression uses '?.' operator, it can be
@@ -1560,28 +1563,28 @@
*
* No parameters.
*/
- static const HintCode OVERRIDE_ON_NON_OVERRIDING_FIELD =
- HintCodeWithUniqueName(
- 'OVERRIDE_ON_NON_OVERRIDING_MEMBER',
- 'HintCode.OVERRIDE_ON_NON_OVERRIDING_FIELD',
- "The field doesn't override an inherited getter or setter.",
- correction: "Try updating this class to match the superclass, or "
- "removing the override annotation.",
- hasPublishedDocs: true);
+ static const HintCode OVERRIDE_ON_NON_OVERRIDING_FIELD = HintCode(
+ 'OVERRIDE_ON_NON_OVERRIDING_MEMBER',
+ "The field doesn't override an inherited getter or setter.",
+ correction: "Try updating this class to match the superclass, or "
+ "removing the override annotation.",
+ hasPublishedDocs: true,
+ uniqueName: 'HintCode.OVERRIDE_ON_NON_OVERRIDING_FIELD',
+ );
/**
* A getter with the override annotation does not override an existing getter.
*
* No parameters.
*/
- static const HintCode OVERRIDE_ON_NON_OVERRIDING_GETTER =
- HintCodeWithUniqueName(
- 'OVERRIDE_ON_NON_OVERRIDING_MEMBER',
- 'HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER',
- "The getter doesn't override an inherited getter.",
- correction: "Try updating this class to match the superclass, or "
- "removing the override annotation.",
- hasPublishedDocs: true);
+ static const HintCode OVERRIDE_ON_NON_OVERRIDING_GETTER = HintCode(
+ 'OVERRIDE_ON_NON_OVERRIDING_MEMBER',
+ "The getter doesn't override an inherited getter.",
+ correction: "Try updating this class to match the superclass, or "
+ "removing the override annotation.",
+ hasPublishedDocs: true,
+ uniqueName: 'HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER',
+ );
/**
* A method with the override annotation does not override an existing method.
@@ -1622,28 +1625,28 @@
// superclass, then consider removing the member from the subclass.
//
// If the member can't be removed, then remove the annotation.
- static const HintCode OVERRIDE_ON_NON_OVERRIDING_METHOD =
- HintCodeWithUniqueName(
- 'OVERRIDE_ON_NON_OVERRIDING_MEMBER',
- 'HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD',
- "The method doesn't override an inherited method.",
- correction: "Try updating this class to match the superclass, or "
- "removing the override annotation.",
- hasPublishedDocs: true);
+ static const HintCode OVERRIDE_ON_NON_OVERRIDING_METHOD = HintCode(
+ 'OVERRIDE_ON_NON_OVERRIDING_MEMBER',
+ "The method doesn't override an inherited method.",
+ correction: "Try updating this class to match the superclass, or "
+ "removing the override annotation.",
+ hasPublishedDocs: true,
+ uniqueName: 'HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD',
+ );
/**
* A setter with the override annotation does not override an existing setter.
*
* No parameters.
*/
- static const HintCode OVERRIDE_ON_NON_OVERRIDING_SETTER =
- HintCodeWithUniqueName(
- 'OVERRIDE_ON_NON_OVERRIDING_MEMBER',
- 'HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER',
- "The setter doesn't override an inherited setter.",
- correction: "Try updating this class to match the superclass, or "
- "removing the override annotation.",
- hasPublishedDocs: true);
+ static const HintCode OVERRIDE_ON_NON_OVERRIDING_SETTER = HintCode(
+ 'OVERRIDE_ON_NON_OVERRIDING_MEMBER',
+ "The setter doesn't override an inherited setter.",
+ correction: "Try updating this class to match the superclass, or "
+ "removing the override annotation.",
+ hasPublishedDocs: true,
+ uniqueName: 'HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER',
+ );
/**
* It is a bad practice for a package import to reference anything outside the
@@ -2544,47 +2547,49 @@
// print(x);
// }
// ```
- static const HintCode UNNECESSARY_NULL_COMPARISON_FALSE =
- HintCodeWithUniqueName(
- 'UNNECESSARY_NULL_COMPARISON',
- 'UNNECESSARY_NULL_COMPARISON_FALSE',
- "The operand can't be null, so the condition is always false.",
- correction: "Try removing the condition, an enclosing condition, "
- "or the whole conditional statement.",
- hasPublishedDocs: true);
+ static const HintCode UNNECESSARY_NULL_COMPARISON_FALSE = HintCode(
+ 'UNNECESSARY_NULL_COMPARISON',
+ "The operand can't be null, so the condition is always false.",
+ correction: "Try removing the condition, an enclosing condition, "
+ "or the whole conditional statement.",
+ hasPublishedDocs: true,
+ uniqueName: 'UNNECESSARY_NULL_COMPARISON_FALSE',
+ );
/**
* No parameters.
*/
- static const HintCode UNNECESSARY_NULL_COMPARISON_TRUE =
- HintCodeWithUniqueName(
- 'UNNECESSARY_NULL_COMPARISON',
- 'UNNECESSARY_NULL_COMPARISON_TRUE',
- "The operand can't be null, so the condition is always true.",
- correction: "Remove the condition.",
- hasPublishedDocs: true);
+ static const HintCode UNNECESSARY_NULL_COMPARISON_TRUE = HintCode(
+ 'UNNECESSARY_NULL_COMPARISON',
+ "The operand can't be null, so the condition is always true.",
+ correction: "Remove the condition.",
+ hasPublishedDocs: true,
+ uniqueName: 'UNNECESSARY_NULL_COMPARISON_TRUE',
+ );
/**
* Unnecessary type checks, the result is always false.
*
* No parameters.
*/
- static const HintCode UNNECESSARY_TYPE_CHECK_FALSE = HintCodeWithUniqueName(
- 'UNNECESSARY_TYPE_CHECK',
- 'UNNECESSARY_TYPE_CHECK_FALSE',
- "Unnecessary type check, the result is always false.",
- correction: "Try correcting the type check, or removing the type check.");
+ static const HintCode UNNECESSARY_TYPE_CHECK_FALSE = HintCode(
+ 'UNNECESSARY_TYPE_CHECK',
+ "Unnecessary type check, the result is always false.",
+ correction: "Try correcting the type check, or removing the type check.",
+ uniqueName: 'UNNECESSARY_TYPE_CHECK_FALSE',
+ );
/**
* Unnecessary type checks, the result is always true.
*
* No parameters.
*/
- static const HintCode UNNECESSARY_TYPE_CHECK_TRUE = HintCodeWithUniqueName(
- 'UNNECESSARY_TYPE_CHECK',
- 'UNNECESSARY_TYPE_CHECK_TRUE',
- "Unnecessary type check, the result is always true.",
- correction: "Try correcting the type check, or removing the type check.");
+ static const HintCode UNNECESSARY_TYPE_CHECK_TRUE = HintCode(
+ 'UNNECESSARY_TYPE_CHECK',
+ "Unnecessary type check, the result is always true.",
+ correction: "Try correcting the type check, or removing the type check.",
+ uniqueName: 'UNNECESSARY_TYPE_CHECK_TRUE',
+ );
/**
* Parameters:
@@ -2734,12 +2739,13 @@
* Parameters:
* 0: the name of the parameter that is declared but not used
*/
- static const HintCode UNUSED_ELEMENT_PARAMETER = HintCodeWithUniqueName(
- 'UNUSED_ELEMENT',
- 'HintCode.UNUSED_ELEMENT_PARAMETER',
- "A value for optional parameter '{0}' isn't ever given.",
- correction: "Try removing the unused parameter.",
- hasPublishedDocs: true);
+ static const HintCode UNUSED_ELEMENT_PARAMETER = HintCode(
+ 'UNUSED_ELEMENT',
+ "A value for optional parameter '{0}' isn't ever given.",
+ correction: "Try removing the unused parameter.",
+ hasPublishedDocs: true,
+ uniqueName: 'HintCode.UNUSED_ELEMENT_PARAMETER',
+ );
/**
* Parameters:
@@ -2926,10 +2932,19 @@
* template. The correction associated with the error will be created from the
* given [correction] template.
*/
- const HintCode(String name, String message,
- {String correction, bool hasPublishedDocs})
- : super.temporary(name, message,
- correction: correction, hasPublishedDocs: hasPublishedDocs);
+ const HintCode(
+ String name,
+ String message, {
+ String correction,
+ bool hasPublishedDocs = false,
+ String uniqueName,
+ }) : super(
+ correction: correction,
+ hasPublishedDocs: hasPublishedDocs,
+ message: message,
+ name: name,
+ uniqueName: uniqueName ?? 'HintCode.$name',
+ );
@override
ErrorSeverity get errorSeverity => ErrorType.HINT.severity;
@@ -2937,15 +2952,3 @@
@override
ErrorType get type => ErrorType.HINT;
}
-
-/// A [HintCode] class in which a [uniqueName] can be given which is not just
-/// derived from [name].
-class HintCodeWithUniqueName extends HintCode {
- @override
- final String uniqueName;
-
- const HintCodeWithUniqueName(String name, this.uniqueName, String message,
- {String correction, bool hasPublishedDocs})
- : super(name, message,
- correction: correction, hasPublishedDocs: hasPublishedDocs);
-}
diff --git a/pkg/analyzer/lib/src/dart/error/lint_codes.dart b/pkg/analyzer/lib/src/dart/error/lint_codes.dart
index 5b5e320..cc1f0c2 100644
--- a/pkg/analyzer/lib/src/dart/error/lint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/lint_codes.dart
@@ -10,8 +10,17 @@
/// compiler, lint recommendations focus on matters of style and practices that
/// might aggregated to define a project's style guide.
class LintCode extends ErrorCode {
- const LintCode(String name, String message, {String correction})
- : super.temporary(name, message, correction: correction);
+ const LintCode(
+ String name,
+ String message, {
+ String correction,
+ String uniqueName,
+ }) : super(
+ correction: correction,
+ message: message,
+ name: name,
+ uniqueName: uniqueName ?? 'LintCode.$name',
+ );
@override
ErrorSeverity get errorSeverity => ErrorSeverity.INFO;
@@ -22,12 +31,6 @@
@override
ErrorType get type => ErrorType.LINT;
- /// Overridden so that [LintCode] and its subclasses share the same uniqueName
- /// pattern (we know how to identify a lint even if we don't know the specific
- /// subclass the lint's code is defined in.
- @override
- String get uniqueName => "LintCode.$name";
-
@override
String get url => 'https://dart-lang.github.io/linter/lints/$name.html';
@@ -36,13 +39,11 @@
other is LintCode && uniqueName == other.uniqueName;
}
+@Deprecated('Use SecurityLintCode and its uniqueName')
class LintCodeWithUniqueName extends LintCode {
- @override
- final String uniqueName;
-
- const LintCodeWithUniqueName(String name, this.uniqueName, String message,
+ const LintCodeWithUniqueName(String name, String uniqueName, String message,
{String correction})
- : super(name, message, correction: correction);
+ : super(name, message, uniqueName: uniqueName, correction: correction);
}
/// Defines security-related best practice recommendations.
@@ -50,19 +51,19 @@
/// The primary difference from [LintCode]s is that these codes cannot be
/// suppressed with `// ignore:` or `// ignore_for_file:` comments.
class SecurityLintCode extends LintCode {
- const SecurityLintCode(String name, String message, {String correction})
- : super(name, message, correction: correction);
+ const SecurityLintCode(String name, String message,
+ {String uniqueName, String correction})
+ : super(name, message,
+ uniqueName: uniqueName ?? 'LintCode.$name', correction: correction);
@override
bool get isIgnorable => false;
}
+@Deprecated('Use SecurityLintCode and its uniqueName')
class SecurityLintCodeWithUniqueName extends SecurityLintCode {
- @override
- final String uniqueName;
-
const SecurityLintCodeWithUniqueName(
- String name, this.uniqueName, String message,
+ String name, String uniqueName, String message,
{String correction})
- : super(name, message, correction: correction);
+ : super(name, message, uniqueName: uniqueName, correction: correction);
}
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
index d2d3c6c..8472e01 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
@@ -924,11 +924,19 @@
* template. The correction associated with the error will be created from the
* given [correction] template.
*/
- const ParserErrorCode(String name, String message,
- {String correction, bool hasPublishedDocs})
- : super.temporary(name, message,
- correction: correction,
- hasPublishedDocs: hasPublishedDocs ?? false);
+ const ParserErrorCode(
+ String name,
+ String message, {
+ String correction,
+ bool hasPublishedDocs = false,
+ String uniqueName,
+ }) : super(
+ correction: correction,
+ hasPublishedDocs: hasPublishedDocs,
+ message: message,
+ name: name,
+ uniqueName: uniqueName ?? 'ParserErrorCode.$name',
+ );
@override
ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
diff --git a/pkg/analyzer/lib/src/dart/error/todo_codes.dart b/pkg/analyzer/lib/src/dart/error/todo_codes.dart
index fe6ed97..15db063 100644
--- a/pkg/analyzer/lib/src/dart/error/todo_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/todo_codes.dart
@@ -37,7 +37,12 @@
/**
* Initialize a newly created error code to have the given [name].
*/
- const TodoCode(String name) : super.temporary(name, "{0}");
+ const TodoCode(String name)
+ : super(
+ message: "{0}",
+ name: name,
+ uniqueName: 'TodoCode.$name',
+ );
@override
ErrorSeverity get errorSeverity => ErrorSeverity.INFO;
diff --git a/pkg/analyzer/lib/src/dart/micro/library_graph.dart b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
index b9b4b8e..26887ce 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_graph.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
@@ -29,7 +29,6 @@
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/link.dart' as graph
show DependencyWalker, Node;
-import 'package:analyzer/src/summary2/informative_data.dart';
import 'package:analyzer/src/util/performance/operation_performance.dart';
import 'package:analyzer/src/workspace/workspace.dart';
import 'package:collection/collection.dart';
@@ -425,7 +424,6 @@
),
);
}
- var informativeData = createInformativeData(unit);
var unlinkedBuilder = UnlinkedUnit2Builder(
apiSignature: computeUnlinkedApiSignature(unit),
exports: exports,
@@ -435,7 +433,6 @@
hasPartOfDirective: hasPartOfDirective,
partOfUri: partOfUriStr,
lineStarts: unit.lineInfo.lineStarts,
- informativeData: informativeData,
);
return CiderUnlinkedUnitBuilder(
contentDigest: digest, unlinkedUnit: unlinkedBuilder);
@@ -708,8 +705,11 @@
/// The hash of all the paths of the files in this cycle.
String cyclePathsHash;
- /// id of the cache entry.
- int id;
+ /// id of the ast cache entry.
+ int astId;
+
+ /// id of the resolution cache entry.
+ int resolutionId;
LibraryCycle();
diff --git a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
index 82e250c..29516e9 100644
--- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
+++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
@@ -29,8 +29,8 @@
import 'package:analyzer/src/summary/api_signature.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary2/bundle_reader.dart';
import 'package:analyzer/src/summary2/link.dart' as link2;
-import 'package:analyzer/src/summary2/linked_bundle_context.dart';
import 'package:analyzer/src/summary2/linked_element_factory.dart';
import 'package:analyzer/src/summary2/reference.dart';
import 'package:analyzer/src/task/options.dart';
@@ -641,9 +641,13 @@
/// Clears all the loaded libraries. Returns the cache ids for the removed
/// artifacts.
Set<int> collectSharedDataIdentifiers() {
- var ids = loadedBundles.map((cycle) => cycle.id).toSet();
+ var idSet = <int>{};
+ for (var cycle in loadedBundles) {
+ idSet.add(cycle.astId);
+ idSet.add(cycle.resolutionId);
+ }
loadedBundles.clear();
- return ids;
+ return idSet;
}
/// Load data required to access elements of the given [targetLibrary].
@@ -651,8 +655,6 @@
@required FileState targetLibrary,
@required OperationPerformanceImpl performance,
}) {
- var inputBundles = <LinkedNodeBundle>[];
-
var librariesLinked = 0;
var librariesLinkedTimer = Stopwatch();
var inputsTimer = Stopwatch();
@@ -665,11 +667,14 @@
cycle.directDependencies.forEach(loadBundle);
- var key = cycle.cyclePathsHash;
- var data = byteStore.get(key, cycle.signature);
- var bytes = data?.bytes;
+ var astKey = '${cycle.cyclePathsHash}.ast';
+ var resolutionKey = '${cycle.cyclePathsHash}.resolution';
+ var astData = byteStore.get(astKey, cycle.signature);
+ var resolutionData = byteStore.get(resolutionKey, cycle.signature);
+ var astBytes = astData?.bytes;
+ var resolutionBytes = resolutionData?.bytes;
- if (bytes == null) {
+ if (astBytes == null || resolutionBytes == null) {
librariesLinkedTimer.start();
inputsTimer.start();
@@ -714,39 +719,38 @@
}
inputsTimer.stop();
- var linkResult = link2.link(elementFactory, inputLibraries);
+ var linkResult = link2.link(elementFactory, inputLibraries, true);
librariesLinked += cycle.libraries.length;
- bytes = serializeBundle(cycle.signature, linkResult).toBuffer();
+ astBytes = linkResult.astBytes;
+ resolutionBytes = linkResult.resolutionBytes;
- data = byteStore.putGet(key, cycle.signature, bytes);
- bytes = data.bytes;
- performance.getDataInt('bytesPut').add(bytes.length);
+ astData = byteStore.putGet(astKey, cycle.signature, astBytes);
+ astBytes = astData.bytes;
+ performance.getDataInt('bytesPut').add(astBytes.length);
+
+ resolutionData =
+ byteStore.putGet(resolutionKey, cycle.signature, resolutionBytes);
+ resolutionBytes = resolutionData.bytes;
+ performance.getDataInt('bytesPut').add(resolutionBytes.length);
librariesLinkedTimer.stop();
} else {
- performance.getDataInt('bytesGet').add(bytes.length);
+ performance.getDataInt('bytesGet').add(astBytes.length);
+ performance.getDataInt('bytesGet').add(resolutionBytes.length);
performance.getDataInt('libraryLoadCount').add(cycle.libraries.length);
}
- cycle.id = data.id;
+ cycle.astId = astData.id;
+ cycle.resolutionId = resolutionData.id;
- var cBundle = CiderLinkedLibraryCycle.fromBuffer(bytes);
- inputBundles.add(cBundle.bundle);
elementFactory.addBundle(
- LinkedBundleContext(elementFactory, cBundle.bundle),
+ BundleReader(
+ elementFactory: elementFactory,
+ astBytes: astBytes,
+ resolutionBytes: resolutionBytes,
+ ),
);
- // Set informative data.
- for (var libraryFile in cycle.libraries) {
- for (var unitFile in libraryFile.libraryFiles) {
- elementFactory.setInformativeData(
- libraryFile.uriStr,
- unitFile.uriStr,
- unitFile.unlinked2.informativeData,
- );
- }
- }
-
// We might have just linked dart:core, ensure the type provider.
_createElementFactoryTypeProvider();
}
@@ -772,7 +776,8 @@
var removedSet = removed.toSet();
loadedBundles.removeWhere((cycle) {
if (cycle.libraries.any(removedSet.contains)) {
- removedIds.add(cycle.id);
+ removedIds.add(cycle.astId);
+ removedIds.add(cycle.resolutionId);
return true;
}
return false;
@@ -788,12 +793,4 @@
elementFactory.createTypeProviders(dartCore, dartAsync);
}
}
-
- static CiderLinkedLibraryCycleBuilder serializeBundle(
- List<int> signature, link2.LinkResult linkResult) {
- return CiderLinkedLibraryCycleBuilder(
- signature: signature,
- bundle: linkResult.bundle,
- );
- }
}
diff --git a/pkg/analyzer/lib/src/error/analyzer_error_code.dart b/pkg/analyzer/lib/src/error/analyzer_error_code.dart
index f8cb42d..a3543a2 100644
--- a/pkg/analyzer/lib/src/error/analyzer_error_code.dart
+++ b/pkg/analyzer/lib/src/error/analyzer_error_code.dart
@@ -3,14 +3,24 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/error/error.dart';
+import 'package:meta/meta.dart';
/// A superclass for error codes that can have a url associated with them.
abstract class AnalyzerErrorCode extends ErrorCode {
/// Initialize a newly created error code.
- const AnalyzerErrorCode.temporary(String name, String message,
- {String correction, bool hasPublishedDocs, bool isUnresolvedIdentifier})
- : super.temporary(name, message,
- correction: correction,
- hasPublishedDocs: hasPublishedDocs ?? false,
- isUnresolvedIdentifier: isUnresolvedIdentifier ?? false);
+ const AnalyzerErrorCode({
+ String correction,
+ bool hasPublishedDocs = false,
+ bool isUnresolvedIdentifier = false,
+ @required String message,
+ @required String name,
+ @required String uniqueName,
+ }) : super(
+ correction: correction,
+ hasPublishedDocs: hasPublishedDocs,
+ isUnresolvedIdentifier: isUnresolvedIdentifier,
+ message: message,
+ name: name,
+ uniqueName: uniqueName,
+ );
}
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index f12b3a7..fc6bb66 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -70,13 +70,13 @@
// }
// ```
static const CompileTimeErrorCode ABSTRACT_FIELD_CONSTRUCTOR_INITIALIZER =
- CompileTimeErrorCodeWithUniqueName(
- 'ABSTRACT_FIELD_INITIALIZER',
- 'ABSTRACT_FIELD_CONSTRUCTOR_INITIALIZER',
- "Abstract fields can't have initializers.",
- correction:
- "Try removing the field initializer or the 'abstract' keyword "
- "from the field declaration.");
+ CompileTimeErrorCode(
+ 'ABSTRACT_FIELD_INITIALIZER',
+ "Abstract fields can't have initializers.",
+ correction: "Try removing the field initializer or the 'abstract' keyword "
+ "from the field declaration.",
+ uniqueName: 'ABSTRACT_FIELD_CONSTRUCTOR_INITIALIZER',
+ );
/**
* No parameters.
@@ -1444,12 +1444,13 @@
* 0: the name of the type variable
*/
static const CompileTimeErrorCode CONFLICTING_TYPE_VARIABLE_AND_CLASS =
- CompileTimeErrorCodeWithUniqueName(
- 'CONFLICTING_TYPE_VARIABLE_AND_CONTAINER',
- 'CONFLICTING_TYPE_VARIABLE_AND_CLASS',
- "'{0}' can't be used to name both a type variable and the class in "
- "which the type variable is defined.",
- correction: "Try renaming either the type variable or the class.");
+ CompileTimeErrorCode(
+ 'CONFLICTING_TYPE_VARIABLE_AND_CONTAINER',
+ "'{0}' can't be used to name both a type variable and the class in "
+ "which the type variable is defined.",
+ correction: "Try renaming either the type variable or the class.",
+ uniqueName: 'CONFLICTING_TYPE_VARIABLE_AND_CLASS',
+ );
/**
* It is a compile time error if an extension declares a type parameter with
@@ -1459,13 +1460,13 @@
* 0: the name of the type variable
*/
static const CompileTimeErrorCode CONFLICTING_TYPE_VARIABLE_AND_EXTENSION =
- CompileTimeErrorCodeWithUniqueName(
- 'CONFLICTING_TYPE_VARIABLE_AND_CONTAINER',
- 'CONFLICTING_TYPE_VARIABLE_AND_EXTENSION',
- "'{0}' can't be used to name both a type variable and the extension "
- "in which the type variable is defined.",
- correction:
- "Try renaming either the type variable or the extension.");
+ CompileTimeErrorCode(
+ 'CONFLICTING_TYPE_VARIABLE_AND_CONTAINER',
+ "'{0}' can't be used to name both a type variable and the extension "
+ "in which the type variable is defined.",
+ correction: "Try renaming either the type variable or the extension.",
+ uniqueName: 'CONFLICTING_TYPE_VARIABLE_AND_EXTENSION',
+ );
/**
* 7. Classes: It is a compile time error if a generic class declares a type
@@ -1476,25 +1477,26 @@
* 0: the name of the type variable
*/
static const CompileTimeErrorCode CONFLICTING_TYPE_VARIABLE_AND_MEMBER_CLASS =
- CompileTimeErrorCodeWithUniqueName(
- 'CONFLICTING_TYPE_VARIABLE_AND_MEMBER',
- 'CONFLICTING_TYPE_VARIABLE_AND_MEMBER_CLASS',
- "'{0}' can't be used to name both a type variable and a member in "
- "this class.",
- correction: "Try renaming either the type variable or the member.");
+ CompileTimeErrorCode(
+ 'CONFLICTING_TYPE_VARIABLE_AND_MEMBER',
+ "'{0}' can't be used to name both a type variable and a member in "
+ "this class.",
+ correction: "Try renaming either the type variable or the member.",
+ uniqueName: 'CONFLICTING_TYPE_VARIABLE_AND_MEMBER_CLASS',
+ );
/**
* It is a compile time error if a generic extension declares a member with
* the same basename as the name of any of the extension's type parameters.
*/
static const CompileTimeErrorCode
- CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION =
- CompileTimeErrorCodeWithUniqueName(
- 'CONFLICTING_TYPE_VARIABLE_AND_MEMBER',
- 'CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION',
- "'{0}' can't be used to name both a type variable and a member in "
- "this extension.",
- correction: "Try renaming either the type variable or the member.");
+ CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION = CompileTimeErrorCode(
+ 'CONFLICTING_TYPE_VARIABLE_AND_MEMBER',
+ "'{0}' can't be used to name both a type variable and a member in "
+ "this extension.",
+ correction: "Try renaming either the type variable or the member.",
+ uniqueName: 'CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION',
+ );
/**
* 16.12.2 Const: It is a compile-time error if evaluation of a constant
@@ -1640,14 +1642,15 @@
* 0: the name of the instance field.
*/
static const CompileTimeErrorCode CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD =
- CompileTimeErrorCodeWithUniqueName(
- 'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD',
- 'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD',
- "This constructor can't be declared 'const' because a mixin adds the "
- "instance field: {0}.",
- correction: "Try removing the 'const' keyword or removing the 'with' "
- "clause from the class declaration, or removing the field from "
- "the mixin class.");
+ CompileTimeErrorCode(
+ 'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD',
+ "This constructor can't be declared 'const' because a mixin adds the "
+ "instance field: {0}.",
+ correction: "Try removing the 'const' keyword or removing the 'with' "
+ "clause from the class declaration, or removing the field from "
+ "the mixin class.",
+ uniqueName: 'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD',
+ );
/**
* 7.6.3 Constant Constructors: The superinitializer that appears, explicitly
@@ -1664,14 +1667,15 @@
* 0: the names of the instance fields.
*/
static const CompileTimeErrorCode CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELDS =
- CompileTimeErrorCodeWithUniqueName(
- 'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD',
- 'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELDS',
- "This constructor can't be declared 'const' because the mixins add "
- "the instance fields: {0}.",
- correction: "Try removing the 'const' keyword or removing the 'with' "
- "clause from the class declaration, or removing the fields from "
- "the mixin classes.");
+ CompileTimeErrorCode(
+ 'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD',
+ "This constructor can't be declared 'const' because the mixins add "
+ "the instance fields: {0}.",
+ correction: "Try removing the 'const' keyword or removing the 'with' "
+ "clause from the class declaration, or removing the fields from "
+ "the mixin classes.",
+ uniqueName: 'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELDS',
+ );
/**
* 7.6.3 Constant Constructors: The superinitializer that appears, explicitly
@@ -1831,13 +1835,14 @@
* 1: the name of the type of the field
*/
static const CompileTimeErrorCode CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE =
- CompileTimeErrorCodeWithUniqueName(
- 'FIELD_INITIALIZER_NOT_ASSIGNABLE',
- 'CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE',
- "The initializer type '{0}' can't be assigned to the field type "
- "'{1}' in a const constructor.",
- correction: "Try using a subtype, or removing the 'const' keyword",
- hasPublishedDocs: true);
+ CompileTimeErrorCode(
+ 'FIELD_INITIALIZER_NOT_ASSIGNABLE',
+ "The initializer type '{0}' can't be assigned to the field type "
+ "'{1}' in a const constructor.",
+ correction: "Try using a subtype, or removing the 'const' keyword",
+ hasPublishedDocs: true,
+ uniqueName: 'CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE',
+ );
/**
* No parameters.
@@ -2162,12 +2167,14 @@
* Parameters:
* 0: the name of the non-type element
*/
- static const CompileTimeErrorCode CONST_WITH_NON_TYPE =
- CompileTimeErrorCodeWithUniqueName('CREATION_WITH_NON_TYPE',
- 'CONST_WITH_NON_TYPE', "The name '{0}' isn't a class.",
- correction: "Try correcting the name to match an existing class.",
- hasPublishedDocs: true,
- isUnresolvedIdentifier: true);
+ static const CompileTimeErrorCode CONST_WITH_NON_TYPE = CompileTimeErrorCode(
+ 'CREATION_WITH_NON_TYPE',
+ "The name '{0}' isn't a class.",
+ correction: "Try correcting the name to match an existing class.",
+ hasPublishedDocs: true,
+ isUnresolvedIdentifier: true,
+ uniqueName: 'CONST_WITH_NON_TYPE',
+ );
/**
* No parameters.
@@ -2475,24 +2482,26 @@
// }
// ```
static const CompileTimeErrorCode DUPLICATE_CONSTRUCTOR_DEFAULT =
- CompileTimeErrorCodeWithUniqueName(
- 'DUPLICATE_CONSTRUCTOR',
- 'DUPLICATE_CONSTRUCTOR_DEFAULT',
- "The default constructor is already defined.",
- correction: "Try giving one of the constructors a name.",
- hasPublishedDocs: true);
+ CompileTimeErrorCode(
+ 'DUPLICATE_CONSTRUCTOR',
+ "The default constructor is already defined.",
+ correction: "Try giving one of the constructors a name.",
+ hasPublishedDocs: true,
+ uniqueName: 'DUPLICATE_CONSTRUCTOR_DEFAULT',
+ );
/**
* Parameters:
* 0: the name of the duplicate entity
*/
static const CompileTimeErrorCode DUPLICATE_CONSTRUCTOR_NAME =
- CompileTimeErrorCodeWithUniqueName(
- 'DUPLICATE_CONSTRUCTOR',
- 'DUPLICATE_CONSTRUCTOR_NAME',
- "The constructor with name '{0}' is already defined.",
- correction: "Try renaming one of the constructors.",
- hasPublishedDocs: true);
+ CompileTimeErrorCode(
+ 'DUPLICATE_CONSTRUCTOR',
+ "The constructor with name '{0}' is already defined.",
+ correction: "Try renaming one of the constructors.",
+ hasPublishedDocs: true,
+ uniqueName: 'DUPLICATE_CONSTRUCTOR_NAME',
+ );
/**
* Parameters:
@@ -2526,6 +2535,14 @@
correction: "Try renaming one of the declarations.",
hasPublishedDocs: true);
+ static const CompileTimeErrorCode DUPLICATE_FIELD_FORMAL_PARAMETER =
+ CompileTimeErrorCode(
+ 'DUPLICATE_FIELD_FORMAL_PARAMETER',
+ "The field '{0}' can't be referenced in multiple initializing "
+ "parameters in the same constructor.",
+ correction: "Try removing one of the parameters, or "
+ "using different fields.");
+
/**
* Parameters:
* 0: the name of the parameter that was duplicated
@@ -3010,11 +3027,14 @@
static const CompileTimeErrorCode EXTENDS_DISALLOWED_CLASS =
// TODO(scheglov) We might want to restore specific code with FrontEnd.
// https://github.com/dart-lang/sdk/issues/31821
- CompileTimeErrorCodeWithUniqueName('SUBTYPE_OF_DISALLOWED_TYPE',
- 'EXTENDS_DISALLOWED_CLASS', "Classes can't extend '{0}'.",
- correction: "Try specifying a different superclass, or "
- "removing the extends clause.",
- hasPublishedDocs: true);
+ CompileTimeErrorCode(
+ 'SUBTYPE_OF_DISALLOWED_TYPE',
+ "Classes can't extend '{0}'.",
+ correction: "Try specifying a different superclass, or "
+ "removing the extends clause.",
+ hasPublishedDocs: true,
+ uniqueName: 'EXTENDS_DISALLOWED_CLASS',
+ );
/**
* Parameters:
@@ -3851,12 +3871,13 @@
// }
// ```
static const CompileTimeErrorCode FINAL_NOT_INITIALIZED_CONSTRUCTOR_1 =
- CompileTimeErrorCodeWithUniqueName(
- 'FINAL_NOT_INITIALIZED_CONSTRUCTOR',
- 'FINAL_NOT_INITIALIZED_CONSTRUCTOR_1',
- "All final variables must be initialized, but '{0}' isn't.",
- correction: "Try adding an initializer for the field.",
- hasPublishedDocs: true);
+ CompileTimeErrorCode(
+ 'FINAL_NOT_INITIALIZED_CONSTRUCTOR',
+ "All final variables must be initialized, but '{0}' isn't.",
+ correction: "Try adding an initializer for the field.",
+ hasPublishedDocs: true,
+ uniqueName: 'FINAL_NOT_INITIALIZED_CONSTRUCTOR_1',
+ );
/**
* Parameters:
@@ -3864,13 +3885,14 @@
* 1: the name of the uninitialized final variable
*/
static const CompileTimeErrorCode FINAL_NOT_INITIALIZED_CONSTRUCTOR_2 =
- CompileTimeErrorCodeWithUniqueName(
- 'FINAL_NOT_INITIALIZED_CONSTRUCTOR',
- 'FINAL_NOT_INITIALIZED_CONSTRUCTOR_2',
- "All final variables must be initialized, but '{0}' and '{1}' "
- "aren't.",
- correction: "Try adding initializers for the fields.",
- hasPublishedDocs: true);
+ CompileTimeErrorCode(
+ 'FINAL_NOT_INITIALIZED_CONSTRUCTOR',
+ "All final variables must be initialized, but '{0}' and '{1}' "
+ "aren't.",
+ correction: "Try adding initializers for the fields.",
+ hasPublishedDocs: true,
+ uniqueName: 'FINAL_NOT_INITIALIZED_CONSTRUCTOR_2',
+ );
/**
* Parameters:
@@ -3879,13 +3901,14 @@
* 2: the number of additional not initialized variables that aren't listed
*/
static const CompileTimeErrorCode FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS =
- CompileTimeErrorCodeWithUniqueName(
- 'FINAL_NOT_INITIALIZED_CONSTRUCTOR',
- 'FINAL_NOT_INITIALIZED_CONSTRUCTOR_3',
- "All final variables must be initialized, but '{0}', '{1}', and {2} "
- "others aren't.",
- correction: "Try adding initializers for the fields.",
- hasPublishedDocs: true);
+ CompileTimeErrorCode(
+ 'FINAL_NOT_INITIALIZED_CONSTRUCTOR',
+ "All final variables must be initialized, but '{0}', '{1}', and {2} "
+ "others aren't.",
+ correction: "Try adding initializers for the fields.",
+ hasPublishedDocs: true,
+ uniqueName: 'FINAL_NOT_INITIALIZED_CONSTRUCTOR_3',
+ );
/**
* 17.6.2 For-in. It the iterable expression does not implement Iterable with
@@ -4201,13 +4224,14 @@
* 0: The name of the disallowed type
*/
static const CompileTimeErrorCode IMPLEMENTS_DISALLOWED_CLASS =
- CompileTimeErrorCodeWithUniqueName(
- 'SUBTYPE_OF_DISALLOWED_TYPE',
- 'IMPLEMENTS_DISALLOWED_CLASS',
- "Classes and mixins can't implement '{0}'.",
- correction: "Try specifying a different interface, or "
- "remove the class from the list.",
- hasPublishedDocs: true);
+ CompileTimeErrorCode(
+ 'SUBTYPE_OF_DISALLOWED_TYPE',
+ "Classes and mixins can't implement '{0}'.",
+ correction: "Try specifying a different interface, or "
+ "remove the class from the list.",
+ hasPublishedDocs: true,
+ uniqueName: 'IMPLEMENTS_DISALLOWED_CLASS',
+ );
/**
* Parameters:
@@ -5043,10 +5067,13 @@
* No parameters.
*/
static const CompileTimeErrorCode INVALID_ANNOTATION_GETTER =
- CompileTimeErrorCodeWithUniqueName('INVALID_ANNOTATION',
- 'INVALID_ANNOTATION_GETTER', "Getters can't be used as annotations.",
- correction: "Try using a top-level variable or a field.",
- hasPublishedDocs: true);
+ CompileTimeErrorCode(
+ 'INVALID_ANNOTATION',
+ "Getters can't be used as annotations.",
+ correction: "Try using a top-level variable or a field.",
+ hasPublishedDocs: true,
+ uniqueName: 'INVALID_ANNOTATION_GETTER',
+ );
/**
* Parameters:
@@ -5549,39 +5576,39 @@
// List<T> newList<T>() => <T>[];
// ```
static const CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_LIST =
- CompileTimeErrorCodeWithUniqueName(
- 'INVALID_TYPE_ARGUMENT_IN_CONST_LITERAL',
- 'INVALID_TYPE_ARGUMENT_IN_CONST_LIST',
- "Constant list literals can't include a type parameter as a type "
- "argument, such as '{0}'.",
- correction:
- "Try replacing the type parameter with a different type.");
+ CompileTimeErrorCode(
+ 'INVALID_TYPE_ARGUMENT_IN_CONST_LITERAL',
+ "Constant list literals can't include a type parameter as a type "
+ "argument, such as '{0}'.",
+ correction: "Try replacing the type parameter with a different type.",
+ uniqueName: 'INVALID_TYPE_ARGUMENT_IN_CONST_LIST',
+ );
/**
* Parameters:
* 0: the name of the type parameter
*/
static const CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_MAP =
- CompileTimeErrorCodeWithUniqueName(
- 'INVALID_TYPE_ARGUMENT_IN_CONST_LITERAL',
- 'INVALID_TYPE_ARGUMENT_IN_CONST_MAP',
- "Constant map literals can't include a type parameter as a type "
- "argument, such as '{0}'.",
- correction:
- "Try replacing the type parameter with a different type.");
+ CompileTimeErrorCode(
+ 'INVALID_TYPE_ARGUMENT_IN_CONST_LITERAL',
+ "Constant map literals can't include a type parameter as a type "
+ "argument, such as '{0}'.",
+ correction: "Try replacing the type parameter with a different type.",
+ uniqueName: 'INVALID_TYPE_ARGUMENT_IN_CONST_MAP',
+ );
/**
* Parameters:
* 0: the name of the type parameter
*/
static const CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_SET =
- CompileTimeErrorCodeWithUniqueName(
- 'INVALID_TYPE_ARGUMENT_IN_CONST_LITERAL',
- 'INVALID_TYPE_ARGUMENT_IN_CONST_SET',
- "Constant set literals can't include a type parameter as a type "
- "argument, such as '{0}'.",
- correction:
- "Try replacing the type parameter with a different type.");
+ CompileTimeErrorCode(
+ 'INVALID_TYPE_ARGUMENT_IN_CONST_LITERAL',
+ "Constant set literals can't include a type parameter as a type "
+ "argument, such as '{0}'.",
+ correction: "Try replacing the type parameter with a different type.",
+ uniqueName: 'INVALID_TYPE_ARGUMENT_IN_CONST_SET',
+ );
/**
* Parameters:
@@ -6476,11 +6503,14 @@
* 0: The name of the disallowed type
*/
static const CompileTimeErrorCode MIXIN_OF_DISALLOWED_CLASS =
- CompileTimeErrorCodeWithUniqueName('SUBTYPE_OF_DISALLOWED_TYPE',
- 'MIXIN_OF_DISALLOWED_CLASS', "Classes can't mixin '{0}'.",
- correction: "Try specifying a different class or mixin, or "
- "remove the class or mixin from the list.",
- hasPublishedDocs: true);
+ CompileTimeErrorCode(
+ 'SUBTYPE_OF_DISALLOWED_TYPE',
+ "Classes can't mixin '{0}'.",
+ correction: "Try specifying a different class or mixin, or "
+ "remove the class or mixin from the list.",
+ hasPublishedDocs: true,
+ uniqueName: 'MIXIN_OF_DISALLOWED_CLASS',
+ );
/**
* No parameters.
@@ -6529,14 +6559,14 @@
* 0: The name of the disallowed type
*/
static const CompileTimeErrorCode
- MIXIN_SUPER_CLASS_CONSTRAINT_DISALLOWED_CLASS =
- CompileTimeErrorCodeWithUniqueName(
- 'SUBTYPE_OF_DISALLOWED_TYPE',
- 'MIXIN_SUPER_CLASS_CONSTRAINT_DISALLOWED_CLASS',
- "''{0}' can't be used as a superclass constraint.",
- correction: "Try specifying a different super-class constraint, or "
- "remove the 'on' clause.",
- hasPublishedDocs: true);
+ MIXIN_SUPER_CLASS_CONSTRAINT_DISALLOWED_CLASS = CompileTimeErrorCode(
+ 'SUBTYPE_OF_DISALLOWED_TYPE',
+ "''{0}' can't be used as a superclass constraint.",
+ correction: "Try specifying a different super-class constraint, or "
+ "remove the 'on' clause.",
+ hasPublishedDocs: true,
+ uniqueName: 'MIXIN_SUPER_CLASS_CONSTRAINT_DISALLOWED_CLASS',
+ );
/**
* No parameters.
@@ -6653,12 +6683,14 @@
// f();
// }
// ```
- static const CompileTimeErrorCode NEW_WITH_NON_TYPE =
- CompileTimeErrorCodeWithUniqueName('CREATION_WITH_NON_TYPE',
- 'NEW_WITH_NON_TYPE', "The name '{0}' isn't a class.",
- correction: "Try correcting the name to match an existing class.",
- hasPublishedDocs: true,
- isUnresolvedIdentifier: true);
+ static const CompileTimeErrorCode NEW_WITH_NON_TYPE = CompileTimeErrorCode(
+ 'CREATION_WITH_NON_TYPE',
+ "The name '{0}' isn't a class.",
+ correction: "Try correcting the name to match an existing class.",
+ hasPublishedDocs: true,
+ isUnresolvedIdentifier: true,
+ uniqueName: 'NEW_WITH_NON_TYPE',
+ );
/**
* 12.11.1 New: If <i>T</i> is a class or parameterized type accessible in the
@@ -6844,12 +6876,13 @@
* constructor
*/
static const CompileTimeErrorCode NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT =
- CompileTimeErrorCodeWithUniqueName(
- 'NO_DEFAULT_SUPER_CONSTRUCTOR',
- 'NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT',
- "The superclass '{0}' doesn't have a zero argument constructor.",
- correction: "Try declaring a zero argument constructor in '{0}', or "
- "explicitly invoking a different constructor in '{0}'.");
+ CompileTimeErrorCode(
+ 'NO_DEFAULT_SUPER_CONSTRUCTOR',
+ "The superclass '{0}' doesn't have a zero argument constructor.",
+ correction: "Try declaring a zero argument constructor in '{0}', or "
+ "explicitly invoking a different constructor in '{0}'.",
+ uniqueName: 'NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT',
+ );
/**
* User friendly specialized error for [NON_GENERATIVE_CONSTRUCTOR]. This
@@ -6873,13 +6906,14 @@
* 1: the name of the subclass that does not contain any explicit constructors
*/
static const CompileTimeErrorCode NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT =
- CompileTimeErrorCodeWithUniqueName(
- 'NO_DEFAULT_SUPER_CONSTRUCTOR',
- 'NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT',
- "The superclass '{0}' doesn't have a zero argument constructor.",
- correction: "Try declaring a zero argument constructor in '{0}', or "
- "declaring a constructor in {1} that explicitly invokes a "
- "constructor in '{0}'.");
+ CompileTimeErrorCode(
+ 'NO_DEFAULT_SUPER_CONSTRUCTOR',
+ "The superclass '{0}' doesn't have a zero argument constructor.",
+ correction: "Try declaring a zero argument constructor in '{0}', or "
+ "declaring a constructor in {1} that explicitly invokes a "
+ "constructor in '{0}'.",
+ uniqueName: 'NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT',
+ );
/**
* Parameters:
@@ -6891,14 +6925,15 @@
*/
static const CompileTimeErrorCode
NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS =
- CompileTimeErrorCodeWithUniqueName(
- 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
- 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS',
- "Missing concrete implementations of '{0}', '{1}', '{2}', '{3}', and "
- "{4} more.",
- correction: "Try implementing the missing methods, or make the class "
- "abstract.",
- hasPublishedDocs: true);
+ CompileTimeErrorCode(
+ 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
+ "Missing concrete implementations of '{0}', '{1}', '{2}', '{3}', and "
+ "{4} more.",
+ correction: "Try implementing the missing methods, or make the class "
+ "abstract.",
+ hasPublishedDocs: true,
+ uniqueName: 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS',
+ );
/**
* Parameters:
@@ -6908,14 +6943,14 @@
* 3: the name of the fourth member
*/
static const CompileTimeErrorCode
- NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR =
- CompileTimeErrorCodeWithUniqueName(
- 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
- 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR',
- "Missing concrete implementations of '{0}', '{1}', '{2}', and '{3}'.",
- correction: "Try implementing the missing methods, or make the class "
- "abstract.",
- hasPublishedDocs: true);
+ NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR = CompileTimeErrorCode(
+ 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
+ "Missing concrete implementations of '{0}', '{1}', '{2}', and '{3}'.",
+ correction: "Try implementing the missing methods, or make the class "
+ "abstract.",
+ hasPublishedDocs: true,
+ uniqueName: 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR',
+ );
/**
* Parameters:
@@ -6981,14 +7016,14 @@
// abstract class B extends A {}
// ```
static const CompileTimeErrorCode
- NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE =
- CompileTimeErrorCodeWithUniqueName(
- 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
- 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE',
- "Missing concrete implementation of '{0}'.",
- correction: "Try implementing the missing method, or make the class "
- "abstract.",
- hasPublishedDocs: true);
+ NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE = CompileTimeErrorCode(
+ 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
+ "Missing concrete implementation of '{0}'.",
+ correction: "Try implementing the missing method, or make the class "
+ "abstract.",
+ hasPublishedDocs: true,
+ uniqueName: 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE',
+ );
/**
* Parameters:
@@ -6997,14 +7032,14 @@
* 2: the name of the third member
*/
static const CompileTimeErrorCode
- NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE =
- CompileTimeErrorCodeWithUniqueName(
- 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
- 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE',
- "Missing concrete implementations of '{0}', '{1}', and '{2}'.",
- correction: "Try implementing the missing methods, or make the class "
- "abstract.",
- hasPublishedDocs: true);
+ NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE = CompileTimeErrorCode(
+ 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
+ "Missing concrete implementations of '{0}', '{1}', and '{2}'.",
+ correction: "Try implementing the missing methods, or make the class "
+ "abstract.",
+ hasPublishedDocs: true,
+ uniqueName: 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE',
+ );
/**
* Parameters:
@@ -7012,14 +7047,14 @@
* 1: the name of the second member
*/
static const CompileTimeErrorCode
- NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO =
- CompileTimeErrorCodeWithUniqueName(
- 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
- 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO',
- "Missing concrete implementations of '{0}' and '{1}'.",
- correction: "Try implementing the missing methods, or make the class "
- "abstract.",
- hasPublishedDocs: true);
+ NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO = CompileTimeErrorCode(
+ 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER',
+ "Missing concrete implementations of '{0}' and '{1}'.",
+ correction: "Try implementing the missing methods, or make the class "
+ "abstract.",
+ hasPublishedDocs: true,
+ uniqueName: 'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO',
+ );
/**
* No parameters.
@@ -8013,14 +8048,15 @@
*/
static const CompileTimeErrorCode
NOT_INITIALIZED_NON_NULLABLE_INSTANCE_FIELD_CONSTRUCTOR =
- CompileTimeErrorCodeWithUniqueName(
- 'NOT_INITIALIZED_NON_NULLABLE_INSTANCE_FIELD',
- 'NOT_INITIALIZED_NON_NULLABLE_INSTANCE_FIELD_CONSTRUCTOR',
- "Non-nullable instance field '{0}' must be initialized.",
- correction: "Try adding an initializer expression, "
- "or add a field initializer in this constructor, "
- "or mark it 'late'.",
- hasPublishedDocs: true);
+ CompileTimeErrorCode(
+ 'NOT_INITIALIZED_NON_NULLABLE_INSTANCE_FIELD',
+ "Non-nullable instance field '{0}' must be initialized.",
+ correction: "Try adding an initializer expression, "
+ "or add a field initializer in this constructor, "
+ "or mark it 'late'.",
+ hasPublishedDocs: true,
+ uniqueName: 'NOT_INITIALIZED_NON_NULLABLE_INSTANCE_FIELD_CONSTRUCTOR',
+ );
/**
* Parameters:
@@ -9141,12 +9177,13 @@
* 2: the name of the constructor
*/
static const CompileTimeErrorCode RETURN_OF_INVALID_TYPE_FROM_CONSTRUCTOR =
- CompileTimeErrorCodeWithUniqueName(
- 'RETURN_OF_INVALID_TYPE',
- 'RETURN_OF_INVALID_TYPE_FROM_CONSTRUCTOR',
- "A value of type '{0}' can't be returned from constructor '{2}' "
- "because it has a return type of '{1}'.",
- hasPublishedDocs: true);
+ CompileTimeErrorCode(
+ 'RETURN_OF_INVALID_TYPE',
+ "A value of type '{0}' can't be returned from constructor '{2}' "
+ "because it has a return type of '{1}'.",
+ hasPublishedDocs: true,
+ uniqueName: 'RETURN_OF_INVALID_TYPE_FROM_CONSTRUCTOR',
+ );
/**
* Parameters:
@@ -9183,12 +9220,13 @@
// int f() => 3;
// ```
static const CompileTimeErrorCode RETURN_OF_INVALID_TYPE_FROM_FUNCTION =
- CompileTimeErrorCodeWithUniqueName(
- 'RETURN_OF_INVALID_TYPE',
- 'RETURN_OF_INVALID_TYPE_FROM_FUNCTION',
- "A value of type '{0}' can't be returned from function '{2}' because "
- "it has a return type of '{1}'.",
- hasPublishedDocs: true);
+ CompileTimeErrorCode(
+ 'RETURN_OF_INVALID_TYPE',
+ "A value of type '{0}' can't be returned from function '{2}' because "
+ "it has a return type of '{1}'.",
+ hasPublishedDocs: true,
+ uniqueName: 'RETURN_OF_INVALID_TYPE_FROM_FUNCTION',
+ );
/**
* Parameters:
@@ -9197,12 +9235,13 @@
* 2: the name of the method
*/
static const CompileTimeErrorCode RETURN_OF_INVALID_TYPE_FROM_METHOD =
- CompileTimeErrorCodeWithUniqueName(
- 'RETURN_OF_INVALID_TYPE',
- 'RETURN_OF_INVALID_TYPE_FROM_METHOD',
- "A value of type '{0}' can't be returned from method '{2}' because "
- "it has a return type of '{1}'.",
- hasPublishedDocs: true);
+ CompileTimeErrorCode(
+ 'RETURN_OF_INVALID_TYPE',
+ "A value of type '{0}' can't be returned from method '{2}' because "
+ "it has a return type of '{1}'.",
+ hasPublishedDocs: true,
+ uniqueName: 'RETURN_OF_INVALID_TYPE_FROM_METHOD',
+ );
/**
* No parameters.
@@ -9911,13 +9950,13 @@
* 0: the name of the superclass that does not define the invoked constructor
*/
static const CompileTimeErrorCode
- UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT =
- CompileTimeErrorCodeWithUniqueName(
- 'UNDEFINED_CONSTRUCTOR_IN_INITIALIZER',
- 'UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT',
- "The class '{0}' doesn't have an unnamed constructor.",
- correction: "Try defining an unnamed constructor in '{0}', or "
- "invoking a different constructor.");
+ UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT = CompileTimeErrorCode(
+ 'UNDEFINED_CONSTRUCTOR_IN_INITIALIZER',
+ "The class '{0}' doesn't have an unnamed constructor.",
+ correction: "Try defining an unnamed constructor in '{0}', or "
+ "invoking a different constructor.",
+ uniqueName: 'UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT',
+ );
/**
* Parameters:
@@ -10684,14 +10723,14 @@
* 1: the name of the enclosing type where the getter is being looked for
*/
static const CompileTimeErrorCode UNDEFINED_SUPER_GETTER =
- CompileTimeErrorCodeWithUniqueName(
- 'UNDEFINED_SUPER_MEMBER',
- 'UNDEFINED_SUPER_GETTER',
- "The getter '{0}' isn't defined in a superclass of '{1}'.",
- correction:
- "Try correcting the name to the name of an existing getter, or "
- "defining a getter or field named '{0}' in a superclass.",
- hasPublishedDocs: true);
+ CompileTimeErrorCode(
+ 'UNDEFINED_SUPER_MEMBER',
+ "The getter '{0}' isn't defined in a superclass of '{1}'.",
+ correction: "Try correcting the name to the name of an existing getter, or "
+ "defining a getter or field named '{0}' in a superclass.",
+ hasPublishedDocs: true,
+ uniqueName: 'UNDEFINED_SUPER_GETTER',
+ );
/**
* Parameters:
@@ -10739,14 +10778,14 @@
// If the member isn’t defined, then either add the member to one of the
// superclasses or remove the invocation.
static const CompileTimeErrorCode UNDEFINED_SUPER_METHOD =
- CompileTimeErrorCodeWithUniqueName(
- 'UNDEFINED_SUPER_MEMBER',
- 'UNDEFINED_SUPER_METHOD',
- "The method '{0}' isn't defined in a superclass of '{1}'.",
- correction:
- "Try correcting the name to the name of an existing method, or "
- "defining a method named '{0}' in a superclass.",
- hasPublishedDocs: true);
+ CompileTimeErrorCode(
+ 'UNDEFINED_SUPER_MEMBER',
+ "The method '{0}' isn't defined in a superclass of '{1}'.",
+ correction: "Try correcting the name to the name of an existing method, or "
+ "defining a method named '{0}' in a superclass.",
+ hasPublishedDocs: true,
+ uniqueName: 'UNDEFINED_SUPER_METHOD',
+ );
/**
* Parameters:
@@ -10754,12 +10793,13 @@
* 1: the name of the enclosing type where the operator is being looked for
*/
static const CompileTimeErrorCode UNDEFINED_SUPER_OPERATOR =
- CompileTimeErrorCodeWithUniqueName(
- 'UNDEFINED_SUPER_MEMBER',
- 'UNDEFINED_SUPER_OPERATOR',
- "The operator '{0}' isn't defined in a superclass of '{1}'.",
- correction: "Try defining the operator '{0}' in a superclass.",
- hasPublishedDocs: true);
+ CompileTimeErrorCode(
+ 'UNDEFINED_SUPER_MEMBER',
+ "The operator '{0}' isn't defined in a superclass of '{1}'.",
+ correction: "Try defining the operator '{0}' in a superclass.",
+ hasPublishedDocs: true,
+ uniqueName: 'UNDEFINED_SUPER_OPERATOR',
+ );
/**
* Parameters:
@@ -10767,14 +10807,14 @@
* 1: the name of the enclosing type where the setter is being looked for
*/
static const CompileTimeErrorCode UNDEFINED_SUPER_SETTER =
- CompileTimeErrorCodeWithUniqueName(
- 'UNDEFINED_SUPER_MEMBER',
- 'UNDEFINED_SUPER_SETTER',
- "The setter '{0}' isn't defined in a superclass of '{1}'.",
- correction:
- "Try correcting the name to the name of an existing setter, or "
- "defining a setter or field named '{0}' in a superclass.",
- hasPublishedDocs: true);
+ CompileTimeErrorCode(
+ 'UNDEFINED_SUPER_MEMBER',
+ "The setter '{0}' isn't defined in a superclass of '{1}'.",
+ correction: "Try correcting the name to the name of an existing setter, or "
+ "defining a setter or field named '{0}' in a superclass.",
+ hasPublishedDocs: true,
+ uniqueName: 'UNDEFINED_SUPER_SETTER',
+ );
/**
* 12.15.1 Ordinary Invocation: It is a static type warning if <i>T</i> does
@@ -11391,14 +11431,21 @@
* template. The correction associated with the error will be created from the
* given [correction] template.
*/
- const CompileTimeErrorCode(String name, String message,
- {String correction,
- bool hasPublishedDocs,
- bool isUnresolvedIdentifier = false})
- : super.temporary(name, message,
- correction: correction,
- hasPublishedDocs: hasPublishedDocs,
- isUnresolvedIdentifier: isUnresolvedIdentifier);
+ const CompileTimeErrorCode(
+ String name,
+ String message, {
+ String correction,
+ bool hasPublishedDocs = false,
+ bool isUnresolvedIdentifier = false,
+ String uniqueName,
+ }) : super(
+ correction: correction,
+ hasPublishedDocs: hasPublishedDocs,
+ isUnresolvedIdentifier: isUnresolvedIdentifier,
+ message: message,
+ name: name,
+ uniqueName: uniqueName ?? 'CompileTimeErrorCode.$name',
+ );
@override
ErrorSeverity get errorSeverity => ErrorType.COMPILE_TIME_ERROR.severity;
@@ -11407,21 +11454,6 @@
ErrorType get type => ErrorType.COMPILE_TIME_ERROR;
}
-class CompileTimeErrorCodeWithUniqueName extends CompileTimeErrorCode {
- @override
- final String uniqueName;
-
- const CompileTimeErrorCodeWithUniqueName(
- String name, this.uniqueName, String message,
- {String correction,
- bool hasPublishedDocs,
- bool isUnresolvedIdentifier = false})
- : super(name, message,
- correction: correction,
- hasPublishedDocs: hasPublishedDocs,
- isUnresolvedIdentifier: isUnresolvedIdentifier);
-}
-
/**
* This class has experimental Language-specific codes.
*
@@ -11495,10 +11527,14 @@
* created from the optional [correction] template.
*/
const LanguageCode(String name, String message,
- {String correction, bool hasPublishedDocs})
- : super.temporary(name, message,
- correction: correction,
- hasPublishedDocs: hasPublishedDocs ?? false);
+ {String correction, bool hasPublishedDocs = false})
+ : super(
+ correction: correction,
+ hasPublishedDocs: hasPublishedDocs,
+ message: message,
+ name: name,
+ uniqueName: 'LanguageCode.$name',
+ );
@override
ErrorSeverity get errorSeverity => type.severity;
@@ -11666,14 +11702,14 @@
* 1: The non-null-aware operator that can replace the invalid operator
*/
static const StaticWarningCode
- INVALID_NULL_AWARE_OPERATOR_AFTER_SHORT_CIRCUIT =
- StaticWarningCodeWithUniqueName(
- 'INVALID_NULL_AWARE_OPERATOR',
- 'INVALID_NULL_AWARE_OPERATOR_AFTER_SHORT_CIRCUIT',
- "The receiver can't be null because of short-circuiting, so the "
- "null-aware operator '{0}' can't be used.",
- correction: "Try replacing the operator '{0}' with '{1}'.",
- hasPublishedDocs: true);
+ INVALID_NULL_AWARE_OPERATOR_AFTER_SHORT_CIRCUIT = StaticWarningCode(
+ 'INVALID_NULL_AWARE_OPERATOR',
+ "The receiver can't be null because of short-circuiting, so the "
+ "null-aware operator '{0}' can't be used.",
+ correction: "Try replacing the operator '{0}' with '{1}'.",
+ hasPublishedDocs: true,
+ uniqueName: 'INVALID_NULL_AWARE_OPERATOR_AFTER_SHORT_CIRCUIT',
+ );
/**
* 7.1 Instance Methods: It is a static warning if an instance method
@@ -11812,14 +11848,21 @@
* template. The correction associated with the error will be created from the
* given [correction] template.
*/
- const StaticWarningCode(String name, String message,
- {String correction,
- bool hasPublishedDocs,
- bool isUnresolvedIdentifier = false})
- : super.temporary(name, message,
- correction: correction,
- hasPublishedDocs: hasPublishedDocs,
- isUnresolvedIdentifier: isUnresolvedIdentifier);
+ const StaticWarningCode(
+ String name,
+ String message, {
+ String correction,
+ bool hasPublishedDocs = false,
+ bool isUnresolvedIdentifier = false,
+ String uniqueName,
+ }) : super(
+ correction: correction,
+ hasPublishedDocs: hasPublishedDocs,
+ isUnresolvedIdentifier: isUnresolvedIdentifier,
+ message: message,
+ name: name,
+ uniqueName: uniqueName ?? 'StaticWarningCode.$name',
+ );
@override
ErrorSeverity get errorSeverity => ErrorSeverity.WARNING;
@@ -11828,21 +11871,6 @@
ErrorType get type => ErrorType.STATIC_WARNING;
}
-class StaticWarningCodeWithUniqueName extends StaticWarningCode {
- @override
- final String uniqueName;
-
- const StaticWarningCodeWithUniqueName(
- String name, this.uniqueName, String message,
- {String correction,
- bool hasPublishedDocs,
- bool isUnresolvedIdentifier = false})
- : super(name, message,
- correction: correction,
- hasPublishedDocs: hasPublishedDocs,
- isUnresolvedIdentifier: isUnresolvedIdentifier);
-}
-
/**
* This class has Strong Mode specific error codes.
*
@@ -11903,11 +11931,15 @@
* created from the optional [correction] template.
*/
const StrongModeCode(ErrorType type, String name, String message,
- {String correction, bool hasPublishedDocs})
+ {String correction, bool hasPublishedDocs = false})
: type = type,
- super.temporary(name, message,
- correction: correction,
- hasPublishedDocs: hasPublishedDocs ?? false);
+ super(
+ correction: correction,
+ hasPublishedDocs: hasPublishedDocs,
+ message: message,
+ name: name,
+ uniqueName: 'StrongModeCode.$name',
+ );
@override
ErrorSeverity get errorSeverity => type.severity;
diff --git a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
index e90e5de..0b5e1f1 100644
--- a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
+++ b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
@@ -367,7 +367,10 @@
}
ErrorCode getError(Element previous, Element current) {
- if (previous is PrefixElement) {
+ if (previous is FieldFormalParameterElement &&
+ current is FieldFormalParameterElement) {
+ return CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER;
+ } else if (previous is PrefixElement) {
return CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER;
}
return CompileTimeErrorCode.DUPLICATE_DEFINITION;
@@ -383,7 +386,9 @@
if (_isGetterSetterPair(element, previous)) {
// OK
} else if (element is FieldFormalParameterElement &&
- previous is FieldFormalParameterElement) {
+ previous is FieldFormalParameterElement &&
+ element.field != null &&
+ element.field.isFinal) {
// Reported as CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES.
} else {
_errorReporter.reportErrorForNode(
diff --git a/pkg/analyzer/lib/src/error/inheritance_override.dart b/pkg/analyzer/lib/src/error/inheritance_override.dart
index 159b36d..d3d43e6 100644
--- a/pkg/analyzer/lib/src/error/inheritance_override.dart
+++ b/pkg/analyzer/lib/src/error/inheritance_override.dart
@@ -17,7 +17,7 @@
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/error/correct_override.dart';
import 'package:analyzer/src/error/getter_setter_types_verifier.dart';
-import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/task/inference_error.dart';
import 'package:meta/meta.dart';
class InheritanceOverrideVerifier {
diff --git a/pkg/analyzer/lib/src/manifest/manifest_warning_code.dart b/pkg/analyzer/lib/src/manifest/manifest_warning_code.dart
index f4d5b8f..1d2955b 100644
--- a/pkg/analyzer/lib/src/manifest/manifest_warning_code.dart
+++ b/pkg/analyzer/lib/src/manifest/manifest_warning_code.dart
@@ -81,7 +81,12 @@
/// Initialize a newly created warning code to have the given [name],
/// [message] and [correction].
const ManifestWarningCode(String name, String message, {String correction})
- : super.temporary(name, message, correction: correction);
+ : super(
+ correction: correction,
+ message: message,
+ name: name,
+ uniqueName: 'ManifestWarningCode.$name',
+ );
@override
ErrorSeverity get errorSeverity => ErrorSeverity.WARNING;
diff --git a/pkg/analyzer/lib/src/pubspec/pubspec_validator.dart b/pkg/analyzer/lib/src/pubspec/pubspec_validator.dart
index fd22ea0..b47fb44 100644
--- a/pkg/analyzer/lib/src/pubspec/pubspec_validator.dart
+++ b/pkg/analyzer/lib/src/pubspec/pubspec_validator.dart
@@ -249,6 +249,12 @@
if (pathEntry != null) {
YamlNode pathKey() => getKey(dependency, PATH_FIELD);
YamlNode pathValue() => getValue(dependency, PATH_FIELD);
+
+ if (pathEntry.contains(r'\')) {
+ _reportErrorForNode(reporter, pathValue(),
+ PubspecWarningCode.PATH_NOT_POSIX, [pathEntry]);
+ return;
+ }
var context = provider.pathContext;
var normalizedPath = context.joinAll(path.posix.split(pathEntry));
var packageRoot = context.dirname(source.fullName);
diff --git a/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.dart b/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.dart
index a93cca0..9fb2b1c 100644
--- a/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.dart
+++ b/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.dart
@@ -83,6 +83,14 @@
correction:
"Try creating the referenced path or using a path that exists.");
+ /// A code indicating that a path value is not is not posix-style.
+ ///
+ /// Parameters:
+ /// 0: the path as given in the file.
+ static const PubspecWarningCode PATH_NOT_POSIX = PubspecWarningCode(
+ 'PATH_NOT_POSIX', "The path {0} is not posix.",
+ correction: "Try converting the value to a posix-style path.");
+
/// A code indicating that a specified path dependency points to a directory
/// that does not contain a pubspec.
///
@@ -109,7 +117,12 @@
/// Initialize a newly created warning code to have the given [name],
/// [message] and [correction].
const PubspecWarningCode(String name, String message, {String correction})
- : super.temporary(name, message, correction: correction);
+ : super(
+ correction: correction,
+ message: message,
+ name: name,
+ uniqueName: 'PubspecWarningCode.$name',
+ );
@override
ErrorSeverity get errorSeverity => ErrorSeverity.WARNING;
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index cddf91d..aa37cf6 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -35,22 +35,6 @@
}
}
-class _EntityRefNullabilitySuffixReader
- extends fb.Reader<idl.EntityRefNullabilitySuffix> {
- const _EntityRefNullabilitySuffixReader() : super();
-
- @override
- int get size => 1;
-
- @override
- idl.EntityRefNullabilitySuffix read(fb.BufferContext bc, int offset) {
- int index = const fb.Uint8Reader().read(bc, offset);
- return index < idl.EntityRefNullabilitySuffix.values.length
- ? idl.EntityRefNullabilitySuffix.values[index]
- : idl.EntityRefNullabilitySuffix.starOrIrrelevant;
- }
-}
-
class _IndexRelationKindReader extends fb.Reader<idl.IndexRelationKind> {
const _IndexRelationKindReader() : super();
@@ -82,99 +66,6 @@
}
}
-class _LinkedNodeCommentTypeReader
- extends fb.Reader<idl.LinkedNodeCommentType> {
- const _LinkedNodeCommentTypeReader() : super();
-
- @override
- int get size => 1;
-
- @override
- idl.LinkedNodeCommentType read(fb.BufferContext bc, int offset) {
- int index = const fb.Uint8Reader().read(bc, offset);
- return index < idl.LinkedNodeCommentType.values.length
- ? idl.LinkedNodeCommentType.values[index]
- : idl.LinkedNodeCommentType.block;
- }
-}
-
-class _LinkedNodeFormalParameterKindReader
- extends fb.Reader<idl.LinkedNodeFormalParameterKind> {
- const _LinkedNodeFormalParameterKindReader() : super();
-
- @override
- int get size => 1;
-
- @override
- idl.LinkedNodeFormalParameterKind read(fb.BufferContext bc, int offset) {
- int index = const fb.Uint8Reader().read(bc, offset);
- return index < idl.LinkedNodeFormalParameterKind.values.length
- ? idl.LinkedNodeFormalParameterKind.values[index]
- : idl.LinkedNodeFormalParameterKind.requiredPositional;
- }
-}
-
-class _LinkedNodeKindReader extends fb.Reader<idl.LinkedNodeKind> {
- const _LinkedNodeKindReader() : super();
-
- @override
- int get size => 1;
-
- @override
- idl.LinkedNodeKind read(fb.BufferContext bc, int offset) {
- int index = const fb.Uint8Reader().read(bc, offset);
- return index < idl.LinkedNodeKind.values.length
- ? idl.LinkedNodeKind.values[index]
- : idl.LinkedNodeKind.adjacentStrings;
- }
-}
-
-class _LinkedNodeTypeKindReader extends fb.Reader<idl.LinkedNodeTypeKind> {
- const _LinkedNodeTypeKindReader() : super();
-
- @override
- int get size => 1;
-
- @override
- idl.LinkedNodeTypeKind read(fb.BufferContext bc, int offset) {
- int index = const fb.Uint8Reader().read(bc, offset);
- return index < idl.LinkedNodeTypeKind.values.length
- ? idl.LinkedNodeTypeKind.values[index]
- : idl.LinkedNodeTypeKind.dynamic_;
- }
-}
-
-class _TopLevelInferenceErrorKindReader
- extends fb.Reader<idl.TopLevelInferenceErrorKind> {
- const _TopLevelInferenceErrorKindReader() : super();
-
- @override
- int get size => 1;
-
- @override
- idl.TopLevelInferenceErrorKind read(fb.BufferContext bc, int offset) {
- int index = const fb.Uint8Reader().read(bc, offset);
- return index < idl.TopLevelInferenceErrorKind.values.length
- ? idl.TopLevelInferenceErrorKind.values[index]
- : idl.TopLevelInferenceErrorKind.assignment;
- }
-}
-
-class _UnlinkedTokenTypeReader extends fb.Reader<idl.UnlinkedTokenType> {
- const _UnlinkedTokenTypeReader() : super();
-
- @override
- int get size => 1;
-
- @override
- idl.UnlinkedTokenType read(fb.BufferContext bc, int offset) {
- int index = const fb.Uint8Reader().read(bc, offset);
- return index < idl.UnlinkedTokenType.values.length
- ? idl.UnlinkedTokenType.values[index]
- : idl.UnlinkedTokenType.NOTHING;
- }
-}
-
class AnalysisDriverExceptionContextBuilder extends Object
with _AnalysisDriverExceptionContextMixin
implements idl.AnalysisDriverExceptionContext {
@@ -3511,143 +3402,6 @@
String toString() => convert.json.encode(toJson());
}
-class CiderLinkedLibraryCycleBuilder extends Object
- with _CiderLinkedLibraryCycleMixin
- implements idl.CiderLinkedLibraryCycle {
- LinkedNodeBundleBuilder _bundle;
- List<int> _signature;
-
- @override
- LinkedNodeBundleBuilder get bundle => _bundle;
-
- set bundle(LinkedNodeBundleBuilder value) {
- this._bundle = value;
- }
-
- @override
- List<int> get signature => _signature ??= <int>[];
-
- /// The hash signature for this linked cycle. It depends of API signatures
- /// of all files in the cycle, and on the signatures of the transitive
- /// closure of the cycle dependencies.
- set signature(List<int> value) {
- assert(value == null || value.every((e) => e >= 0));
- this._signature = value;
- }
-
- CiderLinkedLibraryCycleBuilder(
- {LinkedNodeBundleBuilder bundle, List<int> signature})
- : _bundle = bundle,
- _signature = signature;
-
- /// Flush [informative] data recursively.
- void flushInformative() {
- _bundle?.flushInformative();
- }
-
- /// Accumulate non-[informative] data into [signature].
- void collectApiSignature(api_sig.ApiSignature signature) {
- if (this._signature == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this._signature.length);
- for (var x in this._signature) {
- signature.addInt(x);
- }
- }
- signature.addBool(this._bundle != null);
- this._bundle?.collectApiSignature(signature);
- }
-
- List<int> toBuffer() {
- fb.Builder fbBuilder = fb.Builder();
- return fbBuilder.finish(finish(fbBuilder), "CLNB");
- }
-
- fb.Offset finish(fb.Builder fbBuilder) {
- fb.Offset offset_bundle;
- fb.Offset offset_signature;
- if (_bundle != null) {
- offset_bundle = _bundle.finish(fbBuilder);
- }
- if (!(_signature == null || _signature.isEmpty)) {
- offset_signature = fbBuilder.writeListUint32(_signature);
- }
- fbBuilder.startTable();
- if (offset_bundle != null) {
- fbBuilder.addOffset(1, offset_bundle);
- }
- if (offset_signature != null) {
- fbBuilder.addOffset(0, offset_signature);
- }
- return fbBuilder.endTable();
- }
-}
-
-idl.CiderLinkedLibraryCycle readCiderLinkedLibraryCycle(List<int> buffer) {
- fb.BufferContext rootRef = fb.BufferContext.fromBytes(buffer);
- return const _CiderLinkedLibraryCycleReader().read(rootRef, 0);
-}
-
-class _CiderLinkedLibraryCycleReader
- extends fb.TableReader<_CiderLinkedLibraryCycleImpl> {
- const _CiderLinkedLibraryCycleReader();
-
- @override
- _CiderLinkedLibraryCycleImpl createObject(fb.BufferContext bc, int offset) =>
- _CiderLinkedLibraryCycleImpl(bc, offset);
-}
-
-class _CiderLinkedLibraryCycleImpl extends Object
- with _CiderLinkedLibraryCycleMixin
- implements idl.CiderLinkedLibraryCycle {
- final fb.BufferContext _bc;
- final int _bcOffset;
-
- _CiderLinkedLibraryCycleImpl(this._bc, this._bcOffset);
-
- idl.LinkedNodeBundle _bundle;
- List<int> _signature;
-
- @override
- idl.LinkedNodeBundle get bundle {
- _bundle ??=
- const _LinkedNodeBundleReader().vTableGet(_bc, _bcOffset, 1, null);
- return _bundle;
- }
-
- @override
- List<int> get signature {
- _signature ??=
- const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 0, const <int>[]);
- return _signature;
- }
-}
-
-abstract class _CiderLinkedLibraryCycleMixin
- implements idl.CiderLinkedLibraryCycle {
- @override
- Map<String, Object> toJson() {
- Map<String, Object> _result = <String, Object>{};
- if (bundle != null) {
- _result["bundle"] = bundle.toJson();
- }
- if (signature.isNotEmpty) {
- _result["signature"] = signature;
- }
- return _result;
- }
-
- @override
- Map<String, Object> toMap() => {
- "bundle": bundle,
- "signature": signature,
- };
-
- @override
- String toString() => convert.json.encode(toJson());
-}
-
class CiderUnitErrorsBuilder extends Object
with _CiderUnitErrorsMixin
implements idl.CiderUnitErrors {
@@ -4217,13505 +3971,28 @@
String toString() => convert.json.encode(toJson());
}
-class LinkedLanguageVersionBuilder extends Object
- with _LinkedLanguageVersionMixin
- implements idl.LinkedLanguageVersion {
- int _major;
- int _minor;
-
- @override
- int get major => _major ??= 0;
-
- set major(int value) {
- assert(value == null || value >= 0);
- this._major = value;
- }
-
- @override
- int get minor => _minor ??= 0;
-
- set minor(int value) {
- assert(value == null || value >= 0);
- this._minor = value;
- }
-
- LinkedLanguageVersionBuilder({int major, int minor})
- : _major = major,
- _minor = minor;
-
- /// Flush [informative] data recursively.
- void flushInformative() {}
-
- /// Accumulate non-[informative] data into [signature].
- void collectApiSignature(api_sig.ApiSignature signature) {
- signature.addInt(this._major ?? 0);
- signature.addInt(this._minor ?? 0);
- }
-
- fb.Offset finish(fb.Builder fbBuilder) {
- fbBuilder.startTable();
- if (_major != null && _major != 0) {
- fbBuilder.addUint32(0, _major);
- }
- if (_minor != null && _minor != 0) {
- fbBuilder.addUint32(1, _minor);
- }
- return fbBuilder.endTable();
- }
-}
-
-class _LinkedLanguageVersionReader
- extends fb.TableReader<_LinkedLanguageVersionImpl> {
- const _LinkedLanguageVersionReader();
-
- @override
- _LinkedLanguageVersionImpl createObject(fb.BufferContext bc, int offset) =>
- _LinkedLanguageVersionImpl(bc, offset);
-}
-
-class _LinkedLanguageVersionImpl extends Object
- with _LinkedLanguageVersionMixin
- implements idl.LinkedLanguageVersion {
- final fb.BufferContext _bc;
- final int _bcOffset;
-
- _LinkedLanguageVersionImpl(this._bc, this._bcOffset);
-
- int _major;
- int _minor;
-
- @override
- int get major {
- _major ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 0, 0);
- return _major;
- }
-
- @override
- int get minor {
- _minor ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 1, 0);
- return _minor;
- }
-}
-
-abstract class _LinkedLanguageVersionMixin
- implements idl.LinkedLanguageVersion {
- @override
- Map<String, Object> toJson() {
- Map<String, Object> _result = <String, Object>{};
- if (major != 0) {
- _result["major"] = major;
- }
- if (minor != 0) {
- _result["minor"] = minor;
- }
- return _result;
- }
-
- @override
- Map<String, Object> toMap() => {
- "major": major,
- "minor": minor,
- };
-
- @override
- String toString() => convert.json.encode(toJson());
-}
-
-class LinkedLibraryLanguageVersionBuilder extends Object
- with _LinkedLibraryLanguageVersionMixin
- implements idl.LinkedLibraryLanguageVersion {
- LinkedLanguageVersionBuilder _override2;
- LinkedLanguageVersionBuilder _package;
-
- @override
- LinkedLanguageVersionBuilder get override2 => _override2;
-
- set override2(LinkedLanguageVersionBuilder value) {
- this._override2 = value;
- }
-
- @override
- LinkedLanguageVersionBuilder get package => _package;
-
- set package(LinkedLanguageVersionBuilder value) {
- this._package = value;
- }
-
- LinkedLibraryLanguageVersionBuilder(
- {LinkedLanguageVersionBuilder override2,
- LinkedLanguageVersionBuilder package})
- : _override2 = override2,
- _package = package;
-
- /// Flush [informative] data recursively.
- void flushInformative() {
- _override2?.flushInformative();
- _package?.flushInformative();
- }
-
- /// Accumulate non-[informative] data into [signature].
- void collectApiSignature(api_sig.ApiSignature signature) {
- signature.addBool(this._package != null);
- this._package?.collectApiSignature(signature);
- signature.addBool(this._override2 != null);
- this._override2?.collectApiSignature(signature);
- }
-
- fb.Offset finish(fb.Builder fbBuilder) {
- fb.Offset offset_override2;
- fb.Offset offset_package;
- if (_override2 != null) {
- offset_override2 = _override2.finish(fbBuilder);
- }
- if (_package != null) {
- offset_package = _package.finish(fbBuilder);
- }
- fbBuilder.startTable();
- if (offset_override2 != null) {
- fbBuilder.addOffset(1, offset_override2);
- }
- if (offset_package != null) {
- fbBuilder.addOffset(0, offset_package);
- }
- return fbBuilder.endTable();
- }
-}
-
-class _LinkedLibraryLanguageVersionReader
- extends fb.TableReader<_LinkedLibraryLanguageVersionImpl> {
- const _LinkedLibraryLanguageVersionReader();
-
- @override
- _LinkedLibraryLanguageVersionImpl createObject(
- fb.BufferContext bc, int offset) =>
- _LinkedLibraryLanguageVersionImpl(bc, offset);
-}
-
-class _LinkedLibraryLanguageVersionImpl extends Object
- with _LinkedLibraryLanguageVersionMixin
- implements idl.LinkedLibraryLanguageVersion {
- final fb.BufferContext _bc;
- final int _bcOffset;
-
- _LinkedLibraryLanguageVersionImpl(this._bc, this._bcOffset);
-
- idl.LinkedLanguageVersion _override2;
- idl.LinkedLanguageVersion _package;
-
- @override
- idl.LinkedLanguageVersion get override2 {
- _override2 ??=
- const _LinkedLanguageVersionReader().vTableGet(_bc, _bcOffset, 1, null);
- return _override2;
- }
-
- @override
- idl.LinkedLanguageVersion get package {
- _package ??=
- const _LinkedLanguageVersionReader().vTableGet(_bc, _bcOffset, 0, null);
- return _package;
- }
-}
-
-abstract class _LinkedLibraryLanguageVersionMixin
- implements idl.LinkedLibraryLanguageVersion {
- @override
- Map<String, Object> toJson() {
- Map<String, Object> _result = <String, Object>{};
- if (override2 != null) {
- _result["override2"] = override2.toJson();
- }
- if (package != null) {
- _result["package"] = package.toJson();
- }
- return _result;
- }
-
- @override
- Map<String, Object> toMap() => {
- "override2": override2,
- "package": package,
- };
-
- @override
- String toString() => convert.json.encode(toJson());
-}
-
-class LinkedNodeBuilder extends Object
- with _LinkedNodeMixin
- implements idl.LinkedNode {
- LinkedNodeTypeBuilder _variantField_24;
- List<LinkedNodeBuilder> _variantField_2;
- List<LinkedNodeBuilder> _variantField_4;
- LinkedNodeBuilder _variantField_6;
- LinkedNodeBuilder _variantField_7;
- int _variantField_17;
- LinkedNodeBuilder _variantField_8;
- LinkedNodeTypeSubstitutionBuilder _variantField_38;
- int _variantField_15;
- idl.UnlinkedTokenType _variantField_28;
- bool _variantField_27;
- LinkedNodeBuilder _variantField_9;
- LinkedNodeBuilder _variantField_12;
- List<LinkedNodeBuilder> _variantField_5;
- LinkedNodeBuilder _variantField_13;
- List<String> _variantField_33;
- idl.LinkedNodeCommentType _variantField_29;
- List<LinkedNodeBuilder> _variantField_3;
- List<int> _variantField_41;
- LinkedLibraryLanguageVersionBuilder _variantField_40;
- LinkedNodeBuilder _variantField_10;
- idl.LinkedNodeFormalParameterKind _variantField_26;
- double _variantField_21;
- LinkedNodeTypeBuilder _variantField_25;
- String _variantField_20;
- List<LinkedNodeTypeBuilder> _variantField_39;
- int _flags;
- String _variantField_1;
- int _variantField_36;
- int _variantField_16;
- String _variantField_30;
- LinkedNodeBuilder _variantField_14;
- idl.LinkedNodeKind _kind;
- bool _variantField_31;
- List<String> _variantField_34;
- String _name;
- idl.UnlinkedTokenType _variantField_35;
- TopLevelInferenceErrorBuilder _variantField_32;
- LinkedNodeTypeBuilder _variantField_23;
- LinkedNodeBuilder _variantField_11;
- String _variantField_22;
- int _variantField_19;
-
- @override
- LinkedNodeTypeBuilder get actualReturnType {
- assert(kind == idl.LinkedNodeKind.functionDeclaration ||
- kind == idl.LinkedNodeKind.functionExpression ||
- kind == idl.LinkedNodeKind.functionTypeAlias ||
- kind == idl.LinkedNodeKind.genericFunctionType ||
- kind == idl.LinkedNodeKind.methodDeclaration);
- return _variantField_24;
- }
-
- @override
- LinkedNodeTypeBuilder get actualType {
- assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
- kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
- kind == idl.LinkedNodeKind.simpleFormalParameter ||
- kind == idl.LinkedNodeKind.variableDeclaration);
- return _variantField_24;
- }
-
- @override
- LinkedNodeTypeBuilder get binaryExpression_invokeType {
- assert(kind == idl.LinkedNodeKind.binaryExpression);
- return _variantField_24;
- }
-
- @override
- LinkedNodeTypeBuilder get extensionOverride_extendedType {
- assert(kind == idl.LinkedNodeKind.extensionOverride);
- return _variantField_24;
- }
-
- @override
- LinkedNodeTypeBuilder get invocationExpression_invokeType {
- assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
- kind == idl.LinkedNodeKind.methodInvocation);
- return _variantField_24;
- }
-
- /// The explicit or inferred return type of a function typed node.
- set actualReturnType(LinkedNodeTypeBuilder value) {
- assert(kind == idl.LinkedNodeKind.functionDeclaration ||
- kind == idl.LinkedNodeKind.functionExpression ||
- kind == idl.LinkedNodeKind.functionTypeAlias ||
- kind == idl.LinkedNodeKind.genericFunctionType ||
- kind == idl.LinkedNodeKind.methodDeclaration);
- _variantField_24 = value;
- }
-
- set actualType(LinkedNodeTypeBuilder value) {
- assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
- kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
- kind == idl.LinkedNodeKind.simpleFormalParameter ||
- kind == idl.LinkedNodeKind.variableDeclaration);
- _variantField_24 = value;
- }
-
- set binaryExpression_invokeType(LinkedNodeTypeBuilder value) {
- assert(kind == idl.LinkedNodeKind.binaryExpression);
- _variantField_24 = value;
- }
-
- set extensionOverride_extendedType(LinkedNodeTypeBuilder value) {
- assert(kind == idl.LinkedNodeKind.extensionOverride);
- _variantField_24 = value;
- }
-
- set invocationExpression_invokeType(LinkedNodeTypeBuilder value) {
- assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
- kind == idl.LinkedNodeKind.methodInvocation);
- _variantField_24 = value;
- }
-
- @override
- List<LinkedNodeBuilder> get adjacentStrings_strings {
- assert(kind == idl.LinkedNodeKind.adjacentStrings);
- return _variantField_2 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get argumentList_arguments {
- assert(kind == idl.LinkedNodeKind.argumentList);
- return _variantField_2 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get block_statements {
- assert(kind == idl.LinkedNodeKind.block);
- return _variantField_2 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get cascadeExpression_sections {
- assert(kind == idl.LinkedNodeKind.cascadeExpression);
- return _variantField_2 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get comment_references {
- assert(kind == idl.LinkedNodeKind.comment);
- return _variantField_2 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get compilationUnit_declarations {
- assert(kind == idl.LinkedNodeKind.compilationUnit);
- return _variantField_2 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get constructorDeclaration_initializers {
- assert(kind == idl.LinkedNodeKind.constructorDeclaration);
- return _variantField_2 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get dottedName_components {
- assert(kind == idl.LinkedNodeKind.dottedName);
- return _variantField_2 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get enumDeclaration_constants {
- assert(kind == idl.LinkedNodeKind.enumDeclaration);
- return _variantField_2 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get extensionOverride_arguments {
- assert(kind == idl.LinkedNodeKind.extensionOverride);
- return _variantField_2 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get formalParameterList_parameters {
- assert(kind == idl.LinkedNodeKind.formalParameterList);
- return _variantField_2 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get implementsClause_interfaces {
- assert(kind == idl.LinkedNodeKind.implementsClause);
- return _variantField_2 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get instanceCreationExpression_arguments {
- assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
- return _variantField_2 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get labeledStatement_labels {
- assert(kind == idl.LinkedNodeKind.labeledStatement);
- return _variantField_2 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get libraryIdentifier_components {
- assert(kind == idl.LinkedNodeKind.libraryIdentifier);
- return _variantField_2 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get namespaceDirective_combinators {
- assert(kind == idl.LinkedNodeKind.exportDirective ||
- kind == idl.LinkedNodeKind.importDirective);
- return _variantField_2 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get onClause_superclassConstraints {
- assert(kind == idl.LinkedNodeKind.onClause);
- return _variantField_2 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get stringInterpolation_elements {
- assert(kind == idl.LinkedNodeKind.stringInterpolation);
- return _variantField_2 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get switchStatement_members {
- assert(kind == idl.LinkedNodeKind.switchStatement);
- return _variantField_2 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get tryStatement_catchClauses {
- assert(kind == idl.LinkedNodeKind.tryStatement);
- return _variantField_2 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get typeArgumentList_arguments {
- assert(kind == idl.LinkedNodeKind.typeArgumentList);
- return _variantField_2 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get typedLiteral_typeArguments {
- assert(kind == idl.LinkedNodeKind.listLiteral ||
- kind == idl.LinkedNodeKind.setOrMapLiteral);
- return _variantField_2 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get typeName_typeArguments {
- assert(kind == idl.LinkedNodeKind.typeName);
- return _variantField_2 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get typeParameterList_typeParameters {
- assert(kind == idl.LinkedNodeKind.typeParameterList);
- return _variantField_2 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get variableDeclarationList_variables {
- assert(kind == idl.LinkedNodeKind.variableDeclarationList);
- return _variantField_2 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get withClause_mixinTypes {
- assert(kind == idl.LinkedNodeKind.withClause);
- return _variantField_2 ??= <LinkedNodeBuilder>[];
- }
-
- set adjacentStrings_strings(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.adjacentStrings);
- _variantField_2 = value;
- }
-
- set argumentList_arguments(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.argumentList);
- _variantField_2 = value;
- }
-
- set block_statements(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.block);
- _variantField_2 = value;
- }
-
- set cascadeExpression_sections(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.cascadeExpression);
- _variantField_2 = value;
- }
-
- set comment_references(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.comment);
- _variantField_2 = value;
- }
-
- set compilationUnit_declarations(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.compilationUnit);
- _variantField_2 = value;
- }
-
- set constructorDeclaration_initializers(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.constructorDeclaration);
- _variantField_2 = value;
- }
-
- set dottedName_components(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.dottedName);
- _variantField_2 = value;
- }
-
- set enumDeclaration_constants(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.enumDeclaration);
- _variantField_2 = value;
- }
-
- set extensionOverride_arguments(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.extensionOverride);
- _variantField_2 = value;
- }
-
- set formalParameterList_parameters(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.formalParameterList);
- _variantField_2 = value;
- }
-
- set implementsClause_interfaces(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.implementsClause);
- _variantField_2 = value;
- }
-
- set instanceCreationExpression_arguments(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
- _variantField_2 = value;
- }
-
- set labeledStatement_labels(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.labeledStatement);
- _variantField_2 = value;
- }
-
- set libraryIdentifier_components(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.libraryIdentifier);
- _variantField_2 = value;
- }
-
- set namespaceDirective_combinators(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.exportDirective ||
- kind == idl.LinkedNodeKind.importDirective);
- _variantField_2 = value;
- }
-
- set onClause_superclassConstraints(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.onClause);
- _variantField_2 = value;
- }
-
- set stringInterpolation_elements(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.stringInterpolation);
- _variantField_2 = value;
- }
-
- set switchStatement_members(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.switchStatement);
- _variantField_2 = value;
- }
-
- set tryStatement_catchClauses(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.tryStatement);
- _variantField_2 = value;
- }
-
- set typeArgumentList_arguments(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.typeArgumentList);
- _variantField_2 = value;
- }
-
- set typedLiteral_typeArguments(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.listLiteral ||
- kind == idl.LinkedNodeKind.setOrMapLiteral);
- _variantField_2 = value;
- }
-
- set typeName_typeArguments(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.typeName);
- _variantField_2 = value;
- }
-
- set typeParameterList_typeParameters(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.typeParameterList);
- _variantField_2 = value;
- }
-
- set variableDeclarationList_variables(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.variableDeclarationList);
- _variantField_2 = value;
- }
-
- set withClause_mixinTypes(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.withClause);
- _variantField_2 = value;
- }
-
- @override
- List<LinkedNodeBuilder> get annotatedNode_metadata {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.classTypeAlias ||
- kind == idl.LinkedNodeKind.constructorDeclaration ||
- kind == idl.LinkedNodeKind.declaredIdentifier ||
- kind == idl.LinkedNodeKind.enumDeclaration ||
- kind == idl.LinkedNodeKind.enumConstantDeclaration ||
- kind == idl.LinkedNodeKind.exportDirective ||
- kind == idl.LinkedNodeKind.extensionDeclaration ||
- kind == idl.LinkedNodeKind.fieldDeclaration ||
- kind == idl.LinkedNodeKind.functionDeclaration ||
- kind == idl.LinkedNodeKind.functionTypeAlias ||
- kind == idl.LinkedNodeKind.genericTypeAlias ||
- kind == idl.LinkedNodeKind.importDirective ||
- kind == idl.LinkedNodeKind.libraryDirective ||
- kind == idl.LinkedNodeKind.methodDeclaration ||
- kind == idl.LinkedNodeKind.mixinDeclaration ||
- kind == idl.LinkedNodeKind.partDirective ||
- kind == idl.LinkedNodeKind.partOfDirective ||
- kind == idl.LinkedNodeKind.topLevelVariableDeclaration ||
- kind == idl.LinkedNodeKind.typeParameter ||
- kind == idl.LinkedNodeKind.variableDeclaration ||
- kind == idl.LinkedNodeKind.variableDeclarationList);
- return _variantField_4 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get normalFormalParameter_metadata {
- assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
- kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
- kind == idl.LinkedNodeKind.simpleFormalParameter);
- return _variantField_4 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get switchMember_statements {
- assert(kind == idl.LinkedNodeKind.switchCase ||
- kind == idl.LinkedNodeKind.switchDefault);
- return _variantField_4 ??= <LinkedNodeBuilder>[];
- }
-
- set annotatedNode_metadata(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.classTypeAlias ||
- kind == idl.LinkedNodeKind.constructorDeclaration ||
- kind == idl.LinkedNodeKind.declaredIdentifier ||
- kind == idl.LinkedNodeKind.enumDeclaration ||
- kind == idl.LinkedNodeKind.enumConstantDeclaration ||
- kind == idl.LinkedNodeKind.exportDirective ||
- kind == idl.LinkedNodeKind.extensionDeclaration ||
- kind == idl.LinkedNodeKind.fieldDeclaration ||
- kind == idl.LinkedNodeKind.functionDeclaration ||
- kind == idl.LinkedNodeKind.functionTypeAlias ||
- kind == idl.LinkedNodeKind.genericTypeAlias ||
- kind == idl.LinkedNodeKind.importDirective ||
- kind == idl.LinkedNodeKind.libraryDirective ||
- kind == idl.LinkedNodeKind.methodDeclaration ||
- kind == idl.LinkedNodeKind.mixinDeclaration ||
- kind == idl.LinkedNodeKind.partDirective ||
- kind == idl.LinkedNodeKind.partOfDirective ||
- kind == idl.LinkedNodeKind.topLevelVariableDeclaration ||
- kind == idl.LinkedNodeKind.typeParameter ||
- kind == idl.LinkedNodeKind.variableDeclaration ||
- kind == idl.LinkedNodeKind.variableDeclarationList);
- _variantField_4 = value;
- }
-
- set normalFormalParameter_metadata(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
- kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
- kind == idl.LinkedNodeKind.simpleFormalParameter);
- _variantField_4 = value;
- }
-
- set switchMember_statements(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.switchCase ||
- kind == idl.LinkedNodeKind.switchDefault);
- _variantField_4 = value;
- }
-
- @override
- LinkedNodeBuilder get annotation_arguments {
- assert(kind == idl.LinkedNodeKind.annotation);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get asExpression_expression {
- assert(kind == idl.LinkedNodeKind.asExpression);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get assertInitializer_condition {
- assert(kind == idl.LinkedNodeKind.assertInitializer);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get assertStatement_condition {
- assert(kind == idl.LinkedNodeKind.assertStatement);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get assignmentExpression_leftHandSide {
- assert(kind == idl.LinkedNodeKind.assignmentExpression);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get awaitExpression_expression {
- assert(kind == idl.LinkedNodeKind.awaitExpression);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get binaryExpression_leftOperand {
- assert(kind == idl.LinkedNodeKind.binaryExpression);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get blockFunctionBody_block {
- assert(kind == idl.LinkedNodeKind.blockFunctionBody);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get breakStatement_label {
- assert(kind == idl.LinkedNodeKind.breakStatement);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get cascadeExpression_target {
- assert(kind == idl.LinkedNodeKind.cascadeExpression);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get catchClause_body {
- assert(kind == idl.LinkedNodeKind.catchClause);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get classDeclaration_extendsClause {
- assert(kind == idl.LinkedNodeKind.classDeclaration);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get classTypeAlias_typeParameters {
- assert(kind == idl.LinkedNodeKind.classTypeAlias);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get commentReference_identifier {
- assert(kind == idl.LinkedNodeKind.commentReference);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get compilationUnit_scriptTag {
- assert(kind == idl.LinkedNodeKind.compilationUnit);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get conditionalExpression_condition {
- assert(kind == idl.LinkedNodeKind.conditionalExpression);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get configuration_name {
- assert(kind == idl.LinkedNodeKind.configuration);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get constructorDeclaration_body {
- assert(kind == idl.LinkedNodeKind.constructorDeclaration);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get constructorFieldInitializer_expression {
- assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get constructorName_name {
- assert(kind == idl.LinkedNodeKind.constructorName);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get continueStatement_label {
- assert(kind == idl.LinkedNodeKind.continueStatement);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get declaredIdentifier_identifier {
- assert(kind == idl.LinkedNodeKind.declaredIdentifier);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get defaultFormalParameter_defaultValue {
- assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get doStatement_body {
- assert(kind == idl.LinkedNodeKind.doStatement);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get expressionFunctionBody_expression {
- assert(kind == idl.LinkedNodeKind.expressionFunctionBody);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get expressionStatement_expression {
- assert(kind == idl.LinkedNodeKind.expressionStatement);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get extendsClause_superclass {
- assert(kind == idl.LinkedNodeKind.extendsClause);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get extensionDeclaration_typeParameters {
- assert(kind == idl.LinkedNodeKind.extensionDeclaration);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get fieldDeclaration_fields {
- assert(kind == idl.LinkedNodeKind.fieldDeclaration);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get fieldFormalParameter_type {
- assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get forEachParts_iterable {
- assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration ||
- kind == idl.LinkedNodeKind.forEachPartsWithIdentifier);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get forMixin_forLoopParts {
- assert(kind == idl.LinkedNodeKind.forElement ||
- kind == idl.LinkedNodeKind.forStatement);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get forParts_condition {
- assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
- kind == idl.LinkedNodeKind.forPartsWithExpression);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get functionDeclaration_functionExpression {
- assert(kind == idl.LinkedNodeKind.functionDeclaration);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get functionDeclarationStatement_functionDeclaration {
- assert(kind == idl.LinkedNodeKind.functionDeclarationStatement);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get functionExpression_body {
- assert(kind == idl.LinkedNodeKind.functionExpression);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get functionExpressionInvocation_function {
- assert(kind == idl.LinkedNodeKind.functionExpressionInvocation);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get functionTypeAlias_formalParameters {
- assert(kind == idl.LinkedNodeKind.functionTypeAlias);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get functionTypedFormalParameter_formalParameters {
- assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get genericFunctionType_typeParameters {
- assert(kind == idl.LinkedNodeKind.genericFunctionType);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get genericTypeAlias_typeParameters {
- assert(kind == idl.LinkedNodeKind.genericTypeAlias);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get ifMixin_condition {
- assert(kind == idl.LinkedNodeKind.ifElement ||
- kind == idl.LinkedNodeKind.ifStatement);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get indexExpression_index {
- assert(kind == idl.LinkedNodeKind.indexExpression);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get interpolationExpression_expression {
- assert(kind == idl.LinkedNodeKind.interpolationExpression);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get isExpression_expression {
- assert(kind == idl.LinkedNodeKind.isExpression);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get label_label {
- assert(kind == idl.LinkedNodeKind.label);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get labeledStatement_statement {
- assert(kind == idl.LinkedNodeKind.labeledStatement);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get libraryDirective_name {
- assert(kind == idl.LinkedNodeKind.libraryDirective);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get mapLiteralEntry_key {
- assert(kind == idl.LinkedNodeKind.mapLiteralEntry);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get methodDeclaration_body {
- assert(kind == idl.LinkedNodeKind.methodDeclaration);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get methodInvocation_methodName {
- assert(kind == idl.LinkedNodeKind.methodInvocation);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get mixinDeclaration_onClause {
- assert(kind == idl.LinkedNodeKind.mixinDeclaration);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get namedExpression_expression {
- assert(kind == idl.LinkedNodeKind.namedExpression);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get nativeClause_name {
- assert(kind == idl.LinkedNodeKind.nativeClause);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get nativeFunctionBody_stringLiteral {
- assert(kind == idl.LinkedNodeKind.nativeFunctionBody);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get parenthesizedExpression_expression {
- assert(kind == idl.LinkedNodeKind.parenthesizedExpression);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get partOfDirective_libraryName {
- assert(kind == idl.LinkedNodeKind.partOfDirective);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get postfixExpression_operand {
- assert(kind == idl.LinkedNodeKind.postfixExpression);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get prefixedIdentifier_identifier {
- assert(kind == idl.LinkedNodeKind.prefixedIdentifier);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get prefixExpression_operand {
- assert(kind == idl.LinkedNodeKind.prefixExpression);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get propertyAccess_propertyName {
- assert(kind == idl.LinkedNodeKind.propertyAccess);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get redirectingConstructorInvocation_arguments {
- assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get returnStatement_expression {
- assert(kind == idl.LinkedNodeKind.returnStatement);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get simpleFormalParameter_type {
- assert(kind == idl.LinkedNodeKind.simpleFormalParameter);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get spreadElement_expression {
- assert(kind == idl.LinkedNodeKind.spreadElement);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get superConstructorInvocation_arguments {
- assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get switchCase_expression {
- assert(kind == idl.LinkedNodeKind.switchCase);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get throwExpression_expression {
- assert(kind == idl.LinkedNodeKind.throwExpression);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get topLevelVariableDeclaration_variableList {
- assert(kind == idl.LinkedNodeKind.topLevelVariableDeclaration);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get tryStatement_body {
- assert(kind == idl.LinkedNodeKind.tryStatement);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get typeName_name {
- assert(kind == idl.LinkedNodeKind.typeName);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get typeParameter_bound {
- assert(kind == idl.LinkedNodeKind.typeParameter);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get variableDeclaration_initializer {
- assert(kind == idl.LinkedNodeKind.variableDeclaration);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get variableDeclarationList_type {
- assert(kind == idl.LinkedNodeKind.variableDeclarationList);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get variableDeclarationStatement_variables {
- assert(kind == idl.LinkedNodeKind.variableDeclarationStatement);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get whileStatement_body {
- assert(kind == idl.LinkedNodeKind.whileStatement);
- return _variantField_6;
- }
-
- @override
- LinkedNodeBuilder get yieldStatement_expression {
- assert(kind == idl.LinkedNodeKind.yieldStatement);
- return _variantField_6;
- }
-
- set annotation_arguments(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.annotation);
- _variantField_6 = value;
- }
-
- set asExpression_expression(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.asExpression);
- _variantField_6 = value;
- }
-
- set assertInitializer_condition(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.assertInitializer);
- _variantField_6 = value;
- }
-
- set assertStatement_condition(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.assertStatement);
- _variantField_6 = value;
- }
-
- set assignmentExpression_leftHandSide(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.assignmentExpression);
- _variantField_6 = value;
- }
-
- set awaitExpression_expression(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.awaitExpression);
- _variantField_6 = value;
- }
-
- set binaryExpression_leftOperand(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.binaryExpression);
- _variantField_6 = value;
- }
-
- set blockFunctionBody_block(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.blockFunctionBody);
- _variantField_6 = value;
- }
-
- set breakStatement_label(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.breakStatement);
- _variantField_6 = value;
- }
-
- set cascadeExpression_target(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.cascadeExpression);
- _variantField_6 = value;
- }
-
- set catchClause_body(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.catchClause);
- _variantField_6 = value;
- }
-
- set classDeclaration_extendsClause(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.classDeclaration);
- _variantField_6 = value;
- }
-
- set classTypeAlias_typeParameters(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.classTypeAlias);
- _variantField_6 = value;
- }
-
- set commentReference_identifier(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.commentReference);
- _variantField_6 = value;
- }
-
- set compilationUnit_scriptTag(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.compilationUnit);
- _variantField_6 = value;
- }
-
- set conditionalExpression_condition(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.conditionalExpression);
- _variantField_6 = value;
- }
-
- set configuration_name(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.configuration);
- _variantField_6 = value;
- }
-
- set constructorDeclaration_body(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.constructorDeclaration);
- _variantField_6 = value;
- }
-
- set constructorFieldInitializer_expression(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
- _variantField_6 = value;
- }
-
- set constructorName_name(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.constructorName);
- _variantField_6 = value;
- }
-
- set continueStatement_label(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.continueStatement);
- _variantField_6 = value;
- }
-
- set declaredIdentifier_identifier(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.declaredIdentifier);
- _variantField_6 = value;
- }
-
- set defaultFormalParameter_defaultValue(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
- _variantField_6 = value;
- }
-
- set doStatement_body(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.doStatement);
- _variantField_6 = value;
- }
-
- set expressionFunctionBody_expression(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.expressionFunctionBody);
- _variantField_6 = value;
- }
-
- set expressionStatement_expression(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.expressionStatement);
- _variantField_6 = value;
- }
-
- set extendsClause_superclass(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.extendsClause);
- _variantField_6 = value;
- }
-
- set extensionDeclaration_typeParameters(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.extensionDeclaration);
- _variantField_6 = value;
- }
-
- set fieldDeclaration_fields(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.fieldDeclaration);
- _variantField_6 = value;
- }
-
- set fieldFormalParameter_type(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
- _variantField_6 = value;
- }
-
- set forEachParts_iterable(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration ||
- kind == idl.LinkedNodeKind.forEachPartsWithIdentifier);
- _variantField_6 = value;
- }
-
- set forMixin_forLoopParts(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.forElement ||
- kind == idl.LinkedNodeKind.forStatement);
- _variantField_6 = value;
- }
-
- set forParts_condition(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
- kind == idl.LinkedNodeKind.forPartsWithExpression);
- _variantField_6 = value;
- }
-
- set functionDeclaration_functionExpression(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.functionDeclaration);
- _variantField_6 = value;
- }
-
- set functionDeclarationStatement_functionDeclaration(
- LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.functionDeclarationStatement);
- _variantField_6 = value;
- }
-
- set functionExpression_body(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.functionExpression);
- _variantField_6 = value;
- }
-
- set functionExpressionInvocation_function(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.functionExpressionInvocation);
- _variantField_6 = value;
- }
-
- set functionTypeAlias_formalParameters(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.functionTypeAlias);
- _variantField_6 = value;
- }
-
- set functionTypedFormalParameter_formalParameters(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
- _variantField_6 = value;
- }
-
- set genericFunctionType_typeParameters(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.genericFunctionType);
- _variantField_6 = value;
- }
-
- set genericTypeAlias_typeParameters(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.genericTypeAlias);
- _variantField_6 = value;
- }
-
- set ifMixin_condition(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.ifElement ||
- kind == idl.LinkedNodeKind.ifStatement);
- _variantField_6 = value;
- }
-
- set indexExpression_index(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.indexExpression);
- _variantField_6 = value;
- }
-
- set interpolationExpression_expression(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.interpolationExpression);
- _variantField_6 = value;
- }
-
- set isExpression_expression(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.isExpression);
- _variantField_6 = value;
- }
-
- set label_label(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.label);
- _variantField_6 = value;
- }
-
- set labeledStatement_statement(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.labeledStatement);
- _variantField_6 = value;
- }
-
- set libraryDirective_name(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.libraryDirective);
- _variantField_6 = value;
- }
-
- set mapLiteralEntry_key(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.mapLiteralEntry);
- _variantField_6 = value;
- }
-
- set methodDeclaration_body(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.methodDeclaration);
- _variantField_6 = value;
- }
-
- set methodInvocation_methodName(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.methodInvocation);
- _variantField_6 = value;
- }
-
- set mixinDeclaration_onClause(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.mixinDeclaration);
- _variantField_6 = value;
- }
-
- set namedExpression_expression(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.namedExpression);
- _variantField_6 = value;
- }
-
- set nativeClause_name(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.nativeClause);
- _variantField_6 = value;
- }
-
- set nativeFunctionBody_stringLiteral(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.nativeFunctionBody);
- _variantField_6 = value;
- }
-
- set parenthesizedExpression_expression(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.parenthesizedExpression);
- _variantField_6 = value;
- }
-
- set partOfDirective_libraryName(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.partOfDirective);
- _variantField_6 = value;
- }
-
- set postfixExpression_operand(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.postfixExpression);
- _variantField_6 = value;
- }
-
- set prefixedIdentifier_identifier(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.prefixedIdentifier);
- _variantField_6 = value;
- }
-
- set prefixExpression_operand(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.prefixExpression);
- _variantField_6 = value;
- }
-
- set propertyAccess_propertyName(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.propertyAccess);
- _variantField_6 = value;
- }
-
- set redirectingConstructorInvocation_arguments(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
- _variantField_6 = value;
- }
-
- set returnStatement_expression(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.returnStatement);
- _variantField_6 = value;
- }
-
- set simpleFormalParameter_type(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.simpleFormalParameter);
- _variantField_6 = value;
- }
-
- set spreadElement_expression(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.spreadElement);
- _variantField_6 = value;
- }
-
- set superConstructorInvocation_arguments(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
- _variantField_6 = value;
- }
-
- set switchCase_expression(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.switchCase);
- _variantField_6 = value;
- }
-
- set throwExpression_expression(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.throwExpression);
- _variantField_6 = value;
- }
-
- set topLevelVariableDeclaration_variableList(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.topLevelVariableDeclaration);
- _variantField_6 = value;
- }
-
- set tryStatement_body(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.tryStatement);
- _variantField_6 = value;
- }
-
- set typeName_name(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.typeName);
- _variantField_6 = value;
- }
-
- set typeParameter_bound(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.typeParameter);
- _variantField_6 = value;
- }
-
- set variableDeclaration_initializer(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.variableDeclaration);
- _variantField_6 = value;
- }
-
- set variableDeclarationList_type(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.variableDeclarationList);
- _variantField_6 = value;
- }
-
- set variableDeclarationStatement_variables(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.variableDeclarationStatement);
- _variantField_6 = value;
- }
-
- set whileStatement_body(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.whileStatement);
- _variantField_6 = value;
- }
-
- set yieldStatement_expression(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.yieldStatement);
- _variantField_6 = value;
- }
-
- @override
- LinkedNodeBuilder get annotation_constructorName {
- assert(kind == idl.LinkedNodeKind.annotation);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get asExpression_type {
- assert(kind == idl.LinkedNodeKind.asExpression);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get assertInitializer_message {
- assert(kind == idl.LinkedNodeKind.assertInitializer);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get assertStatement_message {
- assert(kind == idl.LinkedNodeKind.assertStatement);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get assignmentExpression_rightHandSide {
- assert(kind == idl.LinkedNodeKind.assignmentExpression);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get binaryExpression_rightOperand {
- assert(kind == idl.LinkedNodeKind.binaryExpression);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get catchClause_exceptionParameter {
- assert(kind == idl.LinkedNodeKind.catchClause);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get classDeclaration_withClause {
- assert(kind == idl.LinkedNodeKind.classDeclaration);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get classTypeAlias_superclass {
- assert(kind == idl.LinkedNodeKind.classTypeAlias);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get conditionalExpression_elseExpression {
- assert(kind == idl.LinkedNodeKind.conditionalExpression);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get configuration_value {
- assert(kind == idl.LinkedNodeKind.configuration);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get constructorFieldInitializer_fieldName {
- assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get constructorName_type {
- assert(kind == idl.LinkedNodeKind.constructorName);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get declaredIdentifier_type {
- assert(kind == idl.LinkedNodeKind.declaredIdentifier);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get defaultFormalParameter_parameter {
- assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get doStatement_condition {
- assert(kind == idl.LinkedNodeKind.doStatement);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get extensionDeclaration_extendedType {
- assert(kind == idl.LinkedNodeKind.extensionDeclaration);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get extensionOverride_extensionName {
- assert(kind == idl.LinkedNodeKind.extensionOverride);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get fieldFormalParameter_typeParameters {
- assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get forEachPartsWithDeclaration_loopVariable {
- assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get forEachPartsWithIdentifier_identifier {
- assert(kind == idl.LinkedNodeKind.forEachPartsWithIdentifier);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get forElement_body {
- assert(kind == idl.LinkedNodeKind.forElement);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get forPartsWithDeclarations_variables {
- assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get forPartsWithExpression_initialization {
- assert(kind == idl.LinkedNodeKind.forPartsWithExpression);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get forStatement_body {
- assert(kind == idl.LinkedNodeKind.forStatement);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get functionDeclaration_returnType {
- assert(kind == idl.LinkedNodeKind.functionDeclaration);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get functionExpression_formalParameters {
- assert(kind == idl.LinkedNodeKind.functionExpression);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get functionTypeAlias_returnType {
- assert(kind == idl.LinkedNodeKind.functionTypeAlias);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get functionTypedFormalParameter_returnType {
- assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get genericFunctionType_returnType {
- assert(kind == idl.LinkedNodeKind.genericFunctionType);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get genericTypeAlias_functionType {
- assert(kind == idl.LinkedNodeKind.genericTypeAlias);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get ifStatement_elseStatement {
- assert(kind == idl.LinkedNodeKind.ifStatement);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get indexExpression_target {
- assert(kind == idl.LinkedNodeKind.indexExpression);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get instanceCreationExpression_constructorName {
- assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get isExpression_type {
- assert(kind == idl.LinkedNodeKind.isExpression);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get mapLiteralEntry_value {
- assert(kind == idl.LinkedNodeKind.mapLiteralEntry);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get methodDeclaration_formalParameters {
- assert(kind == idl.LinkedNodeKind.methodDeclaration);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get methodInvocation_target {
- assert(kind == idl.LinkedNodeKind.methodInvocation);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get namedExpression_name {
- assert(kind == idl.LinkedNodeKind.namedExpression);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get partOfDirective_uri {
- assert(kind == idl.LinkedNodeKind.partOfDirective);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get prefixedIdentifier_prefix {
- assert(kind == idl.LinkedNodeKind.prefixedIdentifier);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get propertyAccess_target {
- assert(kind == idl.LinkedNodeKind.propertyAccess);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get redirectingConstructorInvocation_constructorName {
- assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get superConstructorInvocation_constructorName {
- assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get switchStatement_expression {
- assert(kind == idl.LinkedNodeKind.switchStatement);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get tryStatement_finallyBlock {
- assert(kind == idl.LinkedNodeKind.tryStatement);
- return _variantField_7;
- }
-
- @override
- LinkedNodeBuilder get whileStatement_condition {
- assert(kind == idl.LinkedNodeKind.whileStatement);
- return _variantField_7;
- }
-
- set annotation_constructorName(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.annotation);
- _variantField_7 = value;
- }
-
- set asExpression_type(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.asExpression);
- _variantField_7 = value;
- }
-
- set assertInitializer_message(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.assertInitializer);
- _variantField_7 = value;
- }
-
- set assertStatement_message(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.assertStatement);
- _variantField_7 = value;
- }
-
- set assignmentExpression_rightHandSide(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.assignmentExpression);
- _variantField_7 = value;
- }
-
- set binaryExpression_rightOperand(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.binaryExpression);
- _variantField_7 = value;
- }
-
- set catchClause_exceptionParameter(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.catchClause);
- _variantField_7 = value;
- }
-
- set classDeclaration_withClause(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.classDeclaration);
- _variantField_7 = value;
- }
-
- set classTypeAlias_superclass(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.classTypeAlias);
- _variantField_7 = value;
- }
-
- set conditionalExpression_elseExpression(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.conditionalExpression);
- _variantField_7 = value;
- }
-
- set configuration_value(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.configuration);
- _variantField_7 = value;
- }
-
- set constructorFieldInitializer_fieldName(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
- _variantField_7 = value;
- }
-
- set constructorName_type(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.constructorName);
- _variantField_7 = value;
- }
-
- set declaredIdentifier_type(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.declaredIdentifier);
- _variantField_7 = value;
- }
-
- set defaultFormalParameter_parameter(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
- _variantField_7 = value;
- }
-
- set doStatement_condition(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.doStatement);
- _variantField_7 = value;
- }
-
- set extensionDeclaration_extendedType(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.extensionDeclaration);
- _variantField_7 = value;
- }
-
- set extensionOverride_extensionName(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.extensionOverride);
- _variantField_7 = value;
- }
-
- set fieldFormalParameter_typeParameters(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
- _variantField_7 = value;
- }
-
- set forEachPartsWithDeclaration_loopVariable(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration);
- _variantField_7 = value;
- }
-
- set forEachPartsWithIdentifier_identifier(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.forEachPartsWithIdentifier);
- _variantField_7 = value;
- }
-
- set forElement_body(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.forElement);
- _variantField_7 = value;
- }
-
- set forPartsWithDeclarations_variables(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations);
- _variantField_7 = value;
- }
-
- set forPartsWithExpression_initialization(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.forPartsWithExpression);
- _variantField_7 = value;
- }
-
- set forStatement_body(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.forStatement);
- _variantField_7 = value;
- }
-
- set functionDeclaration_returnType(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.functionDeclaration);
- _variantField_7 = value;
- }
-
- set functionExpression_formalParameters(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.functionExpression);
- _variantField_7 = value;
- }
-
- set functionTypeAlias_returnType(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.functionTypeAlias);
- _variantField_7 = value;
- }
-
- set functionTypedFormalParameter_returnType(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
- _variantField_7 = value;
- }
-
- set genericFunctionType_returnType(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.genericFunctionType);
- _variantField_7 = value;
- }
-
- set genericTypeAlias_functionType(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.genericTypeAlias);
- _variantField_7 = value;
- }
-
- set ifStatement_elseStatement(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.ifStatement);
- _variantField_7 = value;
- }
-
- set indexExpression_target(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.indexExpression);
- _variantField_7 = value;
- }
-
- set instanceCreationExpression_constructorName(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
- _variantField_7 = value;
- }
-
- set isExpression_type(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.isExpression);
- _variantField_7 = value;
- }
-
- set mapLiteralEntry_value(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.mapLiteralEntry);
- _variantField_7 = value;
- }
-
- set methodDeclaration_formalParameters(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.methodDeclaration);
- _variantField_7 = value;
- }
-
- set methodInvocation_target(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.methodInvocation);
- _variantField_7 = value;
- }
-
- set namedExpression_name(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.namedExpression);
- _variantField_7 = value;
- }
-
- set partOfDirective_uri(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.partOfDirective);
- _variantField_7 = value;
- }
-
- set prefixedIdentifier_prefix(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.prefixedIdentifier);
- _variantField_7 = value;
- }
-
- set propertyAccess_target(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.propertyAccess);
- _variantField_7 = value;
- }
-
- set redirectingConstructorInvocation_constructorName(
- LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
- _variantField_7 = value;
- }
-
- set superConstructorInvocation_constructorName(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
- _variantField_7 = value;
- }
-
- set switchStatement_expression(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.switchStatement);
- _variantField_7 = value;
- }
-
- set tryStatement_finallyBlock(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.tryStatement);
- _variantField_7 = value;
- }
-
- set whileStatement_condition(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.whileStatement);
- _variantField_7 = value;
- }
-
- @override
- int get annotation_element {
- assert(kind == idl.LinkedNodeKind.annotation);
- return _variantField_17 ??= 0;
- }
-
- @override
- int get genericFunctionType_id {
- assert(kind == idl.LinkedNodeKind.genericFunctionType);
- return _variantField_17 ??= 0;
- }
-
- set annotation_element(int value) {
- assert(kind == idl.LinkedNodeKind.annotation);
- assert(value == null || value >= 0);
- _variantField_17 = value;
- }
-
- set genericFunctionType_id(int value) {
- assert(kind == idl.LinkedNodeKind.genericFunctionType);
- assert(value == null || value >= 0);
- _variantField_17 = value;
- }
-
- @override
- LinkedNodeBuilder get annotation_name {
- assert(kind == idl.LinkedNodeKind.annotation);
- return _variantField_8;
- }
-
- @override
- LinkedNodeBuilder get catchClause_exceptionType {
- assert(kind == idl.LinkedNodeKind.catchClause);
- return _variantField_8;
- }
-
- @override
- LinkedNodeBuilder get classDeclaration_nativeClause {
- assert(kind == idl.LinkedNodeKind.classDeclaration);
- return _variantField_8;
- }
-
- @override
- LinkedNodeBuilder get classTypeAlias_withClause {
- assert(kind == idl.LinkedNodeKind.classTypeAlias);
- return _variantField_8;
- }
-
- @override
- LinkedNodeBuilder get conditionalExpression_thenExpression {
- assert(kind == idl.LinkedNodeKind.conditionalExpression);
- return _variantField_8;
- }
-
- @override
- LinkedNodeBuilder get configuration_uri {
- assert(kind == idl.LinkedNodeKind.configuration);
- return _variantField_8;
- }
-
- @override
- LinkedNodeBuilder get constructorDeclaration_parameters {
- assert(kind == idl.LinkedNodeKind.constructorDeclaration);
- return _variantField_8;
- }
-
- @override
- LinkedNodeBuilder get extensionOverride_typeArguments {
- assert(kind == idl.LinkedNodeKind.extensionOverride);
- return _variantField_8;
- }
-
- @override
- LinkedNodeBuilder get fieldFormalParameter_formalParameters {
- assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
- return _variantField_8;
- }
-
- @override
- LinkedNodeBuilder get functionExpression_typeParameters {
- assert(kind == idl.LinkedNodeKind.functionExpression);
- return _variantField_8;
- }
-
- @override
- LinkedNodeBuilder get functionTypeAlias_typeParameters {
- assert(kind == idl.LinkedNodeKind.functionTypeAlias);
- return _variantField_8;
- }
-
- @override
- LinkedNodeBuilder get functionTypedFormalParameter_typeParameters {
- assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
- return _variantField_8;
- }
-
- @override
- LinkedNodeBuilder get genericFunctionType_formalParameters {
- assert(kind == idl.LinkedNodeKind.genericFunctionType);
- return _variantField_8;
- }
-
- @override
- LinkedNodeBuilder get ifElement_thenElement {
- assert(kind == idl.LinkedNodeKind.ifElement);
- return _variantField_8;
- }
-
- @override
- LinkedNodeBuilder get ifStatement_thenStatement {
- assert(kind == idl.LinkedNodeKind.ifStatement);
- return _variantField_8;
- }
-
- @override
- LinkedNodeBuilder get instanceCreationExpression_typeArguments {
- assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
- return _variantField_8;
- }
-
- @override
- LinkedNodeBuilder get methodDeclaration_returnType {
- assert(kind == idl.LinkedNodeKind.methodDeclaration);
- return _variantField_8;
- }
-
- set annotation_name(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.annotation);
- _variantField_8 = value;
- }
-
- set catchClause_exceptionType(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.catchClause);
- _variantField_8 = value;
- }
-
- set classDeclaration_nativeClause(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.classDeclaration);
- _variantField_8 = value;
- }
-
- set classTypeAlias_withClause(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.classTypeAlias);
- _variantField_8 = value;
- }
-
- set conditionalExpression_thenExpression(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.conditionalExpression);
- _variantField_8 = value;
- }
-
- set configuration_uri(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.configuration);
- _variantField_8 = value;
- }
-
- set constructorDeclaration_parameters(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.constructorDeclaration);
- _variantField_8 = value;
- }
-
- set extensionOverride_typeArguments(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.extensionOverride);
- _variantField_8 = value;
- }
-
- set fieldFormalParameter_formalParameters(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
- _variantField_8 = value;
- }
-
- set functionExpression_typeParameters(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.functionExpression);
- _variantField_8 = value;
- }
-
- set functionTypeAlias_typeParameters(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.functionTypeAlias);
- _variantField_8 = value;
- }
-
- set functionTypedFormalParameter_typeParameters(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
- _variantField_8 = value;
- }
-
- set genericFunctionType_formalParameters(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.genericFunctionType);
- _variantField_8 = value;
- }
-
- set ifElement_thenElement(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.ifElement);
- _variantField_8 = value;
- }
-
- set ifStatement_thenStatement(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.ifStatement);
- _variantField_8 = value;
- }
-
- set instanceCreationExpression_typeArguments(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
- _variantField_8 = value;
- }
-
- set methodDeclaration_returnType(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.methodDeclaration);
- _variantField_8 = value;
- }
-
- @override
- LinkedNodeTypeSubstitutionBuilder get annotation_substitution {
- assert(kind == idl.LinkedNodeKind.annotation);
- return _variantField_38;
- }
-
- @override
- LinkedNodeTypeSubstitutionBuilder get assignmentExpression_substitution {
- assert(kind == idl.LinkedNodeKind.assignmentExpression);
- return _variantField_38;
- }
-
- @override
- LinkedNodeTypeSubstitutionBuilder get binaryExpression_substitution {
- assert(kind == idl.LinkedNodeKind.binaryExpression);
- return _variantField_38;
- }
-
- @override
- LinkedNodeTypeSubstitutionBuilder get constructorName_substitution {
- assert(kind == idl.LinkedNodeKind.constructorName);
- return _variantField_38;
- }
-
- @override
- LinkedNodeTypeSubstitutionBuilder get indexExpression_substitution {
- assert(kind == idl.LinkedNodeKind.indexExpression);
- return _variantField_38;
- }
-
- @override
- LinkedNodeTypeSubstitutionBuilder get postfixExpression_substitution {
- assert(kind == idl.LinkedNodeKind.postfixExpression);
- return _variantField_38;
- }
-
- @override
- LinkedNodeTypeSubstitutionBuilder get prefixExpression_substitution {
- assert(kind == idl.LinkedNodeKind.prefixExpression);
- return _variantField_38;
- }
-
- @override
- LinkedNodeTypeSubstitutionBuilder
- get redirectingConstructorInvocation_substitution {
- assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
- return _variantField_38;
- }
-
- @override
- LinkedNodeTypeSubstitutionBuilder get simpleIdentifier_substitution {
- assert(kind == idl.LinkedNodeKind.simpleIdentifier);
- return _variantField_38;
- }
-
- @override
- LinkedNodeTypeSubstitutionBuilder
- get superConstructorInvocation_substitution {
- assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
- return _variantField_38;
- }
-
- set annotation_substitution(LinkedNodeTypeSubstitutionBuilder value) {
- assert(kind == idl.LinkedNodeKind.annotation);
- _variantField_38 = value;
- }
-
- set assignmentExpression_substitution(
- LinkedNodeTypeSubstitutionBuilder value) {
- assert(kind == idl.LinkedNodeKind.assignmentExpression);
- _variantField_38 = value;
- }
-
- set binaryExpression_substitution(LinkedNodeTypeSubstitutionBuilder value) {
- assert(kind == idl.LinkedNodeKind.binaryExpression);
- _variantField_38 = value;
- }
-
- set constructorName_substitution(LinkedNodeTypeSubstitutionBuilder value) {
- assert(kind == idl.LinkedNodeKind.constructorName);
- _variantField_38 = value;
- }
-
- set indexExpression_substitution(LinkedNodeTypeSubstitutionBuilder value) {
- assert(kind == idl.LinkedNodeKind.indexExpression);
- _variantField_38 = value;
- }
-
- set postfixExpression_substitution(LinkedNodeTypeSubstitutionBuilder value) {
- assert(kind == idl.LinkedNodeKind.postfixExpression);
- _variantField_38 = value;
- }
-
- set prefixExpression_substitution(LinkedNodeTypeSubstitutionBuilder value) {
- assert(kind == idl.LinkedNodeKind.prefixExpression);
- _variantField_38 = value;
- }
-
- set redirectingConstructorInvocation_substitution(
- LinkedNodeTypeSubstitutionBuilder value) {
- assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
- _variantField_38 = value;
- }
-
- set simpleIdentifier_substitution(LinkedNodeTypeSubstitutionBuilder value) {
- assert(kind == idl.LinkedNodeKind.simpleIdentifier);
- _variantField_38 = value;
- }
-
- set superConstructorInvocation_substitution(
- LinkedNodeTypeSubstitutionBuilder value) {
- assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
- _variantField_38 = value;
- }
-
- @override
- int get assignmentExpression_element {
- assert(kind == idl.LinkedNodeKind.assignmentExpression);
- return _variantField_15 ??= 0;
- }
-
- @override
- int get binaryExpression_element {
- assert(kind == idl.LinkedNodeKind.binaryExpression);
- return _variantField_15 ??= 0;
- }
-
- @override
- int get constructorName_element {
- assert(kind == idl.LinkedNodeKind.constructorName);
- return _variantField_15 ??= 0;
- }
-
- @override
- int get emptyFunctionBody_fake {
- assert(kind == idl.LinkedNodeKind.emptyFunctionBody);
- return _variantField_15 ??= 0;
- }
-
- @override
- int get emptyStatement_fake {
- assert(kind == idl.LinkedNodeKind.emptyStatement);
- return _variantField_15 ??= 0;
- }
-
- @override
- int get indexExpression_element {
- assert(kind == idl.LinkedNodeKind.indexExpression);
- return _variantField_15 ??= 0;
- }
-
- @override
- int get nullLiteral_fake {
- assert(kind == idl.LinkedNodeKind.nullLiteral);
- return _variantField_15 ??= 0;
- }
-
- @override
- int get postfixExpression_element {
- assert(kind == idl.LinkedNodeKind.postfixExpression);
- return _variantField_15 ??= 0;
- }
-
- @override
- int get prefixExpression_element {
- assert(kind == idl.LinkedNodeKind.prefixExpression);
- return _variantField_15 ??= 0;
- }
-
- @override
- int get redirectingConstructorInvocation_element {
- assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
- return _variantField_15 ??= 0;
- }
-
- @override
- int get simpleIdentifier_element {
- assert(kind == idl.LinkedNodeKind.simpleIdentifier);
- return _variantField_15 ??= 0;
- }
-
- @override
- int get superConstructorInvocation_element {
- assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
- return _variantField_15 ??= 0;
- }
-
- @override
- int get typeParameter_variance {
- assert(kind == idl.LinkedNodeKind.typeParameter);
- return _variantField_15 ??= 0;
- }
-
- set assignmentExpression_element(int value) {
- assert(kind == idl.LinkedNodeKind.assignmentExpression);
- assert(value == null || value >= 0);
- _variantField_15 = value;
- }
-
- set binaryExpression_element(int value) {
- assert(kind == idl.LinkedNodeKind.binaryExpression);
- assert(value == null || value >= 0);
- _variantField_15 = value;
- }
-
- set constructorName_element(int value) {
- assert(kind == idl.LinkedNodeKind.constructorName);
- assert(value == null || value >= 0);
- _variantField_15 = value;
- }
-
- set emptyFunctionBody_fake(int value) {
- assert(kind == idl.LinkedNodeKind.emptyFunctionBody);
- assert(value == null || value >= 0);
- _variantField_15 = value;
- }
-
- set emptyStatement_fake(int value) {
- assert(kind == idl.LinkedNodeKind.emptyStatement);
- assert(value == null || value >= 0);
- _variantField_15 = value;
- }
-
- set indexExpression_element(int value) {
- assert(kind == idl.LinkedNodeKind.indexExpression);
- assert(value == null || value >= 0);
- _variantField_15 = value;
- }
-
- set nullLiteral_fake(int value) {
- assert(kind == idl.LinkedNodeKind.nullLiteral);
- assert(value == null || value >= 0);
- _variantField_15 = value;
- }
-
- set postfixExpression_element(int value) {
- assert(kind == idl.LinkedNodeKind.postfixExpression);
- assert(value == null || value >= 0);
- _variantField_15 = value;
- }
-
- set prefixExpression_element(int value) {
- assert(kind == idl.LinkedNodeKind.prefixExpression);
- assert(value == null || value >= 0);
- _variantField_15 = value;
- }
-
- set redirectingConstructorInvocation_element(int value) {
- assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
- assert(value == null || value >= 0);
- _variantField_15 = value;
- }
-
- set simpleIdentifier_element(int value) {
- assert(kind == idl.LinkedNodeKind.simpleIdentifier);
- assert(value == null || value >= 0);
- _variantField_15 = value;
- }
-
- set superConstructorInvocation_element(int value) {
- assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
- assert(value == null || value >= 0);
- _variantField_15 = value;
- }
-
- set typeParameter_variance(int value) {
- assert(kind == idl.LinkedNodeKind.typeParameter);
- assert(value == null || value >= 0);
- _variantField_15 = value;
- }
-
- @override
- idl.UnlinkedTokenType get assignmentExpression_operator {
- assert(kind == idl.LinkedNodeKind.assignmentExpression);
- return _variantField_28 ??= idl.UnlinkedTokenType.NOTHING;
- }
-
- @override
- idl.UnlinkedTokenType get binaryExpression_operator {
- assert(kind == idl.LinkedNodeKind.binaryExpression);
- return _variantField_28 ??= idl.UnlinkedTokenType.NOTHING;
- }
-
- @override
- idl.UnlinkedTokenType get postfixExpression_operator {
- assert(kind == idl.LinkedNodeKind.postfixExpression);
- return _variantField_28 ??= idl.UnlinkedTokenType.NOTHING;
- }
-
- @override
- idl.UnlinkedTokenType get prefixExpression_operator {
- assert(kind == idl.LinkedNodeKind.prefixExpression);
- return _variantField_28 ??= idl.UnlinkedTokenType.NOTHING;
- }
-
- @override
- idl.UnlinkedTokenType get propertyAccess_operator {
- assert(kind == idl.LinkedNodeKind.propertyAccess);
- return _variantField_28 ??= idl.UnlinkedTokenType.NOTHING;
- }
-
- set assignmentExpression_operator(idl.UnlinkedTokenType value) {
- assert(kind == idl.LinkedNodeKind.assignmentExpression);
- _variantField_28 = value;
- }
-
- set binaryExpression_operator(idl.UnlinkedTokenType value) {
- assert(kind == idl.LinkedNodeKind.binaryExpression);
- _variantField_28 = value;
- }
-
- set postfixExpression_operator(idl.UnlinkedTokenType value) {
- assert(kind == idl.LinkedNodeKind.postfixExpression);
- _variantField_28 = value;
- }
-
- set prefixExpression_operator(idl.UnlinkedTokenType value) {
- assert(kind == idl.LinkedNodeKind.prefixExpression);
- _variantField_28 = value;
- }
-
- set propertyAccess_operator(idl.UnlinkedTokenType value) {
- assert(kind == idl.LinkedNodeKind.propertyAccess);
- _variantField_28 = value;
- }
-
- @override
- bool get booleanLiteral_value {
- assert(kind == idl.LinkedNodeKind.booleanLiteral);
- return _variantField_27 ??= false;
- }
-
- @override
- bool get classDeclaration_isDartObject {
- assert(kind == idl.LinkedNodeKind.classDeclaration);
- return _variantField_27 ??= false;
- }
-
- @override
- bool get inheritsCovariant {
- assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
- kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
- kind == idl.LinkedNodeKind.simpleFormalParameter ||
- kind == idl.LinkedNodeKind.variableDeclaration);
- return _variantField_27 ??= false;
- }
-
- @override
- bool get typeAlias_hasSelfReference {
- assert(kind == idl.LinkedNodeKind.functionTypeAlias ||
- kind == idl.LinkedNodeKind.genericTypeAlias);
- return _variantField_27 ??= false;
- }
-
- set booleanLiteral_value(bool value) {
- assert(kind == idl.LinkedNodeKind.booleanLiteral);
- _variantField_27 = value;
- }
-
- set classDeclaration_isDartObject(bool value) {
- assert(kind == idl.LinkedNodeKind.classDeclaration);
- _variantField_27 = value;
- }
-
- set inheritsCovariant(bool value) {
- assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
- kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
- kind == idl.LinkedNodeKind.simpleFormalParameter ||
- kind == idl.LinkedNodeKind.variableDeclaration);
- _variantField_27 = value;
- }
-
- set typeAlias_hasSelfReference(bool value) {
- assert(kind == idl.LinkedNodeKind.functionTypeAlias ||
- kind == idl.LinkedNodeKind.genericTypeAlias);
- _variantField_27 = value;
- }
-
- @override
- LinkedNodeBuilder get catchClause_stackTraceParameter {
- assert(kind == idl.LinkedNodeKind.catchClause);
- return _variantField_9;
- }
-
- @override
- LinkedNodeBuilder get classTypeAlias_implementsClause {
- assert(kind == idl.LinkedNodeKind.classTypeAlias);
- return _variantField_9;
- }
-
- @override
- LinkedNodeBuilder get constructorDeclaration_redirectedConstructor {
- assert(kind == idl.LinkedNodeKind.constructorDeclaration);
- return _variantField_9;
- }
-
- @override
- LinkedNodeBuilder get ifElement_elseElement {
- assert(kind == idl.LinkedNodeKind.ifElement);
- return _variantField_9;
- }
-
- @override
- LinkedNodeBuilder get methodDeclaration_typeParameters {
- assert(kind == idl.LinkedNodeKind.methodDeclaration);
- return _variantField_9;
- }
-
- set catchClause_stackTraceParameter(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.catchClause);
- _variantField_9 = value;
- }
-
- set classTypeAlias_implementsClause(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.classTypeAlias);
- _variantField_9 = value;
- }
-
- set constructorDeclaration_redirectedConstructor(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.constructorDeclaration);
- _variantField_9 = value;
- }
-
- set ifElement_elseElement(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.ifElement);
- _variantField_9 = value;
- }
-
- set methodDeclaration_typeParameters(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.methodDeclaration);
- _variantField_9 = value;
- }
-
- @override
- LinkedNodeBuilder get classOrMixinDeclaration_implementsClause {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.mixinDeclaration);
- return _variantField_12;
- }
-
- @override
- LinkedNodeBuilder get invocationExpression_typeArguments {
- assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
- kind == idl.LinkedNodeKind.methodInvocation);
- return _variantField_12;
- }
-
- set classOrMixinDeclaration_implementsClause(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.mixinDeclaration);
- _variantField_12 = value;
- }
-
- set invocationExpression_typeArguments(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
- kind == idl.LinkedNodeKind.methodInvocation);
- _variantField_12 = value;
- }
-
- @override
- List<LinkedNodeBuilder> get classOrMixinDeclaration_members {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.mixinDeclaration);
- return _variantField_5 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get extensionDeclaration_members {
- assert(kind == idl.LinkedNodeKind.extensionDeclaration);
- return _variantField_5 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get forParts_updaters {
- assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
- kind == idl.LinkedNodeKind.forPartsWithExpression);
- return _variantField_5 ??= <LinkedNodeBuilder>[];
- }
-
- set classOrMixinDeclaration_members(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.mixinDeclaration);
- _variantField_5 = value;
- }
-
- set extensionDeclaration_members(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.extensionDeclaration);
- _variantField_5 = value;
- }
-
- set forParts_updaters(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
- kind == idl.LinkedNodeKind.forPartsWithExpression);
- _variantField_5 = value;
- }
-
- @override
- LinkedNodeBuilder get classOrMixinDeclaration_typeParameters {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.mixinDeclaration);
- return _variantField_13;
- }
-
- set classOrMixinDeclaration_typeParameters(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.mixinDeclaration);
- _variantField_13 = value;
- }
-
- @override
- List<String> get comment_tokens {
- assert(kind == idl.LinkedNodeKind.comment);
- return _variantField_33 ??= <String>[];
- }
-
- set comment_tokens(List<String> value) {
- assert(kind == idl.LinkedNodeKind.comment);
- _variantField_33 = value;
- }
-
- @override
- idl.LinkedNodeCommentType get comment_type {
- assert(kind == idl.LinkedNodeKind.comment);
- return _variantField_29 ??= idl.LinkedNodeCommentType.block;
- }
-
- set comment_type(idl.LinkedNodeCommentType value) {
- assert(kind == idl.LinkedNodeKind.comment);
- _variantField_29 = value;
- }
-
- @override
- List<LinkedNodeBuilder> get compilationUnit_directives {
- assert(kind == idl.LinkedNodeKind.compilationUnit);
- return _variantField_3 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get listLiteral_elements {
- assert(kind == idl.LinkedNodeKind.listLiteral);
- return _variantField_3 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get namespaceDirective_configurations {
- assert(kind == idl.LinkedNodeKind.exportDirective ||
- kind == idl.LinkedNodeKind.importDirective);
- return _variantField_3 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get setOrMapLiteral_elements {
- assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
- return _variantField_3 ??= <LinkedNodeBuilder>[];
- }
-
- @override
- List<LinkedNodeBuilder> get switchMember_labels {
- assert(kind == idl.LinkedNodeKind.switchCase ||
- kind == idl.LinkedNodeKind.switchDefault);
- return _variantField_3 ??= <LinkedNodeBuilder>[];
- }
-
- set compilationUnit_directives(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.compilationUnit);
- _variantField_3 = value;
- }
-
- set listLiteral_elements(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.listLiteral);
- _variantField_3 = value;
- }
-
- set namespaceDirective_configurations(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.exportDirective ||
- kind == idl.LinkedNodeKind.importDirective);
- _variantField_3 = value;
- }
-
- set setOrMapLiteral_elements(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
- _variantField_3 = value;
- }
-
- set switchMember_labels(List<LinkedNodeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.switchCase ||
- kind == idl.LinkedNodeKind.switchDefault);
- _variantField_3 = value;
- }
-
- @override
- List<int> get compilationUnit_featureSet {
- assert(kind == idl.LinkedNodeKind.compilationUnit);
- return _variantField_41 ??= <int>[];
- }
-
- set compilationUnit_featureSet(List<int> value) {
- assert(kind == idl.LinkedNodeKind.compilationUnit);
- assert(value == null || value.every((e) => e >= 0));
- _variantField_41 = value;
- }
-
- @override
- LinkedLibraryLanguageVersionBuilder get compilationUnit_languageVersion {
- assert(kind == idl.LinkedNodeKind.compilationUnit);
- return _variantField_40;
- }
-
- /// The language version information.
- set compilationUnit_languageVersion(
- LinkedLibraryLanguageVersionBuilder value) {
- assert(kind == idl.LinkedNodeKind.compilationUnit);
- _variantField_40 = value;
- }
-
- @override
- LinkedNodeBuilder get constructorDeclaration_returnType {
- assert(kind == idl.LinkedNodeKind.constructorDeclaration);
- return _variantField_10;
- }
-
- set constructorDeclaration_returnType(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.constructorDeclaration);
- _variantField_10 = value;
- }
-
- @override
- idl.LinkedNodeFormalParameterKind get defaultFormalParameter_kind {
- assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
- return _variantField_26 ??=
- idl.LinkedNodeFormalParameterKind.requiredPositional;
- }
-
- set defaultFormalParameter_kind(idl.LinkedNodeFormalParameterKind value) {
- assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
- _variantField_26 = value;
- }
-
- @override
- double get doubleLiteral_value {
- assert(kind == idl.LinkedNodeKind.doubleLiteral);
- return _variantField_21 ??= 0.0;
- }
-
- set doubleLiteral_value(double value) {
- assert(kind == idl.LinkedNodeKind.doubleLiteral);
- _variantField_21 = value;
- }
-
- @override
- LinkedNodeTypeBuilder get expression_type {
- assert(kind == idl.LinkedNodeKind.assignmentExpression ||
- kind == idl.LinkedNodeKind.asExpression ||
- kind == idl.LinkedNodeKind.awaitExpression ||
- kind == idl.LinkedNodeKind.binaryExpression ||
- kind == idl.LinkedNodeKind.cascadeExpression ||
- kind == idl.LinkedNodeKind.conditionalExpression ||
- kind == idl.LinkedNodeKind.functionExpressionInvocation ||
- kind == idl.LinkedNodeKind.indexExpression ||
- kind == idl.LinkedNodeKind.instanceCreationExpression ||
- kind == idl.LinkedNodeKind.integerLiteral ||
- kind == idl.LinkedNodeKind.listLiteral ||
- kind == idl.LinkedNodeKind.methodInvocation ||
- kind == idl.LinkedNodeKind.nullLiteral ||
- kind == idl.LinkedNodeKind.parenthesizedExpression ||
- kind == idl.LinkedNodeKind.prefixExpression ||
- kind == idl.LinkedNodeKind.prefixedIdentifier ||
- kind == idl.LinkedNodeKind.propertyAccess ||
- kind == idl.LinkedNodeKind.postfixExpression ||
- kind == idl.LinkedNodeKind.rethrowExpression ||
- kind == idl.LinkedNodeKind.setOrMapLiteral ||
- kind == idl.LinkedNodeKind.simpleIdentifier ||
- kind == idl.LinkedNodeKind.superExpression ||
- kind == idl.LinkedNodeKind.symbolLiteral ||
- kind == idl.LinkedNodeKind.thisExpression ||
- kind == idl.LinkedNodeKind.throwExpression);
- return _variantField_25;
- }
-
- @override
- LinkedNodeTypeBuilder get genericFunctionType_type {
- assert(kind == idl.LinkedNodeKind.genericFunctionType);
- return _variantField_25;
- }
-
- set expression_type(LinkedNodeTypeBuilder value) {
- assert(kind == idl.LinkedNodeKind.assignmentExpression ||
- kind == idl.LinkedNodeKind.asExpression ||
- kind == idl.LinkedNodeKind.awaitExpression ||
- kind == idl.LinkedNodeKind.binaryExpression ||
- kind == idl.LinkedNodeKind.cascadeExpression ||
- kind == idl.LinkedNodeKind.conditionalExpression ||
- kind == idl.LinkedNodeKind.functionExpressionInvocation ||
- kind == idl.LinkedNodeKind.indexExpression ||
- kind == idl.LinkedNodeKind.instanceCreationExpression ||
- kind == idl.LinkedNodeKind.integerLiteral ||
- kind == idl.LinkedNodeKind.listLiteral ||
- kind == idl.LinkedNodeKind.methodInvocation ||
- kind == idl.LinkedNodeKind.nullLiteral ||
- kind == idl.LinkedNodeKind.parenthesizedExpression ||
- kind == idl.LinkedNodeKind.prefixExpression ||
- kind == idl.LinkedNodeKind.prefixedIdentifier ||
- kind == idl.LinkedNodeKind.propertyAccess ||
- kind == idl.LinkedNodeKind.postfixExpression ||
- kind == idl.LinkedNodeKind.rethrowExpression ||
- kind == idl.LinkedNodeKind.setOrMapLiteral ||
- kind == idl.LinkedNodeKind.simpleIdentifier ||
- kind == idl.LinkedNodeKind.superExpression ||
- kind == idl.LinkedNodeKind.symbolLiteral ||
- kind == idl.LinkedNodeKind.thisExpression ||
- kind == idl.LinkedNodeKind.throwExpression);
- _variantField_25 = value;
- }
-
- set genericFunctionType_type(LinkedNodeTypeBuilder value) {
- assert(kind == idl.LinkedNodeKind.genericFunctionType);
- _variantField_25 = value;
- }
-
- @override
- String get extensionDeclaration_refName {
- assert(kind == idl.LinkedNodeKind.extensionDeclaration);
- return _variantField_20 ??= '';
- }
-
- @override
- String get namespaceDirective_selectedUri {
- assert(kind == idl.LinkedNodeKind.exportDirective ||
- kind == idl.LinkedNodeKind.importDirective);
- return _variantField_20 ??= '';
- }
-
- @override
- String get simpleStringLiteral_value {
- assert(kind == idl.LinkedNodeKind.simpleStringLiteral);
- return _variantField_20 ??= '';
- }
-
- set extensionDeclaration_refName(String value) {
- assert(kind == idl.LinkedNodeKind.extensionDeclaration);
- _variantField_20 = value;
- }
-
- set namespaceDirective_selectedUri(String value) {
- assert(kind == idl.LinkedNodeKind.exportDirective ||
- kind == idl.LinkedNodeKind.importDirective);
- _variantField_20 = value;
- }
-
- set simpleStringLiteral_value(String value) {
- assert(kind == idl.LinkedNodeKind.simpleStringLiteral);
- _variantField_20 = value;
- }
-
- @override
- List<LinkedNodeTypeBuilder> get extensionOverride_typeArgumentTypes {
- assert(kind == idl.LinkedNodeKind.extensionOverride);
- return _variantField_39 ??= <LinkedNodeTypeBuilder>[];
- }
-
- set extensionOverride_typeArgumentTypes(List<LinkedNodeTypeBuilder> value) {
- assert(kind == idl.LinkedNodeKind.extensionOverride);
- _variantField_39 = value;
- }
-
- @override
- int get flags => _flags ??= 0;
-
- set flags(int value) {
- assert(value == null || value >= 0);
- this._flags = value;
- }
-
- @override
- String get importDirective_prefix {
- assert(kind == idl.LinkedNodeKind.importDirective);
- return _variantField_1 ??= '';
- }
-
- set importDirective_prefix(String value) {
- assert(kind == idl.LinkedNodeKind.importDirective);
- _variantField_1 = value;
- }
-
- @override
- int get informativeId {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.classTypeAlias ||
- kind == idl.LinkedNodeKind.compilationUnit ||
- kind == idl.LinkedNodeKind.compilationUnit ||
- kind == idl.LinkedNodeKind.constructorDeclaration ||
- kind == idl.LinkedNodeKind.defaultFormalParameter ||
- kind == idl.LinkedNodeKind.enumConstantDeclaration ||
- kind == idl.LinkedNodeKind.enumDeclaration ||
- kind == idl.LinkedNodeKind.exportDirective ||
- kind == idl.LinkedNodeKind.extensionDeclaration ||
- kind == idl.LinkedNodeKind.fieldDeclaration ||
- kind == idl.LinkedNodeKind.fieldFormalParameter ||
- kind == idl.LinkedNodeKind.functionDeclaration ||
- kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
- kind == idl.LinkedNodeKind.functionTypeAlias ||
- kind == idl.LinkedNodeKind.genericTypeAlias ||
- kind == idl.LinkedNodeKind.hideCombinator ||
- kind == idl.LinkedNodeKind.importDirective ||
- kind == idl.LinkedNodeKind.libraryDirective ||
- kind == idl.LinkedNodeKind.methodDeclaration ||
- kind == idl.LinkedNodeKind.mixinDeclaration ||
- kind == idl.LinkedNodeKind.partDirective ||
- kind == idl.LinkedNodeKind.partOfDirective ||
- kind == idl.LinkedNodeKind.showCombinator ||
- kind == idl.LinkedNodeKind.simpleFormalParameter ||
- kind == idl.LinkedNodeKind.topLevelVariableDeclaration ||
- kind == idl.LinkedNodeKind.typeParameter ||
- kind == idl.LinkedNodeKind.variableDeclaration ||
- kind == idl.LinkedNodeKind.variableDeclarationList);
- return _variantField_36 ??= 0;
- }
-
- set informativeId(int value) {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.classTypeAlias ||
- kind == idl.LinkedNodeKind.compilationUnit ||
- kind == idl.LinkedNodeKind.compilationUnit ||
- kind == idl.LinkedNodeKind.constructorDeclaration ||
- kind == idl.LinkedNodeKind.defaultFormalParameter ||
- kind == idl.LinkedNodeKind.enumConstantDeclaration ||
- kind == idl.LinkedNodeKind.enumDeclaration ||
- kind == idl.LinkedNodeKind.exportDirective ||
- kind == idl.LinkedNodeKind.extensionDeclaration ||
- kind == idl.LinkedNodeKind.fieldDeclaration ||
- kind == idl.LinkedNodeKind.fieldFormalParameter ||
- kind == idl.LinkedNodeKind.functionDeclaration ||
- kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
- kind == idl.LinkedNodeKind.functionTypeAlias ||
- kind == idl.LinkedNodeKind.genericTypeAlias ||
- kind == idl.LinkedNodeKind.hideCombinator ||
- kind == idl.LinkedNodeKind.importDirective ||
- kind == idl.LinkedNodeKind.libraryDirective ||
- kind == idl.LinkedNodeKind.methodDeclaration ||
- kind == idl.LinkedNodeKind.mixinDeclaration ||
- kind == idl.LinkedNodeKind.partDirective ||
- kind == idl.LinkedNodeKind.partOfDirective ||
- kind == idl.LinkedNodeKind.showCombinator ||
- kind == idl.LinkedNodeKind.simpleFormalParameter ||
- kind == idl.LinkedNodeKind.topLevelVariableDeclaration ||
- kind == idl.LinkedNodeKind.typeParameter ||
- kind == idl.LinkedNodeKind.variableDeclaration ||
- kind == idl.LinkedNodeKind.variableDeclarationList);
- assert(value == null || value >= 0);
- _variantField_36 = value;
- }
-
- @override
- int get integerLiteral_value {
- assert(kind == idl.LinkedNodeKind.integerLiteral);
- return _variantField_16 ??= 0;
- }
-
- set integerLiteral_value(int value) {
- assert(kind == idl.LinkedNodeKind.integerLiteral);
- assert(value == null || value >= 0);
- _variantField_16 = value;
- }
-
- @override
- String get interpolationString_value {
- assert(kind == idl.LinkedNodeKind.interpolationString);
- return _variantField_30 ??= '';
- }
-
- set interpolationString_value(String value) {
- assert(kind == idl.LinkedNodeKind.interpolationString);
- _variantField_30 = value;
- }
-
- @override
- LinkedNodeBuilder get invocationExpression_arguments {
- assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
- kind == idl.LinkedNodeKind.methodInvocation);
- return _variantField_14;
- }
-
- @override
- LinkedNodeBuilder get uriBasedDirective_uri {
- assert(kind == idl.LinkedNodeKind.exportDirective ||
- kind == idl.LinkedNodeKind.importDirective ||
- kind == idl.LinkedNodeKind.partDirective);
- return _variantField_14;
- }
-
- set invocationExpression_arguments(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
- kind == idl.LinkedNodeKind.methodInvocation);
- _variantField_14 = value;
- }
-
- set uriBasedDirective_uri(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.exportDirective ||
- kind == idl.LinkedNodeKind.importDirective ||
- kind == idl.LinkedNodeKind.partDirective);
- _variantField_14 = value;
- }
-
- @override
- idl.LinkedNodeKind get kind => _kind ??= idl.LinkedNodeKind.adjacentStrings;
-
- set kind(idl.LinkedNodeKind value) {
- this._kind = value;
- }
-
- @override
- bool get methodDeclaration_hasOperatorEqualWithParameterTypeFromObject {
- assert(kind == idl.LinkedNodeKind.methodDeclaration);
- return _variantField_31 ??= false;
- }
-
- @override
- bool get simplyBoundable_isSimplyBounded {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.classTypeAlias ||
- kind == idl.LinkedNodeKind.functionTypeAlias ||
- kind == idl.LinkedNodeKind.genericTypeAlias ||
- kind == idl.LinkedNodeKind.mixinDeclaration);
- return _variantField_31 ??= false;
- }
-
- set methodDeclaration_hasOperatorEqualWithParameterTypeFromObject(
- bool value) {
- assert(kind == idl.LinkedNodeKind.methodDeclaration);
- _variantField_31 = value;
- }
-
- set simplyBoundable_isSimplyBounded(bool value) {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.classTypeAlias ||
- kind == idl.LinkedNodeKind.functionTypeAlias ||
- kind == idl.LinkedNodeKind.genericTypeAlias ||
- kind == idl.LinkedNodeKind.mixinDeclaration);
- _variantField_31 = value;
- }
-
- @override
- List<String> get mixinDeclaration_superInvokedNames {
- assert(kind == idl.LinkedNodeKind.mixinDeclaration);
- return _variantField_34 ??= <String>[];
- }
-
- @override
- List<String> get names {
- assert(kind == idl.LinkedNodeKind.hideCombinator ||
- kind == idl.LinkedNodeKind.showCombinator ||
- kind == idl.LinkedNodeKind.symbolLiteral);
- return _variantField_34 ??= <String>[];
- }
-
- set mixinDeclaration_superInvokedNames(List<String> value) {
- assert(kind == idl.LinkedNodeKind.mixinDeclaration);
- _variantField_34 = value;
- }
-
- set names(List<String> value) {
- assert(kind == idl.LinkedNodeKind.hideCombinator ||
- kind == idl.LinkedNodeKind.showCombinator ||
- kind == idl.LinkedNodeKind.symbolLiteral);
- _variantField_34 = value;
- }
-
- @override
- String get name => _name ??= '';
-
- set name(String value) {
- this._name = value;
- }
-
- @override
- idl.UnlinkedTokenType get spreadElement_spreadOperator {
- assert(kind == idl.LinkedNodeKind.spreadElement);
- return _variantField_35 ??= idl.UnlinkedTokenType.NOTHING;
- }
-
- set spreadElement_spreadOperator(idl.UnlinkedTokenType value) {
- assert(kind == idl.LinkedNodeKind.spreadElement);
- _variantField_35 = value;
- }
-
- @override
- TopLevelInferenceErrorBuilder get topLevelTypeInferenceError {
- assert(kind == idl.LinkedNodeKind.methodDeclaration ||
- kind == idl.LinkedNodeKind.simpleFormalParameter ||
- kind == idl.LinkedNodeKind.variableDeclaration);
- return _variantField_32;
- }
-
- set topLevelTypeInferenceError(TopLevelInferenceErrorBuilder value) {
- assert(kind == idl.LinkedNodeKind.methodDeclaration ||
- kind == idl.LinkedNodeKind.simpleFormalParameter ||
- kind == idl.LinkedNodeKind.variableDeclaration);
- _variantField_32 = value;
- }
-
- @override
- LinkedNodeTypeBuilder get typeName_type {
- assert(kind == idl.LinkedNodeKind.typeName);
- return _variantField_23;
- }
-
- @override
- LinkedNodeTypeBuilder get typeParameter_defaultType {
- assert(kind == idl.LinkedNodeKind.typeParameter);
- return _variantField_23;
- }
-
- set typeName_type(LinkedNodeTypeBuilder value) {
- assert(kind == idl.LinkedNodeKind.typeName);
- _variantField_23 = value;
- }
-
- set typeParameter_defaultType(LinkedNodeTypeBuilder value) {
- assert(kind == idl.LinkedNodeKind.typeParameter);
- _variantField_23 = value;
- }
-
- @override
- LinkedNodeBuilder get unused11 {
- assert(kind == idl.LinkedNodeKind.classDeclaration);
- return _variantField_11;
- }
-
- set unused11(LinkedNodeBuilder value) {
- assert(kind == idl.LinkedNodeKind.classDeclaration);
- _variantField_11 = value;
- }
-
- @override
- String get uriBasedDirective_uriContent {
- assert(kind == idl.LinkedNodeKind.exportDirective ||
- kind == idl.LinkedNodeKind.importDirective ||
- kind == idl.LinkedNodeKind.partDirective);
- return _variantField_22 ??= '';
- }
-
- set uriBasedDirective_uriContent(String value) {
- assert(kind == idl.LinkedNodeKind.exportDirective ||
- kind == idl.LinkedNodeKind.importDirective ||
- kind == idl.LinkedNodeKind.partDirective);
- _variantField_22 = value;
- }
-
- @override
- int get uriBasedDirective_uriElement {
- assert(kind == idl.LinkedNodeKind.exportDirective ||
- kind == idl.LinkedNodeKind.importDirective ||
- kind == idl.LinkedNodeKind.partDirective);
- return _variantField_19 ??= 0;
- }
-
- set uriBasedDirective_uriElement(int value) {
- assert(kind == idl.LinkedNodeKind.exportDirective ||
- kind == idl.LinkedNodeKind.importDirective ||
- kind == idl.LinkedNodeKind.partDirective);
- assert(value == null || value >= 0);
- _variantField_19 = value;
- }
-
- LinkedNodeBuilder.adjacentStrings({
- List<LinkedNodeBuilder> adjacentStrings_strings,
- }) : _kind = idl.LinkedNodeKind.adjacentStrings,
- _variantField_2 = adjacentStrings_strings;
-
- LinkedNodeBuilder.annotation({
- LinkedNodeBuilder annotation_arguments,
- LinkedNodeBuilder annotation_constructorName,
- int annotation_element,
- LinkedNodeBuilder annotation_name,
- LinkedNodeTypeSubstitutionBuilder annotation_substitution,
- }) : _kind = idl.LinkedNodeKind.annotation,
- _variantField_6 = annotation_arguments,
- _variantField_7 = annotation_constructorName,
- _variantField_17 = annotation_element,
- _variantField_8 = annotation_name,
- _variantField_38 = annotation_substitution;
-
- LinkedNodeBuilder.argumentList({
- List<LinkedNodeBuilder> argumentList_arguments,
- }) : _kind = idl.LinkedNodeKind.argumentList,
- _variantField_2 = argumentList_arguments;
-
- LinkedNodeBuilder.asExpression({
- LinkedNodeBuilder asExpression_expression,
- LinkedNodeBuilder asExpression_type,
- LinkedNodeTypeBuilder expression_type,
- }) : _kind = idl.LinkedNodeKind.asExpression,
- _variantField_6 = asExpression_expression,
- _variantField_7 = asExpression_type,
- _variantField_25 = expression_type;
-
- LinkedNodeBuilder.assertInitializer({
- LinkedNodeBuilder assertInitializer_condition,
- LinkedNodeBuilder assertInitializer_message,
- }) : _kind = idl.LinkedNodeKind.assertInitializer,
- _variantField_6 = assertInitializer_condition,
- _variantField_7 = assertInitializer_message;
-
- LinkedNodeBuilder.assertStatement({
- LinkedNodeBuilder assertStatement_condition,
- LinkedNodeBuilder assertStatement_message,
- }) : _kind = idl.LinkedNodeKind.assertStatement,
- _variantField_6 = assertStatement_condition,
- _variantField_7 = assertStatement_message;
-
- LinkedNodeBuilder.assignmentExpression({
- LinkedNodeBuilder assignmentExpression_leftHandSide,
- LinkedNodeBuilder assignmentExpression_rightHandSide,
- LinkedNodeTypeSubstitutionBuilder assignmentExpression_substitution,
- int assignmentExpression_element,
- idl.UnlinkedTokenType assignmentExpression_operator,
- LinkedNodeTypeBuilder expression_type,
- }) : _kind = idl.LinkedNodeKind.assignmentExpression,
- _variantField_6 = assignmentExpression_leftHandSide,
- _variantField_7 = assignmentExpression_rightHandSide,
- _variantField_38 = assignmentExpression_substitution,
- _variantField_15 = assignmentExpression_element,
- _variantField_28 = assignmentExpression_operator,
- _variantField_25 = expression_type;
-
- LinkedNodeBuilder.awaitExpression({
- LinkedNodeBuilder awaitExpression_expression,
- LinkedNodeTypeBuilder expression_type,
- }) : _kind = idl.LinkedNodeKind.awaitExpression,
- _variantField_6 = awaitExpression_expression,
- _variantField_25 = expression_type;
-
- LinkedNodeBuilder.binaryExpression({
- LinkedNodeTypeBuilder binaryExpression_invokeType,
- LinkedNodeBuilder binaryExpression_leftOperand,
- LinkedNodeBuilder binaryExpression_rightOperand,
- LinkedNodeTypeSubstitutionBuilder binaryExpression_substitution,
- int binaryExpression_element,
- idl.UnlinkedTokenType binaryExpression_operator,
- LinkedNodeTypeBuilder expression_type,
- }) : _kind = idl.LinkedNodeKind.binaryExpression,
- _variantField_24 = binaryExpression_invokeType,
- _variantField_6 = binaryExpression_leftOperand,
- _variantField_7 = binaryExpression_rightOperand,
- _variantField_38 = binaryExpression_substitution,
- _variantField_15 = binaryExpression_element,
- _variantField_28 = binaryExpression_operator,
- _variantField_25 = expression_type;
-
- LinkedNodeBuilder.block({
- List<LinkedNodeBuilder> block_statements,
- }) : _kind = idl.LinkedNodeKind.block,
- _variantField_2 = block_statements;
-
- LinkedNodeBuilder.blockFunctionBody({
- LinkedNodeBuilder blockFunctionBody_block,
- }) : _kind = idl.LinkedNodeKind.blockFunctionBody,
- _variantField_6 = blockFunctionBody_block;
-
- LinkedNodeBuilder.booleanLiteral({
- bool booleanLiteral_value,
- }) : _kind = idl.LinkedNodeKind.booleanLiteral,
- _variantField_27 = booleanLiteral_value;
-
- LinkedNodeBuilder.breakStatement({
- LinkedNodeBuilder breakStatement_label,
- }) : _kind = idl.LinkedNodeKind.breakStatement,
- _variantField_6 = breakStatement_label;
-
- LinkedNodeBuilder.cascadeExpression({
- List<LinkedNodeBuilder> cascadeExpression_sections,
- LinkedNodeBuilder cascadeExpression_target,
- LinkedNodeTypeBuilder expression_type,
- }) : _kind = idl.LinkedNodeKind.cascadeExpression,
- _variantField_2 = cascadeExpression_sections,
- _variantField_6 = cascadeExpression_target,
- _variantField_25 = expression_type;
-
- LinkedNodeBuilder.catchClause({
- LinkedNodeBuilder catchClause_body,
- LinkedNodeBuilder catchClause_exceptionParameter,
- LinkedNodeBuilder catchClause_exceptionType,
- LinkedNodeBuilder catchClause_stackTraceParameter,
- }) : _kind = idl.LinkedNodeKind.catchClause,
- _variantField_6 = catchClause_body,
- _variantField_7 = catchClause_exceptionParameter,
- _variantField_8 = catchClause_exceptionType,
- _variantField_9 = catchClause_stackTraceParameter;
-
- LinkedNodeBuilder.classDeclaration({
- List<LinkedNodeBuilder> annotatedNode_metadata,
- LinkedNodeBuilder classDeclaration_extendsClause,
- LinkedNodeBuilder classDeclaration_withClause,
- LinkedNodeBuilder classDeclaration_nativeClause,
- bool classDeclaration_isDartObject,
- LinkedNodeBuilder classOrMixinDeclaration_implementsClause,
- List<LinkedNodeBuilder> classOrMixinDeclaration_members,
- LinkedNodeBuilder classOrMixinDeclaration_typeParameters,
- int informativeId,
- bool simplyBoundable_isSimplyBounded,
- LinkedNodeBuilder unused11,
- }) : _kind = idl.LinkedNodeKind.classDeclaration,
- _variantField_4 = annotatedNode_metadata,
- _variantField_6 = classDeclaration_extendsClause,
- _variantField_7 = classDeclaration_withClause,
- _variantField_8 = classDeclaration_nativeClause,
- _variantField_27 = classDeclaration_isDartObject,
- _variantField_12 = classOrMixinDeclaration_implementsClause,
- _variantField_5 = classOrMixinDeclaration_members,
- _variantField_13 = classOrMixinDeclaration_typeParameters,
- _variantField_36 = informativeId,
- _variantField_31 = simplyBoundable_isSimplyBounded,
- _variantField_11 = unused11;
-
- LinkedNodeBuilder.classTypeAlias({
- List<LinkedNodeBuilder> annotatedNode_metadata,
- LinkedNodeBuilder classTypeAlias_typeParameters,
- LinkedNodeBuilder classTypeAlias_superclass,
- LinkedNodeBuilder classTypeAlias_withClause,
- LinkedNodeBuilder classTypeAlias_implementsClause,
- int informativeId,
- bool simplyBoundable_isSimplyBounded,
- }) : _kind = idl.LinkedNodeKind.classTypeAlias,
- _variantField_4 = annotatedNode_metadata,
- _variantField_6 = classTypeAlias_typeParameters,
- _variantField_7 = classTypeAlias_superclass,
- _variantField_8 = classTypeAlias_withClause,
- _variantField_9 = classTypeAlias_implementsClause,
- _variantField_36 = informativeId,
- _variantField_31 = simplyBoundable_isSimplyBounded;
-
- LinkedNodeBuilder.comment({
- List<LinkedNodeBuilder> comment_references,
- List<String> comment_tokens,
- idl.LinkedNodeCommentType comment_type,
- }) : _kind = idl.LinkedNodeKind.comment,
- _variantField_2 = comment_references,
- _variantField_33 = comment_tokens,
- _variantField_29 = comment_type;
-
- LinkedNodeBuilder.commentReference({
- LinkedNodeBuilder commentReference_identifier,
- }) : _kind = idl.LinkedNodeKind.commentReference,
- _variantField_6 = commentReference_identifier;
-
- LinkedNodeBuilder.compilationUnit({
- List<LinkedNodeBuilder> compilationUnit_declarations,
- LinkedNodeBuilder compilationUnit_scriptTag,
- List<LinkedNodeBuilder> compilationUnit_directives,
- List<int> compilationUnit_featureSet,
- LinkedLibraryLanguageVersionBuilder compilationUnit_languageVersion,
- int informativeId,
- }) : _kind = idl.LinkedNodeKind.compilationUnit,
- _variantField_2 = compilationUnit_declarations,
- _variantField_6 = compilationUnit_scriptTag,
- _variantField_3 = compilationUnit_directives,
- _variantField_41 = compilationUnit_featureSet,
- _variantField_40 = compilationUnit_languageVersion,
- _variantField_36 = informativeId;
-
- LinkedNodeBuilder.conditionalExpression({
- LinkedNodeBuilder conditionalExpression_condition,
- LinkedNodeBuilder conditionalExpression_elseExpression,
- LinkedNodeBuilder conditionalExpression_thenExpression,
- LinkedNodeTypeBuilder expression_type,
- }) : _kind = idl.LinkedNodeKind.conditionalExpression,
- _variantField_6 = conditionalExpression_condition,
- _variantField_7 = conditionalExpression_elseExpression,
- _variantField_8 = conditionalExpression_thenExpression,
- _variantField_25 = expression_type;
-
- LinkedNodeBuilder.configuration({
- LinkedNodeBuilder configuration_name,
- LinkedNodeBuilder configuration_value,
- LinkedNodeBuilder configuration_uri,
- }) : _kind = idl.LinkedNodeKind.configuration,
- _variantField_6 = configuration_name,
- _variantField_7 = configuration_value,
- _variantField_8 = configuration_uri;
-
- LinkedNodeBuilder.constructorDeclaration({
- List<LinkedNodeBuilder> constructorDeclaration_initializers,
- List<LinkedNodeBuilder> annotatedNode_metadata,
- LinkedNodeBuilder constructorDeclaration_body,
- LinkedNodeBuilder constructorDeclaration_parameters,
- LinkedNodeBuilder constructorDeclaration_redirectedConstructor,
- LinkedNodeBuilder constructorDeclaration_returnType,
- int informativeId,
- }) : _kind = idl.LinkedNodeKind.constructorDeclaration,
- _variantField_2 = constructorDeclaration_initializers,
- _variantField_4 = annotatedNode_metadata,
- _variantField_6 = constructorDeclaration_body,
- _variantField_8 = constructorDeclaration_parameters,
- _variantField_9 = constructorDeclaration_redirectedConstructor,
- _variantField_10 = constructorDeclaration_returnType,
- _variantField_36 = informativeId;
-
- LinkedNodeBuilder.constructorFieldInitializer({
- LinkedNodeBuilder constructorFieldInitializer_expression,
- LinkedNodeBuilder constructorFieldInitializer_fieldName,
- }) : _kind = idl.LinkedNodeKind.constructorFieldInitializer,
- _variantField_6 = constructorFieldInitializer_expression,
- _variantField_7 = constructorFieldInitializer_fieldName;
-
- LinkedNodeBuilder.constructorName({
- LinkedNodeBuilder constructorName_name,
- LinkedNodeBuilder constructorName_type,
- LinkedNodeTypeSubstitutionBuilder constructorName_substitution,
- int constructorName_element,
- }) : _kind = idl.LinkedNodeKind.constructorName,
- _variantField_6 = constructorName_name,
- _variantField_7 = constructorName_type,
- _variantField_38 = constructorName_substitution,
- _variantField_15 = constructorName_element;
-
- LinkedNodeBuilder.continueStatement({
- LinkedNodeBuilder continueStatement_label,
- }) : _kind = idl.LinkedNodeKind.continueStatement,
- _variantField_6 = continueStatement_label;
-
- LinkedNodeBuilder.declaredIdentifier({
- List<LinkedNodeBuilder> annotatedNode_metadata,
- LinkedNodeBuilder declaredIdentifier_identifier,
- LinkedNodeBuilder declaredIdentifier_type,
- }) : _kind = idl.LinkedNodeKind.declaredIdentifier,
- _variantField_4 = annotatedNode_metadata,
- _variantField_6 = declaredIdentifier_identifier,
- _variantField_7 = declaredIdentifier_type;
-
- LinkedNodeBuilder.defaultFormalParameter({
- LinkedNodeBuilder defaultFormalParameter_defaultValue,
- LinkedNodeBuilder defaultFormalParameter_parameter,
- idl.LinkedNodeFormalParameterKind defaultFormalParameter_kind,
- int informativeId,
- }) : _kind = idl.LinkedNodeKind.defaultFormalParameter,
- _variantField_6 = defaultFormalParameter_defaultValue,
- _variantField_7 = defaultFormalParameter_parameter,
- _variantField_26 = defaultFormalParameter_kind,
- _variantField_36 = informativeId;
-
- LinkedNodeBuilder.doStatement({
- LinkedNodeBuilder doStatement_body,
- LinkedNodeBuilder doStatement_condition,
- }) : _kind = idl.LinkedNodeKind.doStatement,
- _variantField_6 = doStatement_body,
- _variantField_7 = doStatement_condition;
-
- LinkedNodeBuilder.dottedName({
- List<LinkedNodeBuilder> dottedName_components,
- }) : _kind = idl.LinkedNodeKind.dottedName,
- _variantField_2 = dottedName_components;
-
- LinkedNodeBuilder.doubleLiteral({
- double doubleLiteral_value,
- }) : _kind = idl.LinkedNodeKind.doubleLiteral,
- _variantField_21 = doubleLiteral_value;
-
- LinkedNodeBuilder.emptyFunctionBody({
- int emptyFunctionBody_fake,
- }) : _kind = idl.LinkedNodeKind.emptyFunctionBody,
- _variantField_15 = emptyFunctionBody_fake;
-
- LinkedNodeBuilder.emptyStatement({
- int emptyStatement_fake,
- }) : _kind = idl.LinkedNodeKind.emptyStatement,
- _variantField_15 = emptyStatement_fake;
-
- LinkedNodeBuilder.enumConstantDeclaration({
- List<LinkedNodeBuilder> annotatedNode_metadata,
- int informativeId,
- }) : _kind = idl.LinkedNodeKind.enumConstantDeclaration,
- _variantField_4 = annotatedNode_metadata,
- _variantField_36 = informativeId;
-
- LinkedNodeBuilder.enumDeclaration({
- List<LinkedNodeBuilder> enumDeclaration_constants,
- List<LinkedNodeBuilder> annotatedNode_metadata,
- int informativeId,
- }) : _kind = idl.LinkedNodeKind.enumDeclaration,
- _variantField_2 = enumDeclaration_constants,
- _variantField_4 = annotatedNode_metadata,
- _variantField_36 = informativeId;
-
- LinkedNodeBuilder.exportDirective({
- List<LinkedNodeBuilder> namespaceDirective_combinators,
- List<LinkedNodeBuilder> annotatedNode_metadata,
- List<LinkedNodeBuilder> namespaceDirective_configurations,
- String namespaceDirective_selectedUri,
- int informativeId,
- LinkedNodeBuilder uriBasedDirective_uri,
- String uriBasedDirective_uriContent,
- int uriBasedDirective_uriElement,
- }) : _kind = idl.LinkedNodeKind.exportDirective,
- _variantField_2 = namespaceDirective_combinators,
- _variantField_4 = annotatedNode_metadata,
- _variantField_3 = namespaceDirective_configurations,
- _variantField_20 = namespaceDirective_selectedUri,
- _variantField_36 = informativeId,
- _variantField_14 = uriBasedDirective_uri,
- _variantField_22 = uriBasedDirective_uriContent,
- _variantField_19 = uriBasedDirective_uriElement;
-
- LinkedNodeBuilder.expressionFunctionBody({
- LinkedNodeBuilder expressionFunctionBody_expression,
- }) : _kind = idl.LinkedNodeKind.expressionFunctionBody,
- _variantField_6 = expressionFunctionBody_expression;
-
- LinkedNodeBuilder.expressionStatement({
- LinkedNodeBuilder expressionStatement_expression,
- }) : _kind = idl.LinkedNodeKind.expressionStatement,
- _variantField_6 = expressionStatement_expression;
-
- LinkedNodeBuilder.extendsClause({
- LinkedNodeBuilder extendsClause_superclass,
- }) : _kind = idl.LinkedNodeKind.extendsClause,
- _variantField_6 = extendsClause_superclass;
-
- LinkedNodeBuilder.extensionDeclaration({
- List<LinkedNodeBuilder> annotatedNode_metadata,
- LinkedNodeBuilder extensionDeclaration_typeParameters,
- LinkedNodeBuilder extensionDeclaration_extendedType,
- List<LinkedNodeBuilder> extensionDeclaration_members,
- String extensionDeclaration_refName,
- int informativeId,
- }) : _kind = idl.LinkedNodeKind.extensionDeclaration,
- _variantField_4 = annotatedNode_metadata,
- _variantField_6 = extensionDeclaration_typeParameters,
- _variantField_7 = extensionDeclaration_extendedType,
- _variantField_5 = extensionDeclaration_members,
- _variantField_20 = extensionDeclaration_refName,
- _variantField_36 = informativeId;
-
- LinkedNodeBuilder.extensionOverride({
- LinkedNodeTypeBuilder extensionOverride_extendedType,
- List<LinkedNodeBuilder> extensionOverride_arguments,
- LinkedNodeBuilder extensionOverride_extensionName,
- LinkedNodeBuilder extensionOverride_typeArguments,
- List<LinkedNodeTypeBuilder> extensionOverride_typeArgumentTypes,
- }) : _kind = idl.LinkedNodeKind.extensionOverride,
- _variantField_24 = extensionOverride_extendedType,
- _variantField_2 = extensionOverride_arguments,
- _variantField_7 = extensionOverride_extensionName,
- _variantField_8 = extensionOverride_typeArguments,
- _variantField_39 = extensionOverride_typeArgumentTypes;
-
- LinkedNodeBuilder.fieldDeclaration({
- List<LinkedNodeBuilder> annotatedNode_metadata,
- LinkedNodeBuilder fieldDeclaration_fields,
- int informativeId,
- }) : _kind = idl.LinkedNodeKind.fieldDeclaration,
- _variantField_4 = annotatedNode_metadata,
- _variantField_6 = fieldDeclaration_fields,
- _variantField_36 = informativeId;
-
- LinkedNodeBuilder.fieldFormalParameter({
- LinkedNodeTypeBuilder actualType,
- List<LinkedNodeBuilder> normalFormalParameter_metadata,
- LinkedNodeBuilder fieldFormalParameter_type,
- LinkedNodeBuilder fieldFormalParameter_typeParameters,
- LinkedNodeBuilder fieldFormalParameter_formalParameters,
- bool inheritsCovariant,
- int informativeId,
- }) : _kind = idl.LinkedNodeKind.fieldFormalParameter,
- _variantField_24 = actualType,
- _variantField_4 = normalFormalParameter_metadata,
- _variantField_6 = fieldFormalParameter_type,
- _variantField_7 = fieldFormalParameter_typeParameters,
- _variantField_8 = fieldFormalParameter_formalParameters,
- _variantField_27 = inheritsCovariant,
- _variantField_36 = informativeId;
-
- LinkedNodeBuilder.forEachPartsWithDeclaration({
- LinkedNodeBuilder forEachParts_iterable,
- LinkedNodeBuilder forEachPartsWithDeclaration_loopVariable,
- }) : _kind = idl.LinkedNodeKind.forEachPartsWithDeclaration,
- _variantField_6 = forEachParts_iterable,
- _variantField_7 = forEachPartsWithDeclaration_loopVariable;
-
- LinkedNodeBuilder.forEachPartsWithIdentifier({
- LinkedNodeBuilder forEachParts_iterable,
- LinkedNodeBuilder forEachPartsWithIdentifier_identifier,
- }) : _kind = idl.LinkedNodeKind.forEachPartsWithIdentifier,
- _variantField_6 = forEachParts_iterable,
- _variantField_7 = forEachPartsWithIdentifier_identifier;
-
- LinkedNodeBuilder.forElement({
- LinkedNodeBuilder forMixin_forLoopParts,
- LinkedNodeBuilder forElement_body,
- }) : _kind = idl.LinkedNodeKind.forElement,
- _variantField_6 = forMixin_forLoopParts,
- _variantField_7 = forElement_body;
-
- LinkedNodeBuilder.forPartsWithDeclarations({
- LinkedNodeBuilder forParts_condition,
- LinkedNodeBuilder forPartsWithDeclarations_variables,
- List<LinkedNodeBuilder> forParts_updaters,
- }) : _kind = idl.LinkedNodeKind.forPartsWithDeclarations,
- _variantField_6 = forParts_condition,
- _variantField_7 = forPartsWithDeclarations_variables,
- _variantField_5 = forParts_updaters;
-
- LinkedNodeBuilder.forPartsWithExpression({
- LinkedNodeBuilder forParts_condition,
- LinkedNodeBuilder forPartsWithExpression_initialization,
- List<LinkedNodeBuilder> forParts_updaters,
- }) : _kind = idl.LinkedNodeKind.forPartsWithExpression,
- _variantField_6 = forParts_condition,
- _variantField_7 = forPartsWithExpression_initialization,
- _variantField_5 = forParts_updaters;
-
- LinkedNodeBuilder.forStatement({
- LinkedNodeBuilder forMixin_forLoopParts,
- LinkedNodeBuilder forStatement_body,
- }) : _kind = idl.LinkedNodeKind.forStatement,
- _variantField_6 = forMixin_forLoopParts,
- _variantField_7 = forStatement_body;
-
- LinkedNodeBuilder.formalParameterList({
- List<LinkedNodeBuilder> formalParameterList_parameters,
- }) : _kind = idl.LinkedNodeKind.formalParameterList,
- _variantField_2 = formalParameterList_parameters;
-
- LinkedNodeBuilder.functionDeclaration({
- LinkedNodeTypeBuilder actualReturnType,
- List<LinkedNodeBuilder> annotatedNode_metadata,
- LinkedNodeBuilder functionDeclaration_functionExpression,
- LinkedNodeBuilder functionDeclaration_returnType,
- int informativeId,
- }) : _kind = idl.LinkedNodeKind.functionDeclaration,
- _variantField_24 = actualReturnType,
- _variantField_4 = annotatedNode_metadata,
- _variantField_6 = functionDeclaration_functionExpression,
- _variantField_7 = functionDeclaration_returnType,
- _variantField_36 = informativeId;
-
- LinkedNodeBuilder.functionDeclarationStatement({
- LinkedNodeBuilder functionDeclarationStatement_functionDeclaration,
- }) : _kind = idl.LinkedNodeKind.functionDeclarationStatement,
- _variantField_6 = functionDeclarationStatement_functionDeclaration;
-
- LinkedNodeBuilder.functionExpression({
- LinkedNodeTypeBuilder actualReturnType,
- LinkedNodeBuilder functionExpression_body,
- LinkedNodeBuilder functionExpression_formalParameters,
- LinkedNodeBuilder functionExpression_typeParameters,
- }) : _kind = idl.LinkedNodeKind.functionExpression,
- _variantField_24 = actualReturnType,
- _variantField_6 = functionExpression_body,
- _variantField_7 = functionExpression_formalParameters,
- _variantField_8 = functionExpression_typeParameters;
-
- LinkedNodeBuilder.functionExpressionInvocation({
- LinkedNodeTypeBuilder invocationExpression_invokeType,
- LinkedNodeBuilder functionExpressionInvocation_function,
- LinkedNodeBuilder invocationExpression_typeArguments,
- LinkedNodeTypeBuilder expression_type,
- LinkedNodeBuilder invocationExpression_arguments,
- }) : _kind = idl.LinkedNodeKind.functionExpressionInvocation,
- _variantField_24 = invocationExpression_invokeType,
- _variantField_6 = functionExpressionInvocation_function,
- _variantField_12 = invocationExpression_typeArguments,
- _variantField_25 = expression_type,
- _variantField_14 = invocationExpression_arguments;
-
- LinkedNodeBuilder.functionTypeAlias({
- LinkedNodeTypeBuilder actualReturnType,
- List<LinkedNodeBuilder> annotatedNode_metadata,
- LinkedNodeBuilder functionTypeAlias_formalParameters,
- LinkedNodeBuilder functionTypeAlias_returnType,
- LinkedNodeBuilder functionTypeAlias_typeParameters,
- bool typeAlias_hasSelfReference,
- int informativeId,
- bool simplyBoundable_isSimplyBounded,
- }) : _kind = idl.LinkedNodeKind.functionTypeAlias,
- _variantField_24 = actualReturnType,
- _variantField_4 = annotatedNode_metadata,
- _variantField_6 = functionTypeAlias_formalParameters,
- _variantField_7 = functionTypeAlias_returnType,
- _variantField_8 = functionTypeAlias_typeParameters,
- _variantField_27 = typeAlias_hasSelfReference,
- _variantField_36 = informativeId,
- _variantField_31 = simplyBoundable_isSimplyBounded;
-
- LinkedNodeBuilder.functionTypedFormalParameter({
- LinkedNodeTypeBuilder actualType,
- List<LinkedNodeBuilder> normalFormalParameter_metadata,
- LinkedNodeBuilder functionTypedFormalParameter_formalParameters,
- LinkedNodeBuilder functionTypedFormalParameter_returnType,
- LinkedNodeBuilder functionTypedFormalParameter_typeParameters,
- bool inheritsCovariant,
- int informativeId,
- }) : _kind = idl.LinkedNodeKind.functionTypedFormalParameter,
- _variantField_24 = actualType,
- _variantField_4 = normalFormalParameter_metadata,
- _variantField_6 = functionTypedFormalParameter_formalParameters,
- _variantField_7 = functionTypedFormalParameter_returnType,
- _variantField_8 = functionTypedFormalParameter_typeParameters,
- _variantField_27 = inheritsCovariant,
- _variantField_36 = informativeId;
-
- LinkedNodeBuilder.genericFunctionType({
- LinkedNodeTypeBuilder actualReturnType,
- LinkedNodeBuilder genericFunctionType_typeParameters,
- LinkedNodeBuilder genericFunctionType_returnType,
- int genericFunctionType_id,
- LinkedNodeBuilder genericFunctionType_formalParameters,
- LinkedNodeTypeBuilder genericFunctionType_type,
- }) : _kind = idl.LinkedNodeKind.genericFunctionType,
- _variantField_24 = actualReturnType,
- _variantField_6 = genericFunctionType_typeParameters,
- _variantField_7 = genericFunctionType_returnType,
- _variantField_17 = genericFunctionType_id,
- _variantField_8 = genericFunctionType_formalParameters,
- _variantField_25 = genericFunctionType_type;
-
- LinkedNodeBuilder.genericTypeAlias({
- List<LinkedNodeBuilder> annotatedNode_metadata,
- LinkedNodeBuilder genericTypeAlias_typeParameters,
- LinkedNodeBuilder genericTypeAlias_functionType,
- bool typeAlias_hasSelfReference,
- int informativeId,
- bool simplyBoundable_isSimplyBounded,
- }) : _kind = idl.LinkedNodeKind.genericTypeAlias,
- _variantField_4 = annotatedNode_metadata,
- _variantField_6 = genericTypeAlias_typeParameters,
- _variantField_7 = genericTypeAlias_functionType,
- _variantField_27 = typeAlias_hasSelfReference,
- _variantField_36 = informativeId,
- _variantField_31 = simplyBoundable_isSimplyBounded;
-
- LinkedNodeBuilder.hideCombinator({
- int informativeId,
- List<String> names,
- }) : _kind = idl.LinkedNodeKind.hideCombinator,
- _variantField_36 = informativeId,
- _variantField_34 = names;
-
- LinkedNodeBuilder.ifElement({
- LinkedNodeBuilder ifMixin_condition,
- LinkedNodeBuilder ifElement_thenElement,
- LinkedNodeBuilder ifElement_elseElement,
- }) : _kind = idl.LinkedNodeKind.ifElement,
- _variantField_6 = ifMixin_condition,
- _variantField_8 = ifElement_thenElement,
- _variantField_9 = ifElement_elseElement;
-
- LinkedNodeBuilder.ifStatement({
- LinkedNodeBuilder ifMixin_condition,
- LinkedNodeBuilder ifStatement_elseStatement,
- LinkedNodeBuilder ifStatement_thenStatement,
- }) : _kind = idl.LinkedNodeKind.ifStatement,
- _variantField_6 = ifMixin_condition,
- _variantField_7 = ifStatement_elseStatement,
- _variantField_8 = ifStatement_thenStatement;
-
- LinkedNodeBuilder.implementsClause({
- List<LinkedNodeBuilder> implementsClause_interfaces,
- }) : _kind = idl.LinkedNodeKind.implementsClause,
- _variantField_2 = implementsClause_interfaces;
-
- LinkedNodeBuilder.importDirective({
- List<LinkedNodeBuilder> namespaceDirective_combinators,
- List<LinkedNodeBuilder> annotatedNode_metadata,
- List<LinkedNodeBuilder> namespaceDirective_configurations,
- String namespaceDirective_selectedUri,
- String importDirective_prefix,
- int informativeId,
- LinkedNodeBuilder uriBasedDirective_uri,
- String uriBasedDirective_uriContent,
- int uriBasedDirective_uriElement,
- }) : _kind = idl.LinkedNodeKind.importDirective,
- _variantField_2 = namespaceDirective_combinators,
- _variantField_4 = annotatedNode_metadata,
- _variantField_3 = namespaceDirective_configurations,
- _variantField_20 = namespaceDirective_selectedUri,
- _variantField_1 = importDirective_prefix,
- _variantField_36 = informativeId,
- _variantField_14 = uriBasedDirective_uri,
- _variantField_22 = uriBasedDirective_uriContent,
- _variantField_19 = uriBasedDirective_uriElement;
-
- LinkedNodeBuilder.indexExpression({
- LinkedNodeBuilder indexExpression_index,
- LinkedNodeBuilder indexExpression_target,
- LinkedNodeTypeSubstitutionBuilder indexExpression_substitution,
- int indexExpression_element,
- LinkedNodeTypeBuilder expression_type,
- }) : _kind = idl.LinkedNodeKind.indexExpression,
- _variantField_6 = indexExpression_index,
- _variantField_7 = indexExpression_target,
- _variantField_38 = indexExpression_substitution,
- _variantField_15 = indexExpression_element,
- _variantField_25 = expression_type;
-
- LinkedNodeBuilder.instanceCreationExpression({
- List<LinkedNodeBuilder> instanceCreationExpression_arguments,
- LinkedNodeBuilder instanceCreationExpression_constructorName,
- LinkedNodeBuilder instanceCreationExpression_typeArguments,
- LinkedNodeTypeBuilder expression_type,
- }) : _kind = idl.LinkedNodeKind.instanceCreationExpression,
- _variantField_2 = instanceCreationExpression_arguments,
- _variantField_7 = instanceCreationExpression_constructorName,
- _variantField_8 = instanceCreationExpression_typeArguments,
- _variantField_25 = expression_type;
-
- LinkedNodeBuilder.integerLiteral({
- LinkedNodeTypeBuilder expression_type,
- int integerLiteral_value,
- }) : _kind = idl.LinkedNodeKind.integerLiteral,
- _variantField_25 = expression_type,
- _variantField_16 = integerLiteral_value;
-
- LinkedNodeBuilder.interpolationExpression({
- LinkedNodeBuilder interpolationExpression_expression,
- }) : _kind = idl.LinkedNodeKind.interpolationExpression,
- _variantField_6 = interpolationExpression_expression;
-
- LinkedNodeBuilder.interpolationString({
- String interpolationString_value,
- }) : _kind = idl.LinkedNodeKind.interpolationString,
- _variantField_30 = interpolationString_value;
-
- LinkedNodeBuilder.isExpression({
- LinkedNodeBuilder isExpression_expression,
- LinkedNodeBuilder isExpression_type,
- }) : _kind = idl.LinkedNodeKind.isExpression,
- _variantField_6 = isExpression_expression,
- _variantField_7 = isExpression_type;
-
- LinkedNodeBuilder.label({
- LinkedNodeBuilder label_label,
- }) : _kind = idl.LinkedNodeKind.label,
- _variantField_6 = label_label;
-
- LinkedNodeBuilder.labeledStatement({
- List<LinkedNodeBuilder> labeledStatement_labels,
- LinkedNodeBuilder labeledStatement_statement,
- }) : _kind = idl.LinkedNodeKind.labeledStatement,
- _variantField_2 = labeledStatement_labels,
- _variantField_6 = labeledStatement_statement;
-
- LinkedNodeBuilder.libraryDirective({
- List<LinkedNodeBuilder> annotatedNode_metadata,
- LinkedNodeBuilder libraryDirective_name,
- int informativeId,
- }) : _kind = idl.LinkedNodeKind.libraryDirective,
- _variantField_4 = annotatedNode_metadata,
- _variantField_6 = libraryDirective_name,
- _variantField_36 = informativeId;
-
- LinkedNodeBuilder.libraryIdentifier({
- List<LinkedNodeBuilder> libraryIdentifier_components,
- }) : _kind = idl.LinkedNodeKind.libraryIdentifier,
- _variantField_2 = libraryIdentifier_components;
-
- LinkedNodeBuilder.listLiteral({
- List<LinkedNodeBuilder> typedLiteral_typeArguments,
- List<LinkedNodeBuilder> listLiteral_elements,
- LinkedNodeTypeBuilder expression_type,
- }) : _kind = idl.LinkedNodeKind.listLiteral,
- _variantField_2 = typedLiteral_typeArguments,
- _variantField_3 = listLiteral_elements,
- _variantField_25 = expression_type;
-
- LinkedNodeBuilder.mapLiteralEntry({
- LinkedNodeBuilder mapLiteralEntry_key,
- LinkedNodeBuilder mapLiteralEntry_value,
- }) : _kind = idl.LinkedNodeKind.mapLiteralEntry,
- _variantField_6 = mapLiteralEntry_key,
- _variantField_7 = mapLiteralEntry_value;
-
- LinkedNodeBuilder.methodDeclaration({
- LinkedNodeTypeBuilder actualReturnType,
- List<LinkedNodeBuilder> annotatedNode_metadata,
- LinkedNodeBuilder methodDeclaration_body,
- LinkedNodeBuilder methodDeclaration_formalParameters,
- LinkedNodeBuilder methodDeclaration_returnType,
- LinkedNodeBuilder methodDeclaration_typeParameters,
- int informativeId,
- bool methodDeclaration_hasOperatorEqualWithParameterTypeFromObject,
- TopLevelInferenceErrorBuilder topLevelTypeInferenceError,
- }) : _kind = idl.LinkedNodeKind.methodDeclaration,
- _variantField_24 = actualReturnType,
- _variantField_4 = annotatedNode_metadata,
- _variantField_6 = methodDeclaration_body,
- _variantField_7 = methodDeclaration_formalParameters,
- _variantField_8 = methodDeclaration_returnType,
- _variantField_9 = methodDeclaration_typeParameters,
- _variantField_36 = informativeId,
- _variantField_31 =
- methodDeclaration_hasOperatorEqualWithParameterTypeFromObject,
- _variantField_32 = topLevelTypeInferenceError;
-
- LinkedNodeBuilder.methodInvocation({
- LinkedNodeTypeBuilder invocationExpression_invokeType,
- LinkedNodeBuilder methodInvocation_methodName,
- LinkedNodeBuilder methodInvocation_target,
- LinkedNodeBuilder invocationExpression_typeArguments,
- LinkedNodeTypeBuilder expression_type,
- LinkedNodeBuilder invocationExpression_arguments,
- }) : _kind = idl.LinkedNodeKind.methodInvocation,
- _variantField_24 = invocationExpression_invokeType,
- _variantField_6 = methodInvocation_methodName,
- _variantField_7 = methodInvocation_target,
- _variantField_12 = invocationExpression_typeArguments,
- _variantField_25 = expression_type,
- _variantField_14 = invocationExpression_arguments;
-
- LinkedNodeBuilder.mixinDeclaration({
- List<LinkedNodeBuilder> annotatedNode_metadata,
- LinkedNodeBuilder mixinDeclaration_onClause,
- LinkedNodeBuilder classOrMixinDeclaration_implementsClause,
- List<LinkedNodeBuilder> classOrMixinDeclaration_members,
- LinkedNodeBuilder classOrMixinDeclaration_typeParameters,
- int informativeId,
- bool simplyBoundable_isSimplyBounded,
- List<String> mixinDeclaration_superInvokedNames,
- }) : _kind = idl.LinkedNodeKind.mixinDeclaration,
- _variantField_4 = annotatedNode_metadata,
- _variantField_6 = mixinDeclaration_onClause,
- _variantField_12 = classOrMixinDeclaration_implementsClause,
- _variantField_5 = classOrMixinDeclaration_members,
- _variantField_13 = classOrMixinDeclaration_typeParameters,
- _variantField_36 = informativeId,
- _variantField_31 = simplyBoundable_isSimplyBounded,
- _variantField_34 = mixinDeclaration_superInvokedNames;
-
- LinkedNodeBuilder.namedExpression({
- LinkedNodeBuilder namedExpression_expression,
- LinkedNodeBuilder namedExpression_name,
- }) : _kind = idl.LinkedNodeKind.namedExpression,
- _variantField_6 = namedExpression_expression,
- _variantField_7 = namedExpression_name;
-
- LinkedNodeBuilder.nativeClause({
- LinkedNodeBuilder nativeClause_name,
- }) : _kind = idl.LinkedNodeKind.nativeClause,
- _variantField_6 = nativeClause_name;
-
- LinkedNodeBuilder.nativeFunctionBody({
- LinkedNodeBuilder nativeFunctionBody_stringLiteral,
- }) : _kind = idl.LinkedNodeKind.nativeFunctionBody,
- _variantField_6 = nativeFunctionBody_stringLiteral;
-
- LinkedNodeBuilder.nullLiteral({
- int nullLiteral_fake,
- LinkedNodeTypeBuilder expression_type,
- }) : _kind = idl.LinkedNodeKind.nullLiteral,
- _variantField_15 = nullLiteral_fake,
- _variantField_25 = expression_type;
-
- LinkedNodeBuilder.onClause({
- List<LinkedNodeBuilder> onClause_superclassConstraints,
- }) : _kind = idl.LinkedNodeKind.onClause,
- _variantField_2 = onClause_superclassConstraints;
-
- LinkedNodeBuilder.parenthesizedExpression({
- LinkedNodeBuilder parenthesizedExpression_expression,
- LinkedNodeTypeBuilder expression_type,
- }) : _kind = idl.LinkedNodeKind.parenthesizedExpression,
- _variantField_6 = parenthesizedExpression_expression,
- _variantField_25 = expression_type;
-
- LinkedNodeBuilder.partDirective({
- List<LinkedNodeBuilder> annotatedNode_metadata,
- int informativeId,
- LinkedNodeBuilder uriBasedDirective_uri,
- String uriBasedDirective_uriContent,
- int uriBasedDirective_uriElement,
- }) : _kind = idl.LinkedNodeKind.partDirective,
- _variantField_4 = annotatedNode_metadata,
- _variantField_36 = informativeId,
- _variantField_14 = uriBasedDirective_uri,
- _variantField_22 = uriBasedDirective_uriContent,
- _variantField_19 = uriBasedDirective_uriElement;
-
- LinkedNodeBuilder.partOfDirective({
- List<LinkedNodeBuilder> annotatedNode_metadata,
- LinkedNodeBuilder partOfDirective_libraryName,
- LinkedNodeBuilder partOfDirective_uri,
- int informativeId,
- }) : _kind = idl.LinkedNodeKind.partOfDirective,
- _variantField_4 = annotatedNode_metadata,
- _variantField_6 = partOfDirective_libraryName,
- _variantField_7 = partOfDirective_uri,
- _variantField_36 = informativeId;
-
- LinkedNodeBuilder.postfixExpression({
- LinkedNodeBuilder postfixExpression_operand,
- LinkedNodeTypeSubstitutionBuilder postfixExpression_substitution,
- int postfixExpression_element,
- idl.UnlinkedTokenType postfixExpression_operator,
- LinkedNodeTypeBuilder expression_type,
- }) : _kind = idl.LinkedNodeKind.postfixExpression,
- _variantField_6 = postfixExpression_operand,
- _variantField_38 = postfixExpression_substitution,
- _variantField_15 = postfixExpression_element,
- _variantField_28 = postfixExpression_operator,
- _variantField_25 = expression_type;
-
- LinkedNodeBuilder.prefixExpression({
- LinkedNodeBuilder prefixExpression_operand,
- LinkedNodeTypeSubstitutionBuilder prefixExpression_substitution,
- int prefixExpression_element,
- idl.UnlinkedTokenType prefixExpression_operator,
- LinkedNodeTypeBuilder expression_type,
- }) : _kind = idl.LinkedNodeKind.prefixExpression,
- _variantField_6 = prefixExpression_operand,
- _variantField_38 = prefixExpression_substitution,
- _variantField_15 = prefixExpression_element,
- _variantField_28 = prefixExpression_operator,
- _variantField_25 = expression_type;
-
- LinkedNodeBuilder.prefixedIdentifier({
- LinkedNodeBuilder prefixedIdentifier_identifier,
- LinkedNodeBuilder prefixedIdentifier_prefix,
- LinkedNodeTypeBuilder expression_type,
- }) : _kind = idl.LinkedNodeKind.prefixedIdentifier,
- _variantField_6 = prefixedIdentifier_identifier,
- _variantField_7 = prefixedIdentifier_prefix,
- _variantField_25 = expression_type;
-
- LinkedNodeBuilder.propertyAccess({
- LinkedNodeBuilder propertyAccess_propertyName,
- LinkedNodeBuilder propertyAccess_target,
- idl.UnlinkedTokenType propertyAccess_operator,
- LinkedNodeTypeBuilder expression_type,
- }) : _kind = idl.LinkedNodeKind.propertyAccess,
- _variantField_6 = propertyAccess_propertyName,
- _variantField_7 = propertyAccess_target,
- _variantField_28 = propertyAccess_operator,
- _variantField_25 = expression_type;
-
- LinkedNodeBuilder.redirectingConstructorInvocation({
- LinkedNodeBuilder redirectingConstructorInvocation_arguments,
- LinkedNodeBuilder redirectingConstructorInvocation_constructorName,
- LinkedNodeTypeSubstitutionBuilder
- redirectingConstructorInvocation_substitution,
- int redirectingConstructorInvocation_element,
- }) : _kind = idl.LinkedNodeKind.redirectingConstructorInvocation,
- _variantField_6 = redirectingConstructorInvocation_arguments,
- _variantField_7 = redirectingConstructorInvocation_constructorName,
- _variantField_38 = redirectingConstructorInvocation_substitution,
- _variantField_15 = redirectingConstructorInvocation_element;
-
- LinkedNodeBuilder.rethrowExpression({
- LinkedNodeTypeBuilder expression_type,
- }) : _kind = idl.LinkedNodeKind.rethrowExpression,
- _variantField_25 = expression_type;
-
- LinkedNodeBuilder.returnStatement({
- LinkedNodeBuilder returnStatement_expression,
- }) : _kind = idl.LinkedNodeKind.returnStatement,
- _variantField_6 = returnStatement_expression;
-
- LinkedNodeBuilder.setOrMapLiteral({
- List<LinkedNodeBuilder> typedLiteral_typeArguments,
- List<LinkedNodeBuilder> setOrMapLiteral_elements,
- LinkedNodeTypeBuilder expression_type,
- }) : _kind = idl.LinkedNodeKind.setOrMapLiteral,
- _variantField_2 = typedLiteral_typeArguments,
- _variantField_3 = setOrMapLiteral_elements,
- _variantField_25 = expression_type;
-
- LinkedNodeBuilder.showCombinator({
- int informativeId,
- List<String> names,
- }) : _kind = idl.LinkedNodeKind.showCombinator,
- _variantField_36 = informativeId,
- _variantField_34 = names;
-
- LinkedNodeBuilder.simpleFormalParameter({
- LinkedNodeTypeBuilder actualType,
- List<LinkedNodeBuilder> normalFormalParameter_metadata,
- LinkedNodeBuilder simpleFormalParameter_type,
- bool inheritsCovariant,
- int informativeId,
- TopLevelInferenceErrorBuilder topLevelTypeInferenceError,
- }) : _kind = idl.LinkedNodeKind.simpleFormalParameter,
- _variantField_24 = actualType,
- _variantField_4 = normalFormalParameter_metadata,
- _variantField_6 = simpleFormalParameter_type,
- _variantField_27 = inheritsCovariant,
- _variantField_36 = informativeId,
- _variantField_32 = topLevelTypeInferenceError;
-
- LinkedNodeBuilder.simpleIdentifier({
- LinkedNodeTypeSubstitutionBuilder simpleIdentifier_substitution,
- int simpleIdentifier_element,
- LinkedNodeTypeBuilder expression_type,
- }) : _kind = idl.LinkedNodeKind.simpleIdentifier,
- _variantField_38 = simpleIdentifier_substitution,
- _variantField_15 = simpleIdentifier_element,
- _variantField_25 = expression_type;
-
- LinkedNodeBuilder.simpleStringLiteral({
- String simpleStringLiteral_value,
- }) : _kind = idl.LinkedNodeKind.simpleStringLiteral,
- _variantField_20 = simpleStringLiteral_value;
-
- LinkedNodeBuilder.spreadElement({
- LinkedNodeBuilder spreadElement_expression,
- idl.UnlinkedTokenType spreadElement_spreadOperator,
- }) : _kind = idl.LinkedNodeKind.spreadElement,
- _variantField_6 = spreadElement_expression,
- _variantField_35 = spreadElement_spreadOperator;
-
- LinkedNodeBuilder.stringInterpolation({
- List<LinkedNodeBuilder> stringInterpolation_elements,
- }) : _kind = idl.LinkedNodeKind.stringInterpolation,
- _variantField_2 = stringInterpolation_elements;
-
- LinkedNodeBuilder.superConstructorInvocation({
- LinkedNodeBuilder superConstructorInvocation_arguments,
- LinkedNodeBuilder superConstructorInvocation_constructorName,
- LinkedNodeTypeSubstitutionBuilder superConstructorInvocation_substitution,
- int superConstructorInvocation_element,
- }) : _kind = idl.LinkedNodeKind.superConstructorInvocation,
- _variantField_6 = superConstructorInvocation_arguments,
- _variantField_7 = superConstructorInvocation_constructorName,
- _variantField_38 = superConstructorInvocation_substitution,
- _variantField_15 = superConstructorInvocation_element;
-
- LinkedNodeBuilder.superExpression({
- LinkedNodeTypeBuilder expression_type,
- }) : _kind = idl.LinkedNodeKind.superExpression,
- _variantField_25 = expression_type;
-
- LinkedNodeBuilder.switchCase({
- List<LinkedNodeBuilder> switchMember_statements,
- LinkedNodeBuilder switchCase_expression,
- List<LinkedNodeBuilder> switchMember_labels,
- }) : _kind = idl.LinkedNodeKind.switchCase,
- _variantField_4 = switchMember_statements,
- _variantField_6 = switchCase_expression,
- _variantField_3 = switchMember_labels;
-
- LinkedNodeBuilder.switchDefault({
- List<LinkedNodeBuilder> switchMember_statements,
- List<LinkedNodeBuilder> switchMember_labels,
- }) : _kind = idl.LinkedNodeKind.switchDefault,
- _variantField_4 = switchMember_statements,
- _variantField_3 = switchMember_labels;
-
- LinkedNodeBuilder.switchStatement({
- List<LinkedNodeBuilder> switchStatement_members,
- LinkedNodeBuilder switchStatement_expression,
- }) : _kind = idl.LinkedNodeKind.switchStatement,
- _variantField_2 = switchStatement_members,
- _variantField_7 = switchStatement_expression;
-
- LinkedNodeBuilder.symbolLiteral({
- LinkedNodeTypeBuilder expression_type,
- List<String> names,
- }) : _kind = idl.LinkedNodeKind.symbolLiteral,
- _variantField_25 = expression_type,
- _variantField_34 = names;
-
- LinkedNodeBuilder.thisExpression({
- LinkedNodeTypeBuilder expression_type,
- }) : _kind = idl.LinkedNodeKind.thisExpression,
- _variantField_25 = expression_type;
-
- LinkedNodeBuilder.throwExpression({
- LinkedNodeBuilder throwExpression_expression,
- LinkedNodeTypeBuilder expression_type,
- }) : _kind = idl.LinkedNodeKind.throwExpression,
- _variantField_6 = throwExpression_expression,
- _variantField_25 = expression_type;
-
- LinkedNodeBuilder.topLevelVariableDeclaration({
- List<LinkedNodeBuilder> annotatedNode_metadata,
- LinkedNodeBuilder topLevelVariableDeclaration_variableList,
- int informativeId,
- }) : _kind = idl.LinkedNodeKind.topLevelVariableDeclaration,
- _variantField_4 = annotatedNode_metadata,
- _variantField_6 = topLevelVariableDeclaration_variableList,
- _variantField_36 = informativeId;
-
- LinkedNodeBuilder.tryStatement({
- List<LinkedNodeBuilder> tryStatement_catchClauses,
- LinkedNodeBuilder tryStatement_body,
- LinkedNodeBuilder tryStatement_finallyBlock,
- }) : _kind = idl.LinkedNodeKind.tryStatement,
- _variantField_2 = tryStatement_catchClauses,
- _variantField_6 = tryStatement_body,
- _variantField_7 = tryStatement_finallyBlock;
-
- LinkedNodeBuilder.typeArgumentList({
- List<LinkedNodeBuilder> typeArgumentList_arguments,
- }) : _kind = idl.LinkedNodeKind.typeArgumentList,
- _variantField_2 = typeArgumentList_arguments;
-
- LinkedNodeBuilder.typeName({
- List<LinkedNodeBuilder> typeName_typeArguments,
- LinkedNodeBuilder typeName_name,
- LinkedNodeTypeBuilder typeName_type,
- }) : _kind = idl.LinkedNodeKind.typeName,
- _variantField_2 = typeName_typeArguments,
- _variantField_6 = typeName_name,
- _variantField_23 = typeName_type;
-
- LinkedNodeBuilder.typeParameter({
- List<LinkedNodeBuilder> annotatedNode_metadata,
- LinkedNodeBuilder typeParameter_bound,
- int typeParameter_variance,
- int informativeId,
- LinkedNodeTypeBuilder typeParameter_defaultType,
- }) : _kind = idl.LinkedNodeKind.typeParameter,
- _variantField_4 = annotatedNode_metadata,
- _variantField_6 = typeParameter_bound,
- _variantField_15 = typeParameter_variance,
- _variantField_36 = informativeId,
- _variantField_23 = typeParameter_defaultType;
-
- LinkedNodeBuilder.typeParameterList({
- List<LinkedNodeBuilder> typeParameterList_typeParameters,
- }) : _kind = idl.LinkedNodeKind.typeParameterList,
- _variantField_2 = typeParameterList_typeParameters;
-
- LinkedNodeBuilder.variableDeclaration({
- LinkedNodeTypeBuilder actualType,
- List<LinkedNodeBuilder> annotatedNode_metadata,
- LinkedNodeBuilder variableDeclaration_initializer,
- bool inheritsCovariant,
- int informativeId,
- TopLevelInferenceErrorBuilder topLevelTypeInferenceError,
- }) : _kind = idl.LinkedNodeKind.variableDeclaration,
- _variantField_24 = actualType,
- _variantField_4 = annotatedNode_metadata,
- _variantField_6 = variableDeclaration_initializer,
- _variantField_27 = inheritsCovariant,
- _variantField_36 = informativeId,
- _variantField_32 = topLevelTypeInferenceError;
-
- LinkedNodeBuilder.variableDeclarationList({
- List<LinkedNodeBuilder> variableDeclarationList_variables,
- List<LinkedNodeBuilder> annotatedNode_metadata,
- LinkedNodeBuilder variableDeclarationList_type,
- int informativeId,
- }) : _kind = idl.LinkedNodeKind.variableDeclarationList,
- _variantField_2 = variableDeclarationList_variables,
- _variantField_4 = annotatedNode_metadata,
- _variantField_6 = variableDeclarationList_type,
- _variantField_36 = informativeId;
-
- LinkedNodeBuilder.variableDeclarationStatement({
- LinkedNodeBuilder variableDeclarationStatement_variables,
- }) : _kind = idl.LinkedNodeKind.variableDeclarationStatement,
- _variantField_6 = variableDeclarationStatement_variables;
-
- LinkedNodeBuilder.whileStatement({
- LinkedNodeBuilder whileStatement_body,
- LinkedNodeBuilder whileStatement_condition,
- }) : _kind = idl.LinkedNodeKind.whileStatement,
- _variantField_6 = whileStatement_body,
- _variantField_7 = whileStatement_condition;
-
- LinkedNodeBuilder.withClause({
- List<LinkedNodeBuilder> withClause_mixinTypes,
- }) : _kind = idl.LinkedNodeKind.withClause,
- _variantField_2 = withClause_mixinTypes;
-
- LinkedNodeBuilder.yieldStatement({
- LinkedNodeBuilder yieldStatement_expression,
- }) : _kind = idl.LinkedNodeKind.yieldStatement,
- _variantField_6 = yieldStatement_expression;
-
- /// Flush [informative] data recursively.
- void flushInformative() {
- if (kind == idl.LinkedNodeKind.adjacentStrings) {
- adjacentStrings_strings?.forEach((b) => b.flushInformative());
- } else if (kind == idl.LinkedNodeKind.annotation) {
- annotation_arguments?.flushInformative();
- annotation_constructorName?.flushInformative();
- annotation_name?.flushInformative();
- annotation_substitution?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.argumentList) {
- argumentList_arguments?.forEach((b) => b.flushInformative());
- } else if (kind == idl.LinkedNodeKind.asExpression) {
- asExpression_expression?.flushInformative();
- asExpression_type?.flushInformative();
- expression_type?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.assertInitializer) {
- assertInitializer_condition?.flushInformative();
- assertInitializer_message?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.assertStatement) {
- assertStatement_condition?.flushInformative();
- assertStatement_message?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.assignmentExpression) {
- assignmentExpression_leftHandSide?.flushInformative();
- assignmentExpression_rightHandSide?.flushInformative();
- assignmentExpression_substitution?.flushInformative();
- expression_type?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.awaitExpression) {
- awaitExpression_expression?.flushInformative();
- expression_type?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.binaryExpression) {
- binaryExpression_invokeType?.flushInformative();
- binaryExpression_leftOperand?.flushInformative();
- binaryExpression_rightOperand?.flushInformative();
- binaryExpression_substitution?.flushInformative();
- expression_type?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.block) {
- block_statements?.forEach((b) => b.flushInformative());
- } else if (kind == idl.LinkedNodeKind.blockFunctionBody) {
- blockFunctionBody_block?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.booleanLiteral) {
- } else if (kind == idl.LinkedNodeKind.breakStatement) {
- breakStatement_label?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.cascadeExpression) {
- cascadeExpression_sections?.forEach((b) => b.flushInformative());
- cascadeExpression_target?.flushInformative();
- expression_type?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.catchClause) {
- catchClause_body?.flushInformative();
- catchClause_exceptionParameter?.flushInformative();
- catchClause_exceptionType?.flushInformative();
- catchClause_stackTraceParameter?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.classDeclaration) {
- annotatedNode_metadata?.forEach((b) => b.flushInformative());
- classDeclaration_extendsClause?.flushInformative();
- classDeclaration_withClause?.flushInformative();
- classDeclaration_nativeClause?.flushInformative();
- classOrMixinDeclaration_implementsClause?.flushInformative();
- classOrMixinDeclaration_members?.forEach((b) => b.flushInformative());
- classOrMixinDeclaration_typeParameters?.flushInformative();
- informativeId = null;
- unused11?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.classTypeAlias) {
- annotatedNode_metadata?.forEach((b) => b.flushInformative());
- classTypeAlias_typeParameters?.flushInformative();
- classTypeAlias_superclass?.flushInformative();
- classTypeAlias_withClause?.flushInformative();
- classTypeAlias_implementsClause?.flushInformative();
- informativeId = null;
- } else if (kind == idl.LinkedNodeKind.comment) {
- comment_references?.forEach((b) => b.flushInformative());
- } else if (kind == idl.LinkedNodeKind.commentReference) {
- commentReference_identifier?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.compilationUnit) {
- compilationUnit_declarations?.forEach((b) => b.flushInformative());
- compilationUnit_scriptTag?.flushInformative();
- compilationUnit_directives?.forEach((b) => b.flushInformative());
- compilationUnit_languageVersion?.flushInformative();
- informativeId = null;
- } else if (kind == idl.LinkedNodeKind.conditionalExpression) {
- conditionalExpression_condition?.flushInformative();
- conditionalExpression_elseExpression?.flushInformative();
- conditionalExpression_thenExpression?.flushInformative();
- expression_type?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.configuration) {
- configuration_name?.flushInformative();
- configuration_value?.flushInformative();
- configuration_uri?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.constructorDeclaration) {
- constructorDeclaration_initializers?.forEach((b) => b.flushInformative());
- annotatedNode_metadata?.forEach((b) => b.flushInformative());
- constructorDeclaration_body?.flushInformative();
- constructorDeclaration_parameters?.flushInformative();
- constructorDeclaration_redirectedConstructor?.flushInformative();
- constructorDeclaration_returnType?.flushInformative();
- informativeId = null;
- } else if (kind == idl.LinkedNodeKind.constructorFieldInitializer) {
- constructorFieldInitializer_expression?.flushInformative();
- constructorFieldInitializer_fieldName?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.constructorName) {
- constructorName_name?.flushInformative();
- constructorName_type?.flushInformative();
- constructorName_substitution?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.continueStatement) {
- continueStatement_label?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.declaredIdentifier) {
- annotatedNode_metadata?.forEach((b) => b.flushInformative());
- declaredIdentifier_identifier?.flushInformative();
- declaredIdentifier_type?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.defaultFormalParameter) {
- defaultFormalParameter_defaultValue?.flushInformative();
- defaultFormalParameter_parameter?.flushInformative();
- informativeId = null;
- } else if (kind == idl.LinkedNodeKind.doStatement) {
- doStatement_body?.flushInformative();
- doStatement_condition?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.dottedName) {
- dottedName_components?.forEach((b) => b.flushInformative());
- } else if (kind == idl.LinkedNodeKind.doubleLiteral) {
- } else if (kind == idl.LinkedNodeKind.emptyFunctionBody) {
- } else if (kind == idl.LinkedNodeKind.emptyStatement) {
- } else if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
- annotatedNode_metadata?.forEach((b) => b.flushInformative());
- informativeId = null;
- } else if (kind == idl.LinkedNodeKind.enumDeclaration) {
- enumDeclaration_constants?.forEach((b) => b.flushInformative());
- annotatedNode_metadata?.forEach((b) => b.flushInformative());
- informativeId = null;
- } else if (kind == idl.LinkedNodeKind.exportDirective) {
- namespaceDirective_combinators?.forEach((b) => b.flushInformative());
- annotatedNode_metadata?.forEach((b) => b.flushInformative());
- namespaceDirective_configurations?.forEach((b) => b.flushInformative());
- informativeId = null;
- uriBasedDirective_uri?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.expressionFunctionBody) {
- expressionFunctionBody_expression?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.expressionStatement) {
- expressionStatement_expression?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.extendsClause) {
- extendsClause_superclass?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.extensionDeclaration) {
- annotatedNode_metadata?.forEach((b) => b.flushInformative());
- extensionDeclaration_typeParameters?.flushInformative();
- extensionDeclaration_extendedType?.flushInformative();
- extensionDeclaration_members?.forEach((b) => b.flushInformative());
- informativeId = null;
- } else if (kind == idl.LinkedNodeKind.extensionOverride) {
- extensionOverride_extendedType?.flushInformative();
- extensionOverride_arguments?.forEach((b) => b.flushInformative());
- extensionOverride_extensionName?.flushInformative();
- extensionOverride_typeArguments?.flushInformative();
- extensionOverride_typeArgumentTypes?.forEach((b) => b.flushInformative());
- } else if (kind == idl.LinkedNodeKind.fieldDeclaration) {
- annotatedNode_metadata?.forEach((b) => b.flushInformative());
- fieldDeclaration_fields?.flushInformative();
- informativeId = null;
- } else if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
- actualType?.flushInformative();
- normalFormalParameter_metadata?.forEach((b) => b.flushInformative());
- fieldFormalParameter_type?.flushInformative();
- fieldFormalParameter_typeParameters?.flushInformative();
- fieldFormalParameter_formalParameters?.flushInformative();
- informativeId = null;
- } else if (kind == idl.LinkedNodeKind.forEachPartsWithDeclaration) {
- forEachParts_iterable?.flushInformative();
- forEachPartsWithDeclaration_loopVariable?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.forEachPartsWithIdentifier) {
- forEachParts_iterable?.flushInformative();
- forEachPartsWithIdentifier_identifier?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.forElement) {
- forMixin_forLoopParts?.flushInformative();
- forElement_body?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.forPartsWithDeclarations) {
- forParts_condition?.flushInformative();
- forPartsWithDeclarations_variables?.flushInformative();
- forParts_updaters?.forEach((b) => b.flushInformative());
- } else if (kind == idl.LinkedNodeKind.forPartsWithExpression) {
- forParts_condition?.flushInformative();
- forPartsWithExpression_initialization?.flushInformative();
- forParts_updaters?.forEach((b) => b.flushInformative());
- } else if (kind == idl.LinkedNodeKind.forStatement) {
- forMixin_forLoopParts?.flushInformative();
- forStatement_body?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.formalParameterList) {
- formalParameterList_parameters?.forEach((b) => b.flushInformative());
- } else if (kind == idl.LinkedNodeKind.functionDeclaration) {
- actualReturnType?.flushInformative();
- annotatedNode_metadata?.forEach((b) => b.flushInformative());
- functionDeclaration_functionExpression?.flushInformative();
- functionDeclaration_returnType?.flushInformative();
- informativeId = null;
- } else if (kind == idl.LinkedNodeKind.functionDeclarationStatement) {
- functionDeclarationStatement_functionDeclaration?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.functionExpression) {
- actualReturnType?.flushInformative();
- functionExpression_body?.flushInformative();
- functionExpression_formalParameters?.flushInformative();
- functionExpression_typeParameters?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.functionExpressionInvocation) {
- invocationExpression_invokeType?.flushInformative();
- functionExpressionInvocation_function?.flushInformative();
- invocationExpression_typeArguments?.flushInformative();
- expression_type?.flushInformative();
- invocationExpression_arguments?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.functionTypeAlias) {
- actualReturnType?.flushInformative();
- annotatedNode_metadata?.forEach((b) => b.flushInformative());
- functionTypeAlias_formalParameters?.flushInformative();
- functionTypeAlias_returnType?.flushInformative();
- functionTypeAlias_typeParameters?.flushInformative();
- informativeId = null;
- } else if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) {
- actualType?.flushInformative();
- normalFormalParameter_metadata?.forEach((b) => b.flushInformative());
- functionTypedFormalParameter_formalParameters?.flushInformative();
- functionTypedFormalParameter_returnType?.flushInformative();
- functionTypedFormalParameter_typeParameters?.flushInformative();
- informativeId = null;
- } else if (kind == idl.LinkedNodeKind.genericFunctionType) {
- actualReturnType?.flushInformative();
- genericFunctionType_typeParameters?.flushInformative();
- genericFunctionType_returnType?.flushInformative();
- genericFunctionType_formalParameters?.flushInformative();
- genericFunctionType_type?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.genericTypeAlias) {
- annotatedNode_metadata?.forEach((b) => b.flushInformative());
- genericTypeAlias_typeParameters?.flushInformative();
- genericTypeAlias_functionType?.flushInformative();
- informativeId = null;
- } else if (kind == idl.LinkedNodeKind.hideCombinator) {
- informativeId = null;
- } else if (kind == idl.LinkedNodeKind.ifElement) {
- ifMixin_condition?.flushInformative();
- ifElement_thenElement?.flushInformative();
- ifElement_elseElement?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.ifStatement) {
- ifMixin_condition?.flushInformative();
- ifStatement_elseStatement?.flushInformative();
- ifStatement_thenStatement?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.implementsClause) {
- implementsClause_interfaces?.forEach((b) => b.flushInformative());
- } else if (kind == idl.LinkedNodeKind.importDirective) {
- namespaceDirective_combinators?.forEach((b) => b.flushInformative());
- annotatedNode_metadata?.forEach((b) => b.flushInformative());
- namespaceDirective_configurations?.forEach((b) => b.flushInformative());
- informativeId = null;
- uriBasedDirective_uri?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.indexExpression) {
- indexExpression_index?.flushInformative();
- indexExpression_target?.flushInformative();
- indexExpression_substitution?.flushInformative();
- expression_type?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.instanceCreationExpression) {
- instanceCreationExpression_arguments
- ?.forEach((b) => b.flushInformative());
- instanceCreationExpression_constructorName?.flushInformative();
- instanceCreationExpression_typeArguments?.flushInformative();
- expression_type?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.integerLiteral) {
- expression_type?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.interpolationExpression) {
- interpolationExpression_expression?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.interpolationString) {
- } else if (kind == idl.LinkedNodeKind.isExpression) {
- isExpression_expression?.flushInformative();
- isExpression_type?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.label) {
- label_label?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.labeledStatement) {
- labeledStatement_labels?.forEach((b) => b.flushInformative());
- labeledStatement_statement?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.libraryDirective) {
- annotatedNode_metadata?.forEach((b) => b.flushInformative());
- libraryDirective_name?.flushInformative();
- informativeId = null;
- } else if (kind == idl.LinkedNodeKind.libraryIdentifier) {
- libraryIdentifier_components?.forEach((b) => b.flushInformative());
- } else if (kind == idl.LinkedNodeKind.listLiteral) {
- typedLiteral_typeArguments?.forEach((b) => b.flushInformative());
- listLiteral_elements?.forEach((b) => b.flushInformative());
- expression_type?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.mapLiteralEntry) {
- mapLiteralEntry_key?.flushInformative();
- mapLiteralEntry_value?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.methodDeclaration) {
- actualReturnType?.flushInformative();
- annotatedNode_metadata?.forEach((b) => b.flushInformative());
- methodDeclaration_body?.flushInformative();
- methodDeclaration_formalParameters?.flushInformative();
- methodDeclaration_returnType?.flushInformative();
- methodDeclaration_typeParameters?.flushInformative();
- informativeId = null;
- topLevelTypeInferenceError?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.methodInvocation) {
- invocationExpression_invokeType?.flushInformative();
- methodInvocation_methodName?.flushInformative();
- methodInvocation_target?.flushInformative();
- invocationExpression_typeArguments?.flushInformative();
- expression_type?.flushInformative();
- invocationExpression_arguments?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.mixinDeclaration) {
- annotatedNode_metadata?.forEach((b) => b.flushInformative());
- mixinDeclaration_onClause?.flushInformative();
- classOrMixinDeclaration_implementsClause?.flushInformative();
- classOrMixinDeclaration_members?.forEach((b) => b.flushInformative());
- classOrMixinDeclaration_typeParameters?.flushInformative();
- informativeId = null;
- } else if (kind == idl.LinkedNodeKind.namedExpression) {
- namedExpression_expression?.flushInformative();
- namedExpression_name?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.nativeClause) {
- nativeClause_name?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.nativeFunctionBody) {
- nativeFunctionBody_stringLiteral?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.nullLiteral) {
- expression_type?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.onClause) {
- onClause_superclassConstraints?.forEach((b) => b.flushInformative());
- } else if (kind == idl.LinkedNodeKind.parenthesizedExpression) {
- parenthesizedExpression_expression?.flushInformative();
- expression_type?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.partDirective) {
- annotatedNode_metadata?.forEach((b) => b.flushInformative());
- informativeId = null;
- uriBasedDirective_uri?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.partOfDirective) {
- annotatedNode_metadata?.forEach((b) => b.flushInformative());
- partOfDirective_libraryName?.flushInformative();
- partOfDirective_uri?.flushInformative();
- informativeId = null;
- } else if (kind == idl.LinkedNodeKind.postfixExpression) {
- postfixExpression_operand?.flushInformative();
- postfixExpression_substitution?.flushInformative();
- expression_type?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.prefixExpression) {
- prefixExpression_operand?.flushInformative();
- prefixExpression_substitution?.flushInformative();
- expression_type?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.prefixedIdentifier) {
- prefixedIdentifier_identifier?.flushInformative();
- prefixedIdentifier_prefix?.flushInformative();
- expression_type?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.propertyAccess) {
- propertyAccess_propertyName?.flushInformative();
- propertyAccess_target?.flushInformative();
- expression_type?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.redirectingConstructorInvocation) {
- redirectingConstructorInvocation_arguments?.flushInformative();
- redirectingConstructorInvocation_constructorName?.flushInformative();
- redirectingConstructorInvocation_substitution?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.rethrowExpression) {
- expression_type?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.returnStatement) {
- returnStatement_expression?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.setOrMapLiteral) {
- typedLiteral_typeArguments?.forEach((b) => b.flushInformative());
- setOrMapLiteral_elements?.forEach((b) => b.flushInformative());
- expression_type?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.showCombinator) {
- informativeId = null;
- } else if (kind == idl.LinkedNodeKind.simpleFormalParameter) {
- actualType?.flushInformative();
- normalFormalParameter_metadata?.forEach((b) => b.flushInformative());
- simpleFormalParameter_type?.flushInformative();
- informativeId = null;
- topLevelTypeInferenceError?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.simpleIdentifier) {
- simpleIdentifier_substitution?.flushInformative();
- expression_type?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.simpleStringLiteral) {
- } else if (kind == idl.LinkedNodeKind.spreadElement) {
- spreadElement_expression?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.stringInterpolation) {
- stringInterpolation_elements?.forEach((b) => b.flushInformative());
- } else if (kind == idl.LinkedNodeKind.superConstructorInvocation) {
- superConstructorInvocation_arguments?.flushInformative();
- superConstructorInvocation_constructorName?.flushInformative();
- superConstructorInvocation_substitution?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.superExpression) {
- expression_type?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.switchCase) {
- switchMember_statements?.forEach((b) => b.flushInformative());
- switchCase_expression?.flushInformative();
- switchMember_labels?.forEach((b) => b.flushInformative());
- } else if (kind == idl.LinkedNodeKind.switchDefault) {
- switchMember_statements?.forEach((b) => b.flushInformative());
- switchMember_labels?.forEach((b) => b.flushInformative());
- } else if (kind == idl.LinkedNodeKind.switchStatement) {
- switchStatement_members?.forEach((b) => b.flushInformative());
- switchStatement_expression?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.symbolLiteral) {
- expression_type?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.thisExpression) {
- expression_type?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.throwExpression) {
- throwExpression_expression?.flushInformative();
- expression_type?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.topLevelVariableDeclaration) {
- annotatedNode_metadata?.forEach((b) => b.flushInformative());
- topLevelVariableDeclaration_variableList?.flushInformative();
- informativeId = null;
- } else if (kind == idl.LinkedNodeKind.tryStatement) {
- tryStatement_catchClauses?.forEach((b) => b.flushInformative());
- tryStatement_body?.flushInformative();
- tryStatement_finallyBlock?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.typeArgumentList) {
- typeArgumentList_arguments?.forEach((b) => b.flushInformative());
- } else if (kind == idl.LinkedNodeKind.typeName) {
- typeName_typeArguments?.forEach((b) => b.flushInformative());
- typeName_name?.flushInformative();
- typeName_type?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.typeParameter) {
- annotatedNode_metadata?.forEach((b) => b.flushInformative());
- typeParameter_bound?.flushInformative();
- informativeId = null;
- typeParameter_defaultType?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.typeParameterList) {
- typeParameterList_typeParameters?.forEach((b) => b.flushInformative());
- } else if (kind == idl.LinkedNodeKind.variableDeclaration) {
- actualType?.flushInformative();
- annotatedNode_metadata?.forEach((b) => b.flushInformative());
- variableDeclaration_initializer?.flushInformative();
- informativeId = null;
- topLevelTypeInferenceError?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.variableDeclarationList) {
- variableDeclarationList_variables?.forEach((b) => b.flushInformative());
- annotatedNode_metadata?.forEach((b) => b.flushInformative());
- variableDeclarationList_type?.flushInformative();
- informativeId = null;
- } else if (kind == idl.LinkedNodeKind.variableDeclarationStatement) {
- variableDeclarationStatement_variables?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.whileStatement) {
- whileStatement_body?.flushInformative();
- whileStatement_condition?.flushInformative();
- } else if (kind == idl.LinkedNodeKind.withClause) {
- withClause_mixinTypes?.forEach((b) => b.flushInformative());
- } else if (kind == idl.LinkedNodeKind.yieldStatement) {
- yieldStatement_expression?.flushInformative();
- }
- }
-
- /// Accumulate non-[informative] data into [signature].
- void collectApiSignature(api_sig.ApiSignature signature) {
- if (kind == idl.LinkedNodeKind.adjacentStrings) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.adjacentStrings_strings == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.adjacentStrings_strings.length);
- for (var x in this.adjacentStrings_strings) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.annotation) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.annotation_arguments != null);
- this.annotation_arguments?.collectApiSignature(signature);
- signature.addBool(this.annotation_constructorName != null);
- this.annotation_constructorName?.collectApiSignature(signature);
- signature.addBool(this.annotation_name != null);
- this.annotation_name?.collectApiSignature(signature);
- signature.addInt(this.annotation_element ?? 0);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- signature.addBool(this.annotation_substitution != null);
- this.annotation_substitution?.collectApiSignature(signature);
- } else if (kind == idl.LinkedNodeKind.argumentList) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.argumentList_arguments == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.argumentList_arguments.length);
- for (var x in this.argumentList_arguments) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.asExpression) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.asExpression_expression != null);
- this.asExpression_expression?.collectApiSignature(signature);
- signature.addBool(this.asExpression_type != null);
- this.asExpression_type?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.expression_type != null);
- this.expression_type?.collectApiSignature(signature);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.assertInitializer) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.assertInitializer_condition != null);
- this.assertInitializer_condition?.collectApiSignature(signature);
- signature.addBool(this.assertInitializer_message != null);
- this.assertInitializer_message?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.assertStatement) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.assertStatement_condition != null);
- this.assertStatement_condition?.collectApiSignature(signature);
- signature.addBool(this.assertStatement_message != null);
- this.assertStatement_message?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.assignmentExpression) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.assignmentExpression_leftHandSide != null);
- this.assignmentExpression_leftHandSide?.collectApiSignature(signature);
- signature.addBool(this.assignmentExpression_rightHandSide != null);
- this.assignmentExpression_rightHandSide?.collectApiSignature(signature);
- signature.addInt(this.assignmentExpression_element ?? 0);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.expression_type != null);
- this.expression_type?.collectApiSignature(signature);
- signature.addInt(this.assignmentExpression_operator == null
- ? 0
- : this.assignmentExpression_operator.index);
- signature.addString(this.name ?? '');
- signature.addBool(this.assignmentExpression_substitution != null);
- this.assignmentExpression_substitution?.collectApiSignature(signature);
- } else if (kind == idl.LinkedNodeKind.awaitExpression) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.awaitExpression_expression != null);
- this.awaitExpression_expression?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.expression_type != null);
- this.expression_type?.collectApiSignature(signature);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.binaryExpression) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.binaryExpression_leftOperand != null);
- this.binaryExpression_leftOperand?.collectApiSignature(signature);
- signature.addBool(this.binaryExpression_rightOperand != null);
- this.binaryExpression_rightOperand?.collectApiSignature(signature);
- signature.addInt(this.binaryExpression_element ?? 0);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.binaryExpression_invokeType != null);
- this.binaryExpression_invokeType?.collectApiSignature(signature);
- signature.addBool(this.expression_type != null);
- this.expression_type?.collectApiSignature(signature);
- signature.addInt(this.binaryExpression_operator == null
- ? 0
- : this.binaryExpression_operator.index);
- signature.addString(this.name ?? '');
- signature.addBool(this.binaryExpression_substitution != null);
- this.binaryExpression_substitution?.collectApiSignature(signature);
- } else if (kind == idl.LinkedNodeKind.block) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.block_statements == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.block_statements.length);
- for (var x in this.block_statements) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.blockFunctionBody) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.blockFunctionBody_block != null);
- this.blockFunctionBody_block?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.booleanLiteral) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.booleanLiteral_value == true);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.breakStatement) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.breakStatement_label != null);
- this.breakStatement_label?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.cascadeExpression) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.cascadeExpression_sections == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.cascadeExpression_sections.length);
- for (var x in this.cascadeExpression_sections) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.cascadeExpression_target != null);
- this.cascadeExpression_target?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.expression_type != null);
- this.expression_type?.collectApiSignature(signature);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.catchClause) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.catchClause_body != null);
- this.catchClause_body?.collectApiSignature(signature);
- signature.addBool(this.catchClause_exceptionParameter != null);
- this.catchClause_exceptionParameter?.collectApiSignature(signature);
- signature.addBool(this.catchClause_exceptionType != null);
- this.catchClause_exceptionType?.collectApiSignature(signature);
- signature.addBool(this.catchClause_stackTraceParameter != null);
- this.catchClause_stackTraceParameter?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.classDeclaration) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.annotatedNode_metadata == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.annotatedNode_metadata.length);
- for (var x in this.annotatedNode_metadata) {
- x?.collectApiSignature(signature);
- }
- }
- if (this.classOrMixinDeclaration_members == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.classOrMixinDeclaration_members.length);
- for (var x in this.classOrMixinDeclaration_members) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.classDeclaration_extendsClause != null);
- this.classDeclaration_extendsClause?.collectApiSignature(signature);
- signature.addBool(this.classDeclaration_withClause != null);
- this.classDeclaration_withClause?.collectApiSignature(signature);
- signature.addBool(this.classDeclaration_nativeClause != null);
- this.classDeclaration_nativeClause?.collectApiSignature(signature);
- signature.addBool(this.unused11 != null);
- this.unused11?.collectApiSignature(signature);
- signature.addBool(this.classOrMixinDeclaration_implementsClause != null);
- this
- .classOrMixinDeclaration_implementsClause
- ?.collectApiSignature(signature);
- signature.addBool(this.classOrMixinDeclaration_typeParameters != null);
- this
- .classOrMixinDeclaration_typeParameters
- ?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.classDeclaration_isDartObject == true);
- signature.addBool(this.simplyBoundable_isSimplyBounded == true);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.classTypeAlias) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.annotatedNode_metadata == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.annotatedNode_metadata.length);
- for (var x in this.annotatedNode_metadata) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.classTypeAlias_typeParameters != null);
- this.classTypeAlias_typeParameters?.collectApiSignature(signature);
- signature.addBool(this.classTypeAlias_superclass != null);
- this.classTypeAlias_superclass?.collectApiSignature(signature);
- signature.addBool(this.classTypeAlias_withClause != null);
- this.classTypeAlias_withClause?.collectApiSignature(signature);
- signature.addBool(this.classTypeAlias_implementsClause != null);
- this.classTypeAlias_implementsClause?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.simplyBoundable_isSimplyBounded == true);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.comment) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.comment_references == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.comment_references.length);
- for (var x in this.comment_references) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addInt(this.flags ?? 0);
- signature.addInt(this.comment_type == null ? 0 : this.comment_type.index);
- if (this.comment_tokens == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.comment_tokens.length);
- for (var x in this.comment_tokens) {
- signature.addString(x);
- }
- }
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.commentReference) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.commentReference_identifier != null);
- this.commentReference_identifier?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.compilationUnit) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.compilationUnit_declarations == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.compilationUnit_declarations.length);
- for (var x in this.compilationUnit_declarations) {
- x?.collectApiSignature(signature);
- }
- }
- if (this.compilationUnit_directives == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.compilationUnit_directives.length);
- for (var x in this.compilationUnit_directives) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.compilationUnit_scriptTag != null);
- this.compilationUnit_scriptTag?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- signature.addBool(this.compilationUnit_languageVersion != null);
- this.compilationUnit_languageVersion?.collectApiSignature(signature);
- if (this.compilationUnit_featureSet == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.compilationUnit_featureSet.length);
- for (var x in this.compilationUnit_featureSet) {
- signature.addInt(x);
- }
- }
- } else if (kind == idl.LinkedNodeKind.conditionalExpression) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.conditionalExpression_condition != null);
- this.conditionalExpression_condition?.collectApiSignature(signature);
- signature.addBool(this.conditionalExpression_elseExpression != null);
- this.conditionalExpression_elseExpression?.collectApiSignature(signature);
- signature.addBool(this.conditionalExpression_thenExpression != null);
- this.conditionalExpression_thenExpression?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.expression_type != null);
- this.expression_type?.collectApiSignature(signature);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.configuration) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.configuration_name != null);
- this.configuration_name?.collectApiSignature(signature);
- signature.addBool(this.configuration_value != null);
- this.configuration_value?.collectApiSignature(signature);
- signature.addBool(this.configuration_uri != null);
- this.configuration_uri?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.constructorDeclaration) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.constructorDeclaration_initializers == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.constructorDeclaration_initializers.length);
- for (var x in this.constructorDeclaration_initializers) {
- x?.collectApiSignature(signature);
- }
- }
- if (this.annotatedNode_metadata == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.annotatedNode_metadata.length);
- for (var x in this.annotatedNode_metadata) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.constructorDeclaration_body != null);
- this.constructorDeclaration_body?.collectApiSignature(signature);
- signature.addBool(this.constructorDeclaration_parameters != null);
- this.constructorDeclaration_parameters?.collectApiSignature(signature);
- signature
- .addBool(this.constructorDeclaration_redirectedConstructor != null);
- this
- .constructorDeclaration_redirectedConstructor
- ?.collectApiSignature(signature);
- signature.addBool(this.constructorDeclaration_returnType != null);
- this.constructorDeclaration_returnType?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.constructorFieldInitializer) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.constructorFieldInitializer_expression != null);
- this
- .constructorFieldInitializer_expression
- ?.collectApiSignature(signature);
- signature.addBool(this.constructorFieldInitializer_fieldName != null);
- this
- .constructorFieldInitializer_fieldName
- ?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.constructorName) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.constructorName_name != null);
- this.constructorName_name?.collectApiSignature(signature);
- signature.addBool(this.constructorName_type != null);
- this.constructorName_type?.collectApiSignature(signature);
- signature.addInt(this.constructorName_element ?? 0);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- signature.addBool(this.constructorName_substitution != null);
- this.constructorName_substitution?.collectApiSignature(signature);
- } else if (kind == idl.LinkedNodeKind.continueStatement) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.continueStatement_label != null);
- this.continueStatement_label?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.declaredIdentifier) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.annotatedNode_metadata == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.annotatedNode_metadata.length);
- for (var x in this.annotatedNode_metadata) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.declaredIdentifier_identifier != null);
- this.declaredIdentifier_identifier?.collectApiSignature(signature);
- signature.addBool(this.declaredIdentifier_type != null);
- this.declaredIdentifier_type?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.defaultFormalParameter) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.defaultFormalParameter_defaultValue != null);
- this.defaultFormalParameter_defaultValue?.collectApiSignature(signature);
- signature.addBool(this.defaultFormalParameter_parameter != null);
- this.defaultFormalParameter_parameter?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addInt(this.defaultFormalParameter_kind == null
- ? 0
- : this.defaultFormalParameter_kind.index);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.doStatement) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.doStatement_body != null);
- this.doStatement_body?.collectApiSignature(signature);
- signature.addBool(this.doStatement_condition != null);
- this.doStatement_condition?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.dottedName) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.dottedName_components == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.dottedName_components.length);
- for (var x in this.dottedName_components) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.doubleLiteral) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.flags ?? 0);
- signature.addDouble(this.doubleLiteral_value ?? 0.0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.emptyFunctionBody) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.emptyFunctionBody_fake ?? 0);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.emptyStatement) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.emptyStatement_fake ?? 0);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.annotatedNode_metadata == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.annotatedNode_metadata.length);
- for (var x in this.annotatedNode_metadata) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.enumDeclaration) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.enumDeclaration_constants == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.enumDeclaration_constants.length);
- for (var x in this.enumDeclaration_constants) {
- x?.collectApiSignature(signature);
- }
- }
- if (this.annotatedNode_metadata == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.annotatedNode_metadata.length);
- for (var x in this.annotatedNode_metadata) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.exportDirective) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.namespaceDirective_combinators == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.namespaceDirective_combinators.length);
- for (var x in this.namespaceDirective_combinators) {
- x?.collectApiSignature(signature);
- }
- }
- if (this.namespaceDirective_configurations == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.namespaceDirective_configurations.length);
- for (var x in this.namespaceDirective_configurations) {
- x?.collectApiSignature(signature);
- }
- }
- if (this.annotatedNode_metadata == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.annotatedNode_metadata.length);
- for (var x in this.annotatedNode_metadata) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.uriBasedDirective_uri != null);
- this.uriBasedDirective_uri?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addInt(this.uriBasedDirective_uriElement ?? 0);
- signature.addString(this.namespaceDirective_selectedUri ?? '');
- signature.addString(this.uriBasedDirective_uriContent ?? '');
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.expressionFunctionBody) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.expressionFunctionBody_expression != null);
- this.expressionFunctionBody_expression?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.expressionStatement) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.expressionStatement_expression != null);
- this.expressionStatement_expression?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.extendsClause) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.extendsClause_superclass != null);
- this.extendsClause_superclass?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.extensionDeclaration) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.annotatedNode_metadata == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.annotatedNode_metadata.length);
- for (var x in this.annotatedNode_metadata) {
- x?.collectApiSignature(signature);
- }
- }
- if (this.extensionDeclaration_members == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.extensionDeclaration_members.length);
- for (var x in this.extensionDeclaration_members) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.extensionDeclaration_typeParameters != null);
- this.extensionDeclaration_typeParameters?.collectApiSignature(signature);
- signature.addBool(this.extensionDeclaration_extendedType != null);
- this.extensionDeclaration_extendedType?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.extensionDeclaration_refName ?? '');
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.extensionOverride) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.extensionOverride_arguments == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.extensionOverride_arguments.length);
- for (var x in this.extensionOverride_arguments) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.extensionOverride_extensionName != null);
- this.extensionOverride_extensionName?.collectApiSignature(signature);
- signature.addBool(this.extensionOverride_typeArguments != null);
- this.extensionOverride_typeArguments?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.extensionOverride_extendedType != null);
- this.extensionOverride_extendedType?.collectApiSignature(signature);
- signature.addString(this.name ?? '');
- if (this.extensionOverride_typeArgumentTypes == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.extensionOverride_typeArgumentTypes.length);
- for (var x in this.extensionOverride_typeArgumentTypes) {
- x?.collectApiSignature(signature);
- }
- }
- } else if (kind == idl.LinkedNodeKind.fieldDeclaration) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.annotatedNode_metadata == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.annotatedNode_metadata.length);
- for (var x in this.annotatedNode_metadata) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.fieldDeclaration_fields != null);
- this.fieldDeclaration_fields?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.normalFormalParameter_metadata == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.normalFormalParameter_metadata.length);
- for (var x in this.normalFormalParameter_metadata) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.fieldFormalParameter_type != null);
- this.fieldFormalParameter_type?.collectApiSignature(signature);
- signature.addBool(this.fieldFormalParameter_typeParameters != null);
- this.fieldFormalParameter_typeParameters?.collectApiSignature(signature);
- signature.addBool(this.fieldFormalParameter_formalParameters != null);
- this
- .fieldFormalParameter_formalParameters
- ?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.actualType != null);
- this.actualType?.collectApiSignature(signature);
- signature.addBool(this.inheritsCovariant == true);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.forEachPartsWithDeclaration) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.forEachParts_iterable != null);
- this.forEachParts_iterable?.collectApiSignature(signature);
- signature.addBool(this.forEachPartsWithDeclaration_loopVariable != null);
- this
- .forEachPartsWithDeclaration_loopVariable
- ?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.forEachPartsWithIdentifier) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.forEachParts_iterable != null);
- this.forEachParts_iterable?.collectApiSignature(signature);
- signature.addBool(this.forEachPartsWithIdentifier_identifier != null);
- this
- .forEachPartsWithIdentifier_identifier
- ?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.forElement) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.forMixin_forLoopParts != null);
- this.forMixin_forLoopParts?.collectApiSignature(signature);
- signature.addBool(this.forElement_body != null);
- this.forElement_body?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.forPartsWithDeclarations) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.forParts_updaters == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.forParts_updaters.length);
- for (var x in this.forParts_updaters) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.forParts_condition != null);
- this.forParts_condition?.collectApiSignature(signature);
- signature.addBool(this.forPartsWithDeclarations_variables != null);
- this.forPartsWithDeclarations_variables?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.forPartsWithExpression) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.forParts_updaters == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.forParts_updaters.length);
- for (var x in this.forParts_updaters) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.forParts_condition != null);
- this.forParts_condition?.collectApiSignature(signature);
- signature.addBool(this.forPartsWithExpression_initialization != null);
- this
- .forPartsWithExpression_initialization
- ?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.forStatement) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.forMixin_forLoopParts != null);
- this.forMixin_forLoopParts?.collectApiSignature(signature);
- signature.addBool(this.forStatement_body != null);
- this.forStatement_body?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.formalParameterList) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.formalParameterList_parameters == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.formalParameterList_parameters.length);
- for (var x in this.formalParameterList_parameters) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.functionDeclaration) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.annotatedNode_metadata == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.annotatedNode_metadata.length);
- for (var x in this.annotatedNode_metadata) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.functionDeclaration_functionExpression != null);
- this
- .functionDeclaration_functionExpression
- ?.collectApiSignature(signature);
- signature.addBool(this.functionDeclaration_returnType != null);
- this.functionDeclaration_returnType?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.actualReturnType != null);
- this.actualReturnType?.collectApiSignature(signature);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.functionDeclarationStatement) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(
- this.functionDeclarationStatement_functionDeclaration != null);
- this
- .functionDeclarationStatement_functionDeclaration
- ?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.functionExpression) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.functionExpression_body != null);
- this.functionExpression_body?.collectApiSignature(signature);
- signature.addBool(this.functionExpression_formalParameters != null);
- this.functionExpression_formalParameters?.collectApiSignature(signature);
- signature.addBool(this.functionExpression_typeParameters != null);
- this.functionExpression_typeParameters?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.actualReturnType != null);
- this.actualReturnType?.collectApiSignature(signature);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.functionExpressionInvocation) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.functionExpressionInvocation_function != null);
- this
- .functionExpressionInvocation_function
- ?.collectApiSignature(signature);
- signature.addBool(this.invocationExpression_typeArguments != null);
- this.invocationExpression_typeArguments?.collectApiSignature(signature);
- signature.addBool(this.invocationExpression_arguments != null);
- this.invocationExpression_arguments?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.invocationExpression_invokeType != null);
- this.invocationExpression_invokeType?.collectApiSignature(signature);
- signature.addBool(this.expression_type != null);
- this.expression_type?.collectApiSignature(signature);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.functionTypeAlias) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.annotatedNode_metadata == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.annotatedNode_metadata.length);
- for (var x in this.annotatedNode_metadata) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.functionTypeAlias_formalParameters != null);
- this.functionTypeAlias_formalParameters?.collectApiSignature(signature);
- signature.addBool(this.functionTypeAlias_returnType != null);
- this.functionTypeAlias_returnType?.collectApiSignature(signature);
- signature.addBool(this.functionTypeAlias_typeParameters != null);
- this.functionTypeAlias_typeParameters?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.actualReturnType != null);
- this.actualReturnType?.collectApiSignature(signature);
- signature.addBool(this.typeAlias_hasSelfReference == true);
- signature.addBool(this.simplyBoundable_isSimplyBounded == true);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.normalFormalParameter_metadata == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.normalFormalParameter_metadata.length);
- for (var x in this.normalFormalParameter_metadata) {
- x?.collectApiSignature(signature);
- }
- }
- signature
- .addBool(this.functionTypedFormalParameter_formalParameters != null);
- this
- .functionTypedFormalParameter_formalParameters
- ?.collectApiSignature(signature);
- signature.addBool(this.functionTypedFormalParameter_returnType != null);
- this
- .functionTypedFormalParameter_returnType
- ?.collectApiSignature(signature);
- signature
- .addBool(this.functionTypedFormalParameter_typeParameters != null);
- this
- .functionTypedFormalParameter_typeParameters
- ?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.actualType != null);
- this.actualType?.collectApiSignature(signature);
- signature.addBool(this.inheritsCovariant == true);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.genericFunctionType) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.genericFunctionType_typeParameters != null);
- this.genericFunctionType_typeParameters?.collectApiSignature(signature);
- signature.addBool(this.genericFunctionType_returnType != null);
- this.genericFunctionType_returnType?.collectApiSignature(signature);
- signature.addBool(this.genericFunctionType_formalParameters != null);
- this.genericFunctionType_formalParameters?.collectApiSignature(signature);
- signature.addInt(this.genericFunctionType_id ?? 0);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.actualReturnType != null);
- this.actualReturnType?.collectApiSignature(signature);
- signature.addBool(this.genericFunctionType_type != null);
- this.genericFunctionType_type?.collectApiSignature(signature);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.genericTypeAlias) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.annotatedNode_metadata == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.annotatedNode_metadata.length);
- for (var x in this.annotatedNode_metadata) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.genericTypeAlias_typeParameters != null);
- this.genericTypeAlias_typeParameters?.collectApiSignature(signature);
- signature.addBool(this.genericTypeAlias_functionType != null);
- this.genericTypeAlias_functionType?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.typeAlias_hasSelfReference == true);
- signature.addBool(this.simplyBoundable_isSimplyBounded == true);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.hideCombinator) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.flags ?? 0);
- if (this.names == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.names.length);
- for (var x in this.names) {
- signature.addString(x);
- }
- }
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.ifElement) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.ifMixin_condition != null);
- this.ifMixin_condition?.collectApiSignature(signature);
- signature.addBool(this.ifElement_thenElement != null);
- this.ifElement_thenElement?.collectApiSignature(signature);
- signature.addBool(this.ifElement_elseElement != null);
- this.ifElement_elseElement?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.ifStatement) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.ifMixin_condition != null);
- this.ifMixin_condition?.collectApiSignature(signature);
- signature.addBool(this.ifStatement_elseStatement != null);
- this.ifStatement_elseStatement?.collectApiSignature(signature);
- signature.addBool(this.ifStatement_thenStatement != null);
- this.ifStatement_thenStatement?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.implementsClause) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.implementsClause_interfaces == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.implementsClause_interfaces.length);
- for (var x in this.implementsClause_interfaces) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.importDirective) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addString(this.importDirective_prefix ?? '');
- if (this.namespaceDirective_combinators == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.namespaceDirective_combinators.length);
- for (var x in this.namespaceDirective_combinators) {
- x?.collectApiSignature(signature);
- }
- }
- if (this.namespaceDirective_configurations == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.namespaceDirective_configurations.length);
- for (var x in this.namespaceDirective_configurations) {
- x?.collectApiSignature(signature);
- }
- }
- if (this.annotatedNode_metadata == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.annotatedNode_metadata.length);
- for (var x in this.annotatedNode_metadata) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.uriBasedDirective_uri != null);
- this.uriBasedDirective_uri?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addInt(this.uriBasedDirective_uriElement ?? 0);
- signature.addString(this.namespaceDirective_selectedUri ?? '');
- signature.addString(this.uriBasedDirective_uriContent ?? '');
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.indexExpression) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.indexExpression_index != null);
- this.indexExpression_index?.collectApiSignature(signature);
- signature.addBool(this.indexExpression_target != null);
- this.indexExpression_target?.collectApiSignature(signature);
- signature.addInt(this.indexExpression_element ?? 0);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.expression_type != null);
- this.expression_type?.collectApiSignature(signature);
- signature.addString(this.name ?? '');
- signature.addBool(this.indexExpression_substitution != null);
- this.indexExpression_substitution?.collectApiSignature(signature);
- } else if (kind == idl.LinkedNodeKind.instanceCreationExpression) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.instanceCreationExpression_arguments == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.instanceCreationExpression_arguments.length);
- for (var x in this.instanceCreationExpression_arguments) {
- x?.collectApiSignature(signature);
- }
- }
- signature
- .addBool(this.instanceCreationExpression_constructorName != null);
- this
- .instanceCreationExpression_constructorName
- ?.collectApiSignature(signature);
- signature.addBool(this.instanceCreationExpression_typeArguments != null);
- this
- .instanceCreationExpression_typeArguments
- ?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.expression_type != null);
- this.expression_type?.collectApiSignature(signature);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.integerLiteral) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.integerLiteral_value ?? 0);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.expression_type != null);
- this.expression_type?.collectApiSignature(signature);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.interpolationExpression) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.interpolationExpression_expression != null);
- this.interpolationExpression_expression?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.interpolationString) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.interpolationString_value ?? '');
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.isExpression) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.isExpression_expression != null);
- this.isExpression_expression?.collectApiSignature(signature);
- signature.addBool(this.isExpression_type != null);
- this.isExpression_type?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.label) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.label_label != null);
- this.label_label?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.labeledStatement) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.labeledStatement_labels == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.labeledStatement_labels.length);
- for (var x in this.labeledStatement_labels) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.labeledStatement_statement != null);
- this.labeledStatement_statement?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.libraryDirective) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.annotatedNode_metadata == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.annotatedNode_metadata.length);
- for (var x in this.annotatedNode_metadata) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.libraryDirective_name != null);
- this.libraryDirective_name?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.libraryIdentifier) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.libraryIdentifier_components == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.libraryIdentifier_components.length);
- for (var x in this.libraryIdentifier_components) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.listLiteral) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.typedLiteral_typeArguments == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.typedLiteral_typeArguments.length);
- for (var x in this.typedLiteral_typeArguments) {
- x?.collectApiSignature(signature);
- }
- }
- if (this.listLiteral_elements == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.listLiteral_elements.length);
- for (var x in this.listLiteral_elements) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.expression_type != null);
- this.expression_type?.collectApiSignature(signature);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.mapLiteralEntry) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.mapLiteralEntry_key != null);
- this.mapLiteralEntry_key?.collectApiSignature(signature);
- signature.addBool(this.mapLiteralEntry_value != null);
- this.mapLiteralEntry_value?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.methodDeclaration) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.annotatedNode_metadata == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.annotatedNode_metadata.length);
- for (var x in this.annotatedNode_metadata) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.methodDeclaration_body != null);
- this.methodDeclaration_body?.collectApiSignature(signature);
- signature.addBool(this.methodDeclaration_formalParameters != null);
- this.methodDeclaration_formalParameters?.collectApiSignature(signature);
- signature.addBool(this.methodDeclaration_returnType != null);
- this.methodDeclaration_returnType?.collectApiSignature(signature);
- signature.addBool(this.methodDeclaration_typeParameters != null);
- this.methodDeclaration_typeParameters?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.actualReturnType != null);
- this.actualReturnType?.collectApiSignature(signature);
- signature.addBool(
- this.methodDeclaration_hasOperatorEqualWithParameterTypeFromObject ==
- true);
- signature.addBool(this.topLevelTypeInferenceError != null);
- this.topLevelTypeInferenceError?.collectApiSignature(signature);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.methodInvocation) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.methodInvocation_methodName != null);
- this.methodInvocation_methodName?.collectApiSignature(signature);
- signature.addBool(this.methodInvocation_target != null);
- this.methodInvocation_target?.collectApiSignature(signature);
- signature.addBool(this.invocationExpression_typeArguments != null);
- this.invocationExpression_typeArguments?.collectApiSignature(signature);
- signature.addBool(this.invocationExpression_arguments != null);
- this.invocationExpression_arguments?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.invocationExpression_invokeType != null);
- this.invocationExpression_invokeType?.collectApiSignature(signature);
- signature.addBool(this.expression_type != null);
- this.expression_type?.collectApiSignature(signature);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.mixinDeclaration) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.annotatedNode_metadata == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.annotatedNode_metadata.length);
- for (var x in this.annotatedNode_metadata) {
- x?.collectApiSignature(signature);
- }
- }
- if (this.classOrMixinDeclaration_members == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.classOrMixinDeclaration_members.length);
- for (var x in this.classOrMixinDeclaration_members) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.mixinDeclaration_onClause != null);
- this.mixinDeclaration_onClause?.collectApiSignature(signature);
- signature.addBool(this.classOrMixinDeclaration_implementsClause != null);
- this
- .classOrMixinDeclaration_implementsClause
- ?.collectApiSignature(signature);
- signature.addBool(this.classOrMixinDeclaration_typeParameters != null);
- this
- .classOrMixinDeclaration_typeParameters
- ?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.simplyBoundable_isSimplyBounded == true);
- if (this.mixinDeclaration_superInvokedNames == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.mixinDeclaration_superInvokedNames.length);
- for (var x in this.mixinDeclaration_superInvokedNames) {
- signature.addString(x);
- }
- }
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.namedExpression) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.namedExpression_expression != null);
- this.namedExpression_expression?.collectApiSignature(signature);
- signature.addBool(this.namedExpression_name != null);
- this.namedExpression_name?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.nativeClause) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.nativeClause_name != null);
- this.nativeClause_name?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.nativeFunctionBody) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.nativeFunctionBody_stringLiteral != null);
- this.nativeFunctionBody_stringLiteral?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.nullLiteral) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.nullLiteral_fake ?? 0);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.expression_type != null);
- this.expression_type?.collectApiSignature(signature);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.onClause) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.onClause_superclassConstraints == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.onClause_superclassConstraints.length);
- for (var x in this.onClause_superclassConstraints) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.parenthesizedExpression) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.parenthesizedExpression_expression != null);
- this.parenthesizedExpression_expression?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.expression_type != null);
- this.expression_type?.collectApiSignature(signature);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.partDirective) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.annotatedNode_metadata == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.annotatedNode_metadata.length);
- for (var x in this.annotatedNode_metadata) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.uriBasedDirective_uri != null);
- this.uriBasedDirective_uri?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addInt(this.uriBasedDirective_uriElement ?? 0);
- signature.addString(this.uriBasedDirective_uriContent ?? '');
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.partOfDirective) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.annotatedNode_metadata == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.annotatedNode_metadata.length);
- for (var x in this.annotatedNode_metadata) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.partOfDirective_libraryName != null);
- this.partOfDirective_libraryName?.collectApiSignature(signature);
- signature.addBool(this.partOfDirective_uri != null);
- this.partOfDirective_uri?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.postfixExpression) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.postfixExpression_operand != null);
- this.postfixExpression_operand?.collectApiSignature(signature);
- signature.addInt(this.postfixExpression_element ?? 0);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.expression_type != null);
- this.expression_type?.collectApiSignature(signature);
- signature.addInt(this.postfixExpression_operator == null
- ? 0
- : this.postfixExpression_operator.index);
- signature.addString(this.name ?? '');
- signature.addBool(this.postfixExpression_substitution != null);
- this.postfixExpression_substitution?.collectApiSignature(signature);
- } else if (kind == idl.LinkedNodeKind.prefixExpression) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.prefixExpression_operand != null);
- this.prefixExpression_operand?.collectApiSignature(signature);
- signature.addInt(this.prefixExpression_element ?? 0);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.expression_type != null);
- this.expression_type?.collectApiSignature(signature);
- signature.addInt(this.prefixExpression_operator == null
- ? 0
- : this.prefixExpression_operator.index);
- signature.addString(this.name ?? '');
- signature.addBool(this.prefixExpression_substitution != null);
- this.prefixExpression_substitution?.collectApiSignature(signature);
- } else if (kind == idl.LinkedNodeKind.prefixedIdentifier) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.prefixedIdentifier_identifier != null);
- this.prefixedIdentifier_identifier?.collectApiSignature(signature);
- signature.addBool(this.prefixedIdentifier_prefix != null);
- this.prefixedIdentifier_prefix?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.expression_type != null);
- this.expression_type?.collectApiSignature(signature);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.propertyAccess) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.propertyAccess_propertyName != null);
- this.propertyAccess_propertyName?.collectApiSignature(signature);
- signature.addBool(this.propertyAccess_target != null);
- this.propertyAccess_target?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.expression_type != null);
- this.expression_type?.collectApiSignature(signature);
- signature.addInt(this.propertyAccess_operator == null
- ? 0
- : this.propertyAccess_operator.index);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.redirectingConstructorInvocation) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature
- .addBool(this.redirectingConstructorInvocation_arguments != null);
- this
- .redirectingConstructorInvocation_arguments
- ?.collectApiSignature(signature);
- signature.addBool(
- this.redirectingConstructorInvocation_constructorName != null);
- this
- .redirectingConstructorInvocation_constructorName
- ?.collectApiSignature(signature);
- signature.addInt(this.redirectingConstructorInvocation_element ?? 0);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- signature
- .addBool(this.redirectingConstructorInvocation_substitution != null);
- this
- .redirectingConstructorInvocation_substitution
- ?.collectApiSignature(signature);
- } else if (kind == idl.LinkedNodeKind.rethrowExpression) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.expression_type != null);
- this.expression_type?.collectApiSignature(signature);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.returnStatement) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.returnStatement_expression != null);
- this.returnStatement_expression?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.setOrMapLiteral) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.typedLiteral_typeArguments == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.typedLiteral_typeArguments.length);
- for (var x in this.typedLiteral_typeArguments) {
- x?.collectApiSignature(signature);
- }
- }
- if (this.setOrMapLiteral_elements == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.setOrMapLiteral_elements.length);
- for (var x in this.setOrMapLiteral_elements) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.expression_type != null);
- this.expression_type?.collectApiSignature(signature);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.showCombinator) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.flags ?? 0);
- if (this.names == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.names.length);
- for (var x in this.names) {
- signature.addString(x);
- }
- }
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.simpleFormalParameter) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.normalFormalParameter_metadata == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.normalFormalParameter_metadata.length);
- for (var x in this.normalFormalParameter_metadata) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.simpleFormalParameter_type != null);
- this.simpleFormalParameter_type?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.actualType != null);
- this.actualType?.collectApiSignature(signature);
- signature.addBool(this.inheritsCovariant == true);
- signature.addBool(this.topLevelTypeInferenceError != null);
- this.topLevelTypeInferenceError?.collectApiSignature(signature);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.simpleIdentifier) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.simpleIdentifier_element ?? 0);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.expression_type != null);
- this.expression_type?.collectApiSignature(signature);
- signature.addString(this.name ?? '');
- signature.addBool(this.simpleIdentifier_substitution != null);
- this.simpleIdentifier_substitution?.collectApiSignature(signature);
- } else if (kind == idl.LinkedNodeKind.simpleStringLiteral) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.simpleStringLiteral_value ?? '');
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.spreadElement) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.spreadElement_expression != null);
- this.spreadElement_expression?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addInt(this.spreadElement_spreadOperator == null
- ? 0
- : this.spreadElement_spreadOperator.index);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.stringInterpolation) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.stringInterpolation_elements == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.stringInterpolation_elements.length);
- for (var x in this.stringInterpolation_elements) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.superConstructorInvocation) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.superConstructorInvocation_arguments != null);
- this.superConstructorInvocation_arguments?.collectApiSignature(signature);
- signature
- .addBool(this.superConstructorInvocation_constructorName != null);
- this
- .superConstructorInvocation_constructorName
- ?.collectApiSignature(signature);
- signature.addInt(this.superConstructorInvocation_element ?? 0);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- signature.addBool(this.superConstructorInvocation_substitution != null);
- this
- .superConstructorInvocation_substitution
- ?.collectApiSignature(signature);
- } else if (kind == idl.LinkedNodeKind.superExpression) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.expression_type != null);
- this.expression_type?.collectApiSignature(signature);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.switchCase) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.switchMember_labels == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.switchMember_labels.length);
- for (var x in this.switchMember_labels) {
- x?.collectApiSignature(signature);
- }
- }
- if (this.switchMember_statements == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.switchMember_statements.length);
- for (var x in this.switchMember_statements) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.switchCase_expression != null);
- this.switchCase_expression?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.switchDefault) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.switchMember_labels == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.switchMember_labels.length);
- for (var x in this.switchMember_labels) {
- x?.collectApiSignature(signature);
- }
- }
- if (this.switchMember_statements == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.switchMember_statements.length);
- for (var x in this.switchMember_statements) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.switchStatement) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.switchStatement_members == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.switchStatement_members.length);
- for (var x in this.switchStatement_members) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.switchStatement_expression != null);
- this.switchStatement_expression?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.symbolLiteral) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.expression_type != null);
- this.expression_type?.collectApiSignature(signature);
- if (this.names == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.names.length);
- for (var x in this.names) {
- signature.addString(x);
- }
- }
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.thisExpression) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.expression_type != null);
- this.expression_type?.collectApiSignature(signature);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.throwExpression) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.throwExpression_expression != null);
- this.throwExpression_expression?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.expression_type != null);
- this.expression_type?.collectApiSignature(signature);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.topLevelVariableDeclaration) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.annotatedNode_metadata == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.annotatedNode_metadata.length);
- for (var x in this.annotatedNode_metadata) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.topLevelVariableDeclaration_variableList != null);
- this
- .topLevelVariableDeclaration_variableList
- ?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.tryStatement) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.tryStatement_catchClauses == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.tryStatement_catchClauses.length);
- for (var x in this.tryStatement_catchClauses) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.tryStatement_body != null);
- this.tryStatement_body?.collectApiSignature(signature);
- signature.addBool(this.tryStatement_finallyBlock != null);
- this.tryStatement_finallyBlock?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.typeArgumentList) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.typeArgumentList_arguments == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.typeArgumentList_arguments.length);
- for (var x in this.typeArgumentList_arguments) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.typeName) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.typeName_typeArguments == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.typeName_typeArguments.length);
- for (var x in this.typeName_typeArguments) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.typeName_name != null);
- this.typeName_name?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.typeName_type != null);
- this.typeName_type?.collectApiSignature(signature);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.typeParameter) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.annotatedNode_metadata == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.annotatedNode_metadata.length);
- for (var x in this.annotatedNode_metadata) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.typeParameter_bound != null);
- this.typeParameter_bound?.collectApiSignature(signature);
- signature.addInt(this.typeParameter_variance ?? 0);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.typeParameter_defaultType != null);
- this.typeParameter_defaultType?.collectApiSignature(signature);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.typeParameterList) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.typeParameterList_typeParameters == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.typeParameterList_typeParameters.length);
- for (var x in this.typeParameterList_typeParameters) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.variableDeclaration) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.annotatedNode_metadata == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.annotatedNode_metadata.length);
- for (var x in this.annotatedNode_metadata) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.variableDeclaration_initializer != null);
- this.variableDeclaration_initializer?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addBool(this.actualType != null);
- this.actualType?.collectApiSignature(signature);
- signature.addBool(this.inheritsCovariant == true);
- signature.addBool(this.topLevelTypeInferenceError != null);
- this.topLevelTypeInferenceError?.collectApiSignature(signature);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.variableDeclarationList) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.variableDeclarationList_variables == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.variableDeclarationList_variables.length);
- for (var x in this.variableDeclarationList_variables) {
- x?.collectApiSignature(signature);
- }
- }
- if (this.annotatedNode_metadata == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.annotatedNode_metadata.length);
- for (var x in this.annotatedNode_metadata) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this.variableDeclarationList_type != null);
- this.variableDeclarationList_type?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.variableDeclarationStatement) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.variableDeclarationStatement_variables != null);
- this
- .variableDeclarationStatement_variables
- ?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.whileStatement) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.whileStatement_body != null);
- this.whileStatement_body?.collectApiSignature(signature);
- signature.addBool(this.whileStatement_condition != null);
- this.whileStatement_condition?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.withClause) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.withClause_mixinTypes == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.withClause_mixinTypes.length);
- for (var x in this.withClause_mixinTypes) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- } else if (kind == idl.LinkedNodeKind.yieldStatement) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addBool(this.yieldStatement_expression != null);
- this.yieldStatement_expression?.collectApiSignature(signature);
- signature.addInt(this.flags ?? 0);
- signature.addString(this.name ?? '');
- }
- }
-
- fb.Offset finish(fb.Builder fbBuilder) {
- fb.Offset offset_variantField_24;
- fb.Offset offset_variantField_2;
- fb.Offset offset_variantField_4;
- fb.Offset offset_variantField_6;
- fb.Offset offset_variantField_7;
- fb.Offset offset_variantField_8;
- fb.Offset offset_variantField_38;
- fb.Offset offset_variantField_9;
- fb.Offset offset_variantField_12;
- fb.Offset offset_variantField_5;
- fb.Offset offset_variantField_13;
- fb.Offset offset_variantField_33;
- fb.Offset offset_variantField_3;
- fb.Offset offset_variantField_41;
- fb.Offset offset_variantField_40;
- fb.Offset offset_variantField_10;
- fb.Offset offset_variantField_25;
- fb.Offset offset_variantField_20;
- fb.Offset offset_variantField_39;
- fb.Offset offset_variantField_1;
- fb.Offset offset_variantField_30;
- fb.Offset offset_variantField_14;
- fb.Offset offset_variantField_34;
- fb.Offset offset_name;
- fb.Offset offset_variantField_32;
- fb.Offset offset_variantField_23;
- fb.Offset offset_variantField_11;
- fb.Offset offset_variantField_22;
- if (_variantField_24 != null) {
- offset_variantField_24 = _variantField_24.finish(fbBuilder);
- }
- if (!(_variantField_2 == null || _variantField_2.isEmpty)) {
- offset_variantField_2 = fbBuilder
- .writeList(_variantField_2.map((b) => b.finish(fbBuilder)).toList());
- }
- if (!(_variantField_4 == null || _variantField_4.isEmpty)) {
- offset_variantField_4 = fbBuilder
- .writeList(_variantField_4.map((b) => b.finish(fbBuilder)).toList());
- }
- if (_variantField_6 != null) {
- offset_variantField_6 = _variantField_6.finish(fbBuilder);
- }
- if (_variantField_7 != null) {
- offset_variantField_7 = _variantField_7.finish(fbBuilder);
- }
- if (_variantField_8 != null) {
- offset_variantField_8 = _variantField_8.finish(fbBuilder);
- }
- if (_variantField_38 != null) {
- offset_variantField_38 = _variantField_38.finish(fbBuilder);
- }
- if (_variantField_9 != null) {
- offset_variantField_9 = _variantField_9.finish(fbBuilder);
- }
- if (_variantField_12 != null) {
- offset_variantField_12 = _variantField_12.finish(fbBuilder);
- }
- if (!(_variantField_5 == null || _variantField_5.isEmpty)) {
- offset_variantField_5 = fbBuilder
- .writeList(_variantField_5.map((b) => b.finish(fbBuilder)).toList());
- }
- if (_variantField_13 != null) {
- offset_variantField_13 = _variantField_13.finish(fbBuilder);
- }
- if (!(_variantField_33 == null || _variantField_33.isEmpty)) {
- offset_variantField_33 = fbBuilder.writeList(
- _variantField_33.map((b) => fbBuilder.writeString(b)).toList());
- }
- if (!(_variantField_3 == null || _variantField_3.isEmpty)) {
- offset_variantField_3 = fbBuilder
- .writeList(_variantField_3.map((b) => b.finish(fbBuilder)).toList());
- }
- if (!(_variantField_41 == null || _variantField_41.isEmpty)) {
- offset_variantField_41 = fbBuilder.writeListUint32(_variantField_41);
- }
- if (_variantField_40 != null) {
- offset_variantField_40 = _variantField_40.finish(fbBuilder);
- }
- if (_variantField_10 != null) {
- offset_variantField_10 = _variantField_10.finish(fbBuilder);
- }
- if (_variantField_25 != null) {
- offset_variantField_25 = _variantField_25.finish(fbBuilder);
- }
- if (_variantField_20 != null) {
- offset_variantField_20 = fbBuilder.writeString(_variantField_20);
- }
- if (!(_variantField_39 == null || _variantField_39.isEmpty)) {
- offset_variantField_39 = fbBuilder
- .writeList(_variantField_39.map((b) => b.finish(fbBuilder)).toList());
- }
- if (_variantField_1 != null) {
- offset_variantField_1 = fbBuilder.writeString(_variantField_1);
- }
- if (_variantField_30 != null) {
- offset_variantField_30 = fbBuilder.writeString(_variantField_30);
- }
- if (_variantField_14 != null) {
- offset_variantField_14 = _variantField_14.finish(fbBuilder);
- }
- if (!(_variantField_34 == null || _variantField_34.isEmpty)) {
- offset_variantField_34 = fbBuilder.writeList(
- _variantField_34.map((b) => fbBuilder.writeString(b)).toList());
- }
- if (_name != null) {
- offset_name = fbBuilder.writeString(_name);
- }
- if (_variantField_32 != null) {
- offset_variantField_32 = _variantField_32.finish(fbBuilder);
- }
- if (_variantField_23 != null) {
- offset_variantField_23 = _variantField_23.finish(fbBuilder);
- }
- if (_variantField_11 != null) {
- offset_variantField_11 = _variantField_11.finish(fbBuilder);
- }
- if (_variantField_22 != null) {
- offset_variantField_22 = fbBuilder.writeString(_variantField_22);
- }
- fbBuilder.startTable();
- if (offset_variantField_24 != null) {
- fbBuilder.addOffset(24, offset_variantField_24);
- }
- if (offset_variantField_2 != null) {
- fbBuilder.addOffset(2, offset_variantField_2);
- }
- if (offset_variantField_4 != null) {
- fbBuilder.addOffset(4, offset_variantField_4);
- }
- if (offset_variantField_6 != null) {
- fbBuilder.addOffset(6, offset_variantField_6);
- }
- if (offset_variantField_7 != null) {
- fbBuilder.addOffset(7, offset_variantField_7);
- }
- if (_variantField_17 != null && _variantField_17 != 0) {
- fbBuilder.addUint32(17, _variantField_17);
- }
- if (offset_variantField_8 != null) {
- fbBuilder.addOffset(8, offset_variantField_8);
- }
- if (offset_variantField_38 != null) {
- fbBuilder.addOffset(38, offset_variantField_38);
- }
- if (_variantField_15 != null && _variantField_15 != 0) {
- fbBuilder.addUint32(15, _variantField_15);
- }
- if (_variantField_28 != null &&
- _variantField_28 != idl.UnlinkedTokenType.NOTHING) {
- fbBuilder.addUint8(28, _variantField_28.index);
- }
- if (_variantField_27 == true) {
- fbBuilder.addBool(27, true);
- }
- if (offset_variantField_9 != null) {
- fbBuilder.addOffset(9, offset_variantField_9);
- }
- if (offset_variantField_12 != null) {
- fbBuilder.addOffset(12, offset_variantField_12);
- }
- if (offset_variantField_5 != null) {
- fbBuilder.addOffset(5, offset_variantField_5);
- }
- if (offset_variantField_13 != null) {
- fbBuilder.addOffset(13, offset_variantField_13);
- }
- if (offset_variantField_33 != null) {
- fbBuilder.addOffset(33, offset_variantField_33);
- }
- if (_variantField_29 != null &&
- _variantField_29 != idl.LinkedNodeCommentType.block) {
- fbBuilder.addUint8(29, _variantField_29.index);
- }
- if (offset_variantField_3 != null) {
- fbBuilder.addOffset(3, offset_variantField_3);
- }
- if (offset_variantField_41 != null) {
- fbBuilder.addOffset(41, offset_variantField_41);
- }
- if (offset_variantField_40 != null) {
- fbBuilder.addOffset(40, offset_variantField_40);
- }
- if (offset_variantField_10 != null) {
- fbBuilder.addOffset(10, offset_variantField_10);
- }
- if (_variantField_26 != null &&
- _variantField_26 !=
- idl.LinkedNodeFormalParameterKind.requiredPositional) {
- fbBuilder.addUint8(26, _variantField_26.index);
- }
- if (_variantField_21 != null && _variantField_21 != 0.0) {
- fbBuilder.addFloat64(21, _variantField_21);
- }
- if (offset_variantField_25 != null) {
- fbBuilder.addOffset(25, offset_variantField_25);
- }
- if (offset_variantField_20 != null) {
- fbBuilder.addOffset(20, offset_variantField_20);
- }
- if (offset_variantField_39 != null) {
- fbBuilder.addOffset(39, offset_variantField_39);
- }
- if (_flags != null && _flags != 0) {
- fbBuilder.addUint32(18, _flags);
- }
- if (offset_variantField_1 != null) {
- fbBuilder.addOffset(1, offset_variantField_1);
- }
- if (_variantField_36 != null && _variantField_36 != 0) {
- fbBuilder.addUint32(36, _variantField_36);
- }
- if (_variantField_16 != null && _variantField_16 != 0) {
- fbBuilder.addUint32(16, _variantField_16);
- }
- if (offset_variantField_30 != null) {
- fbBuilder.addOffset(30, offset_variantField_30);
- }
- if (offset_variantField_14 != null) {
- fbBuilder.addOffset(14, offset_variantField_14);
- }
- if (_kind != null && _kind != idl.LinkedNodeKind.adjacentStrings) {
- fbBuilder.addUint8(0, _kind.index);
- }
- if (_variantField_31 == true) {
- fbBuilder.addBool(31, true);
- }
- if (offset_variantField_34 != null) {
- fbBuilder.addOffset(34, offset_variantField_34);
- }
- if (offset_name != null) {
- fbBuilder.addOffset(37, offset_name);
- }
- if (_variantField_35 != null &&
- _variantField_35 != idl.UnlinkedTokenType.NOTHING) {
- fbBuilder.addUint8(35, _variantField_35.index);
- }
- if (offset_variantField_32 != null) {
- fbBuilder.addOffset(32, offset_variantField_32);
- }
- if (offset_variantField_23 != null) {
- fbBuilder.addOffset(23, offset_variantField_23);
- }
- if (offset_variantField_11 != null) {
- fbBuilder.addOffset(11, offset_variantField_11);
- }
- if (offset_variantField_22 != null) {
- fbBuilder.addOffset(22, offset_variantField_22);
- }
- if (_variantField_19 != null && _variantField_19 != 0) {
- fbBuilder.addUint32(19, _variantField_19);
- }
- return fbBuilder.endTable();
- }
-}
-
-class _LinkedNodeReader extends fb.TableReader<_LinkedNodeImpl> {
- const _LinkedNodeReader();
-
- @override
- _LinkedNodeImpl createObject(fb.BufferContext bc, int offset) =>
- _LinkedNodeImpl(bc, offset);
-}
-
-class _LinkedNodeImpl extends Object
- with _LinkedNodeMixin
- implements idl.LinkedNode {
- final fb.BufferContext _bc;
- final int _bcOffset;
-
- _LinkedNodeImpl(this._bc, this._bcOffset);
-
- idl.LinkedNodeType _variantField_24;
- List<idl.LinkedNode> _variantField_2;
- List<idl.LinkedNode> _variantField_4;
- idl.LinkedNode _variantField_6;
- idl.LinkedNode _variantField_7;
- int _variantField_17;
- idl.LinkedNode _variantField_8;
- idl.LinkedNodeTypeSubstitution _variantField_38;
- int _variantField_15;
- idl.UnlinkedTokenType _variantField_28;
- bool _variantField_27;
- idl.LinkedNode _variantField_9;
- idl.LinkedNode _variantField_12;
- List<idl.LinkedNode> _variantField_5;
- idl.LinkedNode _variantField_13;
- List<String> _variantField_33;
- idl.LinkedNodeCommentType _variantField_29;
- List<idl.LinkedNode> _variantField_3;
- List<int> _variantField_41;
- idl.LinkedLibraryLanguageVersion _variantField_40;
- idl.LinkedNode _variantField_10;
- idl.LinkedNodeFormalParameterKind _variantField_26;
- double _variantField_21;
- idl.LinkedNodeType _variantField_25;
- String _variantField_20;
- List<idl.LinkedNodeType> _variantField_39;
- int _flags;
- String _variantField_1;
- int _variantField_36;
- int _variantField_16;
- String _variantField_30;
- idl.LinkedNode _variantField_14;
- idl.LinkedNodeKind _kind;
- bool _variantField_31;
- List<String> _variantField_34;
- String _name;
- idl.UnlinkedTokenType _variantField_35;
- idl.TopLevelInferenceError _variantField_32;
- idl.LinkedNodeType _variantField_23;
- idl.LinkedNode _variantField_11;
- String _variantField_22;
- int _variantField_19;
-
- @override
- idl.LinkedNodeType get actualReturnType {
- assert(kind == idl.LinkedNodeKind.functionDeclaration ||
- kind == idl.LinkedNodeKind.functionExpression ||
- kind == idl.LinkedNodeKind.functionTypeAlias ||
- kind == idl.LinkedNodeKind.genericFunctionType ||
- kind == idl.LinkedNodeKind.methodDeclaration);
- _variantField_24 ??=
- const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
- return _variantField_24;
- }
-
- @override
- idl.LinkedNodeType get actualType {
- assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
- kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
- kind == idl.LinkedNodeKind.simpleFormalParameter ||
- kind == idl.LinkedNodeKind.variableDeclaration);
- _variantField_24 ??=
- const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
- return _variantField_24;
- }
-
- @override
- idl.LinkedNodeType get binaryExpression_invokeType {
- assert(kind == idl.LinkedNodeKind.binaryExpression);
- _variantField_24 ??=
- const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
- return _variantField_24;
- }
-
- @override
- idl.LinkedNodeType get extensionOverride_extendedType {
- assert(kind == idl.LinkedNodeKind.extensionOverride);
- _variantField_24 ??=
- const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
- return _variantField_24;
- }
-
- @override
- idl.LinkedNodeType get invocationExpression_invokeType {
- assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
- kind == idl.LinkedNodeKind.methodInvocation);
- _variantField_24 ??=
- const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
- return _variantField_24;
- }
-
- @override
- List<idl.LinkedNode> get adjacentStrings_strings {
- assert(kind == idl.LinkedNodeKind.adjacentStrings);
- _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
- return _variantField_2;
- }
-
- @override
- List<idl.LinkedNode> get argumentList_arguments {
- assert(kind == idl.LinkedNodeKind.argumentList);
- _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
- return _variantField_2;
- }
-
- @override
- List<idl.LinkedNode> get block_statements {
- assert(kind == idl.LinkedNodeKind.block);
- _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
- return _variantField_2;
- }
-
- @override
- List<idl.LinkedNode> get cascadeExpression_sections {
- assert(kind == idl.LinkedNodeKind.cascadeExpression);
- _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
- return _variantField_2;
- }
-
- @override
- List<idl.LinkedNode> get comment_references {
- assert(kind == idl.LinkedNodeKind.comment);
- _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
- return _variantField_2;
- }
-
- @override
- List<idl.LinkedNode> get compilationUnit_declarations {
- assert(kind == idl.LinkedNodeKind.compilationUnit);
- _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
- return _variantField_2;
- }
-
- @override
- List<idl.LinkedNode> get constructorDeclaration_initializers {
- assert(kind == idl.LinkedNodeKind.constructorDeclaration);
- _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
- return _variantField_2;
- }
-
- @override
- List<idl.LinkedNode> get dottedName_components {
- assert(kind == idl.LinkedNodeKind.dottedName);
- _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
- return _variantField_2;
- }
-
- @override
- List<idl.LinkedNode> get enumDeclaration_constants {
- assert(kind == idl.LinkedNodeKind.enumDeclaration);
- _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
- return _variantField_2;
- }
-
- @override
- List<idl.LinkedNode> get extensionOverride_arguments {
- assert(kind == idl.LinkedNodeKind.extensionOverride);
- _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
- return _variantField_2;
- }
-
- @override
- List<idl.LinkedNode> get formalParameterList_parameters {
- assert(kind == idl.LinkedNodeKind.formalParameterList);
- _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
- return _variantField_2;
- }
-
- @override
- List<idl.LinkedNode> get implementsClause_interfaces {
- assert(kind == idl.LinkedNodeKind.implementsClause);
- _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
- return _variantField_2;
- }
-
- @override
- List<idl.LinkedNode> get instanceCreationExpression_arguments {
- assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
- _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
- return _variantField_2;
- }
-
- @override
- List<idl.LinkedNode> get labeledStatement_labels {
- assert(kind == idl.LinkedNodeKind.labeledStatement);
- _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
- return _variantField_2;
- }
-
- @override
- List<idl.LinkedNode> get libraryIdentifier_components {
- assert(kind == idl.LinkedNodeKind.libraryIdentifier);
- _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
- return _variantField_2;
- }
-
- @override
- List<idl.LinkedNode> get namespaceDirective_combinators {
- assert(kind == idl.LinkedNodeKind.exportDirective ||
- kind == idl.LinkedNodeKind.importDirective);
- _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
- return _variantField_2;
- }
-
- @override
- List<idl.LinkedNode> get onClause_superclassConstraints {
- assert(kind == idl.LinkedNodeKind.onClause);
- _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
- return _variantField_2;
- }
-
- @override
- List<idl.LinkedNode> get stringInterpolation_elements {
- assert(kind == idl.LinkedNodeKind.stringInterpolation);
- _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
- return _variantField_2;
- }
-
- @override
- List<idl.LinkedNode> get switchStatement_members {
- assert(kind == idl.LinkedNodeKind.switchStatement);
- _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
- return _variantField_2;
- }
-
- @override
- List<idl.LinkedNode> get tryStatement_catchClauses {
- assert(kind == idl.LinkedNodeKind.tryStatement);
- _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
- return _variantField_2;
- }
-
- @override
- List<idl.LinkedNode> get typeArgumentList_arguments {
- assert(kind == idl.LinkedNodeKind.typeArgumentList);
- _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
- return _variantField_2;
- }
-
- @override
- List<idl.LinkedNode> get typedLiteral_typeArguments {
- assert(kind == idl.LinkedNodeKind.listLiteral ||
- kind == idl.LinkedNodeKind.setOrMapLiteral);
- _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
- return _variantField_2;
- }
-
- @override
- List<idl.LinkedNode> get typeName_typeArguments {
- assert(kind == idl.LinkedNodeKind.typeName);
- _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
- return _variantField_2;
- }
-
- @override
- List<idl.LinkedNode> get typeParameterList_typeParameters {
- assert(kind == idl.LinkedNodeKind.typeParameterList);
- _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
- return _variantField_2;
- }
-
- @override
- List<idl.LinkedNode> get variableDeclarationList_variables {
- assert(kind == idl.LinkedNodeKind.variableDeclarationList);
- _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
- return _variantField_2;
- }
-
- @override
- List<idl.LinkedNode> get withClause_mixinTypes {
- assert(kind == idl.LinkedNodeKind.withClause);
- _variantField_2 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
- return _variantField_2;
- }
-
- @override
- List<idl.LinkedNode> get annotatedNode_metadata {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.classTypeAlias ||
- kind == idl.LinkedNodeKind.constructorDeclaration ||
- kind == idl.LinkedNodeKind.declaredIdentifier ||
- kind == idl.LinkedNodeKind.enumDeclaration ||
- kind == idl.LinkedNodeKind.enumConstantDeclaration ||
- kind == idl.LinkedNodeKind.exportDirective ||
- kind == idl.LinkedNodeKind.extensionDeclaration ||
- kind == idl.LinkedNodeKind.fieldDeclaration ||
- kind == idl.LinkedNodeKind.functionDeclaration ||
- kind == idl.LinkedNodeKind.functionTypeAlias ||
- kind == idl.LinkedNodeKind.genericTypeAlias ||
- kind == idl.LinkedNodeKind.importDirective ||
- kind == idl.LinkedNodeKind.libraryDirective ||
- kind == idl.LinkedNodeKind.methodDeclaration ||
- kind == idl.LinkedNodeKind.mixinDeclaration ||
- kind == idl.LinkedNodeKind.partDirective ||
- kind == idl.LinkedNodeKind.partOfDirective ||
- kind == idl.LinkedNodeKind.topLevelVariableDeclaration ||
- kind == idl.LinkedNodeKind.typeParameter ||
- kind == idl.LinkedNodeKind.variableDeclaration ||
- kind == idl.LinkedNodeKind.variableDeclarationList);
- _variantField_4 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 4, const <idl.LinkedNode>[]);
- return _variantField_4;
- }
-
- @override
- List<idl.LinkedNode> get normalFormalParameter_metadata {
- assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
- kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
- kind == idl.LinkedNodeKind.simpleFormalParameter);
- _variantField_4 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 4, const <idl.LinkedNode>[]);
- return _variantField_4;
- }
-
- @override
- List<idl.LinkedNode> get switchMember_statements {
- assert(kind == idl.LinkedNodeKind.switchCase ||
- kind == idl.LinkedNodeKind.switchDefault);
- _variantField_4 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 4, const <idl.LinkedNode>[]);
- return _variantField_4;
- }
-
- @override
- idl.LinkedNode get annotation_arguments {
- assert(kind == idl.LinkedNodeKind.annotation);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get asExpression_expression {
- assert(kind == idl.LinkedNodeKind.asExpression);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get assertInitializer_condition {
- assert(kind == idl.LinkedNodeKind.assertInitializer);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get assertStatement_condition {
- assert(kind == idl.LinkedNodeKind.assertStatement);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get assignmentExpression_leftHandSide {
- assert(kind == idl.LinkedNodeKind.assignmentExpression);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get awaitExpression_expression {
- assert(kind == idl.LinkedNodeKind.awaitExpression);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get binaryExpression_leftOperand {
- assert(kind == idl.LinkedNodeKind.binaryExpression);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get blockFunctionBody_block {
- assert(kind == idl.LinkedNodeKind.blockFunctionBody);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get breakStatement_label {
- assert(kind == idl.LinkedNodeKind.breakStatement);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get cascadeExpression_target {
- assert(kind == idl.LinkedNodeKind.cascadeExpression);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get catchClause_body {
- assert(kind == idl.LinkedNodeKind.catchClause);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get classDeclaration_extendsClause {
- assert(kind == idl.LinkedNodeKind.classDeclaration);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get classTypeAlias_typeParameters {
- assert(kind == idl.LinkedNodeKind.classTypeAlias);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get commentReference_identifier {
- assert(kind == idl.LinkedNodeKind.commentReference);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get compilationUnit_scriptTag {
- assert(kind == idl.LinkedNodeKind.compilationUnit);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get conditionalExpression_condition {
- assert(kind == idl.LinkedNodeKind.conditionalExpression);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get configuration_name {
- assert(kind == idl.LinkedNodeKind.configuration);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get constructorDeclaration_body {
- assert(kind == idl.LinkedNodeKind.constructorDeclaration);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get constructorFieldInitializer_expression {
- assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get constructorName_name {
- assert(kind == idl.LinkedNodeKind.constructorName);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get continueStatement_label {
- assert(kind == idl.LinkedNodeKind.continueStatement);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get declaredIdentifier_identifier {
- assert(kind == idl.LinkedNodeKind.declaredIdentifier);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get defaultFormalParameter_defaultValue {
- assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get doStatement_body {
- assert(kind == idl.LinkedNodeKind.doStatement);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get expressionFunctionBody_expression {
- assert(kind == idl.LinkedNodeKind.expressionFunctionBody);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get expressionStatement_expression {
- assert(kind == idl.LinkedNodeKind.expressionStatement);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get extendsClause_superclass {
- assert(kind == idl.LinkedNodeKind.extendsClause);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get extensionDeclaration_typeParameters {
- assert(kind == idl.LinkedNodeKind.extensionDeclaration);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get fieldDeclaration_fields {
- assert(kind == idl.LinkedNodeKind.fieldDeclaration);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get fieldFormalParameter_type {
- assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get forEachParts_iterable {
- assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration ||
- kind == idl.LinkedNodeKind.forEachPartsWithIdentifier);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get forMixin_forLoopParts {
- assert(kind == idl.LinkedNodeKind.forElement ||
- kind == idl.LinkedNodeKind.forStatement);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get forParts_condition {
- assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
- kind == idl.LinkedNodeKind.forPartsWithExpression);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get functionDeclaration_functionExpression {
- assert(kind == idl.LinkedNodeKind.functionDeclaration);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get functionDeclarationStatement_functionDeclaration {
- assert(kind == idl.LinkedNodeKind.functionDeclarationStatement);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get functionExpression_body {
- assert(kind == idl.LinkedNodeKind.functionExpression);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get functionExpressionInvocation_function {
- assert(kind == idl.LinkedNodeKind.functionExpressionInvocation);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get functionTypeAlias_formalParameters {
- assert(kind == idl.LinkedNodeKind.functionTypeAlias);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get functionTypedFormalParameter_formalParameters {
- assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get genericFunctionType_typeParameters {
- assert(kind == idl.LinkedNodeKind.genericFunctionType);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get genericTypeAlias_typeParameters {
- assert(kind == idl.LinkedNodeKind.genericTypeAlias);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get ifMixin_condition {
- assert(kind == idl.LinkedNodeKind.ifElement ||
- kind == idl.LinkedNodeKind.ifStatement);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get indexExpression_index {
- assert(kind == idl.LinkedNodeKind.indexExpression);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get interpolationExpression_expression {
- assert(kind == idl.LinkedNodeKind.interpolationExpression);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get isExpression_expression {
- assert(kind == idl.LinkedNodeKind.isExpression);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get label_label {
- assert(kind == idl.LinkedNodeKind.label);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get labeledStatement_statement {
- assert(kind == idl.LinkedNodeKind.labeledStatement);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get libraryDirective_name {
- assert(kind == idl.LinkedNodeKind.libraryDirective);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get mapLiteralEntry_key {
- assert(kind == idl.LinkedNodeKind.mapLiteralEntry);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get methodDeclaration_body {
- assert(kind == idl.LinkedNodeKind.methodDeclaration);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get methodInvocation_methodName {
- assert(kind == idl.LinkedNodeKind.methodInvocation);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get mixinDeclaration_onClause {
- assert(kind == idl.LinkedNodeKind.mixinDeclaration);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get namedExpression_expression {
- assert(kind == idl.LinkedNodeKind.namedExpression);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get nativeClause_name {
- assert(kind == idl.LinkedNodeKind.nativeClause);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get nativeFunctionBody_stringLiteral {
- assert(kind == idl.LinkedNodeKind.nativeFunctionBody);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get parenthesizedExpression_expression {
- assert(kind == idl.LinkedNodeKind.parenthesizedExpression);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get partOfDirective_libraryName {
- assert(kind == idl.LinkedNodeKind.partOfDirective);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get postfixExpression_operand {
- assert(kind == idl.LinkedNodeKind.postfixExpression);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get prefixedIdentifier_identifier {
- assert(kind == idl.LinkedNodeKind.prefixedIdentifier);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get prefixExpression_operand {
- assert(kind == idl.LinkedNodeKind.prefixExpression);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get propertyAccess_propertyName {
- assert(kind == idl.LinkedNodeKind.propertyAccess);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get redirectingConstructorInvocation_arguments {
- assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get returnStatement_expression {
- assert(kind == idl.LinkedNodeKind.returnStatement);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get simpleFormalParameter_type {
- assert(kind == idl.LinkedNodeKind.simpleFormalParameter);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get spreadElement_expression {
- assert(kind == idl.LinkedNodeKind.spreadElement);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get superConstructorInvocation_arguments {
- assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get switchCase_expression {
- assert(kind == idl.LinkedNodeKind.switchCase);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get throwExpression_expression {
- assert(kind == idl.LinkedNodeKind.throwExpression);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get topLevelVariableDeclaration_variableList {
- assert(kind == idl.LinkedNodeKind.topLevelVariableDeclaration);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get tryStatement_body {
- assert(kind == idl.LinkedNodeKind.tryStatement);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get typeName_name {
- assert(kind == idl.LinkedNodeKind.typeName);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get typeParameter_bound {
- assert(kind == idl.LinkedNodeKind.typeParameter);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get variableDeclaration_initializer {
- assert(kind == idl.LinkedNodeKind.variableDeclaration);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get variableDeclarationList_type {
- assert(kind == idl.LinkedNodeKind.variableDeclarationList);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get variableDeclarationStatement_variables {
- assert(kind == idl.LinkedNodeKind.variableDeclarationStatement);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get whileStatement_body {
- assert(kind == idl.LinkedNodeKind.whileStatement);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get yieldStatement_expression {
- assert(kind == idl.LinkedNodeKind.yieldStatement);
- _variantField_6 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 6, null);
- return _variantField_6;
- }
-
- @override
- idl.LinkedNode get annotation_constructorName {
- assert(kind == idl.LinkedNodeKind.annotation);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get asExpression_type {
- assert(kind == idl.LinkedNodeKind.asExpression);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get assertInitializer_message {
- assert(kind == idl.LinkedNodeKind.assertInitializer);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get assertStatement_message {
- assert(kind == idl.LinkedNodeKind.assertStatement);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get assignmentExpression_rightHandSide {
- assert(kind == idl.LinkedNodeKind.assignmentExpression);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get binaryExpression_rightOperand {
- assert(kind == idl.LinkedNodeKind.binaryExpression);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get catchClause_exceptionParameter {
- assert(kind == idl.LinkedNodeKind.catchClause);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get classDeclaration_withClause {
- assert(kind == idl.LinkedNodeKind.classDeclaration);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get classTypeAlias_superclass {
- assert(kind == idl.LinkedNodeKind.classTypeAlias);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get conditionalExpression_elseExpression {
- assert(kind == idl.LinkedNodeKind.conditionalExpression);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get configuration_value {
- assert(kind == idl.LinkedNodeKind.configuration);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get constructorFieldInitializer_fieldName {
- assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get constructorName_type {
- assert(kind == idl.LinkedNodeKind.constructorName);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get declaredIdentifier_type {
- assert(kind == idl.LinkedNodeKind.declaredIdentifier);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get defaultFormalParameter_parameter {
- assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get doStatement_condition {
- assert(kind == idl.LinkedNodeKind.doStatement);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get extensionDeclaration_extendedType {
- assert(kind == idl.LinkedNodeKind.extensionDeclaration);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get extensionOverride_extensionName {
- assert(kind == idl.LinkedNodeKind.extensionOverride);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get fieldFormalParameter_typeParameters {
- assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get forEachPartsWithDeclaration_loopVariable {
- assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get forEachPartsWithIdentifier_identifier {
- assert(kind == idl.LinkedNodeKind.forEachPartsWithIdentifier);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get forElement_body {
- assert(kind == idl.LinkedNodeKind.forElement);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get forPartsWithDeclarations_variables {
- assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get forPartsWithExpression_initialization {
- assert(kind == idl.LinkedNodeKind.forPartsWithExpression);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get forStatement_body {
- assert(kind == idl.LinkedNodeKind.forStatement);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get functionDeclaration_returnType {
- assert(kind == idl.LinkedNodeKind.functionDeclaration);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get functionExpression_formalParameters {
- assert(kind == idl.LinkedNodeKind.functionExpression);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get functionTypeAlias_returnType {
- assert(kind == idl.LinkedNodeKind.functionTypeAlias);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get functionTypedFormalParameter_returnType {
- assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get genericFunctionType_returnType {
- assert(kind == idl.LinkedNodeKind.genericFunctionType);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get genericTypeAlias_functionType {
- assert(kind == idl.LinkedNodeKind.genericTypeAlias);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get ifStatement_elseStatement {
- assert(kind == idl.LinkedNodeKind.ifStatement);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get indexExpression_target {
- assert(kind == idl.LinkedNodeKind.indexExpression);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get instanceCreationExpression_constructorName {
- assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get isExpression_type {
- assert(kind == idl.LinkedNodeKind.isExpression);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get mapLiteralEntry_value {
- assert(kind == idl.LinkedNodeKind.mapLiteralEntry);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get methodDeclaration_formalParameters {
- assert(kind == idl.LinkedNodeKind.methodDeclaration);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get methodInvocation_target {
- assert(kind == idl.LinkedNodeKind.methodInvocation);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get namedExpression_name {
- assert(kind == idl.LinkedNodeKind.namedExpression);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get partOfDirective_uri {
- assert(kind == idl.LinkedNodeKind.partOfDirective);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get prefixedIdentifier_prefix {
- assert(kind == idl.LinkedNodeKind.prefixedIdentifier);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get propertyAccess_target {
- assert(kind == idl.LinkedNodeKind.propertyAccess);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get redirectingConstructorInvocation_constructorName {
- assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get superConstructorInvocation_constructorName {
- assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get switchStatement_expression {
- assert(kind == idl.LinkedNodeKind.switchStatement);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get tryStatement_finallyBlock {
- assert(kind == idl.LinkedNodeKind.tryStatement);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- idl.LinkedNode get whileStatement_condition {
- assert(kind == idl.LinkedNodeKind.whileStatement);
- _variantField_7 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
- return _variantField_7;
- }
-
- @override
- int get annotation_element {
- assert(kind == idl.LinkedNodeKind.annotation);
- _variantField_17 ??=
- const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 17, 0);
- return _variantField_17;
- }
-
- @override
- int get genericFunctionType_id {
- assert(kind == idl.LinkedNodeKind.genericFunctionType);
- _variantField_17 ??=
- const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 17, 0);
- return _variantField_17;
- }
-
- @override
- idl.LinkedNode get annotation_name {
- assert(kind == idl.LinkedNodeKind.annotation);
- _variantField_8 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
- return _variantField_8;
- }
-
- @override
- idl.LinkedNode get catchClause_exceptionType {
- assert(kind == idl.LinkedNodeKind.catchClause);
- _variantField_8 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
- return _variantField_8;
- }
-
- @override
- idl.LinkedNode get classDeclaration_nativeClause {
- assert(kind == idl.LinkedNodeKind.classDeclaration);
- _variantField_8 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
- return _variantField_8;
- }
-
- @override
- idl.LinkedNode get classTypeAlias_withClause {
- assert(kind == idl.LinkedNodeKind.classTypeAlias);
- _variantField_8 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
- return _variantField_8;
- }
-
- @override
- idl.LinkedNode get conditionalExpression_thenExpression {
- assert(kind == idl.LinkedNodeKind.conditionalExpression);
- _variantField_8 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
- return _variantField_8;
- }
-
- @override
- idl.LinkedNode get configuration_uri {
- assert(kind == idl.LinkedNodeKind.configuration);
- _variantField_8 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
- return _variantField_8;
- }
-
- @override
- idl.LinkedNode get constructorDeclaration_parameters {
- assert(kind == idl.LinkedNodeKind.constructorDeclaration);
- _variantField_8 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
- return _variantField_8;
- }
-
- @override
- idl.LinkedNode get extensionOverride_typeArguments {
- assert(kind == idl.LinkedNodeKind.extensionOverride);
- _variantField_8 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
- return _variantField_8;
- }
-
- @override
- idl.LinkedNode get fieldFormalParameter_formalParameters {
- assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
- _variantField_8 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
- return _variantField_8;
- }
-
- @override
- idl.LinkedNode get functionExpression_typeParameters {
- assert(kind == idl.LinkedNodeKind.functionExpression);
- _variantField_8 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
- return _variantField_8;
- }
-
- @override
- idl.LinkedNode get functionTypeAlias_typeParameters {
- assert(kind == idl.LinkedNodeKind.functionTypeAlias);
- _variantField_8 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
- return _variantField_8;
- }
-
- @override
- idl.LinkedNode get functionTypedFormalParameter_typeParameters {
- assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
- _variantField_8 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
- return _variantField_8;
- }
-
- @override
- idl.LinkedNode get genericFunctionType_formalParameters {
- assert(kind == idl.LinkedNodeKind.genericFunctionType);
- _variantField_8 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
- return _variantField_8;
- }
-
- @override
- idl.LinkedNode get ifElement_thenElement {
- assert(kind == idl.LinkedNodeKind.ifElement);
- _variantField_8 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
- return _variantField_8;
- }
-
- @override
- idl.LinkedNode get ifStatement_thenStatement {
- assert(kind == idl.LinkedNodeKind.ifStatement);
- _variantField_8 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
- return _variantField_8;
- }
-
- @override
- idl.LinkedNode get instanceCreationExpression_typeArguments {
- assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
- _variantField_8 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
- return _variantField_8;
- }
-
- @override
- idl.LinkedNode get methodDeclaration_returnType {
- assert(kind == idl.LinkedNodeKind.methodDeclaration);
- _variantField_8 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
- return _variantField_8;
- }
-
- @override
- idl.LinkedNodeTypeSubstitution get annotation_substitution {
- assert(kind == idl.LinkedNodeKind.annotation);
- _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
- .vTableGet(_bc, _bcOffset, 38, null);
- return _variantField_38;
- }
-
- @override
- idl.LinkedNodeTypeSubstitution get assignmentExpression_substitution {
- assert(kind == idl.LinkedNodeKind.assignmentExpression);
- _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
- .vTableGet(_bc, _bcOffset, 38, null);
- return _variantField_38;
- }
-
- @override
- idl.LinkedNodeTypeSubstitution get binaryExpression_substitution {
- assert(kind == idl.LinkedNodeKind.binaryExpression);
- _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
- .vTableGet(_bc, _bcOffset, 38, null);
- return _variantField_38;
- }
-
- @override
- idl.LinkedNodeTypeSubstitution get constructorName_substitution {
- assert(kind == idl.LinkedNodeKind.constructorName);
- _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
- .vTableGet(_bc, _bcOffset, 38, null);
- return _variantField_38;
- }
-
- @override
- idl.LinkedNodeTypeSubstitution get indexExpression_substitution {
- assert(kind == idl.LinkedNodeKind.indexExpression);
- _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
- .vTableGet(_bc, _bcOffset, 38, null);
- return _variantField_38;
- }
-
- @override
- idl.LinkedNodeTypeSubstitution get postfixExpression_substitution {
- assert(kind == idl.LinkedNodeKind.postfixExpression);
- _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
- .vTableGet(_bc, _bcOffset, 38, null);
- return _variantField_38;
- }
-
- @override
- idl.LinkedNodeTypeSubstitution get prefixExpression_substitution {
- assert(kind == idl.LinkedNodeKind.prefixExpression);
- _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
- .vTableGet(_bc, _bcOffset, 38, null);
- return _variantField_38;
- }
-
- @override
- idl.LinkedNodeTypeSubstitution
- get redirectingConstructorInvocation_substitution {
- assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
- _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
- .vTableGet(_bc, _bcOffset, 38, null);
- return _variantField_38;
- }
-
- @override
- idl.LinkedNodeTypeSubstitution get simpleIdentifier_substitution {
- assert(kind == idl.LinkedNodeKind.simpleIdentifier);
- _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
- .vTableGet(_bc, _bcOffset, 38, null);
- return _variantField_38;
- }
-
- @override
- idl.LinkedNodeTypeSubstitution get superConstructorInvocation_substitution {
- assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
- _variantField_38 ??= const _LinkedNodeTypeSubstitutionReader()
- .vTableGet(_bc, _bcOffset, 38, null);
- return _variantField_38;
- }
-
- @override
- int get assignmentExpression_element {
- assert(kind == idl.LinkedNodeKind.assignmentExpression);
- _variantField_15 ??=
- const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
- return _variantField_15;
- }
-
- @override
- int get binaryExpression_element {
- assert(kind == idl.LinkedNodeKind.binaryExpression);
- _variantField_15 ??=
- const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
- return _variantField_15;
- }
-
- @override
- int get constructorName_element {
- assert(kind == idl.LinkedNodeKind.constructorName);
- _variantField_15 ??=
- const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
- return _variantField_15;
- }
-
- @override
- int get emptyFunctionBody_fake {
- assert(kind == idl.LinkedNodeKind.emptyFunctionBody);
- _variantField_15 ??=
- const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
- return _variantField_15;
- }
-
- @override
- int get emptyStatement_fake {
- assert(kind == idl.LinkedNodeKind.emptyStatement);
- _variantField_15 ??=
- const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
- return _variantField_15;
- }
-
- @override
- int get indexExpression_element {
- assert(kind == idl.LinkedNodeKind.indexExpression);
- _variantField_15 ??=
- const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
- return _variantField_15;
- }
-
- @override
- int get nullLiteral_fake {
- assert(kind == idl.LinkedNodeKind.nullLiteral);
- _variantField_15 ??=
- const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
- return _variantField_15;
- }
-
- @override
- int get postfixExpression_element {
- assert(kind == idl.LinkedNodeKind.postfixExpression);
- _variantField_15 ??=
- const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
- return _variantField_15;
- }
-
- @override
- int get prefixExpression_element {
- assert(kind == idl.LinkedNodeKind.prefixExpression);
- _variantField_15 ??=
- const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
- return _variantField_15;
- }
-
- @override
- int get redirectingConstructorInvocation_element {
- assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
- _variantField_15 ??=
- const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
- return _variantField_15;
- }
-
- @override
- int get simpleIdentifier_element {
- assert(kind == idl.LinkedNodeKind.simpleIdentifier);
- _variantField_15 ??=
- const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
- return _variantField_15;
- }
-
- @override
- int get superConstructorInvocation_element {
- assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
- _variantField_15 ??=
- const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
- return _variantField_15;
- }
-
- @override
- int get typeParameter_variance {
- assert(kind == idl.LinkedNodeKind.typeParameter);
- _variantField_15 ??=
- const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 15, 0);
- return _variantField_15;
- }
-
- @override
- idl.UnlinkedTokenType get assignmentExpression_operator {
- assert(kind == idl.LinkedNodeKind.assignmentExpression);
- _variantField_28 ??= const _UnlinkedTokenTypeReader()
- .vTableGet(_bc, _bcOffset, 28, idl.UnlinkedTokenType.NOTHING);
- return _variantField_28;
- }
-
- @override
- idl.UnlinkedTokenType get binaryExpression_operator {
- assert(kind == idl.LinkedNodeKind.binaryExpression);
- _variantField_28 ??= const _UnlinkedTokenTypeReader()
- .vTableGet(_bc, _bcOffset, 28, idl.UnlinkedTokenType.NOTHING);
- return _variantField_28;
- }
-
- @override
- idl.UnlinkedTokenType get postfixExpression_operator {
- assert(kind == idl.LinkedNodeKind.postfixExpression);
- _variantField_28 ??= const _UnlinkedTokenTypeReader()
- .vTableGet(_bc, _bcOffset, 28, idl.UnlinkedTokenType.NOTHING);
- return _variantField_28;
- }
-
- @override
- idl.UnlinkedTokenType get prefixExpression_operator {
- assert(kind == idl.LinkedNodeKind.prefixExpression);
- _variantField_28 ??= const _UnlinkedTokenTypeReader()
- .vTableGet(_bc, _bcOffset, 28, idl.UnlinkedTokenType.NOTHING);
- return _variantField_28;
- }
-
- @override
- idl.UnlinkedTokenType get propertyAccess_operator {
- assert(kind == idl.LinkedNodeKind.propertyAccess);
- _variantField_28 ??= const _UnlinkedTokenTypeReader()
- .vTableGet(_bc, _bcOffset, 28, idl.UnlinkedTokenType.NOTHING);
- return _variantField_28;
- }
-
- @override
- bool get booleanLiteral_value {
- assert(kind == idl.LinkedNodeKind.booleanLiteral);
- _variantField_27 ??=
- const fb.BoolReader().vTableGet(_bc, _bcOffset, 27, false);
- return _variantField_27;
- }
-
- @override
- bool get classDeclaration_isDartObject {
- assert(kind == idl.LinkedNodeKind.classDeclaration);
- _variantField_27 ??=
- const fb.BoolReader().vTableGet(_bc, _bcOffset, 27, false);
- return _variantField_27;
- }
-
- @override
- bool get inheritsCovariant {
- assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
- kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
- kind == idl.LinkedNodeKind.simpleFormalParameter ||
- kind == idl.LinkedNodeKind.variableDeclaration);
- _variantField_27 ??=
- const fb.BoolReader().vTableGet(_bc, _bcOffset, 27, false);
- return _variantField_27;
- }
-
- @override
- bool get typeAlias_hasSelfReference {
- assert(kind == idl.LinkedNodeKind.functionTypeAlias ||
- kind == idl.LinkedNodeKind.genericTypeAlias);
- _variantField_27 ??=
- const fb.BoolReader().vTableGet(_bc, _bcOffset, 27, false);
- return _variantField_27;
- }
-
- @override
- idl.LinkedNode get catchClause_stackTraceParameter {
- assert(kind == idl.LinkedNodeKind.catchClause);
- _variantField_9 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 9, null);
- return _variantField_9;
- }
-
- @override
- idl.LinkedNode get classTypeAlias_implementsClause {
- assert(kind == idl.LinkedNodeKind.classTypeAlias);
- _variantField_9 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 9, null);
- return _variantField_9;
- }
-
- @override
- idl.LinkedNode get constructorDeclaration_redirectedConstructor {
- assert(kind == idl.LinkedNodeKind.constructorDeclaration);
- _variantField_9 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 9, null);
- return _variantField_9;
- }
-
- @override
- idl.LinkedNode get ifElement_elseElement {
- assert(kind == idl.LinkedNodeKind.ifElement);
- _variantField_9 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 9, null);
- return _variantField_9;
- }
-
- @override
- idl.LinkedNode get methodDeclaration_typeParameters {
- assert(kind == idl.LinkedNodeKind.methodDeclaration);
- _variantField_9 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 9, null);
- return _variantField_9;
- }
-
- @override
- idl.LinkedNode get classOrMixinDeclaration_implementsClause {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.mixinDeclaration);
- _variantField_12 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 12, null);
- return _variantField_12;
- }
-
- @override
- idl.LinkedNode get invocationExpression_typeArguments {
- assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
- kind == idl.LinkedNodeKind.methodInvocation);
- _variantField_12 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 12, null);
- return _variantField_12;
- }
-
- @override
- List<idl.LinkedNode> get classOrMixinDeclaration_members {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.mixinDeclaration);
- _variantField_5 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 5, const <idl.LinkedNode>[]);
- return _variantField_5;
- }
-
- @override
- List<idl.LinkedNode> get extensionDeclaration_members {
- assert(kind == idl.LinkedNodeKind.extensionDeclaration);
- _variantField_5 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 5, const <idl.LinkedNode>[]);
- return _variantField_5;
- }
-
- @override
- List<idl.LinkedNode> get forParts_updaters {
- assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
- kind == idl.LinkedNodeKind.forPartsWithExpression);
- _variantField_5 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 5, const <idl.LinkedNode>[]);
- return _variantField_5;
- }
-
- @override
- idl.LinkedNode get classOrMixinDeclaration_typeParameters {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.mixinDeclaration);
- _variantField_13 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 13, null);
- return _variantField_13;
- }
-
- @override
- List<String> get comment_tokens {
- assert(kind == idl.LinkedNodeKind.comment);
- _variantField_33 ??= const fb.ListReader<String>(fb.StringReader())
- .vTableGet(_bc, _bcOffset, 33, const <String>[]);
- return _variantField_33;
- }
-
- @override
- idl.LinkedNodeCommentType get comment_type {
- assert(kind == idl.LinkedNodeKind.comment);
- _variantField_29 ??= const _LinkedNodeCommentTypeReader()
- .vTableGet(_bc, _bcOffset, 29, idl.LinkedNodeCommentType.block);
- return _variantField_29;
- }
-
- @override
- List<idl.LinkedNode> get compilationUnit_directives {
- assert(kind == idl.LinkedNodeKind.compilationUnit);
- _variantField_3 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 3, const <idl.LinkedNode>[]);
- return _variantField_3;
- }
-
- @override
- List<idl.LinkedNode> get listLiteral_elements {
- assert(kind == idl.LinkedNodeKind.listLiteral);
- _variantField_3 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 3, const <idl.LinkedNode>[]);
- return _variantField_3;
- }
-
- @override
- List<idl.LinkedNode> get namespaceDirective_configurations {
- assert(kind == idl.LinkedNodeKind.exportDirective ||
- kind == idl.LinkedNodeKind.importDirective);
- _variantField_3 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 3, const <idl.LinkedNode>[]);
- return _variantField_3;
- }
-
- @override
- List<idl.LinkedNode> get setOrMapLiteral_elements {
- assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
- _variantField_3 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 3, const <idl.LinkedNode>[]);
- return _variantField_3;
- }
-
- @override
- List<idl.LinkedNode> get switchMember_labels {
- assert(kind == idl.LinkedNodeKind.switchCase ||
- kind == idl.LinkedNodeKind.switchDefault);
- _variantField_3 ??= const fb.ListReader<idl.LinkedNode>(_LinkedNodeReader())
- .vTableGet(_bc, _bcOffset, 3, const <idl.LinkedNode>[]);
- return _variantField_3;
- }
-
- @override
- List<int> get compilationUnit_featureSet {
- assert(kind == idl.LinkedNodeKind.compilationUnit);
- _variantField_41 ??= const fb.Uint32ListReader()
- .vTableGet(_bc, _bcOffset, 41, const <int>[]);
- return _variantField_41;
- }
-
- @override
- idl.LinkedLibraryLanguageVersion get compilationUnit_languageVersion {
- assert(kind == idl.LinkedNodeKind.compilationUnit);
- _variantField_40 ??= const _LinkedLibraryLanguageVersionReader()
- .vTableGet(_bc, _bcOffset, 40, null);
- return _variantField_40;
- }
-
- @override
- idl.LinkedNode get constructorDeclaration_returnType {
- assert(kind == idl.LinkedNodeKind.constructorDeclaration);
- _variantField_10 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 10, null);
- return _variantField_10;
- }
-
- @override
- idl.LinkedNodeFormalParameterKind get defaultFormalParameter_kind {
- assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
- _variantField_26 ??= const _LinkedNodeFormalParameterKindReader().vTableGet(
- _bc,
- _bcOffset,
- 26,
- idl.LinkedNodeFormalParameterKind.requiredPositional);
- return _variantField_26;
- }
-
- @override
- double get doubleLiteral_value {
- assert(kind == idl.LinkedNodeKind.doubleLiteral);
- _variantField_21 ??=
- const fb.Float64Reader().vTableGet(_bc, _bcOffset, 21, 0.0);
- return _variantField_21;
- }
-
- @override
- idl.LinkedNodeType get expression_type {
- assert(kind == idl.LinkedNodeKind.assignmentExpression ||
- kind == idl.LinkedNodeKind.asExpression ||
- kind == idl.LinkedNodeKind.awaitExpression ||
- kind == idl.LinkedNodeKind.binaryExpression ||
- kind == idl.LinkedNodeKind.cascadeExpression ||
- kind == idl.LinkedNodeKind.conditionalExpression ||
- kind == idl.LinkedNodeKind.functionExpressionInvocation ||
- kind == idl.LinkedNodeKind.indexExpression ||
- kind == idl.LinkedNodeKind.instanceCreationExpression ||
- kind == idl.LinkedNodeKind.integerLiteral ||
- kind == idl.LinkedNodeKind.listLiteral ||
- kind == idl.LinkedNodeKind.methodInvocation ||
- kind == idl.LinkedNodeKind.nullLiteral ||
- kind == idl.LinkedNodeKind.parenthesizedExpression ||
- kind == idl.LinkedNodeKind.prefixExpression ||
- kind == idl.LinkedNodeKind.prefixedIdentifier ||
- kind == idl.LinkedNodeKind.propertyAccess ||
- kind == idl.LinkedNodeKind.postfixExpression ||
- kind == idl.LinkedNodeKind.rethrowExpression ||
- kind == idl.LinkedNodeKind.setOrMapLiteral ||
- kind == idl.LinkedNodeKind.simpleIdentifier ||
- kind == idl.LinkedNodeKind.superExpression ||
- kind == idl.LinkedNodeKind.symbolLiteral ||
- kind == idl.LinkedNodeKind.thisExpression ||
- kind == idl.LinkedNodeKind.throwExpression);
- _variantField_25 ??=
- const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 25, null);
- return _variantField_25;
- }
-
- @override
- idl.LinkedNodeType get genericFunctionType_type {
- assert(kind == idl.LinkedNodeKind.genericFunctionType);
- _variantField_25 ??=
- const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 25, null);
- return _variantField_25;
- }
-
- @override
- String get extensionDeclaration_refName {
- assert(kind == idl.LinkedNodeKind.extensionDeclaration);
- _variantField_20 ??=
- const fb.StringReader().vTableGet(_bc, _bcOffset, 20, '');
- return _variantField_20;
- }
-
- @override
- String get namespaceDirective_selectedUri {
- assert(kind == idl.LinkedNodeKind.exportDirective ||
- kind == idl.LinkedNodeKind.importDirective);
- _variantField_20 ??=
- const fb.StringReader().vTableGet(_bc, _bcOffset, 20, '');
- return _variantField_20;
- }
-
- @override
- String get simpleStringLiteral_value {
- assert(kind == idl.LinkedNodeKind.simpleStringLiteral);
- _variantField_20 ??=
- const fb.StringReader().vTableGet(_bc, _bcOffset, 20, '');
- return _variantField_20;
- }
-
- @override
- List<idl.LinkedNodeType> get extensionOverride_typeArgumentTypes {
- assert(kind == idl.LinkedNodeKind.extensionOverride);
- _variantField_39 ??=
- const fb.ListReader<idl.LinkedNodeType>(_LinkedNodeTypeReader())
- .vTableGet(_bc, _bcOffset, 39, const <idl.LinkedNodeType>[]);
- return _variantField_39;
- }
-
- @override
- int get flags {
- _flags ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 18, 0);
- return _flags;
- }
-
- @override
- String get importDirective_prefix {
- assert(kind == idl.LinkedNodeKind.importDirective);
- _variantField_1 ??=
- const fb.StringReader().vTableGet(_bc, _bcOffset, 1, '');
- return _variantField_1;
- }
-
- @override
- int get informativeId {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.classTypeAlias ||
- kind == idl.LinkedNodeKind.compilationUnit ||
- kind == idl.LinkedNodeKind.compilationUnit ||
- kind == idl.LinkedNodeKind.constructorDeclaration ||
- kind == idl.LinkedNodeKind.defaultFormalParameter ||
- kind == idl.LinkedNodeKind.enumConstantDeclaration ||
- kind == idl.LinkedNodeKind.enumDeclaration ||
- kind == idl.LinkedNodeKind.exportDirective ||
- kind == idl.LinkedNodeKind.extensionDeclaration ||
- kind == idl.LinkedNodeKind.fieldDeclaration ||
- kind == idl.LinkedNodeKind.fieldFormalParameter ||
- kind == idl.LinkedNodeKind.functionDeclaration ||
- kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
- kind == idl.LinkedNodeKind.functionTypeAlias ||
- kind == idl.LinkedNodeKind.genericTypeAlias ||
- kind == idl.LinkedNodeKind.hideCombinator ||
- kind == idl.LinkedNodeKind.importDirective ||
- kind == idl.LinkedNodeKind.libraryDirective ||
- kind == idl.LinkedNodeKind.methodDeclaration ||
- kind == idl.LinkedNodeKind.mixinDeclaration ||
- kind == idl.LinkedNodeKind.partDirective ||
- kind == idl.LinkedNodeKind.partOfDirective ||
- kind == idl.LinkedNodeKind.showCombinator ||
- kind == idl.LinkedNodeKind.simpleFormalParameter ||
- kind == idl.LinkedNodeKind.topLevelVariableDeclaration ||
- kind == idl.LinkedNodeKind.typeParameter ||
- kind == idl.LinkedNodeKind.variableDeclaration ||
- kind == idl.LinkedNodeKind.variableDeclarationList);
- _variantField_36 ??=
- const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 36, 0);
- return _variantField_36;
- }
-
- @override
- int get integerLiteral_value {
- assert(kind == idl.LinkedNodeKind.integerLiteral);
- _variantField_16 ??=
- const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
- return _variantField_16;
- }
-
- @override
- String get interpolationString_value {
- assert(kind == idl.LinkedNodeKind.interpolationString);
- _variantField_30 ??=
- const fb.StringReader().vTableGet(_bc, _bcOffset, 30, '');
- return _variantField_30;
- }
-
- @override
- idl.LinkedNode get invocationExpression_arguments {
- assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
- kind == idl.LinkedNodeKind.methodInvocation);
- _variantField_14 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 14, null);
- return _variantField_14;
- }
-
- @override
- idl.LinkedNode get uriBasedDirective_uri {
- assert(kind == idl.LinkedNodeKind.exportDirective ||
- kind == idl.LinkedNodeKind.importDirective ||
- kind == idl.LinkedNodeKind.partDirective);
- _variantField_14 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 14, null);
- return _variantField_14;
- }
-
- @override
- idl.LinkedNodeKind get kind {
- _kind ??= const _LinkedNodeKindReader()
- .vTableGet(_bc, _bcOffset, 0, idl.LinkedNodeKind.adjacentStrings);
- return _kind;
- }
-
- @override
- bool get methodDeclaration_hasOperatorEqualWithParameterTypeFromObject {
- assert(kind == idl.LinkedNodeKind.methodDeclaration);
- _variantField_31 ??=
- const fb.BoolReader().vTableGet(_bc, _bcOffset, 31, false);
- return _variantField_31;
- }
-
- @override
- bool get simplyBoundable_isSimplyBounded {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.classTypeAlias ||
- kind == idl.LinkedNodeKind.functionTypeAlias ||
- kind == idl.LinkedNodeKind.genericTypeAlias ||
- kind == idl.LinkedNodeKind.mixinDeclaration);
- _variantField_31 ??=
- const fb.BoolReader().vTableGet(_bc, _bcOffset, 31, false);
- return _variantField_31;
- }
-
- @override
- List<String> get mixinDeclaration_superInvokedNames {
- assert(kind == idl.LinkedNodeKind.mixinDeclaration);
- _variantField_34 ??= const fb.ListReader<String>(fb.StringReader())
- .vTableGet(_bc, _bcOffset, 34, const <String>[]);
- return _variantField_34;
- }
-
- @override
- List<String> get names {
- assert(kind == idl.LinkedNodeKind.hideCombinator ||
- kind == idl.LinkedNodeKind.showCombinator ||
- kind == idl.LinkedNodeKind.symbolLiteral);
- _variantField_34 ??= const fb.ListReader<String>(fb.StringReader())
- .vTableGet(_bc, _bcOffset, 34, const <String>[]);
- return _variantField_34;
- }
-
- @override
- String get name {
- _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 37, '');
- return _name;
- }
-
- @override
- idl.UnlinkedTokenType get spreadElement_spreadOperator {
- assert(kind == idl.LinkedNodeKind.spreadElement);
- _variantField_35 ??= const _UnlinkedTokenTypeReader()
- .vTableGet(_bc, _bcOffset, 35, idl.UnlinkedTokenType.NOTHING);
- return _variantField_35;
- }
-
- @override
- idl.TopLevelInferenceError get topLevelTypeInferenceError {
- assert(kind == idl.LinkedNodeKind.methodDeclaration ||
- kind == idl.LinkedNodeKind.simpleFormalParameter ||
- kind == idl.LinkedNodeKind.variableDeclaration);
- _variantField_32 ??= const _TopLevelInferenceErrorReader()
- .vTableGet(_bc, _bcOffset, 32, null);
- return _variantField_32;
- }
-
- @override
- idl.LinkedNodeType get typeName_type {
- assert(kind == idl.LinkedNodeKind.typeName);
- _variantField_23 ??=
- const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 23, null);
- return _variantField_23;
- }
-
- @override
- idl.LinkedNodeType get typeParameter_defaultType {
- assert(kind == idl.LinkedNodeKind.typeParameter);
- _variantField_23 ??=
- const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 23, null);
- return _variantField_23;
- }
-
- @override
- idl.LinkedNode get unused11 {
- assert(kind == idl.LinkedNodeKind.classDeclaration);
- _variantField_11 ??=
- const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 11, null);
- return _variantField_11;
- }
-
- @override
- String get uriBasedDirective_uriContent {
- assert(kind == idl.LinkedNodeKind.exportDirective ||
- kind == idl.LinkedNodeKind.importDirective ||
- kind == idl.LinkedNodeKind.partDirective);
- _variantField_22 ??=
- const fb.StringReader().vTableGet(_bc, _bcOffset, 22, '');
- return _variantField_22;
- }
-
- @override
- int get uriBasedDirective_uriElement {
- assert(kind == idl.LinkedNodeKind.exportDirective ||
- kind == idl.LinkedNodeKind.importDirective ||
- kind == idl.LinkedNodeKind.partDirective);
- _variantField_19 ??=
- const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 19, 0);
- return _variantField_19;
- }
-}
-
-abstract class _LinkedNodeMixin implements idl.LinkedNode {
- @override
- Map<String, Object> toJson() {
- Map<String, Object> _result = <String, Object>{};
- if (flags != 0) {
- _result["flags"] = flags;
- }
- if (kind != idl.LinkedNodeKind.adjacentStrings) {
- _result["kind"] = kind.toString().split('.')[1];
- }
- if (name != '') {
- _result["name"] = name;
- }
- if (kind == idl.LinkedNodeKind.adjacentStrings) {
- if (adjacentStrings_strings.isNotEmpty) {
- _result["adjacentStrings_strings"] =
- adjacentStrings_strings.map((_value) => _value.toJson()).toList();
- }
- }
- if (kind == idl.LinkedNodeKind.annotation) {
- if (annotation_arguments != null) {
- _result["annotation_arguments"] = annotation_arguments.toJson();
- }
- if (annotation_constructorName != null) {
- _result["annotation_constructorName"] =
- annotation_constructorName.toJson();
- }
- if (annotation_element != 0) {
- _result["annotation_element"] = annotation_element;
- }
- if (annotation_name != null) {
- _result["annotation_name"] = annotation_name.toJson();
- }
- if (annotation_substitution != null) {
- _result["annotation_substitution"] = annotation_substitution.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.argumentList) {
- if (argumentList_arguments.isNotEmpty) {
- _result["argumentList_arguments"] =
- argumentList_arguments.map((_value) => _value.toJson()).toList();
- }
- }
- if (kind == idl.LinkedNodeKind.asExpression) {
- if (asExpression_expression != null) {
- _result["asExpression_expression"] = asExpression_expression.toJson();
- }
- if (asExpression_type != null) {
- _result["asExpression_type"] = asExpression_type.toJson();
- }
- if (expression_type != null) {
- _result["expression_type"] = expression_type.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.assertInitializer) {
- if (assertInitializer_condition != null) {
- _result["assertInitializer_condition"] =
- assertInitializer_condition.toJson();
- }
- if (assertInitializer_message != null) {
- _result["assertInitializer_message"] =
- assertInitializer_message.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.assertStatement) {
- if (assertStatement_condition != null) {
- _result["assertStatement_condition"] =
- assertStatement_condition.toJson();
- }
- if (assertStatement_message != null) {
- _result["assertStatement_message"] = assertStatement_message.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.assignmentExpression) {
- if (assignmentExpression_leftHandSide != null) {
- _result["assignmentExpression_leftHandSide"] =
- assignmentExpression_leftHandSide.toJson();
- }
- if (assignmentExpression_rightHandSide != null) {
- _result["assignmentExpression_rightHandSide"] =
- assignmentExpression_rightHandSide.toJson();
- }
- if (assignmentExpression_substitution != null) {
- _result["assignmentExpression_substitution"] =
- assignmentExpression_substitution.toJson();
- }
- if (assignmentExpression_element != 0) {
- _result["assignmentExpression_element"] = assignmentExpression_element;
- }
- if (assignmentExpression_operator != idl.UnlinkedTokenType.NOTHING) {
- _result["assignmentExpression_operator"] =
- assignmentExpression_operator.toString().split('.')[1];
- }
- if (expression_type != null) {
- _result["expression_type"] = expression_type.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.awaitExpression) {
- if (awaitExpression_expression != null) {
- _result["awaitExpression_expression"] =
- awaitExpression_expression.toJson();
- }
- if (expression_type != null) {
- _result["expression_type"] = expression_type.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.binaryExpression) {
- if (binaryExpression_invokeType != null) {
- _result["binaryExpression_invokeType"] =
- binaryExpression_invokeType.toJson();
- }
- if (binaryExpression_leftOperand != null) {
- _result["binaryExpression_leftOperand"] =
- binaryExpression_leftOperand.toJson();
- }
- if (binaryExpression_rightOperand != null) {
- _result["binaryExpression_rightOperand"] =
- binaryExpression_rightOperand.toJson();
- }
- if (binaryExpression_substitution != null) {
- _result["binaryExpression_substitution"] =
- binaryExpression_substitution.toJson();
- }
- if (binaryExpression_element != 0) {
- _result["binaryExpression_element"] = binaryExpression_element;
- }
- if (binaryExpression_operator != idl.UnlinkedTokenType.NOTHING) {
- _result["binaryExpression_operator"] =
- binaryExpression_operator.toString().split('.')[1];
- }
- if (expression_type != null) {
- _result["expression_type"] = expression_type.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.block) {
- if (block_statements.isNotEmpty) {
- _result["block_statements"] =
- block_statements.map((_value) => _value.toJson()).toList();
- }
- }
- if (kind == idl.LinkedNodeKind.blockFunctionBody) {
- if (blockFunctionBody_block != null) {
- _result["blockFunctionBody_block"] = blockFunctionBody_block.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.booleanLiteral) {
- if (booleanLiteral_value != false) {
- _result["booleanLiteral_value"] = booleanLiteral_value;
- }
- }
- if (kind == idl.LinkedNodeKind.breakStatement) {
- if (breakStatement_label != null) {
- _result["breakStatement_label"] = breakStatement_label.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.cascadeExpression) {
- if (cascadeExpression_sections.isNotEmpty) {
- _result["cascadeExpression_sections"] = cascadeExpression_sections
- .map((_value) => _value.toJson())
- .toList();
- }
- if (cascadeExpression_target != null) {
- _result["cascadeExpression_target"] = cascadeExpression_target.toJson();
- }
- if (expression_type != null) {
- _result["expression_type"] = expression_type.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.catchClause) {
- if (catchClause_body != null) {
- _result["catchClause_body"] = catchClause_body.toJson();
- }
- if (catchClause_exceptionParameter != null) {
- _result["catchClause_exceptionParameter"] =
- catchClause_exceptionParameter.toJson();
- }
- if (catchClause_exceptionType != null) {
- _result["catchClause_exceptionType"] =
- catchClause_exceptionType.toJson();
- }
- if (catchClause_stackTraceParameter != null) {
- _result["catchClause_stackTraceParameter"] =
- catchClause_stackTraceParameter.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.classDeclaration) {
- if (annotatedNode_metadata.isNotEmpty) {
- _result["annotatedNode_metadata"] =
- annotatedNode_metadata.map((_value) => _value.toJson()).toList();
- }
- if (classDeclaration_extendsClause != null) {
- _result["classDeclaration_extendsClause"] =
- classDeclaration_extendsClause.toJson();
- }
- if (classDeclaration_withClause != null) {
- _result["classDeclaration_withClause"] =
- classDeclaration_withClause.toJson();
- }
- if (classDeclaration_nativeClause != null) {
- _result["classDeclaration_nativeClause"] =
- classDeclaration_nativeClause.toJson();
- }
- if (classDeclaration_isDartObject != false) {
- _result["classDeclaration_isDartObject"] =
- classDeclaration_isDartObject;
- }
- if (classOrMixinDeclaration_implementsClause != null) {
- _result["classOrMixinDeclaration_implementsClause"] =
- classOrMixinDeclaration_implementsClause.toJson();
- }
- if (classOrMixinDeclaration_members.isNotEmpty) {
- _result["classOrMixinDeclaration_members"] =
- classOrMixinDeclaration_members
- .map((_value) => _value.toJson())
- .toList();
- }
- if (classOrMixinDeclaration_typeParameters != null) {
- _result["classOrMixinDeclaration_typeParameters"] =
- classOrMixinDeclaration_typeParameters.toJson();
- }
- if (informativeId != 0) {
- _result["informativeId"] = informativeId;
- }
- if (simplyBoundable_isSimplyBounded != false) {
- _result["simplyBoundable_isSimplyBounded"] =
- simplyBoundable_isSimplyBounded;
- }
- if (unused11 != null) {
- _result["unused11"] = unused11.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.classTypeAlias) {
- if (annotatedNode_metadata.isNotEmpty) {
- _result["annotatedNode_metadata"] =
- annotatedNode_metadata.map((_value) => _value.toJson()).toList();
- }
- if (classTypeAlias_typeParameters != null) {
- _result["classTypeAlias_typeParameters"] =
- classTypeAlias_typeParameters.toJson();
- }
- if (classTypeAlias_superclass != null) {
- _result["classTypeAlias_superclass"] =
- classTypeAlias_superclass.toJson();
- }
- if (classTypeAlias_withClause != null) {
- _result["classTypeAlias_withClause"] =
- classTypeAlias_withClause.toJson();
- }
- if (classTypeAlias_implementsClause != null) {
- _result["classTypeAlias_implementsClause"] =
- classTypeAlias_implementsClause.toJson();
- }
- if (informativeId != 0) {
- _result["informativeId"] = informativeId;
- }
- if (simplyBoundable_isSimplyBounded != false) {
- _result["simplyBoundable_isSimplyBounded"] =
- simplyBoundable_isSimplyBounded;
- }
- }
- if (kind == idl.LinkedNodeKind.comment) {
- if (comment_references.isNotEmpty) {
- _result["comment_references"] =
- comment_references.map((_value) => _value.toJson()).toList();
- }
- if (comment_tokens.isNotEmpty) {
- _result["comment_tokens"] = comment_tokens;
- }
- if (comment_type != idl.LinkedNodeCommentType.block) {
- _result["comment_type"] = comment_type.toString().split('.')[1];
- }
- }
- if (kind == idl.LinkedNodeKind.commentReference) {
- if (commentReference_identifier != null) {
- _result["commentReference_identifier"] =
- commentReference_identifier.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.compilationUnit) {
- if (compilationUnit_declarations.isNotEmpty) {
- _result["compilationUnit_declarations"] = compilationUnit_declarations
- .map((_value) => _value.toJson())
- .toList();
- }
- if (compilationUnit_scriptTag != null) {
- _result["compilationUnit_scriptTag"] =
- compilationUnit_scriptTag.toJson();
- }
- if (compilationUnit_directives.isNotEmpty) {
- _result["compilationUnit_directives"] = compilationUnit_directives
- .map((_value) => _value.toJson())
- .toList();
- }
- if (compilationUnit_featureSet.isNotEmpty) {
- _result["compilationUnit_featureSet"] = compilationUnit_featureSet;
- }
- if (compilationUnit_languageVersion != null) {
- _result["compilationUnit_languageVersion"] =
- compilationUnit_languageVersion.toJson();
- }
- if (informativeId != 0) {
- _result["informativeId"] = informativeId;
- }
- }
- if (kind == idl.LinkedNodeKind.conditionalExpression) {
- if (conditionalExpression_condition != null) {
- _result["conditionalExpression_condition"] =
- conditionalExpression_condition.toJson();
- }
- if (conditionalExpression_elseExpression != null) {
- _result["conditionalExpression_elseExpression"] =
- conditionalExpression_elseExpression.toJson();
- }
- if (conditionalExpression_thenExpression != null) {
- _result["conditionalExpression_thenExpression"] =
- conditionalExpression_thenExpression.toJson();
- }
- if (expression_type != null) {
- _result["expression_type"] = expression_type.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.configuration) {
- if (configuration_name != null) {
- _result["configuration_name"] = configuration_name.toJson();
- }
- if (configuration_value != null) {
- _result["configuration_value"] = configuration_value.toJson();
- }
- if (configuration_uri != null) {
- _result["configuration_uri"] = configuration_uri.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.constructorDeclaration) {
- if (constructorDeclaration_initializers.isNotEmpty) {
- _result["constructorDeclaration_initializers"] =
- constructorDeclaration_initializers
- .map((_value) => _value.toJson())
- .toList();
- }
- if (annotatedNode_metadata.isNotEmpty) {
- _result["annotatedNode_metadata"] =
- annotatedNode_metadata.map((_value) => _value.toJson()).toList();
- }
- if (constructorDeclaration_body != null) {
- _result["constructorDeclaration_body"] =
- constructorDeclaration_body.toJson();
- }
- if (constructorDeclaration_parameters != null) {
- _result["constructorDeclaration_parameters"] =
- constructorDeclaration_parameters.toJson();
- }
- if (constructorDeclaration_redirectedConstructor != null) {
- _result["constructorDeclaration_redirectedConstructor"] =
- constructorDeclaration_redirectedConstructor.toJson();
- }
- if (constructorDeclaration_returnType != null) {
- _result["constructorDeclaration_returnType"] =
- constructorDeclaration_returnType.toJson();
- }
- if (informativeId != 0) {
- _result["informativeId"] = informativeId;
- }
- }
- if (kind == idl.LinkedNodeKind.constructorFieldInitializer) {
- if (constructorFieldInitializer_expression != null) {
- _result["constructorFieldInitializer_expression"] =
- constructorFieldInitializer_expression.toJson();
- }
- if (constructorFieldInitializer_fieldName != null) {
- _result["constructorFieldInitializer_fieldName"] =
- constructorFieldInitializer_fieldName.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.constructorName) {
- if (constructorName_name != null) {
- _result["constructorName_name"] = constructorName_name.toJson();
- }
- if (constructorName_type != null) {
- _result["constructorName_type"] = constructorName_type.toJson();
- }
- if (constructorName_substitution != null) {
- _result["constructorName_substitution"] =
- constructorName_substitution.toJson();
- }
- if (constructorName_element != 0) {
- _result["constructorName_element"] = constructorName_element;
- }
- }
- if (kind == idl.LinkedNodeKind.continueStatement) {
- if (continueStatement_label != null) {
- _result["continueStatement_label"] = continueStatement_label.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.declaredIdentifier) {
- if (annotatedNode_metadata.isNotEmpty) {
- _result["annotatedNode_metadata"] =
- annotatedNode_metadata.map((_value) => _value.toJson()).toList();
- }
- if (declaredIdentifier_identifier != null) {
- _result["declaredIdentifier_identifier"] =
- declaredIdentifier_identifier.toJson();
- }
- if (declaredIdentifier_type != null) {
- _result["declaredIdentifier_type"] = declaredIdentifier_type.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.defaultFormalParameter) {
- if (defaultFormalParameter_defaultValue != null) {
- _result["defaultFormalParameter_defaultValue"] =
- defaultFormalParameter_defaultValue.toJson();
- }
- if (defaultFormalParameter_parameter != null) {
- _result["defaultFormalParameter_parameter"] =
- defaultFormalParameter_parameter.toJson();
- }
- if (defaultFormalParameter_kind !=
- idl.LinkedNodeFormalParameterKind.requiredPositional) {
- _result["defaultFormalParameter_kind"] =
- defaultFormalParameter_kind.toString().split('.')[1];
- }
- if (informativeId != 0) {
- _result["informativeId"] = informativeId;
- }
- }
- if (kind == idl.LinkedNodeKind.doStatement) {
- if (doStatement_body != null) {
- _result["doStatement_body"] = doStatement_body.toJson();
- }
- if (doStatement_condition != null) {
- _result["doStatement_condition"] = doStatement_condition.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.dottedName) {
- if (dottedName_components.isNotEmpty) {
- _result["dottedName_components"] =
- dottedName_components.map((_value) => _value.toJson()).toList();
- }
- }
- if (kind == idl.LinkedNodeKind.doubleLiteral) {
- if (doubleLiteral_value != 0.0) {
- _result["doubleLiteral_value"] = doubleLiteral_value.isFinite
- ? doubleLiteral_value
- : doubleLiteral_value.toString();
- }
- }
- if (kind == idl.LinkedNodeKind.emptyFunctionBody) {
- if (emptyFunctionBody_fake != 0) {
- _result["emptyFunctionBody_fake"] = emptyFunctionBody_fake;
- }
- }
- if (kind == idl.LinkedNodeKind.emptyStatement) {
- if (emptyStatement_fake != 0) {
- _result["emptyStatement_fake"] = emptyStatement_fake;
- }
- }
- if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
- if (annotatedNode_metadata.isNotEmpty) {
- _result["annotatedNode_metadata"] =
- annotatedNode_metadata.map((_value) => _value.toJson()).toList();
- }
- if (informativeId != 0) {
- _result["informativeId"] = informativeId;
- }
- }
- if (kind == idl.LinkedNodeKind.enumDeclaration) {
- if (enumDeclaration_constants.isNotEmpty) {
- _result["enumDeclaration_constants"] =
- enumDeclaration_constants.map((_value) => _value.toJson()).toList();
- }
- if (annotatedNode_metadata.isNotEmpty) {
- _result["annotatedNode_metadata"] =
- annotatedNode_metadata.map((_value) => _value.toJson()).toList();
- }
- if (informativeId != 0) {
- _result["informativeId"] = informativeId;
- }
- }
- if (kind == idl.LinkedNodeKind.exportDirective) {
- if (namespaceDirective_combinators.isNotEmpty) {
- _result["namespaceDirective_combinators"] =
- namespaceDirective_combinators
- .map((_value) => _value.toJson())
- .toList();
- }
- if (annotatedNode_metadata.isNotEmpty) {
- _result["annotatedNode_metadata"] =
- annotatedNode_metadata.map((_value) => _value.toJson()).toList();
- }
- if (namespaceDirective_configurations.isNotEmpty) {
- _result["namespaceDirective_configurations"] =
- namespaceDirective_configurations
- .map((_value) => _value.toJson())
- .toList();
- }
- if (namespaceDirective_selectedUri != '') {
- _result["namespaceDirective_selectedUri"] =
- namespaceDirective_selectedUri;
- }
- if (informativeId != 0) {
- _result["informativeId"] = informativeId;
- }
- if (uriBasedDirective_uri != null) {
- _result["uriBasedDirective_uri"] = uriBasedDirective_uri.toJson();
- }
- if (uriBasedDirective_uriContent != '') {
- _result["uriBasedDirective_uriContent"] = uriBasedDirective_uriContent;
- }
- if (uriBasedDirective_uriElement != 0) {
- _result["uriBasedDirective_uriElement"] = uriBasedDirective_uriElement;
- }
- }
- if (kind == idl.LinkedNodeKind.expressionFunctionBody) {
- if (expressionFunctionBody_expression != null) {
- _result["expressionFunctionBody_expression"] =
- expressionFunctionBody_expression.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.expressionStatement) {
- if (expressionStatement_expression != null) {
- _result["expressionStatement_expression"] =
- expressionStatement_expression.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.extendsClause) {
- if (extendsClause_superclass != null) {
- _result["extendsClause_superclass"] = extendsClause_superclass.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.extensionDeclaration) {
- if (annotatedNode_metadata.isNotEmpty) {
- _result["annotatedNode_metadata"] =
- annotatedNode_metadata.map((_value) => _value.toJson()).toList();
- }
- if (extensionDeclaration_typeParameters != null) {
- _result["extensionDeclaration_typeParameters"] =
- extensionDeclaration_typeParameters.toJson();
- }
- if (extensionDeclaration_extendedType != null) {
- _result["extensionDeclaration_extendedType"] =
- extensionDeclaration_extendedType.toJson();
- }
- if (extensionDeclaration_members.isNotEmpty) {
- _result["extensionDeclaration_members"] = extensionDeclaration_members
- .map((_value) => _value.toJson())
- .toList();
- }
- if (extensionDeclaration_refName != '') {
- _result["extensionDeclaration_refName"] = extensionDeclaration_refName;
- }
- if (informativeId != 0) {
- _result["informativeId"] = informativeId;
- }
- }
- if (kind == idl.LinkedNodeKind.extensionOverride) {
- if (extensionOverride_extendedType != null) {
- _result["extensionOverride_extendedType"] =
- extensionOverride_extendedType.toJson();
- }
- if (extensionOverride_arguments.isNotEmpty) {
- _result["extensionOverride_arguments"] = extensionOverride_arguments
- .map((_value) => _value.toJson())
- .toList();
- }
- if (extensionOverride_extensionName != null) {
- _result["extensionOverride_extensionName"] =
- extensionOverride_extensionName.toJson();
- }
- if (extensionOverride_typeArguments != null) {
- _result["extensionOverride_typeArguments"] =
- extensionOverride_typeArguments.toJson();
- }
- if (extensionOverride_typeArgumentTypes.isNotEmpty) {
- _result["extensionOverride_typeArgumentTypes"] =
- extensionOverride_typeArgumentTypes
- .map((_value) => _value.toJson())
- .toList();
- }
- }
- if (kind == idl.LinkedNodeKind.fieldDeclaration) {
- if (annotatedNode_metadata.isNotEmpty) {
- _result["annotatedNode_metadata"] =
- annotatedNode_metadata.map((_value) => _value.toJson()).toList();
- }
- if (fieldDeclaration_fields != null) {
- _result["fieldDeclaration_fields"] = fieldDeclaration_fields.toJson();
- }
- if (informativeId != 0) {
- _result["informativeId"] = informativeId;
- }
- }
- if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
- if (actualType != null) {
- _result["actualType"] = actualType.toJson();
- }
- if (normalFormalParameter_metadata.isNotEmpty) {
- _result["normalFormalParameter_metadata"] =
- normalFormalParameter_metadata
- .map((_value) => _value.toJson())
- .toList();
- }
- if (fieldFormalParameter_type != null) {
- _result["fieldFormalParameter_type"] =
- fieldFormalParameter_type.toJson();
- }
- if (fieldFormalParameter_typeParameters != null) {
- _result["fieldFormalParameter_typeParameters"] =
- fieldFormalParameter_typeParameters.toJson();
- }
- if (fieldFormalParameter_formalParameters != null) {
- _result["fieldFormalParameter_formalParameters"] =
- fieldFormalParameter_formalParameters.toJson();
- }
- if (inheritsCovariant != false) {
- _result["inheritsCovariant"] = inheritsCovariant;
- }
- if (informativeId != 0) {
- _result["informativeId"] = informativeId;
- }
- }
- if (kind == idl.LinkedNodeKind.forEachPartsWithDeclaration) {
- if (forEachParts_iterable != null) {
- _result["forEachParts_iterable"] = forEachParts_iterable.toJson();
- }
- if (forEachPartsWithDeclaration_loopVariable != null) {
- _result["forEachPartsWithDeclaration_loopVariable"] =
- forEachPartsWithDeclaration_loopVariable.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.forEachPartsWithIdentifier) {
- if (forEachParts_iterable != null) {
- _result["forEachParts_iterable"] = forEachParts_iterable.toJson();
- }
- if (forEachPartsWithIdentifier_identifier != null) {
- _result["forEachPartsWithIdentifier_identifier"] =
- forEachPartsWithIdentifier_identifier.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.forElement) {
- if (forMixin_forLoopParts != null) {
- _result["forMixin_forLoopParts"] = forMixin_forLoopParts.toJson();
- }
- if (forElement_body != null) {
- _result["forElement_body"] = forElement_body.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.forPartsWithDeclarations) {
- if (forParts_condition != null) {
- _result["forParts_condition"] = forParts_condition.toJson();
- }
- if (forPartsWithDeclarations_variables != null) {
- _result["forPartsWithDeclarations_variables"] =
- forPartsWithDeclarations_variables.toJson();
- }
- if (forParts_updaters.isNotEmpty) {
- _result["forParts_updaters"] =
- forParts_updaters.map((_value) => _value.toJson()).toList();
- }
- }
- if (kind == idl.LinkedNodeKind.forPartsWithExpression) {
- if (forParts_condition != null) {
- _result["forParts_condition"] = forParts_condition.toJson();
- }
- if (forPartsWithExpression_initialization != null) {
- _result["forPartsWithExpression_initialization"] =
- forPartsWithExpression_initialization.toJson();
- }
- if (forParts_updaters.isNotEmpty) {
- _result["forParts_updaters"] =
- forParts_updaters.map((_value) => _value.toJson()).toList();
- }
- }
- if (kind == idl.LinkedNodeKind.forStatement) {
- if (forMixin_forLoopParts != null) {
- _result["forMixin_forLoopParts"] = forMixin_forLoopParts.toJson();
- }
- if (forStatement_body != null) {
- _result["forStatement_body"] = forStatement_body.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.formalParameterList) {
- if (formalParameterList_parameters.isNotEmpty) {
- _result["formalParameterList_parameters"] =
- formalParameterList_parameters
- .map((_value) => _value.toJson())
- .toList();
- }
- }
- if (kind == idl.LinkedNodeKind.functionDeclaration) {
- if (actualReturnType != null) {
- _result["actualReturnType"] = actualReturnType.toJson();
- }
- if (annotatedNode_metadata.isNotEmpty) {
- _result["annotatedNode_metadata"] =
- annotatedNode_metadata.map((_value) => _value.toJson()).toList();
- }
- if (functionDeclaration_functionExpression != null) {
- _result["functionDeclaration_functionExpression"] =
- functionDeclaration_functionExpression.toJson();
- }
- if (functionDeclaration_returnType != null) {
- _result["functionDeclaration_returnType"] =
- functionDeclaration_returnType.toJson();
- }
- if (informativeId != 0) {
- _result["informativeId"] = informativeId;
- }
- }
- if (kind == idl.LinkedNodeKind.functionDeclarationStatement) {
- if (functionDeclarationStatement_functionDeclaration != null) {
- _result["functionDeclarationStatement_functionDeclaration"] =
- functionDeclarationStatement_functionDeclaration.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.functionExpression) {
- if (actualReturnType != null) {
- _result["actualReturnType"] = actualReturnType.toJson();
- }
- if (functionExpression_body != null) {
- _result["functionExpression_body"] = functionExpression_body.toJson();
- }
- if (functionExpression_formalParameters != null) {
- _result["functionExpression_formalParameters"] =
- functionExpression_formalParameters.toJson();
- }
- if (functionExpression_typeParameters != null) {
- _result["functionExpression_typeParameters"] =
- functionExpression_typeParameters.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.functionExpressionInvocation) {
- if (invocationExpression_invokeType != null) {
- _result["invocationExpression_invokeType"] =
- invocationExpression_invokeType.toJson();
- }
- if (functionExpressionInvocation_function != null) {
- _result["functionExpressionInvocation_function"] =
- functionExpressionInvocation_function.toJson();
- }
- if (invocationExpression_typeArguments != null) {
- _result["invocationExpression_typeArguments"] =
- invocationExpression_typeArguments.toJson();
- }
- if (expression_type != null) {
- _result["expression_type"] = expression_type.toJson();
- }
- if (invocationExpression_arguments != null) {
- _result["invocationExpression_arguments"] =
- invocationExpression_arguments.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.functionTypeAlias) {
- if (actualReturnType != null) {
- _result["actualReturnType"] = actualReturnType.toJson();
- }
- if (annotatedNode_metadata.isNotEmpty) {
- _result["annotatedNode_metadata"] =
- annotatedNode_metadata.map((_value) => _value.toJson()).toList();
- }
- if (functionTypeAlias_formalParameters != null) {
- _result["functionTypeAlias_formalParameters"] =
- functionTypeAlias_formalParameters.toJson();
- }
- if (functionTypeAlias_returnType != null) {
- _result["functionTypeAlias_returnType"] =
- functionTypeAlias_returnType.toJson();
- }
- if (functionTypeAlias_typeParameters != null) {
- _result["functionTypeAlias_typeParameters"] =
- functionTypeAlias_typeParameters.toJson();
- }
- if (typeAlias_hasSelfReference != false) {
- _result["typeAlias_hasSelfReference"] = typeAlias_hasSelfReference;
- }
- if (informativeId != 0) {
- _result["informativeId"] = informativeId;
- }
- if (simplyBoundable_isSimplyBounded != false) {
- _result["simplyBoundable_isSimplyBounded"] =
- simplyBoundable_isSimplyBounded;
- }
- }
- if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) {
- if (actualType != null) {
- _result["actualType"] = actualType.toJson();
- }
- if (normalFormalParameter_metadata.isNotEmpty) {
- _result["normalFormalParameter_metadata"] =
- normalFormalParameter_metadata
- .map((_value) => _value.toJson())
- .toList();
- }
- if (functionTypedFormalParameter_formalParameters != null) {
- _result["functionTypedFormalParameter_formalParameters"] =
- functionTypedFormalParameter_formalParameters.toJson();
- }
- if (functionTypedFormalParameter_returnType != null) {
- _result["functionTypedFormalParameter_returnType"] =
- functionTypedFormalParameter_returnType.toJson();
- }
- if (functionTypedFormalParameter_typeParameters != null) {
- _result["functionTypedFormalParameter_typeParameters"] =
- functionTypedFormalParameter_typeParameters.toJson();
- }
- if (inheritsCovariant != false) {
- _result["inheritsCovariant"] = inheritsCovariant;
- }
- if (informativeId != 0) {
- _result["informativeId"] = informativeId;
- }
- }
- if (kind == idl.LinkedNodeKind.genericFunctionType) {
- if (actualReturnType != null) {
- _result["actualReturnType"] = actualReturnType.toJson();
- }
- if (genericFunctionType_typeParameters != null) {
- _result["genericFunctionType_typeParameters"] =
- genericFunctionType_typeParameters.toJson();
- }
- if (genericFunctionType_returnType != null) {
- _result["genericFunctionType_returnType"] =
- genericFunctionType_returnType.toJson();
- }
- if (genericFunctionType_id != 0) {
- _result["genericFunctionType_id"] = genericFunctionType_id;
- }
- if (genericFunctionType_formalParameters != null) {
- _result["genericFunctionType_formalParameters"] =
- genericFunctionType_formalParameters.toJson();
- }
- if (genericFunctionType_type != null) {
- _result["genericFunctionType_type"] = genericFunctionType_type.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.genericTypeAlias) {
- if (annotatedNode_metadata.isNotEmpty) {
- _result["annotatedNode_metadata"] =
- annotatedNode_metadata.map((_value) => _value.toJson()).toList();
- }
- if (genericTypeAlias_typeParameters != null) {
- _result["genericTypeAlias_typeParameters"] =
- genericTypeAlias_typeParameters.toJson();
- }
- if (genericTypeAlias_functionType != null) {
- _result["genericTypeAlias_functionType"] =
- genericTypeAlias_functionType.toJson();
- }
- if (typeAlias_hasSelfReference != false) {
- _result["typeAlias_hasSelfReference"] = typeAlias_hasSelfReference;
- }
- if (informativeId != 0) {
- _result["informativeId"] = informativeId;
- }
- if (simplyBoundable_isSimplyBounded != false) {
- _result["simplyBoundable_isSimplyBounded"] =
- simplyBoundable_isSimplyBounded;
- }
- }
- if (kind == idl.LinkedNodeKind.hideCombinator) {
- if (informativeId != 0) {
- _result["informativeId"] = informativeId;
- }
- if (names.isNotEmpty) {
- _result["names"] = names;
- }
- }
- if (kind == idl.LinkedNodeKind.ifElement) {
- if (ifMixin_condition != null) {
- _result["ifMixin_condition"] = ifMixin_condition.toJson();
- }
- if (ifElement_thenElement != null) {
- _result["ifElement_thenElement"] = ifElement_thenElement.toJson();
- }
- if (ifElement_elseElement != null) {
- _result["ifElement_elseElement"] = ifElement_elseElement.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.ifStatement) {
- if (ifMixin_condition != null) {
- _result["ifMixin_condition"] = ifMixin_condition.toJson();
- }
- if (ifStatement_elseStatement != null) {
- _result["ifStatement_elseStatement"] =
- ifStatement_elseStatement.toJson();
- }
- if (ifStatement_thenStatement != null) {
- _result["ifStatement_thenStatement"] =
- ifStatement_thenStatement.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.implementsClause) {
- if (implementsClause_interfaces.isNotEmpty) {
- _result["implementsClause_interfaces"] = implementsClause_interfaces
- .map((_value) => _value.toJson())
- .toList();
- }
- }
- if (kind == idl.LinkedNodeKind.importDirective) {
- if (namespaceDirective_combinators.isNotEmpty) {
- _result["namespaceDirective_combinators"] =
- namespaceDirective_combinators
- .map((_value) => _value.toJson())
- .toList();
- }
- if (annotatedNode_metadata.isNotEmpty) {
- _result["annotatedNode_metadata"] =
- annotatedNode_metadata.map((_value) => _value.toJson()).toList();
- }
- if (namespaceDirective_configurations.isNotEmpty) {
- _result["namespaceDirective_configurations"] =
- namespaceDirective_configurations
- .map((_value) => _value.toJson())
- .toList();
- }
- if (namespaceDirective_selectedUri != '') {
- _result["namespaceDirective_selectedUri"] =
- namespaceDirective_selectedUri;
- }
- if (importDirective_prefix != '') {
- _result["importDirective_prefix"] = importDirective_prefix;
- }
- if (informativeId != 0) {
- _result["informativeId"] = informativeId;
- }
- if (uriBasedDirective_uri != null) {
- _result["uriBasedDirective_uri"] = uriBasedDirective_uri.toJson();
- }
- if (uriBasedDirective_uriContent != '') {
- _result["uriBasedDirective_uriContent"] = uriBasedDirective_uriContent;
- }
- if (uriBasedDirective_uriElement != 0) {
- _result["uriBasedDirective_uriElement"] = uriBasedDirective_uriElement;
- }
- }
- if (kind == idl.LinkedNodeKind.indexExpression) {
- if (indexExpression_index != null) {
- _result["indexExpression_index"] = indexExpression_index.toJson();
- }
- if (indexExpression_target != null) {
- _result["indexExpression_target"] = indexExpression_target.toJson();
- }
- if (indexExpression_substitution != null) {
- _result["indexExpression_substitution"] =
- indexExpression_substitution.toJson();
- }
- if (indexExpression_element != 0) {
- _result["indexExpression_element"] = indexExpression_element;
- }
- if (expression_type != null) {
- _result["expression_type"] = expression_type.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.instanceCreationExpression) {
- if (instanceCreationExpression_arguments.isNotEmpty) {
- _result["instanceCreationExpression_arguments"] =
- instanceCreationExpression_arguments
- .map((_value) => _value.toJson())
- .toList();
- }
- if (instanceCreationExpression_constructorName != null) {
- _result["instanceCreationExpression_constructorName"] =
- instanceCreationExpression_constructorName.toJson();
- }
- if (instanceCreationExpression_typeArguments != null) {
- _result["instanceCreationExpression_typeArguments"] =
- instanceCreationExpression_typeArguments.toJson();
- }
- if (expression_type != null) {
- _result["expression_type"] = expression_type.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.integerLiteral) {
- if (expression_type != null) {
- _result["expression_type"] = expression_type.toJson();
- }
- if (integerLiteral_value != 0) {
- _result["integerLiteral_value"] = integerLiteral_value;
- }
- }
- if (kind == idl.LinkedNodeKind.interpolationExpression) {
- if (interpolationExpression_expression != null) {
- _result["interpolationExpression_expression"] =
- interpolationExpression_expression.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.interpolationString) {
- if (interpolationString_value != '') {
- _result["interpolationString_value"] = interpolationString_value;
- }
- }
- if (kind == idl.LinkedNodeKind.isExpression) {
- if (isExpression_expression != null) {
- _result["isExpression_expression"] = isExpression_expression.toJson();
- }
- if (isExpression_type != null) {
- _result["isExpression_type"] = isExpression_type.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.label) {
- if (label_label != null) {
- _result["label_label"] = label_label.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.labeledStatement) {
- if (labeledStatement_labels.isNotEmpty) {
- _result["labeledStatement_labels"] =
- labeledStatement_labels.map((_value) => _value.toJson()).toList();
- }
- if (labeledStatement_statement != null) {
- _result["labeledStatement_statement"] =
- labeledStatement_statement.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.libraryDirective) {
- if (annotatedNode_metadata.isNotEmpty) {
- _result["annotatedNode_metadata"] =
- annotatedNode_metadata.map((_value) => _value.toJson()).toList();
- }
- if (libraryDirective_name != null) {
- _result["libraryDirective_name"] = libraryDirective_name.toJson();
- }
- if (informativeId != 0) {
- _result["informativeId"] = informativeId;
- }
- }
- if (kind == idl.LinkedNodeKind.libraryIdentifier) {
- if (libraryIdentifier_components.isNotEmpty) {
- _result["libraryIdentifier_components"] = libraryIdentifier_components
- .map((_value) => _value.toJson())
- .toList();
- }
- }
- if (kind == idl.LinkedNodeKind.listLiteral) {
- if (typedLiteral_typeArguments.isNotEmpty) {
- _result["typedLiteral_typeArguments"] = typedLiteral_typeArguments
- .map((_value) => _value.toJson())
- .toList();
- }
- if (listLiteral_elements.isNotEmpty) {
- _result["listLiteral_elements"] =
- listLiteral_elements.map((_value) => _value.toJson()).toList();
- }
- if (expression_type != null) {
- _result["expression_type"] = expression_type.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.mapLiteralEntry) {
- if (mapLiteralEntry_key != null) {
- _result["mapLiteralEntry_key"] = mapLiteralEntry_key.toJson();
- }
- if (mapLiteralEntry_value != null) {
- _result["mapLiteralEntry_value"] = mapLiteralEntry_value.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.methodDeclaration) {
- if (actualReturnType != null) {
- _result["actualReturnType"] = actualReturnType.toJson();
- }
- if (annotatedNode_metadata.isNotEmpty) {
- _result["annotatedNode_metadata"] =
- annotatedNode_metadata.map((_value) => _value.toJson()).toList();
- }
- if (methodDeclaration_body != null) {
- _result["methodDeclaration_body"] = methodDeclaration_body.toJson();
- }
- if (methodDeclaration_formalParameters != null) {
- _result["methodDeclaration_formalParameters"] =
- methodDeclaration_formalParameters.toJson();
- }
- if (methodDeclaration_returnType != null) {
- _result["methodDeclaration_returnType"] =
- methodDeclaration_returnType.toJson();
- }
- if (methodDeclaration_typeParameters != null) {
- _result["methodDeclaration_typeParameters"] =
- methodDeclaration_typeParameters.toJson();
- }
- if (informativeId != 0) {
- _result["informativeId"] = informativeId;
- }
- if (methodDeclaration_hasOperatorEqualWithParameterTypeFromObject !=
- false) {
- _result["methodDeclaration_hasOperatorEqualWithParameterTypeFromObject"] =
- methodDeclaration_hasOperatorEqualWithParameterTypeFromObject;
- }
- if (topLevelTypeInferenceError != null) {
- _result["topLevelTypeInferenceError"] =
- topLevelTypeInferenceError.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.methodInvocation) {
- if (invocationExpression_invokeType != null) {
- _result["invocationExpression_invokeType"] =
- invocationExpression_invokeType.toJson();
- }
- if (methodInvocation_methodName != null) {
- _result["methodInvocation_methodName"] =
- methodInvocation_methodName.toJson();
- }
- if (methodInvocation_target != null) {
- _result["methodInvocation_target"] = methodInvocation_target.toJson();
- }
- if (invocationExpression_typeArguments != null) {
- _result["invocationExpression_typeArguments"] =
- invocationExpression_typeArguments.toJson();
- }
- if (expression_type != null) {
- _result["expression_type"] = expression_type.toJson();
- }
- if (invocationExpression_arguments != null) {
- _result["invocationExpression_arguments"] =
- invocationExpression_arguments.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.mixinDeclaration) {
- if (annotatedNode_metadata.isNotEmpty) {
- _result["annotatedNode_metadata"] =
- annotatedNode_metadata.map((_value) => _value.toJson()).toList();
- }
- if (mixinDeclaration_onClause != null) {
- _result["mixinDeclaration_onClause"] =
- mixinDeclaration_onClause.toJson();
- }
- if (classOrMixinDeclaration_implementsClause != null) {
- _result["classOrMixinDeclaration_implementsClause"] =
- classOrMixinDeclaration_implementsClause.toJson();
- }
- if (classOrMixinDeclaration_members.isNotEmpty) {
- _result["classOrMixinDeclaration_members"] =
- classOrMixinDeclaration_members
- .map((_value) => _value.toJson())
- .toList();
- }
- if (classOrMixinDeclaration_typeParameters != null) {
- _result["classOrMixinDeclaration_typeParameters"] =
- classOrMixinDeclaration_typeParameters.toJson();
- }
- if (informativeId != 0) {
- _result["informativeId"] = informativeId;
- }
- if (simplyBoundable_isSimplyBounded != false) {
- _result["simplyBoundable_isSimplyBounded"] =
- simplyBoundable_isSimplyBounded;
- }
- if (mixinDeclaration_superInvokedNames.isNotEmpty) {
- _result["mixinDeclaration_superInvokedNames"] =
- mixinDeclaration_superInvokedNames;
- }
- }
- if (kind == idl.LinkedNodeKind.namedExpression) {
- if (namedExpression_expression != null) {
- _result["namedExpression_expression"] =
- namedExpression_expression.toJson();
- }
- if (namedExpression_name != null) {
- _result["namedExpression_name"] = namedExpression_name.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.nativeClause) {
- if (nativeClause_name != null) {
- _result["nativeClause_name"] = nativeClause_name.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.nativeFunctionBody) {
- if (nativeFunctionBody_stringLiteral != null) {
- _result["nativeFunctionBody_stringLiteral"] =
- nativeFunctionBody_stringLiteral.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.nullLiteral) {
- if (nullLiteral_fake != 0) {
- _result["nullLiteral_fake"] = nullLiteral_fake;
- }
- if (expression_type != null) {
- _result["expression_type"] = expression_type.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.onClause) {
- if (onClause_superclassConstraints.isNotEmpty) {
- _result["onClause_superclassConstraints"] =
- onClause_superclassConstraints
- .map((_value) => _value.toJson())
- .toList();
- }
- }
- if (kind == idl.LinkedNodeKind.parenthesizedExpression) {
- if (parenthesizedExpression_expression != null) {
- _result["parenthesizedExpression_expression"] =
- parenthesizedExpression_expression.toJson();
- }
- if (expression_type != null) {
- _result["expression_type"] = expression_type.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.partDirective) {
- if (annotatedNode_metadata.isNotEmpty) {
- _result["annotatedNode_metadata"] =
- annotatedNode_metadata.map((_value) => _value.toJson()).toList();
- }
- if (informativeId != 0) {
- _result["informativeId"] = informativeId;
- }
- if (uriBasedDirective_uri != null) {
- _result["uriBasedDirective_uri"] = uriBasedDirective_uri.toJson();
- }
- if (uriBasedDirective_uriContent != '') {
- _result["uriBasedDirective_uriContent"] = uriBasedDirective_uriContent;
- }
- if (uriBasedDirective_uriElement != 0) {
- _result["uriBasedDirective_uriElement"] = uriBasedDirective_uriElement;
- }
- }
- if (kind == idl.LinkedNodeKind.partOfDirective) {
- if (annotatedNode_metadata.isNotEmpty) {
- _result["annotatedNode_metadata"] =
- annotatedNode_metadata.map((_value) => _value.toJson()).toList();
- }
- if (partOfDirective_libraryName != null) {
- _result["partOfDirective_libraryName"] =
- partOfDirective_libraryName.toJson();
- }
- if (partOfDirective_uri != null) {
- _result["partOfDirective_uri"] = partOfDirective_uri.toJson();
- }
- if (informativeId != 0) {
- _result["informativeId"] = informativeId;
- }
- }
- if (kind == idl.LinkedNodeKind.postfixExpression) {
- if (postfixExpression_operand != null) {
- _result["postfixExpression_operand"] =
- postfixExpression_operand.toJson();
- }
- if (postfixExpression_substitution != null) {
- _result["postfixExpression_substitution"] =
- postfixExpression_substitution.toJson();
- }
- if (postfixExpression_element != 0) {
- _result["postfixExpression_element"] = postfixExpression_element;
- }
- if (postfixExpression_operator != idl.UnlinkedTokenType.NOTHING) {
- _result["postfixExpression_operator"] =
- postfixExpression_operator.toString().split('.')[1];
- }
- if (expression_type != null) {
- _result["expression_type"] = expression_type.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.prefixExpression) {
- if (prefixExpression_operand != null) {
- _result["prefixExpression_operand"] = prefixExpression_operand.toJson();
- }
- if (prefixExpression_substitution != null) {
- _result["prefixExpression_substitution"] =
- prefixExpression_substitution.toJson();
- }
- if (prefixExpression_element != 0) {
- _result["prefixExpression_element"] = prefixExpression_element;
- }
- if (prefixExpression_operator != idl.UnlinkedTokenType.NOTHING) {
- _result["prefixExpression_operator"] =
- prefixExpression_operator.toString().split('.')[1];
- }
- if (expression_type != null) {
- _result["expression_type"] = expression_type.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.prefixedIdentifier) {
- if (prefixedIdentifier_identifier != null) {
- _result["prefixedIdentifier_identifier"] =
- prefixedIdentifier_identifier.toJson();
- }
- if (prefixedIdentifier_prefix != null) {
- _result["prefixedIdentifier_prefix"] =
- prefixedIdentifier_prefix.toJson();
- }
- if (expression_type != null) {
- _result["expression_type"] = expression_type.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.propertyAccess) {
- if (propertyAccess_propertyName != null) {
- _result["propertyAccess_propertyName"] =
- propertyAccess_propertyName.toJson();
- }
- if (propertyAccess_target != null) {
- _result["propertyAccess_target"] = propertyAccess_target.toJson();
- }
- if (propertyAccess_operator != idl.UnlinkedTokenType.NOTHING) {
- _result["propertyAccess_operator"] =
- propertyAccess_operator.toString().split('.')[1];
- }
- if (expression_type != null) {
- _result["expression_type"] = expression_type.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.redirectingConstructorInvocation) {
- if (redirectingConstructorInvocation_arguments != null) {
- _result["redirectingConstructorInvocation_arguments"] =
- redirectingConstructorInvocation_arguments.toJson();
- }
- if (redirectingConstructorInvocation_constructorName != null) {
- _result["redirectingConstructorInvocation_constructorName"] =
- redirectingConstructorInvocation_constructorName.toJson();
- }
- if (redirectingConstructorInvocation_substitution != null) {
- _result["redirectingConstructorInvocation_substitution"] =
- redirectingConstructorInvocation_substitution.toJson();
- }
- if (redirectingConstructorInvocation_element != 0) {
- _result["redirectingConstructorInvocation_element"] =
- redirectingConstructorInvocation_element;
- }
- }
- if (kind == idl.LinkedNodeKind.rethrowExpression) {
- if (expression_type != null) {
- _result["expression_type"] = expression_type.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.returnStatement) {
- if (returnStatement_expression != null) {
- _result["returnStatement_expression"] =
- returnStatement_expression.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.setOrMapLiteral) {
- if (typedLiteral_typeArguments.isNotEmpty) {
- _result["typedLiteral_typeArguments"] = typedLiteral_typeArguments
- .map((_value) => _value.toJson())
- .toList();
- }
- if (setOrMapLiteral_elements.isNotEmpty) {
- _result["setOrMapLiteral_elements"] =
- setOrMapLiteral_elements.map((_value) => _value.toJson()).toList();
- }
- if (expression_type != null) {
- _result["expression_type"] = expression_type.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.showCombinator) {
- if (informativeId != 0) {
- _result["informativeId"] = informativeId;
- }
- if (names.isNotEmpty) {
- _result["names"] = names;
- }
- }
- if (kind == idl.LinkedNodeKind.simpleFormalParameter) {
- if (actualType != null) {
- _result["actualType"] = actualType.toJson();
- }
- if (normalFormalParameter_metadata.isNotEmpty) {
- _result["normalFormalParameter_metadata"] =
- normalFormalParameter_metadata
- .map((_value) => _value.toJson())
- .toList();
- }
- if (simpleFormalParameter_type != null) {
- _result["simpleFormalParameter_type"] =
- simpleFormalParameter_type.toJson();
- }
- if (inheritsCovariant != false) {
- _result["inheritsCovariant"] = inheritsCovariant;
- }
- if (informativeId != 0) {
- _result["informativeId"] = informativeId;
- }
- if (topLevelTypeInferenceError != null) {
- _result["topLevelTypeInferenceError"] =
- topLevelTypeInferenceError.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.simpleIdentifier) {
- if (simpleIdentifier_substitution != null) {
- _result["simpleIdentifier_substitution"] =
- simpleIdentifier_substitution.toJson();
- }
- if (simpleIdentifier_element != 0) {
- _result["simpleIdentifier_element"] = simpleIdentifier_element;
- }
- if (expression_type != null) {
- _result["expression_type"] = expression_type.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.simpleStringLiteral) {
- if (simpleStringLiteral_value != '') {
- _result["simpleStringLiteral_value"] = simpleStringLiteral_value;
- }
- }
- if (kind == idl.LinkedNodeKind.spreadElement) {
- if (spreadElement_expression != null) {
- _result["spreadElement_expression"] = spreadElement_expression.toJson();
- }
- if (spreadElement_spreadOperator != idl.UnlinkedTokenType.NOTHING) {
- _result["spreadElement_spreadOperator"] =
- spreadElement_spreadOperator.toString().split('.')[1];
- }
- }
- if (kind == idl.LinkedNodeKind.stringInterpolation) {
- if (stringInterpolation_elements.isNotEmpty) {
- _result["stringInterpolation_elements"] = stringInterpolation_elements
- .map((_value) => _value.toJson())
- .toList();
- }
- }
- if (kind == idl.LinkedNodeKind.superConstructorInvocation) {
- if (superConstructorInvocation_arguments != null) {
- _result["superConstructorInvocation_arguments"] =
- superConstructorInvocation_arguments.toJson();
- }
- if (superConstructorInvocation_constructorName != null) {
- _result["superConstructorInvocation_constructorName"] =
- superConstructorInvocation_constructorName.toJson();
- }
- if (superConstructorInvocation_substitution != null) {
- _result["superConstructorInvocation_substitution"] =
- superConstructorInvocation_substitution.toJson();
- }
- if (superConstructorInvocation_element != 0) {
- _result["superConstructorInvocation_element"] =
- superConstructorInvocation_element;
- }
- }
- if (kind == idl.LinkedNodeKind.superExpression) {
- if (expression_type != null) {
- _result["expression_type"] = expression_type.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.switchCase) {
- if (switchMember_statements.isNotEmpty) {
- _result["switchMember_statements"] =
- switchMember_statements.map((_value) => _value.toJson()).toList();
- }
- if (switchCase_expression != null) {
- _result["switchCase_expression"] = switchCase_expression.toJson();
- }
- if (switchMember_labels.isNotEmpty) {
- _result["switchMember_labels"] =
- switchMember_labels.map((_value) => _value.toJson()).toList();
- }
- }
- if (kind == idl.LinkedNodeKind.switchDefault) {
- if (switchMember_statements.isNotEmpty) {
- _result["switchMember_statements"] =
- switchMember_statements.map((_value) => _value.toJson()).toList();
- }
- if (switchMember_labels.isNotEmpty) {
- _result["switchMember_labels"] =
- switchMember_labels.map((_value) => _value.toJson()).toList();
- }
- }
- if (kind == idl.LinkedNodeKind.switchStatement) {
- if (switchStatement_members.isNotEmpty) {
- _result["switchStatement_members"] =
- switchStatement_members.map((_value) => _value.toJson()).toList();
- }
- if (switchStatement_expression != null) {
- _result["switchStatement_expression"] =
- switchStatement_expression.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.symbolLiteral) {
- if (expression_type != null) {
- _result["expression_type"] = expression_type.toJson();
- }
- if (names.isNotEmpty) {
- _result["names"] = names;
- }
- }
- if (kind == idl.LinkedNodeKind.thisExpression) {
- if (expression_type != null) {
- _result["expression_type"] = expression_type.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.throwExpression) {
- if (throwExpression_expression != null) {
- _result["throwExpression_expression"] =
- throwExpression_expression.toJson();
- }
- if (expression_type != null) {
- _result["expression_type"] = expression_type.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.topLevelVariableDeclaration) {
- if (annotatedNode_metadata.isNotEmpty) {
- _result["annotatedNode_metadata"] =
- annotatedNode_metadata.map((_value) => _value.toJson()).toList();
- }
- if (topLevelVariableDeclaration_variableList != null) {
- _result["topLevelVariableDeclaration_variableList"] =
- topLevelVariableDeclaration_variableList.toJson();
- }
- if (informativeId != 0) {
- _result["informativeId"] = informativeId;
- }
- }
- if (kind == idl.LinkedNodeKind.tryStatement) {
- if (tryStatement_catchClauses.isNotEmpty) {
- _result["tryStatement_catchClauses"] =
- tryStatement_catchClauses.map((_value) => _value.toJson()).toList();
- }
- if (tryStatement_body != null) {
- _result["tryStatement_body"] = tryStatement_body.toJson();
- }
- if (tryStatement_finallyBlock != null) {
- _result["tryStatement_finallyBlock"] =
- tryStatement_finallyBlock.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.typeArgumentList) {
- if (typeArgumentList_arguments.isNotEmpty) {
- _result["typeArgumentList_arguments"] = typeArgumentList_arguments
- .map((_value) => _value.toJson())
- .toList();
- }
- }
- if (kind == idl.LinkedNodeKind.typeName) {
- if (typeName_typeArguments.isNotEmpty) {
- _result["typeName_typeArguments"] =
- typeName_typeArguments.map((_value) => _value.toJson()).toList();
- }
- if (typeName_name != null) {
- _result["typeName_name"] = typeName_name.toJson();
- }
- if (typeName_type != null) {
- _result["typeName_type"] = typeName_type.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.typeParameter) {
- if (annotatedNode_metadata.isNotEmpty) {
- _result["annotatedNode_metadata"] =
- annotatedNode_metadata.map((_value) => _value.toJson()).toList();
- }
- if (typeParameter_bound != null) {
- _result["typeParameter_bound"] = typeParameter_bound.toJson();
- }
- if (typeParameter_variance != 0) {
- _result["typeParameter_variance"] = typeParameter_variance;
- }
- if (informativeId != 0) {
- _result["informativeId"] = informativeId;
- }
- if (typeParameter_defaultType != null) {
- _result["typeParameter_defaultType"] =
- typeParameter_defaultType.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.typeParameterList) {
- if (typeParameterList_typeParameters.isNotEmpty) {
- _result["typeParameterList_typeParameters"] =
- typeParameterList_typeParameters
- .map((_value) => _value.toJson())
- .toList();
- }
- }
- if (kind == idl.LinkedNodeKind.variableDeclaration) {
- if (actualType != null) {
- _result["actualType"] = actualType.toJson();
- }
- if (annotatedNode_metadata.isNotEmpty) {
- _result["annotatedNode_metadata"] =
- annotatedNode_metadata.map((_value) => _value.toJson()).toList();
- }
- if (variableDeclaration_initializer != null) {
- _result["variableDeclaration_initializer"] =
- variableDeclaration_initializer.toJson();
- }
- if (inheritsCovariant != false) {
- _result["inheritsCovariant"] = inheritsCovariant;
- }
- if (informativeId != 0) {
- _result["informativeId"] = informativeId;
- }
- if (topLevelTypeInferenceError != null) {
- _result["topLevelTypeInferenceError"] =
- topLevelTypeInferenceError.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.variableDeclarationList) {
- if (variableDeclarationList_variables.isNotEmpty) {
- _result["variableDeclarationList_variables"] =
- variableDeclarationList_variables
- .map((_value) => _value.toJson())
- .toList();
- }
- if (annotatedNode_metadata.isNotEmpty) {
- _result["annotatedNode_metadata"] =
- annotatedNode_metadata.map((_value) => _value.toJson()).toList();
- }
- if (variableDeclarationList_type != null) {
- _result["variableDeclarationList_type"] =
- variableDeclarationList_type.toJson();
- }
- if (informativeId != 0) {
- _result["informativeId"] = informativeId;
- }
- }
- if (kind == idl.LinkedNodeKind.variableDeclarationStatement) {
- if (variableDeclarationStatement_variables != null) {
- _result["variableDeclarationStatement_variables"] =
- variableDeclarationStatement_variables.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.whileStatement) {
- if (whileStatement_body != null) {
- _result["whileStatement_body"] = whileStatement_body.toJson();
- }
- if (whileStatement_condition != null) {
- _result["whileStatement_condition"] = whileStatement_condition.toJson();
- }
- }
- if (kind == idl.LinkedNodeKind.withClause) {
- if (withClause_mixinTypes.isNotEmpty) {
- _result["withClause_mixinTypes"] =
- withClause_mixinTypes.map((_value) => _value.toJson()).toList();
- }
- }
- if (kind == idl.LinkedNodeKind.yieldStatement) {
- if (yieldStatement_expression != null) {
- _result["yieldStatement_expression"] =
- yieldStatement_expression.toJson();
- }
- }
- return _result;
- }
-
- @override
- Map<String, Object> toMap() {
- if (kind == idl.LinkedNodeKind.adjacentStrings) {
- return {
- "adjacentStrings_strings": adjacentStrings_strings,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.annotation) {
- return {
- "annotation_arguments": annotation_arguments,
- "annotation_constructorName": annotation_constructorName,
- "annotation_element": annotation_element,
- "annotation_name": annotation_name,
- "annotation_substitution": annotation_substitution,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.argumentList) {
- return {
- "argumentList_arguments": argumentList_arguments,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.asExpression) {
- return {
- "asExpression_expression": asExpression_expression,
- "asExpression_type": asExpression_type,
- "expression_type": expression_type,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.assertInitializer) {
- return {
- "assertInitializer_condition": assertInitializer_condition,
- "assertInitializer_message": assertInitializer_message,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.assertStatement) {
- return {
- "assertStatement_condition": assertStatement_condition,
- "assertStatement_message": assertStatement_message,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.assignmentExpression) {
- return {
- "assignmentExpression_leftHandSide": assignmentExpression_leftHandSide,
- "assignmentExpression_rightHandSide":
- assignmentExpression_rightHandSide,
- "assignmentExpression_substitution": assignmentExpression_substitution,
- "assignmentExpression_element": assignmentExpression_element,
- "assignmentExpression_operator": assignmentExpression_operator,
- "expression_type": expression_type,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.awaitExpression) {
- return {
- "awaitExpression_expression": awaitExpression_expression,
- "expression_type": expression_type,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.binaryExpression) {
- return {
- "binaryExpression_invokeType": binaryExpression_invokeType,
- "binaryExpression_leftOperand": binaryExpression_leftOperand,
- "binaryExpression_rightOperand": binaryExpression_rightOperand,
- "binaryExpression_substitution": binaryExpression_substitution,
- "binaryExpression_element": binaryExpression_element,
- "binaryExpression_operator": binaryExpression_operator,
- "expression_type": expression_type,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.block) {
- return {
- "block_statements": block_statements,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.blockFunctionBody) {
- return {
- "blockFunctionBody_block": blockFunctionBody_block,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.booleanLiteral) {
- return {
- "booleanLiteral_value": booleanLiteral_value,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.breakStatement) {
- return {
- "breakStatement_label": breakStatement_label,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.cascadeExpression) {
- return {
- "cascadeExpression_sections": cascadeExpression_sections,
- "cascadeExpression_target": cascadeExpression_target,
- "expression_type": expression_type,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.catchClause) {
- return {
- "catchClause_body": catchClause_body,
- "catchClause_exceptionParameter": catchClause_exceptionParameter,
- "catchClause_exceptionType": catchClause_exceptionType,
- "catchClause_stackTraceParameter": catchClause_stackTraceParameter,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.classDeclaration) {
- return {
- "annotatedNode_metadata": annotatedNode_metadata,
- "classDeclaration_extendsClause": classDeclaration_extendsClause,
- "classDeclaration_withClause": classDeclaration_withClause,
- "classDeclaration_nativeClause": classDeclaration_nativeClause,
- "classDeclaration_isDartObject": classDeclaration_isDartObject,
- "classOrMixinDeclaration_implementsClause":
- classOrMixinDeclaration_implementsClause,
- "classOrMixinDeclaration_members": classOrMixinDeclaration_members,
- "classOrMixinDeclaration_typeParameters":
- classOrMixinDeclaration_typeParameters,
- "flags": flags,
- "informativeId": informativeId,
- "kind": kind,
- "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded,
- "name": name,
- "unused11": unused11,
- };
- }
- if (kind == idl.LinkedNodeKind.classTypeAlias) {
- return {
- "annotatedNode_metadata": annotatedNode_metadata,
- "classTypeAlias_typeParameters": classTypeAlias_typeParameters,
- "classTypeAlias_superclass": classTypeAlias_superclass,
- "classTypeAlias_withClause": classTypeAlias_withClause,
- "classTypeAlias_implementsClause": classTypeAlias_implementsClause,
- "flags": flags,
- "informativeId": informativeId,
- "kind": kind,
- "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.comment) {
- return {
- "comment_references": comment_references,
- "comment_tokens": comment_tokens,
- "comment_type": comment_type,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.commentReference) {
- return {
- "commentReference_identifier": commentReference_identifier,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.compilationUnit) {
- return {
- "compilationUnit_declarations": compilationUnit_declarations,
- "compilationUnit_scriptTag": compilationUnit_scriptTag,
- "compilationUnit_directives": compilationUnit_directives,
- "compilationUnit_featureSet": compilationUnit_featureSet,
- "compilationUnit_languageVersion": compilationUnit_languageVersion,
- "flags": flags,
- "informativeId": informativeId,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.conditionalExpression) {
- return {
- "conditionalExpression_condition": conditionalExpression_condition,
- "conditionalExpression_elseExpression":
- conditionalExpression_elseExpression,
- "conditionalExpression_thenExpression":
- conditionalExpression_thenExpression,
- "expression_type": expression_type,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.configuration) {
- return {
- "configuration_name": configuration_name,
- "configuration_value": configuration_value,
- "configuration_uri": configuration_uri,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.constructorDeclaration) {
- return {
- "constructorDeclaration_initializers":
- constructorDeclaration_initializers,
- "annotatedNode_metadata": annotatedNode_metadata,
- "constructorDeclaration_body": constructorDeclaration_body,
- "constructorDeclaration_parameters": constructorDeclaration_parameters,
- "constructorDeclaration_redirectedConstructor":
- constructorDeclaration_redirectedConstructor,
- "constructorDeclaration_returnType": constructorDeclaration_returnType,
- "flags": flags,
- "informativeId": informativeId,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.constructorFieldInitializer) {
- return {
- "constructorFieldInitializer_expression":
- constructorFieldInitializer_expression,
- "constructorFieldInitializer_fieldName":
- constructorFieldInitializer_fieldName,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.constructorName) {
- return {
- "constructorName_name": constructorName_name,
- "constructorName_type": constructorName_type,
- "constructorName_substitution": constructorName_substitution,
- "constructorName_element": constructorName_element,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.continueStatement) {
- return {
- "continueStatement_label": continueStatement_label,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.declaredIdentifier) {
- return {
- "annotatedNode_metadata": annotatedNode_metadata,
- "declaredIdentifier_identifier": declaredIdentifier_identifier,
- "declaredIdentifier_type": declaredIdentifier_type,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.defaultFormalParameter) {
- return {
- "defaultFormalParameter_defaultValue":
- defaultFormalParameter_defaultValue,
- "defaultFormalParameter_parameter": defaultFormalParameter_parameter,
- "defaultFormalParameter_kind": defaultFormalParameter_kind,
- "flags": flags,
- "informativeId": informativeId,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.doStatement) {
- return {
- "doStatement_body": doStatement_body,
- "doStatement_condition": doStatement_condition,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.dottedName) {
- return {
- "dottedName_components": dottedName_components,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.doubleLiteral) {
- return {
- "doubleLiteral_value": doubleLiteral_value,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.emptyFunctionBody) {
- return {
- "emptyFunctionBody_fake": emptyFunctionBody_fake,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.emptyStatement) {
- return {
- "emptyStatement_fake": emptyStatement_fake,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
- return {
- "annotatedNode_metadata": annotatedNode_metadata,
- "flags": flags,
- "informativeId": informativeId,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.enumDeclaration) {
- return {
- "enumDeclaration_constants": enumDeclaration_constants,
- "annotatedNode_metadata": annotatedNode_metadata,
- "flags": flags,
- "informativeId": informativeId,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.exportDirective) {
- return {
- "namespaceDirective_combinators": namespaceDirective_combinators,
- "annotatedNode_metadata": annotatedNode_metadata,
- "namespaceDirective_configurations": namespaceDirective_configurations,
- "namespaceDirective_selectedUri": namespaceDirective_selectedUri,
- "flags": flags,
- "informativeId": informativeId,
- "uriBasedDirective_uri": uriBasedDirective_uri,
- "kind": kind,
- "name": name,
- "uriBasedDirective_uriContent": uriBasedDirective_uriContent,
- "uriBasedDirective_uriElement": uriBasedDirective_uriElement,
- };
- }
- if (kind == idl.LinkedNodeKind.expressionFunctionBody) {
- return {
- "expressionFunctionBody_expression": expressionFunctionBody_expression,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.expressionStatement) {
- return {
- "expressionStatement_expression": expressionStatement_expression,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.extendsClause) {
- return {
- "extendsClause_superclass": extendsClause_superclass,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.extensionDeclaration) {
- return {
- "annotatedNode_metadata": annotatedNode_metadata,
- "extensionDeclaration_typeParameters":
- extensionDeclaration_typeParameters,
- "extensionDeclaration_extendedType": extensionDeclaration_extendedType,
- "extensionDeclaration_members": extensionDeclaration_members,
- "extensionDeclaration_refName": extensionDeclaration_refName,
- "flags": flags,
- "informativeId": informativeId,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.extensionOverride) {
- return {
- "extensionOverride_extendedType": extensionOverride_extendedType,
- "extensionOverride_arguments": extensionOverride_arguments,
- "extensionOverride_extensionName": extensionOverride_extensionName,
- "extensionOverride_typeArguments": extensionOverride_typeArguments,
- "extensionOverride_typeArgumentTypes":
- extensionOverride_typeArgumentTypes,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.fieldDeclaration) {
- return {
- "annotatedNode_metadata": annotatedNode_metadata,
- "fieldDeclaration_fields": fieldDeclaration_fields,
- "flags": flags,
- "informativeId": informativeId,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
- return {
- "actualType": actualType,
- "normalFormalParameter_metadata": normalFormalParameter_metadata,
- "fieldFormalParameter_type": fieldFormalParameter_type,
- "fieldFormalParameter_typeParameters":
- fieldFormalParameter_typeParameters,
- "fieldFormalParameter_formalParameters":
- fieldFormalParameter_formalParameters,
- "inheritsCovariant": inheritsCovariant,
- "flags": flags,
- "informativeId": informativeId,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.forEachPartsWithDeclaration) {
- return {
- "forEachParts_iterable": forEachParts_iterable,
- "forEachPartsWithDeclaration_loopVariable":
- forEachPartsWithDeclaration_loopVariable,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.forEachPartsWithIdentifier) {
- return {
- "forEachParts_iterable": forEachParts_iterable,
- "forEachPartsWithIdentifier_identifier":
- forEachPartsWithIdentifier_identifier,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.forElement) {
- return {
- "forMixin_forLoopParts": forMixin_forLoopParts,
- "forElement_body": forElement_body,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.forPartsWithDeclarations) {
- return {
- "forParts_condition": forParts_condition,
- "forPartsWithDeclarations_variables":
- forPartsWithDeclarations_variables,
- "forParts_updaters": forParts_updaters,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.forPartsWithExpression) {
- return {
- "forParts_condition": forParts_condition,
- "forPartsWithExpression_initialization":
- forPartsWithExpression_initialization,
- "forParts_updaters": forParts_updaters,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.forStatement) {
- return {
- "forMixin_forLoopParts": forMixin_forLoopParts,
- "forStatement_body": forStatement_body,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.formalParameterList) {
- return {
- "formalParameterList_parameters": formalParameterList_parameters,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.functionDeclaration) {
- return {
- "actualReturnType": actualReturnType,
- "annotatedNode_metadata": annotatedNode_metadata,
- "functionDeclaration_functionExpression":
- functionDeclaration_functionExpression,
- "functionDeclaration_returnType": functionDeclaration_returnType,
- "flags": flags,
- "informativeId": informativeId,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.functionDeclarationStatement) {
- return {
- "functionDeclarationStatement_functionDeclaration":
- functionDeclarationStatement_functionDeclaration,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.functionExpression) {
- return {
- "actualReturnType": actualReturnType,
- "functionExpression_body": functionExpression_body,
- "functionExpression_formalParameters":
- functionExpression_formalParameters,
- "functionExpression_typeParameters": functionExpression_typeParameters,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.functionExpressionInvocation) {
- return {
- "invocationExpression_invokeType": invocationExpression_invokeType,
- "functionExpressionInvocation_function":
- functionExpressionInvocation_function,
- "invocationExpression_typeArguments":
- invocationExpression_typeArguments,
- "expression_type": expression_type,
- "flags": flags,
- "invocationExpression_arguments": invocationExpression_arguments,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.functionTypeAlias) {
- return {
- "actualReturnType": actualReturnType,
- "annotatedNode_metadata": annotatedNode_metadata,
- "functionTypeAlias_formalParameters":
- functionTypeAlias_formalParameters,
- "functionTypeAlias_returnType": functionTypeAlias_returnType,
- "functionTypeAlias_typeParameters": functionTypeAlias_typeParameters,
- "typeAlias_hasSelfReference": typeAlias_hasSelfReference,
- "flags": flags,
- "informativeId": informativeId,
- "kind": kind,
- "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) {
- return {
- "actualType": actualType,
- "normalFormalParameter_metadata": normalFormalParameter_metadata,
- "functionTypedFormalParameter_formalParameters":
- functionTypedFormalParameter_formalParameters,
- "functionTypedFormalParameter_returnType":
- functionTypedFormalParameter_returnType,
- "functionTypedFormalParameter_typeParameters":
- functionTypedFormalParameter_typeParameters,
- "inheritsCovariant": inheritsCovariant,
- "flags": flags,
- "informativeId": informativeId,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.genericFunctionType) {
- return {
- "actualReturnType": actualReturnType,
- "genericFunctionType_typeParameters":
- genericFunctionType_typeParameters,
- "genericFunctionType_returnType": genericFunctionType_returnType,
- "genericFunctionType_id": genericFunctionType_id,
- "genericFunctionType_formalParameters":
- genericFunctionType_formalParameters,
- "genericFunctionType_type": genericFunctionType_type,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.genericTypeAlias) {
- return {
- "annotatedNode_metadata": annotatedNode_metadata,
- "genericTypeAlias_typeParameters": genericTypeAlias_typeParameters,
- "genericTypeAlias_functionType": genericTypeAlias_functionType,
- "typeAlias_hasSelfReference": typeAlias_hasSelfReference,
- "flags": flags,
- "informativeId": informativeId,
- "kind": kind,
- "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.hideCombinator) {
- return {
- "flags": flags,
- "informativeId": informativeId,
- "kind": kind,
- "names": names,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.ifElement) {
- return {
- "ifMixin_condition": ifMixin_condition,
- "ifElement_thenElement": ifElement_thenElement,
- "ifElement_elseElement": ifElement_elseElement,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.ifStatement) {
- return {
- "ifMixin_condition": ifMixin_condition,
- "ifStatement_elseStatement": ifStatement_elseStatement,
- "ifStatement_thenStatement": ifStatement_thenStatement,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.implementsClause) {
- return {
- "implementsClause_interfaces": implementsClause_interfaces,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.importDirective) {
- return {
- "namespaceDirective_combinators": namespaceDirective_combinators,
- "annotatedNode_metadata": annotatedNode_metadata,
- "namespaceDirective_configurations": namespaceDirective_configurations,
- "namespaceDirective_selectedUri": namespaceDirective_selectedUri,
- "flags": flags,
- "importDirective_prefix": importDirective_prefix,
- "informativeId": informativeId,
- "uriBasedDirective_uri": uriBasedDirective_uri,
- "kind": kind,
- "name": name,
- "uriBasedDirective_uriContent": uriBasedDirective_uriContent,
- "uriBasedDirective_uriElement": uriBasedDirective_uriElement,
- };
- }
- if (kind == idl.LinkedNodeKind.indexExpression) {
- return {
- "indexExpression_index": indexExpression_index,
- "indexExpression_target": indexExpression_target,
- "indexExpression_substitution": indexExpression_substitution,
- "indexExpression_element": indexExpression_element,
- "expression_type": expression_type,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.instanceCreationExpression) {
- return {
- "instanceCreationExpression_arguments":
- instanceCreationExpression_arguments,
- "instanceCreationExpression_constructorName":
- instanceCreationExpression_constructorName,
- "instanceCreationExpression_typeArguments":
- instanceCreationExpression_typeArguments,
- "expression_type": expression_type,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.integerLiteral) {
- return {
- "expression_type": expression_type,
- "flags": flags,
- "integerLiteral_value": integerLiteral_value,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.interpolationExpression) {
- return {
- "interpolationExpression_expression":
- interpolationExpression_expression,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.interpolationString) {
- return {
- "flags": flags,
- "interpolationString_value": interpolationString_value,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.isExpression) {
- return {
- "isExpression_expression": isExpression_expression,
- "isExpression_type": isExpression_type,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.label) {
- return {
- "label_label": label_label,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.labeledStatement) {
- return {
- "labeledStatement_labels": labeledStatement_labels,
- "labeledStatement_statement": labeledStatement_statement,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.libraryDirective) {
- return {
- "annotatedNode_metadata": annotatedNode_metadata,
- "libraryDirective_name": libraryDirective_name,
- "flags": flags,
- "informativeId": informativeId,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.libraryIdentifier) {
- return {
- "libraryIdentifier_components": libraryIdentifier_components,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.listLiteral) {
- return {
- "typedLiteral_typeArguments": typedLiteral_typeArguments,
- "listLiteral_elements": listLiteral_elements,
- "expression_type": expression_type,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.mapLiteralEntry) {
- return {
- "mapLiteralEntry_key": mapLiteralEntry_key,
- "mapLiteralEntry_value": mapLiteralEntry_value,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.methodDeclaration) {
- return {
- "actualReturnType": actualReturnType,
- "annotatedNode_metadata": annotatedNode_metadata,
- "methodDeclaration_body": methodDeclaration_body,
- "methodDeclaration_formalParameters":
- methodDeclaration_formalParameters,
- "methodDeclaration_returnType": methodDeclaration_returnType,
- "methodDeclaration_typeParameters": methodDeclaration_typeParameters,
- "flags": flags,
- "informativeId": informativeId,
- "kind": kind,
- "methodDeclaration_hasOperatorEqualWithParameterTypeFromObject":
- methodDeclaration_hasOperatorEqualWithParameterTypeFromObject,
- "name": name,
- "topLevelTypeInferenceError": topLevelTypeInferenceError,
- };
- }
- if (kind == idl.LinkedNodeKind.methodInvocation) {
- return {
- "invocationExpression_invokeType": invocationExpression_invokeType,
- "methodInvocation_methodName": methodInvocation_methodName,
- "methodInvocation_target": methodInvocation_target,
- "invocationExpression_typeArguments":
- invocationExpression_typeArguments,
- "expression_type": expression_type,
- "flags": flags,
- "invocationExpression_arguments": invocationExpression_arguments,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.mixinDeclaration) {
- return {
- "annotatedNode_metadata": annotatedNode_metadata,
- "mixinDeclaration_onClause": mixinDeclaration_onClause,
- "classOrMixinDeclaration_implementsClause":
- classOrMixinDeclaration_implementsClause,
- "classOrMixinDeclaration_members": classOrMixinDeclaration_members,
- "classOrMixinDeclaration_typeParameters":
- classOrMixinDeclaration_typeParameters,
- "flags": flags,
- "informativeId": informativeId,
- "kind": kind,
- "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded,
- "mixinDeclaration_superInvokedNames":
- mixinDeclaration_superInvokedNames,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.namedExpression) {
- return {
- "namedExpression_expression": namedExpression_expression,
- "namedExpression_name": namedExpression_name,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.nativeClause) {
- return {
- "nativeClause_name": nativeClause_name,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.nativeFunctionBody) {
- return {
- "nativeFunctionBody_stringLiteral": nativeFunctionBody_stringLiteral,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.nullLiteral) {
- return {
- "nullLiteral_fake": nullLiteral_fake,
- "expression_type": expression_type,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.onClause) {
- return {
- "onClause_superclassConstraints": onClause_superclassConstraints,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.parenthesizedExpression) {
- return {
- "parenthesizedExpression_expression":
- parenthesizedExpression_expression,
- "expression_type": expression_type,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.partDirective) {
- return {
- "annotatedNode_metadata": annotatedNode_metadata,
- "flags": flags,
- "informativeId": informativeId,
- "uriBasedDirective_uri": uriBasedDirective_uri,
- "kind": kind,
- "name": name,
- "uriBasedDirective_uriContent": uriBasedDirective_uriContent,
- "uriBasedDirective_uriElement": uriBasedDirective_uriElement,
- };
- }
- if (kind == idl.LinkedNodeKind.partOfDirective) {
- return {
- "annotatedNode_metadata": annotatedNode_metadata,
- "partOfDirective_libraryName": partOfDirective_libraryName,
- "partOfDirective_uri": partOfDirective_uri,
- "flags": flags,
- "informativeId": informativeId,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.postfixExpression) {
- return {
- "postfixExpression_operand": postfixExpression_operand,
- "postfixExpression_substitution": postfixExpression_substitution,
- "postfixExpression_element": postfixExpression_element,
- "postfixExpression_operator": postfixExpression_operator,
- "expression_type": expression_type,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.prefixExpression) {
- return {
- "prefixExpression_operand": prefixExpression_operand,
- "prefixExpression_substitution": prefixExpression_substitution,
- "prefixExpression_element": prefixExpression_element,
- "prefixExpression_operator": prefixExpression_operator,
- "expression_type": expression_type,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.prefixedIdentifier) {
- return {
- "prefixedIdentifier_identifier": prefixedIdentifier_identifier,
- "prefixedIdentifier_prefix": prefixedIdentifier_prefix,
- "expression_type": expression_type,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.propertyAccess) {
- return {
- "propertyAccess_propertyName": propertyAccess_propertyName,
- "propertyAccess_target": propertyAccess_target,
- "propertyAccess_operator": propertyAccess_operator,
- "expression_type": expression_type,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.redirectingConstructorInvocation) {
- return {
- "redirectingConstructorInvocation_arguments":
- redirectingConstructorInvocation_arguments,
- "redirectingConstructorInvocation_constructorName":
- redirectingConstructorInvocation_constructorName,
- "redirectingConstructorInvocation_substitution":
- redirectingConstructorInvocation_substitution,
- "redirectingConstructorInvocation_element":
- redirectingConstructorInvocation_element,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.rethrowExpression) {
- return {
- "expression_type": expression_type,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.returnStatement) {
- return {
- "returnStatement_expression": returnStatement_expression,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.setOrMapLiteral) {
- return {
- "typedLiteral_typeArguments": typedLiteral_typeArguments,
- "setOrMapLiteral_elements": setOrMapLiteral_elements,
- "expression_type": expression_type,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.showCombinator) {
- return {
- "flags": flags,
- "informativeId": informativeId,
- "kind": kind,
- "names": names,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.simpleFormalParameter) {
- return {
- "actualType": actualType,
- "normalFormalParameter_metadata": normalFormalParameter_metadata,
- "simpleFormalParameter_type": simpleFormalParameter_type,
- "inheritsCovariant": inheritsCovariant,
- "flags": flags,
- "informativeId": informativeId,
- "kind": kind,
- "name": name,
- "topLevelTypeInferenceError": topLevelTypeInferenceError,
- };
- }
- if (kind == idl.LinkedNodeKind.simpleIdentifier) {
- return {
- "simpleIdentifier_substitution": simpleIdentifier_substitution,
- "simpleIdentifier_element": simpleIdentifier_element,
- "expression_type": expression_type,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.simpleStringLiteral) {
- return {
- "simpleStringLiteral_value": simpleStringLiteral_value,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.spreadElement) {
- return {
- "spreadElement_expression": spreadElement_expression,
- "flags": flags,
- "kind": kind,
- "name": name,
- "spreadElement_spreadOperator": spreadElement_spreadOperator,
- };
- }
- if (kind == idl.LinkedNodeKind.stringInterpolation) {
- return {
- "stringInterpolation_elements": stringInterpolation_elements,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.superConstructorInvocation) {
- return {
- "superConstructorInvocation_arguments":
- superConstructorInvocation_arguments,
- "superConstructorInvocation_constructorName":
- superConstructorInvocation_constructorName,
- "superConstructorInvocation_substitution":
- superConstructorInvocation_substitution,
- "superConstructorInvocation_element":
- superConstructorInvocation_element,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.superExpression) {
- return {
- "expression_type": expression_type,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.switchCase) {
- return {
- "switchMember_statements": switchMember_statements,
- "switchCase_expression": switchCase_expression,
- "switchMember_labels": switchMember_labels,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.switchDefault) {
- return {
- "switchMember_statements": switchMember_statements,
- "switchMember_labels": switchMember_labels,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.switchStatement) {
- return {
- "switchStatement_members": switchStatement_members,
- "switchStatement_expression": switchStatement_expression,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.symbolLiteral) {
- return {
- "expression_type": expression_type,
- "flags": flags,
- "kind": kind,
- "names": names,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.thisExpression) {
- return {
- "expression_type": expression_type,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.throwExpression) {
- return {
- "throwExpression_expression": throwExpression_expression,
- "expression_type": expression_type,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.topLevelVariableDeclaration) {
- return {
- "annotatedNode_metadata": annotatedNode_metadata,
- "topLevelVariableDeclaration_variableList":
- topLevelVariableDeclaration_variableList,
- "flags": flags,
- "informativeId": informativeId,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.tryStatement) {
- return {
- "tryStatement_catchClauses": tryStatement_catchClauses,
- "tryStatement_body": tryStatement_body,
- "tryStatement_finallyBlock": tryStatement_finallyBlock,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.typeArgumentList) {
- return {
- "typeArgumentList_arguments": typeArgumentList_arguments,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.typeName) {
- return {
- "typeName_typeArguments": typeName_typeArguments,
- "typeName_name": typeName_name,
- "flags": flags,
- "kind": kind,
- "name": name,
- "typeName_type": typeName_type,
- };
- }
- if (kind == idl.LinkedNodeKind.typeParameter) {
- return {
- "annotatedNode_metadata": annotatedNode_metadata,
- "typeParameter_bound": typeParameter_bound,
- "typeParameter_variance": typeParameter_variance,
- "flags": flags,
- "informativeId": informativeId,
- "kind": kind,
- "name": name,
- "typeParameter_defaultType": typeParameter_defaultType,
- };
- }
- if (kind == idl.LinkedNodeKind.typeParameterList) {
- return {
- "typeParameterList_typeParameters": typeParameterList_typeParameters,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.variableDeclaration) {
- return {
- "actualType": actualType,
- "annotatedNode_metadata": annotatedNode_metadata,
- "variableDeclaration_initializer": variableDeclaration_initializer,
- "inheritsCovariant": inheritsCovariant,
- "flags": flags,
- "informativeId": informativeId,
- "kind": kind,
- "name": name,
- "topLevelTypeInferenceError": topLevelTypeInferenceError,
- };
- }
- if (kind == idl.LinkedNodeKind.variableDeclarationList) {
- return {
- "variableDeclarationList_variables": variableDeclarationList_variables,
- "annotatedNode_metadata": annotatedNode_metadata,
- "variableDeclarationList_type": variableDeclarationList_type,
- "flags": flags,
- "informativeId": informativeId,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.variableDeclarationStatement) {
- return {
- "variableDeclarationStatement_variables":
- variableDeclarationStatement_variables,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.whileStatement) {
- return {
- "whileStatement_body": whileStatement_body,
- "whileStatement_condition": whileStatement_condition,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.withClause) {
- return {
- "withClause_mixinTypes": withClause_mixinTypes,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- if (kind == idl.LinkedNodeKind.yieldStatement) {
- return {
- "yieldStatement_expression": yieldStatement_expression,
- "flags": flags,
- "kind": kind,
- "name": name,
- };
- }
- throw StateError("Unexpected $kind");
- }
-
- @override
- String toString() => convert.json.encode(toJson());
-}
-
-class LinkedNodeBundleBuilder extends Object
- with _LinkedNodeBundleMixin
- implements idl.LinkedNodeBundle {
- List<LinkedNodeLibraryBuilder> _libraries;
- LinkedNodeReferencesBuilder _references;
-
- @override
- List<LinkedNodeLibraryBuilder> get libraries =>
- _libraries ??= <LinkedNodeLibraryBuilder>[];
-
- set libraries(List<LinkedNodeLibraryBuilder> value) {
- this._libraries = value;
- }
-
- @override
- LinkedNodeReferencesBuilder get references => _references;
-
- /// The shared list of references used in the [libraries].
- set references(LinkedNodeReferencesBuilder value) {
- this._references = value;
- }
-
- LinkedNodeBundleBuilder(
- {List<LinkedNodeLibraryBuilder> libraries,
- LinkedNodeReferencesBuilder references})
- : _libraries = libraries,
- _references = references;
-
- /// Flush [informative] data recursively.
- void flushInformative() {
- _libraries?.forEach((b) => b.flushInformative());
- _references?.flushInformative();
- }
-
- /// Accumulate non-[informative] data into [signature].
- void collectApiSignature(api_sig.ApiSignature signature) {
- signature.addBool(this._references != null);
- this._references?.collectApiSignature(signature);
- if (this._libraries == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this._libraries.length);
- for (var x in this._libraries) {
- x?.collectApiSignature(signature);
- }
- }
- }
-
- List<int> toBuffer() {
- fb.Builder fbBuilder = fb.Builder();
- return fbBuilder.finish(finish(fbBuilder), "LNBn");
- }
-
- fb.Offset finish(fb.Builder fbBuilder) {
- fb.Offset offset_libraries;
- fb.Offset offset_references;
- if (!(_libraries == null || _libraries.isEmpty)) {
- offset_libraries = fbBuilder
- .writeList(_libraries.map((b) => b.finish(fbBuilder)).toList());
- }
- if (_references != null) {
- offset_references = _references.finish(fbBuilder);
- }
- fbBuilder.startTable();
- if (offset_libraries != null) {
- fbBuilder.addOffset(1, offset_libraries);
- }
- if (offset_references != null) {
- fbBuilder.addOffset(0, offset_references);
- }
- return fbBuilder.endTable();
- }
-}
-
-idl.LinkedNodeBundle readLinkedNodeBundle(List<int> buffer) {
- fb.BufferContext rootRef = fb.BufferContext.fromBytes(buffer);
- return const _LinkedNodeBundleReader().read(rootRef, 0);
-}
-
-class _LinkedNodeBundleReader extends fb.TableReader<_LinkedNodeBundleImpl> {
- const _LinkedNodeBundleReader();
-
- @override
- _LinkedNodeBundleImpl createObject(fb.BufferContext bc, int offset) =>
- _LinkedNodeBundleImpl(bc, offset);
-}
-
-class _LinkedNodeBundleImpl extends Object
- with _LinkedNodeBundleMixin
- implements idl.LinkedNodeBundle {
- final fb.BufferContext _bc;
- final int _bcOffset;
-
- _LinkedNodeBundleImpl(this._bc, this._bcOffset);
-
- List<idl.LinkedNodeLibrary> _libraries;
- idl.LinkedNodeReferences _references;
-
- @override
- List<idl.LinkedNodeLibrary> get libraries {
- _libraries ??=
- const fb.ListReader<idl.LinkedNodeLibrary>(_LinkedNodeLibraryReader())
- .vTableGet(_bc, _bcOffset, 1, const <idl.LinkedNodeLibrary>[]);
- return _libraries;
- }
-
- @override
- idl.LinkedNodeReferences get references {
- _references ??=
- const _LinkedNodeReferencesReader().vTableGet(_bc, _bcOffset, 0, null);
- return _references;
- }
-}
-
-abstract class _LinkedNodeBundleMixin implements idl.LinkedNodeBundle {
- @override
- Map<String, Object> toJson() {
- Map<String, Object> _result = <String, Object>{};
- if (libraries.isNotEmpty) {
- _result["libraries"] =
- libraries.map((_value) => _value.toJson()).toList();
- }
- if (references != null) {
- _result["references"] = references.toJson();
- }
- return _result;
- }
-
- @override
- Map<String, Object> toMap() => {
- "libraries": libraries,
- "references": references,
- };
-
- @override
- String toString() => convert.json.encode(toJson());
-}
-
-class LinkedNodeLibraryBuilder extends Object
- with _LinkedNodeLibraryMixin
- implements idl.LinkedNodeLibrary {
- List<int> _exports;
- String _name;
- int _nameLength;
- int _nameOffset;
- List<LinkedNodeUnitBuilder> _units;
- String _uriStr;
-
- @override
- List<int> get exports => _exports ??= <int>[];
-
- set exports(List<int> value) {
- assert(value == null || value.every((e) => e >= 0));
- this._exports = value;
- }
-
- @override
- String get name => _name ??= '';
-
- set name(String value) {
- this._name = value;
- }
-
- @override
- int get nameLength => _nameLength ??= 0;
-
- set nameLength(int value) {
- assert(value == null || value >= 0);
- this._nameLength = value;
- }
-
- @override
- int get nameOffset => _nameOffset ??= 0;
-
- set nameOffset(int value) {
- assert(value == null || value >= 0);
- this._nameOffset = value;
- }
-
- @override
- List<LinkedNodeUnitBuilder> get units => _units ??= <LinkedNodeUnitBuilder>[];
-
- set units(List<LinkedNodeUnitBuilder> value) {
- this._units = value;
- }
-
- @override
- String get uriStr => _uriStr ??= '';
-
- set uriStr(String value) {
- this._uriStr = value;
- }
-
- LinkedNodeLibraryBuilder(
- {List<int> exports,
- String name,
- int nameLength,
- int nameOffset,
- List<LinkedNodeUnitBuilder> units,
- String uriStr})
- : _exports = exports,
- _name = name,
- _nameLength = nameLength,
- _nameOffset = nameOffset,
- _units = units,
- _uriStr = uriStr;
-
- /// Flush [informative] data recursively.
- void flushInformative() {
- _units?.forEach((b) => b.flushInformative());
- }
-
- /// Accumulate non-[informative] data into [signature].
- void collectApiSignature(api_sig.ApiSignature signature) {
- signature.addString(this._uriStr ?? '');
- if (this._units == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this._units.length);
- for (var x in this._units) {
- x?.collectApiSignature(signature);
- }
- }
- if (this._exports == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this._exports.length);
- for (var x in this._exports) {
- signature.addInt(x);
- }
- }
- signature.addString(this._name ?? '');
- signature.addInt(this._nameOffset ?? 0);
- signature.addInt(this._nameLength ?? 0);
- }
-
- fb.Offset finish(fb.Builder fbBuilder) {
- fb.Offset offset_exports;
- fb.Offset offset_name;
- fb.Offset offset_units;
- fb.Offset offset_uriStr;
- if (!(_exports == null || _exports.isEmpty)) {
- offset_exports = fbBuilder.writeListUint32(_exports);
- }
- if (_name != null) {
- offset_name = fbBuilder.writeString(_name);
- }
- if (!(_units == null || _units.isEmpty)) {
- offset_units =
- fbBuilder.writeList(_units.map((b) => b.finish(fbBuilder)).toList());
- }
- if (_uriStr != null) {
- offset_uriStr = fbBuilder.writeString(_uriStr);
- }
- fbBuilder.startTable();
- if (offset_exports != null) {
- fbBuilder.addOffset(2, offset_exports);
- }
- if (offset_name != null) {
- fbBuilder.addOffset(3, offset_name);
- }
- if (_nameLength != null && _nameLength != 0) {
- fbBuilder.addUint32(5, _nameLength);
- }
- if (_nameOffset != null && _nameOffset != 0) {
- fbBuilder.addUint32(4, _nameOffset);
- }
- if (offset_units != null) {
- fbBuilder.addOffset(1, offset_units);
- }
- if (offset_uriStr != null) {
- fbBuilder.addOffset(0, offset_uriStr);
- }
- return fbBuilder.endTable();
- }
-}
-
-class _LinkedNodeLibraryReader extends fb.TableReader<_LinkedNodeLibraryImpl> {
- const _LinkedNodeLibraryReader();
-
- @override
- _LinkedNodeLibraryImpl createObject(fb.BufferContext bc, int offset) =>
- _LinkedNodeLibraryImpl(bc, offset);
-}
-
-class _LinkedNodeLibraryImpl extends Object
- with _LinkedNodeLibraryMixin
- implements idl.LinkedNodeLibrary {
- final fb.BufferContext _bc;
- final int _bcOffset;
-
- _LinkedNodeLibraryImpl(this._bc, this._bcOffset);
-
- List<int> _exports;
- String _name;
- int _nameLength;
- int _nameOffset;
- List<idl.LinkedNodeUnit> _units;
- String _uriStr;
-
- @override
- List<int> get exports {
- _exports ??=
- const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 2, const <int>[]);
- return _exports;
- }
-
- @override
- String get name {
- _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 3, '');
- return _name;
- }
-
- @override
- int get nameLength {
- _nameLength ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 5, 0);
- return _nameLength;
- }
-
- @override
- int get nameOffset {
- _nameOffset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 4, 0);
- return _nameOffset;
- }
-
- @override
- List<idl.LinkedNodeUnit> get units {
- _units ??= const fb.ListReader<idl.LinkedNodeUnit>(_LinkedNodeUnitReader())
- .vTableGet(_bc, _bcOffset, 1, const <idl.LinkedNodeUnit>[]);
- return _units;
- }
-
- @override
- String get uriStr {
- _uriStr ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
- return _uriStr;
- }
-}
-
-abstract class _LinkedNodeLibraryMixin implements idl.LinkedNodeLibrary {
- @override
- Map<String, Object> toJson() {
- Map<String, Object> _result = <String, Object>{};
- if (exports.isNotEmpty) {
- _result["exports"] = exports;
- }
- if (name != '') {
- _result["name"] = name;
- }
- if (nameLength != 0) {
- _result["nameLength"] = nameLength;
- }
- if (nameOffset != 0) {
- _result["nameOffset"] = nameOffset;
- }
- if (units.isNotEmpty) {
- _result["units"] = units.map((_value) => _value.toJson()).toList();
- }
- if (uriStr != '') {
- _result["uriStr"] = uriStr;
- }
- return _result;
- }
-
- @override
- Map<String, Object> toMap() => {
- "exports": exports,
- "name": name,
- "nameLength": nameLength,
- "nameOffset": nameOffset,
- "units": units,
- "uriStr": uriStr,
- };
-
- @override
- String toString() => convert.json.encode(toJson());
-}
-
-class LinkedNodeReferencesBuilder extends Object
- with _LinkedNodeReferencesMixin
- implements idl.LinkedNodeReferences {
- List<String> _name;
- List<int> _parent;
-
- @override
- List<String> get name => _name ??= <String>[];
-
- set name(List<String> value) {
- this._name = value;
- }
-
- @override
- List<int> get parent => _parent ??= <int>[];
-
- set parent(List<int> value) {
- assert(value == null || value.every((e) => e >= 0));
- this._parent = value;
- }
-
- LinkedNodeReferencesBuilder({List<String> name, List<int> parent})
- : _name = name,
- _parent = parent;
-
- /// Flush [informative] data recursively.
- void flushInformative() {}
-
- /// Accumulate non-[informative] data into [signature].
- void collectApiSignature(api_sig.ApiSignature signature) {
- if (this._parent == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this._parent.length);
- for (var x in this._parent) {
- signature.addInt(x);
- }
- }
- if (this._name == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this._name.length);
- for (var x in this._name) {
- signature.addString(x);
- }
- }
- }
-
- fb.Offset finish(fb.Builder fbBuilder) {
- fb.Offset offset_name;
- fb.Offset offset_parent;
- if (!(_name == null || _name.isEmpty)) {
- offset_name = fbBuilder
- .writeList(_name.map((b) => fbBuilder.writeString(b)).toList());
- }
- if (!(_parent == null || _parent.isEmpty)) {
- offset_parent = fbBuilder.writeListUint32(_parent);
- }
- fbBuilder.startTable();
- if (offset_name != null) {
- fbBuilder.addOffset(1, offset_name);
- }
- if (offset_parent != null) {
- fbBuilder.addOffset(0, offset_parent);
- }
- return fbBuilder.endTable();
- }
-}
-
-class _LinkedNodeReferencesReader
- extends fb.TableReader<_LinkedNodeReferencesImpl> {
- const _LinkedNodeReferencesReader();
-
- @override
- _LinkedNodeReferencesImpl createObject(fb.BufferContext bc, int offset) =>
- _LinkedNodeReferencesImpl(bc, offset);
-}
-
-class _LinkedNodeReferencesImpl extends Object
- with _LinkedNodeReferencesMixin
- implements idl.LinkedNodeReferences {
- final fb.BufferContext _bc;
- final int _bcOffset;
-
- _LinkedNodeReferencesImpl(this._bc, this._bcOffset);
-
- List<String> _name;
- List<int> _parent;
-
- @override
- List<String> get name {
- _name ??= const fb.ListReader<String>(fb.StringReader())
- .vTableGet(_bc, _bcOffset, 1, const <String>[]);
- return _name;
- }
-
- @override
- List<int> get parent {
- _parent ??=
- const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 0, const <int>[]);
- return _parent;
- }
-}
-
-abstract class _LinkedNodeReferencesMixin implements idl.LinkedNodeReferences {
- @override
- Map<String, Object> toJson() {
- Map<String, Object> _result = <String, Object>{};
- if (name.isNotEmpty) {
- _result["name"] = name;
- }
- if (parent.isNotEmpty) {
- _result["parent"] = parent;
- }
- return _result;
- }
-
- @override
- Map<String, Object> toMap() => {
- "name": name,
- "parent": parent,
- };
-
- @override
- String toString() => convert.json.encode(toJson());
-}
-
-class LinkedNodeTypeBuilder extends Object
- with _LinkedNodeTypeMixin
- implements idl.LinkedNodeType {
- List<LinkedNodeTypeFormalParameterBuilder> _functionFormalParameters;
- LinkedNodeTypeBuilder _functionReturnType;
- int _functionTypedef;
- List<LinkedNodeTypeBuilder> _functionTypedefTypeArguments;
- List<LinkedNodeTypeTypeParameterBuilder> _functionTypeParameters;
- int _interfaceClass;
- List<LinkedNodeTypeBuilder> _interfaceTypeArguments;
- idl.LinkedNodeTypeKind _kind;
- idl.EntityRefNullabilitySuffix _nullabilitySuffix;
- int _typeParameterElement;
- int _typeParameterId;
-
- @override
- List<LinkedNodeTypeFormalParameterBuilder> get functionFormalParameters =>
- _functionFormalParameters ??= <LinkedNodeTypeFormalParameterBuilder>[];
-
- set functionFormalParameters(
- List<LinkedNodeTypeFormalParameterBuilder> value) {
- this._functionFormalParameters = value;
- }
-
- @override
- LinkedNodeTypeBuilder get functionReturnType => _functionReturnType;
-
- set functionReturnType(LinkedNodeTypeBuilder value) {
- this._functionReturnType = value;
- }
-
- @override
- int get functionTypedef => _functionTypedef ??= 0;
-
- /// The typedef this function type is created for.
- set functionTypedef(int value) {
- assert(value == null || value >= 0);
- this._functionTypedef = value;
- }
-
- @override
- List<LinkedNodeTypeBuilder> get functionTypedefTypeArguments =>
- _functionTypedefTypeArguments ??= <LinkedNodeTypeBuilder>[];
-
- set functionTypedefTypeArguments(List<LinkedNodeTypeBuilder> value) {
- this._functionTypedefTypeArguments = value;
- }
-
- @override
- List<LinkedNodeTypeTypeParameterBuilder> get functionTypeParameters =>
- _functionTypeParameters ??= <LinkedNodeTypeTypeParameterBuilder>[];
-
- set functionTypeParameters(List<LinkedNodeTypeTypeParameterBuilder> value) {
- this._functionTypeParameters = value;
- }
-
- @override
- int get interfaceClass => _interfaceClass ??= 0;
-
- /// Reference to a [LinkedNodeReferences].
- set interfaceClass(int value) {
- assert(value == null || value >= 0);
- this._interfaceClass = value;
- }
-
- @override
- List<LinkedNodeTypeBuilder> get interfaceTypeArguments =>
- _interfaceTypeArguments ??= <LinkedNodeTypeBuilder>[];
-
- set interfaceTypeArguments(List<LinkedNodeTypeBuilder> value) {
- this._interfaceTypeArguments = value;
- }
-
- @override
- idl.LinkedNodeTypeKind get kind => _kind ??= idl.LinkedNodeTypeKind.dynamic_;
-
- set kind(idl.LinkedNodeTypeKind value) {
- this._kind = value;
- }
-
- @override
- idl.EntityRefNullabilitySuffix get nullabilitySuffix =>
- _nullabilitySuffix ??= idl.EntityRefNullabilitySuffix.starOrIrrelevant;
-
- set nullabilitySuffix(idl.EntityRefNullabilitySuffix value) {
- this._nullabilitySuffix = value;
- }
-
- @override
- int get typeParameterElement => _typeParameterElement ??= 0;
-
- set typeParameterElement(int value) {
- assert(value == null || value >= 0);
- this._typeParameterElement = value;
- }
-
- @override
- int get typeParameterId => _typeParameterId ??= 0;
-
- set typeParameterId(int value) {
- assert(value == null || value >= 0);
- this._typeParameterId = value;
- }
-
- LinkedNodeTypeBuilder(
- {List<LinkedNodeTypeFormalParameterBuilder> functionFormalParameters,
- LinkedNodeTypeBuilder functionReturnType,
- int functionTypedef,
- List<LinkedNodeTypeBuilder> functionTypedefTypeArguments,
- List<LinkedNodeTypeTypeParameterBuilder> functionTypeParameters,
- int interfaceClass,
- List<LinkedNodeTypeBuilder> interfaceTypeArguments,
- idl.LinkedNodeTypeKind kind,
- idl.EntityRefNullabilitySuffix nullabilitySuffix,
- int typeParameterElement,
- int typeParameterId})
- : _functionFormalParameters = functionFormalParameters,
- _functionReturnType = functionReturnType,
- _functionTypedef = functionTypedef,
- _functionTypedefTypeArguments = functionTypedefTypeArguments,
- _functionTypeParameters = functionTypeParameters,
- _interfaceClass = interfaceClass,
- _interfaceTypeArguments = interfaceTypeArguments,
- _kind = kind,
- _nullabilitySuffix = nullabilitySuffix,
- _typeParameterElement = typeParameterElement,
- _typeParameterId = typeParameterId;
-
- /// Flush [informative] data recursively.
- void flushInformative() {
- _functionFormalParameters?.forEach((b) => b.flushInformative());
- _functionReturnType?.flushInformative();
- _functionTypedefTypeArguments?.forEach((b) => b.flushInformative());
- _functionTypeParameters?.forEach((b) => b.flushInformative());
- _interfaceTypeArguments?.forEach((b) => b.flushInformative());
- }
-
- /// Accumulate non-[informative] data into [signature].
- void collectApiSignature(api_sig.ApiSignature signature) {
- if (this._functionFormalParameters == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this._functionFormalParameters.length);
- for (var x in this._functionFormalParameters) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this._functionReturnType != null);
- this._functionReturnType?.collectApiSignature(signature);
- if (this._functionTypeParameters == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this._functionTypeParameters.length);
- for (var x in this._functionTypeParameters) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addInt(this._interfaceClass ?? 0);
- if (this._interfaceTypeArguments == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this._interfaceTypeArguments.length);
- for (var x in this._interfaceTypeArguments) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addInt(this._kind == null ? 0 : this._kind.index);
- signature.addInt(this._typeParameterElement ?? 0);
- signature.addInt(this._typeParameterId ?? 0);
- signature.addInt(
- this._nullabilitySuffix == null ? 0 : this._nullabilitySuffix.index);
- signature.addInt(this._functionTypedef ?? 0);
- if (this._functionTypedefTypeArguments == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this._functionTypedefTypeArguments.length);
- for (var x in this._functionTypedefTypeArguments) {
- x?.collectApiSignature(signature);
- }
- }
- }
-
- fb.Offset finish(fb.Builder fbBuilder) {
- fb.Offset offset_functionFormalParameters;
- fb.Offset offset_functionReturnType;
- fb.Offset offset_functionTypedefTypeArguments;
- fb.Offset offset_functionTypeParameters;
- fb.Offset offset_interfaceTypeArguments;
- if (!(_functionFormalParameters == null ||
- _functionFormalParameters.isEmpty)) {
- offset_functionFormalParameters = fbBuilder.writeList(
- _functionFormalParameters.map((b) => b.finish(fbBuilder)).toList());
- }
- if (_functionReturnType != null) {
- offset_functionReturnType = _functionReturnType.finish(fbBuilder);
- }
- if (!(_functionTypedefTypeArguments == null ||
- _functionTypedefTypeArguments.isEmpty)) {
- offset_functionTypedefTypeArguments = fbBuilder.writeList(
- _functionTypedefTypeArguments
- .map((b) => b.finish(fbBuilder))
- .toList());
- }
- if (!(_functionTypeParameters == null || _functionTypeParameters.isEmpty)) {
- offset_functionTypeParameters = fbBuilder.writeList(
- _functionTypeParameters.map((b) => b.finish(fbBuilder)).toList());
- }
- if (!(_interfaceTypeArguments == null || _interfaceTypeArguments.isEmpty)) {
- offset_interfaceTypeArguments = fbBuilder.writeList(
- _interfaceTypeArguments.map((b) => b.finish(fbBuilder)).toList());
- }
- fbBuilder.startTable();
- if (offset_functionFormalParameters != null) {
- fbBuilder.addOffset(0, offset_functionFormalParameters);
- }
- if (offset_functionReturnType != null) {
- fbBuilder.addOffset(1, offset_functionReturnType);
- }
- if (_functionTypedef != null && _functionTypedef != 0) {
- fbBuilder.addUint32(9, _functionTypedef);
- }
- if (offset_functionTypedefTypeArguments != null) {
- fbBuilder.addOffset(10, offset_functionTypedefTypeArguments);
- }
- if (offset_functionTypeParameters != null) {
- fbBuilder.addOffset(2, offset_functionTypeParameters);
- }
- if (_interfaceClass != null && _interfaceClass != 0) {
- fbBuilder.addUint32(3, _interfaceClass);
- }
- if (offset_interfaceTypeArguments != null) {
- fbBuilder.addOffset(4, offset_interfaceTypeArguments);
- }
- if (_kind != null && _kind != idl.LinkedNodeTypeKind.dynamic_) {
- fbBuilder.addUint8(5, _kind.index);
- }
- if (_nullabilitySuffix != null &&
- _nullabilitySuffix != idl.EntityRefNullabilitySuffix.starOrIrrelevant) {
- fbBuilder.addUint8(8, _nullabilitySuffix.index);
- }
- if (_typeParameterElement != null && _typeParameterElement != 0) {
- fbBuilder.addUint32(6, _typeParameterElement);
- }
- if (_typeParameterId != null && _typeParameterId != 0) {
- fbBuilder.addUint32(7, _typeParameterId);
- }
- return fbBuilder.endTable();
- }
-}
-
-class _LinkedNodeTypeReader extends fb.TableReader<_LinkedNodeTypeImpl> {
- const _LinkedNodeTypeReader();
-
- @override
- _LinkedNodeTypeImpl createObject(fb.BufferContext bc, int offset) =>
- _LinkedNodeTypeImpl(bc, offset);
-}
-
-class _LinkedNodeTypeImpl extends Object
- with _LinkedNodeTypeMixin
- implements idl.LinkedNodeType {
- final fb.BufferContext _bc;
- final int _bcOffset;
-
- _LinkedNodeTypeImpl(this._bc, this._bcOffset);
-
- List<idl.LinkedNodeTypeFormalParameter> _functionFormalParameters;
- idl.LinkedNodeType _functionReturnType;
- int _functionTypedef;
- List<idl.LinkedNodeType> _functionTypedefTypeArguments;
- List<idl.LinkedNodeTypeTypeParameter> _functionTypeParameters;
- int _interfaceClass;
- List<idl.LinkedNodeType> _interfaceTypeArguments;
- idl.LinkedNodeTypeKind _kind;
- idl.EntityRefNullabilitySuffix _nullabilitySuffix;
- int _typeParameterElement;
- int _typeParameterId;
-
- @override
- List<idl.LinkedNodeTypeFormalParameter> get functionFormalParameters {
- _functionFormalParameters ??=
- const fb.ListReader<idl.LinkedNodeTypeFormalParameter>(
- _LinkedNodeTypeFormalParameterReader())
- .vTableGet(
- _bc, _bcOffset, 0, const <idl.LinkedNodeTypeFormalParameter>[]);
- return _functionFormalParameters;
- }
-
- @override
- idl.LinkedNodeType get functionReturnType {
- _functionReturnType ??=
- const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 1, null);
- return _functionReturnType;
- }
-
- @override
- int get functionTypedef {
- _functionTypedef ??=
- const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 9, 0);
- return _functionTypedef;
- }
-
- @override
- List<idl.LinkedNodeType> get functionTypedefTypeArguments {
- _functionTypedefTypeArguments ??=
- const fb.ListReader<idl.LinkedNodeType>(_LinkedNodeTypeReader())
- .vTableGet(_bc, _bcOffset, 10, const <idl.LinkedNodeType>[]);
- return _functionTypedefTypeArguments;
- }
-
- @override
- List<idl.LinkedNodeTypeTypeParameter> get functionTypeParameters {
- _functionTypeParameters ??=
- const fb.ListReader<idl.LinkedNodeTypeTypeParameter>(
- _LinkedNodeTypeTypeParameterReader())
- .vTableGet(
- _bc, _bcOffset, 2, const <idl.LinkedNodeTypeTypeParameter>[]);
- return _functionTypeParameters;
- }
-
- @override
- int get interfaceClass {
- _interfaceClass ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 3, 0);
- return _interfaceClass;
- }
-
- @override
- List<idl.LinkedNodeType> get interfaceTypeArguments {
- _interfaceTypeArguments ??=
- const fb.ListReader<idl.LinkedNodeType>(_LinkedNodeTypeReader())
- .vTableGet(_bc, _bcOffset, 4, const <idl.LinkedNodeType>[]);
- return _interfaceTypeArguments;
- }
-
- @override
- idl.LinkedNodeTypeKind get kind {
- _kind ??= const _LinkedNodeTypeKindReader()
- .vTableGet(_bc, _bcOffset, 5, idl.LinkedNodeTypeKind.dynamic_);
- return _kind;
- }
-
- @override
- idl.EntityRefNullabilitySuffix get nullabilitySuffix {
- _nullabilitySuffix ??= const _EntityRefNullabilitySuffixReader().vTableGet(
- _bc, _bcOffset, 8, idl.EntityRefNullabilitySuffix.starOrIrrelevant);
- return _nullabilitySuffix;
- }
-
- @override
- int get typeParameterElement {
- _typeParameterElement ??=
- const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 6, 0);
- return _typeParameterElement;
- }
-
- @override
- int get typeParameterId {
- _typeParameterId ??=
- const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 7, 0);
- return _typeParameterId;
- }
-}
-
-abstract class _LinkedNodeTypeMixin implements idl.LinkedNodeType {
- @override
- Map<String, Object> toJson() {
- Map<String, Object> _result = <String, Object>{};
- if (functionFormalParameters.isNotEmpty) {
- _result["functionFormalParameters"] =
- functionFormalParameters.map((_value) => _value.toJson()).toList();
- }
- if (functionReturnType != null) {
- _result["functionReturnType"] = functionReturnType.toJson();
- }
- if (functionTypedef != 0) {
- _result["functionTypedef"] = functionTypedef;
- }
- if (functionTypedefTypeArguments.isNotEmpty) {
- _result["functionTypedefTypeArguments"] = functionTypedefTypeArguments
- .map((_value) => _value.toJson())
- .toList();
- }
- if (functionTypeParameters.isNotEmpty) {
- _result["functionTypeParameters"] =
- functionTypeParameters.map((_value) => _value.toJson()).toList();
- }
- if (interfaceClass != 0) {
- _result["interfaceClass"] = interfaceClass;
- }
- if (interfaceTypeArguments.isNotEmpty) {
- _result["interfaceTypeArguments"] =
- interfaceTypeArguments.map((_value) => _value.toJson()).toList();
- }
- if (kind != idl.LinkedNodeTypeKind.dynamic_) {
- _result["kind"] = kind.toString().split('.')[1];
- }
- if (nullabilitySuffix != idl.EntityRefNullabilitySuffix.starOrIrrelevant) {
- _result["nullabilitySuffix"] = nullabilitySuffix.toString().split('.')[1];
- }
- if (typeParameterElement != 0) {
- _result["typeParameterElement"] = typeParameterElement;
- }
- if (typeParameterId != 0) {
- _result["typeParameterId"] = typeParameterId;
- }
- return _result;
- }
-
- @override
- Map<String, Object> toMap() => {
- "functionFormalParameters": functionFormalParameters,
- "functionReturnType": functionReturnType,
- "functionTypedef": functionTypedef,
- "functionTypedefTypeArguments": functionTypedefTypeArguments,
- "functionTypeParameters": functionTypeParameters,
- "interfaceClass": interfaceClass,
- "interfaceTypeArguments": interfaceTypeArguments,
- "kind": kind,
- "nullabilitySuffix": nullabilitySuffix,
- "typeParameterElement": typeParameterElement,
- "typeParameterId": typeParameterId,
- };
-
- @override
- String toString() => convert.json.encode(toJson());
-}
-
-class LinkedNodeTypeFormalParameterBuilder extends Object
- with _LinkedNodeTypeFormalParameterMixin
- implements idl.LinkedNodeTypeFormalParameter {
- idl.LinkedNodeFormalParameterKind _kind;
- String _name;
- LinkedNodeTypeBuilder _type;
-
- @override
- idl.LinkedNodeFormalParameterKind get kind =>
- _kind ??= idl.LinkedNodeFormalParameterKind.requiredPositional;
-
- set kind(idl.LinkedNodeFormalParameterKind value) {
- this._kind = value;
- }
-
- @override
- String get name => _name ??= '';
-
- set name(String value) {
- this._name = value;
- }
-
- @override
- LinkedNodeTypeBuilder get type => _type;
-
- set type(LinkedNodeTypeBuilder value) {
- this._type = value;
- }
-
- LinkedNodeTypeFormalParameterBuilder(
- {idl.LinkedNodeFormalParameterKind kind,
- String name,
- LinkedNodeTypeBuilder type})
- : _kind = kind,
- _name = name,
- _type = type;
-
- /// Flush [informative] data recursively.
- void flushInformative() {
- _type?.flushInformative();
- }
-
- /// Accumulate non-[informative] data into [signature].
- void collectApiSignature(api_sig.ApiSignature signature) {
- signature.addInt(this._kind == null ? 0 : this._kind.index);
- signature.addString(this._name ?? '');
- signature.addBool(this._type != null);
- this._type?.collectApiSignature(signature);
- }
-
- fb.Offset finish(fb.Builder fbBuilder) {
- fb.Offset offset_name;
- fb.Offset offset_type;
- if (_name != null) {
- offset_name = fbBuilder.writeString(_name);
- }
- if (_type != null) {
- offset_type = _type.finish(fbBuilder);
- }
- fbBuilder.startTable();
- if (_kind != null &&
- _kind != idl.LinkedNodeFormalParameterKind.requiredPositional) {
- fbBuilder.addUint8(0, _kind.index);
- }
- if (offset_name != null) {
- fbBuilder.addOffset(1, offset_name);
- }
- if (offset_type != null) {
- fbBuilder.addOffset(2, offset_type);
- }
- return fbBuilder.endTable();
- }
-}
-
-class _LinkedNodeTypeFormalParameterReader
- extends fb.TableReader<_LinkedNodeTypeFormalParameterImpl> {
- const _LinkedNodeTypeFormalParameterReader();
-
- @override
- _LinkedNodeTypeFormalParameterImpl createObject(
- fb.BufferContext bc, int offset) =>
- _LinkedNodeTypeFormalParameterImpl(bc, offset);
-}
-
-class _LinkedNodeTypeFormalParameterImpl extends Object
- with _LinkedNodeTypeFormalParameterMixin
- implements idl.LinkedNodeTypeFormalParameter {
- final fb.BufferContext _bc;
- final int _bcOffset;
-
- _LinkedNodeTypeFormalParameterImpl(this._bc, this._bcOffset);
-
- idl.LinkedNodeFormalParameterKind _kind;
- String _name;
- idl.LinkedNodeType _type;
-
- @override
- idl.LinkedNodeFormalParameterKind get kind {
- _kind ??= const _LinkedNodeFormalParameterKindReader().vTableGet(_bc,
- _bcOffset, 0, idl.LinkedNodeFormalParameterKind.requiredPositional);
- return _kind;
- }
-
- @override
- String get name {
- _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 1, '');
- return _name;
- }
-
- @override
- idl.LinkedNodeType get type {
- _type ??= const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 2, null);
- return _type;
- }
-}
-
-abstract class _LinkedNodeTypeFormalParameterMixin
- implements idl.LinkedNodeTypeFormalParameter {
- @override
- Map<String, Object> toJson() {
- Map<String, Object> _result = <String, Object>{};
- if (kind != idl.LinkedNodeFormalParameterKind.requiredPositional) {
- _result["kind"] = kind.toString().split('.')[1];
- }
- if (name != '') {
- _result["name"] = name;
- }
- if (type != null) {
- _result["type"] = type.toJson();
- }
- return _result;
- }
-
- @override
- Map<String, Object> toMap() => {
- "kind": kind,
- "name": name,
- "type": type,
- };
-
- @override
- String toString() => convert.json.encode(toJson());
-}
-
-class LinkedNodeTypeSubstitutionBuilder extends Object
- with _LinkedNodeTypeSubstitutionMixin
- implements idl.LinkedNodeTypeSubstitution {
- bool _isLegacy;
- List<LinkedNodeTypeBuilder> _typeArguments;
- List<int> _typeParameters;
-
- @override
- bool get isLegacy => _isLegacy ??= false;
-
- set isLegacy(bool value) {
- this._isLegacy = value;
- }
-
- @override
- List<LinkedNodeTypeBuilder> get typeArguments =>
- _typeArguments ??= <LinkedNodeTypeBuilder>[];
-
- set typeArguments(List<LinkedNodeTypeBuilder> value) {
- this._typeArguments = value;
- }
-
- @override
- List<int> get typeParameters => _typeParameters ??= <int>[];
-
- set typeParameters(List<int> value) {
- assert(value == null || value.every((e) => e >= 0));
- this._typeParameters = value;
- }
-
- LinkedNodeTypeSubstitutionBuilder(
- {bool isLegacy,
- List<LinkedNodeTypeBuilder> typeArguments,
- List<int> typeParameters})
- : _isLegacy = isLegacy,
- _typeArguments = typeArguments,
- _typeParameters = typeParameters;
-
- /// Flush [informative] data recursively.
- void flushInformative() {
- _typeArguments?.forEach((b) => b.flushInformative());
- }
-
- /// Accumulate non-[informative] data into [signature].
- void collectApiSignature(api_sig.ApiSignature signature) {
- if (this._typeParameters == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this._typeParameters.length);
- for (var x in this._typeParameters) {
- signature.addInt(x);
- }
- }
- if (this._typeArguments == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this._typeArguments.length);
- for (var x in this._typeArguments) {
- x?.collectApiSignature(signature);
- }
- }
- signature.addBool(this._isLegacy == true);
- }
-
- fb.Offset finish(fb.Builder fbBuilder) {
- fb.Offset offset_typeArguments;
- fb.Offset offset_typeParameters;
- if (!(_typeArguments == null || _typeArguments.isEmpty)) {
- offset_typeArguments = fbBuilder
- .writeList(_typeArguments.map((b) => b.finish(fbBuilder)).toList());
- }
- if (!(_typeParameters == null || _typeParameters.isEmpty)) {
- offset_typeParameters = fbBuilder.writeListUint32(_typeParameters);
- }
- fbBuilder.startTable();
- if (_isLegacy == true) {
- fbBuilder.addBool(2, true);
- }
- if (offset_typeArguments != null) {
- fbBuilder.addOffset(1, offset_typeArguments);
- }
- if (offset_typeParameters != null) {
- fbBuilder.addOffset(0, offset_typeParameters);
- }
- return fbBuilder.endTable();
- }
-}
-
-class _LinkedNodeTypeSubstitutionReader
- extends fb.TableReader<_LinkedNodeTypeSubstitutionImpl> {
- const _LinkedNodeTypeSubstitutionReader();
-
- @override
- _LinkedNodeTypeSubstitutionImpl createObject(
- fb.BufferContext bc, int offset) =>
- _LinkedNodeTypeSubstitutionImpl(bc, offset);
-}
-
-class _LinkedNodeTypeSubstitutionImpl extends Object
- with _LinkedNodeTypeSubstitutionMixin
- implements idl.LinkedNodeTypeSubstitution {
- final fb.BufferContext _bc;
- final int _bcOffset;
-
- _LinkedNodeTypeSubstitutionImpl(this._bc, this._bcOffset);
-
- bool _isLegacy;
- List<idl.LinkedNodeType> _typeArguments;
- List<int> _typeParameters;
-
- @override
- bool get isLegacy {
- _isLegacy ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 2, false);
- return _isLegacy;
- }
-
- @override
- List<idl.LinkedNodeType> get typeArguments {
- _typeArguments ??=
- const fb.ListReader<idl.LinkedNodeType>(_LinkedNodeTypeReader())
- .vTableGet(_bc, _bcOffset, 1, const <idl.LinkedNodeType>[]);
- return _typeArguments;
- }
-
- @override
- List<int> get typeParameters {
- _typeParameters ??=
- const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 0, const <int>[]);
- return _typeParameters;
- }
-}
-
-abstract class _LinkedNodeTypeSubstitutionMixin
- implements idl.LinkedNodeTypeSubstitution {
- @override
- Map<String, Object> toJson() {
- Map<String, Object> _result = <String, Object>{};
- if (isLegacy != false) {
- _result["isLegacy"] = isLegacy;
- }
- if (typeArguments.isNotEmpty) {
- _result["typeArguments"] =
- typeArguments.map((_value) => _value.toJson()).toList();
- }
- if (typeParameters.isNotEmpty) {
- _result["typeParameters"] = typeParameters;
- }
- return _result;
- }
-
- @override
- Map<String, Object> toMap() => {
- "isLegacy": isLegacy,
- "typeArguments": typeArguments,
- "typeParameters": typeParameters,
- };
-
- @override
- String toString() => convert.json.encode(toJson());
-}
-
-class LinkedNodeTypeTypeParameterBuilder extends Object
- with _LinkedNodeTypeTypeParameterMixin
- implements idl.LinkedNodeTypeTypeParameter {
- LinkedNodeTypeBuilder _bound;
- String _name;
-
- @override
- LinkedNodeTypeBuilder get bound => _bound;
-
- set bound(LinkedNodeTypeBuilder value) {
- this._bound = value;
- }
-
- @override
- String get name => _name ??= '';
-
- set name(String value) {
- this._name = value;
- }
-
- LinkedNodeTypeTypeParameterBuilder({LinkedNodeTypeBuilder bound, String name})
- : _bound = bound,
- _name = name;
-
- /// Flush [informative] data recursively.
- void flushInformative() {
- _bound?.flushInformative();
- }
-
- /// Accumulate non-[informative] data into [signature].
- void collectApiSignature(api_sig.ApiSignature signature) {
- signature.addString(this._name ?? '');
- signature.addBool(this._bound != null);
- this._bound?.collectApiSignature(signature);
- }
-
- fb.Offset finish(fb.Builder fbBuilder) {
- fb.Offset offset_bound;
- fb.Offset offset_name;
- if (_bound != null) {
- offset_bound = _bound.finish(fbBuilder);
- }
- if (_name != null) {
- offset_name = fbBuilder.writeString(_name);
- }
- fbBuilder.startTable();
- if (offset_bound != null) {
- fbBuilder.addOffset(1, offset_bound);
- }
- if (offset_name != null) {
- fbBuilder.addOffset(0, offset_name);
- }
- return fbBuilder.endTable();
- }
-}
-
-class _LinkedNodeTypeTypeParameterReader
- extends fb.TableReader<_LinkedNodeTypeTypeParameterImpl> {
- const _LinkedNodeTypeTypeParameterReader();
-
- @override
- _LinkedNodeTypeTypeParameterImpl createObject(
- fb.BufferContext bc, int offset) =>
- _LinkedNodeTypeTypeParameterImpl(bc, offset);
-}
-
-class _LinkedNodeTypeTypeParameterImpl extends Object
- with _LinkedNodeTypeTypeParameterMixin
- implements idl.LinkedNodeTypeTypeParameter {
- final fb.BufferContext _bc;
- final int _bcOffset;
-
- _LinkedNodeTypeTypeParameterImpl(this._bc, this._bcOffset);
-
- idl.LinkedNodeType _bound;
- String _name;
-
- @override
- idl.LinkedNodeType get bound {
- _bound ??= const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 1, null);
- return _bound;
- }
-
- @override
- String get name {
- _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
- return _name;
- }
-}
-
-abstract class _LinkedNodeTypeTypeParameterMixin
- implements idl.LinkedNodeTypeTypeParameter {
- @override
- Map<String, Object> toJson() {
- Map<String, Object> _result = <String, Object>{};
- if (bound != null) {
- _result["bound"] = bound.toJson();
- }
- if (name != '') {
- _result["name"] = name;
- }
- return _result;
- }
-
- @override
- Map<String, Object> toMap() => {
- "bound": bound,
- "name": name,
- };
-
- @override
- String toString() => convert.json.encode(toJson());
-}
-
-class LinkedNodeUnitBuilder extends Object
- with _LinkedNodeUnitMixin
- implements idl.LinkedNodeUnit {
- bool _isSynthetic;
- LinkedNodeBuilder _node;
- String _partUriStr;
- String _uriStr;
-
- @override
- bool get isSynthetic => _isSynthetic ??= false;
-
- set isSynthetic(bool value) {
- this._isSynthetic = value;
- }
-
- @override
- LinkedNodeBuilder get node => _node;
-
- set node(LinkedNodeBuilder value) {
- this._node = value;
- }
-
- @override
- String get partUriStr => _partUriStr ??= '';
-
- /// If the unit is a part, the URI specified in the `part` directive.
- /// Otherwise empty.
- set partUriStr(String value) {
- this._partUriStr = value;
- }
-
- @override
- String get uriStr => _uriStr ??= '';
-
- /// The absolute URI.
- set uriStr(String value) {
- this._uriStr = value;
- }
-
- LinkedNodeUnitBuilder(
- {bool isSynthetic,
- LinkedNodeBuilder node,
- String partUriStr,
- String uriStr})
- : _isSynthetic = isSynthetic,
- _node = node,
- _partUriStr = partUriStr,
- _uriStr = uriStr;
-
- /// Flush [informative] data recursively.
- void flushInformative() {
- _node?.flushInformative();
- }
-
- /// Accumulate non-[informative] data into [signature].
- void collectApiSignature(api_sig.ApiSignature signature) {
- signature.addString(this._uriStr ?? '');
- signature.addBool(this._node != null);
- this._node?.collectApiSignature(signature);
- signature.addBool(this._isSynthetic == true);
- signature.addString(this._partUriStr ?? '');
- }
-
- fb.Offset finish(fb.Builder fbBuilder) {
- fb.Offset offset_node;
- fb.Offset offset_partUriStr;
- fb.Offset offset_uriStr;
- if (_node != null) {
- offset_node = _node.finish(fbBuilder);
- }
- if (_partUriStr != null) {
- offset_partUriStr = fbBuilder.writeString(_partUriStr);
- }
- if (_uriStr != null) {
- offset_uriStr = fbBuilder.writeString(_uriStr);
- }
- fbBuilder.startTable();
- if (_isSynthetic == true) {
- fbBuilder.addBool(2, true);
- }
- if (offset_node != null) {
- fbBuilder.addOffset(1, offset_node);
- }
- if (offset_partUriStr != null) {
- fbBuilder.addOffset(3, offset_partUriStr);
- }
- if (offset_uriStr != null) {
- fbBuilder.addOffset(0, offset_uriStr);
- }
- return fbBuilder.endTable();
- }
-}
-
-class _LinkedNodeUnitReader extends fb.TableReader<_LinkedNodeUnitImpl> {
- const _LinkedNodeUnitReader();
-
- @override
- _LinkedNodeUnitImpl createObject(fb.BufferContext bc, int offset) =>
- _LinkedNodeUnitImpl(bc, offset);
-}
-
-class _LinkedNodeUnitImpl extends Object
- with _LinkedNodeUnitMixin
- implements idl.LinkedNodeUnit {
- final fb.BufferContext _bc;
- final int _bcOffset;
-
- _LinkedNodeUnitImpl(this._bc, this._bcOffset);
-
- bool _isSynthetic;
- idl.LinkedNode _node;
- String _partUriStr;
- String _uriStr;
-
- @override
- bool get isSynthetic {
- _isSynthetic ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 2, false);
- return _isSynthetic;
- }
-
- @override
- idl.LinkedNode get node {
- _node ??= const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 1, null);
- return _node;
- }
-
- @override
- String get partUriStr {
- _partUriStr ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 3, '');
- return _partUriStr;
- }
-
- @override
- String get uriStr {
- _uriStr ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
- return _uriStr;
- }
-}
-
-abstract class _LinkedNodeUnitMixin implements idl.LinkedNodeUnit {
- @override
- Map<String, Object> toJson() {
- Map<String, Object> _result = <String, Object>{};
- if (isSynthetic != false) {
- _result["isSynthetic"] = isSynthetic;
- }
- if (node != null) {
- _result["node"] = node.toJson();
- }
- if (partUriStr != '') {
- _result["partUriStr"] = partUriStr;
- }
- if (uriStr != '') {
- _result["uriStr"] = uriStr;
- }
- return _result;
- }
-
- @override
- Map<String, Object> toMap() => {
- "isSynthetic": isSynthetic,
- "node": node,
- "partUriStr": partUriStr,
- "uriStr": uriStr,
- };
-
- @override
- String toString() => convert.json.encode(toJson());
-}
-
class PackageBundleBuilder extends Object
with _PackageBundleMixin
implements idl.PackageBundle {
- LinkedNodeBundleBuilder _bundle2;
- PackageBundleSdkBuilder _sdk;
+ int _fake;
@override
- LinkedNodeBundleBuilder get bundle2 => _bundle2;
+ int get fake => _fake ??= 0;
/// The version 2 of the summary.
- set bundle2(LinkedNodeBundleBuilder value) {
- this._bundle2 = value;
+ set fake(int value) {
+ assert(value == null || value >= 0);
+ this._fake = value;
}
- @override
- PackageBundleSdkBuilder get sdk => _sdk;
-
- /// The SDK specific data, if this bundle is for SDK.
- set sdk(PackageBundleSdkBuilder value) {
- this._sdk = value;
- }
-
- PackageBundleBuilder(
- {LinkedNodeBundleBuilder bundle2, PackageBundleSdkBuilder sdk})
- : _bundle2 = bundle2,
- _sdk = sdk;
+ PackageBundleBuilder({int fake}) : _fake = fake;
/// Flush [informative] data recursively.
- void flushInformative() {
- _bundle2?.flushInformative();
- _sdk?.flushInformative();
- }
+ void flushInformative() {}
/// Accumulate non-[informative] data into [signature].
void collectApiSignature(api_sig.ApiSignature signature) {
- signature.addBool(this._bundle2 != null);
- this._bundle2?.collectApiSignature(signature);
- signature.addBool(this._sdk != null);
- this._sdk?.collectApiSignature(signature);
+ signature.addInt(this._fake ?? 0);
}
List<int> toBuffer() {
@@ -17724,20 +4001,9 @@
}
fb.Offset finish(fb.Builder fbBuilder) {
- fb.Offset offset_bundle2;
- fb.Offset offset_sdk;
- if (_bundle2 != null) {
- offset_bundle2 = _bundle2.finish(fbBuilder);
- }
- if (_sdk != null) {
- offset_sdk = _sdk.finish(fbBuilder);
- }
fbBuilder.startTable();
- if (offset_bundle2 != null) {
- fbBuilder.addOffset(0, offset_bundle2);
- }
- if (offset_sdk != null) {
- fbBuilder.addOffset(1, offset_sdk);
+ if (_fake != null && _fake != 0) {
+ fbBuilder.addUint32(0, _fake);
}
return fbBuilder.endTable();
}
@@ -17764,20 +4030,12 @@
_PackageBundleImpl(this._bc, this._bcOffset);
- idl.LinkedNodeBundle _bundle2;
- idl.PackageBundleSdk _sdk;
+ int _fake;
@override
- idl.LinkedNodeBundle get bundle2 {
- _bundle2 ??=
- const _LinkedNodeBundleReader().vTableGet(_bc, _bcOffset, 0, null);
- return _bundle2;
- }
-
- @override
- idl.PackageBundleSdk get sdk {
- _sdk ??= const _PackageBundleSdkReader().vTableGet(_bc, _bcOffset, 1, null);
- return _sdk;
+ int get fake {
+ _fake ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 0, 0);
+ return _fake;
}
}
@@ -17785,1862 +4043,21 @@
@override
Map<String, Object> toJson() {
Map<String, Object> _result = <String, Object>{};
- if (bundle2 != null) {
- _result["bundle2"] = bundle2.toJson();
- }
- if (sdk != null) {
- _result["sdk"] = sdk.toJson();
+ if (fake != 0) {
+ _result["fake"] = fake;
}
return _result;
}
@override
Map<String, Object> toMap() => {
- "bundle2": bundle2,
- "sdk": sdk,
+ "fake": fake,
};
@override
String toString() => convert.json.encode(toJson());
}
-class PackageBundleSdkBuilder extends Object
- with _PackageBundleSdkMixin
- implements idl.PackageBundleSdk {
- String _allowedExperimentsJson;
- LinkedLanguageVersionBuilder _languageVersion;
-
- @override
- String get allowedExperimentsJson => _allowedExperimentsJson ??= '';
-
- /// The content of the `allowed_experiments.json` from SDK.
- set allowedExperimentsJson(String value) {
- this._allowedExperimentsJson = value;
- }
-
- @override
- LinkedLanguageVersionBuilder get languageVersion => _languageVersion;
-
- /// The language version of the SDK.
- set languageVersion(LinkedLanguageVersionBuilder value) {
- this._languageVersion = value;
- }
-
- PackageBundleSdkBuilder(
- {String allowedExperimentsJson,
- LinkedLanguageVersionBuilder languageVersion})
- : _allowedExperimentsJson = allowedExperimentsJson,
- _languageVersion = languageVersion;
-
- /// Flush [informative] data recursively.
- void flushInformative() {
- _languageVersion?.flushInformative();
- }
-
- /// Accumulate non-[informative] data into [signature].
- void collectApiSignature(api_sig.ApiSignature signature) {
- signature.addString(this._allowedExperimentsJson ?? '');
- signature.addBool(this._languageVersion != null);
- this._languageVersion?.collectApiSignature(signature);
- }
-
- fb.Offset finish(fb.Builder fbBuilder) {
- fb.Offset offset_allowedExperimentsJson;
- fb.Offset offset_languageVersion;
- if (_allowedExperimentsJson != null) {
- offset_allowedExperimentsJson =
- fbBuilder.writeString(_allowedExperimentsJson);
- }
- if (_languageVersion != null) {
- offset_languageVersion = _languageVersion.finish(fbBuilder);
- }
- fbBuilder.startTable();
- if (offset_allowedExperimentsJson != null) {
- fbBuilder.addOffset(0, offset_allowedExperimentsJson);
- }
- if (offset_languageVersion != null) {
- fbBuilder.addOffset(1, offset_languageVersion);
- }
- return fbBuilder.endTable();
- }
-}
-
-class _PackageBundleSdkReader extends fb.TableReader<_PackageBundleSdkImpl> {
- const _PackageBundleSdkReader();
-
- @override
- _PackageBundleSdkImpl createObject(fb.BufferContext bc, int offset) =>
- _PackageBundleSdkImpl(bc, offset);
-}
-
-class _PackageBundleSdkImpl extends Object
- with _PackageBundleSdkMixin
- implements idl.PackageBundleSdk {
- final fb.BufferContext _bc;
- final int _bcOffset;
-
- _PackageBundleSdkImpl(this._bc, this._bcOffset);
-
- String _allowedExperimentsJson;
- idl.LinkedLanguageVersion _languageVersion;
-
- @override
- String get allowedExperimentsJson {
- _allowedExperimentsJson ??=
- const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
- return _allowedExperimentsJson;
- }
-
- @override
- idl.LinkedLanguageVersion get languageVersion {
- _languageVersion ??=
- const _LinkedLanguageVersionReader().vTableGet(_bc, _bcOffset, 1, null);
- return _languageVersion;
- }
-}
-
-abstract class _PackageBundleSdkMixin implements idl.PackageBundleSdk {
- @override
- Map<String, Object> toJson() {
- Map<String, Object> _result = <String, Object>{};
- if (allowedExperimentsJson != '') {
- _result["allowedExperimentsJson"] = allowedExperimentsJson;
- }
- if (languageVersion != null) {
- _result["languageVersion"] = languageVersion.toJson();
- }
- return _result;
- }
-
- @override
- Map<String, Object> toMap() => {
- "allowedExperimentsJson": allowedExperimentsJson,
- "languageVersion": languageVersion,
- };
-
- @override
- String toString() => convert.json.encode(toJson());
-}
-
-class TopLevelInferenceErrorBuilder extends Object
- with _TopLevelInferenceErrorMixin
- implements idl.TopLevelInferenceError {
- List<String> _arguments;
- idl.TopLevelInferenceErrorKind _kind;
-
- @override
- List<String> get arguments => _arguments ??= <String>[];
-
- /// The [kind] specific arguments.
- set arguments(List<String> value) {
- this._arguments = value;
- }
-
- @override
- idl.TopLevelInferenceErrorKind get kind =>
- _kind ??= idl.TopLevelInferenceErrorKind.assignment;
-
- /// The kind of the error.
- set kind(idl.TopLevelInferenceErrorKind value) {
- this._kind = value;
- }
-
- TopLevelInferenceErrorBuilder(
- {List<String> arguments, idl.TopLevelInferenceErrorKind kind})
- : _arguments = arguments,
- _kind = kind;
-
- /// Flush [informative] data recursively.
- void flushInformative() {}
-
- /// Accumulate non-[informative] data into [signature].
- void collectApiSignature(api_sig.ApiSignature signature) {
- signature.addInt(this._kind == null ? 0 : this._kind.index);
- if (this._arguments == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this._arguments.length);
- for (var x in this._arguments) {
- signature.addString(x);
- }
- }
- }
-
- fb.Offset finish(fb.Builder fbBuilder) {
- fb.Offset offset_arguments;
- if (!(_arguments == null || _arguments.isEmpty)) {
- offset_arguments = fbBuilder
- .writeList(_arguments.map((b) => fbBuilder.writeString(b)).toList());
- }
- fbBuilder.startTable();
- if (offset_arguments != null) {
- fbBuilder.addOffset(1, offset_arguments);
- }
- if (_kind != null && _kind != idl.TopLevelInferenceErrorKind.assignment) {
- fbBuilder.addUint8(0, _kind.index);
- }
- return fbBuilder.endTable();
- }
-}
-
-class _TopLevelInferenceErrorReader
- extends fb.TableReader<_TopLevelInferenceErrorImpl> {
- const _TopLevelInferenceErrorReader();
-
- @override
- _TopLevelInferenceErrorImpl createObject(fb.BufferContext bc, int offset) =>
- _TopLevelInferenceErrorImpl(bc, offset);
-}
-
-class _TopLevelInferenceErrorImpl extends Object
- with _TopLevelInferenceErrorMixin
- implements idl.TopLevelInferenceError {
- final fb.BufferContext _bc;
- final int _bcOffset;
-
- _TopLevelInferenceErrorImpl(this._bc, this._bcOffset);
-
- List<String> _arguments;
- idl.TopLevelInferenceErrorKind _kind;
-
- @override
- List<String> get arguments {
- _arguments ??= const fb.ListReader<String>(fb.StringReader())
- .vTableGet(_bc, _bcOffset, 1, const <String>[]);
- return _arguments;
- }
-
- @override
- idl.TopLevelInferenceErrorKind get kind {
- _kind ??= const _TopLevelInferenceErrorKindReader().vTableGet(
- _bc, _bcOffset, 0, idl.TopLevelInferenceErrorKind.assignment);
- return _kind;
- }
-}
-
-abstract class _TopLevelInferenceErrorMixin
- implements idl.TopLevelInferenceError {
- @override
- Map<String, Object> toJson() {
- Map<String, Object> _result = <String, Object>{};
- if (arguments.isNotEmpty) {
- _result["arguments"] = arguments;
- }
- if (kind != idl.TopLevelInferenceErrorKind.assignment) {
- _result["kind"] = kind.toString().split('.')[1];
- }
- return _result;
- }
-
- @override
- Map<String, Object> toMap() => {
- "arguments": arguments,
- "kind": kind,
- };
-
- @override
- String toString() => convert.json.encode(toJson());
-}
-
-class UnlinkedInformativeDataBuilder extends Object
- with _UnlinkedInformativeDataMixin
- implements idl.UnlinkedInformativeData {
- int _variantField_2;
- int _variantField_3;
- int _variantField_9;
- int _variantField_8;
- List<int> _variantField_7;
- int _variantField_6;
- int _variantField_5;
- String _variantField_10;
- int _variantField_1;
- List<String> _variantField_4;
- idl.LinkedNodeKind _kind;
-
- @override
- int get codeLength {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.classTypeAlias ||
- kind == idl.LinkedNodeKind.compilationUnit ||
- kind == idl.LinkedNodeKind.constructorDeclaration ||
- kind == idl.LinkedNodeKind.defaultFormalParameter ||
- kind == idl.LinkedNodeKind.enumConstantDeclaration ||
- kind == idl.LinkedNodeKind.enumDeclaration ||
- kind == idl.LinkedNodeKind.extensionDeclaration ||
- kind == idl.LinkedNodeKind.fieldFormalParameter ||
- kind == idl.LinkedNodeKind.functionDeclaration ||
- kind == idl.LinkedNodeKind.functionTypeAlias ||
- kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
- kind == idl.LinkedNodeKind.genericTypeAlias ||
- kind == idl.LinkedNodeKind.methodDeclaration ||
- kind == idl.LinkedNodeKind.mixinDeclaration ||
- kind == idl.LinkedNodeKind.simpleFormalParameter ||
- kind == idl.LinkedNodeKind.typeParameter ||
- kind == idl.LinkedNodeKind.variableDeclaration);
- return _variantField_2 ??= 0;
- }
-
- set codeLength(int value) {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.classTypeAlias ||
- kind == idl.LinkedNodeKind.compilationUnit ||
- kind == idl.LinkedNodeKind.constructorDeclaration ||
- kind == idl.LinkedNodeKind.defaultFormalParameter ||
- kind == idl.LinkedNodeKind.enumConstantDeclaration ||
- kind == idl.LinkedNodeKind.enumDeclaration ||
- kind == idl.LinkedNodeKind.extensionDeclaration ||
- kind == idl.LinkedNodeKind.fieldFormalParameter ||
- kind == idl.LinkedNodeKind.functionDeclaration ||
- kind == idl.LinkedNodeKind.functionTypeAlias ||
- kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
- kind == idl.LinkedNodeKind.genericTypeAlias ||
- kind == idl.LinkedNodeKind.methodDeclaration ||
- kind == idl.LinkedNodeKind.mixinDeclaration ||
- kind == idl.LinkedNodeKind.simpleFormalParameter ||
- kind == idl.LinkedNodeKind.typeParameter ||
- kind == idl.LinkedNodeKind.variableDeclaration);
- assert(value == null || value >= 0);
- _variantField_2 = value;
- }
-
- @override
- int get codeOffset {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.classTypeAlias ||
- kind == idl.LinkedNodeKind.compilationUnit ||
- kind == idl.LinkedNodeKind.constructorDeclaration ||
- kind == idl.LinkedNodeKind.defaultFormalParameter ||
- kind == idl.LinkedNodeKind.enumConstantDeclaration ||
- kind == idl.LinkedNodeKind.enumDeclaration ||
- kind == idl.LinkedNodeKind.extensionDeclaration ||
- kind == idl.LinkedNodeKind.fieldFormalParameter ||
- kind == idl.LinkedNodeKind.functionDeclaration ||
- kind == idl.LinkedNodeKind.functionTypeAlias ||
- kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
- kind == idl.LinkedNodeKind.genericTypeAlias ||
- kind == idl.LinkedNodeKind.methodDeclaration ||
- kind == idl.LinkedNodeKind.mixinDeclaration ||
- kind == idl.LinkedNodeKind.simpleFormalParameter ||
- kind == idl.LinkedNodeKind.typeParameter ||
- kind == idl.LinkedNodeKind.variableDeclaration);
- return _variantField_3 ??= 0;
- }
-
- set codeOffset(int value) {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.classTypeAlias ||
- kind == idl.LinkedNodeKind.compilationUnit ||
- kind == idl.LinkedNodeKind.constructorDeclaration ||
- kind == idl.LinkedNodeKind.defaultFormalParameter ||
- kind == idl.LinkedNodeKind.enumConstantDeclaration ||
- kind == idl.LinkedNodeKind.enumDeclaration ||
- kind == idl.LinkedNodeKind.extensionDeclaration ||
- kind == idl.LinkedNodeKind.fieldFormalParameter ||
- kind == idl.LinkedNodeKind.functionDeclaration ||
- kind == idl.LinkedNodeKind.functionTypeAlias ||
- kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
- kind == idl.LinkedNodeKind.genericTypeAlias ||
- kind == idl.LinkedNodeKind.methodDeclaration ||
- kind == idl.LinkedNodeKind.mixinDeclaration ||
- kind == idl.LinkedNodeKind.simpleFormalParameter ||
- kind == idl.LinkedNodeKind.typeParameter ||
- kind == idl.LinkedNodeKind.variableDeclaration);
- assert(value == null || value >= 0);
- _variantField_3 = value;
- }
-
- @override
- int get combinatorEnd {
- assert(kind == idl.LinkedNodeKind.hideCombinator ||
- kind == idl.LinkedNodeKind.showCombinator);
- return _variantField_9 ??= 0;
- }
-
- set combinatorEnd(int value) {
- assert(kind == idl.LinkedNodeKind.hideCombinator ||
- kind == idl.LinkedNodeKind.showCombinator);
- assert(value == null || value >= 0);
- _variantField_9 = value;
- }
-
- @override
- int get combinatorKeywordOffset {
- assert(kind == idl.LinkedNodeKind.hideCombinator ||
- kind == idl.LinkedNodeKind.showCombinator);
- return _variantField_8 ??= 0;
- }
-
- @override
- int get importDirective_prefixOffset {
- assert(kind == idl.LinkedNodeKind.importDirective);
- return _variantField_8 ??= 0;
- }
-
- set combinatorKeywordOffset(int value) {
- assert(kind == idl.LinkedNodeKind.hideCombinator ||
- kind == idl.LinkedNodeKind.showCombinator);
- assert(value == null || value >= 0);
- _variantField_8 = value;
- }
-
- set importDirective_prefixOffset(int value) {
- assert(kind == idl.LinkedNodeKind.importDirective);
- assert(value == null || value >= 0);
- _variantField_8 = value;
- }
-
- @override
- List<int> get compilationUnit_lineStarts {
- assert(kind == idl.LinkedNodeKind.compilationUnit);
- return _variantField_7 ??= <int>[];
- }
-
- /// Offsets of the first character of each line in the source code.
- set compilationUnit_lineStarts(List<int> value) {
- assert(kind == idl.LinkedNodeKind.compilationUnit);
- assert(value == null || value.every((e) => e >= 0));
- _variantField_7 = value;
- }
-
- @override
- int get constructorDeclaration_periodOffset {
- assert(kind == idl.LinkedNodeKind.constructorDeclaration);
- return _variantField_6 ??= 0;
- }
-
- set constructorDeclaration_periodOffset(int value) {
- assert(kind == idl.LinkedNodeKind.constructorDeclaration);
- assert(value == null || value >= 0);
- _variantField_6 = value;
- }
-
- @override
- int get constructorDeclaration_returnTypeOffset {
- assert(kind == idl.LinkedNodeKind.constructorDeclaration);
- return _variantField_5 ??= 0;
- }
-
- set constructorDeclaration_returnTypeOffset(int value) {
- assert(kind == idl.LinkedNodeKind.constructorDeclaration);
- assert(value == null || value >= 0);
- _variantField_5 = value;
- }
-
- @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 ||
- kind == idl.LinkedNodeKind.libraryDirective ||
- kind == idl.LinkedNodeKind.partDirective ||
- kind == idl.LinkedNodeKind.partOfDirective);
- return _variantField_1 ??= 0;
- }
-
- @override
- int get nameOffset {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.classTypeAlias ||
- kind == idl.LinkedNodeKind.constructorDeclaration ||
- kind == idl.LinkedNodeKind.enumConstantDeclaration ||
- kind == idl.LinkedNodeKind.enumDeclaration ||
- kind == idl.LinkedNodeKind.extensionDeclaration ||
- kind == idl.LinkedNodeKind.fieldFormalParameter ||
- kind == idl.LinkedNodeKind.functionDeclaration ||
- kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
- kind == idl.LinkedNodeKind.functionTypeAlias ||
- kind == idl.LinkedNodeKind.genericTypeAlias ||
- kind == idl.LinkedNodeKind.methodDeclaration ||
- kind == idl.LinkedNodeKind.mixinDeclaration ||
- kind == idl.LinkedNodeKind.simpleFormalParameter ||
- kind == idl.LinkedNodeKind.typeParameter ||
- kind == idl.LinkedNodeKind.variableDeclaration);
- return _variantField_1 ??= 0;
- }
-
- set directiveKeywordOffset(int value) {
- assert(kind == idl.LinkedNodeKind.exportDirective ||
- kind == idl.LinkedNodeKind.importDirective ||
- kind == idl.LinkedNodeKind.libraryDirective ||
- kind == idl.LinkedNodeKind.partDirective ||
- kind == idl.LinkedNodeKind.partOfDirective);
- assert(value == null || value >= 0);
- _variantField_1 = value;
- }
-
- set nameOffset(int value) {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.classTypeAlias ||
- kind == idl.LinkedNodeKind.constructorDeclaration ||
- kind == idl.LinkedNodeKind.enumConstantDeclaration ||
- kind == idl.LinkedNodeKind.enumDeclaration ||
- kind == idl.LinkedNodeKind.extensionDeclaration ||
- kind == idl.LinkedNodeKind.fieldFormalParameter ||
- kind == idl.LinkedNodeKind.functionDeclaration ||
- kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
- kind == idl.LinkedNodeKind.functionTypeAlias ||
- kind == idl.LinkedNodeKind.genericTypeAlias ||
- kind == idl.LinkedNodeKind.methodDeclaration ||
- kind == idl.LinkedNodeKind.mixinDeclaration ||
- kind == idl.LinkedNodeKind.simpleFormalParameter ||
- kind == idl.LinkedNodeKind.typeParameter ||
- kind == idl.LinkedNodeKind.variableDeclaration);
- assert(value == null || value >= 0);
- _variantField_1 = value;
- }
-
- @override
- List<String> get documentationComment_tokens {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.classTypeAlias ||
- kind == idl.LinkedNodeKind.constructorDeclaration ||
- kind == idl.LinkedNodeKind.enumDeclaration ||
- kind == idl.LinkedNodeKind.enumConstantDeclaration ||
- kind == idl.LinkedNodeKind.extensionDeclaration ||
- kind == idl.LinkedNodeKind.fieldDeclaration ||
- kind == idl.LinkedNodeKind.functionDeclaration ||
- kind == idl.LinkedNodeKind.functionTypeAlias ||
- kind == idl.LinkedNodeKind.genericTypeAlias ||
- kind == idl.LinkedNodeKind.libraryDirective ||
- kind == idl.LinkedNodeKind.methodDeclaration ||
- kind == idl.LinkedNodeKind.mixinDeclaration ||
- kind == idl.LinkedNodeKind.topLevelVariableDeclaration);
- return _variantField_4 ??= <String>[];
- }
-
- set documentationComment_tokens(List<String> value) {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.classTypeAlias ||
- kind == idl.LinkedNodeKind.constructorDeclaration ||
- kind == idl.LinkedNodeKind.enumDeclaration ||
- kind == idl.LinkedNodeKind.enumConstantDeclaration ||
- kind == idl.LinkedNodeKind.extensionDeclaration ||
- kind == idl.LinkedNodeKind.fieldDeclaration ||
- kind == idl.LinkedNodeKind.functionDeclaration ||
- kind == idl.LinkedNodeKind.functionTypeAlias ||
- kind == idl.LinkedNodeKind.genericTypeAlias ||
- kind == idl.LinkedNodeKind.libraryDirective ||
- kind == idl.LinkedNodeKind.methodDeclaration ||
- kind == idl.LinkedNodeKind.mixinDeclaration ||
- kind == idl.LinkedNodeKind.topLevelVariableDeclaration);
- _variantField_4 = value;
- }
-
- @override
- idl.LinkedNodeKind get kind => _kind ??= idl.LinkedNodeKind.adjacentStrings;
-
- /// The kind of the node.
- set kind(idl.LinkedNodeKind value) {
- this._kind = value;
- }
-
- UnlinkedInformativeDataBuilder.classDeclaration({
- int codeLength,
- int codeOffset,
- int nameOffset,
- List<String> documentationComment_tokens,
- }) : _kind = idl.LinkedNodeKind.classDeclaration,
- _variantField_2 = codeLength,
- _variantField_3 = codeOffset,
- _variantField_1 = nameOffset,
- _variantField_4 = documentationComment_tokens;
-
- UnlinkedInformativeDataBuilder.classTypeAlias({
- int codeLength,
- int codeOffset,
- int nameOffset,
- List<String> documentationComment_tokens,
- }) : _kind = idl.LinkedNodeKind.classTypeAlias,
- _variantField_2 = codeLength,
- _variantField_3 = codeOffset,
- _variantField_1 = nameOffset,
- _variantField_4 = documentationComment_tokens;
-
- UnlinkedInformativeDataBuilder.compilationUnit({
- int codeLength,
- int codeOffset,
- List<int> compilationUnit_lineStarts,
- }) : _kind = idl.LinkedNodeKind.compilationUnit,
- _variantField_2 = codeLength,
- _variantField_3 = codeOffset,
- _variantField_7 = compilationUnit_lineStarts;
-
- UnlinkedInformativeDataBuilder.constructorDeclaration({
- int codeLength,
- int codeOffset,
- int constructorDeclaration_periodOffset,
- int constructorDeclaration_returnTypeOffset,
- int nameOffset,
- List<String> documentationComment_tokens,
- }) : _kind = idl.LinkedNodeKind.constructorDeclaration,
- _variantField_2 = codeLength,
- _variantField_3 = codeOffset,
- _variantField_6 = constructorDeclaration_periodOffset,
- _variantField_5 = constructorDeclaration_returnTypeOffset,
- _variantField_1 = nameOffset,
- _variantField_4 = documentationComment_tokens;
-
- UnlinkedInformativeDataBuilder.defaultFormalParameter({
- int codeLength,
- int codeOffset,
- String defaultFormalParameter_defaultValueCode,
- }) : _kind = idl.LinkedNodeKind.defaultFormalParameter,
- _variantField_2 = codeLength,
- _variantField_3 = codeOffset,
- _variantField_10 = defaultFormalParameter_defaultValueCode;
-
- UnlinkedInformativeDataBuilder.enumConstantDeclaration({
- int codeLength,
- int codeOffset,
- int nameOffset,
- List<String> documentationComment_tokens,
- }) : _kind = idl.LinkedNodeKind.enumConstantDeclaration,
- _variantField_2 = codeLength,
- _variantField_3 = codeOffset,
- _variantField_1 = nameOffset,
- _variantField_4 = documentationComment_tokens;
-
- UnlinkedInformativeDataBuilder.enumDeclaration({
- int codeLength,
- int codeOffset,
- int nameOffset,
- List<String> documentationComment_tokens,
- }) : _kind = idl.LinkedNodeKind.enumDeclaration,
- _variantField_2 = codeLength,
- _variantField_3 = codeOffset,
- _variantField_1 = nameOffset,
- _variantField_4 = documentationComment_tokens;
-
- UnlinkedInformativeDataBuilder.exportDirective({
- int directiveKeywordOffset,
- }) : _kind = idl.LinkedNodeKind.exportDirective,
- _variantField_1 = directiveKeywordOffset;
-
- UnlinkedInformativeDataBuilder.extensionDeclaration({
- int codeLength,
- int codeOffset,
- int nameOffset,
- List<String> documentationComment_tokens,
- }) : _kind = idl.LinkedNodeKind.extensionDeclaration,
- _variantField_2 = codeLength,
- _variantField_3 = codeOffset,
- _variantField_1 = nameOffset,
- _variantField_4 = documentationComment_tokens;
-
- UnlinkedInformativeDataBuilder.fieldDeclaration({
- List<String> documentationComment_tokens,
- }) : _kind = idl.LinkedNodeKind.fieldDeclaration,
- _variantField_4 = documentationComment_tokens;
-
- UnlinkedInformativeDataBuilder.fieldFormalParameter({
- int codeLength,
- int codeOffset,
- int nameOffset,
- }) : _kind = idl.LinkedNodeKind.fieldFormalParameter,
- _variantField_2 = codeLength,
- _variantField_3 = codeOffset,
- _variantField_1 = nameOffset;
-
- UnlinkedInformativeDataBuilder.functionDeclaration({
- int codeLength,
- int codeOffset,
- int nameOffset,
- List<String> documentationComment_tokens,
- }) : _kind = idl.LinkedNodeKind.functionDeclaration,
- _variantField_2 = codeLength,
- _variantField_3 = codeOffset,
- _variantField_1 = nameOffset,
- _variantField_4 = documentationComment_tokens;
-
- UnlinkedInformativeDataBuilder.functionTypeAlias({
- int codeLength,
- int codeOffset,
- int nameOffset,
- List<String> documentationComment_tokens,
- }) : _kind = idl.LinkedNodeKind.functionTypeAlias,
- _variantField_2 = codeLength,
- _variantField_3 = codeOffset,
- _variantField_1 = nameOffset,
- _variantField_4 = documentationComment_tokens;
-
- UnlinkedInformativeDataBuilder.functionTypedFormalParameter({
- int codeLength,
- int codeOffset,
- int nameOffset,
- }) : _kind = idl.LinkedNodeKind.functionTypedFormalParameter,
- _variantField_2 = codeLength,
- _variantField_3 = codeOffset,
- _variantField_1 = nameOffset;
-
- UnlinkedInformativeDataBuilder.genericTypeAlias({
- int codeLength,
- int codeOffset,
- int nameOffset,
- List<String> documentationComment_tokens,
- }) : _kind = idl.LinkedNodeKind.genericTypeAlias,
- _variantField_2 = codeLength,
- _variantField_3 = codeOffset,
- _variantField_1 = nameOffset,
- _variantField_4 = documentationComment_tokens;
-
- UnlinkedInformativeDataBuilder.hideCombinator({
- int combinatorEnd,
- int combinatorKeywordOffset,
- }) : _kind = idl.LinkedNodeKind.hideCombinator,
- _variantField_9 = combinatorEnd,
- _variantField_8 = combinatorKeywordOffset;
-
- UnlinkedInformativeDataBuilder.importDirective({
- int importDirective_prefixOffset,
- int directiveKeywordOffset,
- }) : _kind = idl.LinkedNodeKind.importDirective,
- _variantField_8 = importDirective_prefixOffset,
- _variantField_1 = directiveKeywordOffset;
-
- UnlinkedInformativeDataBuilder.libraryDirective({
- int directiveKeywordOffset,
- List<String> documentationComment_tokens,
- }) : _kind = idl.LinkedNodeKind.libraryDirective,
- _variantField_1 = directiveKeywordOffset,
- _variantField_4 = documentationComment_tokens;
-
- UnlinkedInformativeDataBuilder.methodDeclaration({
- int codeLength,
- int codeOffset,
- int nameOffset,
- List<String> documentationComment_tokens,
- }) : _kind = idl.LinkedNodeKind.methodDeclaration,
- _variantField_2 = codeLength,
- _variantField_3 = codeOffset,
- _variantField_1 = nameOffset,
- _variantField_4 = documentationComment_tokens;
-
- UnlinkedInformativeDataBuilder.mixinDeclaration({
- int codeLength,
- int codeOffset,
- int nameOffset,
- List<String> documentationComment_tokens,
- }) : _kind = idl.LinkedNodeKind.mixinDeclaration,
- _variantField_2 = codeLength,
- _variantField_3 = codeOffset,
- _variantField_1 = nameOffset,
- _variantField_4 = documentationComment_tokens;
-
- UnlinkedInformativeDataBuilder.partDirective({
- int directiveKeywordOffset,
- }) : _kind = idl.LinkedNodeKind.partDirective,
- _variantField_1 = directiveKeywordOffset;
-
- UnlinkedInformativeDataBuilder.partOfDirective({
- int directiveKeywordOffset,
- }) : _kind = idl.LinkedNodeKind.partOfDirective,
- _variantField_1 = directiveKeywordOffset;
-
- UnlinkedInformativeDataBuilder.showCombinator({
- int combinatorEnd,
- int combinatorKeywordOffset,
- }) : _kind = idl.LinkedNodeKind.showCombinator,
- _variantField_9 = combinatorEnd,
- _variantField_8 = combinatorKeywordOffset;
-
- UnlinkedInformativeDataBuilder.simpleFormalParameter({
- int codeLength,
- int codeOffset,
- int nameOffset,
- }) : _kind = idl.LinkedNodeKind.simpleFormalParameter,
- _variantField_2 = codeLength,
- _variantField_3 = codeOffset,
- _variantField_1 = nameOffset;
-
- UnlinkedInformativeDataBuilder.topLevelVariableDeclaration({
- List<String> documentationComment_tokens,
- }) : _kind = idl.LinkedNodeKind.topLevelVariableDeclaration,
- _variantField_4 = documentationComment_tokens;
-
- UnlinkedInformativeDataBuilder.typeParameter({
- int codeLength,
- int codeOffset,
- int nameOffset,
- }) : _kind = idl.LinkedNodeKind.typeParameter,
- _variantField_2 = codeLength,
- _variantField_3 = codeOffset,
- _variantField_1 = nameOffset;
-
- UnlinkedInformativeDataBuilder.variableDeclaration({
- int codeLength,
- int codeOffset,
- int nameOffset,
- }) : _kind = idl.LinkedNodeKind.variableDeclaration,
- _variantField_2 = codeLength,
- _variantField_3 = codeOffset,
- _variantField_1 = nameOffset;
-
- /// Flush [informative] data recursively.
- void flushInformative() {
- if (kind == idl.LinkedNodeKind.classDeclaration) {
- } else if (kind == idl.LinkedNodeKind.classTypeAlias) {
- } else if (kind == idl.LinkedNodeKind.compilationUnit) {
- } else if (kind == idl.LinkedNodeKind.constructorDeclaration) {
- } else if (kind == idl.LinkedNodeKind.defaultFormalParameter) {
- } else if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
- } else if (kind == idl.LinkedNodeKind.enumDeclaration) {
- } else if (kind == idl.LinkedNodeKind.exportDirective) {
- } else if (kind == idl.LinkedNodeKind.extensionDeclaration) {
- } else if (kind == idl.LinkedNodeKind.fieldDeclaration) {
- } else if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
- } else if (kind == idl.LinkedNodeKind.functionDeclaration) {
- } else if (kind == idl.LinkedNodeKind.functionTypeAlias) {
- } else if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) {
- } else if (kind == idl.LinkedNodeKind.genericTypeAlias) {
- } else if (kind == idl.LinkedNodeKind.hideCombinator) {
- } else if (kind == idl.LinkedNodeKind.importDirective) {
- } else if (kind == idl.LinkedNodeKind.libraryDirective) {
- } else if (kind == idl.LinkedNodeKind.methodDeclaration) {
- } else if (kind == idl.LinkedNodeKind.mixinDeclaration) {
- } else if (kind == idl.LinkedNodeKind.partDirective) {
- } else if (kind == idl.LinkedNodeKind.partOfDirective) {
- } else if (kind == idl.LinkedNodeKind.showCombinator) {
- } else if (kind == idl.LinkedNodeKind.simpleFormalParameter) {
- } else if (kind == idl.LinkedNodeKind.topLevelVariableDeclaration) {
- } else if (kind == idl.LinkedNodeKind.typeParameter) {
- } else if (kind == idl.LinkedNodeKind.variableDeclaration) {}
- }
-
- /// Accumulate non-[informative] data into [signature].
- void collectApiSignature(api_sig.ApiSignature signature) {
- if (kind == idl.LinkedNodeKind.classDeclaration) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.nameOffset ?? 0);
- signature.addInt(this.codeLength ?? 0);
- signature.addInt(this.codeOffset ?? 0);
- if (this.documentationComment_tokens == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.documentationComment_tokens.length);
- for (var x in this.documentationComment_tokens) {
- signature.addString(x);
- }
- }
- } else if (kind == idl.LinkedNodeKind.classTypeAlias) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.nameOffset ?? 0);
- signature.addInt(this.codeLength ?? 0);
- signature.addInt(this.codeOffset ?? 0);
- if (this.documentationComment_tokens == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.documentationComment_tokens.length);
- for (var x in this.documentationComment_tokens) {
- signature.addString(x);
- }
- }
- } else if (kind == idl.LinkedNodeKind.compilationUnit) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.codeLength ?? 0);
- signature.addInt(this.codeOffset ?? 0);
- if (this.compilationUnit_lineStarts == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.compilationUnit_lineStarts.length);
- for (var x in this.compilationUnit_lineStarts) {
- signature.addInt(x);
- }
- }
- } else if (kind == idl.LinkedNodeKind.constructorDeclaration) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.nameOffset ?? 0);
- signature.addInt(this.codeLength ?? 0);
- signature.addInt(this.codeOffset ?? 0);
- if (this.documentationComment_tokens == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.documentationComment_tokens.length);
- for (var x in this.documentationComment_tokens) {
- signature.addString(x);
- }
- }
- signature.addInt(this.constructorDeclaration_returnTypeOffset ?? 0);
- signature.addInt(this.constructorDeclaration_periodOffset ?? 0);
- } else if (kind == idl.LinkedNodeKind.defaultFormalParameter) {
- 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);
- signature.addInt(this.codeLength ?? 0);
- signature.addInt(this.codeOffset ?? 0);
- if (this.documentationComment_tokens == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.documentationComment_tokens.length);
- for (var x in this.documentationComment_tokens) {
- signature.addString(x);
- }
- }
- } else if (kind == idl.LinkedNodeKind.enumDeclaration) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.nameOffset ?? 0);
- signature.addInt(this.codeLength ?? 0);
- signature.addInt(this.codeOffset ?? 0);
- if (this.documentationComment_tokens == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.documentationComment_tokens.length);
- for (var x in this.documentationComment_tokens) {
- signature.addString(x);
- }
- }
- } else if (kind == idl.LinkedNodeKind.exportDirective) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.directiveKeywordOffset ?? 0);
- } else if (kind == idl.LinkedNodeKind.extensionDeclaration) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.nameOffset ?? 0);
- signature.addInt(this.codeLength ?? 0);
- signature.addInt(this.codeOffset ?? 0);
- if (this.documentationComment_tokens == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.documentationComment_tokens.length);
- for (var x in this.documentationComment_tokens) {
- signature.addString(x);
- }
- }
- } else if (kind == idl.LinkedNodeKind.fieldDeclaration) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.documentationComment_tokens == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.documentationComment_tokens.length);
- for (var x in this.documentationComment_tokens) {
- signature.addString(x);
- }
- }
- } else if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.nameOffset ?? 0);
- signature.addInt(this.codeLength ?? 0);
- signature.addInt(this.codeOffset ?? 0);
- } else if (kind == idl.LinkedNodeKind.functionDeclaration) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.nameOffset ?? 0);
- signature.addInt(this.codeLength ?? 0);
- signature.addInt(this.codeOffset ?? 0);
- if (this.documentationComment_tokens == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.documentationComment_tokens.length);
- for (var x in this.documentationComment_tokens) {
- signature.addString(x);
- }
- }
- } else if (kind == idl.LinkedNodeKind.functionTypeAlias) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.nameOffset ?? 0);
- signature.addInt(this.codeLength ?? 0);
- signature.addInt(this.codeOffset ?? 0);
- if (this.documentationComment_tokens == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.documentationComment_tokens.length);
- for (var x in this.documentationComment_tokens) {
- signature.addString(x);
- }
- }
- } else if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.nameOffset ?? 0);
- signature.addInt(this.codeLength ?? 0);
- signature.addInt(this.codeOffset ?? 0);
- } else if (kind == idl.LinkedNodeKind.genericTypeAlias) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.nameOffset ?? 0);
- signature.addInt(this.codeLength ?? 0);
- signature.addInt(this.codeOffset ?? 0);
- if (this.documentationComment_tokens == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.documentationComment_tokens.length);
- for (var x in this.documentationComment_tokens) {
- signature.addString(x);
- }
- }
- } else if (kind == idl.LinkedNodeKind.hideCombinator) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.combinatorKeywordOffset ?? 0);
- signature.addInt(this.combinatorEnd ?? 0);
- } else if (kind == idl.LinkedNodeKind.importDirective) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.directiveKeywordOffset ?? 0);
- signature.addInt(this.importDirective_prefixOffset ?? 0);
- } else if (kind == idl.LinkedNodeKind.libraryDirective) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.directiveKeywordOffset ?? 0);
- if (this.documentationComment_tokens == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.documentationComment_tokens.length);
- for (var x in this.documentationComment_tokens) {
- signature.addString(x);
- }
- }
- } else if (kind == idl.LinkedNodeKind.methodDeclaration) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.nameOffset ?? 0);
- signature.addInt(this.codeLength ?? 0);
- signature.addInt(this.codeOffset ?? 0);
- if (this.documentationComment_tokens == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.documentationComment_tokens.length);
- for (var x in this.documentationComment_tokens) {
- signature.addString(x);
- }
- }
- } else if (kind == idl.LinkedNodeKind.mixinDeclaration) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.nameOffset ?? 0);
- signature.addInt(this.codeLength ?? 0);
- signature.addInt(this.codeOffset ?? 0);
- if (this.documentationComment_tokens == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.documentationComment_tokens.length);
- for (var x in this.documentationComment_tokens) {
- signature.addString(x);
- }
- }
- } else if (kind == idl.LinkedNodeKind.partDirective) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.directiveKeywordOffset ?? 0);
- } else if (kind == idl.LinkedNodeKind.partOfDirective) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.directiveKeywordOffset ?? 0);
- } else if (kind == idl.LinkedNodeKind.showCombinator) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.combinatorKeywordOffset ?? 0);
- signature.addInt(this.combinatorEnd ?? 0);
- } else if (kind == idl.LinkedNodeKind.simpleFormalParameter) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.nameOffset ?? 0);
- signature.addInt(this.codeLength ?? 0);
- signature.addInt(this.codeOffset ?? 0);
- } else if (kind == idl.LinkedNodeKind.topLevelVariableDeclaration) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- if (this.documentationComment_tokens == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this.documentationComment_tokens.length);
- for (var x in this.documentationComment_tokens) {
- signature.addString(x);
- }
- }
- } else if (kind == idl.LinkedNodeKind.typeParameter) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.nameOffset ?? 0);
- signature.addInt(this.codeLength ?? 0);
- signature.addInt(this.codeOffset ?? 0);
- } else if (kind == idl.LinkedNodeKind.variableDeclaration) {
- signature.addInt(this.kind == null ? 0 : this.kind.index);
- signature.addInt(this.nameOffset ?? 0);
- signature.addInt(this.codeLength ?? 0);
- signature.addInt(this.codeOffset ?? 0);
- }
- }
-
- 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());
- }
- fbBuilder.startTable();
- if (_variantField_2 != null && _variantField_2 != 0) {
- fbBuilder.addUint32(2, _variantField_2);
- }
- if (_variantField_3 != null && _variantField_3 != 0) {
- fbBuilder.addUint32(3, _variantField_3);
- }
- if (_variantField_9 != null && _variantField_9 != 0) {
- fbBuilder.addUint32(9, _variantField_9);
- }
- if (_variantField_8 != null && _variantField_8 != 0) {
- fbBuilder.addUint32(8, _variantField_8);
- }
- if (offset_variantField_7 != null) {
- fbBuilder.addOffset(7, offset_variantField_7);
- }
- if (_variantField_6 != null && _variantField_6 != 0) {
- fbBuilder.addUint32(6, _variantField_6);
- }
- 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);
- }
- if (offset_variantField_4 != null) {
- fbBuilder.addOffset(4, offset_variantField_4);
- }
- if (_kind != null && _kind != idl.LinkedNodeKind.adjacentStrings) {
- fbBuilder.addUint8(0, _kind.index);
- }
- return fbBuilder.endTable();
- }
-}
-
-class _UnlinkedInformativeDataReader
- extends fb.TableReader<_UnlinkedInformativeDataImpl> {
- const _UnlinkedInformativeDataReader();
-
- @override
- _UnlinkedInformativeDataImpl createObject(fb.BufferContext bc, int offset) =>
- _UnlinkedInformativeDataImpl(bc, offset);
-}
-
-class _UnlinkedInformativeDataImpl extends Object
- with _UnlinkedInformativeDataMixin
- implements idl.UnlinkedInformativeData {
- final fb.BufferContext _bc;
- final int _bcOffset;
-
- _UnlinkedInformativeDataImpl(this._bc, this._bcOffset);
-
- int _variantField_2;
- int _variantField_3;
- int _variantField_9;
- int _variantField_8;
- List<int> _variantField_7;
- int _variantField_6;
- int _variantField_5;
- String _variantField_10;
- int _variantField_1;
- List<String> _variantField_4;
- idl.LinkedNodeKind _kind;
-
- @override
- int get codeLength {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.classTypeAlias ||
- kind == idl.LinkedNodeKind.compilationUnit ||
- kind == idl.LinkedNodeKind.constructorDeclaration ||
- kind == idl.LinkedNodeKind.defaultFormalParameter ||
- kind == idl.LinkedNodeKind.enumConstantDeclaration ||
- kind == idl.LinkedNodeKind.enumDeclaration ||
- kind == idl.LinkedNodeKind.extensionDeclaration ||
- kind == idl.LinkedNodeKind.fieldFormalParameter ||
- kind == idl.LinkedNodeKind.functionDeclaration ||
- kind == idl.LinkedNodeKind.functionTypeAlias ||
- kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
- kind == idl.LinkedNodeKind.genericTypeAlias ||
- kind == idl.LinkedNodeKind.methodDeclaration ||
- kind == idl.LinkedNodeKind.mixinDeclaration ||
- kind == idl.LinkedNodeKind.simpleFormalParameter ||
- kind == idl.LinkedNodeKind.typeParameter ||
- kind == idl.LinkedNodeKind.variableDeclaration);
- _variantField_2 ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 2, 0);
- return _variantField_2;
- }
-
- @override
- int get codeOffset {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.classTypeAlias ||
- kind == idl.LinkedNodeKind.compilationUnit ||
- kind == idl.LinkedNodeKind.constructorDeclaration ||
- kind == idl.LinkedNodeKind.defaultFormalParameter ||
- kind == idl.LinkedNodeKind.enumConstantDeclaration ||
- kind == idl.LinkedNodeKind.enumDeclaration ||
- kind == idl.LinkedNodeKind.extensionDeclaration ||
- kind == idl.LinkedNodeKind.fieldFormalParameter ||
- kind == idl.LinkedNodeKind.functionDeclaration ||
- kind == idl.LinkedNodeKind.functionTypeAlias ||
- kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
- kind == idl.LinkedNodeKind.genericTypeAlias ||
- kind == idl.LinkedNodeKind.methodDeclaration ||
- kind == idl.LinkedNodeKind.mixinDeclaration ||
- kind == idl.LinkedNodeKind.simpleFormalParameter ||
- kind == idl.LinkedNodeKind.typeParameter ||
- kind == idl.LinkedNodeKind.variableDeclaration);
- _variantField_3 ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 3, 0);
- return _variantField_3;
- }
-
- @override
- int get combinatorEnd {
- assert(kind == idl.LinkedNodeKind.hideCombinator ||
- kind == idl.LinkedNodeKind.showCombinator);
- _variantField_9 ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 9, 0);
- return _variantField_9;
- }
-
- @override
- int get combinatorKeywordOffset {
- assert(kind == idl.LinkedNodeKind.hideCombinator ||
- kind == idl.LinkedNodeKind.showCombinator);
- _variantField_8 ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 8, 0);
- return _variantField_8;
- }
-
- @override
- int get importDirective_prefixOffset {
- assert(kind == idl.LinkedNodeKind.importDirective);
- _variantField_8 ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 8, 0);
- return _variantField_8;
- }
-
- @override
- List<int> get compilationUnit_lineStarts {
- assert(kind == idl.LinkedNodeKind.compilationUnit);
- _variantField_7 ??=
- const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 7, const <int>[]);
- return _variantField_7;
- }
-
- @override
- int get constructorDeclaration_periodOffset {
- assert(kind == idl.LinkedNodeKind.constructorDeclaration);
- _variantField_6 ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 6, 0);
- return _variantField_6;
- }
-
- @override
- int get constructorDeclaration_returnTypeOffset {
- assert(kind == idl.LinkedNodeKind.constructorDeclaration);
- _variantField_5 ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 5, 0);
- return _variantField_5;
- }
-
- @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 ||
- kind == idl.LinkedNodeKind.libraryDirective ||
- kind == idl.LinkedNodeKind.partDirective ||
- kind == idl.LinkedNodeKind.partOfDirective);
- _variantField_1 ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 1, 0);
- return _variantField_1;
- }
-
- @override
- int get nameOffset {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.classTypeAlias ||
- kind == idl.LinkedNodeKind.constructorDeclaration ||
- kind == idl.LinkedNodeKind.enumConstantDeclaration ||
- kind == idl.LinkedNodeKind.enumDeclaration ||
- kind == idl.LinkedNodeKind.extensionDeclaration ||
- kind == idl.LinkedNodeKind.fieldFormalParameter ||
- kind == idl.LinkedNodeKind.functionDeclaration ||
- kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
- kind == idl.LinkedNodeKind.functionTypeAlias ||
- kind == idl.LinkedNodeKind.genericTypeAlias ||
- kind == idl.LinkedNodeKind.methodDeclaration ||
- kind == idl.LinkedNodeKind.mixinDeclaration ||
- kind == idl.LinkedNodeKind.simpleFormalParameter ||
- kind == idl.LinkedNodeKind.typeParameter ||
- kind == idl.LinkedNodeKind.variableDeclaration);
- _variantField_1 ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 1, 0);
- return _variantField_1;
- }
-
- @override
- List<String> get documentationComment_tokens {
- assert(kind == idl.LinkedNodeKind.classDeclaration ||
- kind == idl.LinkedNodeKind.classTypeAlias ||
- kind == idl.LinkedNodeKind.constructorDeclaration ||
- kind == idl.LinkedNodeKind.enumDeclaration ||
- kind == idl.LinkedNodeKind.enumConstantDeclaration ||
- kind == idl.LinkedNodeKind.extensionDeclaration ||
- kind == idl.LinkedNodeKind.fieldDeclaration ||
- kind == idl.LinkedNodeKind.functionDeclaration ||
- kind == idl.LinkedNodeKind.functionTypeAlias ||
- kind == idl.LinkedNodeKind.genericTypeAlias ||
- kind == idl.LinkedNodeKind.libraryDirective ||
- kind == idl.LinkedNodeKind.methodDeclaration ||
- kind == idl.LinkedNodeKind.mixinDeclaration ||
- kind == idl.LinkedNodeKind.topLevelVariableDeclaration);
- _variantField_4 ??= const fb.ListReader<String>(fb.StringReader())
- .vTableGet(_bc, _bcOffset, 4, const <String>[]);
- return _variantField_4;
- }
-
- @override
- idl.LinkedNodeKind get kind {
- _kind ??= const _LinkedNodeKindReader()
- .vTableGet(_bc, _bcOffset, 0, idl.LinkedNodeKind.adjacentStrings);
- return _kind;
- }
-}
-
-abstract class _UnlinkedInformativeDataMixin
- implements idl.UnlinkedInformativeData {
- @override
- Map<String, Object> toJson() {
- Map<String, Object> _result = <String, Object>{};
- if (kind != idl.LinkedNodeKind.adjacentStrings) {
- _result["kind"] = kind.toString().split('.')[1];
- }
- if (kind == idl.LinkedNodeKind.classDeclaration) {
- if (codeLength != 0) {
- _result["codeLength"] = codeLength;
- }
- if (codeOffset != 0) {
- _result["codeOffset"] = codeOffset;
- }
- if (nameOffset != 0) {
- _result["nameOffset"] = nameOffset;
- }
- if (documentationComment_tokens.isNotEmpty) {
- _result["documentationComment_tokens"] = documentationComment_tokens;
- }
- }
- if (kind == idl.LinkedNodeKind.classTypeAlias) {
- if (codeLength != 0) {
- _result["codeLength"] = codeLength;
- }
- if (codeOffset != 0) {
- _result["codeOffset"] = codeOffset;
- }
- if (nameOffset != 0) {
- _result["nameOffset"] = nameOffset;
- }
- if (documentationComment_tokens.isNotEmpty) {
- _result["documentationComment_tokens"] = documentationComment_tokens;
- }
- }
- if (kind == idl.LinkedNodeKind.compilationUnit) {
- if (codeLength != 0) {
- _result["codeLength"] = codeLength;
- }
- if (codeOffset != 0) {
- _result["codeOffset"] = codeOffset;
- }
- if (compilationUnit_lineStarts.isNotEmpty) {
- _result["compilationUnit_lineStarts"] = compilationUnit_lineStarts;
- }
- }
- if (kind == idl.LinkedNodeKind.constructorDeclaration) {
- if (codeLength != 0) {
- _result["codeLength"] = codeLength;
- }
- if (codeOffset != 0) {
- _result["codeOffset"] = codeOffset;
- }
- if (constructorDeclaration_periodOffset != 0) {
- _result["constructorDeclaration_periodOffset"] =
- constructorDeclaration_periodOffset;
- }
- if (constructorDeclaration_returnTypeOffset != 0) {
- _result["constructorDeclaration_returnTypeOffset"] =
- constructorDeclaration_returnTypeOffset;
- }
- if (nameOffset != 0) {
- _result["nameOffset"] = nameOffset;
- }
- if (documentationComment_tokens.isNotEmpty) {
- _result["documentationComment_tokens"] = documentationComment_tokens;
- }
- }
- 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 (codeLength != 0) {
- _result["codeLength"] = codeLength;
- }
- if (codeOffset != 0) {
- _result["codeOffset"] = codeOffset;
- }
- if (nameOffset != 0) {
- _result["nameOffset"] = nameOffset;
- }
- if (documentationComment_tokens.isNotEmpty) {
- _result["documentationComment_tokens"] = documentationComment_tokens;
- }
- }
- if (kind == idl.LinkedNodeKind.enumDeclaration) {
- if (codeLength != 0) {
- _result["codeLength"] = codeLength;
- }
- if (codeOffset != 0) {
- _result["codeOffset"] = codeOffset;
- }
- if (nameOffset != 0) {
- _result["nameOffset"] = nameOffset;
- }
- if (documentationComment_tokens.isNotEmpty) {
- _result["documentationComment_tokens"] = documentationComment_tokens;
- }
- }
- if (kind == idl.LinkedNodeKind.exportDirective) {
- if (directiveKeywordOffset != 0) {
- _result["directiveKeywordOffset"] = directiveKeywordOffset;
- }
- }
- if (kind == idl.LinkedNodeKind.extensionDeclaration) {
- if (codeLength != 0) {
- _result["codeLength"] = codeLength;
- }
- if (codeOffset != 0) {
- _result["codeOffset"] = codeOffset;
- }
- if (nameOffset != 0) {
- _result["nameOffset"] = nameOffset;
- }
- if (documentationComment_tokens.isNotEmpty) {
- _result["documentationComment_tokens"] = documentationComment_tokens;
- }
- }
- if (kind == idl.LinkedNodeKind.fieldDeclaration) {
- if (documentationComment_tokens.isNotEmpty) {
- _result["documentationComment_tokens"] = documentationComment_tokens;
- }
- }
- if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
- if (codeLength != 0) {
- _result["codeLength"] = codeLength;
- }
- if (codeOffset != 0) {
- _result["codeOffset"] = codeOffset;
- }
- if (nameOffset != 0) {
- _result["nameOffset"] = nameOffset;
- }
- }
- if (kind == idl.LinkedNodeKind.functionDeclaration) {
- if (codeLength != 0) {
- _result["codeLength"] = codeLength;
- }
- if (codeOffset != 0) {
- _result["codeOffset"] = codeOffset;
- }
- if (nameOffset != 0) {
- _result["nameOffset"] = nameOffset;
- }
- if (documentationComment_tokens.isNotEmpty) {
- _result["documentationComment_tokens"] = documentationComment_tokens;
- }
- }
- if (kind == idl.LinkedNodeKind.functionTypeAlias) {
- if (codeLength != 0) {
- _result["codeLength"] = codeLength;
- }
- if (codeOffset != 0) {
- _result["codeOffset"] = codeOffset;
- }
- if (nameOffset != 0) {
- _result["nameOffset"] = nameOffset;
- }
- if (documentationComment_tokens.isNotEmpty) {
- _result["documentationComment_tokens"] = documentationComment_tokens;
- }
- }
- if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) {
- if (codeLength != 0) {
- _result["codeLength"] = codeLength;
- }
- if (codeOffset != 0) {
- _result["codeOffset"] = codeOffset;
- }
- if (nameOffset != 0) {
- _result["nameOffset"] = nameOffset;
- }
- }
- if (kind == idl.LinkedNodeKind.genericTypeAlias) {
- if (codeLength != 0) {
- _result["codeLength"] = codeLength;
- }
- if (codeOffset != 0) {
- _result["codeOffset"] = codeOffset;
- }
- if (nameOffset != 0) {
- _result["nameOffset"] = nameOffset;
- }
- if (documentationComment_tokens.isNotEmpty) {
- _result["documentationComment_tokens"] = documentationComment_tokens;
- }
- }
- if (kind == idl.LinkedNodeKind.hideCombinator) {
- if (combinatorEnd != 0) {
- _result["combinatorEnd"] = combinatorEnd;
- }
- if (combinatorKeywordOffset != 0) {
- _result["combinatorKeywordOffset"] = combinatorKeywordOffset;
- }
- }
- if (kind == idl.LinkedNodeKind.importDirective) {
- if (importDirective_prefixOffset != 0) {
- _result["importDirective_prefixOffset"] = importDirective_prefixOffset;
- }
- if (directiveKeywordOffset != 0) {
- _result["directiveKeywordOffset"] = directiveKeywordOffset;
- }
- }
- if (kind == idl.LinkedNodeKind.libraryDirective) {
- if (directiveKeywordOffset != 0) {
- _result["directiveKeywordOffset"] = directiveKeywordOffset;
- }
- if (documentationComment_tokens.isNotEmpty) {
- _result["documentationComment_tokens"] = documentationComment_tokens;
- }
- }
- if (kind == idl.LinkedNodeKind.methodDeclaration) {
- if (codeLength != 0) {
- _result["codeLength"] = codeLength;
- }
- if (codeOffset != 0) {
- _result["codeOffset"] = codeOffset;
- }
- if (nameOffset != 0) {
- _result["nameOffset"] = nameOffset;
- }
- if (documentationComment_tokens.isNotEmpty) {
- _result["documentationComment_tokens"] = documentationComment_tokens;
- }
- }
- if (kind == idl.LinkedNodeKind.mixinDeclaration) {
- if (codeLength != 0) {
- _result["codeLength"] = codeLength;
- }
- if (codeOffset != 0) {
- _result["codeOffset"] = codeOffset;
- }
- if (nameOffset != 0) {
- _result["nameOffset"] = nameOffset;
- }
- if (documentationComment_tokens.isNotEmpty) {
- _result["documentationComment_tokens"] = documentationComment_tokens;
- }
- }
- if (kind == idl.LinkedNodeKind.partDirective) {
- if (directiveKeywordOffset != 0) {
- _result["directiveKeywordOffset"] = directiveKeywordOffset;
- }
- }
- if (kind == idl.LinkedNodeKind.partOfDirective) {
- if (directiveKeywordOffset != 0) {
- _result["directiveKeywordOffset"] = directiveKeywordOffset;
- }
- }
- if (kind == idl.LinkedNodeKind.showCombinator) {
- if (combinatorEnd != 0) {
- _result["combinatorEnd"] = combinatorEnd;
- }
- if (combinatorKeywordOffset != 0) {
- _result["combinatorKeywordOffset"] = combinatorKeywordOffset;
- }
- }
- if (kind == idl.LinkedNodeKind.simpleFormalParameter) {
- if (codeLength != 0) {
- _result["codeLength"] = codeLength;
- }
- if (codeOffset != 0) {
- _result["codeOffset"] = codeOffset;
- }
- if (nameOffset != 0) {
- _result["nameOffset"] = nameOffset;
- }
- }
- if (kind == idl.LinkedNodeKind.topLevelVariableDeclaration) {
- if (documentationComment_tokens.isNotEmpty) {
- _result["documentationComment_tokens"] = documentationComment_tokens;
- }
- }
- if (kind == idl.LinkedNodeKind.typeParameter) {
- if (codeLength != 0) {
- _result["codeLength"] = codeLength;
- }
- if (codeOffset != 0) {
- _result["codeOffset"] = codeOffset;
- }
- if (nameOffset != 0) {
- _result["nameOffset"] = nameOffset;
- }
- }
- if (kind == idl.LinkedNodeKind.variableDeclaration) {
- if (codeLength != 0) {
- _result["codeLength"] = codeLength;
- }
- if (codeOffset != 0) {
- _result["codeOffset"] = codeOffset;
- }
- if (nameOffset != 0) {
- _result["nameOffset"] = nameOffset;
- }
- }
- return _result;
- }
-
- @override
- Map<String, Object> toMap() {
- if (kind == idl.LinkedNodeKind.classDeclaration) {
- return {
- "codeLength": codeLength,
- "codeOffset": codeOffset,
- "nameOffset": nameOffset,
- "documentationComment_tokens": documentationComment_tokens,
- "kind": kind,
- };
- }
- if (kind == idl.LinkedNodeKind.classTypeAlias) {
- return {
- "codeLength": codeLength,
- "codeOffset": codeOffset,
- "nameOffset": nameOffset,
- "documentationComment_tokens": documentationComment_tokens,
- "kind": kind,
- };
- }
- if (kind == idl.LinkedNodeKind.compilationUnit) {
- return {
- "codeLength": codeLength,
- "codeOffset": codeOffset,
- "compilationUnit_lineStarts": compilationUnit_lineStarts,
- "kind": kind,
- };
- }
- if (kind == idl.LinkedNodeKind.constructorDeclaration) {
- return {
- "codeLength": codeLength,
- "codeOffset": codeOffset,
- "constructorDeclaration_periodOffset":
- constructorDeclaration_periodOffset,
- "constructorDeclaration_returnTypeOffset":
- constructorDeclaration_returnTypeOffset,
- "nameOffset": nameOffset,
- "documentationComment_tokens": documentationComment_tokens,
- "kind": kind,
- };
- }
- if (kind == idl.LinkedNodeKind.defaultFormalParameter) {
- return {
- "codeLength": codeLength,
- "codeOffset": codeOffset,
- "defaultFormalParameter_defaultValueCode":
- defaultFormalParameter_defaultValueCode,
- "kind": kind,
- };
- }
- if (kind == idl.LinkedNodeKind.enumConstantDeclaration) {
- return {
- "codeLength": codeLength,
- "codeOffset": codeOffset,
- "nameOffset": nameOffset,
- "documentationComment_tokens": documentationComment_tokens,
- "kind": kind,
- };
- }
- if (kind == idl.LinkedNodeKind.enumDeclaration) {
- return {
- "codeLength": codeLength,
- "codeOffset": codeOffset,
- "nameOffset": nameOffset,
- "documentationComment_tokens": documentationComment_tokens,
- "kind": kind,
- };
- }
- if (kind == idl.LinkedNodeKind.exportDirective) {
- return {
- "directiveKeywordOffset": directiveKeywordOffset,
- "kind": kind,
- };
- }
- if (kind == idl.LinkedNodeKind.extensionDeclaration) {
- return {
- "codeLength": codeLength,
- "codeOffset": codeOffset,
- "nameOffset": nameOffset,
- "documentationComment_tokens": documentationComment_tokens,
- "kind": kind,
- };
- }
- if (kind == idl.LinkedNodeKind.fieldDeclaration) {
- return {
- "documentationComment_tokens": documentationComment_tokens,
- "kind": kind,
- };
- }
- if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
- return {
- "codeLength": codeLength,
- "codeOffset": codeOffset,
- "nameOffset": nameOffset,
- "kind": kind,
- };
- }
- if (kind == idl.LinkedNodeKind.functionDeclaration) {
- return {
- "codeLength": codeLength,
- "codeOffset": codeOffset,
- "nameOffset": nameOffset,
- "documentationComment_tokens": documentationComment_tokens,
- "kind": kind,
- };
- }
- if (kind == idl.LinkedNodeKind.functionTypeAlias) {
- return {
- "codeLength": codeLength,
- "codeOffset": codeOffset,
- "nameOffset": nameOffset,
- "documentationComment_tokens": documentationComment_tokens,
- "kind": kind,
- };
- }
- if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) {
- return {
- "codeLength": codeLength,
- "codeOffset": codeOffset,
- "nameOffset": nameOffset,
- "kind": kind,
- };
- }
- if (kind == idl.LinkedNodeKind.genericTypeAlias) {
- return {
- "codeLength": codeLength,
- "codeOffset": codeOffset,
- "nameOffset": nameOffset,
- "documentationComment_tokens": documentationComment_tokens,
- "kind": kind,
- };
- }
- if (kind == idl.LinkedNodeKind.hideCombinator) {
- return {
- "combinatorEnd": combinatorEnd,
- "combinatorKeywordOffset": combinatorKeywordOffset,
- "kind": kind,
- };
- }
- if (kind == idl.LinkedNodeKind.importDirective) {
- return {
- "importDirective_prefixOffset": importDirective_prefixOffset,
- "directiveKeywordOffset": directiveKeywordOffset,
- "kind": kind,
- };
- }
- if (kind == idl.LinkedNodeKind.libraryDirective) {
- return {
- "directiveKeywordOffset": directiveKeywordOffset,
- "documentationComment_tokens": documentationComment_tokens,
- "kind": kind,
- };
- }
- if (kind == idl.LinkedNodeKind.methodDeclaration) {
- return {
- "codeLength": codeLength,
- "codeOffset": codeOffset,
- "nameOffset": nameOffset,
- "documentationComment_tokens": documentationComment_tokens,
- "kind": kind,
- };
- }
- if (kind == idl.LinkedNodeKind.mixinDeclaration) {
- return {
- "codeLength": codeLength,
- "codeOffset": codeOffset,
- "nameOffset": nameOffset,
- "documentationComment_tokens": documentationComment_tokens,
- "kind": kind,
- };
- }
- if (kind == idl.LinkedNodeKind.partDirective) {
- return {
- "directiveKeywordOffset": directiveKeywordOffset,
- "kind": kind,
- };
- }
- if (kind == idl.LinkedNodeKind.partOfDirective) {
- return {
- "directiveKeywordOffset": directiveKeywordOffset,
- "kind": kind,
- };
- }
- if (kind == idl.LinkedNodeKind.showCombinator) {
- return {
- "combinatorEnd": combinatorEnd,
- "combinatorKeywordOffset": combinatorKeywordOffset,
- "kind": kind,
- };
- }
- if (kind == idl.LinkedNodeKind.simpleFormalParameter) {
- return {
- "codeLength": codeLength,
- "codeOffset": codeOffset,
- "nameOffset": nameOffset,
- "kind": kind,
- };
- }
- if (kind == idl.LinkedNodeKind.topLevelVariableDeclaration) {
- return {
- "documentationComment_tokens": documentationComment_tokens,
- "kind": kind,
- };
- }
- if (kind == idl.LinkedNodeKind.typeParameter) {
- return {
- "codeLength": codeLength,
- "codeOffset": codeOffset,
- "nameOffset": nameOffset,
- "kind": kind,
- };
- }
- if (kind == idl.LinkedNodeKind.variableDeclaration) {
- return {
- "codeLength": codeLength,
- "codeOffset": codeOffset,
- "nameOffset": nameOffset,
- "kind": kind,
- };
- }
- throw StateError("Unexpected $kind");
- }
-
- @override
- String toString() => convert.json.encode(toJson());
-}
-
class UnlinkedNamespaceDirectiveBuilder extends Object
with _UnlinkedNamespaceDirectiveMixin
implements idl.UnlinkedNamespaceDirective {
@@ -19926,7 +4343,6 @@
bool _hasLibraryDirective;
bool _hasPartOfDirective;
List<UnlinkedNamespaceDirectiveBuilder> _imports;
- List<UnlinkedInformativeDataBuilder> _informativeData;
List<int> _lineStarts;
String _partOfUri;
List<String> _parts;
@@ -19976,14 +4392,6 @@
}
@override
- List<UnlinkedInformativeDataBuilder> get informativeData =>
- _informativeData ??= <UnlinkedInformativeDataBuilder>[];
-
- set informativeData(List<UnlinkedInformativeDataBuilder> value) {
- this._informativeData = value;
- }
-
- @override
List<int> get lineStarts => _lineStarts ??= <int>[];
/// Offsets of the first character of each line in the source code.
@@ -20014,7 +4422,6 @@
bool hasLibraryDirective,
bool hasPartOfDirective,
List<UnlinkedNamespaceDirectiveBuilder> imports,
- List<UnlinkedInformativeDataBuilder> informativeData,
List<int> lineStarts,
String partOfUri,
List<String> parts})
@@ -20023,7 +4430,6 @@
_hasLibraryDirective = hasLibraryDirective,
_hasPartOfDirective = hasPartOfDirective,
_imports = imports,
- _informativeData = informativeData,
_lineStarts = lineStarts,
_partOfUri = partOfUri,
_parts = parts;
@@ -20032,7 +4438,6 @@
void flushInformative() {
_exports?.forEach((b) => b.flushInformative());
_imports?.forEach((b) => b.flushInformative());
- _informativeData?.forEach((b) => b.flushInformative());
_lineStarts = null;
}
@@ -20072,14 +4477,6 @@
}
}
signature.addBool(this._hasLibraryDirective == true);
- if (this._informativeData == null) {
- signature.addInt(0);
- } else {
- signature.addInt(this._informativeData.length);
- for (var x in this._informativeData) {
- x?.collectApiSignature(signature);
- }
- }
signature.addString(this._partOfUri ?? '');
}
@@ -20092,7 +4489,6 @@
fb.Offset offset_apiSignature;
fb.Offset offset_exports;
fb.Offset offset_imports;
- fb.Offset offset_informativeData;
fb.Offset offset_lineStarts;
fb.Offset offset_partOfUri;
fb.Offset offset_parts;
@@ -20107,10 +4503,6 @@
offset_imports = fbBuilder
.writeList(_imports.map((b) => b.finish(fbBuilder)).toList());
}
- if (!(_informativeData == null || _informativeData.isEmpty)) {
- offset_informativeData = fbBuilder
- .writeList(_informativeData.map((b) => b.finish(fbBuilder)).toList());
- }
if (!(_lineStarts == null || _lineStarts.isEmpty)) {
offset_lineStarts = fbBuilder.writeListUint32(_lineStarts);
}
@@ -20137,14 +4529,11 @@
if (offset_imports != null) {
fbBuilder.addOffset(2, offset_imports);
}
- if (offset_informativeData != null) {
- fbBuilder.addOffset(7, offset_informativeData);
- }
if (offset_lineStarts != null) {
fbBuilder.addOffset(5, offset_lineStarts);
}
if (offset_partOfUri != null) {
- fbBuilder.addOffset(8, offset_partOfUri);
+ fbBuilder.addOffset(7, offset_partOfUri);
}
if (offset_parts != null) {
fbBuilder.addOffset(4, offset_parts);
@@ -20179,7 +4568,6 @@
bool _hasLibraryDirective;
bool _hasPartOfDirective;
List<idl.UnlinkedNamespaceDirective> _imports;
- List<idl.UnlinkedInformativeData> _informativeData;
List<int> _lineStarts;
String _partOfUri;
List<String> _parts;
@@ -20222,14 +4610,6 @@
}
@override
- List<idl.UnlinkedInformativeData> get informativeData {
- _informativeData ??= const fb.ListReader<idl.UnlinkedInformativeData>(
- _UnlinkedInformativeDataReader())
- .vTableGet(_bc, _bcOffset, 7, const <idl.UnlinkedInformativeData>[]);
- return _informativeData;
- }
-
- @override
List<int> get lineStarts {
_lineStarts ??=
const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 5, const <int>[]);
@@ -20238,7 +4618,7 @@
@override
String get partOfUri {
- _partOfUri ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 8, '');
+ _partOfUri ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 7, '');
return _partOfUri;
}
@@ -20269,10 +4649,6 @@
if (imports.isNotEmpty) {
_result["imports"] = imports.map((_value) => _value.toJson()).toList();
}
- if (informativeData.isNotEmpty) {
- _result["informativeData"] =
- informativeData.map((_value) => _value.toJson()).toList();
- }
if (lineStarts.isNotEmpty) {
_result["lineStarts"] = lineStarts;
}
@@ -20292,7 +4668,6 @@
"hasLibraryDirective": hasLibraryDirective,
"hasPartOfDirective": hasPartOfDirective,
"imports": imports,
- "informativeData": informativeData,
"lineStarts": lineStarts,
"partOfUri": partOfUri,
"parts": parts,
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index e9c6fe6..bdce0bf 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -39,30 +39,6 @@
VARIABLE
}
-/// Enum representing nullability suffixes in summaries.
-///
-/// This enum is similar to [NullabilitySuffix], but the order is different so
-/// that [EntityRefNullabilitySuffix.starOrIrrelevant] can be the default.
-enum EntityRefNullabilitySuffix : byte {
- /// An indication that the canonical representation of the type under
- /// consideration ends with `*`. Types having this nullability suffix are
- /// called "legacy types"; it has not yet been determined whether they should
- /// be unioned with the Null type.
- ///
- /// Also used in circumstances where no nullability suffix information is
- /// needed.
- starOrIrrelevant,
-
- /// An indication that the canonical representation of the type under
- /// consideration ends with `?`. Types having this nullability suffix should
- /// be interpreted as being unioned with the Null type.
- question,
-
- /// An indication that the canonical representation of the type under
- /// consideration does not end with either `?` or `*`.
- none
-}
-
/// Enum used to indicate the kind of an index relation.
enum IndexRelationKind : byte {
/// Left: class.
@@ -149,586 +125,6 @@
unit
}
-/// Types of comments.
-enum LinkedNodeCommentType : byte {
- block,
-
- documentation,
-
- endOfLine
-}
-
-/// Kinds of formal parameters.
-enum LinkedNodeFormalParameterKind : byte {
- requiredPositional,
-
- optionalPositional,
-
- optionalNamed,
-
- requiredNamed
-}
-
-/// Kinds of [LinkedNode].
-enum LinkedNodeKind : byte {
- adjacentStrings,
-
- annotation,
-
- argumentList,
-
- asExpression,
-
- assertInitializer,
-
- assertStatement,
-
- assignmentExpression,
-
- awaitExpression,
-
- binaryExpression,
-
- block,
-
- blockFunctionBody,
-
- booleanLiteral,
-
- breakStatement,
-
- cascadeExpression,
-
- catchClause,
-
- classDeclaration,
-
- classTypeAlias,
-
- comment,
-
- commentReference,
-
- compilationUnit,
-
- conditionalExpression,
-
- configuration,
-
- constructorDeclaration,
-
- constructorFieldInitializer,
-
- constructorName,
-
- continueStatement,
-
- declaredIdentifier,
-
- defaultFormalParameter,
-
- doubleLiteral,
-
- doStatement,
-
- dottedName,
-
- emptyFunctionBody,
-
- emptyStatement,
-
- enumConstantDeclaration,
-
- enumDeclaration,
-
- exportDirective,
-
- expressionFunctionBody,
-
- expressionStatement,
-
- extendsClause,
-
- extensionDeclaration,
-
- fieldDeclaration,
-
- fieldFormalParameter,
-
- formalParameterList,
-
- forEachPartsWithDeclaration,
-
- forEachPartsWithIdentifier,
-
- forElement,
-
- forPartsWithDeclarations,
-
- forPartsWithExpression,
-
- forStatement,
-
- functionDeclaration,
-
- functionDeclarationStatement,
-
- functionExpression,
-
- functionExpressionInvocation,
-
- functionTypeAlias,
-
- functionTypedFormalParameter,
-
- genericFunctionType,
-
- genericTypeAlias,
-
- hideCombinator,
-
- ifElement,
-
- ifStatement,
-
- implementsClause,
-
- importDirective,
-
- instanceCreationExpression,
-
- indexExpression,
-
- integerLiteral,
-
- interpolationExpression,
-
- interpolationString,
-
- isExpression,
-
- label,
-
- labeledStatement,
-
- libraryDirective,
-
- libraryIdentifier,
-
- listLiteral,
-
- mapLiteralEntry,
-
- methodDeclaration,
-
- methodInvocation,
-
- mixinDeclaration,
-
- namedExpression,
-
- nativeClause,
-
- nativeFunctionBody,
-
- nullLiteral,
-
- onClause,
-
- parenthesizedExpression,
-
- partDirective,
-
- partOfDirective,
-
- postfixExpression,
-
- prefixExpression,
-
- prefixedIdentifier,
-
- propertyAccess,
-
- redirectingConstructorInvocation,
-
- rethrowExpression,
-
- returnStatement,
-
- setOrMapLiteral,
-
- showCombinator,
-
- simpleFormalParameter,
-
- simpleIdentifier,
-
- simpleStringLiteral,
-
- spreadElement,
-
- stringInterpolation,
-
- superConstructorInvocation,
-
- superExpression,
-
- switchCase,
-
- switchDefault,
-
- switchStatement,
-
- symbolLiteral,
-
- thisExpression,
-
- throwExpression,
-
- topLevelVariableDeclaration,
-
- tryStatement,
-
- typeArgumentList,
-
- typeName,
-
- typeParameter,
-
- typeParameterList,
-
- variableDeclaration,
-
- variableDeclarationList,
-
- variableDeclarationStatement,
-
- whileStatement,
-
- withClause,
-
- yieldStatement,
-
- extensionOverride
-}
-
-/// Kinds of [LinkedNodeType]s.
-enum LinkedNodeTypeKind : byte {
- dynamic_,
-
- function,
-
- interface,
-
- never,
-
- typeParameter,
-
- void_
-}
-
-/// Enum used to indicate the kind of the error during top-level inference.
-enum TopLevelInferenceErrorKind : byte {
- assignment,
-
- instanceGetter,
-
- dependencyCycle,
-
- overrideConflictFieldType,
-
- overrideNoCombinedSuperSignature
-}
-
-/// Enum of token types, corresponding to AST token types.
-enum UnlinkedTokenType : byte {
- NOTHING,
-
- ABSTRACT,
-
- AMPERSAND,
-
- AMPERSAND_AMPERSAND,
-
- AMPERSAND_EQ,
-
- AS,
-
- ASSERT,
-
- ASYNC,
-
- AT,
-
- AWAIT,
-
- BACKPING,
-
- BACKSLASH,
-
- BANG,
-
- BANG_EQ,
-
- BANG_EQ_EQ,
-
- BAR,
-
- BAR_BAR,
-
- BAR_EQ,
-
- BREAK,
-
- CARET,
-
- CARET_EQ,
-
- CASE,
-
- CATCH,
-
- CLASS,
-
- CLOSE_CURLY_BRACKET,
-
- CLOSE_PAREN,
-
- CLOSE_SQUARE_BRACKET,
-
- COLON,
-
- COMMA,
-
- CONST,
-
- CONTINUE,
-
- COVARIANT,
-
- DEFAULT,
-
- DEFERRED,
-
- DO,
-
- DOUBLE,
-
- DYNAMIC,
-
- ELSE,
-
- ENUM,
-
- EOF,
-
- EQ,
-
- EQ_EQ,
-
- EQ_EQ_EQ,
-
- EXPORT,
-
- EXTENDS,
-
- EXTERNAL,
-
- FACTORY,
-
- FALSE,
-
- FINAL,
-
- FINALLY,
-
- FOR,
-
- FUNCTION,
-
- FUNCTION_KEYWORD,
-
- GET,
-
- GT,
-
- GT_EQ,
-
- GT_GT,
-
- GT_GT_EQ,
-
- GT_GT_GT,
-
- GT_GT_GT_EQ,
-
- HASH,
-
- HEXADECIMAL,
-
- HIDE,
-
- IDENTIFIER,
-
- IF,
-
- IMPLEMENTS,
-
- IMPORT,
-
- IN,
-
- INDEX,
-
- INDEX_EQ,
-
- INT,
-
- INTERFACE,
-
- IS,
-
- LATE,
-
- LIBRARY,
-
- LT,
-
- LT_EQ,
-
- LT_LT,
-
- LT_LT_EQ,
-
- MINUS,
-
- MINUS_EQ,
-
- MINUS_MINUS,
-
- MIXIN,
-
- MULTI_LINE_COMMENT,
-
- NATIVE,
-
- NEW,
-
- NULL,
-
- OF,
-
- ON,
-
- OPEN_CURLY_BRACKET,
-
- OPEN_PAREN,
-
- OPEN_SQUARE_BRACKET,
-
- OPERATOR,
-
- PART,
-
- PATCH,
-
- PERCENT,
-
- PERCENT_EQ,
-
- PERIOD,
-
- PERIOD_PERIOD,
-
- PERIOD_PERIOD_PERIOD,
-
- PERIOD_PERIOD_PERIOD_QUESTION,
-
- PLUS,
-
- PLUS_EQ,
-
- PLUS_PLUS,
-
- QUESTION,
-
- QUESTION_PERIOD,
-
- QUESTION_QUESTION,
-
- QUESTION_QUESTION_EQ,
-
- REQUIRED,
-
- RETHROW,
-
- RETURN,
-
- SCRIPT_TAG,
-
- SEMICOLON,
-
- SET,
-
- SHOW,
-
- SINGLE_LINE_COMMENT,
-
- SLASH,
-
- SLASH_EQ,
-
- SOURCE,
-
- STAR,
-
- STAR_EQ,
-
- STATIC,
-
- STRING,
-
- STRING_INTERPOLATION_EXPRESSION,
-
- STRING_INTERPOLATION_IDENTIFIER,
-
- SUPER,
-
- SWITCH,
-
- SYNC,
-
- THIS,
-
- THROW,
-
- TILDE,
-
- TILDE_SLASH,
-
- TILDE_SLASH_EQ,
-
- TRUE,
-
- TRY,
-
- TYPEDEF,
-
- VAR,
-
- VOID,
-
- WHILE,
-
- WITH,
-
- YIELD,
-
- INOUT,
-
- OUT
-}
-
/// Information about the context of an exception in analysis driver.
table AnalysisDriverExceptionContext {
/// The exception string.
@@ -1010,17 +406,6 @@
shows:[string] (id: 0);
}
-/// Information about linked libraries, a group of libraries that form
-/// a library cycle.
-table CiderLinkedLibraryCycle {
- bundle:LinkedNodeBundle (id: 1);
-
- /// The hash signature for this linked cycle. It depends of API signatures
- /// of all files in the cycle, and on the signatures of the transitive
- /// closure of the cycle dependencies.
- signature:[uint] (id: 0);
-}
-
/// Errors for a single unit.
table CiderUnitErrors {
errors:[AnalysisDriverUnitError] (id: 1);
@@ -1063,257 +448,10 @@
templateValues:[string] (id: 1);
}
-table LinkedLanguageVersion {
- major:uint (id: 0);
-
- minor:uint (id: 1);
-}
-
-table LinkedLibraryLanguageVersion {
- override2:LinkedLanguageVersion (id: 1);
-
- package:LinkedLanguageVersion (id: 0);
-}
-
-/// Information about a linked AST node.
-table LinkedNode {
- /// The explicit or inferred return type of a function typed node.
- variantField_24:LinkedNodeType (id: 24);
-
- variantField_2:[LinkedNode] (id: 2);
-
- variantField_4:[LinkedNode] (id: 4);
-
- variantField_6:LinkedNode (id: 6);
-
- variantField_7:LinkedNode (id: 7);
-
- variantField_17:uint (id: 17);
-
- variantField_8:LinkedNode (id: 8);
-
- variantField_38:LinkedNodeTypeSubstitution (id: 38);
-
- variantField_15:uint (id: 15);
-
- variantField_28:UnlinkedTokenType (id: 28);
-
- variantField_27:bool (id: 27);
-
- variantField_9:LinkedNode (id: 9);
-
- variantField_12:LinkedNode (id: 12);
-
- variantField_5:[LinkedNode] (id: 5);
-
- variantField_13:LinkedNode (id: 13);
-
- variantField_33:[string] (id: 33);
-
- variantField_29:LinkedNodeCommentType (id: 29);
-
- variantField_3:[LinkedNode] (id: 3);
-
- variantField_41:[uint] (id: 41);
-
- /// The language version information.
- variantField_40:LinkedLibraryLanguageVersion (id: 40);
-
- variantField_10:LinkedNode (id: 10);
-
- variantField_26:LinkedNodeFormalParameterKind (id: 26);
-
- variantField_21:double (id: 21);
-
- variantField_25:LinkedNodeType (id: 25);
-
- variantField_20:string (id: 20);
-
- variantField_39:[LinkedNodeType] (id: 39);
-
- flags:uint (id: 18);
-
- variantField_1:string (id: 1);
-
- variantField_36:uint (id: 36);
-
- variantField_16:uint (id: 16);
-
- variantField_30:string (id: 30);
-
- variantField_14:LinkedNode (id: 14);
-
- kind:LinkedNodeKind (id: 0);
-
- variantField_31:bool (id: 31);
-
- variantField_34:[string] (id: 34);
-
- name:string (id: 37);
-
- variantField_35:UnlinkedTokenType (id: 35);
-
- variantField_32:TopLevelInferenceError (id: 32);
-
- variantField_23:LinkedNodeType (id: 23);
-
- variantField_11:LinkedNode (id: 11);
-
- variantField_22:string (id: 22);
-
- variantField_19:uint (id: 19);
-}
-
-/// Information about a group of libraries linked together, for example because
-/// they form a single cycle, or because they represent a single build artifact.
-table LinkedNodeBundle {
- libraries:[LinkedNodeLibrary] (id: 1);
-
- /// The shared list of references used in the [libraries].
- references:LinkedNodeReferences (id: 0);
-}
-
-/// Information about a single library in a [LinkedNodeBundle].
-table LinkedNodeLibrary {
- exports:[uint] (id: 2);
-
- name:string (id: 3);
-
- nameLength:uint (id: 5);
-
- nameOffset:uint (id: 4);
-
- units:[LinkedNodeUnit] (id: 1);
-
- uriStr:string (id: 0);
-}
-
-/// Flattened tree of declarations referenced from [LinkedNode]s.
-table LinkedNodeReferences {
- name:[string] (id: 1);
-
- parent:[uint] (id: 0);
-}
-
-/// Information about a Dart type.
-table LinkedNodeType {
- functionFormalParameters:[LinkedNodeTypeFormalParameter] (id: 0);
-
- functionReturnType:LinkedNodeType (id: 1);
-
- /// The typedef this function type is created for.
- functionTypedef:uint (id: 9);
-
- functionTypedefTypeArguments:[LinkedNodeType] (id: 10);
-
- functionTypeParameters:[LinkedNodeTypeTypeParameter] (id: 2);
-
- /// Reference to a [LinkedNodeReferences].
- interfaceClass:uint (id: 3);
-
- interfaceTypeArguments:[LinkedNodeType] (id: 4);
-
- kind:LinkedNodeTypeKind (id: 5);
-
- nullabilitySuffix:EntityRefNullabilitySuffix (id: 8);
-
- typeParameterElement:uint (id: 6);
-
- typeParameterId:uint (id: 7);
-}
-
-/// Information about a formal parameter in a function type.
-table LinkedNodeTypeFormalParameter {
- kind:LinkedNodeFormalParameterKind (id: 0);
-
- name:string (id: 1);
-
- type:LinkedNodeType (id: 2);
-}
-
-/// Information about a type substitution.
-table LinkedNodeTypeSubstitution {
- isLegacy:bool (id: 2);
-
- typeArguments:[LinkedNodeType] (id: 1);
-
- typeParameters:[uint] (id: 0);
-}
-
-/// Information about a type parameter in a function type.
-table LinkedNodeTypeTypeParameter {
- bound:LinkedNodeType (id: 1);
-
- name:string (id: 0);
-}
-
-/// Information about a single library in a [LinkedNodeLibrary].
-table LinkedNodeUnit {
- isSynthetic:bool (id: 2);
-
- node:LinkedNode (id: 1);
-
- /// If the unit is a part, the URI specified in the `part` directive.
- /// Otherwise empty.
- partUriStr:string (id: 3);
-
- /// The absolute URI.
- uriStr:string (id: 0);
-}
-
/// Summary information about a package.
table PackageBundle {
/// The version 2 of the summary.
- bundle2:LinkedNodeBundle (id: 0);
-
- /// The SDK specific data, if this bundle is for SDK.
- sdk:PackageBundleSdk (id: 1);
-}
-
-/// Summary information about a package.
-table PackageBundleSdk {
- /// The content of the `allowed_experiments.json` from SDK.
- allowedExperimentsJson:string (id: 0);
-
- /// The language version of the SDK.
- languageVersion:LinkedLanguageVersion (id: 1);
-}
-
-/// Summary information about a top-level type inference error.
-table TopLevelInferenceError {
- /// The [kind] specific arguments.
- arguments:[string] (id: 1);
-
- /// The kind of the error.
- kind:TopLevelInferenceErrorKind (id: 0);
-}
-
-table UnlinkedInformativeData {
- variantField_2:uint (id: 2);
-
- variantField_3:uint (id: 3);
-
- variantField_9:uint (id: 9);
-
- variantField_8:uint (id: 8);
-
- /// Offsets of the first character of each line in the source code.
- variantField_7:[uint] (id: 7);
-
- variantField_6:uint (id: 6);
-
- 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);
-
- /// The kind of the node.
- kind:LinkedNodeKind (id: 0);
+ fake:uint (id: 0);
}
/// Unlinked summary information about a namespace directive.
@@ -1357,13 +495,11 @@
/// URIs of `import` directives.
imports:[UnlinkedNamespaceDirective] (id: 2);
- informativeData:[UnlinkedInformativeData] (id: 7);
-
/// Offsets of the first character of each line in the source code.
lineStarts:[uint] (id: 5);
/// URI of the `part of` directive.
- partOfUri:string (id: 8);
+ partOfUri:string (id: 7);
/// URIs of `part` directives.
parts:[string] (id: 4);
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index 4b84de9..bd9d540 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -40,7 +40,7 @@
/// Except as otherwise noted, synthetic elements are not stored in the summary;
/// they are re-synthesized at the time the summary is read.
import 'base.dart' as base;
-import 'base.dart' show Id, TopLevel, Variant, VariantId;
+import 'base.dart' show Id, TopLevel;
import 'format.dart' as generated;
/// Annotation describing information which is not part of Dart semantics; in
@@ -448,23 +448,6 @@
List<String> get shows;
}
-/// Information about linked libraries, a group of libraries that form
-/// a library cycle.
-@TopLevel('CLNB')
-abstract class CiderLinkedLibraryCycle extends base.SummaryClass {
- factory CiderLinkedLibraryCycle.fromBuffer(List<int> buffer) =>
- generated.readCiderLinkedLibraryCycle(buffer);
-
- @Id(1)
- LinkedNodeBundle get bundle;
-
- /// The hash signature for this linked cycle. It depends of API signatures
- /// of all files in the cycle, and on the signatures of the transitive
- /// closure of the cycle dependencies.
- @Id(0)
- List<int> get signature;
-}
-
/// Errors for a single unit.
@TopLevel('CUEr')
abstract class CiderUnitErrors extends base.SummaryClass {
@@ -525,30 +508,6 @@
List<String> get templateValues;
}
-/// Enum representing nullability suffixes in summaries.
-///
-/// This enum is similar to [NullabilitySuffix], but the order is different so
-/// that [EntityRefNullabilitySuffix.starOrIrrelevant] can be the default.
-enum EntityRefNullabilitySuffix {
- /// An indication that the canonical representation of the type under
- /// consideration ends with `*`. Types having this nullability suffix are
- /// called "legacy types"; it has not yet been determined whether they should
- /// be unioned with the Null type.
- ///
- /// Also used in circumstances where no nullability suffix information is
- /// needed.
- starOrIrrelevant,
-
- /// An indication that the canonical representation of the type under
- /// consideration ends with `?`. Types having this nullability suffix should
- /// be interpreted as being unioned with the Null type.
- question,
-
- /// An indication that the canonical representation of the type under
- /// consideration does not end with either `?` or `*`.
- none,
-}
-
/// Enum used to indicate the kind of an index relation.
enum IndexRelationKind {
/// Left: class.
@@ -635,1263 +594,6 @@
unit
}
-abstract class LinkedLanguageVersion extends base.SummaryClass {
- @Id(0)
- int get major;
-
- @Id(1)
- int get minor;
-}
-
-abstract class LinkedLibraryLanguageVersion extends base.SummaryClass {
- @Id(1)
- LinkedLanguageVersion get override2;
-
- @Id(0)
- LinkedLanguageVersion get package;
-}
-
-/// Information about a linked AST node.
-@Variant('kind')
-abstract class LinkedNode extends base.SummaryClass {
- /// The explicit or inferred return type of a function typed node.
- @VariantId(24, variantList: [
- LinkedNodeKind.functionDeclaration,
- LinkedNodeKind.functionExpression,
- LinkedNodeKind.functionTypeAlias,
- LinkedNodeKind.genericFunctionType,
- LinkedNodeKind.methodDeclaration,
- ])
- LinkedNodeType get actualReturnType;
-
- /// The explicit or inferred type of a variable.
- @VariantId(24, variantList: [
- LinkedNodeKind.fieldFormalParameter,
- LinkedNodeKind.functionTypedFormalParameter,
- LinkedNodeKind.simpleFormalParameter,
- LinkedNodeKind.variableDeclaration,
- ])
- LinkedNodeType get actualType;
-
- @VariantId(2, variant: LinkedNodeKind.adjacentStrings)
- List<LinkedNode> get adjacentStrings_strings;
-
- @VariantId(4, variantList: [
- LinkedNodeKind.classDeclaration,
- LinkedNodeKind.classTypeAlias,
- LinkedNodeKind.constructorDeclaration,
- LinkedNodeKind.declaredIdentifier,
- LinkedNodeKind.enumDeclaration,
- LinkedNodeKind.enumConstantDeclaration,
- LinkedNodeKind.exportDirective,
- LinkedNodeKind.extensionDeclaration,
- LinkedNodeKind.fieldDeclaration,
- LinkedNodeKind.functionDeclaration,
- LinkedNodeKind.functionTypeAlias,
- LinkedNodeKind.genericTypeAlias,
- LinkedNodeKind.importDirective,
- LinkedNodeKind.libraryDirective,
- LinkedNodeKind.methodDeclaration,
- LinkedNodeKind.mixinDeclaration,
- LinkedNodeKind.partDirective,
- LinkedNodeKind.partOfDirective,
- LinkedNodeKind.topLevelVariableDeclaration,
- LinkedNodeKind.typeParameter,
- LinkedNodeKind.variableDeclaration,
- LinkedNodeKind.variableDeclarationList,
- ])
- List<LinkedNode> get annotatedNode_metadata;
-
- @VariantId(6, variant: LinkedNodeKind.annotation)
- LinkedNode get annotation_arguments;
-
- @VariantId(7, variant: LinkedNodeKind.annotation)
- LinkedNode get annotation_constructorName;
-
- @VariantId(17, variant: LinkedNodeKind.annotation)
- int get annotation_element;
-
- @VariantId(8, variant: LinkedNodeKind.annotation)
- LinkedNode get annotation_name;
-
- @VariantId(38, variant: LinkedNodeKind.annotation)
- LinkedNodeTypeSubstitution get annotation_substitution;
-
- @VariantId(2, variant: LinkedNodeKind.argumentList)
- List<LinkedNode> get argumentList_arguments;
-
- @VariantId(6, variant: LinkedNodeKind.asExpression)
- LinkedNode get asExpression_expression;
-
- @VariantId(7, variant: LinkedNodeKind.asExpression)
- LinkedNode get asExpression_type;
-
- @VariantId(6, variant: LinkedNodeKind.assertInitializer)
- LinkedNode get assertInitializer_condition;
-
- @VariantId(7, variant: LinkedNodeKind.assertInitializer)
- LinkedNode get assertInitializer_message;
-
- @VariantId(6, variant: LinkedNodeKind.assertStatement)
- LinkedNode get assertStatement_condition;
-
- @VariantId(7, variant: LinkedNodeKind.assertStatement)
- LinkedNode get assertStatement_message;
-
- @VariantId(15, variant: LinkedNodeKind.assignmentExpression)
- int get assignmentExpression_element;
-
- @VariantId(6, variant: LinkedNodeKind.assignmentExpression)
- LinkedNode get assignmentExpression_leftHandSide;
-
- @VariantId(28, variant: LinkedNodeKind.assignmentExpression)
- UnlinkedTokenType get assignmentExpression_operator;
-
- @VariantId(7, variant: LinkedNodeKind.assignmentExpression)
- LinkedNode get assignmentExpression_rightHandSide;
-
- @VariantId(38, variant: LinkedNodeKind.assignmentExpression)
- LinkedNodeTypeSubstitution get assignmentExpression_substitution;
-
- @VariantId(6, variant: LinkedNodeKind.awaitExpression)
- LinkedNode get awaitExpression_expression;
-
- @VariantId(15, variant: LinkedNodeKind.binaryExpression)
- int get binaryExpression_element;
-
- @VariantId(24, variant: LinkedNodeKind.binaryExpression)
- LinkedNodeType get binaryExpression_invokeType;
-
- @VariantId(6, variant: LinkedNodeKind.binaryExpression)
- LinkedNode get binaryExpression_leftOperand;
-
- @VariantId(28, variant: LinkedNodeKind.binaryExpression)
- UnlinkedTokenType get binaryExpression_operator;
-
- @VariantId(7, variant: LinkedNodeKind.binaryExpression)
- LinkedNode get binaryExpression_rightOperand;
-
- @VariantId(38, variant: LinkedNodeKind.binaryExpression)
- LinkedNodeTypeSubstitution get binaryExpression_substitution;
-
- @VariantId(2, variant: LinkedNodeKind.block)
- List<LinkedNode> get block_statements;
-
- @VariantId(6, variant: LinkedNodeKind.blockFunctionBody)
- LinkedNode get blockFunctionBody_block;
-
- @VariantId(27, variant: LinkedNodeKind.booleanLiteral)
- bool get booleanLiteral_value;
-
- @VariantId(6, variant: LinkedNodeKind.breakStatement)
- LinkedNode get breakStatement_label;
-
- @VariantId(2, variant: LinkedNodeKind.cascadeExpression)
- List<LinkedNode> get cascadeExpression_sections;
-
- @VariantId(6, variant: LinkedNodeKind.cascadeExpression)
- LinkedNode get cascadeExpression_target;
-
- @VariantId(6, variant: LinkedNodeKind.catchClause)
- LinkedNode get catchClause_body;
-
- @VariantId(7, variant: LinkedNodeKind.catchClause)
- LinkedNode get catchClause_exceptionParameter;
-
- @VariantId(8, variant: LinkedNodeKind.catchClause)
- LinkedNode get catchClause_exceptionType;
-
- @VariantId(9, variant: LinkedNodeKind.catchClause)
- LinkedNode get catchClause_stackTraceParameter;
-
- @VariantId(6, variant: LinkedNodeKind.classDeclaration)
- LinkedNode get classDeclaration_extendsClause;
-
- @VariantId(27, variant: LinkedNodeKind.classDeclaration)
- bool get classDeclaration_isDartObject;
-
- @VariantId(8, variant: LinkedNodeKind.classDeclaration)
- LinkedNode get classDeclaration_nativeClause;
-
- @VariantId(7, variant: LinkedNodeKind.classDeclaration)
- LinkedNode get classDeclaration_withClause;
-
- @VariantId(12, variantList: [
- LinkedNodeKind.classDeclaration,
- LinkedNodeKind.mixinDeclaration,
- ])
- LinkedNode get classOrMixinDeclaration_implementsClause;
-
- @VariantId(5, variantList: [
- LinkedNodeKind.classDeclaration,
- LinkedNodeKind.mixinDeclaration,
- ])
- List<LinkedNode> get classOrMixinDeclaration_members;
-
- @VariantId(13, variantList: [
- LinkedNodeKind.classDeclaration,
- LinkedNodeKind.mixinDeclaration,
- ])
- LinkedNode get classOrMixinDeclaration_typeParameters;
-
- @VariantId(9, variant: LinkedNodeKind.classTypeAlias)
- LinkedNode get classTypeAlias_implementsClause;
-
- @VariantId(7, variant: LinkedNodeKind.classTypeAlias)
- LinkedNode get classTypeAlias_superclass;
-
- @VariantId(6, variant: LinkedNodeKind.classTypeAlias)
- LinkedNode get classTypeAlias_typeParameters;
-
- @VariantId(8, variant: LinkedNodeKind.classTypeAlias)
- LinkedNode get classTypeAlias_withClause;
-
- @VariantId(2, variant: LinkedNodeKind.comment)
- List<LinkedNode> get comment_references;
-
- @VariantId(33, variant: LinkedNodeKind.comment)
- List<String> get comment_tokens;
-
- @VariantId(29, variant: LinkedNodeKind.comment)
- LinkedNodeCommentType get comment_type;
-
- @VariantId(6, variant: LinkedNodeKind.commentReference)
- LinkedNode get commentReference_identifier;
-
- @VariantId(2, variant: LinkedNodeKind.compilationUnit)
- List<LinkedNode> get compilationUnit_declarations;
-
- @VariantId(3, variant: LinkedNodeKind.compilationUnit)
- List<LinkedNode> get compilationUnit_directives;
-
- @VariantId(41, variant: LinkedNodeKind.compilationUnit)
- List<int> get compilationUnit_featureSet;
-
- /// The language version information.
- @VariantId(40, variant: LinkedNodeKind.compilationUnit)
- LinkedLibraryLanguageVersion get compilationUnit_languageVersion;
-
- @VariantId(6, variant: LinkedNodeKind.compilationUnit)
- LinkedNode get compilationUnit_scriptTag;
-
- @VariantId(6, variant: LinkedNodeKind.conditionalExpression)
- LinkedNode get conditionalExpression_condition;
-
- @VariantId(7, variant: LinkedNodeKind.conditionalExpression)
- LinkedNode get conditionalExpression_elseExpression;
-
- @VariantId(8, variant: LinkedNodeKind.conditionalExpression)
- LinkedNode get conditionalExpression_thenExpression;
-
- @VariantId(6, variant: LinkedNodeKind.configuration)
- LinkedNode get configuration_name;
-
- @VariantId(8, variant: LinkedNodeKind.configuration)
- LinkedNode get configuration_uri;
-
- @VariantId(7, variant: LinkedNodeKind.configuration)
- LinkedNode get configuration_value;
-
- @VariantId(6, variant: LinkedNodeKind.constructorDeclaration)
- LinkedNode get constructorDeclaration_body;
-
- @VariantId(2, variant: LinkedNodeKind.constructorDeclaration)
- List<LinkedNode> get constructorDeclaration_initializers;
-
- @VariantId(8, variant: LinkedNodeKind.constructorDeclaration)
- LinkedNode get constructorDeclaration_parameters;
-
- @VariantId(9, variant: LinkedNodeKind.constructorDeclaration)
- LinkedNode get constructorDeclaration_redirectedConstructor;
-
- @VariantId(10, variant: LinkedNodeKind.constructorDeclaration)
- LinkedNode get constructorDeclaration_returnType;
-
- @VariantId(6, variant: LinkedNodeKind.constructorFieldInitializer)
- LinkedNode get constructorFieldInitializer_expression;
-
- @VariantId(7, variant: LinkedNodeKind.constructorFieldInitializer)
- LinkedNode get constructorFieldInitializer_fieldName;
-
- @VariantId(15, variant: LinkedNodeKind.constructorName)
- int get constructorName_element;
-
- @VariantId(6, variant: LinkedNodeKind.constructorName)
- LinkedNode get constructorName_name;
-
- @VariantId(38, variant: LinkedNodeKind.constructorName)
- LinkedNodeTypeSubstitution get constructorName_substitution;
-
- @VariantId(7, variant: LinkedNodeKind.constructorName)
- LinkedNode get constructorName_type;
-
- @VariantId(6, variant: LinkedNodeKind.continueStatement)
- LinkedNode get continueStatement_label;
-
- @VariantId(6, variant: LinkedNodeKind.declaredIdentifier)
- LinkedNode get declaredIdentifier_identifier;
-
- @VariantId(7, variant: LinkedNodeKind.declaredIdentifier)
- LinkedNode get declaredIdentifier_type;
-
- @VariantId(6, variant: LinkedNodeKind.defaultFormalParameter)
- LinkedNode get defaultFormalParameter_defaultValue;
-
- @VariantId(26, variant: LinkedNodeKind.defaultFormalParameter)
- LinkedNodeFormalParameterKind get defaultFormalParameter_kind;
-
- @VariantId(7, variant: LinkedNodeKind.defaultFormalParameter)
- LinkedNode get defaultFormalParameter_parameter;
-
- @VariantId(6, variant: LinkedNodeKind.doStatement)
- LinkedNode get doStatement_body;
-
- @VariantId(7, variant: LinkedNodeKind.doStatement)
- LinkedNode get doStatement_condition;
-
- @VariantId(2, variant: LinkedNodeKind.dottedName)
- List<LinkedNode> get dottedName_components;
-
- @VariantId(21, variant: LinkedNodeKind.doubleLiteral)
- double get doubleLiteral_value;
-
- @VariantId(15, variant: LinkedNodeKind.emptyFunctionBody)
- int get emptyFunctionBody_fake;
-
- @VariantId(15, variant: LinkedNodeKind.emptyStatement)
- int get emptyStatement_fake;
-
- @VariantId(2, variant: LinkedNodeKind.enumDeclaration)
- List<LinkedNode> get enumDeclaration_constants;
-
- @VariantId(25, variantList: [
- LinkedNodeKind.assignmentExpression,
- LinkedNodeKind.asExpression,
- LinkedNodeKind.awaitExpression,
- LinkedNodeKind.binaryExpression,
- LinkedNodeKind.cascadeExpression,
- LinkedNodeKind.conditionalExpression,
- LinkedNodeKind.functionExpressionInvocation,
- LinkedNodeKind.indexExpression,
- LinkedNodeKind.instanceCreationExpression,
- LinkedNodeKind.integerLiteral,
- LinkedNodeKind.listLiteral,
- LinkedNodeKind.methodInvocation,
- LinkedNodeKind.nullLiteral,
- LinkedNodeKind.parenthesizedExpression,
- LinkedNodeKind.prefixExpression,
- LinkedNodeKind.prefixedIdentifier,
- LinkedNodeKind.propertyAccess,
- LinkedNodeKind.postfixExpression,
- LinkedNodeKind.rethrowExpression,
- LinkedNodeKind.setOrMapLiteral,
- LinkedNodeKind.simpleIdentifier,
- LinkedNodeKind.superExpression,
- LinkedNodeKind.symbolLiteral,
- LinkedNodeKind.thisExpression,
- LinkedNodeKind.throwExpression,
- ])
- LinkedNodeType get expression_type;
-
- @VariantId(6, variant: LinkedNodeKind.expressionFunctionBody)
- LinkedNode get expressionFunctionBody_expression;
-
- @VariantId(6, variant: LinkedNodeKind.expressionStatement)
- LinkedNode get expressionStatement_expression;
-
- @VariantId(6, variant: LinkedNodeKind.extendsClause)
- LinkedNode get extendsClause_superclass;
-
- @VariantId(7, variant: LinkedNodeKind.extensionDeclaration)
- LinkedNode get extensionDeclaration_extendedType;
-
- @VariantId(5, variant: LinkedNodeKind.extensionDeclaration)
- List<LinkedNode> get extensionDeclaration_members;
-
- @VariantId(20, variant: LinkedNodeKind.extensionDeclaration)
- String get extensionDeclaration_refName;
-
- @VariantId(6, variant: LinkedNodeKind.extensionDeclaration)
- LinkedNode get extensionDeclaration_typeParameters;
-
- @VariantId(2, variant: LinkedNodeKind.extensionOverride)
- List<LinkedNode> get extensionOverride_arguments;
-
- @VariantId(24, variant: LinkedNodeKind.extensionOverride)
- LinkedNodeType get extensionOverride_extendedType;
-
- @VariantId(7, variant: LinkedNodeKind.extensionOverride)
- LinkedNode get extensionOverride_extensionName;
-
- @VariantId(8, variant: LinkedNodeKind.extensionOverride)
- LinkedNode get extensionOverride_typeArguments;
-
- @VariantId(39, variant: LinkedNodeKind.extensionOverride)
- List<LinkedNodeType> get extensionOverride_typeArgumentTypes;
-
- @VariantId(6, variant: LinkedNodeKind.fieldDeclaration)
- LinkedNode get fieldDeclaration_fields;
-
- @VariantId(8, variant: LinkedNodeKind.fieldFormalParameter)
- LinkedNode get fieldFormalParameter_formalParameters;
-
- @VariantId(6, variant: LinkedNodeKind.fieldFormalParameter)
- LinkedNode get fieldFormalParameter_type;
-
- @VariantId(7, variant: LinkedNodeKind.fieldFormalParameter)
- LinkedNode get fieldFormalParameter_typeParameters;
-
- @Id(18)
- int get flags;
-
- @VariantId(6, variantList: [
- LinkedNodeKind.forEachPartsWithDeclaration,
- LinkedNodeKind.forEachPartsWithIdentifier,
- ])
- LinkedNode get forEachParts_iterable;
-
- @VariantId(7, variant: LinkedNodeKind.forEachPartsWithDeclaration)
- LinkedNode get forEachPartsWithDeclaration_loopVariable;
-
- @VariantId(7, variant: LinkedNodeKind.forEachPartsWithIdentifier)
- LinkedNode get forEachPartsWithIdentifier_identifier;
-
- @VariantId(7, variant: LinkedNodeKind.forElement)
- LinkedNode get forElement_body;
-
- @VariantId(2, variant: LinkedNodeKind.formalParameterList)
- List<LinkedNode> get formalParameterList_parameters;
-
- @VariantId(6, variantList: [
- LinkedNodeKind.forElement,
- LinkedNodeKind.forStatement,
- ])
- LinkedNode get forMixin_forLoopParts;
-
- @VariantId(6, variantList: [
- LinkedNodeKind.forPartsWithDeclarations,
- LinkedNodeKind.forPartsWithExpression,
- ])
- LinkedNode get forParts_condition;
-
- @VariantId(5, variantList: [
- LinkedNodeKind.forPartsWithDeclarations,
- LinkedNodeKind.forPartsWithExpression,
- ])
- List<LinkedNode> get forParts_updaters;
-
- @VariantId(7, variant: LinkedNodeKind.forPartsWithDeclarations)
- LinkedNode get forPartsWithDeclarations_variables;
-
- @VariantId(7, variant: LinkedNodeKind.forPartsWithExpression)
- LinkedNode get forPartsWithExpression_initialization;
-
- @VariantId(7, variant: LinkedNodeKind.forStatement)
- LinkedNode get forStatement_body;
-
- @VariantId(6, variant: LinkedNodeKind.functionDeclaration)
- LinkedNode get functionDeclaration_functionExpression;
-
- @VariantId(7, variant: LinkedNodeKind.functionDeclaration)
- LinkedNode get functionDeclaration_returnType;
-
- @VariantId(6, variant: LinkedNodeKind.functionDeclarationStatement)
- LinkedNode get functionDeclarationStatement_functionDeclaration;
-
- @VariantId(6, variant: LinkedNodeKind.functionExpression)
- LinkedNode get functionExpression_body;
-
- @VariantId(7, variant: LinkedNodeKind.functionExpression)
- LinkedNode get functionExpression_formalParameters;
-
- @VariantId(8, variant: LinkedNodeKind.functionExpression)
- LinkedNode get functionExpression_typeParameters;
-
- @VariantId(6, variant: LinkedNodeKind.functionExpressionInvocation)
- LinkedNode get functionExpressionInvocation_function;
-
- @VariantId(6, variant: LinkedNodeKind.functionTypeAlias)
- LinkedNode get functionTypeAlias_formalParameters;
-
- @VariantId(7, variant: LinkedNodeKind.functionTypeAlias)
- LinkedNode get functionTypeAlias_returnType;
-
- @VariantId(8, variant: LinkedNodeKind.functionTypeAlias)
- LinkedNode get functionTypeAlias_typeParameters;
-
- @VariantId(6, variant: LinkedNodeKind.functionTypedFormalParameter)
- LinkedNode get functionTypedFormalParameter_formalParameters;
-
- @VariantId(7, variant: LinkedNodeKind.functionTypedFormalParameter)
- LinkedNode get functionTypedFormalParameter_returnType;
-
- @VariantId(8, variant: LinkedNodeKind.functionTypedFormalParameter)
- LinkedNode get functionTypedFormalParameter_typeParameters;
-
- @VariantId(8, variant: LinkedNodeKind.genericFunctionType)
- LinkedNode get genericFunctionType_formalParameters;
-
- @VariantId(17, variant: LinkedNodeKind.genericFunctionType)
- int get genericFunctionType_id;
-
- @VariantId(7, variant: LinkedNodeKind.genericFunctionType)
- LinkedNode get genericFunctionType_returnType;
-
- @VariantId(25, variant: LinkedNodeKind.genericFunctionType)
- LinkedNodeType get genericFunctionType_type;
-
- @VariantId(6, variant: LinkedNodeKind.genericFunctionType)
- LinkedNode get genericFunctionType_typeParameters;
-
- @VariantId(7, variant: LinkedNodeKind.genericTypeAlias)
- LinkedNode get genericTypeAlias_functionType;
-
- @VariantId(6, variant: LinkedNodeKind.genericTypeAlias)
- LinkedNode get genericTypeAlias_typeParameters;
-
- @VariantId(9, variant: LinkedNodeKind.ifElement)
- LinkedNode get ifElement_elseElement;
-
- @VariantId(8, variant: LinkedNodeKind.ifElement)
- LinkedNode get ifElement_thenElement;
-
- @VariantId(6, variantList: [
- LinkedNodeKind.ifElement,
- LinkedNodeKind.ifStatement,
- ])
- LinkedNode get ifMixin_condition;
-
- @VariantId(7, variant: LinkedNodeKind.ifStatement)
- LinkedNode get ifStatement_elseStatement;
-
- @VariantId(8, variant: LinkedNodeKind.ifStatement)
- LinkedNode get ifStatement_thenStatement;
-
- @VariantId(2, variant: LinkedNodeKind.implementsClause)
- List<LinkedNode> get implementsClause_interfaces;
-
- @VariantId(1, variant: LinkedNodeKind.importDirective)
- String get importDirective_prefix;
-
- @VariantId(15, variant: LinkedNodeKind.indexExpression)
- int get indexExpression_element;
-
- @VariantId(6, variant: LinkedNodeKind.indexExpression)
- LinkedNode get indexExpression_index;
-
- @VariantId(38, variant: LinkedNodeKind.indexExpression)
- LinkedNodeTypeSubstitution get indexExpression_substitution;
-
- @VariantId(7, variant: LinkedNodeKind.indexExpression)
- LinkedNode get indexExpression_target;
-
- @VariantId(36, variantList: [
- LinkedNodeKind.classDeclaration,
- LinkedNodeKind.classTypeAlias,
- LinkedNodeKind.compilationUnit,
- LinkedNodeKind.compilationUnit,
- LinkedNodeKind.constructorDeclaration,
- LinkedNodeKind.defaultFormalParameter,
- LinkedNodeKind.enumConstantDeclaration,
- LinkedNodeKind.enumDeclaration,
- LinkedNodeKind.exportDirective,
- LinkedNodeKind.extensionDeclaration,
- LinkedNodeKind.fieldDeclaration,
- LinkedNodeKind.fieldFormalParameter,
- LinkedNodeKind.functionDeclaration,
- LinkedNodeKind.functionTypedFormalParameter,
- LinkedNodeKind.functionTypeAlias,
- LinkedNodeKind.genericTypeAlias,
- LinkedNodeKind.hideCombinator,
- LinkedNodeKind.importDirective,
- LinkedNodeKind.libraryDirective,
- LinkedNodeKind.methodDeclaration,
- LinkedNodeKind.mixinDeclaration,
- LinkedNodeKind.partDirective,
- LinkedNodeKind.partOfDirective,
- LinkedNodeKind.showCombinator,
- LinkedNodeKind.simpleFormalParameter,
- LinkedNodeKind.topLevelVariableDeclaration,
- LinkedNodeKind.typeParameter,
- LinkedNodeKind.variableDeclaration,
- LinkedNodeKind.variableDeclarationList,
- ])
- @informative
- int get informativeId;
-
- @VariantId(27, variantList: [
- LinkedNodeKind.fieldFormalParameter,
- LinkedNodeKind.functionTypedFormalParameter,
- LinkedNodeKind.simpleFormalParameter,
- LinkedNodeKind.variableDeclaration,
- ])
- bool get inheritsCovariant;
-
- @VariantId(2, variant: LinkedNodeKind.instanceCreationExpression)
- List<LinkedNode> get instanceCreationExpression_arguments;
-
- @VariantId(7, variant: LinkedNodeKind.instanceCreationExpression)
- LinkedNode get instanceCreationExpression_constructorName;
-
- @VariantId(8, variant: LinkedNodeKind.instanceCreationExpression)
- LinkedNode get instanceCreationExpression_typeArguments;
-
- @VariantId(16, variant: LinkedNodeKind.integerLiteral)
- int get integerLiteral_value;
-
- @VariantId(6, variant: LinkedNodeKind.interpolationExpression)
- LinkedNode get interpolationExpression_expression;
-
- @VariantId(30, variant: LinkedNodeKind.interpolationString)
- String get interpolationString_value;
-
- @VariantId(14, variantList: [
- LinkedNodeKind.functionExpressionInvocation,
- LinkedNodeKind.methodInvocation,
- ])
- LinkedNode get invocationExpression_arguments;
-
- @VariantId(24, variantList: [
- LinkedNodeKind.functionExpressionInvocation,
- LinkedNodeKind.methodInvocation,
- ])
- LinkedNodeType get invocationExpression_invokeType;
-
- @VariantId(12, variantList: [
- LinkedNodeKind.functionExpressionInvocation,
- LinkedNodeKind.methodInvocation,
- ])
- LinkedNode get invocationExpression_typeArguments;
-
- @VariantId(6, variant: LinkedNodeKind.isExpression)
- LinkedNode get isExpression_expression;
-
- @VariantId(7, variant: LinkedNodeKind.isExpression)
- LinkedNode get isExpression_type;
-
- @Id(0)
- LinkedNodeKind get kind;
-
- @VariantId(6, variant: LinkedNodeKind.label)
- LinkedNode get label_label;
-
- @VariantId(2, variant: LinkedNodeKind.labeledStatement)
- List<LinkedNode> get labeledStatement_labels;
-
- @VariantId(6, variant: LinkedNodeKind.labeledStatement)
- LinkedNode get labeledStatement_statement;
-
- @VariantId(6, variant: LinkedNodeKind.libraryDirective)
- LinkedNode get libraryDirective_name;
-
- @VariantId(2, variant: LinkedNodeKind.libraryIdentifier)
- List<LinkedNode> get libraryIdentifier_components;
-
- @VariantId(3, variant: LinkedNodeKind.listLiteral)
- List<LinkedNode> get listLiteral_elements;
-
- @VariantId(6, variant: LinkedNodeKind.mapLiteralEntry)
- LinkedNode get mapLiteralEntry_key;
-
- @VariantId(7, variant: LinkedNodeKind.mapLiteralEntry)
- LinkedNode get mapLiteralEntry_value;
-
- @VariantId(6, variant: LinkedNodeKind.methodDeclaration)
- LinkedNode get methodDeclaration_body;
-
- @VariantId(7, variant: LinkedNodeKind.methodDeclaration)
- LinkedNode get methodDeclaration_formalParameters;
-
- @VariantId(31, variant: LinkedNodeKind.methodDeclaration)
- bool get methodDeclaration_hasOperatorEqualWithParameterTypeFromObject;
-
- @VariantId(8, variant: LinkedNodeKind.methodDeclaration)
- LinkedNode get methodDeclaration_returnType;
-
- @VariantId(9, variant: LinkedNodeKind.methodDeclaration)
- LinkedNode get methodDeclaration_typeParameters;
-
- @VariantId(6, variant: LinkedNodeKind.methodInvocation)
- LinkedNode get methodInvocation_methodName;
-
- @VariantId(7, variant: LinkedNodeKind.methodInvocation)
- LinkedNode get methodInvocation_target;
-
- @VariantId(6, variant: LinkedNodeKind.mixinDeclaration)
- LinkedNode get mixinDeclaration_onClause;
-
- @VariantId(34, variant: LinkedNodeKind.mixinDeclaration)
- List<String> get mixinDeclaration_superInvokedNames;
-
- @Id(37)
- String get name;
-
- @VariantId(6, variant: LinkedNodeKind.namedExpression)
- LinkedNode get namedExpression_expression;
-
- @VariantId(7, variant: LinkedNodeKind.namedExpression)
- LinkedNode get namedExpression_name;
-
- @VariantId(34, variantList: [
- LinkedNodeKind.hideCombinator,
- LinkedNodeKind.showCombinator,
- LinkedNodeKind.symbolLiteral,
- ])
- List<String> get names;
-
- @VariantId(2, variantList: [
- LinkedNodeKind.exportDirective,
- LinkedNodeKind.importDirective,
- ])
- List<LinkedNode> get namespaceDirective_combinators;
-
- @VariantId(3, variantList: [
- LinkedNodeKind.exportDirective,
- LinkedNodeKind.importDirective,
- ])
- List<LinkedNode> get namespaceDirective_configurations;
-
- @VariantId(20, variantList: [
- LinkedNodeKind.exportDirective,
- LinkedNodeKind.importDirective,
- ])
- String get namespaceDirective_selectedUri;
-
- @VariantId(6, variant: LinkedNodeKind.nativeClause)
- LinkedNode get nativeClause_name;
-
- @VariantId(6, variant: LinkedNodeKind.nativeFunctionBody)
- LinkedNode get nativeFunctionBody_stringLiteral;
-
- @VariantId(4, variantList: [
- LinkedNodeKind.fieldFormalParameter,
- LinkedNodeKind.functionTypedFormalParameter,
- LinkedNodeKind.simpleFormalParameter,
- ])
- List<LinkedNode> get normalFormalParameter_metadata;
-
- @VariantId(15, variant: LinkedNodeKind.nullLiteral)
- int get nullLiteral_fake;
-
- @VariantId(2, variant: LinkedNodeKind.onClause)
- List<LinkedNode> get onClause_superclassConstraints;
-
- @VariantId(6, variant: LinkedNodeKind.parenthesizedExpression)
- LinkedNode get parenthesizedExpression_expression;
-
- @VariantId(6, variant: LinkedNodeKind.partOfDirective)
- LinkedNode get partOfDirective_libraryName;
-
- @VariantId(7, variant: LinkedNodeKind.partOfDirective)
- LinkedNode get partOfDirective_uri;
-
- @VariantId(15, variant: LinkedNodeKind.postfixExpression)
- int get postfixExpression_element;
-
- @VariantId(6, variant: LinkedNodeKind.postfixExpression)
- LinkedNode get postfixExpression_operand;
-
- @VariantId(28, variant: LinkedNodeKind.postfixExpression)
- UnlinkedTokenType get postfixExpression_operator;
-
- @VariantId(38, variant: LinkedNodeKind.postfixExpression)
- LinkedNodeTypeSubstitution get postfixExpression_substitution;
-
- @VariantId(6, variant: LinkedNodeKind.prefixedIdentifier)
- LinkedNode get prefixedIdentifier_identifier;
-
- @VariantId(7, variant: LinkedNodeKind.prefixedIdentifier)
- LinkedNode get prefixedIdentifier_prefix;
-
- @VariantId(15, variant: LinkedNodeKind.prefixExpression)
- int get prefixExpression_element;
-
- @VariantId(6, variant: LinkedNodeKind.prefixExpression)
- LinkedNode get prefixExpression_operand;
-
- @VariantId(28, variant: LinkedNodeKind.prefixExpression)
- UnlinkedTokenType get prefixExpression_operator;
-
- @VariantId(38, variant: LinkedNodeKind.prefixExpression)
- LinkedNodeTypeSubstitution get prefixExpression_substitution;
-
- @VariantId(28, variant: LinkedNodeKind.propertyAccess)
- UnlinkedTokenType get propertyAccess_operator;
-
- @VariantId(6, variant: LinkedNodeKind.propertyAccess)
- LinkedNode get propertyAccess_propertyName;
-
- @VariantId(7, variant: LinkedNodeKind.propertyAccess)
- LinkedNode get propertyAccess_target;
-
- @VariantId(6, variant: LinkedNodeKind.redirectingConstructorInvocation)
- LinkedNode get redirectingConstructorInvocation_arguments;
-
- @VariantId(7, variant: LinkedNodeKind.redirectingConstructorInvocation)
- LinkedNode get redirectingConstructorInvocation_constructorName;
-
- @VariantId(15, variant: LinkedNodeKind.redirectingConstructorInvocation)
- int get redirectingConstructorInvocation_element;
-
- @VariantId(38, variant: LinkedNodeKind.redirectingConstructorInvocation)
- LinkedNodeTypeSubstitution get redirectingConstructorInvocation_substitution;
-
- @VariantId(6, variant: LinkedNodeKind.returnStatement)
- LinkedNode get returnStatement_expression;
-
- @VariantId(3, variant: LinkedNodeKind.setOrMapLiteral)
- List<LinkedNode> get setOrMapLiteral_elements;
-
- @VariantId(6, variant: LinkedNodeKind.simpleFormalParameter)
- LinkedNode get simpleFormalParameter_type;
-
- @VariantId(15, variant: LinkedNodeKind.simpleIdentifier)
- int get simpleIdentifier_element;
-
- @VariantId(38, variant: LinkedNodeKind.simpleIdentifier)
- LinkedNodeTypeSubstitution get simpleIdentifier_substitution;
-
- @VariantId(20, variant: LinkedNodeKind.simpleStringLiteral)
- String get simpleStringLiteral_value;
-
- @VariantId(31, variantList: [
- LinkedNodeKind.classDeclaration,
- LinkedNodeKind.classTypeAlias,
- LinkedNodeKind.functionTypeAlias,
- LinkedNodeKind.genericTypeAlias,
- LinkedNodeKind.mixinDeclaration,
- ])
- bool get simplyBoundable_isSimplyBounded;
-
- @VariantId(6, variant: LinkedNodeKind.spreadElement)
- LinkedNode get spreadElement_expression;
-
- @VariantId(35, variant: LinkedNodeKind.spreadElement)
- UnlinkedTokenType get spreadElement_spreadOperator;
-
- @VariantId(2, variant: LinkedNodeKind.stringInterpolation)
- List<LinkedNode> get stringInterpolation_elements;
-
- @VariantId(6, variant: LinkedNodeKind.superConstructorInvocation)
- LinkedNode get superConstructorInvocation_arguments;
-
- @VariantId(7, variant: LinkedNodeKind.superConstructorInvocation)
- LinkedNode get superConstructorInvocation_constructorName;
-
- @VariantId(15, variant: LinkedNodeKind.superConstructorInvocation)
- int get superConstructorInvocation_element;
-
- @VariantId(38, variant: LinkedNodeKind.superConstructorInvocation)
- LinkedNodeTypeSubstitution get superConstructorInvocation_substitution;
-
- @VariantId(6, variant: LinkedNodeKind.switchCase)
- LinkedNode get switchCase_expression;
-
- @VariantId(3, variantList: [
- LinkedNodeKind.switchCase,
- LinkedNodeKind.switchDefault,
- ])
- List<LinkedNode> get switchMember_labels;
-
- @VariantId(4, variantList: [
- LinkedNodeKind.switchCase,
- LinkedNodeKind.switchDefault,
- ])
- List<LinkedNode> get switchMember_statements;
-
- @VariantId(7, variant: LinkedNodeKind.switchStatement)
- LinkedNode get switchStatement_expression;
-
- @VariantId(2, variant: LinkedNodeKind.switchStatement)
- List<LinkedNode> get switchStatement_members;
-
- @VariantId(6, variant: LinkedNodeKind.throwExpression)
- LinkedNode get throwExpression_expression;
-
- @VariantId(32, variantList: [
- LinkedNodeKind.methodDeclaration,
- LinkedNodeKind.simpleFormalParameter,
- LinkedNodeKind.variableDeclaration,
- ])
- TopLevelInferenceError get topLevelTypeInferenceError;
-
- @VariantId(6, variant: LinkedNodeKind.topLevelVariableDeclaration)
- LinkedNode get topLevelVariableDeclaration_variableList;
-
- @VariantId(6, variant: LinkedNodeKind.tryStatement)
- LinkedNode get tryStatement_body;
-
- @VariantId(2, variant: LinkedNodeKind.tryStatement)
- List<LinkedNode> get tryStatement_catchClauses;
-
- @VariantId(7, variant: LinkedNodeKind.tryStatement)
- LinkedNode get tryStatement_finallyBlock;
-
- @VariantId(27, variantList: [
- LinkedNodeKind.functionTypeAlias,
- LinkedNodeKind.genericTypeAlias,
- ])
- bool get typeAlias_hasSelfReference;
-
- @VariantId(2, variant: LinkedNodeKind.typeArgumentList)
- List<LinkedNode> get typeArgumentList_arguments;
-
- @VariantId(2, variantList: [
- LinkedNodeKind.listLiteral,
- LinkedNodeKind.setOrMapLiteral,
- ])
- List<LinkedNode> get typedLiteral_typeArguments;
-
- @VariantId(6, variant: LinkedNodeKind.typeName)
- LinkedNode get typeName_name;
-
- @VariantId(23, variant: LinkedNodeKind.typeName)
- LinkedNodeType get typeName_type;
-
- @VariantId(2, variant: LinkedNodeKind.typeName)
- List<LinkedNode> get typeName_typeArguments;
-
- @VariantId(6, variant: LinkedNodeKind.typeParameter)
- LinkedNode get typeParameter_bound;
-
- @VariantId(23, variant: LinkedNodeKind.typeParameter)
- LinkedNodeType get typeParameter_defaultType;
-
- @VariantId(15, variant: LinkedNodeKind.typeParameter)
- int get typeParameter_variance;
-
- @VariantId(2, variant: LinkedNodeKind.typeParameterList)
- List<LinkedNode> get typeParameterList_typeParameters;
-
- @VariantId(11, variantList: [
- LinkedNodeKind.classDeclaration,
- ])
- LinkedNode get unused11;
-
- @VariantId(14, variantList: [
- LinkedNodeKind.exportDirective,
- LinkedNodeKind.importDirective,
- LinkedNodeKind.partDirective,
- ])
- LinkedNode get uriBasedDirective_uri;
-
- @VariantId(22, variantList: [
- LinkedNodeKind.exportDirective,
- LinkedNodeKind.importDirective,
- LinkedNodeKind.partDirective,
- ])
- String get uriBasedDirective_uriContent;
-
- @VariantId(19, variantList: [
- LinkedNodeKind.exportDirective,
- LinkedNodeKind.importDirective,
- LinkedNodeKind.partDirective,
- ])
- int get uriBasedDirective_uriElement;
-
- @VariantId(6, variant: LinkedNodeKind.variableDeclaration)
- LinkedNode get variableDeclaration_initializer;
-
- @VariantId(6, variant: LinkedNodeKind.variableDeclarationList)
- LinkedNode get variableDeclarationList_type;
-
- @VariantId(2, variant: LinkedNodeKind.variableDeclarationList)
- List<LinkedNode> get variableDeclarationList_variables;
-
- @VariantId(6, variant: LinkedNodeKind.variableDeclarationStatement)
- LinkedNode get variableDeclarationStatement_variables;
-
- @VariantId(6, variant: LinkedNodeKind.whileStatement)
- LinkedNode get whileStatement_body;
-
- @VariantId(7, variant: LinkedNodeKind.whileStatement)
- LinkedNode get whileStatement_condition;
-
- @VariantId(2, variant: LinkedNodeKind.withClause)
- List<LinkedNode> get withClause_mixinTypes;
-
- @VariantId(6, variant: LinkedNodeKind.yieldStatement)
- LinkedNode get yieldStatement_expression;
-}
-
-/// Information about a group of libraries linked together, for example because
-/// they form a single cycle, or because they represent a single build artifact.
-@TopLevel('LNBn')
-abstract class LinkedNodeBundle extends base.SummaryClass {
- factory LinkedNodeBundle.fromBuffer(List<int> buffer) =>
- generated.readLinkedNodeBundle(buffer);
- @Id(1)
- List<LinkedNodeLibrary> get libraries;
-
- /// The shared list of references used in the [libraries].
- @Id(0)
- LinkedNodeReferences get references;
-}
-
-/// Types of comments.
-enum LinkedNodeCommentType { block, documentation, endOfLine }
-
-/// Kinds of formal parameters.
-enum LinkedNodeFormalParameterKind {
- requiredPositional,
- optionalPositional,
- optionalNamed,
- requiredNamed
-}
-
-/// Kinds of [LinkedNode].
-enum LinkedNodeKind {
- adjacentStrings,
- annotation,
- argumentList,
- asExpression,
- assertInitializer,
- assertStatement,
- assignmentExpression,
- awaitExpression,
- binaryExpression,
- block,
- blockFunctionBody,
- booleanLiteral,
- breakStatement,
- cascadeExpression,
- catchClause,
- classDeclaration,
- classTypeAlias,
- comment,
- commentReference,
- compilationUnit,
- conditionalExpression,
- configuration,
- constructorDeclaration,
- constructorFieldInitializer,
- constructorName,
- continueStatement,
- declaredIdentifier,
- defaultFormalParameter,
- doubleLiteral,
- doStatement,
- dottedName,
- emptyFunctionBody,
- emptyStatement,
- enumConstantDeclaration,
- enumDeclaration,
- exportDirective,
- expressionFunctionBody,
- expressionStatement,
- extendsClause,
- extensionDeclaration,
- fieldDeclaration,
- fieldFormalParameter,
- formalParameterList,
- forEachPartsWithDeclaration,
- forEachPartsWithIdentifier,
- forElement,
- forPartsWithDeclarations,
- forPartsWithExpression,
- forStatement,
- functionDeclaration,
- functionDeclarationStatement,
- functionExpression,
- functionExpressionInvocation,
- functionTypeAlias,
- functionTypedFormalParameter,
- genericFunctionType,
- genericTypeAlias,
- hideCombinator,
- ifElement,
- ifStatement,
- implementsClause,
- importDirective,
- instanceCreationExpression,
- indexExpression,
- integerLiteral,
- interpolationExpression,
- interpolationString,
- isExpression,
- label,
- labeledStatement,
- libraryDirective,
- libraryIdentifier,
- listLiteral,
- mapLiteralEntry,
- methodDeclaration,
- methodInvocation,
- mixinDeclaration,
- namedExpression,
- nativeClause,
- nativeFunctionBody,
- nullLiteral,
- onClause,
- parenthesizedExpression,
- partDirective,
- partOfDirective,
- postfixExpression,
- prefixExpression,
- prefixedIdentifier,
- propertyAccess,
- redirectingConstructorInvocation,
- rethrowExpression,
- returnStatement,
- setOrMapLiteral,
- showCombinator,
- simpleFormalParameter,
- simpleIdentifier,
- simpleStringLiteral,
- spreadElement,
- stringInterpolation,
- superConstructorInvocation,
- superExpression,
- switchCase,
- switchDefault,
- switchStatement,
- symbolLiteral,
- thisExpression,
- throwExpression,
- topLevelVariableDeclaration,
- tryStatement,
- typeArgumentList,
- typeName,
- typeParameter,
- typeParameterList,
- variableDeclaration,
- variableDeclarationList,
- variableDeclarationStatement,
- whileStatement,
- withClause,
- yieldStatement,
- extensionOverride,
-}
-
-/// Information about a single library in a [LinkedNodeBundle].
-abstract class LinkedNodeLibrary extends base.SummaryClass {
- @Id(2)
- List<int> get exports;
-
- @Id(3)
- String get name;
-
- @Id(5)
- int get nameLength;
-
- @Id(4)
- int get nameOffset;
-
- @Id(1)
- List<LinkedNodeUnit> get units;
-
- @Id(0)
- String get uriStr;
-}
-
-/// Flattened tree of declarations referenced from [LinkedNode]s.
-abstract class LinkedNodeReferences extends base.SummaryClass {
- @Id(1)
- List<String> get name;
-
- @Id(0)
- List<int> get parent;
-}
-
-/// Information about a Dart type.
-abstract class LinkedNodeType extends base.SummaryClass {
- @Id(0)
- List<LinkedNodeTypeFormalParameter> get functionFormalParameters;
-
- @Id(1)
- LinkedNodeType get functionReturnType;
-
- /// The typedef this function type is created for.
- @Id(9)
- int get functionTypedef;
-
- @Id(10)
- List<LinkedNodeType> get functionTypedefTypeArguments;
-
- @Id(2)
- List<LinkedNodeTypeTypeParameter> get functionTypeParameters;
-
- /// Reference to a [LinkedNodeReferences].
- @Id(3)
- int get interfaceClass;
-
- @Id(4)
- List<LinkedNodeType> get interfaceTypeArguments;
-
- @Id(5)
- LinkedNodeTypeKind get kind;
-
- @Id(8)
- EntityRefNullabilitySuffix get nullabilitySuffix;
-
- @Id(6)
- int get typeParameterElement;
-
- @Id(7)
- int get typeParameterId;
-}
-
-/// Information about a formal parameter in a function type.
-abstract class LinkedNodeTypeFormalParameter extends base.SummaryClass {
- @Id(0)
- LinkedNodeFormalParameterKind get kind;
-
- @Id(1)
- String get name;
-
- @Id(2)
- LinkedNodeType get type;
-}
-
-/// Kinds of [LinkedNodeType]s.
-enum LinkedNodeTypeKind {
- dynamic_,
- function,
- interface,
- never,
- typeParameter,
- void_
-}
-
-/// Information about a type substitution.
-abstract class LinkedNodeTypeSubstitution extends base.SummaryClass {
- @Id(2)
- bool get isLegacy;
-
- @Id(1)
- List<LinkedNodeType> get typeArguments;
-
- @Id(0)
- List<int> get typeParameters;
-}
-
-/// Information about a type parameter in a function type.
-abstract class LinkedNodeTypeTypeParameter extends base.SummaryClass {
- @Id(1)
- LinkedNodeType get bound;
-
- @Id(0)
- String get name;
-}
-
-/// Information about a single library in a [LinkedNodeLibrary].
-abstract class LinkedNodeUnit extends base.SummaryClass {
- @Id(2)
- bool get isSynthetic;
-
- @Id(1)
- LinkedNode get node;
-
- /// If the unit is a part, the URI specified in the `part` directive.
- /// Otherwise empty.
- @Id(3)
- String get partUriStr;
-
- /// The absolute URI.
- @Id(0)
- String get uriStr;
-}
-
/// Summary information about a package.
@TopLevel('PBdl')
abstract class PackageBundle extends base.SummaryClass {
@@ -1900,170 +602,7 @@
/// The version 2 of the summary.
@Id(0)
- LinkedNodeBundle get bundle2;
-
- /// The SDK specific data, if this bundle is for SDK.
- @Id(1)
- PackageBundleSdk get sdk;
-}
-
-/// Summary information about a package.
-abstract class PackageBundleSdk extends base.SummaryClass {
- /// The content of the `allowed_experiments.json` from SDK.
- @Id(0)
- String get allowedExperimentsJson;
-
- /// The language version of the SDK.
- @Id(1)
- LinkedLanguageVersion get languageVersion;
-}
-
-/// Summary information about a top-level type inference error.
-abstract class TopLevelInferenceError extends base.SummaryClass {
- /// The [kind] specific arguments.
- @Id(1)
- List<String> get arguments;
-
- /// The kind of the error.
- @Id(0)
- TopLevelInferenceErrorKind get kind;
-}
-
-/// Enum used to indicate the kind of the error during top-level inference.
-enum TopLevelInferenceErrorKind {
- assignment,
- instanceGetter,
- dependencyCycle,
- overrideConflictFieldType,
- overrideNoCombinedSuperSignature,
-}
-
-@Variant('kind')
-abstract class UnlinkedInformativeData extends base.SummaryClass {
- @VariantId(2, variantList: [
- LinkedNodeKind.classDeclaration,
- LinkedNodeKind.classTypeAlias,
- LinkedNodeKind.compilationUnit,
- LinkedNodeKind.constructorDeclaration,
- LinkedNodeKind.defaultFormalParameter,
- LinkedNodeKind.enumConstantDeclaration,
- LinkedNodeKind.enumDeclaration,
- LinkedNodeKind.extensionDeclaration,
- LinkedNodeKind.fieldFormalParameter,
- LinkedNodeKind.functionDeclaration,
- LinkedNodeKind.functionTypeAlias,
- LinkedNodeKind.functionTypedFormalParameter,
- LinkedNodeKind.genericTypeAlias,
- LinkedNodeKind.methodDeclaration,
- LinkedNodeKind.mixinDeclaration,
- LinkedNodeKind.simpleFormalParameter,
- LinkedNodeKind.typeParameter,
- LinkedNodeKind.variableDeclaration,
- ])
- int get codeLength;
-
- @VariantId(3, variantList: [
- LinkedNodeKind.classDeclaration,
- LinkedNodeKind.classTypeAlias,
- LinkedNodeKind.compilationUnit,
- LinkedNodeKind.constructorDeclaration,
- LinkedNodeKind.defaultFormalParameter,
- LinkedNodeKind.enumConstantDeclaration,
- LinkedNodeKind.enumDeclaration,
- LinkedNodeKind.extensionDeclaration,
- LinkedNodeKind.fieldFormalParameter,
- LinkedNodeKind.functionDeclaration,
- LinkedNodeKind.functionTypeAlias,
- LinkedNodeKind.functionTypedFormalParameter,
- LinkedNodeKind.genericTypeAlias,
- LinkedNodeKind.methodDeclaration,
- LinkedNodeKind.mixinDeclaration,
- LinkedNodeKind.simpleFormalParameter,
- LinkedNodeKind.typeParameter,
- LinkedNodeKind.variableDeclaration,
- ])
- int get codeOffset;
-
- @VariantId(9, variantList: [
- LinkedNodeKind.hideCombinator,
- LinkedNodeKind.showCombinator,
- ])
- int get combinatorEnd;
-
- @VariantId(8, variantList: [
- LinkedNodeKind.hideCombinator,
- LinkedNodeKind.showCombinator,
- ])
- int get combinatorKeywordOffset;
-
- /// Offsets of the first character of each line in the source code.
- @VariantId(7, variant: LinkedNodeKind.compilationUnit)
- List<int> get compilationUnit_lineStarts;
-
- @VariantId(6, variant: LinkedNodeKind.constructorDeclaration)
- int get constructorDeclaration_periodOffset;
-
- @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,
- LinkedNodeKind.libraryDirective,
- LinkedNodeKind.partDirective,
- LinkedNodeKind.partOfDirective,
- ])
- int get directiveKeywordOffset;
-
- @VariantId(4, variantList: [
- LinkedNodeKind.classDeclaration,
- LinkedNodeKind.classTypeAlias,
- LinkedNodeKind.constructorDeclaration,
- LinkedNodeKind.enumDeclaration,
- LinkedNodeKind.enumConstantDeclaration,
- LinkedNodeKind.extensionDeclaration,
- LinkedNodeKind.fieldDeclaration,
- LinkedNodeKind.functionDeclaration,
- LinkedNodeKind.functionTypeAlias,
- LinkedNodeKind.genericTypeAlias,
- LinkedNodeKind.libraryDirective,
- LinkedNodeKind.methodDeclaration,
- LinkedNodeKind.mixinDeclaration,
- LinkedNodeKind.topLevelVariableDeclaration,
- ])
- List<String> get documentationComment_tokens;
-
- @VariantId(8, variant: LinkedNodeKind.importDirective)
- int get importDirective_prefixOffset;
-
- /// The kind of the node.
- @Id(0)
- LinkedNodeKind get kind;
-
- @VariantId(1, variantList: [
- LinkedNodeKind.classDeclaration,
- LinkedNodeKind.classTypeAlias,
- LinkedNodeKind.constructorDeclaration,
- LinkedNodeKind.enumConstantDeclaration,
- LinkedNodeKind.enumDeclaration,
- LinkedNodeKind.extensionDeclaration,
- LinkedNodeKind.fieldFormalParameter,
- LinkedNodeKind.functionDeclaration,
- LinkedNodeKind.functionTypedFormalParameter,
- LinkedNodeKind.functionTypeAlias,
- LinkedNodeKind.genericTypeAlias,
- LinkedNodeKind.methodDeclaration,
- LinkedNodeKind.mixinDeclaration,
- LinkedNodeKind.simpleFormalParameter,
- LinkedNodeKind.typeParameter,
- LinkedNodeKind.variableDeclaration,
- ])
- int get nameOffset;
+ int get fake;
}
/// Unlinked summary information about a namespace directive.
@@ -2095,153 +634,6 @@
String get value;
}
-/// Enum of token types, corresponding to AST token types.
-enum UnlinkedTokenType {
- NOTHING,
- ABSTRACT,
- AMPERSAND,
- AMPERSAND_AMPERSAND,
- AMPERSAND_EQ,
- AS,
- ASSERT,
- ASYNC,
- AT,
- AWAIT,
- BACKPING,
- BACKSLASH,
- BANG,
- BANG_EQ,
- BANG_EQ_EQ,
- BAR,
- BAR_BAR,
- BAR_EQ,
- BREAK,
- CARET,
- CARET_EQ,
- CASE,
- CATCH,
- CLASS,
- CLOSE_CURLY_BRACKET,
- CLOSE_PAREN,
- CLOSE_SQUARE_BRACKET,
- COLON,
- COMMA,
- CONST,
- CONTINUE,
- COVARIANT,
- DEFAULT,
- DEFERRED,
- DO,
- DOUBLE,
- DYNAMIC,
- ELSE,
- ENUM,
- EOF,
- EQ,
- EQ_EQ,
- EQ_EQ_EQ,
- EXPORT,
- EXTENDS,
- EXTERNAL,
- FACTORY,
- FALSE,
- FINAL,
- FINALLY,
- FOR,
- FUNCTION,
- FUNCTION_KEYWORD,
- GET,
- GT,
- GT_EQ,
- GT_GT,
- GT_GT_EQ,
- GT_GT_GT,
- GT_GT_GT_EQ,
- HASH,
- HEXADECIMAL,
- HIDE,
- IDENTIFIER,
- IF,
- IMPLEMENTS,
- IMPORT,
- IN,
- INDEX,
- INDEX_EQ,
- INT,
- INTERFACE,
- IS,
- LATE,
- LIBRARY,
- LT,
- LT_EQ,
- LT_LT,
- LT_LT_EQ,
- MINUS,
- MINUS_EQ,
- MINUS_MINUS,
- MIXIN,
- MULTI_LINE_COMMENT,
- NATIVE,
- NEW,
- NULL,
- OF,
- ON,
- OPEN_CURLY_BRACKET,
- OPEN_PAREN,
- OPEN_SQUARE_BRACKET,
- OPERATOR,
- PART,
- PATCH,
- PERCENT,
- PERCENT_EQ,
- PERIOD,
- PERIOD_PERIOD,
- PERIOD_PERIOD_PERIOD,
- PERIOD_PERIOD_PERIOD_QUESTION,
- PLUS,
- PLUS_EQ,
- PLUS_PLUS,
- QUESTION,
- QUESTION_PERIOD,
- QUESTION_QUESTION,
- QUESTION_QUESTION_EQ,
- REQUIRED,
- RETHROW,
- RETURN,
- SCRIPT_TAG,
- SEMICOLON,
- SET,
- SHOW,
- SINGLE_LINE_COMMENT,
- SLASH,
- SLASH_EQ,
- SOURCE,
- STAR,
- STAR_EQ,
- STATIC,
- STRING,
- STRING_INTERPOLATION_EXPRESSION,
- STRING_INTERPOLATION_IDENTIFIER,
- SUPER,
- SWITCH,
- SYNC,
- THIS,
- THROW,
- TILDE,
- TILDE_SLASH,
- TILDE_SLASH_EQ,
- TRUE,
- TRY,
- TYPEDEF,
- VAR,
- VOID,
- WHILE,
- WITH,
- YIELD,
- INOUT,
- OUT,
-}
-
/// Unlinked summary information about a compilation unit.
@TopLevel('UUN2')
abstract class UnlinkedUnit2 extends base.SummaryClass {
@@ -2269,16 +661,13 @@
@Id(2)
List<UnlinkedNamespaceDirective> get imports;
- @Id(7)
- List<UnlinkedInformativeData> get informativeData;
-
/// Offsets of the first character of each line in the source code.
@informative
@Id(5)
List<int> get lineStarts;
/// URI of the `part of` directive.
- @Id(8)
+ @Id(7)
String get partOfUri;
/// URIs of `part` directives.
diff --git a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
index 0aa30cd..b206f48 100644
--- a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
@@ -9,7 +9,7 @@
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary2/package_bundle_format.dart';
/// A [ConflictingSummaryException] indicates that two different summaries
/// provided to a [SummaryDataStore] conflict.
@@ -109,8 +109,8 @@
/// summary package bundles. It contains maps which can be used to find linked
/// and unlinked summaries by URI.
class SummaryDataStore {
- /// List of all [PackageBundle]s.
- final List<PackageBundle> bundles = <PackageBundle>[];
+ /// List of all [PackageBundleReader]s.
+ final List<PackageBundleReader> bundles = [];
/// Map from the URI of a unit to the summary path that contained it.
final Map<String, String> uriToSummaryPath = <String, String>{};
@@ -126,19 +126,17 @@
}
/// Add the given [bundle] loaded from the file with the given [path].
- void addBundle(String path, PackageBundle bundle) {
+ void addBundle(String path, PackageBundleReader bundle) {
bundles.add(bundle);
- if (bundle.bundle2 != null) {
- for (var library in bundle.bundle2.libraries) {
- var libraryUri = library.uriStr;
- _libraryUris.add(libraryUri);
- for (var unit in library.units) {
- var unitUri = unit.uriStr;
- uriToSummaryPath[unitUri] = path;
- if (unitUri != libraryUri) {
- _partUris.add(unitUri);
- }
+ for (var library in bundle.libraries) {
+ var libraryUri = library.uriStr;
+ _libraryUris.add(libraryUri);
+ for (var unit in library.units) {
+ var unitUri = unit.uriStr;
+ uriToSummaryPath[unitUri] = path;
+ if (unitUri != libraryUri) {
+ _partUris.add(unitUri);
}
}
}
@@ -162,15 +160,15 @@
}
void _fillMaps(String path, ResourceProvider resourceProvider) {
- List<int> buffer;
+ List<int> bytes;
if (resourceProvider != null) {
var file = resourceProvider.getFile(path);
- buffer = file.readAsBytesSync();
+ bytes = file.readAsBytesSync();
} else {
io.File file = io.File(path);
- buffer = file.readAsBytesSync();
+ bytes = file.readAsBytesSync();
}
- PackageBundle bundle = PackageBundle.fromBuffer(buffer);
+ var bundle = PackageBundleReader(bytes);
addBundle(path, bundle);
}
}
diff --git a/pkg/analyzer/lib/src/summary/summarize_elements.dart b/pkg/analyzer/lib/src/summary/summarize_elements.dart
deleted file mode 100644
index 1c5a27b..0000000
--- a/pkg/analyzer/lib/src/summary/summarize_elements.dart
+++ /dev/null
@@ -1,23 +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:analyzer/src/summary/format.dart';
-
-/// Object that gathers information uses it to assemble a new
-/// [PackageBundleBuilder].
-class PackageBundleAssembler {
- LinkedNodeBundleBuilder _bundle2;
-
- /// Assemble a new [PackageBundleBuilder] using the gathered information.
- PackageBundleBuilder assemble() {
- return PackageBundleBuilder(bundle2: _bundle2);
- }
-
- void setBundle2(LinkedNodeBundleBuilder bundle2) {
- if (_bundle2 != null) {
- throw StateError('Bundle2 may be set only once.');
- }
- _bundle2 = bundle2;
- }
-}
diff --git a/pkg/analyzer/lib/src/summary/summary_sdk.dart b/pkg/analyzer/lib/src/summary/summary_sdk.dart
index 809db0f..2d0bd29 100644
--- a/pkg/analyzer/lib/src/summary/summary_sdk.dart
+++ b/pkg/analyzer/lib/src/summary/summary_sdk.dart
@@ -5,8 +5,8 @@
import 'package:analyzer/file_system/file_system.dart' show ResourceProvider;
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart' show Source;
-import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/package_bundle_reader.dart';
+import 'package:analyzer/src/summary2/package_bundle_format.dart';
import 'package:pub_semver/pub_semver.dart';
/// An implementation of [DartSdk] which provides analysis results for `dart:`
@@ -16,7 +16,7 @@
class SummaryBasedDartSdk implements DartSdk {
SummaryDataStore _dataStore;
InSummaryUriResolver _uriResolver;
- PackageBundle _bundle;
+ PackageBundleReader _bundle;
ResourceProvider resourceProvider;
SummaryBasedDartSdk(String summaryPath, bool _, {this.resourceProvider}) {
@@ -26,26 +26,21 @@
_bundle = _dataStore.bundles.single;
}
- SummaryBasedDartSdk.fromBundle(bool _, PackageBundle bundle,
- {this.resourceProvider}) {
- _dataStore = SummaryDataStore([], resourceProvider: resourceProvider);
- _dataStore.addBundle('dart_sdk.sum', bundle);
- _uriResolver = InSummaryUriResolver(resourceProvider, _dataStore);
- _bundle = bundle;
- }
-
@override
String get allowedExperimentsJson {
return _bundle.sdk.allowedExperimentsJson;
}
- /// Return the [PackageBundle] for this SDK, not `null`.
- PackageBundle get bundle => _bundle;
+ /// Return the [PackageBundleReader] for this SDK, not `null`.
+ PackageBundleReader get bundle => _bundle;
@override
Version get languageVersion {
- var version = _bundle.sdk.languageVersion;
- return Version(version.major, version.minor, 0);
+ return Version(
+ _bundle.sdk.languageVersionMajor,
+ _bundle.sdk.languageVersionMinor,
+ 0,
+ );
}
@override
diff --git a/pkg/analyzer/lib/src/summary2/apply_resolution.dart b/pkg/analyzer/lib/src/summary2/apply_resolution.dart
new file mode 100644
index 0000000..dfbdab2
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/apply_resolution.dart
@@ -0,0 +1,1059 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast.dart';
+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/element.dart';
+import 'package:analyzer/src/dart/resolver/variance.dart';
+import 'package:analyzer/src/summary2/bundle_reader.dart';
+import 'package:analyzer/src/summary2/linked_unit_context.dart';
+import 'package:analyzer/src/task/inference_error.dart';
+
+class ApplyResolutionVisitor extends ThrowingAstVisitor<void> {
+ final LinkedUnitContext _unitContext;
+ final LinkedResolutionReader _resolution;
+
+ /// The stack of [TypeParameterElement]s and [ParameterElement] that are
+ /// available in the scope of [_nextElement] and [_nextType].
+ ///
+ /// This stack is shared with [_resolution].
+ final List<Element> _localElements;
+
+ final List<ElementImpl> _enclosingElements = [];
+
+ ApplyResolutionVisitor(
+ this._unitContext,
+ this._localElements,
+ this._resolution,
+ ) {
+ _enclosingElements.add(_unitContext.unit.declaredElement as ElementImpl);
+ }
+
+ /// TODO(scheglov) make private
+ void addParentTypeParameters(AstNode node) {
+ var enclosing = node.parent;
+ if (enclosing is ClassOrMixinDeclaration) {
+ var typeParameterList = enclosing.typeParameters;
+ if (typeParameterList == null) return;
+
+ for (var typeParameter in typeParameterList.typeParameters) {
+ var element = typeParameter.declaredElement;
+ _localElements.add(element);
+ }
+ } else if (enclosing is ExtensionDeclaration) {
+ var typeParameterList = enclosing.typeParameters;
+ if (typeParameterList == null) return;
+
+ for (var typeParameter in typeParameterList.typeParameters) {
+ var element = typeParameter.declaredElement;
+ _localElements.add(element);
+ }
+ } else if (enclosing is VariableDeclarationList) {
+ var enclosing2 = enclosing.parent;
+ if (enclosing2 is FieldDeclaration) {
+ return addParentTypeParameters(enclosing2);
+ } else if (enclosing2 is TopLevelVariableDeclaration) {
+ return;
+ } else {
+ throw UnimplementedError('${enclosing2.runtimeType}');
+ }
+ } else {
+ throw UnimplementedError('${enclosing.runtimeType}');
+ }
+ }
+
+ @override
+ void visitAdjacentStrings(AdjacentStrings node) {
+ node.strings.accept(this);
+ // TODO(scheglov) type?
+ }
+
+ @override
+ void visitAnnotation(Annotation node) {
+ node.name.accept(this);
+ node.constructorName?.accept(this);
+ node.arguments?.accept(this);
+ node.element = _nextElement();
+ }
+
+ @override
+ void visitArgumentList(ArgumentList node) {
+ node.arguments.accept(this);
+ }
+
+ @override
+ void visitAsExpression(AsExpression node) {
+ node.expression.accept(this);
+ node.type.accept(this);
+ _expression(node);
+ }
+
+ @override
+ void visitAssertInitializer(AssertInitializer node) {
+ node.condition.accept(this);
+ node.message?.accept(this);
+ }
+
+ @override
+ void visitAssignmentExpression(AssignmentExpression node) {
+ var nodeImpl = node as AssignmentExpressionImpl;
+ node.leftHandSide.accept(this);
+ node.rightHandSide.accept(this);
+ node.staticElement = _nextElement();
+ nodeImpl.readElement = _nextElement();
+ nodeImpl.readType = _nextType();
+ nodeImpl.writeElement = _nextElement();
+ nodeImpl.writeType = _nextType();
+ _expression(node);
+ }
+
+ @override
+ void visitBinaryExpression(BinaryExpression node) {
+ node.leftOperand.accept(this);
+ node.rightOperand.accept(this);
+
+ node.staticElement = _nextElement();
+ node.staticType = _nextType();
+ }
+
+ @override
+ void visitBooleanLiteral(BooleanLiteral node) {
+ node.staticType = _nextType();
+ }
+
+ @override
+ void visitCascadeExpression(CascadeExpression node) {
+ node.target.accept(this);
+ node.cascadeSections.accept(this);
+ node.staticType = node.target.staticType;
+ }
+
+ @override
+ visitClassDeclaration(ClassDeclaration node) {
+ _assertNoLocalElements();
+
+ var element = node.declaredElement as ClassElementImpl;
+ element.isSimplyBounded = _resolution.readByte() != 0;
+ _enclosingElements.add(element);
+
+ node.typeParameters?.accept(this);
+ node.extendsClause?.accept(this);
+ node.nativeClause?.accept(this);
+ node.withClause?.accept(this);
+ node.implementsClause?.accept(this);
+ _namedCompilationUnitMember(node);
+
+ _enclosingElements.removeLast();
+ }
+
+ @override
+ void visitClassTypeAlias(ClassTypeAlias node) {
+ _assertNoLocalElements();
+ var element = node.declaredElement as ClassElementImpl;
+ _enclosingElements.add(element);
+
+ element.isSimplyBounded = _resolution.readByte() != 0;
+ node.typeParameters?.accept(this);
+ node.superclass?.accept(this);
+ node.withClause?.accept(this);
+ node.implementsClause?.accept(this);
+ node.metadata?.accept(this);
+
+ _enclosingElements.removeLast();
+ }
+
+ @override
+ void visitConditionalExpression(ConditionalExpression node) {
+ node.condition.accept(this);
+ node.thenExpression.accept(this);
+ node.elseExpression.accept(this);
+ node.staticType = _nextType();
+ }
+
+ @override
+ void visitConfiguration(Configuration node) {
+ node.name?.accept(this);
+ node.value?.accept(this);
+ node.uri?.accept(this);
+ }
+
+ @override
+ void visitConstructorDeclaration(ConstructorDeclaration node) {
+ _assertNoLocalElements();
+ _pushEnclosingClassTypeParameters(node);
+
+ var element = node.declaredElement as ConstructorElementImpl;
+ _enclosingElements.add(element.enclosingElement);
+ _enclosingElements.add(element);
+
+ node.returnType?.accept(this);
+ node.parameters?.accept(this);
+
+ for (var parameter in node.parameters.parameters) {
+ _localElements.add(parameter.declaredElement);
+ }
+
+ node.initializers?.accept(this);
+ node.redirectedConstructor?.accept(this);
+ node.metadata?.accept(this);
+
+ _enclosingElements.removeLast();
+ _enclosingElements.removeLast();
+ }
+
+ @override
+ void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+ node.fieldName.accept(this);
+ node.expression.accept(this);
+ }
+
+ @override
+ void visitConstructorName(ConstructorName node) {
+ node.type.accept(this);
+ node.name?.accept(this);
+ node.staticElement = _nextElement();
+ }
+
+ @override
+ void visitDeclaredIdentifier(DeclaredIdentifier node) {
+ node.type?.accept(this);
+ // node.identifier.accept(this);
+ _declaration(node);
+ }
+
+ @override
+ visitDefaultFormalParameter(DefaultFormalParameter node) {
+ var nodeImpl = node as DefaultFormalParameterImpl;
+
+ var enclosing = _enclosingElements.last;
+ var name = node.identifier?.name ?? '';
+ var reference = node.isNamed && enclosing.reference != null
+ ? enclosing.reference.getChild('@parameter').getChild(name)
+ : null;
+ ParameterElementImpl element;
+ if (node.parameter is FieldFormalParameter) {
+ element = DefaultFieldFormalParameterElementImpl.forLinkedNode(
+ enclosing, reference, node);
+ } else {
+ element =
+ DefaultParameterElementImpl.forLinkedNode(enclosing, reference, node);
+ }
+
+ var summaryData = nodeImpl.summaryData as SummaryDataForFormalParameter;
+ element.setCodeRange(summaryData.codeOffset, summaryData.codeLength);
+
+ node.parameter.accept(this);
+ node.defaultValue?.accept(this);
+ }
+
+ @override
+ void visitDottedName(DottedName node) {
+ node.components.accept(this);
+ }
+
+ @override
+ void visitDoubleLiteral(DoubleLiteral node) {
+ // TODO(scheglov) type?
+ }
+
+ @override
+ void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
+ node.metadata?.accept(this);
+ }
+
+ @override
+ void visitEnumDeclaration(EnumDeclaration node) {
+ node.constants.accept(this);
+ node.metadata?.accept(this);
+ }
+
+ @override
+ void visitExportDirective(ExportDirective node) {
+ _namespaceDirective(node);
+ (node.element as ExportElementImpl).exportedLibrary = _nextElement();
+ }
+
+ @override
+ void visitExpressionFunctionBody(ExpressionFunctionBody node) {
+ node.expression.accept(this);
+ }
+
+ @override
+ visitExtendsClause(ExtendsClause node) {
+ node.superclass.accept(this);
+ }
+
+ @override
+ void visitExtensionDeclaration(ExtensionDeclaration node) {
+ _assertNoLocalElements();
+
+ var element = node.declaredElement as ExtensionElementImpl;
+ _enclosingElements.add(element);
+
+ node.typeParameters?.accept(this);
+ node.extendedType?.accept(this);
+ node.metadata?.accept(this);
+
+ _enclosingElements.removeLast();
+ }
+
+ @override
+ void visitExtensionOverride(ExtensionOverride node) {
+ node.extensionName.accept(this);
+ node.typeArguments?.accept(this);
+ node.argumentList.accept(this);
+ (node as ExtensionOverrideImpl).extendedType = _nextType();
+ // TODO(scheglov) typeArgumentTypes?
+ }
+
+ @override
+ void visitFieldDeclaration(FieldDeclaration node) {
+ _assertNoLocalElements();
+ _pushEnclosingClassTypeParameters(node);
+
+ node.fields.accept(this);
+ node.metadata?.accept(this);
+ }
+
+ @override
+ void visitFieldFormalParameter(FieldFormalParameter node) {
+ ParameterElement element;
+ if (node.parent is! DefaultFormalParameter) {
+ var enclosing = _enclosingElements.last;
+ element =
+ FieldFormalParameterElementImpl.forLinkedNode(enclosing, null, node);
+ }
+
+ var localElementsLength = _localElements.length;
+
+ node.typeParameters?.accept(this);
+ node.type?.accept(this);
+ node.parameters?.accept(this);
+ _normalFormalParameter(node, element);
+
+ _localElements.length = localElementsLength;
+ }
+
+ @override
+ void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
+ node.loopVariable.accept(this);
+ _forEachParts(node);
+ }
+
+ @override
+ void visitForElement(ForElement node) {
+ node.body.accept(this);
+ node.forLoopParts.accept(this);
+ }
+
+ @override
+ visitFormalParameterList(FormalParameterList node) {
+ node.parameters.accept(this);
+ }
+
+ @override
+ void visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
+ for (var variable in node.variables.variables) {
+ var nameNode = variable.name;
+ nameNode.staticElement = LocalVariableElementImpl(
+ nameNode.name,
+ nameNode.offset,
+ );
+ }
+ node.variables.accept(this);
+ _forParts(node);
+ }
+
+ @override
+ void visitFunctionDeclaration(FunctionDeclaration node) {
+ _assertNoLocalElements();
+
+ var element = node.declaredElement as ExecutableElementImpl;
+ assert(element != null);
+
+ _enclosingElements.add(element);
+
+ node.functionExpression.accept(this);
+ node.returnType?.accept(this);
+
+ node.metadata?.accept(this);
+ element.returnType = _nextType();
+ }
+
+ @override
+ void visitFunctionExpression(FunctionExpression node) {
+ node.typeParameters?.accept(this);
+ node.parameters?.accept(this);
+ }
+
+ @override
+ void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+ node.function.accept(this);
+ _invocationExpression(node);
+ }
+
+ @override
+ void visitFunctionTypeAlias(FunctionTypeAlias node) {
+ _assertNoLocalElements();
+
+ var element = node.declaredElement as FunctionTypeAliasElementImpl;
+ _enclosingElements.add(element);
+
+ node.typeParameters?.accept(this);
+
+ _enclosingElements.add(element.function);
+ node.returnType?.accept(this);
+ node.parameters?.accept(this);
+ _enclosingElements.removeLast();
+
+ node.metadata?.accept(this);
+
+ element.function.returnType = _nextType();
+ element.isSimplyBounded = _resolution.readByte() != 0;
+ element.hasSelfReference = _resolution.readByte() != 0;
+
+ _enclosingElements.removeLast();
+ }
+
+ @override
+ void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+ var element = node.declaredElement;
+ if (node.parent is! DefaultFormalParameter) {
+ var enclosing = _enclosingElements.last;
+ element =
+ ParameterElementImpl.forLinkedNodeFactory(enclosing, null, node);
+ }
+
+ var localElementsLength = _localElements.length;
+
+ node.typeParameters?.accept(this);
+ node.returnType?.accept(this);
+ node.parameters?.accept(this);
+ _normalFormalParameter(node, element);
+
+ _localElements.length = localElementsLength;
+ }
+
+ @override
+ void visitGenericFunctionType(GenericFunctionType node) {
+ var nodeImpl = node as GenericFunctionTypeImpl;
+ var localElementsLength = _localElements.length;
+
+ var element = nodeImpl.declaredElement as GenericFunctionTypeElementImpl;
+ element ??= GenericFunctionTypeElementImpl.forLinkedNode(
+ _enclosingElements.last, null, node);
+ _enclosingElements.add(element);
+
+ node.typeParameters?.accept(this);
+ node.returnType?.accept(this);
+ node.parameters?.accept(this);
+ nodeImpl.type = _nextType();
+
+ _localElements.length = localElementsLength;
+ _enclosingElements.removeLast();
+ }
+
+ @override
+ void visitGenericTypeAlias(GenericTypeAlias node) {
+ _assertNoLocalElements();
+
+ var element = node.declaredElement as FunctionTypeAliasElementImpl;
+ assert(element != null);
+
+ _enclosingElements.add(element);
+
+ node.typeParameters?.accept(this);
+ node.functionType?.accept(this);
+ node.metadata?.accept(this);
+ element.isSimplyBounded = _resolution.readByte() != 0;
+ element.hasSelfReference = _resolution.readByte() != 0;
+
+ _enclosingElements.removeLast();
+ }
+
+ @override
+ void visitHideCombinator(HideCombinator node) {
+ node.hiddenNames.accept(this);
+ }
+
+ @override
+ void visitIfElement(IfElement node) {
+ node.condition.accept(this);
+ node.thenElement.accept(this);
+ node.elseElement?.accept(this);
+ }
+
+ @override
+ visitImplementsClause(ImplementsClause node) {
+ node.interfaces.accept(this);
+ }
+
+ @override
+ void visitImportDirective(ImportDirective node) {
+ _namespaceDirective(node);
+
+ var element = node.element as ImportElementImpl;
+ element.importedLibrary = _nextElement();
+ }
+
+ @override
+ void visitIndexExpression(IndexExpression node) {
+ node.target?.accept(this);
+ node.index.accept(this);
+ node.staticElement = _nextElement();
+ _expression(node);
+ }
+
+ @override
+ void visitInstanceCreationExpression(InstanceCreationExpression node) {
+ node.constructorName.accept(this);
+ (node as InstanceCreationExpressionImpl).typeArguments?.accept(this);
+ node.argumentList.accept(this);
+ node.staticType = _nextType();
+ _resolveNamedExpressions(
+ node.constructorName.staticElement,
+ node.argumentList,
+ );
+ }
+
+ @override
+ void visitIntegerLiteral(IntegerLiteral node) {
+ node.staticType = _nextType();
+ }
+
+ @override
+ void visitInterpolationExpression(InterpolationExpression node) {
+ node.expression.accept(this);
+ }
+
+ @override
+ void visitInterpolationString(InterpolationString node) {
+ // TODO(scheglov) type?
+ }
+
+ @override
+ void visitIsExpression(IsExpression node) {
+ node.expression.accept(this);
+ node.type.accept(this);
+ _expression(node);
+ }
+
+ @override
+ void visitLibraryDirective(LibraryDirective node) {
+ node.name.accept(this);
+ _directive(node);
+ }
+
+ @override
+ void visitLibraryIdentifier(LibraryIdentifier node) {
+ node.components.accept(this);
+ }
+
+ @override
+ void visitListLiteral(ListLiteral node) {
+ node.typeArguments?.accept(this);
+ node.elements.accept(this);
+ node.staticType = _nextType();
+ }
+
+ @override
+ void visitMapLiteralEntry(MapLiteralEntry node) {
+ node.key.accept(this);
+ node.value.accept(this);
+ }
+
+ @override
+ visitMethodDeclaration(MethodDeclaration node) {
+ _assertNoLocalElements();
+ _pushEnclosingClassTypeParameters(node);
+
+ var element = node.declaredElement as ExecutableElementImpl;
+ _enclosingElements.add(element.enclosingElement);
+ _enclosingElements.add(element);
+
+ node.typeParameters?.accept(this);
+ node.returnType?.accept(this);
+ node.parameters?.accept(this);
+ node.metadata?.accept(this);
+
+ element.returnType = _nextType();
+ _setTopLevelInferenceError(element);
+ if (element is MethodElementImpl) {
+ element.isOperatorEqualWithParameterTypeFromObject =
+ _resolution.readByte() != 0;
+ }
+
+ _enclosingElements.removeLast();
+ _enclosingElements.removeLast();
+ }
+
+ @override
+ void visitMethodInvocation(MethodInvocation node) {
+ node.target?.accept(this);
+ node.methodName.accept(this);
+ _invocationExpression(node);
+ }
+
+ @override
+ void visitMixinDeclaration(MixinDeclaration node) {
+ _assertNoLocalElements();
+ var element = node.declaredElement as MixinElementImpl;
+ element.isSimplyBounded = _resolution.readByte() != 0;
+ element.superInvokedNames = _resolution.readStringList();
+ _enclosingElements.add(element);
+
+ node.typeParameters?.accept(this);
+ node.onClause?.accept(this);
+ node.implementsClause?.accept(this);
+ node.metadata?.accept(this);
+
+ _enclosingElements.removeLast();
+ }
+
+ @override
+ void visitNamedExpression(NamedExpression node) {
+ node.expression.accept(this);
+ }
+
+ @override
+ void visitNativeClause(NativeClause node) {
+ node.name.accept(this);
+ }
+
+ @override
+ void visitNullLiteral(NullLiteral node) {
+ // TODO(scheglov) type?
+ }
+
+ @override
+ void visitOnClause(OnClause node) {
+ node.superclassConstraints.accept(this);
+ }
+
+ @override
+ void visitParenthesizedExpression(ParenthesizedExpression node) {
+ node.expression.accept(this);
+ node.staticType = _nextType();
+ }
+
+ @override
+ void visitPartDirective(PartDirective node) {
+ _uriBasedDirective(node);
+ }
+
+ @override
+ void visitPartOfDirective(PartOfDirective node) {
+ node.uri?.accept(this);
+ _directive(node);
+ }
+
+ @override
+ void visitPostfixExpression(PostfixExpression node) {
+ var nodeImpl = node as PostfixExpressionImpl;
+ node.operand.accept(this);
+ node.staticElement = _nextElement();
+ if (node.operator.type.isIncrementOperator) {
+ nodeImpl.readElement = _nextElement();
+ nodeImpl.readType = _nextType();
+ nodeImpl.writeElement = _nextElement();
+ nodeImpl.writeType = _nextType();
+ }
+ _expression(node);
+ }
+
+ @override
+ void visitPrefixedIdentifier(PrefixedIdentifier node) {
+ node.prefix.accept(this);
+ node.identifier.accept(this);
+ _expression(node);
+ }
+
+ @override
+ void visitPrefixExpression(PrefixExpression node) {
+ var nodeImpl = node as PrefixExpressionImpl;
+ node.operand.accept(this);
+ node.staticElement = _nextElement();
+ if (node.operator.type.isIncrementOperator) {
+ nodeImpl.readElement = _nextElement();
+ nodeImpl.readType = _nextType();
+ nodeImpl.writeElement = _nextElement();
+ nodeImpl.writeType = _nextType();
+ }
+ _expression(node);
+ }
+
+ @override
+ void visitPropertyAccess(PropertyAccess node) {
+ node.target?.accept(this);
+ node.propertyName.accept(this);
+
+ node.staticType = _nextType();
+ }
+
+ @override
+ void visitRedirectingConstructorInvocation(
+ RedirectingConstructorInvocation node) {
+ node.constructorName?.accept(this);
+ node.argumentList.accept(this);
+ node.staticElement = _nextElement();
+ _resolveNamedExpressions(node.staticElement, node.argumentList);
+ }
+
+ @override
+ void visitSetOrMapLiteral(SetOrMapLiteral node) {
+ node.typeArguments?.accept(this);
+ node.elements.accept(this);
+ node.staticType = _nextType();
+ }
+
+ @override
+ void visitShowCombinator(ShowCombinator node) {
+ node.shownNames.accept(this);
+ }
+
+ @override
+ visitSimpleFormalParameter(SimpleFormalParameter node) {
+ var element = node.declaredElement as ParameterElementImpl;
+ if (node.parent is! DefaultFormalParameter) {
+ var enclosing = _enclosingElements.last;
+ element =
+ ParameterElementImpl.forLinkedNodeFactory(enclosing, null, node);
+ }
+
+ node.type?.accept(this);
+ _normalFormalParameter(node, element);
+
+ element.inheritsCovariant = _resolution.readByte() != 0;
+ }
+
+ @override
+ visitSimpleIdentifier(SimpleIdentifier node) {
+ node.staticElement = _nextElement();
+ node.staticType = _nextType();
+ }
+
+ @override
+ void visitSimpleStringLiteral(SimpleStringLiteral node) {
+ // TODO(scheglov) type?
+ }
+
+ @override
+ void visitSpreadElement(SpreadElement node) {
+ node.expression.accept(this);
+ }
+
+ @override
+ void visitStringInterpolation(StringInterpolation node) {
+ node.elements.accept(this);
+ // TODO(scheglov) type?
+ }
+
+ @override
+ void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+ node.constructorName?.accept(this);
+ node.argumentList.accept(this);
+ node.staticElement = _nextElement();
+ _resolveNamedExpressions(node.staticElement, node.argumentList);
+ }
+
+ @override
+ void visitSuperExpression(SuperExpression node) {
+ node.staticType = _nextType();
+ }
+
+ @override
+ void visitSymbolLiteral(SymbolLiteral node) {
+ node.staticType = _nextType();
+ }
+
+ @override
+ void visitThisExpression(ThisExpression node) {
+ node.staticType = _nextType();
+ }
+
+ @override
+ void visitThrowExpression(ThrowExpression node) {
+ node.expression.accept(this);
+ node.staticType = _nextType();
+ }
+
+ @override
+ void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+ node.variables.accept(this);
+ node.metadata?.accept(this);
+ }
+
+ @override
+ visitTypeArgumentList(TypeArgumentList node) {
+ node.arguments?.accept(this);
+ }
+
+ @override
+ visitTypeName(TypeName node) {
+ node.name.accept(this);
+ node.typeArguments?.accept(this);
+
+ node.type = _nextType();
+ }
+
+ @override
+ visitTypeParameterList(TypeParameterList node) {
+ for (var typeParameter in node.typeParameters) {
+ var element = TypeParameterElementImpl.forLinkedNode(
+ _enclosingElements.last,
+ typeParameter,
+ );
+ _localElements.add(element);
+ }
+
+ for (var node in node.typeParameters) {
+ var nodeImpl = node as TypeParameterImpl;
+ var element = node.declaredElement as TypeParameterElementImpl;
+
+ var summaryData = nodeImpl.summaryData as SummaryDataForTypeParameter;
+ element.setCodeRange(summaryData.codeOffset, summaryData.codeLength);
+
+ node.bound?.accept(this);
+ element.bound = node.bound?.type;
+
+ node.metadata.accept(this);
+ element.metadata = _buildAnnotations2(
+ _unitContext.reference.element,
+ node.metadata,
+ );
+
+ element.variance = _decodeVariance(_resolution.readByte());
+ element.defaultType = _nextType();
+
+ // TODO(scheglov) We used to do this with the previous elements impl.
+ // We probably still do this.
+ // But the code below is bad and incomplete.
+ // And why does this affect MethodMember(s)?
+ {
+ var parent = node.parent;
+ if (parent is ClassDeclaration) {
+ (parent.declaredElement as ElementImpl).encloseElement(element);
+ } else if (parent is ClassTypeAlias) {
+ (parent.declaredElement as ElementImpl).encloseElement(element);
+ } else if (parent is ExtensionDeclaration) {
+ (parent.declaredElement as ElementImpl).encloseElement(element);
+ } else if (parent is FunctionExpression) {
+ var parent2 = parent.parent;
+ if (parent2 is FunctionDeclaration) {
+ (parent2.declaredElement as ElementImpl).encloseElement(element);
+ }
+ } else if (parent is FunctionTypeAlias) {
+ (parent.declaredElement as ElementImpl).encloseElement(element);
+ } else if (parent is GenericTypeAlias) {
+ (parent.declaredElement as ElementImpl).encloseElement(element);
+ } else if (parent is MethodDeclaration) {
+ (parent.declaredElement as ElementImpl).encloseElement(element);
+ } else if (parent is MixinDeclaration) {
+ (parent.declaredElement as ElementImpl).encloseElement(element);
+ }
+ }
+ }
+ }
+
+ @override
+ void visitVariableDeclaration(VariableDeclaration node) {
+ var element = node.declaredElement as VariableElementImpl;
+ element.type = _nextType();
+ _setTopLevelInferenceError(element);
+ if (element is FieldElementImpl) {
+ element.inheritsCovariant = _resolution.readByte() != 0;
+ }
+
+ node.initializer?.accept(this);
+ }
+
+ @override
+ void visitVariableDeclarationList(VariableDeclarationList node) {
+ node.type?.accept(this);
+ node.variables.accept(this);
+ node.metadata?.accept(this);
+ }
+
+ @override
+ void visitWithClause(WithClause node) {
+ node.mixinTypes.accept(this);
+ }
+
+ void _annotatedNode(AnnotatedNode node) {
+ node.metadata?.accept(this);
+ }
+
+ void _assertNoLocalElements() {
+ assert(_localElements.isEmpty);
+ assert(_enclosingElements.length == 1 &&
+ _enclosingElements.first is CompilationUnitElement);
+ }
+
+ /// Return annotations for the given [nodeList] in the [unit].
+ List<ElementAnnotation> _buildAnnotations2(
+ CompilationUnitElementImpl unit, List<Annotation> nodeList) {
+ var length = nodeList.length;
+ if (length == 0) {
+ return const <ElementAnnotation>[];
+ }
+
+ var annotations = List<ElementAnnotation>(length);
+ for (int i = 0; i < length; i++) {
+ var ast = nodeList[i];
+ annotations[i] = ElementAnnotationImpl(unit)
+ ..annotationAst = ast
+ ..element = ast.element;
+ }
+ return annotations;
+ }
+
+ void _compilationUnitMember(CompilationUnitMember node) {
+ _declaration(node);
+ }
+
+ void _declaration(Declaration node) {
+ _annotatedNode(node);
+ }
+
+ void _directive(Directive node) {
+ node.metadata?.accept(this);
+ }
+
+ void _expression(Expression node) {
+ node.staticType = _nextType();
+ }
+
+ void _forEachParts(ForEachParts node) {
+ _forLoopParts(node);
+ node.iterable.accept(this);
+ }
+
+ void _forLoopParts(ForLoopParts node) {}
+
+ void _formalParameter(FormalParameter node) {
+ (node.declaredElement as ParameterElementImpl).type = _nextType();
+ }
+
+ void _forParts(ForParts node) {
+ node.condition?.accept(this);
+ node.updaters.accept(this);
+ _forLoopParts(node);
+ }
+
+ void _invocationExpression(InvocationExpression node) {
+ node.typeArguments?.accept(this);
+ node.argumentList.accept(this);
+ _expression(node);
+ // TODO(scheglov) typeArgumentTypes and staticInvokeType?
+ var nodeImpl = node as InvocationExpressionImpl;
+ nodeImpl.typeArgumentTypes = [];
+ }
+
+ void _namedCompilationUnitMember(NamedCompilationUnitMember node) {
+ _compilationUnitMember(node);
+ }
+
+ void _namespaceDirective(NamespaceDirective node) {
+ node.combinators?.accept(this);
+ node.configurations?.accept(this);
+ _uriBasedDirective(node);
+ }
+
+ Element _nextElement() {
+ return _resolution.nextElement();
+ }
+
+ DartType _nextType() {
+ return _resolution.nextType();
+ }
+
+ void _normalFormalParameter(
+ NormalFormalParameter node,
+ ParameterElementImpl element,
+ ) {
+ if (node.parent is! DefaultFormalParameter) {
+ var nodeImpl = node as NormalFormalParameterImpl;
+ var summaryData = nodeImpl.summaryData as SummaryDataForFormalParameter;
+ element.setCodeRange(summaryData.codeOffset, summaryData.codeLength);
+ }
+
+ node.metadata?.accept(this);
+ _formalParameter(node);
+ }
+
+ /// TODO(scheglov) also enclosing elements
+ void _pushEnclosingClassTypeParameters(ClassMember node) {
+ var parent = node.parent;
+ if (parent is ClassOrMixinDeclaration) {
+ var classElement = parent.declaredElement;
+ _localElements.addAll(classElement.typeParameters);
+ } else {
+ var extension = parent as ExtensionDeclaration;
+ var classElement = extension.declaredElement;
+ _localElements.addAll(classElement.typeParameters);
+ }
+ }
+
+ TopLevelInferenceError _readTopLevelInferenceError() {
+ var kindIndex = _resolution.readByte();
+ var kind = TopLevelInferenceErrorKind.values[kindIndex];
+ if (kind == TopLevelInferenceErrorKind.none) {
+ return null;
+ }
+ return TopLevelInferenceError(
+ kind: kind,
+ arguments: _resolution.readStringList(),
+ );
+ }
+
+ void _resolveNamedExpressions(
+ Element executable,
+ ArgumentList argumentList,
+ ) {
+ for (var argument in argumentList.arguments) {
+ if (argument is NamedExpression) {
+ var nameNode = argument.name.label;
+ if (executable is ExecutableElement) {
+ var parameters = executable.parameters;
+ var name = nameNode.name;
+ nameNode.staticElement = parameters.firstWhere((e) {
+ return e.name == name;
+ }, orElse: () => null);
+ }
+ }
+ }
+ }
+
+ void _setTopLevelInferenceError(ElementImpl element) {
+ if (element is MethodElementImpl) {
+ element.typeInferenceError = _readTopLevelInferenceError();
+ } else if (element is PropertyInducingElementImpl) {
+ element.typeInferenceError = _readTopLevelInferenceError();
+ }
+ }
+
+ void _uriBasedDirective(UriBasedDirective node) {
+ _directive(node);
+ node.uri.accept(this);
+ }
+
+ static Variance _decodeVariance(int encoding) {
+ if (encoding == 0) {
+ return null;
+ } else if (encoding == 1) {
+ return Variance.unrelated;
+ } else if (encoding == 2) {
+ return Variance.covariant;
+ } else if (encoding == 3) {
+ return Variance.contravariant;
+ } else if (encoding == 4) {
+ return Variance.invariant;
+ } else {
+ throw UnimplementedError('encoding: $encoding');
+ }
+ }
+}
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_flags.dart b/pkg/analyzer/lib/src/summary2/ast_binary_flags.dart
index beac780..e911fea 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_flags.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_flags.dart
@@ -13,13 +13,18 @@
ForStatement,
);
+ static final _hasConstConstructor = _checkBit(
+ 0,
+ ClassDeclaration,
+ );
+
static final _hasEqual = _checkBit(
0,
Configuration,
);
static final _hasInitializer = _checkBit(
- 0,
+ 2,
DefaultFormalParameter,
VariableDeclaration,
);
@@ -27,6 +32,9 @@
static final _hasName = _checkBit(
5,
ConstructorDeclaration,
+ FieldFormalParameter,
+ FunctionTypedFormalParameter,
+ SimpleFormalParameter,
);
static final _hasNot = _checkBit(
@@ -34,6 +42,11 @@
IsExpression,
);
+ static final _hasPrefix = _checkBit(
+ 1,
+ ImportDirective,
+ );
+
static final _hasPeriod = _checkBit(
0,
IndexExpression,
@@ -183,8 +196,14 @@
MethodDeclaration,
);
+ static final _isPositional = _checkBit(
+ 1,
+ DefaultFormalParameter,
+ );
+
static final _isRequired = _checkBit(
0,
+ DefaultFormalParameter,
NormalFormalParameter,
);
@@ -227,12 +246,14 @@
static int encode({
bool hasAwait = false,
+ bool hasConstConstructor = false,
bool hasEqual = false,
bool hasInitializer = false,
bool hasName = false,
bool hasNot = false,
bool hasPeriod = false,
bool hasPeriod2 = false,
+ bool hasPrefix = false,
bool hasQuestion = false,
bool hasSeparatorColon = false,
bool hasSeparatorEquals = false,
@@ -256,6 +277,7 @@
bool isNative = false,
bool isNew = false,
bool isOperator = false,
+ bool isPositional = false,
bool isRequired = false,
bool isSet = false,
bool isStar = false,
@@ -268,6 +290,9 @@
if (hasAwait) {
result |= _hasAwait;
}
+ if (hasConstConstructor) {
+ result |= _hasConstConstructor;
+ }
if (hasEqual) {
result |= _hasEqual;
}
@@ -286,6 +311,9 @@
if (hasPeriod2) {
result |= _hasPeriod2;
}
+ if (hasPrefix) {
+ result |= _hasPrefix;
+ }
if (hasQuestion) {
result |= _hasQuestion;
}
@@ -355,6 +383,9 @@
if (isOperator) {
result |= _isOperator;
}
+ if (isPositional) {
+ result |= _isPositional;
+ }
if (isRequired) {
result |= _isRequired;
}
@@ -383,6 +414,10 @@
return (flags & _hasAwait) != 0;
}
+ static bool hasConstConstructor(int flags) {
+ return (flags & _hasConstConstructor) != 0;
+ }
+
static bool hasEqual(int flags) {
return (flags & _hasEqual) != 0;
}
@@ -407,6 +442,10 @@
return (flags & _hasPeriod2) != 0;
}
+ static bool hasPrefix(int flags) {
+ return (flags & _hasPrefix) != 0;
+ }
+
static bool hasQuestion(int flags) {
return (flags & _hasQuestion) != 0;
}
@@ -499,6 +538,10 @@
return (flags & _isOperator) != 0;
}
+ static bool isPositional(int flags) {
+ return (flags & _isPositional) != 0;
+ }
+
static bool isRequired(int flags) {
return (flags & _isRequired) != 0;
}
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index 4df499f..c84049b 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -2,2099 +2,1799 @@
// 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:typed_data';
+
import 'package:analyzer/dart/ast/ast.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/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/ast/ast_factory.dart';
-import 'package:analyzer/src/dart/element/member.dart';
-import 'package:analyzer/src/dart/element/type_algebra.dart';
-import 'package:analyzer/src/dart/resolver/variance.dart';
+import 'package:analyzer/src/dart/ast/token.dart';
import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
import 'package:analyzer/src/generated/testing/token_factory.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary2/ast_binary_flags.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
-import 'package:analyzer/src/summary2/linked_unit_context.dart';
-import 'package:analyzer/src/summary2/tokens_context.dart';
+import 'package:analyzer/src/summary2/ast_binary_tag.dart';
+import 'package:analyzer/src/summary2/ast_binary_tokens.dart';
+import 'package:analyzer/src/summary2/bundle_reader.dart';
+import 'package:analyzer/src/summary2/unlinked_token_type.dart';
+import 'package:meta/meta.dart';
-var timerAstBinaryReader = Stopwatch();
-var timerAstBinaryReaderClass = Stopwatch();
-var timerAstBinaryReaderDirective = Stopwatch();
-var timerAstBinaryReaderFunctionBody = Stopwatch();
-var timerAstBinaryReaderFunctionDeclaration = Stopwatch();
-var timerAstBinaryReaderMixin = Stopwatch();
-var timerAstBinaryReaderTopLevelVar = Stopwatch();
-
-/// Deserializer of fully resolved ASTs from flat buffers.
+/// Deserializer of ASTs.
class AstBinaryReader {
- final LinkedUnitContext _unitContext;
+ static final _noDocumentationComment = Uint32List(0);
- /// Set to `true` when this reader is used to lazily read its unit.
- bool isLazy = false;
+ final UnitReader _unitReader;
+ final bool _withInformative;
- /// Whether we are reading a directive.
- ///
- /// [StringLiteral]s in directives are not actual expressions, and don't need
- /// a type. Moreover, when we are reading `dart:core` imports, the type
- /// provider is not ready yet, so we cannot access type `String`.
- bool _isReadingDirective = false;
+ AstBinaryReader({
+ @required UnitReader reader,
+ }) : _unitReader = reader,
+ _withInformative = reader.withInformative;
- AstBinaryReader(this._unitContext);
-
- InterfaceType get _boolType => _unitContext.typeProvider.boolType;
-
- InterfaceType get _doubleType => _unitContext.typeProvider.doubleType;
-
- InterfaceType get _intType => _unitContext.typeProvider.intType;
-
- DartType get _nullType => _unitContext.typeProvider.nullType;
-
- InterfaceType get _stringType => _unitContext.typeProvider.stringType;
-
- AstNode readNode(LinkedNode data) {
- timerAstBinaryReader.start();
- try {
- return _readNode(data);
- } finally {
- timerAstBinaryReader.stop();
- }
- }
-
- DartType readType(LinkedNodeType data) {
- return _readType(data);
- }
-
- Token _combinatorKeyword(LinkedNode data, Keyword keyword, Token def) {
- var informativeData = _unitContext.getInformativeData(data);
- if (informativeData != null) {
- return TokenFactory.tokenFromKeyword(keyword)
- ..offset = informativeData.combinatorKeywordOffset;
- }
- return def;
- }
-
- SimpleIdentifier _declaredIdentifier(LinkedNode data) {
- var informativeData = _unitContext.getInformativeData(data);
- var offset = informativeData?.nameOffset ?? 0;
- return astFactory.simpleIdentifier(
- TokenFactory.tokenFromString(data.name)..offset = offset,
- isDeclaration: true,
- );
- }
-
- Token _directiveKeyword(LinkedNode data, Keyword keyword, Token def) {
- var informativeData = _unitContext.getInformativeData(data);
- if (informativeData != null) {
- return TokenFactory.tokenFromKeyword(keyword)
- ..offset = informativeData.directiveKeywordOffset;
- }
- return def;
- }
-
- Element _elementOfComponents(
- int rawElementIndex,
- LinkedNodeTypeSubstitution substitutionNode,
- ) {
- var element = _getElement(rawElementIndex);
- if (substitutionNode == null) return element;
-
- var typeParameters = substitutionNode.typeParameters
- .map<TypeParameterElement>(_getElement)
- .toList();
- var typeArguments = substitutionNode.typeArguments.map(_readType).toList();
- var substitution = Substitution.fromPairs(typeParameters, typeArguments);
-
- var member = ExecutableMember.from2(element, substitution);
- if (substitutionNode.isLegacy) {
- member = Member.legacy(member);
- }
-
- return member;
- }
-
- T _getElement<T extends Element>(int index) {
- var bundleContext = _unitContext.bundleContext;
- return bundleContext.elementOfIndex(index);
- }
-
- AdjacentStrings _read_adjacentStrings(LinkedNode data) {
- var node = astFactory.adjacentStrings(
- _readNodeList(data.adjacentStrings_strings),
- );
- if (!_isReadingDirective) {
- node.staticType = _stringType;
- }
- return node;
- }
-
- Annotation _read_annotation(LinkedNode data) {
- return astFactory.annotation(
- _Tokens.AT,
- _readNode(data.annotation_name),
- _Tokens.PERIOD,
- _readNode(data.annotation_constructorName),
- _readNode(data.annotation_arguments),
- )..element = _elementOfComponents(
- data.annotation_element,
- data.annotation_substitution,
- );
- }
-
- ArgumentList _read_argumentList(LinkedNode data) {
- return astFactory.argumentList(
- _Tokens.OPEN_PAREN,
- _readNodeList(data.argumentList_arguments),
- _Tokens.CLOSE_PAREN,
- );
- }
-
- AsExpression _read_asExpression(LinkedNode data) {
- return astFactory.asExpression(
- _readNode(data.asExpression_expression),
- _Tokens.AS,
- _readNode(data.asExpression_type),
- )..staticType = _readType(data.expression_type);
- }
-
- AssertInitializer _read_assertInitializer(LinkedNode data) {
- return astFactory.assertInitializer(
- _Tokens.ASSERT,
- _Tokens.OPEN_PAREN,
- _readNode(data.assertInitializer_condition),
- _Tokens.COMMA,
- _readNode(data.assertInitializer_message),
- _Tokens.CLOSE_PAREN,
- );
- }
-
- AssertStatement _read_assertStatement(LinkedNode data) {
- return astFactory.assertStatement(
- _Tokens.AS,
- _Tokens.OPEN_PAREN,
- _readNode(data.assertStatement_condition),
- _Tokens.COMMA,
- _readNode(data.assertStatement_message),
- _Tokens.CLOSE_PAREN,
- _Tokens.SEMICOLON,
- );
- }
-
- AssignmentExpression _read_assignmentExpression(LinkedNode data) {
- return astFactory.assignmentExpression(
- _readNode(data.assignmentExpression_leftHandSide),
- _Tokens.fromType(data.assignmentExpression_operator),
- _readNode(data.assignmentExpression_rightHandSide),
- )
- ..staticElement = _elementOfComponents(
- data.assignmentExpression_element,
- data.assignmentExpression_substitution,
- )
- ..staticType = _readType(data.expression_type);
- }
-
- AwaitExpression _read_awaitExpression(LinkedNode data) {
- return astFactory.awaitExpression(
- _Tokens.AWAIT,
- _readNode(data.awaitExpression_expression),
- )..staticType = _readType(data.expression_type);
- }
-
- BinaryExpression _read_binaryExpression(LinkedNode data) {
- return astFactory.binaryExpression(
- _readNode(data.binaryExpression_leftOperand),
- _Tokens.fromType(data.binaryExpression_operator),
- _readNode(data.binaryExpression_rightOperand),
- )
- ..staticElement = _elementOfComponents(
- data.binaryExpression_element,
- data.binaryExpression_substitution,
- )
- ..staticType = _readType(data.expression_type);
- }
-
- Block _read_block(LinkedNode data) {
- return astFactory.block(
- _Tokens.OPEN_CURLY_BRACKET,
- _readNodeList(data.block_statements),
- _Tokens.CLOSE_CURLY_BRACKET,
- );
- }
-
- BlockFunctionBody _read_blockFunctionBody(LinkedNode data) {
- timerAstBinaryReaderFunctionBody.start();
- try {
- return astFactory.blockFunctionBody(
- _Tokens.choose(
- AstBinaryFlags.isAsync(data.flags),
- _Tokens.ASYNC,
- AstBinaryFlags.isSync(data.flags),
- _Tokens.SYNC,
- ),
- AstBinaryFlags.isStar(data.flags) ? _Tokens.STAR : null,
- _readNode(data.blockFunctionBody_block),
- );
- } finally {
- timerAstBinaryReaderFunctionBody.stop();
- }
- }
-
- BooleanLiteral _read_booleanLiteral(LinkedNode data) {
- return AstTestFactory.booleanLiteral(data.booleanLiteral_value)
- ..staticType = _boolType;
- }
-
- BreakStatement _read_breakStatement(LinkedNode data) {
- return astFactory.breakStatement(
- _Tokens.BREAK,
- _readNode(data.breakStatement_label),
- _Tokens.SEMICOLON,
- );
- }
-
- CascadeExpression _read_cascadeExpression(LinkedNode data) {
- return astFactory.cascadeExpression(
- _readNode(data.cascadeExpression_target),
- _readNodeList(data.cascadeExpression_sections),
- )..staticType = _readType(data.expression_type);
- }
-
- CatchClause _read_catchClause(LinkedNode data) {
- var exceptionType = _readNode(data.catchClause_exceptionType);
- var exceptionParameter = _readNode(data.catchClause_exceptionParameter);
- var stackTraceParameter = _readNode(data.catchClause_stackTraceParameter);
- return astFactory.catchClause(
- exceptionType != null ? _Tokens.ON : null,
- exceptionType,
- exceptionParameter != null ? _Tokens.CATCH : null,
- exceptionParameter != null ? _Tokens.OPEN_PAREN : null,
- exceptionParameter,
- stackTraceParameter != null ? _Tokens.COMMA : null,
- stackTraceParameter,
- exceptionParameter != null ? _Tokens.CLOSE_PAREN : null,
- _readNode(data.catchClause_body),
- );
- }
-
- ClassDeclaration _read_classDeclaration(LinkedNode data) {
- timerAstBinaryReaderClass.start();
- try {
- var node = astFactory.classDeclaration(
- _readDocumentationComment(data),
- _readNodeListLazy(data.annotatedNode_metadata),
- AstBinaryFlags.isAbstract(data.flags) ? _Tokens.ABSTRACT : null,
- _Tokens.CLASS,
- _declaredIdentifier(data),
- _readNode(data.classOrMixinDeclaration_typeParameters),
- _readNodeLazy(data.classDeclaration_extendsClause),
- _readNodeLazy(data.classDeclaration_withClause),
- _readNodeLazy(data.classOrMixinDeclaration_implementsClause),
- _Tokens.OPEN_CURLY_BRACKET,
- _readNodeListLazy(data.classOrMixinDeclaration_members),
- _Tokens.CLOSE_CURLY_BRACKET,
- );
- node.nativeClause = _readNodeLazy(data.classDeclaration_nativeClause);
- LazyClassDeclaration.setData(node, data);
- return node;
- } finally {
- timerAstBinaryReaderClass.stop();
- }
- }
-
- ClassTypeAlias _read_classTypeAlias(LinkedNode data) {
- timerAstBinaryReaderClass.start();
- try {
- var node = astFactory.classTypeAlias(
- _readDocumentationComment(data),
- _readNodeListLazy(data.annotatedNode_metadata),
- _Tokens.CLASS,
- _declaredIdentifier(data),
- _readNode(data.classTypeAlias_typeParameters),
- _Tokens.EQ,
- AstBinaryFlags.isAbstract(data.flags) ? _Tokens.ABSTRACT : null,
- _readNodeLazy(data.classTypeAlias_superclass),
- _readNodeLazy(data.classTypeAlias_withClause),
- _readNodeLazy(data.classTypeAlias_implementsClause),
- _Tokens.SEMICOLON,
- );
- LazyClassTypeAlias.setData(node, data);
- return node;
- } finally {
- timerAstBinaryReaderClass.stop();
- }
- }
-
- Comment _read_comment(LinkedNode data) {
- var tokens = data.comment_tokens
- .map((lexeme) => TokenFactory.tokenFromString(lexeme))
- .toList();
- switch (data.comment_type) {
- case LinkedNodeCommentType.block:
- return astFactory.endOfLineComment(
- tokens,
- );
- case LinkedNodeCommentType.documentation:
- return astFactory.documentationComment(
- tokens,
- _readNodeList(data.comment_references),
- );
- case LinkedNodeCommentType.endOfLine:
- return astFactory.endOfLineComment(
- tokens,
- );
+ AstNode readNode() {
+ var tag = _readByte();
+ switch (tag) {
+ case Tag.AdjacentStrings:
+ return _readAdjacentStrings();
+ case Tag.Annotation:
+ return _readAnnotation();
+ case Tag.ArgumentList:
+ return _readArgumentList();
+ case Tag.AsExpression:
+ return _readAsExpression();
+ case Tag.AssertInitializer:
+ return _readAssertInitializer();
+ case Tag.AssignmentExpression:
+ return _readAssignmentExpression();
+ case Tag.BinaryExpression:
+ return _readBinaryExpression();
+ case Tag.BooleanLiteral:
+ return _readBooleanLiteral();
+ case Tag.CascadeExpression:
+ return _readCascadeExpression();
+ case Tag.Class:
+ return _readClassDeclaration();
+ case Tag.ClassTypeAlias:
+ return _readClassTypeAlias();
+ case Tag.ConditionalExpression:
+ return _readConditionalExpression();
+ case Tag.Configuration:
+ return _readConfiguration();
+ case Tag.ConstructorDeclaration:
+ return _readConstructorDeclaration();
+ case Tag.ConstructorFieldInitializer:
+ return _readConstructorFieldInitializer();
+ case Tag.ConstructorName:
+ return _readConstructorName();
+ case Tag.DeclaredIdentifier:
+ return _readDeclaredIdentifier();
+ case Tag.DefaultFormalParameter:
+ return _readDefaultFormalParameter();
+ case Tag.DottedName:
+ return _readDottedName();
+ case Tag.DoubleLiteral:
+ return _readDoubleLiteral();
+ case Tag.EnumConstantDeclaration:
+ return _readEnumConstantDeclaration();
+ case Tag.EnumDeclaration:
+ return _readEnumDeclaration();
+ case Tag.ExportDirective:
+ return _readExportDirective();
+ case Tag.ExtendsClause:
+ return _readExtendsClause();
+ case Tag.ExtensionDeclaration:
+ return _readExtensionDeclaration();
+ case Tag.ExtensionOverride:
+ return _readExtensionOverride();
+ case Tag.FieldDeclaration:
+ return _readFieldDeclaration();
+ case Tag.ForEachPartsWithDeclaration:
+ return _readForEachPartsWithDeclaration();
+ case Tag.ForElement:
+ return _readForElement();
+ case Tag.ForPartsWithDeclarations:
+ return _readForPartsWithDeclarations();
+ case Tag.FieldFormalParameter:
+ return _readFieldFormalParameter();
+ case Tag.FormalParameterList:
+ return _readFormalParameterList();
+ case Tag.FunctionDeclaration:
+ return _readFunctionDeclaration();
+ case Tag.FunctionExpression:
+ return _readFunctionExpression();
+ case Tag.FunctionExpressionInvocation:
+ return _readFunctionExpressionInvocation();
+ case Tag.FunctionTypeAlias:
+ return _readFunctionTypeAlias();
+ case Tag.FunctionTypedFormalParameter:
+ return _readFunctionTypedFormalParameter();
+ case Tag.GenericFunctionType:
+ return _readGenericFunctionType();
+ case Tag.GenericTypeAlias:
+ return _readGenericTypeAlias();
+ case Tag.HideCombinator:
+ return _readHideCombinator();
+ case Tag.IfElement:
+ return _readIfElement();
+ case Tag.ImplementsClause:
+ return _readImplementsClause();
+ case Tag.IndexExpression:
+ return _readIndexExpression();
+ case Tag.IntegerLiteralNegative1:
+ return _readIntegerLiteralNegative1();
+ case Tag.IntegerLiteralNull:
+ return _readIntegerLiteralNull();
+ case Tag.IntegerLiteralPositive1:
+ return _readIntegerLiteralPositive1();
+ case Tag.IntegerLiteralPositive:
+ return _readIntegerLiteralPositive();
+ case Tag.IntegerLiteralNegative:
+ return _readIntegerLiteralNegative();
+ case Tag.InterpolationExpression:
+ return _readInterpolationExpression();
+ case Tag.InterpolationString:
+ return _readInterpolationString();
+ case Tag.IsExpression:
+ return _readIsExpression();
+ case Tag.LibraryDirective:
+ return _readLibraryDirective();
+ case Tag.LibraryIdentifier:
+ return _readLibraryIdentifier();
+ case Tag.ListLiteral:
+ return _readListLiteral();
+ case Tag.MapLiteralEntry:
+ return _readMapLiteralEntry();
+ case Tag.MethodDeclaration:
+ return _readMethodDeclaration();
+ case Tag.MixinDeclaration:
+ return _readMixinDeclaration();
+ case Tag.MethodInvocation:
+ return _readMethodInvocation();
+ case Tag.NamedExpression:
+ return _readNamedExpression();
+ case Tag.NativeClause:
+ return _readNativeClause();
+ case Tag.NullLiteral:
+ return _readNullLiteral();
+ case Tag.OnClause:
+ return _readOnClause();
+ case Tag.ImportDirective:
+ return _readImportDirective();
+ case Tag.InstanceCreationExpression:
+ return _readInstanceCreationExpression();
+ case Tag.ParenthesizedExpression:
+ return _readParenthesizedExpression();
+ case Tag.PartDirective:
+ return _readPartDirective();
+ case Tag.PartOfDirective:
+ return _readPartOfDirective();
+ case Tag.PostfixExpression:
+ return _readPostfixExpression();
+ case Tag.PrefixExpression:
+ return _readPrefixExpression();
+ case Tag.PrefixedIdentifier:
+ return _readPrefixedIdentifier();
+ case Tag.PropertyAccess:
+ return _readPropertyAccess();
+ case Tag.RedirectingConstructorInvocation:
+ return _readRedirectingConstructorInvocation();
+ case Tag.SetOrMapLiteral:
+ return _readSetOrMapLiteral();
+ case Tag.ShowCombinator:
+ return _readShowCombinator();
+ case Tag.SimpleFormalParameter:
+ return _readSimpleFormalParameter();
+ case Tag.SimpleIdentifier:
+ return _readSimpleIdentifier();
+ case Tag.SimpleStringLiteral:
+ return _readSimpleStringLiteral();
+ case Tag.SpreadElement:
+ return _readSpreadElement();
+ case Tag.StringInterpolation:
+ return _readStringInterpolation();
+ case Tag.SuperConstructorInvocation:
+ return _readSuperConstructorInvocation();
+ case Tag.SuperExpression:
+ return _readSuperExpression();
+ case Tag.SymbolLiteral:
+ return _readSymbolLiteral();
+ case Tag.ThisExpression:
+ return _readThisExpression();
+ case Tag.ThrowExpression:
+ return _readThrowExpression();
+ case Tag.TypeArgumentList:
+ return _readTypeArgumentList();
+ case Tag.TypeName:
+ return _readTypeName();
+ case Tag.TypeParameter:
+ return _readTypeParameter();
+ case Tag.TypeParameterList:
+ return _readTypeParameterList();
+ case Tag.TopLevelVariableDeclaration:
+ return _readTopLevelVariableDeclaration();
+ case Tag.VariableDeclaration:
+ return _readVariableDeclaration();
+ case Tag.VariableDeclarationList:
+ return _readVariableDeclarationList();
+ case Tag.WithClause:
+ return _readWithClause();
default:
- throw StateError('${data.comment_type}');
+ throw UnimplementedError('Unexpected tag: $tag');
}
}
- CommentReference _read_commentReference(LinkedNode data) {
- return astFactory.commentReference(
- AstBinaryFlags.isNew(data.flags) ? _Tokens.NEW : null,
- _readNode(data.commentReference_identifier),
+ IntegerLiteral _createIntegerLiteral(int value) {
+ // TODO(scheglov) Write token?
+ return astFactory.integerLiteral(
+ TokenFactory.tokenFromTypeAndString(TokenType.INT, '$value'),
+ value,
);
}
- CompilationUnit _read_compilationUnit(LinkedNode data) {
- var node = astFactory.compilationUnit(
- beginToken: null,
- scriptTag: _readNode(data.compilationUnit_scriptTag),
- directives: _readNodeList(data.compilationUnit_directives),
- declarations: _readNodeList(data.compilationUnit_declarations),
- endToken: null,
- featureSet: ExperimentStatus.fromStorage(
- data.compilationUnit_featureSet,
- ),
+ FunctionBody _functionBodyForFlags(int flags) {
+ if (AstBinaryFlags.isNative(flags)) {
+ return AstTestFactory.nativeFunctionBody('');
+ } else if (AstBinaryFlags.isAbstract(flags)) {
+ return AstTestFactory.emptyFunctionBody();
+ } else {
+ return astFactory.blockFunctionBody(
+ AstBinaryFlags.isAsync(flags) ? Tokens.ASYNC : null,
+ AstBinaryFlags.isGenerator(flags) ? Tokens.STAR : null,
+ astFactory.block(
+ Tokens.OPEN_CURLY_BRACKET,
+ const <Statement>[],
+ Tokens.CLOSE_CURLY_BRACKET,
+ ),
+ );
+ }
+ }
+
+ AdjacentStrings _readAdjacentStrings() {
+ var components = _readNodeList<StringLiteral>();
+ return astFactory.adjacentStrings(components);
+ }
+
+ Annotation _readAnnotation() {
+ var name = _readOptionalNode() as Identifier;
+ var constructorName = _readOptionalNode() as SimpleIdentifier;
+ var arguments = _readOptionalNode() as ArgumentList;
+ return astFactory.annotation(
+ Tokens.AT,
+ name,
+ Tokens.PERIOD,
+ constructorName,
+ arguments,
);
- LazyCompilationUnit(node, data);
+ }
+
+ ArgumentList _readArgumentList() {
+ var arguments = _readNodeList<Expression>();
+
+ return astFactory.argumentList(
+ Tokens.OPEN_PAREN,
+ arguments,
+ Tokens.CLOSE_PAREN,
+ );
+ }
+
+ AsExpression _readAsExpression() {
+ var expression = readNode() as Expression;
+ var type = readNode() as TypeAnnotation;
+ return astFactory.asExpression(expression, Tokens.AS, type);
+ }
+
+ AssertInitializer _readAssertInitializer() {
+ var condition = readNode() as Expression;
+ var message = _readOptionalNode() as Expression;
+ return astFactory.assertInitializer(
+ Tokens.ASSERT,
+ Tokens.OPEN_PAREN,
+ condition,
+ Tokens.COMMA,
+ message,
+ Tokens.CLOSE_PAREN,
+ );
+ }
+
+ AssignmentExpression _readAssignmentExpression() {
+ var leftHandSide = readNode() as Expression;
+ var rightHandSide = readNode() as Expression;
+ var operatorType = UnlinkedTokenType.values[_readByte()];
+ return astFactory.assignmentExpression(
+ leftHandSide,
+ Tokens.fromType(operatorType),
+ rightHandSide,
+ );
+ }
+
+ BinaryExpression _readBinaryExpression() {
+ var leftOperand = readNode() as Expression;
+ var rightOperand = readNode() as Expression;
+ var operatorType = UnlinkedTokenType.values[_readByte()];
+ return astFactory.binaryExpression(
+ leftOperand,
+ Tokens.fromType(operatorType),
+ rightOperand,
+ );
+ }
+
+ BooleanLiteral _readBooleanLiteral() {
+ var value = _readByte() == 1;
+ // TODO(scheglov) type?
+ return AstTestFactory.booleanLiteral(value);
+ }
+
+ int _readByte() {
+ return _unitReader.astReader.readByte();
+ }
+
+ CascadeExpression _readCascadeExpression() {
+ var target = readNode() as Expression;
+ var sections = _readNodeList<Expression>();
+ return astFactory.cascadeExpression(target, sections);
+ }
+
+ ClassDeclaration _readClassDeclaration() {
+ var flags = _readByte();
+
+ var codeOffset = _readInformativeUint30();
+ var codeLength = _readInformativeUint30();
+ var documentationTokenIndexList = _readUint30List();
+
+ var typeParameters = _readOptionalNode() as TypeParameterList;
+ var extendsClause = _readOptionalNode() as ExtendsClause;
+ var withClause = _readOptionalNode() as WithClause;
+ var implementsClause = _readOptionalNode() as ImplementsClause;
+ var nativeClause = _readOptionalNode() as NativeClause;
+ var name = readNode() as SimpleIdentifier;
+ var metadata = _readNodeList<Annotation>();
+
+ var node = astFactory.classDeclaration(
+ null,
+ metadata,
+ AstBinaryFlags.isAbstract(flags) ? Tokens.ABSTRACT : null,
+ Tokens.CLASS,
+ name,
+ typeParameters,
+ extendsClause,
+ withClause,
+ implementsClause,
+ Tokens.OPEN_CURLY_BRACKET,
+ const <ClassMember>[],
+ Tokens.CLOSE_CURLY_BRACKET,
+ ) as ClassDeclarationImpl;
+ node.nativeClause = nativeClause;
+
+ node.linkedContext = LinkedContext(
+ _unitReader,
+ node,
+ codeOffset: codeOffset,
+ codeLength: codeLength,
+ isClassWithConstConstructor: AstBinaryFlags.hasConstConstructor(flags),
+ resolutionIndex: _readUInt30(),
+ documentationTokenIndexList: documentationTokenIndexList,
+ );
+
return node;
}
- ConditionalExpression _read_conditionalExpression(LinkedNode data) {
+ ClassTypeAlias _readClassTypeAlias() {
+ var flags = _readByte();
+
+ var codeOffset = _readInformativeUint30();
+ var codeLength = _readInformativeUint30();
+
+ var typeParameters = _readOptionalNode() as TypeParameterList;
+ var superClass = readNode() as TypeName;
+ var withClause = readNode() as WithClause;
+ var implementsClause = _readOptionalNode() as ImplementsClause;
+ var name = readNode() as SimpleIdentifier;
+ var metadata = _readNodeList<Annotation>();
+ var documentationTokenIndexList = _readUint30List();
+
+ var node = astFactory.classTypeAlias(
+ null,
+ metadata,
+ Tokens.CLASS,
+ name,
+ typeParameters,
+ Tokens.EQ,
+ AstBinaryFlags.isAbstract(flags) ? Tokens.ABSTRACT : null,
+ superClass,
+ withClause,
+ implementsClause,
+ Tokens.SEMICOLON,
+ ) as ClassTypeAliasImpl;
+
+ node.linkedContext = LinkedContext(
+ _unitReader,
+ node,
+ codeOffset: codeOffset,
+ codeLength: codeLength,
+ resolutionIndex: _readUInt30(),
+ documentationTokenIndexList: documentationTokenIndexList,
+ );
+
+ return node;
+ }
+
+ ConditionalExpression _readConditionalExpression() {
+ var condition = readNode() as Expression;
+ var thenExpression = readNode() as Expression;
+ var elseExpression = readNode() as Expression;
return astFactory.conditionalExpression(
- _readNode(data.conditionalExpression_condition),
- _Tokens.QUESTION,
- _readNode(data.conditionalExpression_thenExpression),
- _Tokens.COLON,
- _readNode(data.conditionalExpression_elseExpression),
- )..staticType = _readType(data.expression_type);
+ condition,
+ Tokens.QUESTION,
+ thenExpression,
+ Tokens.COLON,
+ elseExpression,
+ );
}
- Configuration _read_configuration(LinkedNode data) {
+ Configuration _readConfiguration() {
+ var flags = _readByte();
+ var name = readNode() as DottedName;
+ var value = _readOptionalNode() as StringLiteral;
+ var uri = readNode() as StringLiteral;
return astFactory.configuration(
- _Tokens.IF,
- _Tokens.OPEN_PAREN,
- _readNode(data.configuration_name),
- AstBinaryFlags.hasEqual(data.flags) ? _Tokens.EQ : null,
- _readNode(data.configuration_value),
- _Tokens.CLOSE_PAREN,
- _readNode(data.configuration_uri),
+ Tokens.IF,
+ Tokens.OPEN_PAREN,
+ name,
+ AstBinaryFlags.hasEqual(flags) ? Tokens.EQ : null,
+ value,
+ Tokens.CLOSE_PAREN,
+ uri,
);
}
- ConstructorDeclaration _read_constructorDeclaration(LinkedNode data) {
- SimpleIdentifier returnType = _readNode(
- data.constructorDeclaration_returnType,
- );
+ ConstructorDeclaration _readConstructorDeclaration() {
+ var flags = _readByte();
- var informativeData = _unitContext.getInformativeData(data);
- returnType.token.offset =
- informativeData?.constructorDeclaration_returnTypeOffset ?? 0;
+ var codeOffset = _readInformativeUint30();
+ var codeLength = _readInformativeUint30();
+ var documentationTokenIndexList = _readUint30List();
- Token periodToken;
- SimpleIdentifier nameIdentifier;
- if (AstBinaryFlags.hasName(data.flags)) {
- periodToken = Token(
- TokenType.PERIOD,
- informativeData?.constructorDeclaration_periodOffset ?? 0,
- );
- nameIdentifier = _declaredIdentifier(data);
+ var returnType = readNode() as SimpleIdentifier;
+
+ Token period;
+ SimpleIdentifier name;
+ if (AstBinaryFlags.hasName(flags)) {
+ var periodOffset = _readInformativeUint30();
+ period = Token(TokenType.PERIOD, periodOffset);
+ name = readNode() as SimpleIdentifier;
}
+ var parameters = readNode() as FormalParameterList;
+ var initializers = _readNodeList<ConstructorInitializer>();
+ var redirectedConstructor = _readOptionalNode() as ConstructorName;
+ var metadata = _readNodeList<Annotation>();
+
var node = astFactory.constructorDeclaration(
- _readDocumentationComment(data),
- _readNodeListLazy(data.annotatedNode_metadata),
- AstBinaryFlags.isExternal(data.flags) ? _Tokens.EXTERNAL : null,
- AstBinaryFlags.isConst(data.flags) ? _Tokens.CONST : null,
- AstBinaryFlags.isFactory(data.flags) ? _Tokens.FACTORY : null,
+ null,
+ metadata,
+ AstBinaryFlags.isExternal(flags) ? Tokens.EXTERNAL : null,
+ AstBinaryFlags.isConst(flags) ? Tokens.CONST : null,
+ AstBinaryFlags.isFactory(flags) ? Tokens.FACTORY : null,
returnType,
- periodToken,
- nameIdentifier,
- _readNodeLazy(data.constructorDeclaration_parameters),
- _Tokens.choose(
- AstBinaryFlags.hasSeparatorColon(data.flags),
- _Tokens.COLON,
- AstBinaryFlags.hasSeparatorEquals(data.flags),
- _Tokens.EQ,
+ period,
+ name,
+ parameters,
+ Tokens.choose(
+ AstBinaryFlags.hasSeparatorColon(flags),
+ Tokens.COLON,
+ AstBinaryFlags.hasSeparatorEquals(flags),
+ Tokens.EQ,
),
- _readNodeListLazy(data.constructorDeclaration_initializers),
- _readNodeLazy(data.constructorDeclaration_redirectedConstructor),
- _readNodeLazy(data.constructorDeclaration_body),
+ initializers,
+ redirectedConstructor,
+ null,
+ ) as ConstructorDeclarationImpl;
+
+ node.linkedContext = LinkedContext(
+ _unitReader,
+ node,
+ codeOffset: codeOffset,
+ codeLength: codeLength,
+ resolutionIndex: _readUInt30(),
+ documentationTokenIndexList: documentationTokenIndexList,
);
- LazyConstructorDeclaration.setData(node, data);
+
return node;
}
- ConstructorFieldInitializer _read_constructorFieldInitializer(
- LinkedNode data) {
- var hasThis = AstBinaryFlags.hasThis(data.flags);
+ ConstructorFieldInitializer _readConstructorFieldInitializer() {
+ var flags = _readByte();
+ var fieldName = readNode() as SimpleIdentifier;
+ var expression = readNode() as Expression;
+ var hasThis = AstBinaryFlags.hasThis(flags);
return astFactory.constructorFieldInitializer(
- hasThis ? _Tokens.THIS : null,
- hasThis ? _Tokens.PERIOD : null,
- _readNode(data.constructorFieldInitializer_fieldName),
- _Tokens.EQ,
- _readNode(data.constructorFieldInitializer_expression),
+ hasThis ? Tokens.THIS : null,
+ hasThis ? Tokens.PERIOD : null,
+ fieldName,
+ Tokens.EQ,
+ expression,
);
}
- ConstructorName _read_constructorName(LinkedNode data) {
+ ConstructorName _readConstructorName() {
+ var type = readNode() as TypeName;
+ var name = _readOptionalNode() as SimpleIdentifier;
+
return astFactory.constructorName(
- _readNode(data.constructorName_type),
- data.constructorName_name != null ? _Tokens.PERIOD : null,
- _readNode(data.constructorName_name),
- )..staticElement = _elementOfComponents(
- data.constructorName_element,
- data.constructorName_substitution,
- );
- }
-
- ContinueStatement _read_continueStatement(LinkedNode data) {
- return astFactory.continueStatement(
- _Tokens.CONTINUE,
- _readNode(data.continueStatement_label),
- _Tokens.SEMICOLON,
+ type,
+ name != null ? Tokens.PERIOD : null,
+ name,
);
}
- DeclaredIdentifier _read_declaredIdentifier(LinkedNode data) {
+ DeclaredIdentifier _readDeclaredIdentifier() {
+ var flags = _readByte();
+ var type = _readOptionalNode() as TypeAnnotation;
+ var identifier = readNode() as SimpleIdentifier;
+ var metadata = _readNodeList<Annotation>();
return astFactory.declaredIdentifier(
- _readDocumentationComment(data),
- _readNodeList(data.annotatedNode_metadata),
- _Tokens.choose(
- AstBinaryFlags.isConst(data.flags),
- _Tokens.CONST,
- AstBinaryFlags.isFinal(data.flags),
- _Tokens.FINAL,
- AstBinaryFlags.isVar(data.flags),
- _Tokens.VAR,
- ),
- _readNode(data.declaredIdentifier_type),
- _readNode(data.declaredIdentifier_identifier),
- );
- }
-
- DefaultFormalParameter _read_defaultFormalParameter(LinkedNode data) {
- var node = astFactory.defaultFormalParameter(
- _readNode(data.defaultFormalParameter_parameter),
- _toParameterKind(data.defaultFormalParameter_kind),
- data.defaultFormalParameter_defaultValue != null ? _Tokens.COLON : null,
- _readNodeLazy(data.defaultFormalParameter_defaultValue),
- );
- LazyFormalParameter.setData(node, data);
- return node;
- }
-
- DoStatement _read_doStatement(LinkedNode data) {
- return astFactory.doStatement(
- _Tokens.DO,
- _readNode(data.doStatement_body),
- _Tokens.WHILE,
- _Tokens.OPEN_PAREN,
- _readNode(data.doStatement_condition),
- _Tokens.CLOSE_PAREN,
- _Tokens.SEMICOLON,
- );
- }
-
- DottedName _read_dottedName(LinkedNode data) {
- return astFactory.dottedName(
- _readNodeList(data.dottedName_components),
- );
- }
-
- DoubleLiteral _read_doubleLiteral(LinkedNode data) {
- return AstTestFactory.doubleLiteral(data.doubleLiteral_value)
- ..staticType = _doubleType;
- }
-
- EmptyFunctionBody _read_emptyFunctionBody(LinkedNode data) {
- return astFactory.emptyFunctionBody(
- _Tokens.SEMICOLON,
- );
- }
-
- EmptyStatement _read_emptyStatement(LinkedNode data) {
- return astFactory.emptyStatement(
- _Tokens.SEMICOLON,
- );
- }
-
- EnumConstantDeclaration _read_enumConstantDeclaration(LinkedNode data) {
- var node = astFactory.enumConstantDeclaration(
- _readDocumentationComment(data),
- _readNodeListLazy(data.annotatedNode_metadata),
- _declaredIdentifier(data),
- );
- LazyEnumConstantDeclaration.setData(node, data);
- return node;
- }
-
- EnumDeclaration _read_enumDeclaration(LinkedNode data) {
- var node = astFactory.enumDeclaration(
- _readDocumentationComment(data),
- _readNodeListLazy(data.annotatedNode_metadata),
- _Tokens.ENUM,
- _declaredIdentifier(data),
- _Tokens.OPEN_CURLY_BRACKET,
- _readNodeListLazy(data.enumDeclaration_constants),
- _Tokens.CLOSE_CURLY_BRACKET,
- );
- LazyEnumDeclaration.setData(node, data);
- return node;
- }
-
- ExportDirective _read_exportDirective(LinkedNode data) {
- timerAstBinaryReaderDirective.start();
- _isReadingDirective = true;
- try {
- var node = astFactory.exportDirective(
- _readDocumentationComment(data),
- _readNodeListLazy(data.annotatedNode_metadata),
- _directiveKeyword(data, Keyword.EXPORT, _Tokens.EXPORT),
- _readNode(data.uriBasedDirective_uri),
- _readNodeList(data.namespaceDirective_configurations),
- _readNodeList(data.namespaceDirective_combinators),
- _Tokens.SEMICOLON,
- );
- LazyDirective.setData(node, data);
- return node;
- } finally {
- _isReadingDirective = false;
- timerAstBinaryReaderDirective.stop();
- }
- }
-
- ExpressionFunctionBody _read_expressionFunctionBody(LinkedNode data) {
- timerAstBinaryReaderFunctionBody.start();
- try {
- return astFactory.expressionFunctionBody(
- _Tokens.choose(
- AstBinaryFlags.isAsync(data.flags),
- _Tokens.ASYNC,
- AstBinaryFlags.isSync(data.flags),
- _Tokens.SYNC,
- ),
- _Tokens.ARROW,
- _readNode(data.expressionFunctionBody_expression),
- _Tokens.SEMICOLON,
- );
- } finally {
- timerAstBinaryReaderFunctionBody.stop();
- }
- }
-
- ExpressionStatement _read_expressionStatement(LinkedNode data) {
- return astFactory.expressionStatement(
- _readNode(data.expressionStatement_expression),
- _Tokens.SEMICOLON,
- );
- }
-
- ExtendsClause _read_extendsClause(LinkedNode data) {
- return astFactory.extendsClause(
- _Tokens.EXTENDS,
- _readNode(data.extendsClause_superclass),
- );
- }
-
- ExtensionDeclaration _read_extensionDeclaration(LinkedNode data) {
- timerAstBinaryReaderClass.start();
- try {
- var node = astFactory.extensionDeclaration(
- comment: _readDocumentationComment(data),
- metadata: _readNodeListLazy(data.annotatedNode_metadata),
- extensionKeyword: _Tokens.EXTENSION,
- name: data.name.isNotEmpty ? _declaredIdentifier(data) : null,
- typeParameters: _readNode(data.extensionDeclaration_typeParameters),
- onKeyword: _Tokens.ON,
- extendedType: _readNodeLazy(data.extensionDeclaration_extendedType),
- leftBracket: _Tokens.OPEN_CURLY_BRACKET,
- members: _readNodeListLazy(data.extensionDeclaration_members),
- rightBracket: _Tokens.CLOSE_CURLY_BRACKET,
- );
- LazyExtensionDeclaration(node, data);
- return node;
- } finally {
- timerAstBinaryReaderClass.stop();
- }
- }
-
- ExtensionOverride _read_extensionOverride(LinkedNode data) {
- var node = astFactory.extensionOverride(
- extensionName: _readNode(data.extensionOverride_extensionName),
- argumentList: astFactory.argumentList(
- _Tokens.OPEN_PAREN,
- _readNodeList(
- data.extensionOverride_arguments,
- ),
- _Tokens.CLOSE_PAREN,
- ),
- typeArguments: _readNode(data.extensionOverride_typeArguments),
- ) as ExtensionOverrideImpl;
- node.extendedType = _readType(data.extensionOverride_extendedType);
- node.typeArgumentTypes =
- data.extensionOverride_typeArgumentTypes.map(_readType).toList();
- return node;
- }
-
- FieldDeclaration _read_fieldDeclaration(LinkedNode data) {
- var node = astFactory.fieldDeclaration2(
- comment: _readDocumentationComment(data),
- abstractKeyword:
- AstBinaryFlags.isAbstract(data.flags) ? _Tokens.ABSTRACT : null,
- covariantKeyword:
- AstBinaryFlags.isCovariant(data.flags) ? _Tokens.COVARIANT : null,
- externalKeyword:
- AstBinaryFlags.isExternal(data.flags) ? _Tokens.EXTERNAL : null,
- fieldList: _readNode(data.fieldDeclaration_fields),
- metadata: _readNodeListLazy(data.annotatedNode_metadata),
- semicolon: _Tokens.SEMICOLON,
- staticKeyword:
- AstBinaryFlags.isStatic(data.flags) ? _Tokens.STATIC : null,
- );
- LazyFieldDeclaration.setData(node, data);
- return node;
- }
-
- FieldFormalParameter _read_fieldFormalParameter(LinkedNode data) {
- var node = astFactory.fieldFormalParameter2(
- identifier: _declaredIdentifier(data),
- period: _Tokens.PERIOD,
- thisKeyword: _Tokens.THIS,
- covariantKeyword:
- AstBinaryFlags.isCovariant(data.flags) ? _Tokens.COVARIANT : null,
- typeParameters: _readNode(data.fieldFormalParameter_typeParameters),
- keyword: _Tokens.choose(
- AstBinaryFlags.isConst(data.flags),
- _Tokens.CONST,
- AstBinaryFlags.isFinal(data.flags),
- _Tokens.FINAL,
- AstBinaryFlags.isVar(data.flags),
- _Tokens.VAR,
- ),
- metadata: _readNodeList(data.normalFormalParameter_metadata),
- comment: _readDocumentationComment(data),
- type: _readNodeLazy(data.fieldFormalParameter_type),
- parameters: _readNodeLazy(data.fieldFormalParameter_formalParameters),
- question:
- AstBinaryFlags.hasQuestion(data.flags) ? _Tokens.QUESTION : null,
- requiredKeyword:
- AstBinaryFlags.isRequired(data.flags) ? _Tokens.REQUIRED : null,
- );
- LazyFormalParameter.setData(node, data);
- return node;
- }
-
- ForEachPartsWithDeclaration _read_forEachPartsWithDeclaration(
- LinkedNode data) {
- return astFactory.forEachPartsWithDeclaration(
- inKeyword: _Tokens.IN,
- iterable: _readNode(data.forEachParts_iterable),
- loopVariable: _readNode(data.forEachPartsWithDeclaration_loopVariable),
- );
- }
-
- ForEachPartsWithIdentifier _read_forEachPartsWithIdentifier(LinkedNode data) {
- return astFactory.forEachPartsWithIdentifier(
- inKeyword: _Tokens.IN,
- iterable: _readNode(data.forEachParts_iterable),
- identifier: _readNode(data.forEachPartsWithIdentifier_identifier),
- );
- }
-
- ForElement _read_forElement(LinkedNode data) {
- return astFactory.forElement(
- awaitKeyword: AstBinaryFlags.hasAwait(data.flags) ? _Tokens.AWAIT : null,
- body: _readNode(data.forElement_body),
- forKeyword: _Tokens.FOR,
- forLoopParts: _readNode(data.forMixin_forLoopParts),
- leftParenthesis: _Tokens.OPEN_PAREN,
- rightParenthesis: _Tokens.CLOSE_PAREN,
- );
- }
-
- FormalParameterList _read_formalParameterList(LinkedNode data) {
- return astFactory.formalParameterList(
- _Tokens.OPEN_PAREN,
- _readNodeList(data.formalParameterList_parameters),
- _Tokens.choose(
- AstBinaryFlags.isDelimiterCurly(data.flags),
- _Tokens.OPEN_CURLY_BRACKET,
- AstBinaryFlags.isDelimiterSquare(data.flags),
- _Tokens.OPEN_SQUARE_BRACKET,
- ),
- _Tokens.choose(
- AstBinaryFlags.isDelimiterCurly(data.flags),
- _Tokens.CLOSE_CURLY_BRACKET,
- AstBinaryFlags.isDelimiterSquare(data.flags),
- _Tokens.CLOSE_SQUARE_BRACKET,
- ),
- _Tokens.CLOSE_PAREN,
- );
- }
-
- ForPartsWithDeclarations _read_forPartsWithDeclarations(LinkedNode data) {
- return astFactory.forPartsWithDeclarations(
- condition: _readNode(data.forParts_condition),
- leftSeparator: _Tokens.SEMICOLON,
- rightSeparator: _Tokens.SEMICOLON,
- updaters: _readNodeList(data.forParts_updaters),
- variables: _readNode(data.forPartsWithDeclarations_variables),
- );
- }
-
- ForPartsWithExpression _read_forPartsWithExpression(LinkedNode data) {
- return astFactory.forPartsWithExpression(
- condition: _readNode(data.forParts_condition),
- initialization: _readNode(data.forPartsWithExpression_initialization),
- leftSeparator: _Tokens.SEMICOLON,
- rightSeparator: _Tokens.SEMICOLON,
- updaters: _readNodeList(data.forParts_updaters),
- );
- }
-
- ForStatement _read_forStatement(LinkedNode data) {
- return astFactory.forStatement(
- awaitKeyword: AstBinaryFlags.hasAwait(data.flags) ? _Tokens.AWAIT : null,
- forKeyword: _Tokens.FOR,
- leftParenthesis: _Tokens.OPEN_PAREN,
- forLoopParts: _readNode(data.forMixin_forLoopParts),
- rightParenthesis: _Tokens.CLOSE_PAREN,
- body: _readNode(data.forStatement_body),
- );
- }
-
- FunctionDeclaration _read_functionDeclaration(LinkedNode data) {
- timerAstBinaryReaderFunctionDeclaration.start();
- try {
- var node = astFactory.functionDeclaration(
- _readDocumentationComment(data),
- _readNodeListLazy(data.annotatedNode_metadata),
- AstBinaryFlags.isExternal(data.flags) ? _Tokens.EXTERNAL : null,
- _readNodeLazy(data.functionDeclaration_returnType),
- _Tokens.choose(
- AstBinaryFlags.isGet(data.flags),
- _Tokens.GET,
- AstBinaryFlags.isSet(data.flags),
- _Tokens.SET,
- ),
- _declaredIdentifier(data),
- _readNodeLazy(data.functionDeclaration_functionExpression),
- );
- LazyFunctionDeclaration.setData(node, data);
- return node;
- } finally {
- timerAstBinaryReaderFunctionDeclaration.stop();
- }
- }
-
- FunctionDeclarationStatement _read_functionDeclarationStatement(
- LinkedNode data) {
- return astFactory.functionDeclarationStatement(
- _readNode(data.functionDeclarationStatement_functionDeclaration),
- );
- }
-
- FunctionExpression _read_functionExpression(LinkedNode data) {
- var node = astFactory.functionExpression(
- _readNode(data.functionExpression_typeParameters),
- _readNodeLazy(data.functionExpression_formalParameters),
- _readNodeLazy(data.functionExpression_body),
- );
- LazyFunctionExpression.setData(node, data);
- return node;
- }
-
- FunctionExpressionInvocation _read_functionExpressionInvocation(
- LinkedNode data) {
- return astFactory.functionExpressionInvocation(
- _readNode(data.functionExpressionInvocation_function),
- _readNode(data.invocationExpression_typeArguments),
- _readNode(data.invocationExpression_arguments),
- )..staticInvokeType = _readType(data.invocationExpression_invokeType);
- }
-
- FunctionTypeAlias _read_functionTypeAlias(LinkedNode data) {
- var node = astFactory.functionTypeAlias(
- _readDocumentationComment(data),
- _readNodeListLazy(data.annotatedNode_metadata),
- _Tokens.TYPEDEF,
- _readNodeLazy(data.functionTypeAlias_returnType),
- _declaredIdentifier(data),
- _readNode(data.functionTypeAlias_typeParameters),
- _readNodeLazy(data.functionTypeAlias_formalParameters),
- _Tokens.SEMICOLON,
- );
- LazyFunctionTypeAlias.setData(node, data);
- LazyFunctionTypeAlias.setHasSelfReference(
- node,
- data.typeAlias_hasSelfReference,
- );
- return node;
- }
-
- FunctionTypedFormalParameter _read_functionTypedFormalParameter(
- LinkedNode data) {
- var node = astFactory.functionTypedFormalParameter2(
- comment: _readDocumentationComment(data),
- covariantKeyword:
- AstBinaryFlags.isCovariant(data.flags) ? _Tokens.COVARIANT : null,
- identifier: _declaredIdentifier(data),
- metadata: _readNodeListLazy(data.normalFormalParameter_metadata),
- parameters: _readNodeLazy(
- data.functionTypedFormalParameter_formalParameters,
- ),
- requiredKeyword:
- AstBinaryFlags.isRequired(data.flags) ? _Tokens.REQUIRED : null,
- returnType: _readNodeLazy(data.functionTypedFormalParameter_returnType),
- typeParameters: _readNode(
- data.functionTypedFormalParameter_typeParameters,
- ),
- );
- LazyFormalParameter.setData(node, data);
- return node;
- }
-
- GenericFunctionType _read_genericFunctionType(LinkedNode data) {
- var id = data.genericFunctionType_id;
-
- // Read type parameters, without bounds, to avoid forward references.
- TypeParameterList typeParameterList;
- var typeParameterListData = data.genericFunctionType_typeParameters;
- if (typeParameterListData != null) {
- var dataList = typeParameterListData.typeParameterList_typeParameters;
- var typeParameters = List<TypeParameter>(dataList.length);
- for (var i = 0; i < dataList.length; ++i) {
- var data = dataList[i];
- typeParameters[i] = astFactory.typeParameter(
- _readDocumentationComment(data),
- _readNodeList(data.annotatedNode_metadata),
- _declaredIdentifier(data),
- data.typeParameter_bound != null ? _Tokens.EXTENDS : null,
- null,
- );
- }
- typeParameterList = astFactory.typeParameterList(
- _Tokens.LT,
- typeParameters,
- _Tokens.GT,
- );
- }
-
- GenericFunctionTypeImpl node = astFactory.genericFunctionType(
null,
- _Tokens.FUNCTION,
- typeParameterList,
- null,
- question:
- AstBinaryFlags.hasQuestion(data.flags) ? _Tokens.QUESTION : null,
- );
-
- // Create the node element, so now type parameter elements are available.
- LazyAst.setGenericFunctionTypeId(node, id);
- _unitContext.createGenericFunctionTypeElement(id, node);
-
- // Finish reading.
- if (typeParameterListData != null) {
- var dataList = typeParameterListData.typeParameterList_typeParameters;
- var typeParameters = typeParameterList.typeParameters;
- for (var i = 0; i < dataList.length; ++i) {
- var data = dataList[i];
- var node = typeParameters[i];
- node.bound = _readNode(data.typeParameter_bound);
- }
- }
- node.returnType = readNode(data.genericFunctionType_returnType);
- node.parameters = _readNode(data.genericFunctionType_formalParameters);
- node.type = _readType(data.genericFunctionType_type);
-
- return node;
- }
-
- GenericTypeAlias _read_genericTypeAlias(LinkedNode data) {
- var node = astFactory.genericTypeAlias(
- _readDocumentationComment(data),
- _readNodeListLazy(data.annotatedNode_metadata),
- _Tokens.TYPEDEF,
- _declaredIdentifier(data),
- _readNode(data.genericTypeAlias_typeParameters),
- _Tokens.EQ,
- _readNodeLazy(data.genericTypeAlias_functionType),
- _Tokens.SEMICOLON,
- );
- LazyGenericTypeAlias.setData(node, data);
- LazyGenericTypeAlias.setHasSelfReference(
- node,
- data.typeAlias_hasSelfReference,
- );
- return node;
- }
-
- HideCombinator _read_hideCombinator(LinkedNode data) {
- var node = astFactory.hideCombinator(
- _combinatorKeyword(data, Keyword.HIDE, _Tokens.HIDE),
- data.names.map((name) => AstTestFactory.identifier3(name)).toList(),
- );
- LazyCombinator(node, data);
- return node;
- }
-
- IfElement _read_ifElement(LinkedNode data) {
- var elseElement = _readNode(data.ifElement_elseElement);
- return astFactory.ifElement(
- condition: _readNode(data.ifMixin_condition),
- elseElement: elseElement,
- elseKeyword: elseElement != null ? _Tokens.ELSE : null,
- ifKeyword: _Tokens.IF,
- leftParenthesis: _Tokens.OPEN_PAREN,
- rightParenthesis: _Tokens.CLOSE_PAREN,
- thenElement: _readNode(data.ifElement_thenElement),
- );
- }
-
- IfStatement _read_ifStatement(LinkedNode data) {
- var elseStatement = _readNode(data.ifStatement_elseStatement);
- return astFactory.ifStatement(
- _Tokens.IF,
- _Tokens.OPEN_PAREN,
- _readNode(data.ifMixin_condition),
- _Tokens.CLOSE_PAREN,
- _readNode(data.ifStatement_thenStatement),
- elseStatement != null ? _Tokens.ELSE : null,
- elseStatement,
- );
- }
-
- ImplementsClause _read_implementsClause(LinkedNode data) {
- return astFactory.implementsClause(
- _Tokens.IMPLEMENTS,
- _readNodeList(data.implementsClause_interfaces),
- );
- }
-
- ImportDirective _read_importDirective(LinkedNode data) {
- timerAstBinaryReaderDirective.start();
- _isReadingDirective = true;
- try {
- SimpleIdentifier prefix;
- if (data.importDirective_prefix.isNotEmpty) {
- prefix = astFactory.simpleIdentifier(
- TokenFactory.tokenFromString(data.importDirective_prefix),
- );
-
- var informativeData = _unitContext.getInformativeData(data);
- prefix.token.offset =
- informativeData?.importDirective_prefixOffset ?? 0;
- }
-
- var node = astFactory.importDirective(
- _readDocumentationComment(data),
- _readNodeListLazy(data.annotatedNode_metadata),
- _directiveKeyword(data, Keyword.IMPORT, _Tokens.IMPORT),
- _readNode(data.uriBasedDirective_uri),
- _readNodeList(data.namespaceDirective_configurations),
- AstBinaryFlags.isDeferred(data.flags) ? _Tokens.DEFERRED : null,
- _Tokens.AS,
- prefix,
- _readNodeList(data.namespaceDirective_combinators),
- _Tokens.SEMICOLON,
- );
- LazyDirective.setData(node, data);
- return node;
- } finally {
- _isReadingDirective = false;
- timerAstBinaryReaderDirective.stop();
- }
- }
-
- IndexExpression _read_indexExpression(LinkedNode data) {
- return astFactory.indexExpressionForTarget2(
- target: _readNode(data.indexExpression_target),
- question:
- AstBinaryFlags.hasQuestion(data.flags) ? _Tokens.QUESTION : null,
- leftBracket: _Tokens.OPEN_SQUARE_BRACKET,
- index: _readNode(data.indexExpression_index),
- rightBracket: _Tokens.CLOSE_SQUARE_BRACKET,
- )
- ..period =
- AstBinaryFlags.hasPeriod(data.flags) ? _Tokens.PERIOD_PERIOD : null
- ..staticElement = _elementOfComponents(
- data.indexExpression_element,
- data.indexExpression_substitution,
- )
- ..staticType = _readType(data.expression_type);
- }
-
- InstanceCreationExpression _read_instanceCreationExpression(LinkedNode data) {
- var node = astFactory.instanceCreationExpression(
- _Tokens.choose(
- AstBinaryFlags.isConst(data.flags),
- _Tokens.CONST,
- AstBinaryFlags.isNew(data.flags),
- _Tokens.NEW,
+ metadata,
+ Tokens.choose(
+ AstBinaryFlags.isConst(flags),
+ Tokens.CONST,
+ AstBinaryFlags.isFinal(flags),
+ Tokens.FINAL,
+ AstBinaryFlags.isVar(flags),
+ Tokens.VAR,
),
- _readNode(data.instanceCreationExpression_constructorName),
- astFactory.argumentList(
- _Tokens.OPEN_PAREN,
- _readNodeList(
- data.instanceCreationExpression_arguments,
- ),
- _Tokens.CLOSE_PAREN,
- ),
- typeArguments: _readNode(data.instanceCreationExpression_typeArguments),
- );
- node.staticType = _readType(data.expression_type);
- return node;
- }
-
- IntegerLiteral _read_integerLiteral(LinkedNode data) {
- // TODO(scheglov) Remove `?? _intType` after internal SDK roll.
- return AstTestFactory.integer(data.integerLiteral_value)
- ..staticType = _readType(data.expression_type) ?? _intType;
- }
-
- InterpolationExpression _read_interpolationExpression(LinkedNode data) {
- var isIdentifier =
- AstBinaryFlags.isStringInterpolationIdentifier(data.flags);
- return astFactory.interpolationExpression(
- isIdentifier
- ? _Tokens.OPEN_CURLY_BRACKET
- : _Tokens.STRING_INTERPOLATION_EXPRESSION,
- _readNode(data.interpolationExpression_expression),
- isIdentifier ? null : _Tokens.CLOSE_CURLY_BRACKET,
+ type,
+ identifier,
);
}
- InterpolationString _read_interpolationString(LinkedNode data) {
- return astFactory.interpolationString(
- TokenFactory.tokenFromString(data.interpolationString_value),
- data.interpolationString_value,
- );
- }
+ DefaultFormalParameter _readDefaultFormalParameter() {
+ var flags = _readByte();
+ var codeOffset = _readInformativeUint30();
+ var codeLength = _readInformativeUint30();
+ var parameter = readNode() as NormalFormalParameter;
+ var defaultValue = _readOptionalNode() as Expression;
- IsExpression _read_isExpression(LinkedNode data) {
- return astFactory.isExpression(
- _readNode(data.isExpression_expression),
- _Tokens.IS,
- AstBinaryFlags.hasNot(data.flags) ? _Tokens.BANG : null,
- _readNode(data.isExpression_type),
- )..staticType = _boolType;
- }
-
- Label _read_label(LinkedNode data) {
- return astFactory.label(
- _readNode(data.label_label),
- _Tokens.COLON,
- );
- }
-
- LabeledStatement _read_labeledStatement(LinkedNode data) {
- return astFactory.labeledStatement(
- _readNodeList(data.labeledStatement_labels),
- _readNode(data.labeledStatement_statement),
- );
- }
-
- LibraryDirective _read_libraryDirective(LinkedNode data) {
- timerAstBinaryReaderDirective.start();
- _isReadingDirective = true;
- try {
- var node = astFactory.libraryDirective(
- _unitContext.createComment(data),
- _readNodeListLazy(data.annotatedNode_metadata),
- _Tokens.LIBRARY,
- _readNode(data.libraryDirective_name),
- _Tokens.SEMICOLON,
- );
- LazyDirective.setData(node, data);
- return node;
- } finally {
- _isReadingDirective = false;
- timerAstBinaryReaderDirective.stop();
- }
- }
-
- LibraryIdentifier _read_libraryIdentifier(LinkedNode data) {
- return astFactory.libraryIdentifier(
- _readNodeList(data.libraryIdentifier_components),
- );
- }
-
- ListLiteral _read_listLiteral(LinkedNode data) {
- return astFactory.listLiteral(
- AstBinaryFlags.isConst(data.flags) ? _Tokens.CONST : null,
- AstBinaryFlags.hasTypeArguments(data.flags)
- ? astFactory.typeArgumentList(
- _Tokens.LT,
- _readNodeList(data.typedLiteral_typeArguments),
- _Tokens.GT,
- )
- : null,
- _Tokens.OPEN_SQUARE_BRACKET,
- _readNodeList(data.listLiteral_elements),
- _Tokens.CLOSE_SQUARE_BRACKET,
- )..staticType = _readType(data.expression_type);
- }
-
- MapLiteralEntry _read_mapLiteralEntry(LinkedNode data) {
- return astFactory.mapLiteralEntry(
- _readNode(data.mapLiteralEntry_key),
- _Tokens.COLON,
- _readNode(data.mapLiteralEntry_value),
- );
- }
-
- MethodDeclaration _read_methodDeclaration(LinkedNode data) {
- FunctionBody body;
- if (AstBinaryFlags.isNative(data.flags)) {
- body = AstTestFactory.nativeFunctionBody('');
- } else if (AstBinaryFlags.isAbstract(data.flags)) {
- body = AstTestFactory.emptyFunctionBody();
+ ParameterKind kind;
+ if (AstBinaryFlags.isPositional(flags)) {
+ kind = AstBinaryFlags.isRequired(flags)
+ ? ParameterKind.REQUIRED
+ : ParameterKind.POSITIONAL;
} else {
- body = AstTestFactory.blockFunctionBody(AstTestFactory.block());
+ kind = AstBinaryFlags.isRequired(flags)
+ ? ParameterKind.NAMED_REQUIRED
+ : ParameterKind.NAMED;
}
- var node = astFactory.methodDeclaration(
- _readDocumentationComment(data),
- _readNodeListLazy(data.annotatedNode_metadata),
- AstBinaryFlags.isExternal(data.flags) ? _Tokens.EXTERNAL : null,
- AstBinaryFlags.isStatic(data.flags) ? _Tokens.STATIC : null,
- _readNodeLazy(data.methodDeclaration_returnType),
- _Tokens.choose(
- AstBinaryFlags.isGet(data.flags),
- _Tokens.GET,
- AstBinaryFlags.isSet(data.flags),
- _Tokens.SET,
+ var node = astFactory.defaultFormalParameter(
+ parameter,
+ kind,
+ AstBinaryFlags.hasInitializer(flags) ? Tokens.COLON : null,
+ defaultValue,
+ ) as DefaultFormalParameterImpl;
+ node.summaryData = SummaryDataForFormalParameter(
+ codeOffset: codeOffset,
+ codeLength: codeLength,
+ );
+
+ return node;
+ }
+
+ DottedName _readDottedName() {
+ var components = _readNodeList<SimpleIdentifier>();
+ return astFactory.dottedName(components);
+ }
+
+ DoubleLiteral _readDoubleLiteral() {
+ var value = _unitReader.astReader.readDouble();
+ return AstTestFactory.doubleLiteral(value);
+ }
+
+ EnumConstantDeclaration _readEnumConstantDeclaration() {
+ var codeOffset = _readInformativeUint30();
+ var codeLength = _readInformativeUint30();
+ var documentationTokenIndexList = _readUint30List();
+
+ var name = readNode() as SimpleIdentifier;
+ var metadata = _readNodeList<Annotation>();
+
+ var node = astFactory.enumConstantDeclaration(null, metadata, name)
+ as EnumConstantDeclarationImpl;
+
+ node.linkedContext = LinkedContext(
+ _unitReader,
+ node,
+ codeOffset: codeOffset,
+ codeLength: codeLength,
+ resolutionIndex: -1,
+ documentationTokenIndexList: documentationTokenIndexList,
+ );
+
+ return node;
+ }
+
+ EnumDeclaration _readEnumDeclaration() {
+ var codeOffset = _readInformativeUint30();
+ var codeLength = _readInformativeUint30();
+ var documentationTokenIndexList = _readUint30List();
+
+ var constants = _readNodeList<EnumConstantDeclaration>();
+ var name = readNode() as SimpleIdentifier;
+ var metadata = _readNodeList<Annotation>();
+
+ var node = astFactory.enumDeclaration(
+ null,
+ metadata,
+ Tokens.ENUM,
+ name,
+ Tokens.OPEN_CURLY_BRACKET,
+ constants,
+ Tokens.CLOSE_CURLY_BRACKET,
+ ) as EnumDeclarationImpl;
+
+ node.linkedContext = LinkedContext(
+ _unitReader,
+ node,
+ codeOffset: codeOffset,
+ codeLength: codeLength,
+ resolutionIndex: _readUInt30(),
+ documentationTokenIndexList: documentationTokenIndexList,
+ );
+
+ return node;
+ }
+
+ ExportDirective _readExportDirective() {
+ var combinators = _readNodeList<Combinator>();
+ var configurations = _readNodeList<Configuration>();
+ var uri = readNode();
+ var keywordOffset = _readInformativeUint30();
+ var metadata = _readNodeList<Annotation>();
+
+ var node = astFactory.exportDirective(
+ null,
+ metadata,
+ KeywordToken(Keyword.EXPORT, keywordOffset),
+ uri,
+ configurations,
+ combinators,
+ Tokens.SEMICOLON,
+ ) as ExportDirectiveImpl;
+
+ node.linkedContext = LinkedContext(
+ _unitReader,
+ node,
+ codeOffset: -1,
+ codeLength: 0,
+ documentationTokenIndexList: _noDocumentationComment,
+ resolutionIndex: _readUInt30(),
+ );
+
+ return node;
+ }
+
+ ExtendsClause _readExtendsClause() {
+ var type = readNode() as TypeName;
+ return astFactory.extendsClause(Tokens.EXTENDS, type);
+ }
+
+ ExtensionDeclaration _readExtensionDeclaration() {
+ var codeOffset = _readInformativeUint30();
+ var codeLength = _readInformativeUint30();
+ var documentationTokenIndexList = _readUint30List();
+
+ var typeParameters = _readOptionalNode() as TypeParameterList;
+ var extendedType = readNode() as TypeAnnotation;
+ var name = _readOptionalNode() as SimpleIdentifier;
+ var metadata = _readNodeList<Annotation>();
+
+ var node = astFactory.extensionDeclaration(
+ comment: null,
+ metadata: metadata,
+ extensionKeyword: Tokens.EXTENSION,
+ name: name,
+ typeParameters: typeParameters,
+ onKeyword: Tokens.ON,
+ extendedType: extendedType,
+ leftBracket: Tokens.OPEN_CURLY_BRACKET,
+ members: const <ClassMember>[],
+ rightBracket: Tokens.CLOSE_CURLY_BRACKET,
+ ) as ExtensionDeclarationImpl;
+
+ node.linkedContext = LinkedContext(
+ _unitReader,
+ node,
+ codeOffset: codeOffset,
+ codeLength: codeLength,
+ resolutionIndex: _readUInt30(),
+ documentationTokenIndexList: documentationTokenIndexList,
+ );
+
+ return node;
+ }
+
+ ExtensionOverride _readExtensionOverride() {
+ var extensionName = readNode() as Identifier;
+ var typeArguments = _readOptionalNode() as TypeArgumentList;
+ var argumentList = readNode() as ArgumentList;
+ return astFactory.extensionOverride(
+ extensionName: extensionName,
+ argumentList: argumentList,
+ typeArguments: typeArguments,
+ );
+ }
+
+ FieldDeclaration _readFieldDeclaration() {
+ var flags = _readByte();
+ var codeOffsetLengthList = _readInformativeUint30List();
+ var documentationTokenIndexList = _readUint30List();
+ var fields = readNode() as VariableDeclarationList;
+ var metadata = _readNodeList<Annotation>();
+
+ var node = astFactory.fieldDeclaration2(
+ comment: null,
+ abstractKeyword:
+ AstBinaryFlags.isAbstract(flags) ? Tokens.ABSTRACT : null,
+ covariantKeyword:
+ AstBinaryFlags.isCovariant(flags) ? Tokens.COVARIANT : null,
+ externalKeyword:
+ AstBinaryFlags.isExternal(flags) ? Tokens.EXTERNAL : null,
+ fieldList: fields,
+ metadata: metadata,
+ semicolon: Tokens.SEMICOLON,
+ staticKeyword: AstBinaryFlags.isStatic(flags) ? Tokens.STATIC : null,
+ ) as FieldDeclarationImpl;
+
+ node.linkedContext = LinkedContext(
+ _unitReader,
+ node,
+ codeOffset: -1,
+ codeLength: 0,
+ codeOffsetLengthList: codeOffsetLengthList,
+ resolutionIndex: _readUInt30(),
+ documentationTokenIndexList: documentationTokenIndexList,
+ );
+
+ return node;
+ }
+
+ FieldFormalParameter _readFieldFormalParameter() {
+ var typeParameters = _readOptionalNode() as TypeParameterList;
+ var type = _readOptionalNode() as TypeAnnotation;
+ var formalParameters = _readOptionalNode() as FormalParameterList;
+ var flags = _readByte();
+ var codeOffset = _readInformativeUint30();
+ var codeLength = _readInformativeUint30();
+ var metadata = _readNodeList<Annotation>();
+ var identifier = readNode() as SimpleIdentifier;
+ var node = astFactory.fieldFormalParameter2(
+ identifier: identifier,
+ period: Tokens.PERIOD,
+ thisKeyword: Tokens.THIS,
+ covariantKeyword:
+ AstBinaryFlags.isCovariant(flags) ? Tokens.COVARIANT : null,
+ typeParameters: typeParameters,
+ keyword: Tokens.choose(
+ AstBinaryFlags.isConst(flags),
+ Tokens.CONST,
+ AstBinaryFlags.isFinal(flags),
+ Tokens.FINAL,
+ AstBinaryFlags.isVar(flags),
+ Tokens.VAR,
),
- AstBinaryFlags.isOperator(data.flags) ? _Tokens.OPERATOR : null,
- _declaredIdentifier(data),
- _readNode(data.methodDeclaration_typeParameters),
- _readNodeLazy(data.methodDeclaration_formalParameters),
+ metadata: metadata,
+ comment: null,
+ type: type,
+ parameters: formalParameters,
+ question: AstBinaryFlags.hasQuestion(flags) ? Tokens.QUESTION : null,
+ requiredKeyword:
+ AstBinaryFlags.isRequired(flags) ? Tokens.REQUIRED : null,
+ ) as FieldFormalParameterImpl;
+ node.summaryData = SummaryDataForFormalParameter(
+ codeOffset: codeOffset,
+ codeLength: codeLength,
+ );
+ return node;
+ }
+
+ ForEachPartsWithDeclaration _readForEachPartsWithDeclaration() {
+ var loopVariable = readNode() as DeclaredIdentifier;
+ var iterable = readNode() as Expression;
+ return astFactory.forEachPartsWithDeclaration(
+ inKeyword: Tokens.IN,
+ iterable: iterable,
+ loopVariable: loopVariable,
+ );
+ }
+
+ ForElement _readForElement() {
+ var body = readNode() as CollectionElement;
+ var flags = _readByte();
+ var forLoopParts = readNode() as ForLoopParts;
+ return astFactory.forElement(
+ awaitKeyword: AstBinaryFlags.hasAwait(flags) ? Tokens.AWAIT : null,
+ body: body,
+ forKeyword: Tokens.FOR,
+ forLoopParts: forLoopParts,
+ leftParenthesis: Tokens.OPEN_PAREN,
+ rightParenthesis: Tokens.CLOSE_PAREN,
+ );
+ }
+
+ FormalParameterList _readFormalParameterList() {
+ var flags = _readByte();
+ var parameters = _readNodeList<FormalParameter>();
+
+ return astFactory.formalParameterList(
+ Tokens.OPEN_PAREN,
+ parameters,
+ Tokens.choose(
+ AstBinaryFlags.isDelimiterCurly(flags),
+ Tokens.OPEN_CURLY_BRACKET,
+ AstBinaryFlags.isDelimiterSquare(flags),
+ Tokens.OPEN_SQUARE_BRACKET,
+ ),
+ Tokens.choose(
+ AstBinaryFlags.isDelimiterCurly(flags),
+ Tokens.CLOSE_CURLY_BRACKET,
+ AstBinaryFlags.isDelimiterSquare(flags),
+ Tokens.CLOSE_SQUARE_BRACKET,
+ ),
+ Tokens.CLOSE_PAREN,
+ );
+ }
+
+ ForPartsWithDeclarations _readForPartsWithDeclarations() {
+ var variables = readNode() as VariableDeclarationList;
+ var condition = _readOptionalNode() as Expression;
+ var updaters = _readNodeList<Expression>();
+ return astFactory.forPartsWithDeclarations(
+ condition: condition,
+ leftSeparator: Tokens.SEMICOLON,
+ rightSeparator: Tokens.SEMICOLON,
+ updaters: updaters,
+ variables: variables,
+ );
+ }
+
+ FunctionDeclaration _readFunctionDeclaration() {
+ var flags = _readByte();
+ var codeOffset = _readInformativeUint30();
+ var codeLength = _readInformativeUint30();
+ var documentationTokenIndexList = _readUint30List();
+ var functionExpression = readNode() as FunctionExpression;
+ var returnType = _readOptionalNode() as TypeAnnotation;
+ var name = readNode() as SimpleIdentifier;
+ var metadata = _readNodeList<Annotation>();
+
+ var node = astFactory.functionDeclaration(
+ null,
+ metadata,
+ AstBinaryFlags.isExternal(flags) ? Tokens.EXTERNAL : null,
+ returnType,
+ Tokens.choose(
+ AstBinaryFlags.isGet(flags),
+ Tokens.GET,
+ AstBinaryFlags.isSet(flags),
+ Tokens.SET,
+ ),
+ name,
+ functionExpression,
+ ) as FunctionDeclarationImpl;
+
+ node.linkedContext = LinkedContext(
+ _unitReader,
+ node,
+ codeOffset: codeOffset,
+ codeLength: codeLength,
+ resolutionIndex: _readUInt30(),
+ documentationTokenIndexList: documentationTokenIndexList,
+ );
+
+ return node;
+ }
+
+ FunctionExpression _readFunctionExpression() {
+ var flags = _readByte();
+ var typeParameters = _readOptionalNode() as TypeParameterList;
+ var formalParameters = _readOptionalNode() as FormalParameterList;
+ var body = _functionBodyForFlags(flags);
+
+ return astFactory.functionExpression(
+ typeParameters,
+ formalParameters,
body,
);
- LazyMethodDeclaration.setData(node, data);
- LazyAst.setOperatorEqualParameterTypeFromObject(
+ }
+
+ FunctionExpressionInvocation _readFunctionExpressionInvocation() {
+ var function = readNode() as Expression;
+ var typeArguments = _readOptionalNode() as TypeArgumentList;
+ var arguments = readNode() as ArgumentList;
+ return astFactory.functionExpressionInvocation(
+ function,
+ typeArguments,
+ arguments,
+ );
+ }
+
+ FunctionTypeAlias _readFunctionTypeAlias() {
+ var codeOffset = _readInformativeUint30();
+ var codeLength = _readInformativeUint30();
+ var documentationTokenIndexList = _readUint30List();
+
+ var typeParameters = _readOptionalNode() as TypeParameterList;
+ var returnType = _readOptionalNode() as TypeAnnotation;
+ var formalParameters = readNode() as FormalParameterList;
+ var name = readNode() as SimpleIdentifier;
+ var metadata = _readNodeList<Annotation>();
+
+ var node = astFactory.functionTypeAlias(
+ null,
+ metadata,
+ Tokens.TYPEDEF,
+ returnType,
+ name,
+ typeParameters,
+ formalParameters,
+ Tokens.SEMICOLON,
+ ) as FunctionTypeAliasImpl;
+
+ node.linkedContext = LinkedContext(
+ _unitReader,
node,
- data.methodDeclaration_hasOperatorEqualWithParameterTypeFromObject,
+ codeOffset: codeOffset,
+ codeLength: codeLength,
+ resolutionIndex: _readUInt30(),
+ documentationTokenIndexList: documentationTokenIndexList,
+ );
+
+ return node;
+ }
+
+ FunctionTypedFormalParameter _readFunctionTypedFormalParameter() {
+ var typeParameters = _readOptionalNode() as TypeParameterList;
+ var returnType = _readOptionalNode() as TypeAnnotation;
+ var formalParameters = readNode() as FormalParameterList;
+ var flags = _readByte();
+ var codeOffset = _readInformativeUint30();
+ var codeLength = _readInformativeUint30();
+ var metadata = _readNodeList<Annotation>();
+ var identifier = readNode() as SimpleIdentifier;
+ var node = astFactory.functionTypedFormalParameter2(
+ comment: null,
+ covariantKeyword:
+ AstBinaryFlags.isCovariant(flags) ? Tokens.COVARIANT : null,
+ identifier: identifier,
+ metadata: metadata,
+ parameters: formalParameters,
+ requiredKeyword:
+ AstBinaryFlags.isRequired(flags) ? Tokens.REQUIRED : null,
+ returnType: returnType,
+ typeParameters: typeParameters,
+ ) as FunctionTypedFormalParameterImpl;
+ node.summaryData = SummaryDataForFormalParameter(
+ codeOffset: codeOffset,
+ codeLength: codeLength,
);
return node;
}
- MethodInvocation _read_methodInvocation(LinkedNode data) {
- return astFactory.methodInvocation(
- _readNode(data.methodInvocation_target),
- _Tokens.choose(
- AstBinaryFlags.hasPeriod(data.flags),
- _Tokens.PERIOD,
- AstBinaryFlags.hasPeriod2(data.flags),
- _Tokens.PERIOD_PERIOD,
+ GenericFunctionType _readGenericFunctionType() {
+ var flags = _readByte();
+ var typeParameters = _readOptionalNode() as TypeParameterList;
+ var returnType = _readOptionalNode() as TypeAnnotation;
+ var formalParameters = readNode() as FormalParameterList;
+
+ return astFactory.genericFunctionType(
+ returnType,
+ Tokens.FUNCTION,
+ typeParameters,
+ formalParameters,
+ question: AstBinaryFlags.hasQuestion(flags) ? Tokens.QUESTION : null,
+ );
+ }
+
+ GenericTypeAlias _readGenericTypeAlias() {
+ var codeOffset = _readInformativeUint30();
+ var codeLength = _readInformativeUint30();
+ var documentationTokenIndexList = _readUint30List();
+
+ var typeParameters = _readOptionalNode() as TypeParameterList;
+ var functionType = _readOptionalNode();
+ var name = readNode() as SimpleIdentifier;
+ var metadata = _readNodeList<Annotation>();
+
+ var node = astFactory.genericTypeAlias(
+ null,
+ metadata,
+ Tokens.TYPEDEF,
+ name,
+ typeParameters,
+ Tokens.EQ,
+ functionType,
+ Tokens.SEMICOLON,
+ ) as GenericTypeAliasImpl;
+
+ node.linkedContext = LinkedContext(
+ _unitReader,
+ node,
+ codeOffset: codeOffset,
+ codeLength: codeLength,
+ resolutionIndex: _readUInt30(),
+ documentationTokenIndexList: documentationTokenIndexList,
+ );
+
+ return node;
+ }
+
+ HideCombinator _readHideCombinator() {
+ var keywordOffset = _readInformativeUint30();
+ return astFactory.hideCombinator(
+ KeywordToken(Keyword.HIDE, keywordOffset),
+ _readNodeList<SimpleIdentifier>(),
+ );
+ }
+
+ IfElement _readIfElement() {
+ var condition = readNode() as Expression;
+ var thenElement = readNode() as CollectionElement;
+ var elseElement = _readOptionalNode() as CollectionElement;
+ return astFactory.ifElement(
+ condition: condition,
+ elseElement: elseElement,
+ elseKeyword: elseElement != null ? Tokens.ELSE : null,
+ ifKeyword: Tokens.IF,
+ leftParenthesis: Tokens.OPEN_PAREN,
+ rightParenthesis: Tokens.CLOSE_PAREN,
+ thenElement: thenElement,
+ );
+ }
+
+ ImplementsClause _readImplementsClause() {
+ var interfaces = _readNodeList<TypeName>();
+ return astFactory.implementsClause(Tokens.IMPLEMENTS, interfaces);
+ }
+
+ ImportDirective _readImportDirective() {
+ var flags = _readByte();
+
+ SimpleIdentifier prefixIdentifier;
+ if (AstBinaryFlags.hasPrefix(flags)) {
+ var prefixName = _readStringReference();
+ var prefixOffset = _readInformativeUint30();
+ prefixIdentifier = astFactory.simpleIdentifier(
+ StringToken(TokenType.STRING, prefixName, prefixOffset),
+ );
+ }
+
+ var combinators = _readNodeList<Combinator>();
+ var configurations = _readNodeList<Configuration>();
+ var uri = readNode();
+ var keywordOffset = _readInformativeUint30();
+ var metadata = _readNodeList<Annotation>();
+
+ var node = astFactory.importDirective(
+ null,
+ metadata,
+ KeywordToken(Keyword.IMPORT, keywordOffset),
+ uri,
+ configurations,
+ AstBinaryFlags.isDeferred(flags) ? Tokens.DEFERRED : null,
+ Tokens.AS,
+ prefixIdentifier,
+ combinators,
+ Tokens.SEMICOLON,
+ ) as ImportDirectiveImpl;
+
+ node.linkedContext = LinkedContext(
+ _unitReader,
+ node,
+ codeOffset: -1,
+ codeLength: 0,
+ documentationTokenIndexList: _noDocumentationComment,
+ resolutionIndex: _readUInt30(),
+ );
+
+ return node;
+ }
+
+ IndexExpression _readIndexExpression() {
+ var flags = _readByte();
+ var target = _readOptionalNode() as Expression;
+ var index = readNode() as Expression;
+ return astFactory.indexExpressionForTarget2(
+ target: target,
+ question: AstBinaryFlags.hasQuestion(flags) ? Tokens.QUESTION : null,
+ leftBracket: Tokens.OPEN_SQUARE_BRACKET,
+ index: index,
+ rightBracket: Tokens.CLOSE_SQUARE_BRACKET,
+ )..period = AstBinaryFlags.hasPeriod(flags) ? Tokens.PERIOD_PERIOD : null;
+ }
+
+ int _readInformativeUint30() {
+ if (_withInformative) {
+ return _readUInt30();
+ }
+ return 0;
+ }
+
+ Uint32List _readInformativeUint30List() {
+ if (_withInformative) {
+ return _readUint30List();
+ }
+ return null;
+ }
+
+ InstanceCreationExpression _readInstanceCreationExpression() {
+ var flags = _readByte();
+ var constructorName = readNode() as ConstructorName;
+ var argumentList = readNode() as ArgumentList;
+
+ return astFactory.instanceCreationExpression(
+ Tokens.choose(
+ AstBinaryFlags.isConst(flags),
+ Tokens.CONST,
+ AstBinaryFlags.isNew(flags),
+ Tokens.NEW,
),
- _readNode(data.methodInvocation_methodName),
- _readNode(data.invocationExpression_typeArguments),
- _readNode(data.invocationExpression_arguments),
- )..staticInvokeType = _readType(data.invocationExpression_invokeType);
+ constructorName,
+ argumentList,
+ );
}
- MixinDeclaration _read_mixinDeclaration(LinkedNode data) {
- timerAstBinaryReaderMixin.start();
- try {
- var node = astFactory.mixinDeclaration(
- _readDocumentationComment(data),
- _readNodeListLazy(data.annotatedNode_metadata),
- _Tokens.MIXIN,
- _declaredIdentifier(data),
- _readNode(data.classOrMixinDeclaration_typeParameters),
- _readNodeLazy(data.mixinDeclaration_onClause),
- _readNodeLazy(data.classOrMixinDeclaration_implementsClause),
- _Tokens.OPEN_CURLY_BRACKET,
- _readNodeListLazy(data.classOrMixinDeclaration_members),
- _Tokens.CLOSE_CURLY_BRACKET,
- );
- LazyMixinDeclaration(node, data);
- return node;
- } finally {
- timerAstBinaryReaderMixin.stop();
- }
+ IntegerLiteral _readIntegerLiteralNegative() {
+ var value = (_readUint32() << 32) | _readUint32();
+ return _createIntegerLiteral(-value);
}
- NamedExpression _read_namedExpression(LinkedNode data) {
- Expression expression = _readNode(data.namedExpression_expression);
- return astFactory.namedExpression(
- _readNode(data.namedExpression_name),
+ IntegerLiteral _readIntegerLiteralNegative1() {
+ var value = _readByte();
+ return _createIntegerLiteral(-value);
+ }
+
+ IntegerLiteral _readIntegerLiteralNull() {
+ var lexeme = _readStringReference();
+ return astFactory.integerLiteral(
+ TokenFactory.tokenFromTypeAndString(TokenType.INT, lexeme),
+ null,
+ );
+ }
+
+ IntegerLiteral _readIntegerLiteralPositive() {
+ var value = (_readUint32() << 32) | _readUint32();
+ return _createIntegerLiteral(value);
+ }
+
+ IntegerLiteral _readIntegerLiteralPositive1() {
+ var value = _readByte();
+ return _createIntegerLiteral(value);
+ }
+
+ InterpolationExpression _readInterpolationExpression() {
+ var flags = _readByte();
+ var expression = readNode() as Expression;
+ var isIdentifier = AstBinaryFlags.isStringInterpolationIdentifier(flags);
+ return astFactory.interpolationExpression(
+ isIdentifier
+ ? Tokens.OPEN_CURLY_BRACKET
+ : Tokens.STRING_INTERPOLATION_EXPRESSION,
expression,
- )..staticType = expression.staticType;
- }
-
- NativeClause _read_nativeClause(LinkedNode data) {
- return astFactory.nativeClause(
- _Tokens.NATIVE,
- _readNode(data.nativeClause_name),
+ isIdentifier ? null : Tokens.CLOSE_CURLY_BRACKET,
);
}
- NativeFunctionBody _read_nativeFunctionBody(LinkedNode data) {
- return astFactory.nativeFunctionBody(
- _Tokens.NATIVE,
- _readNode(data.nativeFunctionBody_stringLiteral),
- _Tokens.SEMICOLON,
+ InterpolationString _readInterpolationString() {
+ var value = _readStringReference();
+ return astFactory.interpolationString(
+ TokenFactory.tokenFromString(value),
+ value,
);
}
- NullLiteral _read_nullLiteral(LinkedNode data) {
+ IsExpression _readIsExpression() {
+ var flags = _readByte();
+ var expression = readNode() as Expression;
+ var type = readNode() as TypeAnnotation;
+ return astFactory.isExpression(
+ expression,
+ Tokens.IS,
+ AstBinaryFlags.hasNot(flags) ? Tokens.BANG : null,
+ type,
+ );
+ }
+
+ LibraryDirective _readLibraryDirective() {
+ var documentationTokenIndexList = _readUint30List();
+ var name = readNode();
+ var keywordOffset = _readInformativeUint30();
+ var metadata = _readNodeList<Annotation>();
+
+ var node = astFactory.libraryDirective(
+ null,
+ metadata,
+ KeywordToken(Keyword.LIBRARY, keywordOffset),
+ name,
+ Tokens.SEMICOLON,
+ );
+ SummaryDataForLibraryDirective(
+ _unitReader,
+ node,
+ documentationTokenIndexList: documentationTokenIndexList,
+ );
+ return node;
+ }
+
+ LibraryIdentifier _readLibraryIdentifier() {
+ var components = _readNodeList<SimpleIdentifier>();
+ return astFactory.libraryIdentifier(
+ components,
+ );
+ }
+
+ ListLiteral _readListLiteral() {
+ var flags = _readByte();
+ var typeArguments = _readOptionalNode();
+ var elements = _readNodeList<CollectionElement>();
+
+ return astFactory.listLiteral(
+ AstBinaryFlags.isConst(flags) ? Tokens.CONST : null,
+ typeArguments,
+ Tokens.OPEN_SQUARE_BRACKET,
+ elements,
+ Tokens.CLOSE_SQUARE_BRACKET,
+ );
+ }
+
+ MapLiteralEntry _readMapLiteralEntry() {
+ var key = readNode() as Expression;
+ var value = readNode() as Expression;
+ return astFactory.mapLiteralEntry(key, Tokens.COLON, value);
+ }
+
+ MethodDeclaration _readMethodDeclaration() {
+ var flags = _readUInt30();
+
+ var codeOffset = _readInformativeUint30();
+ var codeLength = _readInformativeUint30();
+ var documentationTokenIndexList = _readUint30List();
+
+ var name = readNode() as SimpleIdentifier;
+ var typeParameters = _readOptionalNode() as TypeParameterList;
+ var returnType = _readOptionalNode() as TypeAnnotation;
+ var formalParameters = _readOptionalNode() as FormalParameterList;
+ var metadata = _readNodeList<Annotation>();
+ var body = _functionBodyForFlags(flags);
+
+ var node = astFactory.methodDeclaration(
+ null,
+ metadata,
+ AstBinaryFlags.isExternal(flags) ? Tokens.EXTERNAL : null,
+ AstBinaryFlags.isStatic(flags) ? Tokens.STATIC : null,
+ returnType,
+ Tokens.choose(
+ AstBinaryFlags.isGet(flags),
+ Tokens.GET,
+ AstBinaryFlags.isSet(flags),
+ Tokens.SET,
+ ),
+ AstBinaryFlags.isOperator(flags) ? Tokens.OPERATOR : null,
+ name,
+ typeParameters,
+ formalParameters,
+ body,
+ ) as MethodDeclarationImpl;
+
+ node.linkedContext = LinkedContext(
+ _unitReader,
+ node,
+ codeOffset: codeOffset,
+ codeLength: codeLength,
+ resolutionIndex: _readUInt30(),
+ documentationTokenIndexList: documentationTokenIndexList,
+ );
+
+ return node;
+ }
+
+ MethodInvocation _readMethodInvocation() {
+ var flags = _readByte();
+ var target = _readOptionalNode() as Expression;
+ var methodName = readNode() as SimpleIdentifier;
+ var typeArguments = _readOptionalNode() as TypeArgumentList;
+ var arguments = readNode() as ArgumentList;
+
+ return astFactory.methodInvocation(
+ target,
+ Tokens.choose(
+ AstBinaryFlags.hasPeriod(flags),
+ Tokens.PERIOD,
+ AstBinaryFlags.hasPeriod2(flags),
+ Tokens.PERIOD_PERIOD,
+ ),
+ methodName,
+ typeArguments,
+ arguments,
+ );
+ }
+
+ MixinDeclaration _readMixinDeclaration() {
+ var codeOffset = _readInformativeUint30();
+ var codeLength = _readInformativeUint30();
+ var documentationTokenIndexList = _readUint30List();
+
+ var typeParameters = _readOptionalNode() as TypeParameterList;
+ var onClause = _readOptionalNode() as OnClause;
+ var implementsClause = _readOptionalNode() as ImplementsClause;
+ var name = readNode() as SimpleIdentifier;
+ var metadata = _readNodeList<Annotation>();
+
+ var node = astFactory.mixinDeclaration(
+ null,
+ metadata,
+ Tokens.MIXIN,
+ name,
+ typeParameters,
+ onClause,
+ implementsClause,
+ Tokens.OPEN_CURLY_BRACKET,
+ const <ClassMember>[],
+ Tokens.CLOSE_CURLY_BRACKET,
+ ) as MixinDeclarationImpl;
+
+ node.linkedContext = LinkedContext(
+ _unitReader,
+ node,
+ codeOffset: codeOffset,
+ codeLength: codeLength,
+ resolutionIndex: _readUInt30(),
+ documentationTokenIndexList: documentationTokenIndexList,
+ );
+
+ return node;
+ }
+
+ NamedExpression _readNamedExpression() {
+ var name = _readStringReference();
+ var offset = _readInformativeUint30();
+ var nameNode = astFactory.label(
+ astFactory.simpleIdentifier(
+ StringToken(TokenType.STRING, name, offset),
+ ),
+ Tokens.COLON,
+ );
+
+ var expression = readNode() as Expression;
+ return astFactory.namedExpression(nameNode, expression);
+ }
+
+ NativeClause _readNativeClause() {
+ var name = readNode();
+ return astFactory.nativeClause(Tokens.NATIVE, name);
+ }
+
+ List<T> _readNodeList<T>() {
+ var length = _readUInt30();
+ // TODO(scheglov) This will not work for null safety, rewrite.
+ var result = List<T>.filled(length, null);
+ for (var i = 0; i < length; ++i) {
+ result[i] = readNode() as T;
+ }
+ return result;
+ }
+
+ NullLiteral _readNullLiteral() {
return astFactory.nullLiteral(
- _Tokens.NULL,
- )..staticType = _nullType;
- }
-
- OnClause _read_onClause(LinkedNode data) {
- return astFactory.onClause(
- _Tokens.ON,
- _readNodeList(data.onClause_superclassConstraints),
+ Tokens.NULL,
);
}
- ParenthesizedExpression _read_parenthesizedExpression(LinkedNode data) {
+ OnClause _readOnClause() {
+ var superclassConstraints = _readNodeList<TypeName>();
+ return astFactory.onClause(Tokens.ON, superclassConstraints);
+ }
+
+ AstNode _readOptionalNode() {
+ if (_readOptionTag()) {
+ return readNode();
+ } else {
+ return null;
+ }
+ }
+
+ bool _readOptionTag() {
+ var tag = _readByte();
+ if (tag == Tag.Nothing) {
+ return false;
+ } else if (tag == Tag.Something) {
+ return true;
+ } else {
+ throw UnimplementedError('Unexpected option tag: $tag');
+ }
+ }
+
+ ParenthesizedExpression _readParenthesizedExpression() {
+ var expression = readNode() as Expression;
return astFactory.parenthesizedExpression(
- _Tokens.OPEN_PAREN,
- _readNode(data.parenthesizedExpression_expression),
- _Tokens.CLOSE_PAREN,
- )..staticType = _readType(data.expression_type);
- }
-
- PartDirective _read_partDirective(LinkedNode data) {
- timerAstBinaryReaderDirective.start();
- _isReadingDirective = true;
- try {
- var node = astFactory.partDirective(
- _readDocumentationComment(data),
- _readNodeListLazy(data.annotatedNode_metadata),
- _Tokens.PART,
- _readNode(data.uriBasedDirective_uri),
- _Tokens.SEMICOLON,
- );
- LazyDirective.setData(node, data);
- return node;
- } finally {
- _isReadingDirective = false;
- timerAstBinaryReaderDirective.stop();
- }
- }
-
- PartOfDirective _read_partOfDirective(LinkedNode data) {
- timerAstBinaryReaderDirective.start();
- _isReadingDirective = true;
- try {
- var node = astFactory.partOfDirective(
- _readDocumentationComment(data),
- _readNodeListLazy(data.annotatedNode_metadata),
- _Tokens.PART,
- _Tokens.OF,
- _readNode(data.partOfDirective_uri),
- _readNode(data.partOfDirective_libraryName),
- _Tokens.SEMICOLON,
- );
- LazyDirective.setData(node, data);
- return node;
- } finally {
- _isReadingDirective = false;
- timerAstBinaryReaderDirective.stop();
- }
- }
-
- PostfixExpression _read_postfixExpression(LinkedNode data) {
- return astFactory.postfixExpression(
- _readNode(data.postfixExpression_operand),
- _Tokens.fromType(data.postfixExpression_operator),
- )
- ..staticElement = _elementOfComponents(
- data.postfixExpression_element,
- data.postfixExpression_substitution,
- )
- ..staticType = _readType(data.expression_type);
- }
-
- PrefixedIdentifier _read_prefixedIdentifier(LinkedNode data) {
- return astFactory.prefixedIdentifier(
- _readNode(data.prefixedIdentifier_prefix),
- _Tokens.PERIOD,
- _readNode(data.prefixedIdentifier_identifier),
- )..staticType = _readType(data.expression_type);
- }
-
- PrefixExpression _read_prefixExpression(LinkedNode data) {
- return astFactory.prefixExpression(
- _Tokens.fromType(data.prefixExpression_operator),
- _readNode(data.prefixExpression_operand),
- )
- ..staticElement = _elementOfComponents(
- data.prefixExpression_element,
- data.prefixExpression_substitution,
- )
- ..staticType = _readType(data.expression_type);
- }
-
- PropertyAccess _read_propertyAccess(LinkedNode data) {
- return astFactory.propertyAccess(
- _readNode(data.propertyAccess_target),
- _Tokens.fromType(data.propertyAccess_operator),
- _readNode(data.propertyAccess_propertyName),
- )..staticType = _readType(data.expression_type);
- }
-
- RedirectingConstructorInvocation _read_redirectingConstructorInvocation(
- LinkedNode data) {
- var hasThis = AstBinaryFlags.hasThis(data.flags);
- return astFactory.redirectingConstructorInvocation(
- hasThis ? _Tokens.THIS : null,
- hasThis ? _Tokens.PERIOD : null,
- _readNode(data.redirectingConstructorInvocation_constructorName),
- _readNode(data.redirectingConstructorInvocation_arguments),
- )..staticElement = _elementOfComponents(
- data.redirectingConstructorInvocation_element,
- data.redirectingConstructorInvocation_substitution,
- );
- }
-
- RethrowExpression _read_rethrowExpression(LinkedNode data) {
- return astFactory.rethrowExpression(
- _Tokens.RETHROW,
- )..staticType = _readType(data.expression_type);
- }
-
- ReturnStatement _read_returnStatement(LinkedNode data) {
- return astFactory.returnStatement(
- _Tokens.RETURN,
- _readNode(data.returnStatement_expression),
- _Tokens.SEMICOLON,
+ Tokens.OPEN_PAREN,
+ expression,
+ Tokens.CLOSE_PAREN,
);
}
- SetOrMapLiteral _read_setOrMapLiteral(LinkedNode data) {
- SetOrMapLiteralImpl node = astFactory.setOrMapLiteral(
- constKeyword: AstBinaryFlags.isConst(data.flags) ? _Tokens.CONST : null,
- elements: _readNodeList(data.setOrMapLiteral_elements),
- leftBracket: _Tokens.OPEN_CURLY_BRACKET,
- typeArguments: AstBinaryFlags.hasTypeArguments(data.flags)
- ? astFactory.typeArgumentList(
- _Tokens.LT,
- _readNodeList(data.typedLiteral_typeArguments),
- _Tokens.GT,
- )
- : null,
- rightBracket: _Tokens.CLOSE_CURLY_BRACKET,
- )..staticType = _readType(data.expression_type);
- if (AstBinaryFlags.isMap(data.flags)) {
+ PartDirective _readPartDirective() {
+ var uri = readNode();
+ var keywordOffset = _readInformativeUint30();
+ var metadata = _readNodeList<Annotation>();
+
+ return astFactory.partDirective(
+ null,
+ metadata,
+ KeywordToken(Keyword.PART, keywordOffset),
+ uri,
+ Tokens.SEMICOLON,
+ );
+ }
+
+ PartOfDirective _readPartOfDirective() {
+ var libraryName = _readOptionalNode() as LibraryIdentifier;
+ var uri = _readOptionalNode() as StringLiteral;
+ var keywordOffset = _readInformativeUint30();
+ var metadata = _readNodeList<Annotation>();
+
+ return astFactory.partOfDirective(
+ null,
+ metadata,
+ KeywordToken(Keyword.PART, keywordOffset),
+ Tokens.OF,
+ uri,
+ libraryName,
+ Tokens.SEMICOLON,
+ );
+ }
+
+ PostfixExpression _readPostfixExpression() {
+ var operand = readNode() as Expression;
+ var operatorType = UnlinkedTokenType.values[_readByte()];
+ return astFactory.postfixExpression(
+ operand,
+ Tokens.fromType(operatorType),
+ );
+ }
+
+ PrefixedIdentifier _readPrefixedIdentifier() {
+ var prefix = readNode() as SimpleIdentifier;
+ var identifier = readNode() as SimpleIdentifier;
+ return astFactory.prefixedIdentifier(
+ prefix,
+ Tokens.PERIOD,
+ identifier,
+ );
+ }
+
+ PrefixExpression _readPrefixExpression() {
+ var operatorType = UnlinkedTokenType.values[_readByte()];
+ var operand = readNode() as Expression;
+ return astFactory.prefixExpression(
+ Tokens.fromType(operatorType),
+ operand,
+ );
+ }
+
+ PropertyAccess _readPropertyAccess() {
+ var flags = _readByte();
+ var target = _readOptionalNode() as Expression;
+ var propertyName = readNode() as SimpleIdentifier;
+ return astFactory.propertyAccess(
+ target,
+ Tokens.choose(
+ AstBinaryFlags.hasPeriod(flags),
+ Tokens.PERIOD,
+ AstBinaryFlags.hasPeriod2(flags),
+ Tokens.PERIOD_PERIOD,
+ ),
+ propertyName,
+ );
+ }
+
+ RedirectingConstructorInvocation _readRedirectingConstructorInvocation() {
+ var flags = _readByte();
+ var constructorName = _readOptionalNode() as SimpleIdentifier;
+ var argumentList = readNode() as ArgumentList;
+ var hasThis = AstBinaryFlags.hasThis(flags);
+ return astFactory.redirectingConstructorInvocation(
+ hasThis ? Tokens.THIS : null,
+ hasThis ? Tokens.PERIOD : null,
+ constructorName,
+ argumentList,
+ );
+ }
+
+ SetOrMapLiteral _readSetOrMapLiteral() {
+ var flags = _readByte();
+ var typeArguments = _readOptionalNode() as TypeArgumentList;
+ var elements = _readNodeList<CollectionElement>();
+ var node = astFactory.setOrMapLiteral(
+ constKeyword: AstBinaryFlags.isConst(flags) ? Tokens.CONST : null,
+ elements: elements,
+ leftBracket: Tokens.OPEN_CURLY_BRACKET,
+ typeArguments: typeArguments,
+ rightBracket: Tokens.CLOSE_CURLY_BRACKET,
+ ) as SetOrMapLiteralImpl;
+ if (AstBinaryFlags.isMap(flags)) {
node.becomeMap();
- } else if (AstBinaryFlags.isSet(data.flags)) {
+ } else if (AstBinaryFlags.isSet(flags)) {
node.becomeSet();
}
return node;
}
- ShowCombinator _read_showCombinator(LinkedNode data) {
- var node = astFactory.showCombinator(
- _combinatorKeyword(data, Keyword.SHOW, _Tokens.SHOW),
- data.names.map((name) => AstTestFactory.identifier3(name)).toList(),
+ ShowCombinator _readShowCombinator() {
+ var keywordOffset = _readInformativeUint30();
+ return astFactory.showCombinator(
+ KeywordToken(Keyword.SHOW, keywordOffset),
+ _readNodeList<SimpleIdentifier>(),
);
- LazyCombinator(node, data);
- return node;
}
- SimpleFormalParameter _read_simpleFormalParameter(LinkedNode data) {
- SimpleFormalParameterImpl node = astFactory.simpleFormalParameter2(
- identifier: _declaredIdentifier(data),
- type: _readNode(data.simpleFormalParameter_type),
+ SimpleFormalParameter _readSimpleFormalParameter() {
+ var type = _readOptionalNode() as TypeAnnotation;
+ var flags = _readByte();
+ var codeOffset = _readInformativeUint30();
+ var codeLength = _readInformativeUint30();
+ var metadata = _readNodeList<Annotation>();
+ var identifier =
+ AstBinaryFlags.hasName(flags) ? readNode() as SimpleIdentifier : null;
+
+ var node = astFactory.simpleFormalParameter2(
+ identifier: identifier,
+ type: type,
covariantKeyword:
- AstBinaryFlags.isCovariant(data.flags) ? _Tokens.COVARIANT : null,
- comment: _readDocumentationComment(data),
- metadata: _readNodeList(data.normalFormalParameter_metadata),
- keyword: _Tokens.choose(
- AstBinaryFlags.isConst(data.flags),
- _Tokens.CONST,
- AstBinaryFlags.isFinal(data.flags),
- _Tokens.FINAL,
- AstBinaryFlags.isVar(data.flags),
- _Tokens.VAR,
+ AstBinaryFlags.isCovariant(flags) ? Tokens.COVARIANT : null,
+ comment: null,
+ metadata: metadata,
+ keyword: Tokens.choose(
+ AstBinaryFlags.isConst(flags),
+ Tokens.CONST,
+ AstBinaryFlags.isFinal(flags),
+ Tokens.FINAL,
+ AstBinaryFlags.isVar(flags),
+ Tokens.VAR,
),
requiredKeyword:
- AstBinaryFlags.isRequired(data.flags) ? _Tokens.REQUIRED : null,
+ AstBinaryFlags.isRequired(flags) ? Tokens.REQUIRED : null,
+ ) as SimpleFormalParameterImpl;
+ node.summaryData = SummaryDataForFormalParameter(
+ codeOffset: codeOffset,
+ codeLength: codeLength,
);
- LazyFormalParameter.setData(node, data);
- LazyAst.setInheritsCovariant(node, data.inheritsCovariant);
return node;
}
- SimpleIdentifier _read_simpleIdentifier(LinkedNode data) {
+ SimpleIdentifier _readSimpleIdentifier() {
+ var name = _readStringReference();
+ var offset = _readInformativeUint30();
return astFactory.simpleIdentifier(
- TokenFactory.tokenFromString(data.name),
- isDeclaration: AstBinaryFlags.isDeclaration(data.flags),
- )
- ..staticElement = _elementOfComponents(
- data.simpleIdentifier_element,
- data.simpleIdentifier_substitution,
- )
- ..staticType = _readType(data.expression_type);
+ StringToken(TokenType.STRING, name, offset),
+ );
}
- SimpleStringLiteral _read_simpleStringLiteral(LinkedNode data) {
- var node = AstTestFactory.string2(data.simpleStringLiteral_value);
- if (!_isReadingDirective) {
- node.staticType = _stringType;
- }
- return node;
+ SimpleStringLiteral _readSimpleStringLiteral() {
+ var lexeme = _readStringReference();
+ var value = _readStringReference();
+
+ return astFactory.simpleStringLiteral(
+ TokenFactory.tokenFromString(lexeme),
+ value,
+ );
}
- SpreadElement _read_spreadElement(LinkedNode data) {
+ SpreadElement _readSpreadElement() {
+ var flags = _readByte();
+ var expression = readNode() as Expression;
return astFactory.spreadElement(
- spreadOperator: _Tokens.fromType(data.spreadElement_spreadOperator),
- expression: _readNode(data.spreadElement_expression),
+ spreadOperator: AstBinaryFlags.hasQuestion(flags)
+ ? Tokens.PERIOD_PERIOD_PERIOD_QUESTION
+ : Tokens.PERIOD_PERIOD_PERIOD,
+ expression: expression,
);
}
- StringInterpolation _read_stringInterpolation(LinkedNode data) {
- var node = astFactory.stringInterpolation(
- _readNodeList(data.stringInterpolation_elements),
- );
- if (!_isReadingDirective) {
- node.staticType = _stringType;
- }
- return node;
+ StringInterpolation _readStringInterpolation() {
+ var elements = _readNodeList<InterpolationElement>();
+ return astFactory.stringInterpolation(elements);
}
- SuperConstructorInvocation _read_superConstructorInvocation(LinkedNode data) {
+ String _readStringReference() {
+ return _unitReader.astReader.readStringReference();
+ }
+
+ SuperConstructorInvocation _readSuperConstructorInvocation() {
+ var constructorName = _readOptionalNode() as SimpleIdentifier;
+ var argumentList = readNode() as ArgumentList;
return astFactory.superConstructorInvocation(
- _Tokens.SUPER,
- _Tokens.PERIOD,
- _readNode(data.superConstructorInvocation_constructorName),
- _readNode(data.superConstructorInvocation_arguments),
- )..staticElement = _elementOfComponents(
- data.superConstructorInvocation_element,
- data.superConstructorInvocation_substitution,
- );
- }
-
- SuperExpression _read_superExpression(LinkedNode data) {
- return astFactory.superExpression(
- _Tokens.SUPER,
- )..staticType = _readType(data.expression_type);
- }
-
- SwitchCase _read_switchCase(LinkedNode data) {
- return astFactory.switchCase(
- _readNodeList(data.switchMember_labels),
- _Tokens.CASE,
- _readNode(data.switchCase_expression),
- _Tokens.COLON,
- _readNodeList(data.switchMember_statements),
+ Tokens.SUPER,
+ Tokens.PERIOD,
+ constructorName,
+ argumentList,
);
}
- SwitchDefault _read_switchDefault(LinkedNode data) {
- return astFactory.switchDefault(
- _readNodeList(data.switchMember_labels),
- _Tokens.DEFAULT,
- _Tokens.COLON,
- _readNodeList(data.switchMember_statements),
- );
+ SuperExpression _readSuperExpression() {
+ return astFactory.superExpression(Tokens.SUPER);
}
- SwitchStatement _read_switchStatement(LinkedNode data) {
- return astFactory.switchStatement(
- _Tokens.SWITCH,
- _Tokens.OPEN_PAREN,
- _readNode(data.switchStatement_expression),
- _Tokens.CLOSE_PAREN,
- _Tokens.OPEN_CURLY_BRACKET,
- _readNodeList(data.switchStatement_members),
- _Tokens.CLOSE_CURLY_BRACKET,
- );
- }
-
- SymbolLiteral _read_symbolLiteral(LinkedNode data) {
- return astFactory.symbolLiteral(
- _Tokens.HASH,
- data.names.map((lexeme) => TokenFactory.tokenFromString(lexeme)).toList(),
- )..staticType = _readType(data.expression_type);
- }
-
- ThisExpression _read_thisExpression(LinkedNode data) {
- return astFactory.thisExpression(
- _Tokens.THIS,
- )..staticType = _readType(data.expression_type);
- }
-
- ThrowExpression _read_throwExpression(LinkedNode data) {
- return astFactory.throwExpression(
- _Tokens.THROW,
- _readNode(data.throwExpression_expression),
- )..staticType = _readType(data.expression_type);
- }
-
- TopLevelVariableDeclaration _read_topLevelVariableDeclaration(
- LinkedNode data) {
- timerAstBinaryReaderTopLevelVar.start();
- try {
- var node = astFactory.topLevelVariableDeclaration(
- _readDocumentationComment(data),
- _readNodeListLazy(data.annotatedNode_metadata),
- _readNode(data.topLevelVariableDeclaration_variableList),
- _Tokens.SEMICOLON,
- externalKeyword:
- AstBinaryFlags.isExternal(data.flags) ? _Tokens.EXTERNAL : null,
- );
- LazyTopLevelVariableDeclaration.setData(node, data);
- return node;
- } finally {
- timerAstBinaryReaderTopLevelVar.stop();
+ SymbolLiteral _readSymbolLiteral() {
+ var components = <Token>[];
+ var length = _readUInt30();
+ for (var i = 0; i < length; i++) {
+ var lexeme = _readStringReference();
+ var token = TokenFactory.tokenFromString(lexeme);
+ components.add(token);
}
+ return astFactory.symbolLiteral(Tokens.HASH, components);
}
- TryStatement _read_tryStatement(LinkedNode data) {
- return astFactory.tryStatement(
- _Tokens.TRY,
- _readNode(data.tryStatement_body),
- _readNodeList(data.tryStatement_catchClauses),
- _Tokens.FINALLY,
- _readNode(data.tryStatement_finallyBlock),
+ ThisExpression _readThisExpression() {
+ return astFactory.thisExpression(Tokens.THIS);
+ }
+
+ ThrowExpression _readThrowExpression() {
+ var expression = readNode() as Expression;
+ return astFactory.throwExpression(Tokens.THROW, expression);
+ }
+
+ TopLevelVariableDeclaration _readTopLevelVariableDeclaration() {
+ var flags = _readByte();
+ var codeOffsetLengthList = _readInformativeUint30List();
+ var documentationTokenIndexList = _readUint30List();
+ var variableList = readNode() as VariableDeclarationList;
+ var metadata = _readNodeList<Annotation>();
+
+ var node = astFactory.topLevelVariableDeclaration(
+ null,
+ metadata,
+ variableList,
+ Tokens.SEMICOLON,
+ externalKeyword:
+ AstBinaryFlags.isExternal(flags) ? Tokens.EXTERNAL : null,
+ ) as TopLevelVariableDeclarationImpl;
+
+ node.linkedContext = LinkedContext(
+ _unitReader,
+ node,
+ codeOffset: -1,
+ codeLength: 0,
+ codeOffsetLengthList: codeOffsetLengthList,
+ resolutionIndex: _readUInt30(),
+ documentationTokenIndexList: documentationTokenIndexList,
);
+
+ return node;
}
- TypeArgumentList _read_typeArgumentList(LinkedNode data) {
- return astFactory.typeArgumentList(
- _Tokens.LT,
- _readNodeList(data.typeArgumentList_arguments),
- _Tokens.GT,
- );
+ TypeArgumentList _readTypeArgumentList() {
+ var arguments = _readNodeList<TypeAnnotation>();
+ return astFactory.typeArgumentList(Tokens.LT, arguments, Tokens.GT);
}
- TypeName _read_typeName(LinkedNode data) {
+ TypeName _readTypeName() {
+ var flags = _readByte();
+ var name = readNode() as Identifier;
+ var typeArguments = _readOptionalNode() as TypeArgumentList;
+
return astFactory.typeName(
- _readNode(data.typeName_name),
- AstBinaryFlags.hasTypeArguments(data.flags)
- ? astFactory.typeArgumentList(
- _Tokens.LT,
- _readNodeList(data.typeName_typeArguments),
- _Tokens.GT,
- )
- : null,
- question:
- AstBinaryFlags.hasQuestion(data.flags) ? _Tokens.QUESTION : null,
- )..type = _readType(data.typeName_type);
+ name,
+ typeArguments,
+ question: AstBinaryFlags.hasQuestion(flags) ? Tokens.QUESTION : null,
+ );
}
- TypeParameter _read_typeParameter(LinkedNode data) {
- // TODO (kallentu) : Clean up AstFactoryImpl casting once variance is
- // added to the interface.
- var node = (astFactory as AstFactoryImpl).typeParameter2(
- comment: _readDocumentationComment(data),
- metadata: _readNodeListLazy(data.annotatedNode_metadata),
- name: _declaredIdentifier(data),
- extendsKeyword: _Tokens.EXTENDS,
- bound: _readNodeLazy(data.typeParameter_bound),
+ TypeParameter _readTypeParameter() {
+ var codeOffset = _readInformativeUint30();
+ var codeLength = _readInformativeUint30();
+ var name = readNode() as Identifier;
+ var bound = _readOptionalNode() as TypeAnnotation;
+ var metadata = _readNodeList<Annotation>();
+
+ var node = astFactory.typeParameter(
+ null,
+ metadata,
+ name,
+ bound != null ? Tokens.EXTENDS : null,
+ bound,
+ ) as TypeParameterImpl;
+ node.summaryData = SummaryDataForTypeParameter(
+ codeOffset: codeOffset,
+ codeLength: codeLength,
);
- LazyAst.setVariance(node, _decodeVariance(data.typeParameter_variance));
- LazyTypeParameter.setData(node, data);
+
return node;
}
- TypeParameterList _read_typeParameterList(LinkedNode data) {
+ TypeParameterList _readTypeParameterList() {
+ var typeParameters = _readNodeList<TypeParameter>();
return astFactory.typeParameterList(
- _Tokens.LT,
- _readNodeList(data.typeParameterList_typeParameters),
- _Tokens.GT,
+ Tokens.LT,
+ typeParameters,
+ Tokens.GT,
);
}
- VariableDeclaration _read_variableDeclaration(LinkedNode data) {
- var node = astFactory.variableDeclaration(
- _declaredIdentifier(data),
- _Tokens.EQ,
- _readNodeLazy(data.variableDeclaration_initializer),
- );
- LazyVariableDeclaration.setData(node, data);
- LazyAst.setInheritsCovariant(node, data.inheritsCovariant);
- return node;
- }
-
- VariableDeclarationList _read_variableDeclarationList(LinkedNode data) {
- var node = astFactory.variableDeclarationList2(
- comment: _readDocumentationComment(data),
- keyword: _Tokens.choose(
- AstBinaryFlags.isConst(data.flags),
- _Tokens.CONST,
- AstBinaryFlags.isFinal(data.flags),
- _Tokens.FINAL,
- AstBinaryFlags.isVar(data.flags),
- _Tokens.VAR,
- ),
- lateKeyword: AstBinaryFlags.isLate(data.flags) ? _Tokens.LATE : null,
- metadata: _readNodeListLazy(data.annotatedNode_metadata),
- type: _readNodeLazy(data.variableDeclarationList_type),
- variables: _readNodeList(data.variableDeclarationList_variables),
- );
- LazyVariableDeclarationList.setData(node, data);
- return node;
- }
-
- VariableDeclarationStatement _read_variableDeclarationStatement(
- LinkedNode data) {
- return astFactory.variableDeclarationStatement(
- _readNode(data.variableDeclarationStatement_variables),
- _Tokens.SEMICOLON,
- );
- }
-
- WhileStatement _read_whileStatement(LinkedNode data) {
- return astFactory.whileStatement(
- _Tokens.WHILE,
- _Tokens.OPEN_PAREN,
- _readNode(data.whileStatement_condition),
- _Tokens.CLOSE_PAREN,
- _readNode(data.whileStatement_body),
- );
- }
-
- WithClause _read_withClause(LinkedNode data) {
- return astFactory.withClause(
- _Tokens.WITH,
- _readNodeList(data.withClause_mixinTypes),
- );
- }
-
- YieldStatement _read_yieldStatement(LinkedNode data) {
- return astFactory.yieldStatement(
- _Tokens.YIELD,
- AstBinaryFlags.isStar(data.flags) ? _Tokens.STAR : null,
- _readNode(data.yieldStatement_expression),
- _Tokens.SEMICOLON,
- );
- }
-
- Comment _readDocumentationComment(LinkedNode data) {
- return null;
- }
-
- AstNode _readNode(LinkedNode data) {
- if (data == null) return null;
-
- switch (data.kind) {
- case LinkedNodeKind.adjacentStrings:
- return _read_adjacentStrings(data);
- case LinkedNodeKind.annotation:
- return _read_annotation(data);
- case LinkedNodeKind.argumentList:
- return _read_argumentList(data);
- case LinkedNodeKind.asExpression:
- return _read_asExpression(data);
- case LinkedNodeKind.assertInitializer:
- return _read_assertInitializer(data);
- case LinkedNodeKind.assertStatement:
- return _read_assertStatement(data);
- case LinkedNodeKind.assignmentExpression:
- return _read_assignmentExpression(data);
- case LinkedNodeKind.awaitExpression:
- return _read_awaitExpression(data);
- case LinkedNodeKind.binaryExpression:
- return _read_binaryExpression(data);
- case LinkedNodeKind.block:
- return _read_block(data);
- case LinkedNodeKind.blockFunctionBody:
- return _read_blockFunctionBody(data);
- case LinkedNodeKind.booleanLiteral:
- return _read_booleanLiteral(data);
- case LinkedNodeKind.breakStatement:
- return _read_breakStatement(data);
- case LinkedNodeKind.cascadeExpression:
- return _read_cascadeExpression(data);
- case LinkedNodeKind.catchClause:
- return _read_catchClause(data);
- case LinkedNodeKind.classDeclaration:
- return _read_classDeclaration(data);
- case LinkedNodeKind.classTypeAlias:
- return _read_classTypeAlias(data);
- case LinkedNodeKind.comment:
- return _read_comment(data);
- case LinkedNodeKind.commentReference:
- return _read_commentReference(data);
- case LinkedNodeKind.compilationUnit:
- return _read_compilationUnit(data);
- case LinkedNodeKind.conditionalExpression:
- return _read_conditionalExpression(data);
- case LinkedNodeKind.configuration:
- return _read_configuration(data);
- case LinkedNodeKind.constructorDeclaration:
- return _read_constructorDeclaration(data);
- case LinkedNodeKind.constructorFieldInitializer:
- return _read_constructorFieldInitializer(data);
- case LinkedNodeKind.constructorName:
- return _read_constructorName(data);
- case LinkedNodeKind.continueStatement:
- return _read_continueStatement(data);
- case LinkedNodeKind.declaredIdentifier:
- return _read_declaredIdentifier(data);
- case LinkedNodeKind.defaultFormalParameter:
- return _read_defaultFormalParameter(data);
- case LinkedNodeKind.doStatement:
- return _read_doStatement(data);
- case LinkedNodeKind.dottedName:
- return _read_dottedName(data);
- case LinkedNodeKind.doubleLiteral:
- return _read_doubleLiteral(data);
- case LinkedNodeKind.emptyFunctionBody:
- return _read_emptyFunctionBody(data);
- case LinkedNodeKind.emptyStatement:
- return _read_emptyStatement(data);
- case LinkedNodeKind.enumConstantDeclaration:
- return _read_enumConstantDeclaration(data);
- case LinkedNodeKind.enumDeclaration:
- return _read_enumDeclaration(data);
- case LinkedNodeKind.exportDirective:
- return _read_exportDirective(data);
- case LinkedNodeKind.expressionFunctionBody:
- return _read_expressionFunctionBody(data);
- case LinkedNodeKind.expressionStatement:
- return _read_expressionStatement(data);
- case LinkedNodeKind.extendsClause:
- return _read_extendsClause(data);
- case LinkedNodeKind.extensionDeclaration:
- return _read_extensionDeclaration(data);
- case LinkedNodeKind.extensionOverride:
- return _read_extensionOverride(data);
- case LinkedNodeKind.fieldDeclaration:
- return _read_fieldDeclaration(data);
- case LinkedNodeKind.fieldFormalParameter:
- return _read_fieldFormalParameter(data);
- case LinkedNodeKind.forEachPartsWithDeclaration:
- return _read_forEachPartsWithDeclaration(data);
- case LinkedNodeKind.forEachPartsWithIdentifier:
- return _read_forEachPartsWithIdentifier(data);
- case LinkedNodeKind.forElement:
- return _read_forElement(data);
- case LinkedNodeKind.forPartsWithExpression:
- return _read_forPartsWithExpression(data);
- case LinkedNodeKind.forPartsWithDeclarations:
- return _read_forPartsWithDeclarations(data);
- case LinkedNodeKind.forStatement:
- return _read_forStatement(data);
- case LinkedNodeKind.formalParameterList:
- return _read_formalParameterList(data);
- case LinkedNodeKind.functionDeclaration:
- return _read_functionDeclaration(data);
- case LinkedNodeKind.functionDeclarationStatement:
- return _read_functionDeclarationStatement(data);
- case LinkedNodeKind.functionExpression:
- return _read_functionExpression(data);
- case LinkedNodeKind.functionExpressionInvocation:
- return _read_functionExpressionInvocation(data);
- case LinkedNodeKind.functionTypeAlias:
- return _read_functionTypeAlias(data);
- case LinkedNodeKind.functionTypedFormalParameter:
- return _read_functionTypedFormalParameter(data);
- case LinkedNodeKind.genericFunctionType:
- return _read_genericFunctionType(data);
- case LinkedNodeKind.genericTypeAlias:
- return _read_genericTypeAlias(data);
- case LinkedNodeKind.hideCombinator:
- return _read_hideCombinator(data);
- case LinkedNodeKind.ifElement:
- return _read_ifElement(data);
- case LinkedNodeKind.ifStatement:
- return _read_ifStatement(data);
- case LinkedNodeKind.implementsClause:
- return _read_implementsClause(data);
- case LinkedNodeKind.importDirective:
- return _read_importDirective(data);
- case LinkedNodeKind.indexExpression:
- return _read_indexExpression(data);
- case LinkedNodeKind.instanceCreationExpression:
- return _read_instanceCreationExpression(data);
- case LinkedNodeKind.integerLiteral:
- return _read_integerLiteral(data);
- case LinkedNodeKind.interpolationString:
- return _read_interpolationString(data);
- case LinkedNodeKind.interpolationExpression:
- return _read_interpolationExpression(data);
- case LinkedNodeKind.isExpression:
- return _read_isExpression(data);
- case LinkedNodeKind.label:
- return _read_label(data);
- case LinkedNodeKind.labeledStatement:
- return _read_labeledStatement(data);
- case LinkedNodeKind.libraryDirective:
- return _read_libraryDirective(data);
- case LinkedNodeKind.libraryIdentifier:
- return _read_libraryIdentifier(data);
- case LinkedNodeKind.listLiteral:
- return _read_listLiteral(data);
- case LinkedNodeKind.mapLiteralEntry:
- return _read_mapLiteralEntry(data);
- case LinkedNodeKind.methodDeclaration:
- return _read_methodDeclaration(data);
- case LinkedNodeKind.methodInvocation:
- return _read_methodInvocation(data);
- case LinkedNodeKind.mixinDeclaration:
- return _read_mixinDeclaration(data);
- case LinkedNodeKind.namedExpression:
- return _read_namedExpression(data);
- case LinkedNodeKind.nativeClause:
- return _read_nativeClause(data);
- case LinkedNodeKind.nativeFunctionBody:
- return _read_nativeFunctionBody(data);
- case LinkedNodeKind.nullLiteral:
- return _read_nullLiteral(data);
- case LinkedNodeKind.onClause:
- return _read_onClause(data);
- case LinkedNodeKind.parenthesizedExpression:
- return _read_parenthesizedExpression(data);
- case LinkedNodeKind.partDirective:
- return _read_partDirective(data);
- case LinkedNodeKind.partOfDirective:
- return _read_partOfDirective(data);
- case LinkedNodeKind.postfixExpression:
- return _read_postfixExpression(data);
- case LinkedNodeKind.prefixExpression:
- return _read_prefixExpression(data);
- case LinkedNodeKind.propertyAccess:
- return _read_propertyAccess(data);
- case LinkedNodeKind.prefixedIdentifier:
- return _read_prefixedIdentifier(data);
- case LinkedNodeKind.redirectingConstructorInvocation:
- return _read_redirectingConstructorInvocation(data);
- case LinkedNodeKind.rethrowExpression:
- return _read_rethrowExpression(data);
- case LinkedNodeKind.returnStatement:
- return _read_returnStatement(data);
- case LinkedNodeKind.setOrMapLiteral:
- return _read_setOrMapLiteral(data);
- case LinkedNodeKind.showCombinator:
- return _read_showCombinator(data);
- case LinkedNodeKind.simpleFormalParameter:
- return _read_simpleFormalParameter(data);
- case LinkedNodeKind.simpleIdentifier:
- return _read_simpleIdentifier(data);
- case LinkedNodeKind.simpleStringLiteral:
- return _read_simpleStringLiteral(data);
- case LinkedNodeKind.spreadElement:
- return _read_spreadElement(data);
- case LinkedNodeKind.stringInterpolation:
- return _read_stringInterpolation(data);
- case LinkedNodeKind.superConstructorInvocation:
- return _read_superConstructorInvocation(data);
- case LinkedNodeKind.superExpression:
- return _read_superExpression(data);
- case LinkedNodeKind.switchCase:
- return _read_switchCase(data);
- case LinkedNodeKind.switchDefault:
- return _read_switchDefault(data);
- case LinkedNodeKind.switchStatement:
- return _read_switchStatement(data);
- case LinkedNodeKind.symbolLiteral:
- return _read_symbolLiteral(data);
- case LinkedNodeKind.thisExpression:
- return _read_thisExpression(data);
- case LinkedNodeKind.throwExpression:
- return _read_throwExpression(data);
- case LinkedNodeKind.topLevelVariableDeclaration:
- return _read_topLevelVariableDeclaration(data);
- case LinkedNodeKind.tryStatement:
- return _read_tryStatement(data);
- case LinkedNodeKind.typeArgumentList:
- return _read_typeArgumentList(data);
- case LinkedNodeKind.typeName:
- return _read_typeName(data);
- case LinkedNodeKind.typeParameter:
- return _read_typeParameter(data);
- case LinkedNodeKind.typeParameterList:
- return _read_typeParameterList(data);
- case LinkedNodeKind.variableDeclaration:
- return _read_variableDeclaration(data);
- case LinkedNodeKind.variableDeclarationList:
- return _read_variableDeclarationList(data);
- case LinkedNodeKind.variableDeclarationStatement:
- return _read_variableDeclarationStatement(data);
- case LinkedNodeKind.whileStatement:
- return _read_whileStatement(data);
- case LinkedNodeKind.withClause:
- return _read_withClause(data);
- case LinkedNodeKind.yieldStatement:
- return _read_yieldStatement(data);
- default:
- throw UnimplementedError('Expression kind: ${data.kind}');
+ int _readUInt30() {
+ var byte = _readByte();
+ if (byte & 0x80 == 0) {
+ // 0xxxxxxx
+ return byte;
+ } else if (byte & 0x40 == 0) {
+ // 10xxxxxx
+ return ((byte & 0x3F) << 8) | _readByte();
+ } else {
+ // 11xxxxxx
+ return ((byte & 0x3F) << 24) |
+ (_readByte() << 16) |
+ (_readByte() << 8) |
+ _readByte();
}
}
- AstNode _readNodeLazy(LinkedNode data) {
- if (isLazy) return null;
- return _readNode(data);
- }
-
- List<T> _readNodeList<T>(List<LinkedNode> nodeList) {
- var result = List<T>.filled(nodeList.length, null);
- for (var i = 0; i < nodeList.length; ++i) {
- var linkedNode = nodeList[i];
- result[i] = _readNode(linkedNode) as T;
+ Uint32List _readUint30List() {
+ var length = _readUInt30();
+ var result = Uint32List(length);
+ for (var i = 0; i < length; ++i) {
+ result[i] = _readUInt30();
}
return result;
}
- List<T> _readNodeListLazy<T>(List<LinkedNode> nodeList) {
- if (isLazy) {
- return List<T>.filled(nodeList.length, null);
- }
- return _readNodeList(nodeList);
+ int _readUint32() {
+ return (_readByte() << 24) |
+ (_readByte() << 16) |
+ (_readByte() << 8) |
+ _readByte();
}
- DartType _readType(LinkedNodeType data) {
- return _unitContext.readType(data);
+ VariableDeclaration _readVariableDeclaration() {
+ var flags = _readByte();
+ var name = readNode() as SimpleIdentifier;
+ var initializer = _readOptionalNode() as Expression;
+
+ var node = astFactory.variableDeclaration(
+ name,
+ Tokens.EQ,
+ initializer,
+ ) as VariableDeclarationImpl;
+
+ node.hasInitializer = AstBinaryFlags.hasInitializer(flags);
+
+ return node;
}
- static Variance _decodeVariance(int encoding) {
- if (encoding == 0) {
- return null;
- } else if (encoding == 1) {
- return Variance.unrelated;
- } else if (encoding == 2) {
- return Variance.covariant;
- } else if (encoding == 3) {
- return Variance.contravariant;
- } else if (encoding == 4) {
- return Variance.invariant;
- } else {
- throw UnimplementedError('encoding: $encoding');
- }
- }
+ VariableDeclarationList _readVariableDeclarationList() {
+ var flags = _readByte();
+ var type = _readOptionalNode() as TypeAnnotation;
+ var variables = _readNodeList<VariableDeclaration>();
+ var metadata = _readNodeList<Annotation>();
- static ParameterKind _toParameterKind(LinkedNodeFormalParameterKind kind) {
- switch (kind) {
- case LinkedNodeFormalParameterKind.requiredPositional:
- return ParameterKind.REQUIRED;
- case LinkedNodeFormalParameterKind.requiredNamed:
- return ParameterKind.NAMED_REQUIRED;
- break;
- case LinkedNodeFormalParameterKind.optionalPositional:
- return ParameterKind.POSITIONAL;
- break;
- case LinkedNodeFormalParameterKind.optionalNamed:
- return ParameterKind.NAMED;
- default:
- throw StateError('Unexpected: $kind');
- }
- }
-}
-
-class _Tokens {
- static final ABSTRACT = TokenFactory.tokenFromKeyword(Keyword.ABSTRACT);
- static final ARROW = TokenFactory.tokenFromType(TokenType.FUNCTION);
- static final AS = TokenFactory.tokenFromKeyword(Keyword.AS);
- static final ASSERT = TokenFactory.tokenFromKeyword(Keyword.ASSERT);
- static final AT = TokenFactory.tokenFromType(TokenType.AT);
- static final ASYNC = TokenFactory.tokenFromKeyword(Keyword.ASYNC);
- static final AWAIT = TokenFactory.tokenFromKeyword(Keyword.AWAIT);
- static final BANG = TokenFactory.tokenFromType(TokenType.BANG);
- static final BREAK = TokenFactory.tokenFromKeyword(Keyword.BREAK);
- static final CASE = TokenFactory.tokenFromKeyword(Keyword.CASE);
- static final CATCH = TokenFactory.tokenFromKeyword(Keyword.CATCH);
- static final CLASS = TokenFactory.tokenFromKeyword(Keyword.CLASS);
- static final CLOSE_CURLY_BRACKET =
- TokenFactory.tokenFromType(TokenType.CLOSE_CURLY_BRACKET);
- static final CLOSE_PAREN = TokenFactory.tokenFromType(TokenType.CLOSE_PAREN);
- static final CLOSE_SQUARE_BRACKET =
- TokenFactory.tokenFromType(TokenType.CLOSE_SQUARE_BRACKET);
- static final COLON = TokenFactory.tokenFromType(TokenType.COLON);
- static final COMMA = TokenFactory.tokenFromType(TokenType.COMMA);
- static final CONST = TokenFactory.tokenFromKeyword(Keyword.CONST);
- static final CONTINUE = TokenFactory.tokenFromKeyword(Keyword.CONTINUE);
- static final COVARIANT = TokenFactory.tokenFromKeyword(Keyword.COVARIANT);
- static final DEFERRED = TokenFactory.tokenFromKeyword(Keyword.DEFERRED);
- static final ELSE = TokenFactory.tokenFromKeyword(Keyword.ELSE);
- static final EXTERNAL = TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
- static final FACTORY = TokenFactory.tokenFromKeyword(Keyword.FACTORY);
- static final DEFAULT = TokenFactory.tokenFromKeyword(Keyword.DEFAULT);
- static final DO = TokenFactory.tokenFromKeyword(Keyword.DO);
- static final ENUM = TokenFactory.tokenFromKeyword(Keyword.ENUM);
- static final EQ = TokenFactory.tokenFromType(TokenType.EQ);
- static final EXPORT = TokenFactory.tokenFromKeyword(Keyword.EXPORT);
- static final EXTENDS = TokenFactory.tokenFromKeyword(Keyword.EXTENDS);
- static final EXTENSION = TokenFactory.tokenFromKeyword(Keyword.EXTENSION);
- static final FINAL = TokenFactory.tokenFromKeyword(Keyword.FINAL);
- static final FINALLY = TokenFactory.tokenFromKeyword(Keyword.FINALLY);
- static final FOR = TokenFactory.tokenFromKeyword(Keyword.FOR);
- static final FUNCTION = TokenFactory.tokenFromKeyword(Keyword.FUNCTION);
- static final GET = TokenFactory.tokenFromKeyword(Keyword.GET);
- static final GT = TokenFactory.tokenFromType(TokenType.GT);
- static final HASH = TokenFactory.tokenFromType(TokenType.HASH);
- static final HIDE = TokenFactory.tokenFromKeyword(Keyword.HIDE);
- static final IF = TokenFactory.tokenFromKeyword(Keyword.IF);
- static final IMPLEMENTS = TokenFactory.tokenFromKeyword(Keyword.IMPORT);
- static final IMPORT = TokenFactory.tokenFromKeyword(Keyword.IMPLEMENTS);
- static final IN = TokenFactory.tokenFromKeyword(Keyword.IN);
- static final IS = TokenFactory.tokenFromKeyword(Keyword.IS);
- static final LATE = TokenFactory.tokenFromKeyword(Keyword.LATE);
- static final LIBRARY = TokenFactory.tokenFromKeyword(Keyword.LIBRARY);
- static final LT = TokenFactory.tokenFromType(TokenType.LT);
- static final MIXIN = TokenFactory.tokenFromKeyword(Keyword.MIXIN);
- static final NATIVE = TokenFactory.tokenFromKeyword(Keyword.NATIVE);
- static final NEW = TokenFactory.tokenFromKeyword(Keyword.NEW);
- static final NULL = TokenFactory.tokenFromKeyword(Keyword.NULL);
- static final OF = TokenFactory.tokenFromKeyword(Keyword.OF);
- static final ON = TokenFactory.tokenFromKeyword(Keyword.ON);
- static final OPEN_CURLY_BRACKET =
- TokenFactory.tokenFromType(TokenType.OPEN_CURLY_BRACKET);
- static final OPEN_PAREN = TokenFactory.tokenFromType(TokenType.OPEN_PAREN);
- static final OPEN_SQUARE_BRACKET =
- TokenFactory.tokenFromType(TokenType.OPEN_SQUARE_BRACKET);
- static final OPERATOR = TokenFactory.tokenFromKeyword(Keyword.OPERATOR);
- static final PART = TokenFactory.tokenFromKeyword(Keyword.PART);
- static final PERIOD = TokenFactory.tokenFromType(TokenType.PERIOD);
- static final PERIOD_PERIOD =
- TokenFactory.tokenFromType(TokenType.PERIOD_PERIOD);
- static final QUESTION = TokenFactory.tokenFromType(TokenType.QUESTION);
- static final REQUIRED = TokenFactory.tokenFromKeyword(Keyword.REQUIRED);
- static final RETHROW = TokenFactory.tokenFromKeyword(Keyword.RETHROW);
- static final RETURN = TokenFactory.tokenFromKeyword(Keyword.RETURN);
- static final SEMICOLON = TokenFactory.tokenFromType(TokenType.SEMICOLON);
- static final SET = TokenFactory.tokenFromKeyword(Keyword.SET);
- static final SHOW = TokenFactory.tokenFromKeyword(Keyword.SHOW);
- static final STAR = TokenFactory.tokenFromType(TokenType.STAR);
- static final STATIC = TokenFactory.tokenFromKeyword(Keyword.STATIC);
- static final STRING_INTERPOLATION_EXPRESSION =
- TokenFactory.tokenFromType(TokenType.STRING_INTERPOLATION_EXPRESSION);
- static final SUPER = TokenFactory.tokenFromKeyword(Keyword.SUPER);
- static final SWITCH = TokenFactory.tokenFromKeyword(Keyword.SWITCH);
- static final SYNC = TokenFactory.tokenFromKeyword(Keyword.SYNC);
- static final THIS = TokenFactory.tokenFromKeyword(Keyword.THIS);
- static final THROW = TokenFactory.tokenFromKeyword(Keyword.THROW);
- static final TRY = TokenFactory.tokenFromKeyword(Keyword.TRY);
- static final TYPEDEF = TokenFactory.tokenFromKeyword(Keyword.TYPEDEF);
- static final VAR = TokenFactory.tokenFromKeyword(Keyword.VAR);
- static final WITH = TokenFactory.tokenFromKeyword(Keyword.WITH);
- static final WHILE = TokenFactory.tokenFromKeyword(Keyword.WHILE);
- static final YIELD = TokenFactory.tokenFromKeyword(Keyword.YIELD);
-
- static Token choose(bool if1, Token then1, bool if2, Token then2,
- [bool if3, Token then3]) {
- if (if1) return then1;
- if (if2) return then2;
- if (if2 == true) return then3;
- return null;
- }
-
- static Token fromType(UnlinkedTokenType type) {
- return TokenFactory.tokenFromType(
- TokensContext.binaryToAstTokenType(type),
+ return astFactory.variableDeclarationList2(
+ comment: null,
+ keyword: Tokens.choose(
+ AstBinaryFlags.isConst(flags),
+ Tokens.CONST,
+ AstBinaryFlags.isFinal(flags),
+ Tokens.FINAL,
+ AstBinaryFlags.isVar(flags),
+ Tokens.VAR,
+ ),
+ lateKeyword: AstBinaryFlags.isLate(flags) ? Tokens.LATE : null,
+ metadata: metadata,
+ type: type,
+ variables: variables,
);
}
+
+ WithClause _readWithClause() {
+ var mixins = _readNodeList<TypeName>();
+ return astFactory.withClause(Tokens.WITH, mixins);
+ }
}
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart b/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
new file mode 100644
index 0000000..3c31999
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
@@ -0,0 +1,124 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Tag {
+ static const int Nothing = 0;
+ static const int Something = 1;
+
+ static const int AdjacentStrings = 75;
+ static const int Annotation = 2;
+ static const int ArgumentList = 3;
+ static const int AsExpression = 84;
+ static const int AssertInitializer = 82;
+ static const int AssignmentExpression = 96;
+ static const int BinaryExpression = 52;
+ static const int BooleanLiteral = 4;
+ static const int CascadeExpression = 95;
+ static const int Class = 5;
+ static const int ClassTypeAlias = 44;
+ static const int ConditionalExpression = 51;
+ static const int Configuration = 46;
+ static const int ConstructorDeclaration = 6;
+ static const int ConstructorFieldInitializer = 50;
+ static const int ConstructorName = 7;
+ static const int DeclaredIdentifier = 90;
+ static const int DefaultFormalParameter = 8;
+ static const int DottedName = 47;
+ static const int DoubleLiteral = 9;
+ static const int EnumConstantDeclaration = 10;
+ static const int EnumDeclaration = 11;
+ static const int ExportDirective = 12;
+ static const int ExtendsClause = 13;
+ static const int ExtensionDeclaration = 14;
+ static const int ExtensionOverride = 87;
+ static const int FieldDeclaration = 15;
+ static const int FieldFormalParameter = 16;
+ static const int ForEachPartsWithDeclaration = 89;
+ static const int ForElement = 88;
+ static const int ForPartsWithDeclarations = 91;
+ static const int FormalParameterList = 17;
+ static const int FunctionDeclaration = 18;
+ static const int FunctionDeclaration_getter = 57;
+ static const int FunctionDeclaration_setter = 58;
+ static const int FunctionExpression = 19;
+ static const int FunctionExpressionInvocation = 93;
+ static const int FunctionTypeAlias = 55;
+ static const int FunctionTypedFormalParameter = 20;
+ static const int GenericFunctionType = 21;
+ static const int GenericTypeAlias = 22;
+ static const int HideCombinator = 48;
+ static const int IfElement = 63;
+ static const int ImplementsClause = 23;
+ static const int ImportDirective = 24;
+ static const int IndexExpression = 98;
+ static const int InstanceCreationExpression = 25;
+ static const int IntegerLiteralNegative = 73;
+ static const int IntegerLiteralNegative1 = 71;
+ static const int IntegerLiteralNull = 97;
+ static const int IntegerLiteralPositive = 72;
+ static const int IntegerLiteralPositive1 = 26;
+ static const int InterpolationExpression = 77;
+ static const int InterpolationString = 78;
+ static const int IsExpression = 83;
+ static const int Label = 61;
+ static const int LibraryDirective = 27;
+ static const int LibraryIdentifier = 28;
+ static const int ListLiteral = 56;
+ static const int MapLiteralEntry = 66;
+ static const int MethodDeclaration = 29;
+ static const int MethodDeclaration_getter = 85;
+ static const int MethodDeclaration_setter = 86;
+ static const int MethodInvocation = 59;
+ static const int MixinDeclaration = 67;
+ static const int NamedExpression = 60;
+ static const int NativeClause = 92;
+ static const int OnClause = 68;
+ static const int NullLiteral = 49;
+ static const int ParenthesizedExpression = 53;
+ static const int PartDirective = 30;
+ static const int PartOfDirective = 31;
+ static const int PostfixExpression = 94;
+ static const int PrefixExpression = 79;
+ static const int PrefixedIdentifier = 32;
+ static const int PropertyAccess = 62;
+ static const int RedirectingConstructorInvocation = 54;
+ static const int SetOrMapLiteral = 65;
+ static const int ShowCombinator = 33;
+ static const int SimpleFormalParameter = 34;
+ static const int SimpleIdentifier = 35;
+ static const int SimpleStringLiteral = 36;
+ static const int SpreadElement = 64;
+ static const int StringInterpolation = 76;
+ static const int SuperConstructorInvocation = 69;
+ static const int SuperExpression = 80;
+ static const int SymbolLiteral = 74;
+ static const int ThisExpression = 70;
+ static const int ThrowExpression = 81;
+ static const int TopLevelVariableDeclaration = 37;
+ static const int TypeArgumentList = 38;
+ static const int TypeName = 39;
+ static const int TypeParameter = 40;
+ static const int TypeParameterList = 41;
+ static const int VariableDeclaration = 42;
+ static const int VariableDeclarationList = 43;
+ static const int WithClause = 45;
+
+ static const int RawElement = 0;
+ static const int MemberLegacyWithoutTypeArguments = 1;
+ static const int MemberLegacyWithTypeArguments = 2;
+ static const int MemberWithTypeArguments = 3;
+
+ static const int ParameterKindRequiredPositional = 1;
+ static const int ParameterKindOptionalPositional = 2;
+ static const int ParameterKindRequiredNamed = 3;
+ static const int ParameterKindOptionalNamed = 4;
+
+ static const int NullType = 2;
+ static const int DynamicType = 3;
+ static const int FunctionType = 4;
+ static const int NeverType = 5;
+ static const int InterfaceType = 6;
+ static const int TypeParameterType = 7;
+ static const int VoidType = 8;
+}
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_tokens.dart b/pkg/analyzer/lib/src/summary2/ast_binary_tokens.dart
new file mode 100644
index 0000000..a9a8a69
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_tokens.dart
@@ -0,0 +1,116 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/src/generated/testing/token_factory.dart';
+import 'package:analyzer/src/summary2/tokens_context.dart';
+import 'package:analyzer/src/summary2/unlinked_token_type.dart';
+
+class Tokens {
+ static final ABSTRACT = TokenFactory.tokenFromKeyword(Keyword.ABSTRACT);
+ static final ARROW = TokenFactory.tokenFromType(TokenType.FUNCTION);
+ static final AS = TokenFactory.tokenFromKeyword(Keyword.AS);
+ static final ASSERT = TokenFactory.tokenFromKeyword(Keyword.ASSERT);
+ static final AT = TokenFactory.tokenFromType(TokenType.AT);
+ static final ASYNC = TokenFactory.tokenFromKeyword(Keyword.ASYNC);
+ static final AWAIT = TokenFactory.tokenFromKeyword(Keyword.AWAIT);
+ static final BANG = TokenFactory.tokenFromType(TokenType.BANG);
+ static final BREAK = TokenFactory.tokenFromKeyword(Keyword.BREAK);
+ static final CASE = TokenFactory.tokenFromKeyword(Keyword.CASE);
+ static final CATCH = TokenFactory.tokenFromKeyword(Keyword.CATCH);
+ static final CLASS = TokenFactory.tokenFromKeyword(Keyword.CLASS);
+ static final CLOSE_CURLY_BRACKET =
+ TokenFactory.tokenFromType(TokenType.CLOSE_CURLY_BRACKET);
+ static final CLOSE_PAREN = TokenFactory.tokenFromType(TokenType.CLOSE_PAREN);
+ static final CLOSE_SQUARE_BRACKET =
+ TokenFactory.tokenFromType(TokenType.CLOSE_SQUARE_BRACKET);
+ static final COLON = TokenFactory.tokenFromType(TokenType.COLON);
+ static final COMMA = TokenFactory.tokenFromType(TokenType.COMMA);
+ static final CONST = TokenFactory.tokenFromKeyword(Keyword.CONST);
+ static final CONTINUE = TokenFactory.tokenFromKeyword(Keyword.CONTINUE);
+ static final COVARIANT = TokenFactory.tokenFromKeyword(Keyword.COVARIANT);
+ static final DEFERRED = TokenFactory.tokenFromKeyword(Keyword.DEFERRED);
+ static final ELSE = TokenFactory.tokenFromKeyword(Keyword.ELSE);
+ static final EXTERNAL = TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
+ static final FACTORY = TokenFactory.tokenFromKeyword(Keyword.FACTORY);
+ static final DEFAULT = TokenFactory.tokenFromKeyword(Keyword.DEFAULT);
+ static final DO = TokenFactory.tokenFromKeyword(Keyword.DO);
+ static final ENUM = TokenFactory.tokenFromKeyword(Keyword.ENUM);
+ static final EQ = TokenFactory.tokenFromType(TokenType.EQ);
+ static final EXPORT = TokenFactory.tokenFromKeyword(Keyword.EXPORT);
+ static final EXTENDS = TokenFactory.tokenFromKeyword(Keyword.EXTENDS);
+ static final EXTENSION = TokenFactory.tokenFromKeyword(Keyword.EXTENSION);
+ static final FINAL = TokenFactory.tokenFromKeyword(Keyword.FINAL);
+ static final FINALLY = TokenFactory.tokenFromKeyword(Keyword.FINALLY);
+ static final FOR = TokenFactory.tokenFromKeyword(Keyword.FOR);
+ static final FUNCTION = TokenFactory.tokenFromKeyword(Keyword.FUNCTION);
+ static final GET = TokenFactory.tokenFromKeyword(Keyword.GET);
+ static final GT = TokenFactory.tokenFromType(TokenType.GT);
+ static final HASH = TokenFactory.tokenFromType(TokenType.HASH);
+ static final HIDE = TokenFactory.tokenFromKeyword(Keyword.HIDE);
+ static final IF = TokenFactory.tokenFromKeyword(Keyword.IF);
+ static final IMPLEMENTS = TokenFactory.tokenFromKeyword(Keyword.IMPORT);
+ static final IMPORT = TokenFactory.tokenFromKeyword(Keyword.IMPLEMENTS);
+ static final IN = TokenFactory.tokenFromKeyword(Keyword.IN);
+ static final IS = TokenFactory.tokenFromKeyword(Keyword.IS);
+ static final LATE = TokenFactory.tokenFromKeyword(Keyword.LATE);
+ static final LIBRARY = TokenFactory.tokenFromKeyword(Keyword.LIBRARY);
+ static final LT = TokenFactory.tokenFromType(TokenType.LT);
+ static final MIXIN = TokenFactory.tokenFromKeyword(Keyword.MIXIN);
+ static final NATIVE = TokenFactory.tokenFromKeyword(Keyword.NATIVE);
+ static final NEW = TokenFactory.tokenFromKeyword(Keyword.NEW);
+ static final NULL = TokenFactory.tokenFromKeyword(Keyword.NULL);
+ static final OF = TokenFactory.tokenFromKeyword(Keyword.OF);
+ static final ON = TokenFactory.tokenFromKeyword(Keyword.ON);
+ static final OPEN_CURLY_BRACKET =
+ TokenFactory.tokenFromType(TokenType.OPEN_CURLY_BRACKET);
+ static final OPEN_PAREN = TokenFactory.tokenFromType(TokenType.OPEN_PAREN);
+ static final OPEN_SQUARE_BRACKET =
+ TokenFactory.tokenFromType(TokenType.OPEN_SQUARE_BRACKET);
+ static final OPERATOR = TokenFactory.tokenFromKeyword(Keyword.OPERATOR);
+ static final PART = TokenFactory.tokenFromKeyword(Keyword.PART);
+ static final PERIOD = TokenFactory.tokenFromType(TokenType.PERIOD);
+ static final PERIOD_PERIOD =
+ TokenFactory.tokenFromType(TokenType.PERIOD_PERIOD);
+ static final PERIOD_PERIOD_PERIOD =
+ TokenFactory.tokenFromType(TokenType.PERIOD_PERIOD_PERIOD);
+ static final PERIOD_PERIOD_PERIOD_QUESTION =
+ TokenFactory.tokenFromType(TokenType.PERIOD_PERIOD_PERIOD_QUESTION);
+ static final QUESTION = TokenFactory.tokenFromType(TokenType.QUESTION);
+ static final REQUIRED = TokenFactory.tokenFromKeyword(Keyword.REQUIRED);
+ static final RETHROW = TokenFactory.tokenFromKeyword(Keyword.RETHROW);
+ static final RETURN = TokenFactory.tokenFromKeyword(Keyword.RETURN);
+ static final SEMICOLON = TokenFactory.tokenFromType(TokenType.SEMICOLON);
+ static final SET = TokenFactory.tokenFromKeyword(Keyword.SET);
+ static final SHOW = TokenFactory.tokenFromKeyword(Keyword.SHOW);
+ static final STAR = TokenFactory.tokenFromType(TokenType.STAR);
+ static final STATIC = TokenFactory.tokenFromKeyword(Keyword.STATIC);
+ static final STRING_INTERPOLATION_EXPRESSION =
+ TokenFactory.tokenFromType(TokenType.STRING_INTERPOLATION_EXPRESSION);
+ static final SUPER = TokenFactory.tokenFromKeyword(Keyword.SUPER);
+ static final SWITCH = TokenFactory.tokenFromKeyword(Keyword.SWITCH);
+ static final SYNC = TokenFactory.tokenFromKeyword(Keyword.SYNC);
+ static final THIS = TokenFactory.tokenFromKeyword(Keyword.THIS);
+ static final THROW = TokenFactory.tokenFromKeyword(Keyword.THROW);
+ static final TRY = TokenFactory.tokenFromKeyword(Keyword.TRY);
+ static final TYPEDEF = TokenFactory.tokenFromKeyword(Keyword.TYPEDEF);
+ static final VAR = TokenFactory.tokenFromKeyword(Keyword.VAR);
+ static final WITH = TokenFactory.tokenFromKeyword(Keyword.WITH);
+ static final WHILE = TokenFactory.tokenFromKeyword(Keyword.WHILE);
+ static final YIELD = TokenFactory.tokenFromKeyword(Keyword.YIELD);
+
+ static Token choose(bool if1, Token then1, bool if2, Token then2,
+ [bool if3, Token then3]) {
+ if (if1) return then1;
+ if (if2) return then2;
+ if (if2 == true) return then3;
+ return null;
+ }
+
+ static Token fromType(UnlinkedTokenType type) {
+ return TokenFactory.tokenFromType(
+ TokensContext.binaryToAstTokenType(type),
+ );
+ }
+}
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
index 0035dd8..9d2b3df 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
@@ -2,1712 +2,1748 @@
// 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/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/resolver/variance.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary2/ast_binary_flags.dart';
-import 'package:analyzer/src/summary2/informative_data.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
-import 'package:analyzer/src/summary2/linking_bundle_context.dart';
+import 'package:analyzer/src/summary2/ast_binary_tag.dart';
+import 'package:analyzer/src/summary2/bundle_writer.dart';
+import 'package:analyzer/src/summary2/data_writer.dart';
import 'package:analyzer/src/summary2/tokens_writer.dart';
+import 'package:analyzer/src/task/inference_error.dart';
+import 'package:meta/meta.dart';
-var timerAstBinaryWriter = Stopwatch();
-var timerAstBinaryWriterClass = Stopwatch();
-var timerAstBinaryWriterDirective = Stopwatch();
-var timerAstBinaryWriterFunctionBody = Stopwatch();
-var timerAstBinaryWriterMixin = Stopwatch();
-var timerAstBinaryWriterTopVar = Stopwatch();
-var timerAstBinaryWriterTypedef = Stopwatch();
+/// Serializer of fully resolved ASTs.
+class AstBinaryWriter extends ThrowingAstVisitor<void> {
+ final bool _withInformative;
+ final BufferedSink _sink;
+ final StringIndexer _stringIndexer;
+ final ResolutionUnit _resolutionUnit;
+ final ResolutionSink _resolutionSink;
-/// Serializer of fully resolved ASTs into flat buffers.
-class AstBinaryWriter extends ThrowingAstVisitor<LinkedNodeBuilder> {
- final LinkingBundleContext _linkingContext;
-
- /// Is `true` if the current [ClassDeclaration] has a const constructor,
- /// so initializers of final fields should be written.
+ /// TODO(scheglov) Keep it private, and write here, similarly as we do
+ /// for [_classMemberIndexItems]?
+ final List<_UnitMemberIndexItem> unitMemberIndexItems = [];
+ final List<_ClassMemberIndexItem> _classMemberIndexItems = [];
+ bool _isConstField = false;
+ bool _isFinalField = false;
+ bool _isConstTopLevelVariable = false;
bool _hasConstConstructor = false;
+ int _nextUnnamedExtensionId = 0;
- AstBinaryWriter(this._linkingContext);
+ AstBinaryWriter({
+ @required BundleWriterAst bundleWriterAst,
+ @required ResolutionUnit resolutionUnit,
+ }) : _withInformative = bundleWriterAst.withInformative,
+ _sink = bundleWriterAst.sink,
+ _stringIndexer = bundleWriterAst.stringIndexer,
+ _resolutionUnit = resolutionUnit,
+ _resolutionSink = resolutionUnit.library.sink;
@override
- LinkedNodeBuilder visitAdjacentStrings(AdjacentStrings node) {
- return LinkedNodeBuilder.adjacentStrings(
- adjacentStrings_strings: _writeNodeList(node.strings),
- );
+ void visitAdjacentStrings(AdjacentStrings node) {
+ _writeByte(Tag.AdjacentStrings);
+ _writeNodeList(node.strings);
}
@override
- LinkedNodeBuilder visitAnnotation(Annotation node) {
- var elementComponents = _componentsOfElement(node.element);
+ void visitAnnotation(Annotation node) {
+ _writeByte(Tag.Annotation);
- LinkedNodeBuilder storedArguments;
+ _writeOptionalNode(node.name);
+ _writeOptionalNode(node.constructorName);
+
var arguments = node.arguments;
if (arguments != null) {
- if (arguments.arguments.every(_isSerializableExpression)) {
- storedArguments = arguments.accept(this);
- } else {
- storedArguments = LinkedNodeBuilder.argumentList();
+ if (!arguments.arguments.every(_isSerializableExpression)) {
+ arguments = null;
+ }
+ }
+ _writeOptionalNode(arguments);
+
+ _resolutionSink.writeElement(node.element);
+ }
+
+ @override
+ void visitArgumentList(ArgumentList node) {
+ _writeByte(Tag.ArgumentList);
+ _writeNodeList(node.arguments);
+ }
+
+ @override
+ void visitAsExpression(AsExpression node) {
+ _writeByte(Tag.AsExpression);
+ _writeNode(node.expression);
+ _writeNode(node.type);
+ _storeExpression(node);
+ }
+
+ @override
+ void visitAssertInitializer(AssertInitializer node) {
+ _writeByte(Tag.AssertInitializer);
+ _writeNode(node.condition);
+ _writeOptionalNode(node.message);
+ }
+
+ @override
+ void visitAssignmentExpression(AssignmentExpression node) {
+ _writeByte(Tag.AssignmentExpression);
+
+ _writeNode(node.leftHandSide);
+ _writeNode(node.rightHandSide);
+
+ var operatorToken = node.operator.type;
+ var binaryToken = TokensWriter.astToBinaryTokenType(operatorToken);
+ _writeByte(binaryToken.index);
+
+ _resolutionSink.writeElement(node.staticElement);
+ _resolutionSink.writeElement(node.readElement);
+ _resolutionSink.writeType(node.readType);
+ _resolutionSink.writeElement(node.writeElement);
+ _resolutionSink.writeType(node.writeType);
+ _storeExpression(node);
+ }
+
+ @override
+ void visitBinaryExpression(BinaryExpression node) {
+ _writeByte(Tag.BinaryExpression);
+
+ _writeNode(node.leftOperand);
+ _writeNode(node.rightOperand);
+
+ var operatorToken = node.operator.type;
+ var binaryToken = TokensWriter.astToBinaryTokenType(operatorToken);
+ _writeByte(binaryToken.index);
+
+ _resolutionSink?.writeElement(node.staticElement);
+ _resolutionSink?.writeType(node.staticType);
+ }
+
+ @override
+ void visitBooleanLiteral(BooleanLiteral node) {
+ _writeByte(Tag.BooleanLiteral);
+ _writeByte(node.value ? 1 : 0);
+ // TODO(scheglov) Dont write type?
+ _resolutionSink?.writeType(node.staticType);
+ }
+
+ @override
+ void visitCascadeExpression(CascadeExpression node) {
+ _writeByte(Tag.CascadeExpression);
+ _writeNode(node.target);
+ _writeNodeList(node.cascadeSections);
+ }
+
+ @override
+ void visitClassDeclaration(ClassDeclaration node) {
+ var classOffset = _sink.offset;
+ var resolutionIndex = _resolutionUnit.enterDeclaration();
+
+ _hasConstConstructor = false;
+ for (var member in node.members) {
+ if (member is ConstructorDeclaration && member.constKeyword != null) {
+ _hasConstConstructor = true;
+ break;
}
}
- return LinkedNodeBuilder.annotation(
- annotation_arguments: storedArguments,
- annotation_constructorName: node.constructorName?.accept(this),
- annotation_element: elementComponents.rawElement,
- annotation_substitution: elementComponents.substitution,
- annotation_name: node.name?.accept(this),
- );
- }
-
- @override
- LinkedNodeBuilder visitArgumentList(ArgumentList node) {
- return LinkedNodeBuilder.argumentList(
- argumentList_arguments: _writeNodeList(node.arguments),
- );
- }
-
- @override
- LinkedNodeBuilder visitAsExpression(AsExpression node) {
- return LinkedNodeBuilder.asExpression(
- asExpression_expression: node.expression.accept(this),
- asExpression_type: node.type.accept(this),
- );
- }
-
- @override
- LinkedNodeBuilder visitAssertInitializer(AssertInitializer node) {
- return LinkedNodeBuilder.assertInitializer(
- assertInitializer_condition: node.condition.accept(this),
- assertInitializer_message: node.message?.accept(this),
- );
- }
-
- @override
- LinkedNodeBuilder visitAssertStatement(AssertStatement node) {
- var builder = LinkedNodeBuilder.assertStatement(
- assertStatement_condition: node.condition.accept(this),
- assertStatement_message: node.message?.accept(this),
- );
- _storeStatement(builder, node);
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitAssignmentExpression(AssignmentExpression node) {
- var elementComponents = _componentsOfElement(node.staticElement);
- return LinkedNodeBuilder.assignmentExpression(
- assignmentExpression_element: elementComponents.rawElement,
- assignmentExpression_substitution: elementComponents.substitution,
- assignmentExpression_leftHandSide: node.leftHandSide.accept(this),
- assignmentExpression_operator: TokensWriter.astToBinaryTokenType(
- node.operator.type,
- ),
- assignmentExpression_rightHandSide: node.rightHandSide.accept(this),
- expression_type: _writeType(node.staticType),
- );
- }
-
- @override
- LinkedNodeBuilder visitAwaitExpression(AwaitExpression node) {
- return LinkedNodeBuilder.awaitExpression(
- awaitExpression_expression: node.expression.accept(this),
- expression_type: _writeType(node.staticType),
- );
- }
-
- @override
- LinkedNodeBuilder visitBinaryExpression(BinaryExpression node) {
- var elementComponents = _componentsOfElement(node.staticElement);
- return LinkedNodeBuilder.binaryExpression(
- binaryExpression_element: elementComponents.rawElement,
- binaryExpression_substitution: elementComponents.substitution,
- binaryExpression_leftOperand: node.leftOperand.accept(this),
- binaryExpression_operator: TokensWriter.astToBinaryTokenType(
- node.operator.type,
- ),
- binaryExpression_rightOperand: node.rightOperand.accept(this),
- expression_type: _writeType(node.staticType),
- );
- }
-
- @override
- LinkedNodeBuilder visitBlock(Block node) {
- return LinkedNodeBuilder.block(
- block_statements: _writeNodeList(node.statements),
- );
- }
-
- @override
- LinkedNodeBuilder visitBlockFunctionBody(BlockFunctionBody node) {
- timerAstBinaryWriterFunctionBody.start();
- try {
- var builder = LinkedNodeBuilder.blockFunctionBody(
- blockFunctionBody_block: node.block.accept(this),
- );
- builder.flags = AstBinaryFlags.encode(
- isAsync: node.keyword?.keyword == Keyword.ASYNC,
- isStar: node.star != null,
- isSync: node.keyword?.keyword == Keyword.SYNC,
- );
- return builder;
- } finally {
- timerAstBinaryWriterFunctionBody.stop();
- }
- }
-
- @override
- LinkedNodeBuilder visitBooleanLiteral(BooleanLiteral node) {
- return LinkedNodeBuilder.booleanLiteral(
- booleanLiteral_value: node.value,
- );
- }
-
- @override
- LinkedNodeBuilder visitBreakStatement(BreakStatement node) {
- var builder = LinkedNodeBuilder.breakStatement(
- breakStatement_label: node.label?.accept(this),
- );
- _storeStatement(builder, node);
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitCascadeExpression(CascadeExpression node) {
- var builder = LinkedNodeBuilder.cascadeExpression(
- cascadeExpression_target: node.target.accept(this),
- cascadeExpression_sections: _writeNodeList(node.cascadeSections),
- );
- _storeExpression(builder, node);
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitCatchClause(CatchClause node) {
- return LinkedNodeBuilder.catchClause(
- catchClause_body: node.body.accept(this),
- catchClause_exceptionParameter: node.exceptionParameter?.accept(this),
- catchClause_exceptionType: node.exceptionType?.accept(this),
- catchClause_stackTraceParameter: node.stackTraceParameter?.accept(this),
- );
- }
-
- @override
- LinkedNodeBuilder visitClassDeclaration(ClassDeclaration node) {
- try {
- timerAstBinaryWriterClass.start();
-
- _hasConstConstructor = false;
- for (var member in node.members) {
- if (member is ConstructorDeclaration && member.constKeyword != null) {
- _hasConstConstructor = true;
- break;
- }
- }
-
- var builder = LinkedNodeBuilder.classDeclaration(
- classDeclaration_extendsClause: node.extendsClause?.accept(this),
- classDeclaration_nativeClause: node.nativeClause?.accept(this),
- classDeclaration_withClause: node.withClause?.accept(this),
- );
- builder.flags = AstBinaryFlags.encode(
+ _writeByte(Tag.Class);
+ _writeByte(
+ AstBinaryFlags.encode(
+ hasConstConstructor: _hasConstConstructor,
isAbstract: node.abstractKeyword != null,
- );
- _storeClassOrMixinDeclaration(builder, node);
- return builder;
- } finally {
- timerAstBinaryWriterClass.stop();
- }
- }
+ ),
+ );
+ _resolutionSink.writeByte(node.declaredElement.isSimplyBounded ? 1 : 0);
- @override
- LinkedNodeBuilder visitClassTypeAlias(ClassTypeAlias node) {
- timerAstBinaryWriterClass.start();
- try {
- var builder = LinkedNodeBuilder.classTypeAlias(
- classTypeAlias_implementsClause: node.implementsClause?.accept(this),
- classTypeAlias_superclass: node.superclass.accept(this),
- classTypeAlias_typeParameters: node.typeParameters?.accept(this),
- classTypeAlias_withClause: node.withClause.accept(this),
- );
- builder.flags = AstBinaryFlags.encode(
- isAbstract: node.abstractKeyword != null,
- );
- _storeTypeAlias(builder, node);
- _storeIsSimpleBounded(builder, node);
- return builder;
- } finally {
- timerAstBinaryWriterClass.stop();
- }
- }
+ _writeInformativeUint30(node.offset);
+ _writeInformativeUint30(node.length);
+ _writeDocumentationCommentString(node.documentationComment);
- @override
- LinkedNodeBuilder visitComment(Comment node) {
- LinkedNodeCommentType type;
- if (node.isBlock) {
- type = LinkedNodeCommentType.block;
- } else if (node.isDocumentation) {
- type = LinkedNodeCommentType.documentation;
- } else if (node.isEndOfLine) {
- type = LinkedNodeCommentType.endOfLine;
- }
+ _pushScopeTypeParameters(node.typeParameters);
- return LinkedNodeBuilder.comment(
- comment_tokens: node.tokens.map((t) => t.lexeme).toList(),
- comment_type: type,
- // TODO(scheglov) restore
-// comment_references: _writeNodeList(node.references),
+ _writeOptionalNode(node.typeParameters);
+ _writeOptionalNode(node.extendsClause);
+ _writeOptionalNode(node.withClause);
+ _writeOptionalNode(node.implementsClause);
+ _writeOptionalNode(node.nativeClause);
+ _storeNamedCompilationUnitMember(node);
+ _writeUInt30(resolutionIndex);
+
+ _classMemberIndexItems.clear();
+ _writeNodeList(node.members);
+ _hasConstConstructor = false;
+
+ _resolutionSink.localElements.popScope();
+
+ // TODO(scheglov) write member index
+ var classIndexOffset = _sink.offset;
+ _writeClassMemberIndex();
+
+ unitMemberIndexItems.add(
+ _UnitMemberIndexItem(
+ offset: classOffset,
+ tag: Tag.Class,
+ name: node.name.name,
+ classIndexOffset: classIndexOffset,
+ ),
);
}
@override
- LinkedNodeBuilder visitCommentReference(CommentReference node) {
-// var identifier = node.identifier;
-// _tokensWriter.writeTokens(
-// node.newKeyword ?? identifier.beginToken,
-// identifier.endToken,
-// );
-//
-// return LinkedNodeBuilder.commentReference(
-// commentReference_identifier: identifier.accept(this),
-// commentReference_newKeyword: _getToken(node.newKeyword),
-// );
- return null;
+ void visitClassTypeAlias(ClassTypeAlias node) {
+ unitMemberIndexItems.add(
+ _UnitMemberIndexItem(
+ offset: _sink.offset,
+ tag: Tag.ClassTypeAlias,
+ name: node.name.name,
+ ),
+ );
+
+ var resolutionIndex = _resolutionUnit.enterDeclaration();
+
+ _writeByte(Tag.ClassTypeAlias);
+ _writeByte(
+ AstBinaryFlags.encode(
+ isAbstract: node.abstractKeyword != null,
+ ),
+ );
+ _resolutionSink.writeByte(node.declaredElement.isSimplyBounded ? 1 : 0);
+ _writeInformativeUint30(node.offset);
+ _writeInformativeUint30(node.length);
+ _pushScopeTypeParameters(node.typeParameters);
+ _writeOptionalNode(node.typeParameters);
+ _writeNode(node.superclass);
+ _writeNode(node.withClause);
+ _writeOptionalNode(node.implementsClause);
+ _storeTypeAlias(node);
+ _writeDocumentationCommentString(node.documentationComment);
+ _writeUInt30(resolutionIndex);
+ _resolutionSink.localElements.popScope();
}
@override
- LinkedNodeBuilder visitCompilationUnit(CompilationUnit node) {
+ void visitCompilationUnit(CompilationUnit node) {
var nodeImpl = node as CompilationUnitImpl;
- var builder = LinkedNodeBuilder.compilationUnit(
- compilationUnit_declarations: _writeNodeList(node.declarations),
- compilationUnit_directives: _writeNodeList(node.directives),
- compilationUnit_featureSet:
- (node.featureSet as ExperimentStatus).toStorage(),
- compilationUnit_languageVersion: LinkedLibraryLanguageVersionBuilder(
- package: LinkedLanguageVersionBuilder(
- major: nodeImpl.languageVersion.package.major,
- minor: nodeImpl.languageVersion.package.minor,
- ),
- override2: nodeImpl.languageVersion.override != null
- ? LinkedLanguageVersionBuilder(
- major: nodeImpl.languageVersion.override.major,
- minor: nodeImpl.languageVersion.override.minor,
- )
- : null,
+ _writeLanguageVersion(nodeImpl.languageVersion);
+ _writeFeatureSet(node.featureSet);
+ _writeLineInfo(node.lineInfo);
+ _writeUInt30(_withInformative ? node.length : 0);
+ _writeNodeList(node.directives);
+ for (var declaration in node.declarations) {
+ declaration.accept(this);
+ }
+ }
+
+ @override
+ void visitConditionalExpression(ConditionalExpression node) {
+ _writeByte(Tag.ConditionalExpression);
+ _writeNode(node.condition);
+ _writeNode(node.thenExpression);
+ _writeNode(node.elseExpression);
+ _storeExpression(node);
+ }
+
+ @override
+ void visitConfiguration(Configuration node) {
+ _writeByte(Tag.Configuration);
+
+ _writeByte(
+ AstBinaryFlags.encode(
+ hasEqual: node.equalToken != null,
),
- compilationUnit_scriptTag: node.scriptTag?.accept(this),
- informativeId: getInformativeId(node),
);
- return builder;
+
+ _writeNode(node.name);
+ _writeOptionalNode(node.value);
+ _writeNode(node.uri);
}
@override
- LinkedNodeBuilder visitConditionalExpression(ConditionalExpression node) {
- var builder = LinkedNodeBuilder.conditionalExpression(
- conditionalExpression_condition: node.condition.accept(this),
- conditionalExpression_elseExpression: node.elseExpression.accept(this),
- conditionalExpression_thenExpression: node.thenExpression.accept(this),
+ void visitConstructorDeclaration(ConstructorDeclaration node) {
+ _classMemberIndexItems.add(
+ _ClassMemberIndexItem(
+ offset: _sink.offset,
+ tag: Tag.ConstructorDeclaration,
+ name: node.name?.name ?? '',
+ ),
);
- _storeExpression(builder, node);
- return builder;
+
+ _writeByte(Tag.ConstructorDeclaration);
+
+ _writeByte(
+ AstBinaryFlags.encode(
+ hasName: node.name != null,
+ hasSeparatorColon: node.separator?.type == TokenType.COLON,
+ hasSeparatorEquals: node.separator?.type == TokenType.EQ,
+ isAbstract: node.body is EmptyFunctionBody,
+ isConst: node.constKeyword != null,
+ isExternal: node.externalKeyword != null,
+ isFactory: node.factoryKeyword != null,
+ ),
+ );
+
+ _writeInformativeUint30(node.offset);
+ _writeInformativeUint30(node.length);
+ _writeDocumentationCommentString(node.documentationComment);
+
+ var resolutionIndex = _resolutionUnit.enterDeclaration();
+ _writeNode(node.returnType);
+ if (node.period != null) {
+ _writeInformativeUint30(node.period.offset);
+ _writeDeclarationName(node.name);
+ }
+ _writeNode(node.parameters);
+
+ _resolutionSink.localElements.pushScope();
+ for (var parameter in node.parameters.parameters) {
+ _resolutionSink.localElements.declare(parameter.declaredElement);
+ }
+ _writeNodeList(node.initializers);
+ _resolutionSink.localElements.popScope();
+
+ _writeOptionalNode(node.redirectedConstructor);
+ _storeClassMember(node);
+ _writeUInt30(resolutionIndex);
}
@override
- LinkedNodeBuilder visitConfiguration(Configuration node) {
- var builder = LinkedNodeBuilder.configuration(
- configuration_name: node.name?.accept(this),
- configuration_value: node.value?.accept(this),
- configuration_uri: node.uri?.accept(this),
+ void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+ _writeByte(Tag.ConstructorFieldInitializer);
+
+ _writeByte(
+ AstBinaryFlags.encode(
+ hasThis: node.thisKeyword != null,
+ ),
);
- builder.flags = AstBinaryFlags.encode(
- hasEqual: node.equalToken != null,
- );
- return builder;
+
+ _writeNode(node.fieldName);
+ _writeNode(node.expression);
+ _storeConstructorInitializer(node);
}
@override
- LinkedNodeBuilder visitConstructorDeclaration(ConstructorDeclaration node) {
- var builder = LinkedNodeBuilder.constructorDeclaration(
- constructorDeclaration_initializers: _writeNodeList(node.initializers),
- constructorDeclaration_parameters: node.parameters.accept(this),
- constructorDeclaration_redirectedConstructor:
- node.redirectedConstructor?.accept(this),
- constructorDeclaration_returnType: node.returnType.accept(this),
- informativeId: getInformativeId(node),
- );
- builder.flags = AstBinaryFlags.encode(
- hasName: node.name != null,
- hasSeparatorColon: node.separator?.type == TokenType.COLON,
- hasSeparatorEquals: node.separator?.type == TokenType.EQ,
- isAbstract: node.body is EmptyFunctionBody,
- isConst: node.constKeyword != null,
- isExternal: node.externalKeyword != null,
- isFactory: node.factoryKeyword != null,
- );
- builder.name = node.name?.name;
- _storeClassMember(builder, node);
- return builder;
+ void visitConstructorName(ConstructorName node) {
+ _writeByte(Tag.ConstructorName);
+ _writeNode(node.type);
+ _writeOptionalNode(node.name);
+ _resolutionSink?.writeElement(node.staticElement);
}
@override
- LinkedNodeBuilder visitConstructorFieldInitializer(
- ConstructorFieldInitializer node) {
- var builder = LinkedNodeBuilder.constructorFieldInitializer(
- constructorFieldInitializer_expression: node.expression.accept(this),
- constructorFieldInitializer_fieldName: node.fieldName.accept(this),
+ void visitDeclaredIdentifier(DeclaredIdentifier node) {
+ _writeByte(Tag.DeclaredIdentifier);
+ _writeByte(
+ AstBinaryFlags.encode(
+ isConst: node.keyword?.keyword == Keyword.CONST,
+ isFinal: node.keyword?.keyword == Keyword.FINAL,
+ isVar: node.keyword?.keyword == Keyword.VAR,
+ ),
);
- builder.flags = AstBinaryFlags.encode(
- hasThis: node.thisKeyword != null,
- );
- _storeConstructorInitializer(builder, node);
- return builder;
+ _writeOptionalNode(node.type);
+ _writeDeclarationName(node.identifier);
+ _storeDeclaration(node);
}
@override
- LinkedNodeBuilder visitConstructorName(ConstructorName node) {
- var elementComponents = _componentsOfElement(node.staticElement);
- return LinkedNodeBuilder.constructorName(
- constructorName_element: elementComponents.rawElement,
- constructorName_substitution: elementComponents.substitution,
- constructorName_name: node.name?.accept(this),
- constructorName_type: node.type.accept(this),
- );
- }
+ void visitDefaultFormalParameter(DefaultFormalParameter node) {
+ _writeByte(Tag.DefaultFormalParameter);
- @override
- LinkedNodeBuilder visitContinueStatement(ContinueStatement node) {
- var builder = LinkedNodeBuilder.continueStatement(
- continueStatement_label: node.label?.accept(this),
+ _writeByte(
+ AstBinaryFlags.encode(
+ hasInitializer: node.defaultValue != null,
+ isPositional: node.isPositional,
+ isRequired: node.isRequired,
+ ),
);
- _storeStatement(builder, node);
- return builder;
- }
- @override
- LinkedNodeBuilder visitDeclaredIdentifier(DeclaredIdentifier node) {
- var builder = LinkedNodeBuilder.declaredIdentifier(
- declaredIdentifier_identifier: node.identifier.accept(this),
- declaredIdentifier_type: node.type?.accept(this),
- );
- builder.flags = AstBinaryFlags.encode(
- isConst: node.keyword?.keyword == Keyword.CONST,
- isFinal: node.keyword?.keyword == Keyword.FINAL,
- isVar: node.keyword?.keyword == Keyword.VAR,
- );
- _storeDeclaration(builder, node);
- return builder;
- }
+ _writeInformativeUint30(node.offset);
+ _writeInformativeUint30(node.length);
- @override
- LinkedNodeBuilder visitDefaultFormalParameter(DefaultFormalParameter node) {
+ _writeNode(node.parameter);
+
var defaultValue = node.defaultValue;
if (!_isSerializableExpression(defaultValue)) {
defaultValue = null;
}
-
- var builder = LinkedNodeBuilder.defaultFormalParameter(
- defaultFormalParameter_defaultValue: defaultValue?.accept(this),
- defaultFormalParameter_kind: _toParameterKind(node),
- defaultFormalParameter_parameter: node.parameter.accept(this),
- informativeId: getInformativeId(node),
- );
- builder.flags = AstBinaryFlags.encode(
- hasInitializer: node.defaultValue != null,
- );
- return builder;
+ _writeOptionalNode(defaultValue);
}
@override
- LinkedNodeBuilder visitDoStatement(DoStatement node) {
- return LinkedNodeBuilder.doStatement(
- doStatement_body: node.body.accept(this),
- doStatement_condition: node.condition.accept(this),
- );
+ void visitDottedName(DottedName node) {
+ _writeByte(Tag.DottedName);
+ _writeNodeList(node.components);
}
@override
- LinkedNodeBuilder visitDottedName(DottedName node) {
- return LinkedNodeBuilder.dottedName(
- dottedName_components: _writeNodeList(node.components),
- );
+ void visitDoubleLiteral(DoubleLiteral node) {
+ _writeByte(Tag.DoubleLiteral);
+ _writeDouble(node.value);
}
@override
- LinkedNodeBuilder visitDoubleLiteral(DoubleLiteral node) {
- return LinkedNodeBuilder.doubleLiteral(
- doubleLiteral_value: node.value,
- );
+ void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
+ _writeByte(Tag.EnumConstantDeclaration);
+
+ _writeInformativeUint30(node.offset);
+ _writeInformativeUint30(node.length);
+ _writeDocumentationCommentString(node.documentationComment);
+
+ _writeDeclarationName(node.name);
+ _storeDeclaration(node);
}
@override
- LinkedNodeBuilder visitEmptyFunctionBody(EmptyFunctionBody node) {
- var builder = LinkedNodeBuilder.emptyFunctionBody();
- _storeFunctionBody(builder, node);
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitEmptyStatement(EmptyStatement node) {
- return LinkedNodeBuilder.emptyStatement();
- }
-
- @override
- LinkedNodeBuilder visitEnumConstantDeclaration(EnumConstantDeclaration node) {
- var builder = LinkedNodeBuilder.enumConstantDeclaration(
- informativeId: getInformativeId(node),
- );
- builder..name = node.name.name;
- _storeDeclaration(builder, node);
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitEnumDeclaration(EnumDeclaration node) {
- var builder = LinkedNodeBuilder.enumDeclaration(
- enumDeclaration_constants: _writeNodeList(node.constants),
- );
- _storeNamedCompilationUnitMember(builder, node);
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitExportDirective(ExportDirective node) {
- timerAstBinaryWriterDirective.start();
- try {
- var builder = LinkedNodeBuilder.exportDirective();
- _storeNamespaceDirective(builder, node);
- return builder;
- } finally {
- timerAstBinaryWriterDirective.stop();
- }
- }
-
- @override
- LinkedNodeBuilder visitExpressionFunctionBody(ExpressionFunctionBody node) {
- timerAstBinaryWriterFunctionBody.start();
- try {
- var builder = LinkedNodeBuilder.expressionFunctionBody(
- expressionFunctionBody_expression: node.expression.accept(this),
- );
- builder.flags = AstBinaryFlags.encode(
- isAsync: node.keyword?.keyword == Keyword.ASYNC,
- isSync: node.keyword?.keyword == Keyword.SYNC,
- );
- return builder;
- } finally {
- timerAstBinaryWriterFunctionBody.stop();
- }
- }
-
- @override
- LinkedNodeBuilder visitExpressionStatement(ExpressionStatement node) {
- return LinkedNodeBuilder.expressionStatement(
- expressionStatement_expression: node.expression.accept(this),
- );
- }
-
- @override
- LinkedNodeBuilder visitExtendsClause(ExtendsClause node) {
- return LinkedNodeBuilder.extendsClause(
- extendsClause_superclass: node.superclass.accept(this),
- );
- }
-
- @override
- LinkedNodeBuilder visitExtensionDeclaration(ExtensionDeclaration node) {
- var builder = LinkedNodeBuilder.extensionDeclaration(
- extensionDeclaration_extendedType: node.extendedType.accept(this),
- extensionDeclaration_members: _writeNodeList(node.members),
- extensionDeclaration_typeParameters: node.typeParameters?.accept(this),
- );
-
- _storeCompilationUnitMember(builder, node);
- _storeInformativeId(builder, node);
- builder.name = node.name?.name;
- LazyExtensionDeclaration.get(node).put(builder);
-
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitExtensionOverride(ExtensionOverride node) {
- var builder = LinkedNodeBuilder.extensionOverride(
- extensionOverride_arguments: _writeNodeList(
- node.argumentList.arguments,
+ void visitEnumDeclaration(EnumDeclaration node) {
+ var resolutionIndex = _resolutionUnit.enterDeclaration();
+ unitMemberIndexItems.add(
+ _UnitMemberIndexItem(
+ offset: _sink.offset,
+ tag: Tag.EnumDeclaration,
+ name: node.name.name,
),
- extensionOverride_extensionName: node.extensionName.accept(this),
- extensionOverride_typeArguments: node.typeArguments?.accept(this),
- extensionOverride_typeArgumentTypes:
- node.typeArgumentTypes.map(_writeType).toList(),
- extensionOverride_extendedType: _writeType(node.extendedType),
);
- return builder;
+
+ _writeByte(Tag.EnumDeclaration);
+
+ _writeInformativeUint30(node.offset);
+ _writeInformativeUint30(node.length);
+ _writeDocumentationCommentString(node.documentationComment);
+
+ _writeNodeList(node.constants);
+ _storeNamedCompilationUnitMember(node);
+ _writeUInt30(resolutionIndex);
}
@override
- LinkedNodeBuilder visitFieldDeclaration(FieldDeclaration node) {
- var builder = LinkedNodeBuilder.fieldDeclaration(
- fieldDeclaration_fields: node.fields.accept(this),
- informativeId: getInformativeId(node),
- );
- builder.flags = AstBinaryFlags.encode(
- isAbstract: node.abstractKeyword != null,
- isCovariant: node.covariantKeyword != null,
- isExternal: node.externalKeyword != null,
- isStatic: node.staticKeyword != null,
- );
- _storeClassMember(builder, node);
+ void visitExportDirective(ExportDirective node) {
+ var resolutionIndex = _resolutionUnit.enterDeclaration();
- return builder;
- }
+ _writeByte(Tag.ExportDirective);
+ _storeNamespaceDirective(node);
+ _writeUInt30(resolutionIndex);
- @override
- LinkedNodeBuilder visitFieldFormalParameter(FieldFormalParameter node) {
- var builder = LinkedNodeBuilder.fieldFormalParameter(
- fieldFormalParameter_formalParameters: node.parameters?.accept(this),
- fieldFormalParameter_type: node.type?.accept(this),
- fieldFormalParameter_typeParameters: node.typeParameters?.accept(this),
- );
- _storeNormalFormalParameter(builder, node, node.keyword);
- builder.flags |= AstBinaryFlags.encode(hasQuestion: node.question != null);
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitForEachPartsWithDeclaration(
- ForEachPartsWithDeclaration node) {
- var builder = LinkedNodeBuilder.forEachPartsWithDeclaration(
- forEachPartsWithDeclaration_loopVariable: node.loopVariable.accept(this),
- );
- _storeForEachParts(builder, node);
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitForEachPartsWithIdentifier(
- ForEachPartsWithIdentifier node) {
- var builder = LinkedNodeBuilder.forEachPartsWithIdentifier(
- forEachPartsWithIdentifier_identifier: node.identifier.accept(this),
- );
- _storeForEachParts(builder, node);
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitForElement(ForElement node) {
- var builder = LinkedNodeBuilder.forElement(
- forElement_body: node.body.accept(this),
- );
- _storeForMixin(builder, node as ForElementImpl);
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitFormalParameterList(FormalParameterList node) {
- var builder = LinkedNodeBuilder.formalParameterList(
- formalParameterList_parameters: _writeNodeList(node.parameters),
- );
- builder.flags = AstBinaryFlags.encode(
- isDelimiterCurly:
- node.leftDelimiter?.type == TokenType.OPEN_CURLY_BRACKET,
- isDelimiterSquare:
- node.leftDelimiter?.type == TokenType.OPEN_SQUARE_BRACKET,
- );
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitForPartsWithDeclarations(
- ForPartsWithDeclarations node) {
- var builder = LinkedNodeBuilder.forPartsWithDeclarations(
- forPartsWithDeclarations_variables: node.variables.accept(this),
- );
- _storeForParts(builder, node);
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitForPartsWithExpression(ForPartsWithExpression node) {
- var builder = LinkedNodeBuilder.forPartsWithExpression(
- forPartsWithExpression_initialization: node.initialization?.accept(this),
- );
- _storeForParts(builder, node);
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitForStatement(ForStatement node) {
- var builder = LinkedNodeBuilder.forStatement(
- forStatement_body: node.body.accept(this),
- );
- _storeForMixin(builder, node as ForStatementImpl);
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitFunctionDeclaration(FunctionDeclaration node) {
- var builder = LinkedNodeBuilder.functionDeclaration(
- functionDeclaration_returnType: node.returnType?.accept(this),
- functionDeclaration_functionExpression:
- node.functionExpression?.accept(this),
- );
- builder.flags = AstBinaryFlags.encode(
- isExternal: node.externalKeyword != null,
- isGet: node.isGetter,
- isSet: node.isSetter,
- );
- _storeNamedCompilationUnitMember(builder, node);
- _writeActualReturnType(builder, node);
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitFunctionDeclarationStatement(
- FunctionDeclarationStatement node) {
- return LinkedNodeBuilder.functionDeclarationStatement(
- functionDeclarationStatement_functionDeclaration:
- node.functionDeclaration.accept(this),
+ _resolutionSink?.writeElement(
+ (node.element as ExportElementImpl).exportedLibrary,
);
}
@override
- LinkedNodeBuilder visitFunctionExpression(FunctionExpression node) {
- var bodyToStore = node.body;
- if (node.parent.parent is CompilationUnit) {
- bodyToStore = null;
- }
- var builder = LinkedNodeBuilder.functionExpression(
- functionExpression_typeParameters: node.typeParameters?.accept(this),
- functionExpression_formalParameters: node.parameters?.accept(this),
- functionExpression_body: bodyToStore?.accept(this),
- );
- builder.flags = AstBinaryFlags.encode(
- isAsync: node.body?.isAsynchronous ?? false,
- isGenerator: node.body?.isGenerator ?? false,
- );
- return builder;
+ void visitExtendsClause(ExtendsClause node) {
+ _writeByte(Tag.ExtendsClause);
+ _writeNode(node.superclass);
}
@override
- LinkedNodeBuilder visitFunctionExpressionInvocation(
- FunctionExpressionInvocation node) {
- var builder = LinkedNodeBuilder.functionExpressionInvocation(
- functionExpressionInvocation_function: node.function?.accept(this),
+ void visitExtensionDeclaration(ExtensionDeclaration node) {
+ var classOffset = _sink.offset;
+ var resolutionIndex = _resolutionUnit.enterDeclaration();
+
+ _writeByte(Tag.ExtensionDeclaration);
+
+ _writeInformativeUint30(node.offset);
+ _writeInformativeUint30(node.length);
+ _writeDocumentationCommentString(node.documentationComment);
+
+ _pushScopeTypeParameters(node.typeParameters);
+ _writeOptionalNode(node.typeParameters);
+ _writeNode(node.extendedType);
+ _writeOptionalDeclarationName(node.name);
+ _storeCompilationUnitMember(node);
+ _writeUInt30(resolutionIndex);
+
+ _classMemberIndexItems.clear();
+ _writeNodeList(node.members);
+
+ _resolutionSink.localElements.popScope();
+
+ // TODO(scheglov) write member index
+ var classIndexOffset = _sink.offset;
+ _writeClassMemberIndex();
+
+ var nameIdentifier = node.name;
+ var indexName = nameIdentifier != null
+ ? nameIdentifier.name
+ : 'extension-${_nextUnnamedExtensionId++}';
+ unitMemberIndexItems.add(
+ _UnitMemberIndexItem(
+ offset: classOffset,
+ tag: Tag.ExtensionDeclaration,
+ name: indexName,
+ classIndexOffset: classIndexOffset,
+ ),
);
- _storeInvocationExpression(builder, node);
- return builder;
}
@override
- LinkedNodeBuilder visitFunctionTypeAlias(FunctionTypeAlias node) {
- timerAstBinaryWriterTypedef.start();
+ void visitExtensionOverride(ExtensionOverride node) {
+ _writeByte(Tag.ExtensionOverride);
+ _writeNode(node.extensionName);
+ _writeOptionalNode(node.typeArguments);
+ _writeNode(node.argumentList);
+ _resolutionSink.writeType(node.extendedType);
+ // TODO(scheglov) typeArgumentTypes?
+ }
+
+ @override
+ void visitFieldDeclaration(FieldDeclaration node) {
+ _classMemberIndexItems.add(
+ _ClassMemberIndexItem(
+ offset: _sink.offset,
+ tag: Tag.FieldDeclaration,
+ fieldNames: node.fields.variables.map((e) => e.name.name).toList(),
+ ),
+ );
+
+ _writeByte(Tag.FieldDeclaration);
+ _writeByte(
+ AstBinaryFlags.encode(
+ isAbstract: node.abstractKeyword != null,
+ isCovariant: node.covariantKeyword != null,
+ isExternal: node.externalKeyword != null,
+ isStatic: node.staticKeyword != null,
+ ),
+ );
+
+ _writeInformativeVariableCodeRanges(node.offset, node.fields);
+ _writeDocumentationCommentString(node.documentationComment);
+
+ var resolutionIndex = _resolutionUnit.enterDeclaration();
+
+ _isConstField = node.fields.isConst;
+ _isFinalField = node.fields.isFinal;
try {
- var builder = LinkedNodeBuilder.functionTypeAlias(
- functionTypeAlias_formalParameters: node.parameters.accept(this),
- functionTypeAlias_returnType: node.returnType?.accept(this),
- functionTypeAlias_typeParameters: node.typeParameters?.accept(this),
- typeAlias_hasSelfReference:
- LazyFunctionTypeAlias.getHasSelfReference(node),
- );
- _storeTypeAlias(builder, node);
- _writeActualReturnType(builder, node);
- _storeIsSimpleBounded(builder, node);
- return builder;
+ _writeNode(node.fields);
} finally {
- timerAstBinaryWriterTypedef.stop();
+ _isConstField = false;
+ _isFinalField = false;
}
+
+ _storeClassMember(node);
+
+ _writeUInt30(resolutionIndex);
}
@override
- LinkedNodeBuilder visitFunctionTypedFormalParameter(
- FunctionTypedFormalParameter node) {
- var builder = LinkedNodeBuilder.functionTypedFormalParameter(
- functionTypedFormalParameter_formalParameters:
- node.parameters.accept(this),
- functionTypedFormalParameter_returnType: node.returnType?.accept(this),
- functionTypedFormalParameter_typeParameters:
- node.typeParameters?.accept(this),
- );
- _storeNormalFormalParameter(builder, node, null);
- return builder;
- }
+ void visitFieldFormalParameter(FieldFormalParameter node) {
+ _writeByte(Tag.FieldFormalParameter);
- @override
- LinkedNodeBuilder visitGenericFunctionType(GenericFunctionType node) {
- var id = LazyAst.getGenericFunctionTypeId(node);
- assert(id != null);
-
- var builder = LinkedNodeBuilder.genericFunctionType(
- genericFunctionType_id: id,
- genericFunctionType_returnType: node.returnType?.accept(this),
- genericFunctionType_typeParameters: node.typeParameters?.accept(this),
- genericFunctionType_formalParameters: node.parameters.accept(this),
- genericFunctionType_type: _writeType(node.type),
- );
- builder.flags = AstBinaryFlags.encode(
+ _pushScopeTypeParameters(node.typeParameters);
+ _writeOptionalNode(node.typeParameters);
+ _writeOptionalNode(node.type);
+ _writeOptionalNode(node.parameters);
+ _storeNormalFormalParameter(
+ node,
+ node.keyword,
hasQuestion: node.question != null,
);
- _writeActualReturnType(builder, node);
-
- return builder;
+ _resolutionSink.localElements.popScope();
}
@override
- LinkedNodeBuilder visitGenericTypeAlias(GenericTypeAlias node) {
- timerAstBinaryWriterTypedef.start();
- try {
- var builder = LinkedNodeBuilder.genericTypeAlias(
- genericTypeAlias_typeParameters: node.typeParameters?.accept(this),
- genericTypeAlias_functionType: node.functionType?.accept(this),
- typeAlias_hasSelfReference:
- LazyGenericTypeAlias.getHasSelfReference(node),
- );
- _storeTypeAlias(builder, node);
- _storeIsSimpleBounded(builder, node);
- return builder;
- } finally {
- timerAstBinaryWriterTypedef.stop();
+ void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
+ _writeByte(Tag.ForEachPartsWithDeclaration);
+ _writeNode(node.loopVariable);
+ _storeForEachParts(node);
+ }
+
+ @override
+ void visitForElement(ForElement node) {
+ _writeByte(Tag.ForElement);
+ _writeNode(node.body);
+ _storeForMixin(node as ForElementImpl);
+ }
+
+ @override
+ void visitFormalParameterList(FormalParameterList node) {
+ _writeByte(Tag.FormalParameterList);
+
+ var leftDelimiter = node.leftDelimiter?.type;
+ _writeByte(
+ AstBinaryFlags.encode(
+ isDelimiterCurly: leftDelimiter == TokenType.OPEN_CURLY_BRACKET,
+ isDelimiterSquare: leftDelimiter == TokenType.OPEN_SQUARE_BRACKET,
+ ),
+ );
+
+ _writeNodeList(node.parameters);
+ }
+
+ @override
+ void visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
+ _writeByte(Tag.ForPartsWithDeclarations);
+ _writeNode(node.variables);
+ _storeForParts(node);
+ }
+
+ @override
+ void visitFunctionDeclaration(FunctionDeclaration node) {
+ var indexTag = Tag.FunctionDeclaration;
+ if (node.isGetter) {
+ indexTag = Tag.FunctionDeclaration_getter;
+ } else if (node.isSetter) {
+ indexTag = Tag.FunctionDeclaration_setter;
}
- }
-
- @override
- LinkedNodeBuilder visitHideCombinator(HideCombinator node) {
- var builder = LinkedNodeBuilder.hideCombinator(
- names: node.hiddenNames.map((id) => id.name).toList(),
+ unitMemberIndexItems.add(
+ _UnitMemberIndexItem(
+ offset: _sink.offset,
+ tag: indexTag,
+ name: node.name.name,
+ variableNames: null,
+ ),
);
- _storeInformativeId(builder, node);
- return builder;
- }
- @override
- LinkedNodeBuilder visitIfElement(IfElement node) {
- var builder = LinkedNodeBuilder.ifElement(
- ifMixin_condition: node.condition.accept(this),
- ifElement_elseElement: node.elseElement?.accept(this),
- ifElement_thenElement: node.thenElement.accept(this),
+ _writeByte(Tag.FunctionDeclaration);
+
+ _writeByte(
+ AstBinaryFlags.encode(
+ isExternal: node.externalKeyword != null,
+ isGet: node.isGetter,
+ isSet: node.isSetter,
+ ),
);
- return builder;
+
+ _writeInformativeUint30(node.offset);
+ _writeInformativeUint30(node.length);
+ _writeDocumentationCommentString(node.documentationComment);
+
+ var resolutionIndex = _resolutionUnit.enterDeclaration();
+
+ _pushScopeTypeParameters(node.functionExpression.typeParameters);
+
+ _writeNode(node.functionExpression);
+ _writeOptionalNode(node.returnType);
+ _storeNamedCompilationUnitMember(node);
+ _writeActualReturnType(node.declaredElement.returnType);
+
+ _resolutionSink.localElements.popScope();
+
+ _writeUInt30(resolutionIndex);
}
@override
- LinkedNodeBuilder visitIfStatement(IfStatement node) {
- var builder = LinkedNodeBuilder.ifStatement(
- ifMixin_condition: node.condition.accept(this),
- ifStatement_elseStatement: node.elseStatement?.accept(this),
- ifStatement_thenStatement: node.thenStatement.accept(this),
+ void visitFunctionExpression(FunctionExpression node) {
+ _writeByte(Tag.FunctionExpression);
+
+ var body = node.body;
+ _writeByte(
+ AstBinaryFlags.encode(
+ isAsync: body?.isAsynchronous ?? false,
+ isGenerator: body?.isGenerator ?? false,
+ ),
);
- return builder;
+
+ _writeOptionalNode(node.typeParameters);
+ _writeOptionalNode(node.parameters);
}
@override
- LinkedNodeBuilder visitImplementsClause(ImplementsClause node) {
- return LinkedNodeBuilder.implementsClause(
- implementsClause_interfaces: _writeNodeList(node.interfaces),
+ void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+ _writeByte(Tag.FunctionExpressionInvocation);
+ _writeNode(node.function);
+ _storeInvocationExpression(node);
+ }
+
+ @override
+ void visitFunctionTypeAlias(FunctionTypeAlias node) {
+ unitMemberIndexItems.add(
+ _UnitMemberIndexItem(
+ offset: _sink.offset,
+ tag: Tag.FunctionTypeAlias,
+ name: node.name.name,
+ variableNames: null,
+ ),
);
+
+ _writeByte(Tag.FunctionTypeAlias);
+
+ _writeInformativeUint30(node.offset);
+ _writeInformativeUint30(node.length);
+ _writeDocumentationCommentString(node.documentationComment);
+
+ var resolutionIndex = _resolutionUnit.enterDeclaration();
+
+ _pushScopeTypeParameters(node.typeParameters);
+
+ _writeOptionalNode(node.typeParameters);
+ _writeOptionalNode(node.returnType);
+ _writeNode(node.parameters);
+
+ _storeTypeAlias(node);
+
+ var element = node.declaredElement as FunctionTypeAliasElementImpl;
+ _writeActualReturnType(element.function.returnType);
+ // TODO(scheglov) pack into one byte
+ _resolutionSink.writeByte(element.isSimplyBounded ? 1 : 0);
+ _resolutionSink.writeByte(element.hasSelfReference ? 1 : 0);
+
+ _resolutionSink.localElements.popScope();
+
+ _writeUInt30(resolutionIndex);
}
@override
- LinkedNodeBuilder visitImportDirective(ImportDirective node) {
- timerAstBinaryWriterDirective.start();
- try {
- var builder = LinkedNodeBuilder.importDirective(
- importDirective_prefix: node.prefix?.name,
- );
- builder.flags = AstBinaryFlags.encode(
+ void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+ _writeByte(Tag.FunctionTypedFormalParameter);
+
+ _pushScopeTypeParameters(node.typeParameters);
+ _writeOptionalNode(node.typeParameters);
+ _writeOptionalNode(node.returnType);
+ _writeNode(node.parameters);
+ _storeNormalFormalParameter(node, null);
+ _resolutionSink.localElements.popScope();
+ }
+
+ @override
+ void visitGenericFunctionType(GenericFunctionType node) {
+ _writeByte(Tag.GenericFunctionType);
+
+ _writeByte(
+ AstBinaryFlags.encode(
+ hasQuestion: node.question != null,
+ ),
+ );
+
+ _pushScopeTypeParameters(node.typeParameters);
+
+ _writeOptionalNode(node.typeParameters);
+ _writeOptionalNode(node.returnType);
+ _writeNode(node.parameters);
+ _resolutionSink?.writeType(node.type);
+
+ _resolutionSink.localElements.popScope();
+ }
+
+ @override
+ void visitGenericTypeAlias(GenericTypeAlias node) {
+ unitMemberIndexItems.add(
+ _UnitMemberIndexItem(
+ offset: _sink.offset,
+ tag: Tag.GenericTypeAlias,
+ name: node.name.name,
+ ),
+ );
+
+ _writeByte(Tag.GenericTypeAlias);
+
+ _writeInformativeUint30(node.offset);
+ _writeInformativeUint30(node.length);
+ _writeDocumentationCommentString(node.documentationComment);
+
+ var resolutionIndex = _resolutionUnit.enterDeclaration();
+
+ _pushScopeTypeParameters(node.typeParameters);
+
+ _writeOptionalNode(node.typeParameters);
+ _writeOptionalNode(node.functionType);
+ _storeTypeAlias(node);
+
+ var element = node.declaredElement as FunctionTypeAliasElementImpl;
+ // TODO(scheglov) pack into one byte
+ _resolutionSink.writeByte(element.isSimplyBounded ? 1 : 0);
+ _resolutionSink.writeByte(element.hasSelfReference ? 1 : 0);
+
+ _resolutionSink.localElements.popScope();
+
+ _writeUInt30(resolutionIndex);
+ }
+
+ @override
+ void visitHideCombinator(HideCombinator node) {
+ _writeByte(Tag.HideCombinator);
+ _writeInformativeUint30(node.keyword.offset);
+ _writeNodeList(node.hiddenNames);
+ }
+
+ @override
+ void visitIfElement(IfElement node) {
+ _writeByte(Tag.IfElement);
+ _writeNode(node.condition);
+ _writeNode(node.thenElement);
+ _writeOptionalNode(node.elseElement);
+ }
+
+ @override
+ void visitImplementsClause(ImplementsClause node) {
+ _writeByte(Tag.ImplementsClause);
+ _writeNodeList(node.interfaces);
+ }
+
+ @override
+ void visitImportDirective(ImportDirective node) {
+ var resolutionIndex = _resolutionUnit.enterDeclaration();
+
+ _writeByte(Tag.ImportDirective);
+
+ var prefix = node.prefix;
+ _writeByte(
+ AstBinaryFlags.encode(
+ hasPrefix: prefix != null,
isDeferred: node.deferredKeyword != null,
- );
- _storeNamespaceDirective(builder, node);
- return builder;
- } finally {
- timerAstBinaryWriterDirective.stop();
- }
- }
-
- @override
- LinkedNodeBuilder visitIndexExpression(IndexExpression node) {
- var elementComponents = _componentsOfElement(node.staticElement);
- var builder = LinkedNodeBuilder.indexExpression(
- indexExpression_element: elementComponents.rawElement,
- indexExpression_substitution: elementComponents.substitution,
- indexExpression_index: node.index.accept(this),
- indexExpression_target: node.target?.accept(this),
- expression_type: _writeType(node.staticType),
- );
- builder.flags = AstBinaryFlags.encode(
- hasPeriod: node.period != null,
- hasQuestion: node.question != null,
- );
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitInstanceCreationExpression(
- InstanceCreationExpression node) {
- InstanceCreationExpressionImpl nodeImpl = node;
- var builder = LinkedNodeBuilder.instanceCreationExpression(
- instanceCreationExpression_arguments: _writeNodeList(
- node.argumentList.arguments,
),
- instanceCreationExpression_constructorName:
- node.constructorName.accept(this),
- instanceCreationExpression_typeArguments:
- nodeImpl.typeArguments?.accept(this),
- expression_type: _writeType(node.staticType),
);
- builder.flags = AstBinaryFlags.encode(
- isConst: node.keyword?.type == Keyword.CONST,
- isNew: node.keyword?.type == Keyword.NEW,
- );
- return builder;
+
+ if (prefix != null) {
+ _writeStringReference(prefix.name);
+ _writeInformativeUint30(prefix.offset);
+ }
+
+ _storeNamespaceDirective(node);
+ _writeUInt30(resolutionIndex);
+
+ var element = node.element as ImportElementImpl;
+ _resolutionSink?.writeElement(element.importedLibrary);
}
@override
- LinkedNodeBuilder visitIntegerLiteral(IntegerLiteral node) {
- return LinkedNodeBuilder.integerLiteral(
- expression_type: _writeType(node.staticType),
- integerLiteral_value: node.value,
+ void visitIndexExpression(IndexExpression node) {
+ _writeByte(Tag.IndexExpression);
+ _writeByte(
+ AstBinaryFlags.encode(
+ hasPeriod: node.period != null,
+ hasQuestion: node.question != null,
+ ),
);
+ _writeOptionalNode(node.target);
+ _writeNode(node.index);
+ _resolutionSink.writeElement(node.staticElement);
+ _storeExpression(node);
}
@override
- LinkedNodeBuilder visitInterpolationExpression(InterpolationExpression node) {
- return LinkedNodeBuilder.interpolationExpression(
- interpolationExpression_expression: node.expression.accept(this),
- )..flags = AstBinaryFlags.encode(
+ void visitInstanceCreationExpression(InstanceCreationExpression node) {
+ _writeByte(Tag.InstanceCreationExpression);
+
+ _writeByte(
+ AstBinaryFlags.encode(
+ isConst: node.keyword?.type == Keyword.CONST,
+ isNew: node.keyword?.type == Keyword.NEW,
+ ),
+ );
+
+ _writeNode(node.constructorName);
+ _writeNode(node.argumentList);
+ _storeExpression(node);
+ }
+
+ @override
+ void visitIntegerLiteral(IntegerLiteral node) {
+ var value = node.value;
+
+ if (value == null) {
+ _writeByte(Tag.IntegerLiteralNull);
+ _writeStringReference(node.literal.lexeme);
+ } else {
+ var isPositive = value >= 0;
+ if (!isPositive) {
+ value = -value;
+ }
+
+ if (value & 0xFF == value) {
+ _writeByte(
+ isPositive
+ ? Tag.IntegerLiteralPositive1
+ : Tag.IntegerLiteralNegative1,
+ );
+ _writeByte(value);
+ } else {
+ _writeByte(
+ isPositive ? Tag.IntegerLiteralPositive : Tag.IntegerLiteralNegative,
+ );
+ _writeUInt32(value >> 32);
+ _writeUInt32(value & 0xFFFFFFFF);
+ }
+ }
+
+ // TODO(scheglov) Dont write type, AKA separate true `int` and `double`?
+ _resolutionSink?.writeType(node.staticType);
+ }
+
+ @override
+ void visitInterpolationExpression(InterpolationExpression node) {
+ _writeByte(Tag.InterpolationExpression);
+ _writeByte(
+ AstBinaryFlags.encode(
isStringInterpolationIdentifier:
node.leftBracket.type == TokenType.STRING_INTERPOLATION_IDENTIFIER,
- );
- }
-
- @override
- LinkedNodeBuilder visitInterpolationString(InterpolationString node) {
- return LinkedNodeBuilder.interpolationString(
- interpolationString_value: node.value,
- );
- }
-
- @override
- LinkedNodeBuilder visitIsExpression(IsExpression node) {
- var builder = LinkedNodeBuilder.isExpression(
- isExpression_expression: node.expression.accept(this),
- isExpression_type: node.type.accept(this),
- );
- builder.flags = AstBinaryFlags.encode(
- hasNot: node.notOperator != null,
- );
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitLabel(Label node) {
- return LinkedNodeBuilder.label(
- label_label: node.label.accept(this),
- );
- }
-
- @override
- LinkedNodeBuilder visitLabeledStatement(LabeledStatement node) {
- return LinkedNodeBuilder.labeledStatement(
- labeledStatement_labels: _writeNodeList(node.labels),
- labeledStatement_statement: node.statement.accept(this),
- );
- }
-
- @override
- LinkedNodeBuilder visitLibraryDirective(LibraryDirective node) {
- timerAstBinaryWriterDirective.start();
- try {
- var builder = LinkedNodeBuilder.libraryDirective(
- informativeId: getInformativeId(node),
- libraryDirective_name: node.name.accept(this),
- );
- _storeDirective(builder, node);
- return builder;
- } finally {
- timerAstBinaryWriterDirective.stop();
- }
- }
-
- @override
- LinkedNodeBuilder visitLibraryIdentifier(LibraryIdentifier node) {
- return LinkedNodeBuilder.libraryIdentifier(
- libraryIdentifier_components: _writeNodeList(node.components),
- );
- }
-
- @override
- LinkedNodeBuilder visitListLiteral(ListLiteral node) {
- var builder = LinkedNodeBuilder.listLiteral(
- listLiteral_elements: _writeNodeList(node.elements),
- );
- _storeTypedLiteral(builder, node);
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitMapLiteralEntry(MapLiteralEntry node) {
- return LinkedNodeBuilder.mapLiteralEntry(
- mapLiteralEntry_key: node.key.accept(this),
- mapLiteralEntry_value: node.value.accept(this),
- );
- }
-
- @override
- LinkedNodeBuilder visitMethodDeclaration(MethodDeclaration node) {
- var builder = LinkedNodeBuilder.methodDeclaration(
- methodDeclaration_returnType: node.returnType?.accept(this),
- methodDeclaration_typeParameters: node.typeParameters?.accept(this),
- methodDeclaration_formalParameters: node.parameters?.accept(this),
- methodDeclaration_hasOperatorEqualWithParameterTypeFromObject:
- LazyAst.hasOperatorEqualParameterTypeFromObject(node),
- );
- builder.name = node.name.name;
- builder.flags = AstBinaryFlags.encode(
- isAbstract: node.body is EmptyFunctionBody,
- isAsync: node.body?.isAsynchronous ?? false,
- isExternal: node.externalKeyword != null,
- isGenerator: node.body?.isGenerator ?? false,
- isGet: node.isGetter,
- isNative: node.body is NativeFunctionBody,
- isOperator: node.operatorKeyword != null,
- isSet: node.isSetter,
- isStatic: node.isStatic,
- );
- builder.topLevelTypeInferenceError = LazyAst.getTypeInferenceError(node);
- _storeClassMember(builder, node);
- _storeInformativeId(builder, node);
- _writeActualReturnType(builder, node);
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitMethodInvocation(MethodInvocation node) {
- var builder = LinkedNodeBuilder.methodInvocation(
- methodInvocation_methodName: node.methodName?.accept(this),
- methodInvocation_target: node.target?.accept(this),
- );
- builder.flags = AstBinaryFlags.encode(
- hasPeriod: node.operator?.type == TokenType.PERIOD,
- hasPeriod2: node.operator?.type == TokenType.PERIOD_PERIOD,
- );
- _storeInvocationExpression(builder, node);
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitMixinDeclaration(MixinDeclaration node) {
- timerAstBinaryWriterMixin.start();
- try {
- var builder = LinkedNodeBuilder.mixinDeclaration(
- mixinDeclaration_onClause: node.onClause?.accept(this),
- );
- _storeClassOrMixinDeclaration(builder, node);
- LazyMixinDeclaration.get(node).put(builder);
- return builder;
- } finally {
- timerAstBinaryWriterMixin.stop();
- }
- }
-
- @override
- LinkedNodeBuilder visitNamedExpression(NamedExpression node) {
- return LinkedNodeBuilder.namedExpression(
- namedExpression_expression: node.expression.accept(this),
- namedExpression_name: node.name.accept(this),
- );
- }
-
- @override
- LinkedNodeBuilder visitNativeClause(NativeClause node) {
- return LinkedNodeBuilder.nativeClause(
- nativeClause_name: node.name.accept(this),
- );
- }
-
- @override
- LinkedNodeBuilder visitNativeFunctionBody(NativeFunctionBody node) {
- return LinkedNodeBuilder.nativeFunctionBody(
- nativeFunctionBody_stringLiteral: node.stringLiteral?.accept(this),
- );
- }
-
- @override
- LinkedNodeBuilder visitNullLiteral(NullLiteral node) {
- return LinkedNodeBuilder.nullLiteral();
- }
-
- @override
- LinkedNodeBuilder visitOnClause(OnClause node) {
- return LinkedNodeBuilder.onClause(
- onClause_superclassConstraints:
- _writeNodeList(node.superclassConstraints),
- );
- }
-
- @override
- LinkedNodeBuilder visitParenthesizedExpression(ParenthesizedExpression node) {
- var builder = LinkedNodeBuilder.parenthesizedExpression(
- parenthesizedExpression_expression: node.expression.accept(this),
- );
- _storeExpression(builder, node);
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitPartDirective(PartDirective node) {
- timerAstBinaryWriterDirective.start();
- try {
- var builder = LinkedNodeBuilder.partDirective();
- _storeUriBasedDirective(builder, node);
- return builder;
- } finally {
- timerAstBinaryWriterDirective.stop();
- }
- }
-
- @override
- LinkedNodeBuilder visitPartOfDirective(PartOfDirective node) {
- timerAstBinaryWriterDirective.start();
- try {
- var builder = LinkedNodeBuilder.partOfDirective(
- partOfDirective_libraryName: node.libraryName?.accept(this),
- partOfDirective_uri: node.uri?.accept(this),
- );
- _storeDirective(builder, node);
- return builder;
- } finally {
- timerAstBinaryWriterDirective.stop();
- }
- }
-
- @override
- LinkedNodeBuilder visitPostfixExpression(PostfixExpression node) {
- var elementComponents = _componentsOfElement(node.staticElement);
- return LinkedNodeBuilder.postfixExpression(
- expression_type: _writeType(node.staticType),
- postfixExpression_element: elementComponents.rawElement,
- postfixExpression_substitution: elementComponents.substitution,
- postfixExpression_operand: node.operand.accept(this),
- postfixExpression_operator: TokensWriter.astToBinaryTokenType(
- node.operator.type,
),
);
+ _writeNode(node.expression);
}
@override
- LinkedNodeBuilder visitPrefixedIdentifier(PrefixedIdentifier node) {
- return LinkedNodeBuilder.prefixedIdentifier(
- prefixedIdentifier_identifier: node.identifier.accept(this),
- prefixedIdentifier_prefix: node.prefix.accept(this),
- expression_type: _writeType(node.staticType),
- );
+ void visitInterpolationString(InterpolationString node) {
+ _writeByte(Tag.InterpolationString);
+ _writeStringReference(node.value);
}
@override
- LinkedNodeBuilder visitPrefixExpression(PrefixExpression node) {
- var elementComponents = _componentsOfElement(node.staticElement);
- return LinkedNodeBuilder.prefixExpression(
- expression_type: _writeType(node.staticType),
- prefixExpression_element: elementComponents.rawElement,
- prefixExpression_substitution: elementComponents.substitution,
- prefixExpression_operand: node.operand.accept(this),
- prefixExpression_operator: TokensWriter.astToBinaryTokenType(
- node.operator.type,
+ void visitIsExpression(IsExpression node) {
+ _writeByte(Tag.IsExpression);
+ _writeByte(
+ AstBinaryFlags.encode(
+ hasNot: node.notOperator != null,
),
);
+ _writeNode(node.expression);
+ _writeNode(node.type);
+ _storeExpression(node);
}
@override
- LinkedNodeBuilder visitPropertyAccess(PropertyAccess node) {
- var builder = LinkedNodeBuilder.propertyAccess(
- propertyAccess_operator: TokensWriter.astToBinaryTokenType(
- node.operator.type,
+ void visitLibraryDirective(LibraryDirective node) {
+ _writeByte(Tag.LibraryDirective);
+ _writeDocumentationCommentString(node.documentationComment);
+ visitLibraryIdentifier(node.name);
+ _storeDirective(node);
+ }
+
+ @override
+ void visitLibraryIdentifier(LibraryIdentifier node) {
+ _writeByte(Tag.LibraryIdentifier);
+ _writeNodeList(node.components);
+ }
+
+ @override
+ void visitListLiteral(ListLiteral node) {
+ _writeByte(Tag.ListLiteral);
+
+ _writeByte(
+ AstBinaryFlags.encode(
+ isConst: node.constKeyword != null,
),
- propertyAccess_propertyName: node.propertyName.accept(this),
- propertyAccess_target: node.target?.accept(this),
);
- _storeExpression(builder, node);
- return builder;
+
+ _writeOptionalNode(node.typeArguments);
+ _writeNodeList(node.elements);
+
+ _storeExpression(node);
}
@override
- LinkedNodeBuilder visitRedirectingConstructorInvocation(
- RedirectingConstructorInvocation node) {
- var elementComponents = _componentsOfElement(node.staticElement);
- var builder = LinkedNodeBuilder.redirectingConstructorInvocation(
- redirectingConstructorInvocation_arguments:
- node.argumentList.accept(this),
- redirectingConstructorInvocation_constructorName:
- node.constructorName?.accept(this),
- redirectingConstructorInvocation_element: elementComponents.rawElement,
- redirectingConstructorInvocation_substitution:
- elementComponents.substitution,
- );
- builder.flags = AstBinaryFlags.encode(
- hasThis: node.thisKeyword != null,
- );
- _storeConstructorInitializer(builder, node);
- return builder;
+ void visitMapLiteralEntry(MapLiteralEntry node) {
+ _writeByte(Tag.MapLiteralEntry);
+ _writeNode(node.key);
+ _writeNode(node.value);
}
@override
- LinkedNodeBuilder visitRethrowExpression(RethrowExpression node) {
- return LinkedNodeBuilder.rethrowExpression(
- expression_type: _writeType(node.staticType),
- );
- }
-
- @override
- LinkedNodeBuilder visitReturnStatement(ReturnStatement node) {
- return LinkedNodeBuilder.returnStatement(
- returnStatement_expression: node.expression?.accept(this),
- );
- }
-
- @override
- LinkedNodeBuilder visitScriptTag(ScriptTag node) {
- return null;
- }
-
- @override
- LinkedNodeBuilder visitSetOrMapLiteral(SetOrMapLiteral node) {
- var builder = LinkedNodeBuilder.setOrMapLiteral(
- setOrMapLiteral_elements: _writeNodeList(node.elements),
- );
- _storeTypedLiteral(builder, node, isMap: node.isMap, isSet: node.isSet);
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitShowCombinator(ShowCombinator node) {
- var builder = LinkedNodeBuilder.showCombinator(
- names: node.shownNames.map((id) => id.name).toList(),
- );
- _storeInformativeId(builder, node);
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitSimpleFormalParameter(SimpleFormalParameter node) {
- var builder = LinkedNodeBuilder.simpleFormalParameter(
- simpleFormalParameter_type: node.type?.accept(this),
- );
- builder.topLevelTypeInferenceError = LazyAst.getTypeInferenceError(node);
- _storeNormalFormalParameter(builder, node, node.keyword);
- _storeInheritsCovariant(builder, node);
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitSimpleIdentifier(SimpleIdentifier node) {
- Element element;
- if (!node.inDeclarationContext()) {
- element = node.staticElement;
- if (element is MultiplyDefinedElement) {
- element = null;
- }
+ void visitMethodDeclaration(MethodDeclaration node) {
+ var indexTag = Tag.MethodDeclaration;
+ if (node.isGetter) {
+ indexTag = Tag.MethodDeclaration_getter;
+ } else if (node.isSetter) {
+ indexTag = Tag.MethodDeclaration_setter;
}
-
- var elementComponents = _componentsOfElement(element);
- var builder = LinkedNodeBuilder.simpleIdentifier(
- simpleIdentifier_element: elementComponents.rawElement,
- simpleIdentifier_substitution: elementComponents.substitution,
- expression_type: _writeType(node.staticType),
- );
- builder.flags = AstBinaryFlags.encode(
- isDeclaration: node is DeclaredSimpleIdentifier,
- );
- builder.name = node.name;
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitSimpleStringLiteral(SimpleStringLiteral node) {
- var builder = LinkedNodeBuilder.simpleStringLiteral(
- simpleStringLiteral_value: node.value,
- );
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitSpreadElement(SpreadElement node) {
- return LinkedNodeBuilder.spreadElement(
- spreadElement_expression: node.expression.accept(this),
- spreadElement_spreadOperator: TokensWriter.astToBinaryTokenType(
- node.spreadOperator.type,
+ _classMemberIndexItems.add(
+ _ClassMemberIndexItem(
+ offset: _sink.offset,
+ tag: indexTag,
+ name: node.name.name,
),
);
- }
- @override
- LinkedNodeBuilder visitStringInterpolation(StringInterpolation node) {
- return LinkedNodeBuilder.stringInterpolation(
- stringInterpolation_elements: _writeNodeList(node.elements),
- );
- }
+ _writeByte(Tag.MethodDeclaration);
- @override
- LinkedNodeBuilder visitSuperConstructorInvocation(
- SuperConstructorInvocation node) {
- var elementComponents = _componentsOfElement(node.staticElement);
- var builder = LinkedNodeBuilder.superConstructorInvocation(
- superConstructorInvocation_arguments: node.argumentList.accept(this),
- superConstructorInvocation_constructorName:
- node.constructorName?.accept(this),
- superConstructorInvocation_element: elementComponents.rawElement,
- superConstructorInvocation_substitution: elementComponents.substitution,
- );
- _storeConstructorInitializer(builder, node);
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitSuperExpression(SuperExpression node) {
- var builder = LinkedNodeBuilder.superExpression();
- _storeExpression(builder, node);
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitSwitchCase(SwitchCase node) {
- var builder = LinkedNodeBuilder.switchCase(
- switchCase_expression: node.expression.accept(this),
- );
- _storeSwitchMember(builder, node);
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitSwitchDefault(SwitchDefault node) {
- var builder = LinkedNodeBuilder.switchDefault();
- _storeSwitchMember(builder, node);
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitSwitchStatement(SwitchStatement node) {
- return LinkedNodeBuilder.switchStatement(
- switchStatement_expression: node.expression.accept(this),
- switchStatement_members: _writeNodeList(node.members),
- );
- }
-
- @override
- LinkedNodeBuilder visitSymbolLiteral(SymbolLiteral node) {
- var builder = LinkedNodeBuilder.symbolLiteral(
- names: node.components.map((t) => t.lexeme).toList(),
- );
- _storeExpression(builder, node);
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitThisExpression(ThisExpression node) {
- var builder = LinkedNodeBuilder.thisExpression();
- _storeExpression(builder, node);
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitThrowExpression(ThrowExpression node) {
- return LinkedNodeBuilder.throwExpression(
- throwExpression_expression: node.expression.accept(this),
- expression_type: _writeType(node.staticType),
- );
- }
-
- @override
- LinkedNodeBuilder visitTopLevelVariableDeclaration(
- TopLevelVariableDeclaration node) {
- timerAstBinaryWriterTopVar.start();
- try {
- var builder = LinkedNodeBuilder.topLevelVariableDeclaration(
- informativeId: getInformativeId(node),
- topLevelVariableDeclaration_variableList: node.variables?.accept(this),
- );
- builder.flags = AstBinaryFlags.encode(
+ _writeUInt30(
+ AstBinaryFlags.encode(
+ isAbstract: node.body is EmptyFunctionBody,
+ isAsync: node.body?.isAsynchronous ?? false,
isExternal: node.externalKeyword != null,
- );
- _storeCompilationUnitMember(builder, node);
-
- return builder;
- } finally {
- timerAstBinaryWriterTopVar.stop();
- }
- }
-
- @override
- LinkedNodeBuilder visitTryStatement(TryStatement node) {
- return LinkedNodeBuilder.tryStatement(
- tryStatement_body: node.body.accept(this),
- tryStatement_catchClauses: _writeNodeList(node.catchClauses),
- tryStatement_finallyBlock: node.finallyBlock?.accept(this),
- );
- }
-
- @override
- LinkedNodeBuilder visitTypeArgumentList(TypeArgumentList node) {
- return LinkedNodeBuilder.typeArgumentList(
- typeArgumentList_arguments: _writeNodeList(node.arguments),
- );
- }
-
- @override
- LinkedNodeBuilder visitTypeName(TypeName node) {
- return LinkedNodeBuilder.typeName(
- typeName_name: node.name.accept(this),
- typeName_type: _writeType(node.type),
- typeName_typeArguments: _writeNodeList(
- node.typeArguments?.arguments,
+ isGenerator: node.body?.isGenerator ?? false,
+ isGet: node.isGetter,
+ isNative: node.body is NativeFunctionBody,
+ isOperator: node.operatorKeyword != null,
+ isSet: node.isSetter,
+ isStatic: node.isStatic,
),
- )..flags = AstBinaryFlags.encode(
+ );
+
+ _writeInformativeUint30(node.offset);
+ _writeInformativeUint30(node.length);
+ _writeDocumentationCommentString(node.documentationComment);
+
+ var resolutionIndex = _resolutionUnit.enterDeclaration();
+
+ _pushScopeTypeParameters(node.typeParameters);
+
+ _writeDeclarationName(node.name);
+ _writeOptionalNode(node.typeParameters);
+ _writeOptionalNode(node.returnType);
+ _writeOptionalNode(node.parameters);
+
+ _storeClassMember(node);
+
+ _writeUInt30(resolutionIndex);
+
+ var element = node.declaredElement as ExecutableElementImpl;
+ _writeActualReturnType(element.returnType);
+ _writeTopLevelInferenceError(element);
+ // TODO(scheglov) move this flag into ClassElementImpl?
+ if (element is MethodElementImpl) {
+ _resolutionSink.writeByte(
+ element.isOperatorEqualWithParameterTypeFromObject ? 1 : 0,
+ );
+ }
+
+ _resolutionSink.localElements.popScope();
+ }
+
+ @override
+ void visitMethodInvocation(MethodInvocation node) {
+ _writeByte(Tag.MethodInvocation);
+ _writeByte(
+ AstBinaryFlags.encode(
+ hasPeriod: node.operator?.type == TokenType.PERIOD,
+ hasPeriod2: node.operator?.type == TokenType.PERIOD_PERIOD,
+ ),
+ );
+ _writeOptionalNode(node.target);
+ _writeNode(node.methodName);
+ _storeInvocationExpression(node);
+ }
+
+ @override
+ void visitMixinDeclaration(MixinDeclaration node) {
+ var classOffset = _sink.offset;
+ var resolutionIndex = _resolutionUnit.enterDeclaration();
+
+ _writeByte(Tag.MixinDeclaration);
+
+ var element = node.declaredElement as MixinElementImpl;
+ _resolutionSink.writeByte(element.isSimplyBounded ? 1 : 0);
+ _resolutionSink.writeStringList(element.superInvokedNames);
+
+ _writeInformativeUint30(node.offset);
+ _writeInformativeUint30(node.length);
+ _writeDocumentationCommentString(node.documentationComment);
+
+ _pushScopeTypeParameters(node.typeParameters);
+
+ _writeOptionalNode(node.typeParameters);
+ _writeOptionalNode(node.onClause);
+ _writeOptionalNode(node.implementsClause);
+ _storeNamedCompilationUnitMember(node);
+ _writeUInt30(resolutionIndex);
+
+ _classMemberIndexItems.clear();
+ _writeNodeList(node.members);
+ _hasConstConstructor = false;
+
+ _resolutionSink.localElements.popScope();
+
+ // TODO(scheglov) write member index
+ var classIndexOffset = _sink.offset;
+ _writeClassMemberIndex();
+
+ unitMemberIndexItems.add(
+ _UnitMemberIndexItem(
+ offset: classOffset,
+ tag: Tag.MixinDeclaration,
+ name: node.name.name,
+ classIndexOffset: classIndexOffset,
+ ),
+ );
+ }
+
+ @override
+ void visitNamedExpression(NamedExpression node) {
+ _writeByte(Tag.NamedExpression);
+
+ var nameNode = node.name.label;
+ _writeStringReference(nameNode.name);
+ _writeInformativeUint30(nameNode.offset);
+
+ _writeNode(node.expression);
+ }
+
+ @override
+ void visitNativeClause(NativeClause node) {
+ _writeByte(Tag.NativeClause);
+ _writeNode(node.name);
+ }
+
+ @override
+ void visitNullLiteral(NullLiteral node) {
+ _writeByte(Tag.NullLiteral);
+ }
+
+ @override
+ void visitOnClause(OnClause node) {
+ _writeByte(Tag.OnClause);
+ _writeNodeList(node.superclassConstraints);
+ }
+
+ @override
+ void visitParenthesizedExpression(ParenthesizedExpression node) {
+ _writeByte(Tag.ParenthesizedExpression);
+ _writeNode(node.expression);
+ _storeExpression(node);
+ }
+
+ @override
+ void visitPartDirective(PartDirective node) {
+ _writeByte(Tag.PartDirective);
+ _storeUriBasedDirective(node);
+ }
+
+ @override
+ void visitPartOfDirective(PartOfDirective node) {
+ _writeByte(Tag.PartOfDirective);
+ _writeOptionalNode(node.libraryName);
+ _writeOptionalNode(node.uri);
+ _storeDirective(node);
+ }
+
+ @override
+ void visitPostfixExpression(PostfixExpression node) {
+ _writeByte(Tag.PostfixExpression);
+
+ _writeNode(node.operand);
+
+ var operatorToken = node.operator.type;
+ var binaryToken = TokensWriter.astToBinaryTokenType(operatorToken);
+ _writeByte(binaryToken.index);
+
+ _resolutionSink.writeElement(node.staticElement);
+ if (operatorToken.isIncrementOperator) {
+ _resolutionSink.writeElement(node.readElement);
+ _resolutionSink.writeType(node.readType);
+ _resolutionSink.writeElement(node.writeElement);
+ _resolutionSink.writeType(node.writeType);
+ }
+ _storeExpression(node);
+ }
+
+ @override
+ void visitPrefixedIdentifier(PrefixedIdentifier node) {
+ _writeByte(Tag.PrefixedIdentifier);
+ _writeNode(node.prefix);
+ _writeNode(node.identifier);
+
+ // TODO(scheglov) In actual prefixed identifier, the type of the identifier.
+ _resolutionSink?.writeType(node.staticType);
+ }
+
+ @override
+ void visitPrefixExpression(PrefixExpression node) {
+ _writeByte(Tag.PrefixExpression);
+
+ var operatorToken = node.operator.type;
+ var binaryToken = TokensWriter.astToBinaryTokenType(operatorToken);
+ _writeByte(binaryToken.index);
+
+ _writeNode(node.operand);
+
+ _resolutionSink?.writeElement(node.staticElement);
+ if (operatorToken.isIncrementOperator) {
+ _resolutionSink.writeElement(node.readElement);
+ _resolutionSink.writeType(node.readType);
+ _resolutionSink.writeElement(node.writeElement);
+ _resolutionSink.writeType(node.writeType);
+ }
+ _storeExpression(node);
+ }
+
+ @override
+ void visitPropertyAccess(PropertyAccess node) {
+ _writeByte(Tag.PropertyAccess);
+ _writeByte(
+ AstBinaryFlags.encode(
+ hasPeriod: node.operator?.type == TokenType.PERIOD,
+ hasPeriod2: node.operator?.type == TokenType.PERIOD_PERIOD,
+ ),
+ );
+ _writeOptionalNode(node.target);
+ _writeNode(node.propertyName);
+ // TODO(scheglov) Get from the property?
+ _storeExpression(node);
+ }
+
+ @override
+ void visitRedirectingConstructorInvocation(
+ RedirectingConstructorInvocation node) {
+ _writeByte(Tag.RedirectingConstructorInvocation);
+
+ _writeByte(
+ AstBinaryFlags.encode(
+ hasThis: node.thisKeyword != null,
+ ),
+ );
+
+ _writeOptionalNode(node.constructorName);
+ _writeNode(node.argumentList);
+ _resolutionSink?.writeElement(node.staticElement);
+ _storeConstructorInitializer(node);
+ }
+
+ @override
+ void visitSetOrMapLiteral(SetOrMapLiteral node) {
+ _writeByte(Tag.SetOrMapLiteral);
+
+ // TODO(scheglov) isMap/isSet is resolution data
+ _writeByte(
+ AstBinaryFlags.encode(
+ isConst: node.constKeyword != null,
+ isMap: node.isMap,
+ isSet: node.isSet,
+ ),
+ );
+
+ _writeOptionalNode(node.typeArguments);
+ _writeNodeList(node.elements);
+
+ _storeExpression(node);
+ }
+
+ @override
+ void visitShowCombinator(ShowCombinator node) {
+ _writeByte(Tag.ShowCombinator);
+ _writeInformativeUint30(node.keyword.offset);
+ _writeNodeList(node.shownNames);
+ }
+
+ @override
+ void visitSimpleFormalParameter(SimpleFormalParameter node) {
+ _writeByte(Tag.SimpleFormalParameter);
+
+ _writeOptionalNode(node.type);
+ _storeNormalFormalParameter(node, node.keyword);
+
+ var element = node.declaredElement as ParameterElementImpl;
+ _resolutionSink.writeByte(element.inheritsCovariant ? 1 : 0);
+ }
+
+ @override
+ void visitSimpleIdentifier(SimpleIdentifier node) {
+ _writeByte(Tag.SimpleIdentifier);
+ _writeStringReference(node.name);
+ _writeInformativeUint30(node.offset);
+ _resolutionSink?.writeElement(node.staticElement);
+ // TODO(scheglov) It is inefficient to write many null types.
+ _resolutionSink?.writeType(node.staticType);
+ }
+
+ @override
+ void visitSimpleStringLiteral(SimpleStringLiteral node) {
+ _writeByte(Tag.SimpleStringLiteral);
+ _writeStringReference(node.literal.lexeme);
+ _writeStringReference(node.value);
+ }
+
+ @override
+ void visitSpreadElement(SpreadElement node) {
+ _writeByte(Tag.SpreadElement);
+ _writeByte(
+ AstBinaryFlags.encode(
+ hasQuestion:
+ node.spreadOperator.type == TokenType.PERIOD_PERIOD_PERIOD_QUESTION,
+ ),
+ );
+ _writeNode(node.expression);
+ }
+
+ @override
+ void visitStringInterpolation(StringInterpolation node) {
+ _writeByte(Tag.StringInterpolation);
+ _writeNodeList(node.elements);
+ }
+
+ @override
+ void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+ _writeByte(Tag.SuperConstructorInvocation);
+
+ _writeOptionalNode(node.constructorName);
+ _writeNode(node.argumentList);
+ _resolutionSink?.writeElement(node.staticElement);
+ _storeConstructorInitializer(node);
+ }
+
+ @override
+ void visitSuperExpression(SuperExpression node) {
+ _writeByte(Tag.SuperExpression);
+ _storeExpression(node);
+ }
+
+ @override
+ void visitSymbolLiteral(SymbolLiteral node) {
+ _writeByte(Tag.SymbolLiteral);
+
+ var components = node.components;
+ _writeUInt30(components.length);
+ for (var token in components) {
+ _writeStringReference(token.lexeme);
+ }
+ _storeExpression(node);
+ }
+
+ @override
+ void visitThisExpression(ThisExpression node) {
+ _writeByte(Tag.ThisExpression);
+ _storeExpression(node);
+ }
+
+ @override
+ void visitThrowExpression(ThrowExpression node) {
+ _writeByte(Tag.ThrowExpression);
+ _writeNode(node.expression);
+ _storeExpression(node);
+ }
+
+ @override
+ void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+ unitMemberIndexItems.add(
+ _UnitMemberIndexItem(
+ offset: _sink.offset,
+ tag: Tag.TopLevelVariableDeclaration,
+ variableNames: node.variables.variables
+ .map((variable) => variable.name.name)
+ .toList(),
+ ),
+ );
+
+ _writeByte(Tag.TopLevelVariableDeclaration);
+ _writeByte(
+ AstBinaryFlags.encode(
+ isExternal: node.externalKeyword != null,
+ ),
+ );
+
+ _writeInformativeVariableCodeRanges(node.offset, node.variables);
+ _writeDocumentationCommentString(node.documentationComment);
+
+ var resolutionIndex = _resolutionUnit.enterDeclaration();
+
+ _isConstTopLevelVariable = node.variables.isConst;
+ try {
+ _writeNode(node.variables);
+ } finally {
+ _isConstTopLevelVariable = false;
+ }
+
+ _storeCompilationUnitMember(node);
+
+ _writeUInt30(resolutionIndex);
+ }
+
+ @override
+ void visitTypeArgumentList(TypeArgumentList node) {
+ _writeByte(Tag.TypeArgumentList);
+ _writeNodeList(node.arguments);
+ }
+
+ @override
+ void visitTypeName(TypeName node) {
+ _writeByte(Tag.TypeName);
+
+ _writeByte(
+ AstBinaryFlags.encode(
hasQuestion: node.question != null,
hasTypeArguments: node.typeArguments != null,
- );
- }
-
- @override
- LinkedNodeBuilder visitTypeParameter(TypeParameter node) {
- var builder = LinkedNodeBuilder.typeParameter(
- typeParameter_bound: node.bound?.accept(this),
- typeParameter_defaultType: _writeType(LazyAst.getDefaultType(node)),
- typeParameter_variance: _encodeVariance(LazyAst.getVariance(node)),
- informativeId: getInformativeId(node),
+ ),
);
- builder.name = node.name.name;
- _storeDeclaration(builder, node);
- return builder;
+
+ _writeNode(node.name);
+ _writeOptionalNode(node.typeArguments);
+
+ _resolutionSink.writeType(node.type);
}
@override
- LinkedNodeBuilder visitTypeParameterList(TypeParameterList node) {
- return LinkedNodeBuilder.typeParameterList(
- typeParameterList_typeParameters: _writeNodeList(node.typeParameters),
+ void visitTypeParameter(TypeParameter node) {
+ _writeByte(Tag.TypeParameter);
+ _writeInformativeUint30(node.offset);
+ _writeInformativeUint30(node.length);
+ _writeDeclarationName(node.name);
+ _writeOptionalNode(node.bound);
+ _storeDeclaration(node);
+
+ var element = node.declaredElement as TypeParameterElementImpl;
+ _resolutionSink.writeByte(
+ _encodeVariance(element),
);
+ _resolutionSink.writeType(element.defaultType);
}
@override
- LinkedNodeBuilder visitVariableDeclaration(VariableDeclaration node) {
- var initializer = node.initializer;
- var declarationList = node.parent as VariableDeclarationList;
- var declaration = declarationList.parent;
- if (declaration is TopLevelVariableDeclaration) {
- if (!declarationList.isConst) {
- initializer = null;
- }
- } else if (declaration is FieldDeclaration) {
- if (!(declarationList.isConst ||
- !declaration.isStatic &&
- declarationList.isFinal &&
- _hasConstConstructor)) {
- initializer = null;
+ void visitTypeParameterList(TypeParameterList node) {
+ _writeByte(Tag.TypeParameterList);
+ _writeNodeList(node.typeParameters);
+ }
+
+ @override
+ void visitVariableDeclaration(VariableDeclaration node) {
+ _writeByte(Tag.VariableDeclaration);
+ _writeByte(
+ AstBinaryFlags.encode(
+ hasInitializer: node.initializer != null,
+ ),
+ );
+ _writeDeclarationName(node.name);
+
+ // TODO(scheglov) Enforce not null, remove `?` in `?.type` below.
+ var element = node.declaredElement as VariableElementImpl;
+ _writeActualType(element?.type);
+ _writeTopLevelInferenceError(element);
+ if (element is FieldElementImpl) {
+ _resolutionSink.writeByte(element.inheritsCovariant ? 1 : 0);
+ }
+
+ Expression initializerToWrite;
+ if (_isConstField ||
+ _hasConstConstructor && _isFinalField ||
+ _isConstTopLevelVariable) {
+ var initializer = node.initializer;
+ if (_isSerializableExpression(initializer)) {
+ initializerToWrite = initializer;
}
}
+ _writeOptionalNode(initializerToWrite);
+ }
- if (!_isSerializableExpression(initializer)) {
- initializer = null;
+ @override
+ void visitVariableDeclarationList(VariableDeclarationList node) {
+ _writeByte(Tag.VariableDeclarationList);
+ _writeByte(
+ AstBinaryFlags.encode(
+ isConst: node.isConst,
+ isFinal: node.isFinal,
+ isLate: node.lateKeyword != null,
+ isVar: node.keyword?.keyword == Keyword.VAR,
+ ),
+ );
+ _writeOptionalNode(node.type);
+ _writeNodeList(node.variables);
+ _storeAnnotatedNode(node);
+ }
+
+ @override
+ void visitWithClause(WithClause node) {
+ _writeByte(Tag.WithClause);
+ _writeNodeList(node.mixinTypes);
+ }
+
+ void _pushScopeTypeParameters(TypeParameterList node) {
+ _resolutionSink.localElements.pushScope();
+
+ if (node == null) {
+ return;
}
- var builder = LinkedNodeBuilder.variableDeclaration(
- informativeId: getInformativeId(node),
- variableDeclaration_initializer: initializer?.accept(this),
- );
- builder.flags = AstBinaryFlags.encode(
- hasInitializer: node.initializer != null,
- );
- builder.name = node.name.name;
- builder.topLevelTypeInferenceError = LazyAst.getTypeInferenceError(node);
- _writeActualType(builder, node);
- _storeInheritsCovariant(builder, node);
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitVariableDeclarationList(VariableDeclarationList node) {
- var builder = LinkedNodeBuilder.variableDeclarationList(
- variableDeclarationList_type: node.type?.accept(this),
- variableDeclarationList_variables: _writeNodeList(node.variables),
- );
- builder.flags = AstBinaryFlags.encode(
- isConst: node.isConst,
- isFinal: node.isFinal,
- isLate: node.lateKeyword != null,
- isVar: node.keyword?.keyword == Keyword.VAR,
- );
- _storeAnnotatedNode(builder, node);
- return builder;
- }
-
- @override
- LinkedNodeBuilder visitVariableDeclarationStatement(
- VariableDeclarationStatement node) {
- return LinkedNodeBuilder.variableDeclarationStatement(
- variableDeclarationStatement_variables: node.variables.accept(this),
- );
- }
-
- @override
- LinkedNodeBuilder visitWhileStatement(WhileStatement node) {
- return LinkedNodeBuilder.whileStatement(
- whileStatement_body: node.body.accept(this),
- whileStatement_condition: node.condition.accept(this),
- );
- }
-
- @override
- LinkedNodeBuilder visitWithClause(WithClause node) {
- return LinkedNodeBuilder.withClause(
- withClause_mixinTypes: _writeNodeList(node.mixinTypes),
- );
- }
-
- @override
- LinkedNodeBuilder visitYieldStatement(YieldStatement node) {
- var builder = LinkedNodeBuilder.yieldStatement(
- yieldStatement_expression: node.expression.accept(this),
- );
- builder.flags = AstBinaryFlags.encode(
- isStar: node.star != null,
- );
- _storeStatement(builder, node);
- return builder;
- }
-
- LinkedNodeBuilder writeUnit(CompilationUnit unit) {
- timerAstBinaryWriter.start();
- try {
- return unit.accept(this);
- } finally {
- timerAstBinaryWriter.stop();
+ for (var typeParameter in node.typeParameters) {
+ _resolutionSink.localElements.declare(typeParameter.declaredElement);
}
}
- _ElementComponents _componentsOfElement(Element element) {
- if (element is ParameterMember) {
- element = element.declaration;
- }
-
- if (element is Member) {
- var elementIndex = _indexOfElement(element.declaration);
- var substitution = element.substitution.map;
- var substitutionBuilder = LinkedNodeTypeSubstitutionBuilder(
- isLegacy: element.isLegacy,
- typeParameters: substitution.keys.map(_indexOfElement).toList(),
- typeArguments: substitution.values.map(_writeType).toList(),
- );
- return _ElementComponents(elementIndex, substitutionBuilder);
- }
-
- var elementIndex = _indexOfElement(element);
- return _ElementComponents(elementIndex, null);
+ void _storeAnnotatedNode(AnnotatedNode node) {
+ _writeNodeList(node.metadata);
}
- int _indexOfElement(Element element) {
- return _linkingContext.indexOfElement(element);
+ void _storeClassMember(ClassMember node) {
+ _storeDeclaration(node);
}
- void _storeAnnotatedNode(LinkedNodeBuilder builder, AnnotatedNode node) {
- builder.annotatedNode_metadata = _writeNodeList(node.metadata);
+ void _storeCompilationUnitMember(CompilationUnitMember node) {
+ _storeDeclaration(node);
}
- void _storeClassMember(LinkedNodeBuilder builder, ClassMember node) {
- _storeDeclaration(builder, node);
+ void _storeConstructorInitializer(ConstructorInitializer node) {}
+
+ void _storeDeclaration(Declaration node) {
+ _storeAnnotatedNode(node);
}
- void _storeClassOrMixinDeclaration(
- LinkedNodeBuilder builder, ClassOrMixinDeclaration node) {
- builder
- ..classOrMixinDeclaration_implementsClause =
- node.implementsClause?.accept(this)
- ..classOrMixinDeclaration_members = _writeNodeList(node.members)
- ..classOrMixinDeclaration_typeParameters =
- node.typeParameters?.accept(this);
- _storeNamedCompilationUnitMember(builder, node);
- _storeIsSimpleBounded(builder, node);
+ void _storeDirective(Directive node) {
+ _writeInformativeUint30(node.keyword.offset);
+ _storeAnnotatedNode(node);
}
- void _storeCompilationUnitMember(
- LinkedNodeBuilder builder, CompilationUnitMember node) {
- _storeDeclaration(builder, node);
+ void _storeExpression(Expression node) {
+ _resolutionSink?.writeType(node.staticType);
}
- void _storeConstructorInitializer(
- LinkedNodeBuilder builder, ConstructorInitializer node) {}
-
- void _storeDeclaration(LinkedNodeBuilder builder, Declaration node) {
- _storeAnnotatedNode(builder, node);
+ void _storeForEachParts(ForEachParts node) {
+ _writeNode(node.iterable);
+ _storeForLoopParts(node);
}
- void _storeDirective(LinkedNodeBuilder builder, Directive node) {
- _storeAnnotatedNode(builder, node);
- _storeInformativeId(builder, node);
+ void _storeForLoopParts(ForLoopParts node) {}
+
+ void _storeFormalParameter(FormalParameter node) {
+ _writeActualType(node.declaredElement.type);
}
- void _storeExpression(LinkedNodeBuilder builder, Expression node) {
- builder.expression_type = _writeType(node.staticType);
- }
-
- void _storeForEachParts(LinkedNodeBuilder builder, ForEachParts node) {
- _storeForLoopParts(builder, node);
- builder..forEachParts_iterable = node.iterable?.accept(this);
- }
-
- void _storeForLoopParts(LinkedNodeBuilder builder, ForLoopParts node) {}
-
- void _storeFormalParameter(LinkedNodeBuilder builder, FormalParameter node) {
- _writeActualType(builder, node);
- }
-
- void _storeForMixin(LinkedNodeBuilder builder, ForMixin node) {
- builder.flags = AstBinaryFlags.encode(
- hasAwait: node.awaitKeyword != null,
+ void _storeForMixin(ForMixin node) {
+ _writeByte(
+ AstBinaryFlags.encode(
+ hasAwait: node.awaitKeyword != null,
+ ),
);
- builder..forMixin_forLoopParts = node.forLoopParts.accept(this);
+ _writeNode(node.forLoopParts);
}
- void _storeForParts(LinkedNodeBuilder builder, ForParts node) {
- _storeForLoopParts(builder, node);
- builder
- ..forParts_condition = node.condition?.accept(this)
- ..forParts_updaters = _writeNodeList(node.updaters);
+ void _storeForParts(ForParts node) {
+ _writeOptionalNode(node.condition);
+ _writeNodeList(node.updaters);
+ _storeForLoopParts(node);
}
- void _storeFunctionBody(LinkedNodeBuilder builder, FunctionBody node) {}
-
- void _storeInformativeId(LinkedNodeBuilder builder, AstNode node) {
- builder.informativeId = getInformativeId(node);
+ void _storeInvocationExpression(InvocationExpression node) {
+ _writeOptionalNode(node.typeArguments);
+ _writeNode(node.argumentList);
+ _storeExpression(node);
+ // TODO(scheglov) typeArgumentTypes and staticInvokeType?
}
- void _storeInheritsCovariant(LinkedNodeBuilder builder, AstNode node) {
- var value = LazyAst.getInheritsCovariant(node);
- builder.inheritsCovariant = value;
+ void _storeNamedCompilationUnitMember(NamedCompilationUnitMember node) {
+ _writeDeclarationName(node.name);
+ _storeCompilationUnitMember(node);
}
- void _storeInvocationExpression(
- LinkedNodeBuilder builder, InvocationExpression node) {
- _storeExpression(builder, node);
- builder
- ..invocationExpression_arguments = node.argumentList.accept(this)
- ..invocationExpression_invokeType = _writeType(node.staticInvokeType)
- ..invocationExpression_typeArguments = node.typeArguments?.accept(this);
- }
-
- void _storeIsSimpleBounded(LinkedNodeBuilder builder, AstNode node) {
- var flag = LazyAst.isSimplyBounded(node);
- // TODO(scheglov) Check for `null` when writing resolved AST.
- builder.simplyBoundable_isSimplyBounded = flag;
- }
-
- void _storeNamedCompilationUnitMember(
- LinkedNodeBuilder builder, NamedCompilationUnitMember node) {
- _storeCompilationUnitMember(builder, node);
- _storeInformativeId(builder, node);
- builder.name = node.name.name;
- }
-
- void _storeNamespaceDirective(
- LinkedNodeBuilder builder, NamespaceDirective node) {
- _storeUriBasedDirective(builder, node);
- builder
- ..namespaceDirective_combinators = _writeNodeList(node.combinators)
- ..namespaceDirective_configurations = _writeNodeList(node.configurations)
- ..namespaceDirective_selectedUri = LazyDirective.getSelectedUri(node);
+ void _storeNamespaceDirective(NamespaceDirective node) {
+ _writeNodeList(node.combinators);
+ _writeNodeList(node.configurations);
+ _storeUriBasedDirective(node);
}
void _storeNormalFormalParameter(
- LinkedNodeBuilder builder, NormalFormalParameter node, Token keyword) {
- _storeFormalParameter(builder, node);
- builder
- ..flags = AstBinaryFlags.encode(
+ NormalFormalParameter node,
+ Token keyword, {
+ bool hasQuestion = false,
+ }) {
+ _writeByte(
+ AstBinaryFlags.encode(
+ hasName: node.identifier != null,
+ hasQuestion: hasQuestion,
isConst: keyword?.type == Keyword.CONST,
isCovariant: node.covariantKeyword != null,
isFinal: keyword?.type == Keyword.FINAL,
isRequired: node.requiredKeyword != null,
isVar: keyword?.type == Keyword.VAR,
- )
- ..informativeId = getInformativeId(node)
- ..name = node.identifier?.name
- ..normalFormalParameter_metadata = _writeNodeList(node.metadata);
- }
-
- void _storeStatement(LinkedNodeBuilder builder, Statement node) {}
-
- void _storeSwitchMember(LinkedNodeBuilder builder, SwitchMember node) {
- builder.switchMember_labels = _writeNodeList(node.labels);
- builder.switchMember_statements = _writeNodeList(node.statements);
- }
-
- void _storeTypeAlias(LinkedNodeBuilder builder, TypeAlias node) {
- _storeNamedCompilationUnitMember(builder, node);
- }
-
- void _storeTypedLiteral(LinkedNodeBuilder builder, TypedLiteral node,
- {bool isMap = false, bool isSet = false}) {
- _storeExpression(builder, node);
- builder
- ..flags = AstBinaryFlags.encode(
- hasTypeArguments: node.typeArguments != null,
- isConst: node.constKeyword != null,
- isMap: isMap,
- isSet: isSet,
- )
- ..typedLiteral_typeArguments = _writeNodeList(
- node.typeArguments?.arguments,
- );
- }
-
- void _storeUriBasedDirective(
- LinkedNodeBuilder builder, UriBasedDirective node) {
- _storeDirective(builder, node);
- builder
- ..uriBasedDirective_uri = node.uri.accept(this)
- ..uriBasedDirective_uriContent = node.uriContent
- ..uriBasedDirective_uriElement = _indexOfElement(node.uriElement);
- }
-
- void _writeActualReturnType(LinkedNodeBuilder builder, AstNode node) {
- var type = LazyAst.getReturnType(node);
- // TODO(scheglov) Check for `null` when writing resolved AST.
- builder.actualReturnType = _writeType(type);
- }
-
- void _writeActualType(LinkedNodeBuilder builder, AstNode node) {
- var type = LazyAst.getType(node);
- // TODO(scheglov) Check for `null` when writing resolved AST.
- builder.actualType = _writeType(type);
- }
-
- List<LinkedNodeBuilder> _writeNodeList(List<AstNode> nodeList) {
- if (nodeList == null) {
- return const <LinkedNodeBuilder>[];
- }
-
- var result = List<LinkedNodeBuilder>.filled(
- nodeList.length,
- null,
- growable: true,
+ ),
);
- for (var i = 0; i < nodeList.length; ++i) {
- result[i] = nodeList[i].accept(this);
+
+ // TODO(scheglov) Don't store when in DefaultFormalParameter?
+ _writeInformativeUint30(node.offset);
+ _writeInformativeUint30(node.length);
+
+ _writeNodeList(node.metadata);
+ if (node.identifier != null) {
+ _writeDeclarationName(node.identifier);
}
- return result;
+ _storeFormalParameter(node);
}
- LinkedNodeTypeBuilder _writeType(DartType type) {
- return _linkingContext.writeType(type);
+ void _storeTypeAlias(TypeAlias node) {
+ _storeNamedCompilationUnitMember(node);
}
- static int _encodeVariance(Variance variance) {
- if (variance == null) {
+ void _storeUriBasedDirective(UriBasedDirective node) {
+ _writeNode(node.uri);
+ _storeDirective(node);
+ }
+
+ void _writeActualReturnType(DartType type) {
+ // TODO(scheglov) Check for `null` when writing resolved AST.
+ _resolutionSink?.writeType(type);
+ }
+
+ void _writeActualType(DartType type) {
+ // TODO(scheglov) Check for `null` when writing resolved AST.
+ _resolutionSink?.writeType(type);
+ }
+
+ void _writeByte(int byte) {
+ assert((byte & 0xFF) == byte);
+ _sink.addByte(byte);
+ }
+
+ void _writeClassMemberIndex() {
+ _writeUInt30(_classMemberIndexItems.length);
+ for (var declaration in _classMemberIndexItems) {
+ _writeUInt30(declaration.offset);
+ _writeByte(declaration.tag);
+ if (declaration.name != null) {
+ _writeStringReference(declaration.name);
+ } else {
+ _writeUInt30(declaration.fieldNames.length);
+ for (var name in declaration.fieldNames) {
+ _writeStringReference(name);
+ }
+ }
+ }
+ }
+
+ void _writeDeclarationName(SimpleIdentifier node) {
+ _writeByte(Tag.SimpleIdentifier);
+ _writeStringReference(node.name);
+ _writeInformativeUint30(node.offset);
+ }
+
+ /// We write tokens as a list, so this must be the last entity written.
+ void _writeDocumentationCommentString(Comment node) {
+ if (node != null && _withInformative) {
+ var tokens = node.tokens;
+ _writeUInt30(tokens.length);
+ for (var token in tokens) {
+ _writeStringReference(token.lexeme);
+ }
+ } else {
+ _writeUInt30(0);
+ }
+ }
+
+ _writeDouble(double value) {
+ _sink.addDouble(value);
+ }
+
+ /// TODO(scheglov) Optimize the encoding format.
+ void _writeFeatureSet(FeatureSet featureSet) {
+ var experimentStatus = featureSet as ExperimentStatus;
+ var encoded = experimentStatus.toStorage();
+ _writeUint32List(encoded);
+ }
+
+ void _writeInformativeUint30(int value) {
+ if (_withInformative) {
+ _writeUInt30(value);
+ }
+ }
+
+ void _writeInformativeVariableCodeRanges(
+ int firstOffset,
+ VariableDeclarationList node,
+ ) {
+ if (_withInformative) {
+ var variables = node.variables;
+ _writeUInt30(variables.length * 2);
+ var isFirst = true;
+ for (var variable in variables) {
+ var offset = isFirst ? firstOffset : variable.offset;
+ var end = variable.end;
+ _writeUInt30(offset);
+ _writeUInt30(end - offset);
+ isFirst = false;
+ }
+ }
+ }
+
+ void _writeLanguageVersion(LibraryLanguageVersion languageVersion) {
+ _writeUInt30(languageVersion.package.major);
+ _writeUInt30(languageVersion.package.minor);
+
+ var override = languageVersion.override;
+ if (override != null) {
+ _writeUInt30(override.major + 1);
+ _writeUInt30(override.minor + 1);
+ } else {
+ _writeUInt30(0);
+ _writeUInt30(0);
+ }
+ }
+
+ void _writeLineInfo(LineInfo lineInfo) {
+ if (_withInformative) {
+ _writeUint30List(lineInfo.lineStarts);
+ } else {
+ _writeUint30List(const <int>[0]);
+ }
+ }
+
+ void _writeNode(AstNode node) {
+ node.accept(this);
+ }
+
+ void _writeNodeList(List<AstNode> nodeList) {
+ _writeUInt30(nodeList.length);
+ for (var i = 0; i < nodeList.length; ++i) {
+ nodeList[i].accept(this);
+ }
+ }
+
+ void _writeOptionalDeclarationName(SimpleIdentifier node) {
+ if (node == null) {
+ _writeByte(Tag.Nothing);
+ } else {
+ _writeByte(Tag.Something);
+ _writeDeclarationName(node);
+ }
+ }
+
+ void _writeOptionalNode(AstNode node) {
+ if (node == null) {
+ _writeByte(Tag.Nothing);
+ } else {
+ _writeByte(Tag.Something);
+ _writeNode(node);
+ }
+ }
+
+ void _writeStringReference(String string) {
+ assert(string != null);
+ var index = _stringIndexer[string];
+ _writeUInt30(index);
+ }
+
+ void _writeTopLevelInferenceError(ElementImpl element) {
+ TopLevelInferenceError error;
+ if (element is MethodElementImpl) {
+ error = element.typeInferenceError;
+ } else if (element is PropertyInducingElementImpl) {
+ error = element.typeInferenceError;
+ } else {
+ return;
+ }
+
+ if (error != null) {
+ _resolutionSink.writeByte(error.kind.index);
+ _resolutionSink.writeStringList(error.arguments);
+ } else {
+ _resolutionSink.writeByte(TopLevelInferenceErrorKind.none.index);
+ }
+ }
+
+ @pragma("vm:prefer-inline")
+ void _writeUInt30(int value) {
+ _sink.writeUInt30(value);
+ }
+
+ void _writeUint30List(List<int> values) {
+ var length = values.length;
+ _writeUInt30(length);
+ for (var i = 0; i < length; i++) {
+ _writeUInt30(values[i]);
+ }
+ }
+
+ void _writeUInt32(int value) {
+ _sink.addByte4((value >> 24) & 0xFF, (value >> 16) & 0xFF,
+ (value >> 8) & 0xFF, value & 0xFF);
+ }
+
+ void _writeUint32List(List<int> values) {
+ var length = values.length;
+ _writeUInt32(length);
+ for (var i = 0; i < length; i++) {
+ _writeUInt32(values[i]);
+ }
+ }
+
+ static int _encodeVariance(TypeParameterElementImpl element) {
+ if (element.isLegacyCovariant) {
return 0;
- } else if (variance == Variance.unrelated) {
+ }
+
+ var variance = element.variance;
+ if (variance == Variance.unrelated) {
return 1;
} else if (variance == Variance.covariant) {
return 2;
@@ -1733,28 +1769,21 @@
node.accept(visitor);
return visitor.result;
}
-
- static LinkedNodeFormalParameterKind _toParameterKind(FormalParameter node) {
- if (node.isRequiredPositional) {
- return LinkedNodeFormalParameterKind.requiredPositional;
- } else if (node.isRequiredNamed) {
- return LinkedNodeFormalParameterKind.requiredNamed;
- } else if (node.isOptionalPositional) {
- return LinkedNodeFormalParameterKind.optionalPositional;
- } else if (node.isOptionalNamed) {
- return LinkedNodeFormalParameterKind.optionalNamed;
- } else {
- throw StateError('Unknown kind of parameter');
- }
- }
}
-/// Components of a [Member] - the raw element, and the substitution.
-class _ElementComponents {
- final int rawElement;
- final LinkedNodeTypeSubstitutionBuilder substitution;
+/// An item in the class index, used to read only requested class members.
+class _ClassMemberIndexItem {
+ final int offset;
+ final int tag;
+ final String name;
+ final List<String> fieldNames;
- _ElementComponents(this.rawElement, this.substitution);
+ _ClassMemberIndexItem({
+ @required this.offset,
+ @required this.tag,
+ this.name,
+ this.fieldNames,
+ });
}
class _IsSerializableExpressionVisitor extends RecursiveAstVisitor<void> {
@@ -1765,3 +1794,22 @@
result = false;
}
}
+
+/// An item in the unit index, used to read only requested unit members.
+class _UnitMemberIndexItem {
+ final int offset;
+ final int tag;
+ final String name;
+ final List<String> variableNames;
+
+ /// The absolute offset of the index of class members, `0` if not a class.
+ final int classIndexOffset;
+
+ _UnitMemberIndexItem({
+ @required this.offset,
+ @required this.tag,
+ this.name,
+ this.variableNames,
+ this.classIndexOffset = 0,
+ });
+}
diff --git a/pkg/analyzer/lib/src/summary2/binary_format_doc.dart b/pkg/analyzer/lib/src/summary2/binary_format_doc.dart
new file mode 100644
index 0000000..646328e
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/binary_format_doc.dart
@@ -0,0 +1,188 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/summary2/ast_binary_tag.dart';
+
+class AstBundle {
+ /// The blob with libraries.
+ ///
+ /// Items of [libraryOffsets] point here.
+ List<AstLibrary> libraries;
+
+ /// Pointers to libraries in the [libraries] blob.
+ ///
+ /// We need these offsets because we read [ResolutionLibrary] only
+ /// partially - URI, offsets of units, but nothing about units. So,
+ /// we don't know where one library ends, and another starts.
+ ///
+ /// TODO(scheglov) too complicated? Read all?
+ List<Uint30> libraryOffsets;
+
+ /// [stringTableOffset] points here.
+ StringTableFormat stringTable;
+
+ /// We record `uint32` to know exactly the location of this field.
+ /// It is always at the end of the byte buffer `-4`.
+ Uint32 librariesOffset;
+
+ /// We record `uint32` to know exactly the location of this field.
+ /// It is always at the end of the byte buffer `-0`.
+ Uint32 stringTableOffset;
+}
+
+class AstLibrary {
+ /// The name from the `library` directive, might be the empty string.
+ StringRef name;
+
+ /// The offset `+1` of the name in the `library` directive.
+ /// So, `0` if absent, decoded then into `-1`.
+ Uint30 nameOffset;
+
+ /// The length of the name in the `library` directive, `0` if absent.
+ Uint30 nameLength;
+
+ /// Offsets pointing at [AstUnitFormat.headerOffset].
+ List<Uint30> unitOffsets;
+}
+
+class AstUnitFormat {
+ /// The header of the unit, read when create the reader.
+ /// [headerOffset] points here.
+ AstUnitHeader header;
+
+ /// [AstUnitIndexItem.offset] from [indexOfMembers] points into here.
+ Object declarations;
+
+ /// The offset of [header].
+ Uint30 headerOffset;
+
+ /// The index of declarations in the unit.
+ List<AstUnitIndexItem> indexOfMembers;
+}
+
+class AstUnitHeader {
+ /// Four elements: package major/minor, override major/minor.
+ /// The override is `+1`, if `0` then no override.
+ FormatUint32List languageVersion;
+
+ /// Encoded feature set.
+ FormatUint32List featureSet;
+}
+
+class AstUnitIndexItem {
+ /// The offset in [AstUnitFormat.declarations].
+ Uint30 offset;
+
+ /// The tag of the declaration from [Tag].
+ Byte tag;
+
+ /// If not [Tag.TopLevelVariableDeclaration], the name of the declaration.
+ /// Otherwise absent, [topLevelVariableNames] instead.
+ StringRef name;
+
+ /// If [Tag.TopLevelVariableDeclaration], the names of the variables.
+ /// Otherwise absent, [name] instead.
+ List<StringRef> topLevelVariableNames;
+}
+
+class Byte {}
+
+class FormatUint32List {}
+
+class ResolutionBundle {
+ /// The blob with libraries.
+ ///
+ /// [libraryOffsets] points here.
+ List<ResolutionLibrary> libraries;
+
+ /// Pointers to libraries in the [libraries] blob.
+ ///
+ /// We need these offsets because we read [ResolutionLibrary] only
+ /// partially - URI, offsets of units, but nothing about units. So,
+ /// we don't know where one library ends, and another starts.
+ ///
+ /// TODO(scheglov) too complicated? Read all?
+ List<Uint30> libraryOffsets;
+
+ /// The index of the parent reference, so we can add its name from
+ /// the [referenceNames]. Is `0` for the root.
+ ///
+ /// [referencesOffset] points here.
+ List<Uint30> referenceParents;
+
+ /// The name of this component of a reference, e.g. `String` or `@class`.
+ /// Is the empty string for the root.
+ List<StringRef> referenceNames;
+
+ /// We record `uint32` to know exactly the location of this field.
+ /// It is always at the end of the byte buffer `-8`.
+ Uint32 librariesOffset;
+
+ /// We record `uint32` to know exactly the location of this field.
+ /// It is always at the end of the byte buffer `-4`.
+ ///
+ /// Points at [referenceParents].
+ Uint32 referencesOffset;
+
+ /// We record `uint32` to know exactly the location of this field.
+ /// It is always at the end of the byte buffer `-0`.
+ Uint32 stringTableOffset;
+}
+
+class ResolutionLibrary {
+ /// The blob with units.
+ List<ResolutionUnitFormat> units;
+
+ /// [ResolutionBundle.libraryOffsets] points here.
+ StringRef uriStr;
+
+ /// Indexes of exported elements in [ResolutionBundle.referenceNames].
+ List<Uint30> exportedReferences;
+
+ /// Absolute offsets pointing at [ResolutionUnitFormat.uriStr].
+ List<Uint30> unitOffsets;
+}
+
+class ResolutionUnitFormat {
+ /// [ResolutionLibrary.unitOffsets] points here.
+ StringRef uriStr;
+
+ Byte isSynthetic;
+
+ Byte isPart;
+
+ /// If [isPart], the URI that is used in the `part` directive.
+ /// The empty string for the defining unit.
+ StringRef partUriStr;
+
+ /// The offset of the resolution information for directives.
+ /// For example resolution of metadata.
+ Uint30 directivesResolutionOffset;
+
+ /// Offsets of the resolution information for each declaration.
+ List<Uint30> declarationOffsets;
+}
+
+/// The reference to a [String], in form of [Uint30].
+class StringRef {}
+
+/// Any string is witten as [Uint30] and is an index into the string table.
+/// So, we can write each unique string only once.
+class StringTableFormat {
+ /// The blob with WTF8 encoded strings.
+ Object strings;
+
+ /// The length of [strings] in bytes. So, we know how much to go back in
+ /// the byte buffer from here to start reading strings.
+ Uint30 lengthInBytes;
+
+ /// The length of each string in bytes inside [strings].
+ ///
+ /// This allows us to read strings lazily as they are requested.
+ List<Uint30> lengths;
+}
+
+class Uint30 {}
+
+class Uint32 {}
diff --git a/pkg/analyzer/lib/src/summary2/bundle_reader.dart b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
new file mode 100644
index 0000000..c2d6a9a
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
@@ -0,0 +1,1112 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:typed_data';
+
+import 'package:analyzer/dart/ast/ast.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/nullability_suffix.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/source/line_info.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/generated/testing/token_factory.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/summary2/apply_resolution.dart';
+import 'package:analyzer/src/summary2/ast_binary_reader.dart';
+import 'package:analyzer/src/summary2/ast_binary_tag.dart';
+import 'package:analyzer/src/summary2/data_reader.dart';
+import 'package:analyzer/src/summary2/linked_element_factory.dart';
+import 'package:analyzer/src/summary2/linked_unit_context.dart';
+import 'package:analyzer/src/summary2/reference.dart';
+import 'package:meta/meta.dart';
+import 'package:pub_semver/pub_semver.dart';
+
+class BundleReader {
+ final LinkedElementFactory elementFactory;
+
+ final SummaryDataReader _astReader;
+ final SummaryDataReader _resolutionReader;
+
+ bool withInformative = false;
+
+ final Map<String, LibraryReader> libraryMap = {};
+
+ BundleReader({
+ @required LinkedElementFactory elementFactory,
+ @required Uint8List astBytes,
+ @required Uint8List resolutionBytes,
+ }) : elementFactory = elementFactory,
+ _astReader = SummaryDataReader(astBytes),
+ _resolutionReader = SummaryDataReader(resolutionBytes) {
+ _astReader.offset = 0;
+ withInformative = _astReader.readByte() == 1;
+
+ _astReader.offset = _astReader.bytes.length - 4 * 2;
+ var astLibrariesOffset = _astReader.readUint32();
+ var astStringsOffset = _astReader.readUint32();
+ _astReader.createStringTable(astStringsOffset);
+
+ _resolutionReader.offset = _resolutionReader.bytes.length - 4 * 3;
+ var resolutionLibrariesOffset = _resolutionReader.readUint32();
+ var resolutionReferencesOffset = _resolutionReader.readUint32();
+ var resolutionStringsOffset = _resolutionReader.readUint32();
+ _resolutionReader.createStringTable(resolutionStringsOffset);
+
+ var referenceReader = _ReferenceReader(
+ elementFactory,
+ _resolutionReader,
+ resolutionReferencesOffset,
+ );
+
+ _astReader.offset = astLibrariesOffset;
+ var astLibraryOffsets = _astReader.readUint30List();
+
+ _resolutionReader.offset = resolutionLibrariesOffset;
+ var resolutionLibraryOffsets = _resolutionReader.readUint30List();
+
+ assert(astLibraryOffsets.length == resolutionLibraryOffsets.length);
+
+ for (var i = 0; i < astLibraryOffsets.length; i++) {
+ _astReader.offset = astLibraryOffsets[i];
+ var name = _astReader.readStringReference();
+ var nameOffset = _astReader.readUInt30() - 1;
+ var nameLength = _astReader.readUInt30();
+ var hasPartOfDirective = _astReader.readByte() != 0;
+ var astUnitOffsets = _astReader.readUint30List();
+
+ _resolutionReader.offset = resolutionLibraryOffsets[i];
+ var libraryUriStr = _resolutionReader.readStringReference();
+ var resolutionUnitOffsets = _resolutionReader.readUint30List();
+ assert(astUnitOffsets.length == resolutionUnitOffsets.length);
+ var exportsIndexList = _resolutionReader.readUint30List();
+
+ var reference = elementFactory.rootReference.getChild(libraryUriStr);
+ var libraryReader = LibraryReader._(
+ elementFactory,
+ withInformative,
+ _astReader,
+ _resolutionReader,
+ referenceReader,
+ reference,
+ name,
+ nameOffset,
+ nameLength,
+ hasPartOfDirective,
+ astUnitOffsets,
+ resolutionUnitOffsets,
+ exportsIndexList,
+ );
+ libraryMap[libraryUriStr] = libraryReader;
+ }
+ }
+
+ LibraryReader getLibrary(String uriStr) {
+ return libraryMap[uriStr];
+ }
+}
+
+class ClassReader {
+ final int membersOffset;
+
+ ClassReader(this.membersOffset);
+}
+
+class LibraryReader {
+ final LinkedElementFactory elementFactory;
+ final bool withInformative;
+ final SummaryDataReader astReader;
+ final SummaryDataReader resolutionReader;
+ final _ReferenceReader referenceReader;
+ final Reference reference;
+
+ final String name;
+ final int nameOffset;
+ final int nameLength;
+
+ /// Is `true` if the defining unit has [PartOfDirective].
+ final bool hasPartOfDirective;
+
+ final Uint32List astUnitOffsets;
+ final Uint32List resolutionUnitOffsets;
+ final Uint32List exportsIndexList;
+ List<Reference> _exports;
+
+ List<UnitReader> _units;
+
+ LibraryReader._(
+ this.elementFactory,
+ this.withInformative,
+ this.astReader,
+ this.resolutionReader,
+ this.referenceReader,
+ this.reference,
+ this.name,
+ this.nameOffset,
+ this.nameLength,
+ this.hasPartOfDirective,
+ this.astUnitOffsets,
+ this.resolutionUnitOffsets,
+ this.exportsIndexList,
+ ) {
+ assert(astUnitOffsets.length == resolutionUnitOffsets.length);
+ }
+
+ List<Reference> get exports {
+ if (_exports == null) {
+ var length = exportsIndexList.length;
+ _exports = List.filled(length, null, growable: false);
+ for (var i = 0; i < length; i++) {
+ var index = exportsIndexList[i];
+ var reference = referenceReader.referenceOfIndex(index);
+ _exports[i] = reference;
+ }
+ }
+ return _exports;
+ }
+
+ List<UnitReader> get units {
+ if (_units == null) {
+ _units = [];
+ for (var i = 0; i < astUnitOffsets.length; i++) {
+ var astUnitOffset = astUnitOffsets[i];
+ var resolutionUnitOffset = resolutionUnitOffsets[i];
+
+ astReader.offset = astUnitOffset;
+ var headerOffset = astReader.readUInt30();
+ var indexOffset = astReader.offset;
+
+ resolutionReader.offset = resolutionUnitOffset;
+ var unitUriStr = resolutionReader.readStringReference();
+ var isSynthetic = resolutionReader.readByte() != 0;
+ var isPart = resolutionReader.readByte() != 0;
+ var partUriStr = resolutionReader.readStringReference();
+ if (!isPart) {
+ partUriStr = null;
+ }
+ var resolutionDirectivesOffset = resolutionReader.readUInt30();
+ var resolutionDeclarationOffsets = resolutionReader.readUint30List();
+
+ _units.add(
+ UnitReader._(
+ this,
+ resolutionDirectivesOffset,
+ resolutionDeclarationOffsets,
+ reference.getChild('@unit').getChild(unitUriStr),
+ isSynthetic,
+ partUriStr,
+ headerOffset,
+ indexOffset,
+ ),
+ );
+ }
+ }
+ return _units;
+ }
+}
+
+class LinkedContext implements AstLinkedContext {
+ final UnitReader _unitReader;
+ final AstNode _node;
+ final int _resolutionIndex;
+ final Uint32List _codeOffsetLengthList;
+ final Uint32List _documentationTokenIndexList;
+
+ @override
+ final int codeOffset;
+
+ @override
+ final int codeLength;
+
+ @override
+ final bool isClassWithConstConstructor;
+
+ bool _isApplied = false;
+
+ bool _hasDocumentationComment = false;
+
+ _UnitMemberReader _reader;
+
+ LinkedContext(
+ this._unitReader,
+ this._node, {
+ @required this.codeOffset,
+ @required this.codeLength,
+ this.isClassWithConstConstructor = false,
+ Uint32List codeOffsetLengthList,
+ @required int resolutionIndex,
+ @required Uint32List documentationTokenIndexList,
+ }) : _resolutionIndex = resolutionIndex,
+ _codeOffsetLengthList = codeOffsetLengthList,
+ _documentationTokenIndexList = documentationTokenIndexList;
+
+ @override
+ List<ClassMember> get classMembers {
+ var reader = _reader;
+ if (reader is _ClassReader) {
+ return reader.classMembers;
+ } else if (_node is ClassTypeAlias) {
+ return const <ClassMember>[];
+ } else {
+ throw UnimplementedError();
+ }
+ }
+
+ @override
+ // TODO: implement unitDirectives
+ List<Directive> get unitDirectives => throw UnimplementedError();
+
+ @override
+ void applyResolution(LinkedUnitContext unitContext) {
+ if (_isApplied) {
+ return;
+ }
+ _isApplied = true;
+
+ // EnumConstantDeclaration has no separate resolution.
+ // Its metadata is resolved during EnumDeclaration resolution.
+ if (_resolutionIndex == -1) {
+ return;
+ }
+
+ var localElements = <Element>[];
+ var resolutionReader = LinkedResolutionReader(
+ _unitReader,
+ localElements,
+ _unitReader._resolutionDeclarationsOffset[_resolutionIndex],
+ );
+ _node.accept(
+ ApplyResolutionVisitor(
+ unitContext,
+ localElements,
+ resolutionReader,
+ ),
+ );
+ }
+
+ @override
+ int getVariableDeclarationCodeLength(VariableDeclaration node) {
+ var variableList = node.parent as VariableDeclarationList;
+ var variables = variableList.variables;
+ for (var i = 0; i < variables.length; i++) {
+ if (identical(variables[i], node)) {
+ return _codeOffsetLengthList[2 * i + 1];
+ }
+ }
+ throw StateError('No |$node| in: $variableList');
+ }
+
+ @override
+ int getVariableDeclarationCodeOffset(VariableDeclaration node) {
+ var variableList = node.parent as VariableDeclarationList;
+ var variables = variableList.variables;
+ for (var i = 0; i < variables.length; i++) {
+ if (identical(variables[i], node)) {
+ return _codeOffsetLengthList[2 * i + 0];
+ }
+ }
+ throw StateError('No |$node| in: $variableList');
+ }
+
+ @override
+ void readDocumentationComment() {
+ if (_hasDocumentationComment) {
+ return;
+ }
+ _hasDocumentationComment = true;
+
+ if (_documentationTokenIndexList.isEmpty) {
+ return;
+ }
+
+ var tokens = <Token>[];
+ for (var lexemeIndex in _documentationTokenIndexList) {
+ var lexeme = _unitReader.astReader.stringOfIndex(lexemeIndex);
+ var token = TokenFactory.tokenFromString(lexeme);
+ tokens.add(token);
+ }
+
+ var comment = astFactory.documentationComment(tokens);
+ (_node as AnnotatedNodeImpl).documentationComment = comment;
+ }
+}
+
+/// Helper for reading elements and types from their binary encoding.
+class LinkedResolutionReader {
+ final UnitReader _unitReader;
+
+ /// The stack of [TypeParameterElement]s and [ParameterElement] that are
+ /// available in the scope of [nextElement] and [nextType].
+ ///
+ /// This stack is shared with the client of the reader, and update mostly
+ /// by the client. However it is also updated during [_readFunctionType].
+ final List<Element> _localElements;
+
+ /// The offset in [_Reader.bytes] from which we read resolution now.
+ int _byteOffset = 0;
+
+ LinkedResolutionReader(
+ this._unitReader,
+ this._localElements,
+ this._byteOffset,
+ );
+
+ Element nextElement() {
+ var memberFlags = readByte();
+ var element = _readRawElement();
+
+ if (memberFlags == Tag.RawElement) {
+ return element;
+ }
+
+ if (memberFlags == Tag.MemberLegacyWithTypeArguments ||
+ memberFlags == Tag.MemberWithTypeArguments) {
+ var arguments = _readTypeList();
+ // TODO(scheglov) why to check for empty? If we have this flags.
+ if (arguments.isNotEmpty) {
+ var typeParameters =
+ (element.enclosingElement as TypeParameterizedElement)
+ .typeParameters;
+ var substitution = Substitution.fromPairs(typeParameters, arguments);
+ element = ExecutableMember.from2(element, substitution);
+ }
+ }
+
+ if (memberFlags == Tag.MemberLegacyWithTypeArguments) {
+ return Member.legacy(element);
+ }
+
+ if (memberFlags == Tag.MemberWithTypeArguments) {
+ return element;
+ }
+
+ throw UnimplementedError('memberFlags: $memberFlags');
+ }
+
+ String nextString() {
+ var index = _readUInt30();
+ return _unitReader._resolutionReader.stringOfIndex(index);
+ }
+
+ DartType nextType() {
+ var tag = readByte();
+ if (tag == Tag.NullType) {
+ return null;
+ } else if (tag == Tag.DynamicType) {
+ return DynamicTypeImpl.instance;
+ } else if (tag == Tag.FunctionType) {
+ return _readFunctionType();
+ } else if (tag == Tag.InterfaceType) {
+ var element = nextElement();
+ var length = _readUInt30();
+ var typeArguments = List<DartType>.filled(length, null);
+ for (var i = 0; i < length; i++) {
+ typeArguments[i] = nextType();
+ }
+ var nullability = _readNullability();
+ return InterfaceTypeImpl(
+ element: element,
+ typeArguments: typeArguments,
+ nullabilitySuffix: nullability,
+ );
+ } else if (tag == Tag.NeverType) {
+ var nullability = _readNullability();
+ return NeverTypeImpl.instance.withNullability(nullability);
+ } else if (tag == Tag.TypeParameterType) {
+ var element = nextElement();
+ var nullability = _readNullability();
+ return TypeParameterTypeImpl(
+ element: element,
+ nullabilitySuffix: nullability,
+ );
+ } else if (tag == Tag.VoidType) {
+ return VoidTypeImpl.instance;
+ } else {
+ throw UnimplementedError('$tag');
+ }
+ }
+
+ int readByte() {
+ return _unitReader._resolutionReader.bytes[_byteOffset++];
+ }
+
+ List<String> readStringList() {
+ var values = <String>[];
+ var length = _readUInt30();
+ for (var i = 0; i < length; i++) {
+ var value = _readStringReference();
+ values.add(value);
+ }
+ return values;
+ }
+
+ int readUInt30() {
+ var byte = readByte();
+ if (byte & 0x80 == 0) {
+ // 0xxxxxxx
+ return byte;
+ } else if (byte & 0x40 == 0) {
+ // 10xxxxxx
+ return ((byte & 0x3F) << 8) | readByte();
+ } else {
+ // 11xxxxxx
+ return ((byte & 0x3F) << 24) |
+ (readByte() << 16) |
+ (readByte() << 8) |
+ readByte();
+ }
+ }
+
+ /// TODO(scheglov) Optimize for write/read of types without type parameters.
+ FunctionType _readFunctionType() {
+ var typeParameters = <TypeParameterElement>[];
+ var typeParametersLength = _readUInt30();
+ for (var i = 0; i < typeParametersLength; i++) {
+ var name = _readStringReference();
+ var element = TypeParameterElementImpl.synthetic(name);
+ typeParameters.add(element);
+ _localElements.add(element);
+ }
+ for (var i = 0; i < typeParametersLength; i++) {
+ var element = typeParameters[i] as TypeParameterElementImpl;
+ var bound = nextType();
+ element.bound = bound;
+ }
+
+ var typedefElement = nextElement();
+ var typeArguments = _readTypeList();
+
+ var returnType = nextType();
+
+ var formalParameters = <ParameterElement>[];
+ var formalParametersLength = _readUInt30();
+ for (var i = 0; i < formalParametersLength; i++) {
+ var kindIndex = readByte();
+ var type = nextType();
+ var name = nextString();
+ formalParameters.add(
+ ParameterElementImpl.synthetic(
+ name,
+ type,
+ _formalParameterKind(kindIndex),
+ ),
+ );
+ }
+
+ var nullability = _readNullability();
+
+ _localElements.length -= typeParametersLength;
+
+ return FunctionTypeImpl(
+ typeFormals: typeParameters,
+ parameters: formalParameters,
+ returnType: returnType,
+ nullabilitySuffix: nullability,
+ element: typedefElement,
+ typeArguments: typeArguments,
+ );
+ }
+
+ NullabilitySuffix _readNullability() {
+ var index = readByte();
+ return NullabilitySuffix.values[index];
+ }
+
+ Element _readRawElement() {
+ var index = _readUInt30();
+
+ if ((index & 0x1) == 0x1) {
+ return _localElements[index >> 1];
+ }
+
+ var referenceIndex = index >> 1;
+ var referenceReader = _unitReader._referenceReader;
+ var reference = referenceReader.referenceOfIndex(referenceIndex);
+
+ var elementFactory = _unitReader.elementFactory;
+ return elementFactory.elementOfReference(reference);
+ }
+
+ String _readStringReference() {
+ var index = _readUInt30();
+ return _unitReader._resolutionReader.stringOfIndex(index);
+ }
+
+ List<DartType> _readTypeList() {
+ var types = <DartType>[];
+ var length = _readUInt30();
+ for (var i = 0; i < length; i++) {
+ var argument = nextType();
+ types.add(argument);
+ }
+ return types;
+ }
+
+ int _readUInt30() {
+ var byte = readByte();
+ if (byte & 0x80 == 0) {
+ // 0xxxxxxx
+ return byte;
+ } else if (byte & 0x40 == 0) {
+ // 10xxxxxx
+ return ((byte & 0x3F) << 8) | readByte();
+ } else {
+ // 11xxxxxx
+ return ((byte & 0x3F) << 24) |
+ (readByte() << 16) |
+ (readByte() << 8) |
+ readByte();
+ }
+ }
+
+ static ParameterKind _formalParameterKind(int encoding) {
+ if (encoding == Tag.ParameterKindRequiredPositional) {
+ return ParameterKind.REQUIRED;
+ } else if (encoding == Tag.ParameterKindOptionalPositional) {
+ return ParameterKind.POSITIONAL;
+ } else if (encoding == Tag.ParameterKindRequiredNamed) {
+ return ParameterKind.NAMED_REQUIRED;
+ } else if (encoding == Tag.ParameterKindOptionalNamed) {
+ return ParameterKind.NAMED;
+ } else {
+ throw StateError('Unexpected parameter kind encoding: $encoding');
+ }
+ }
+}
+
+class SummaryDataForCompilationUnit {
+ final int codeLength;
+
+ SummaryDataForCompilationUnit(this.codeLength);
+}
+
+class SummaryDataForFormalParameter {
+ final int codeOffset;
+ final int codeLength;
+
+ SummaryDataForFormalParameter({
+ @required this.codeOffset,
+ @required this.codeLength,
+ });
+}
+
+class SummaryDataForLibraryDirective {
+ final UnitReader _unitReader;
+ final LibraryDirectiveImpl _node;
+ final Uint32List _documentationTokenIndexList;
+ bool _hasDocumentationComment = false;
+
+ SummaryDataForLibraryDirective(
+ this._unitReader,
+ this._node, {
+ @required Uint32List documentationTokenIndexList,
+ }) : _documentationTokenIndexList = documentationTokenIndexList {
+ _node.summaryData = this;
+ }
+
+ void readDocumentationComment() {
+ if (_hasDocumentationComment) {
+ return;
+ }
+ _hasDocumentationComment = true;
+
+ if (_documentationTokenIndexList.isEmpty) {
+ return;
+ }
+
+ var tokens = <Token>[];
+ for (var lexemeIndex in _documentationTokenIndexList) {
+ var lexeme = _unitReader.astReader.stringOfIndex(lexemeIndex);
+ var token = TokenFactory.tokenFromString(lexeme);
+ tokens.add(token);
+ }
+
+ var comment = astFactory.documentationComment(tokens);
+ _node.documentationComment = comment;
+ }
+}
+
+class SummaryDataForTypeParameter {
+ final int codeOffset;
+ final int codeLength;
+
+ SummaryDataForTypeParameter({
+ @required this.codeOffset,
+ @required this.codeLength,
+ });
+}
+
+class UnitReader implements ReferenceNodeAccessor {
+ final LibraryReader libraryReader;
+ final Reference reference;
+
+ final bool isSynthetic;
+
+ /// If a part, the URI that is used in the [PartDirective].
+ /// Or `null` for the defining unit.
+ final String partUriStr;
+
+ final int _directivesResolutionOffset;
+ bool _isDirectivesResolutionApplied = false;
+
+ final Uint32List _resolutionDeclarationsOffset;
+
+ int _directivesOffset;
+ final List<_UnitMemberReader> _memberReaders = [];
+
+ CompilationUnitImpl _unit;
+ bool _hasDirectives = false;
+ bool _hasDeclarations = false;
+
+ UnitReader._(
+ this.libraryReader,
+ this._directivesResolutionOffset,
+ this._resolutionDeclarationsOffset,
+ this.reference,
+ this.isSynthetic,
+ this.partUriStr,
+ int headerOffset,
+ int indexOffset,
+ ) {
+ reference.nodeAccessor = this;
+
+ astReader.offset = headerOffset;
+ var languageVersion = _readLanguageVersion();
+ var featureSetEncoded = astReader.readUint32List();
+ var lineInfo = _readLineInfo();
+ var codeLength = astReader.readUInt30();
+ var featureSet = ExperimentStatus.fromStorage(featureSetEncoded);
+ _directivesOffset = astReader.offset;
+
+ _unit = astFactory.compilationUnit(
+ beginToken: null,
+ // TODO(scheglov)
+ // scriptTag: _readNode(data.compilationUnit_scriptTag),
+ directives: [],
+ declarations: [],
+ endToken: null,
+ featureSet: featureSet,
+ );
+ _unit.languageVersion = languageVersion;
+ _unit.lineInfo = lineInfo;
+ _unit.summaryData = SummaryDataForCompilationUnit(codeLength);
+
+ astReader.offset = indexOffset;
+ _readIndex2();
+ }
+
+ SummaryDataReader get astReader => libraryReader.astReader;
+
+ LinkedElementFactory get elementFactory => libraryReader.elementFactory;
+
+ /// TODO(scheglov)
+ /// This methods breaks lazy loading, and loads everything eagerly.
+ /// We use it because of `unitElement.types` for example, when we are
+ /// explicitly asked for all [ClassDeclaration]s and [ClassTypeAlias]s.
+ @Deprecated('review it')
+ @override
+ CompilationUnit get node {
+ readDirectives();
+ readDeclarations();
+ return _unit;
+ }
+
+ CompilationUnit get unit => _unit;
+
+ String get uriStr => reference.name;
+
+ bool get withInformative => libraryReader.withInformative;
+
+ _ReferenceReader get _referenceReader => libraryReader.referenceReader;
+
+ SummaryDataReader get _resolutionReader => libraryReader.resolutionReader;
+
+ /// Apply resolution to directives.
+ void applyDirectivesResolution(LinkedUnitContext unitContext) {
+ if (_isDirectivesResolutionApplied) {
+ return;
+ }
+ _isDirectivesResolutionApplied = true;
+
+ var localElements = <Element>[];
+ var resolutionReader = LinkedResolutionReader(
+ this,
+ localElements,
+ _directivesResolutionOffset,
+ );
+ for (var directive in _unit.directives) {
+ directive.accept(
+ ApplyResolutionVisitor(
+ unitContext,
+ localElements,
+ resolutionReader,
+ ),
+ );
+ }
+ }
+
+ void readDeclarations() {
+ if (!_hasDeclarations) {
+ _hasDeclarations = true;
+ for (var reader in _memberReaders) {
+ reader.node;
+ }
+ }
+ }
+
+ /// Ensure that directives are read in this unit.
+ void readDirectives() {
+ if (!_hasDirectives) {
+ _hasDirectives = true;
+ astReader.offset = _directivesOffset;
+ var length = astReader.readUInt30();
+ for (var i = 0; i < length; i++) {
+ var astReader = AstBinaryReader(
+ reader: this,
+ );
+ var directive = astReader.readNode() as Directive;
+ _unit.directives.add(directive);
+ }
+ }
+ }
+
+ @override
+ void readIndex() {}
+
+ /// Read the index of declarations in this unit, and add `null`s into
+ /// [CompilationUnit.declarations] as placeholders.
+ ///
+ /// TODO(scheglov) we don't need both this method, and [readIndex].
+ void _readIndex2() {
+ var unitReference = reference;
+ var length = astReader.readUInt30();
+ for (var i = 0; i < length; i++) {
+ var offset = astReader.readUInt30();
+ var tag = astReader.readByte();
+ if (tag == Tag.Class) {
+ var name = astReader.readStringReference();
+ var indexOffset = astReader.readUInt30();
+ var reference = unitReference.getChild('@class').getChild(name);
+ _memberReaders.add(
+ _ClassReader(
+ unitReader: this,
+ reference: reference,
+ offset: offset,
+ unit: _unit,
+ indexOffset: indexOffset,
+ ),
+ );
+ } else if (tag == Tag.ClassTypeAlias) {
+ var name = astReader.readStringReference();
+ var reader = _UnitMemberReader(this, offset, _unit);
+ _memberReaders.add(reader);
+ unitReference.getChild('@class').getChild(name).nodeAccessor = reader;
+ } else if (tag == Tag.EnumDeclaration) {
+ var name = astReader.readStringReference();
+ var reader = _UnitMemberReader(this, offset, _unit);
+ _memberReaders.add(reader);
+ unitReference.getChild('@enum').getChild(name).nodeAccessor = reader;
+ } else if (tag == Tag.ExtensionDeclaration) {
+ var name = astReader.readStringReference();
+ var indexOffset = astReader.readUInt30();
+ var reference = unitReference.getChild('@extension').getChild(name);
+ _memberReaders.add(
+ _ClassReader(
+ unitReader: this,
+ reference: reference,
+ offset: offset,
+ unit: _unit,
+ indexOffset: indexOffset,
+ ),
+ );
+ } else if (tag == Tag.FunctionDeclaration) {
+ var name = astReader.readStringReference();
+ var reader = _UnitMemberReader(this, offset, _unit);
+ _memberReaders.add(reader);
+ var containerRef = unitReference.getChild('@function');
+ containerRef.getChild(name).nodeAccessor = reader;
+ } else if (tag == Tag.FunctionDeclaration_getter) {
+ var name = astReader.readStringReference();
+ var reader = _UnitMemberReader(this, offset, _unit);
+ _memberReaders.add(reader);
+ var getterRef = unitReference.getChild('@getter');
+ getterRef.getChild(name).nodeAccessor = reader;
+ var variableRef = unitReference.getChild('@variable');
+ variableRef.getChild(name).nodeAccessor ??= reader;
+ } else if (tag == Tag.FunctionDeclaration_setter) {
+ var name = astReader.readStringReference();
+ var reader = _UnitMemberReader(this, offset, _unit);
+ _memberReaders.add(reader);
+ var setterRef = unitReference.getChild('@setter');
+ setterRef.getChild(name).nodeAccessor = reader;
+ var variableRef = unitReference.getChild('@variable');
+ variableRef.getChild(name).nodeAccessor ??= reader;
+ } else if (tag == Tag.GenericTypeAlias) {
+ var name = astReader.readStringReference();
+ var reader = _UnitMemberReader(this, offset, _unit);
+ _memberReaders.add(reader);
+ unitReference.getChild('@typeAlias').getChild(name).nodeAccessor =
+ reader;
+ } else if (tag == Tag.FunctionTypeAlias) {
+ var name = astReader.readStringReference();
+ var reader = _UnitMemberReader(this, offset, _unit);
+ _memberReaders.add(reader);
+ unitReference.getChild('@typeAlias').getChild(name).nodeAccessor =
+ reader;
+ } else if (tag == Tag.MixinDeclaration) {
+ var name = astReader.readStringReference();
+ var indexOffset = astReader.readUInt30();
+ var reference = unitReference.getChild('@mixin').getChild(name);
+ _memberReaders.add(
+ _ClassReader(
+ unitReader: this,
+ reference: reference,
+ offset: offset,
+ unit: _unit,
+ indexOffset: indexOffset,
+ ),
+ );
+ } else if (tag == Tag.TopLevelVariableDeclaration) {
+ var reader = _UnitMemberReader(this, offset, _unit);
+ var length = astReader.readUInt30();
+ for (var i = 0; i < length; i++) {
+ var name = astReader.readStringReference();
+ _memberReaders.add(reader);
+ unitReference.getChild('@getter').getChild(name).nodeAccessor =
+ reader;
+ // TODO(scheglov) only if not final/const
+ // Crash in language_2/export/local_export_test.dart
+ unitReference.getChild('@setter').getChild(name).nodeAccessor =
+ reader;
+ }
+ } else {
+ // TODO(scheglov) implement
+ }
+ }
+ }
+
+ LibraryLanguageVersion _readLanguageVersion() {
+ var packageMajor = astReader.readUInt30();
+ var packageMinor = astReader.readUInt30();
+ var overrideMajor = astReader.readUInt30();
+ var overrideMinor = astReader.readUInt30();
+ return LibraryLanguageVersion(
+ package: Version(packageMajor, packageMinor, 0),
+ override: overrideMajor > 0
+ ? Version(overrideMajor - 1, overrideMinor - 1, 0)
+ : null,
+ );
+ }
+
+ LineInfo _readLineInfo() {
+ var lineStarts = astReader.readUint30List();
+ return LineInfo(lineStarts);
+ }
+}
+
+class _ClassMemberReader implements ReferenceNodeAccessor {
+ final UnitReader unitReader;
+ final int offset;
+ final NodeListImpl<ClassMember> _members;
+ final int _membersIndex;
+ ClassMemberImpl _node;
+
+ _ClassMemberReader(this.unitReader, this.offset, this._members)
+ : _membersIndex = _members.length {
+ _members.add(null);
+ }
+
+ @override
+ AstNode get node {
+ if (_node == null) {
+ var astReader = AstBinaryReader(
+ reader: unitReader,
+ );
+ unitReader.astReader.offset = offset;
+ _node = astReader.readNode() as ClassMemberImpl;
+ _members[_membersIndex] = _node;
+ }
+ return _node;
+ }
+
+ @override
+ void readIndex() {}
+}
+
+class _ClassReader extends _UnitMemberReader {
+ final Reference reference;
+ final int indexOffset;
+
+ bool _hasIndex = false;
+ final List<_ClassMemberReader> _classMemberReaders = [];
+ List<ClassMember> _classMembers;
+
+ _ClassReader({
+ @required this.reference,
+ @required UnitReader unitReader,
+ @required int offset,
+ @required CompilationUnit unit,
+ @required this.indexOffset,
+ }) : super(unitReader, offset, unit) {
+ reference.nodeAccessor ??= this;
+ }
+
+ List<_ClassMemberReader> get classMemberReaders {
+ readIndex();
+ return _classMemberReaders;
+ }
+
+ List<ClassMember> get classMembers {
+ return classMemberReaders.map((e) => e.node as ClassMember).toList();
+ }
+
+ @override
+ void readIndex() {
+ if (_hasIndex) return;
+ _hasIndex = true;
+
+ var node = _node;
+ if (node == null) {
+ throw StateError('The class node must be read before reading members.');
+ }
+
+ if (node is ClassDeclarationImpl) {
+ _classMembers = node.members;
+ } else if (node is ExtensionDeclarationImpl) {
+ _classMembers = node.members;
+ } else if (node is MixinDeclarationImpl) {
+ _classMembers = node.members;
+ } else {
+ throw StateError('(${node.runtimeType}) $node');
+ }
+
+ unitReader.astReader.offset = indexOffset;
+
+ var length = unitReader.astReader.readUInt30();
+ for (var i = 0; i < length; i++) {
+ var offset = unitReader.astReader.readUInt30();
+ var tag = unitReader.astReader.readByte();
+ if (tag == Tag.ConstructorDeclaration) {
+ var reader = _ClassMemberReader(unitReader, offset, _classMembers);
+ _classMemberReaders.add(reader);
+ var name = unitReader.astReader.readStringReference();
+ var reference = this.reference.getChild('@constructor').getChild(name);
+ reference.nodeAccessor ??= reader;
+ } else if (tag == Tag.MethodDeclaration) {
+ var reader = _ClassMemberReader(unitReader, offset, _classMembers);
+ _classMemberReaders.add(reader);
+ var name = unitReader.astReader.readStringReference();
+ var reference = this.reference.getChild('@method').getChild(name);
+ reference.nodeAccessor ??= reader;
+ } else if (tag == Tag.MethodDeclaration_getter) {
+ var reader = _ClassMemberReader(unitReader, offset, _classMembers);
+ _classMemberReaders.add(reader);
+ var name = unitReader.astReader.readStringReference();
+ var reference = this.reference.getChild('@getter').getChild(name);
+ reference.nodeAccessor ??= reader;
+ } else if (tag == Tag.MethodDeclaration_setter) {
+ var reader = _ClassMemberReader(unitReader, offset, _classMembers);
+ _classMemberReaders.add(reader);
+ var name = unitReader.astReader.readStringReference();
+ var reference = this.reference.getChild('@setter').getChild(name);
+ reference.nodeAccessor ??= reader;
+ } else if (tag == Tag.FieldDeclaration) {
+ var reader = _ClassMemberReader(unitReader, offset, _classMembers);
+ _classMemberReaders.add(reader);
+ var length = unitReader.astReader.readUInt30();
+ for (var i = 0; i < length; i++) {
+ var name = unitReader.astReader.readStringReference();
+ var fieldRef = reference.getChild('@field').getChild(name);
+ fieldRef.nodeAccessor ??= reader;
+ var getterRef = reference.getChild('@getter').getChild(name);
+ getterRef.nodeAccessor ??= reader;
+ var setterRef = reference.getChild('@setter').getChild(name);
+ setterRef.nodeAccessor ??= reader;
+ }
+ } else {
+ throw UnimplementedError('tag: $tag');
+ }
+ }
+ }
+}
+
+class _ReferenceReader {
+ final LinkedElementFactory elementFactory;
+ final SummaryDataReader _reader;
+ Uint32List _parents;
+ Uint32List _names;
+ List<Reference> _references;
+
+ _ReferenceReader(this.elementFactory, this._reader, int offset) {
+ _reader.offset = offset;
+ _parents = _reader.readUint30List();
+ _names = _reader.readUint30List();
+ assert(_parents.length == _names.length);
+
+ _references = List.filled(_names.length, null);
+ }
+
+ Reference referenceOfIndex(int index) {
+ var reference = _references[index];
+ if (reference != null) {
+ return reference;
+ }
+
+ if (index == 0) {
+ reference = elementFactory.rootReference;
+ _references[index] = reference;
+ return reference;
+ }
+
+ var nameIndex = _names[index];
+ var name = _reader.stringOfIndex(nameIndex);
+
+ var parentIndex = _parents[index];
+ var parent = referenceOfIndex(parentIndex);
+
+ reference = parent.getChild(name);
+ _references[index] = reference;
+
+ return reference;
+ }
+}
+
+class _UnitMemberReader implements ReferenceNodeAccessor {
+ final UnitReader unitReader;
+ final int offset;
+ final CompilationUnit _unit;
+ final int _index;
+ CompilationUnitMemberImpl _node;
+
+ _UnitMemberReader(this.unitReader, this.offset, this._unit)
+ : _index = _unit.declarations.length {
+ _unit.declarations.add(null);
+ }
+
+ @override
+ AstNode get node {
+ if (_node == null) {
+ var astReader = AstBinaryReader(
+ reader: unitReader,
+ );
+ unitReader.astReader.offset = offset;
+ _node = astReader.readNode() as CompilationUnitMember;
+ _unit.declarations[_index] = _node;
+
+ var hasLinkedContext = _node as HasAstLinkedContext;
+ var linkedContext = hasLinkedContext.linkedContext as LinkedContext;
+ linkedContext._reader = this;
+ }
+ return _node;
+ }
+
+ @override
+ void readIndex() {}
+}
diff --git a/pkg/analyzer/lib/src/summary2/bundle_writer.dart b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
new file mode 100644
index 0000000..0da35249
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
@@ -0,0 +1,698 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:typed_data';
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/summary2/ast_binary_tag.dart';
+import 'package:analyzer/src/summary2/ast_binary_writer.dart';
+import 'package:analyzer/src/summary2/binary_format_doc.dart';
+import 'package:analyzer/src/summary2/data_writer.dart';
+import 'package:analyzer/src/summary2/reference.dart';
+import 'package:meta/meta.dart';
+
+class BundleWriter {
+ final bool withInformative;
+ BundleWriterAst _astWriter;
+ BundleWriterResolution _resolutionWriter;
+
+ BundleWriter(this.withInformative, Reference dynamicReference) {
+ _astWriter = BundleWriterAst(withInformative);
+ _resolutionWriter = BundleWriterResolution(dynamicReference);
+ }
+
+ void addLibrary(LibraryToWrite library) {
+ var resolutionLibrary = _resolutionWriter.enterLibrary(library);
+
+ var astUnitOffsets = <int>[];
+ for (var unit in library.units) {
+ var resolutionUnit = resolutionLibrary.enterUnit(unit);
+ var offset = _astWriter.writeUnit(unit.node, resolutionUnit);
+ astUnitOffsets.add(offset);
+ }
+
+ _astWriter.writeLibrary(library.units[0].node, astUnitOffsets);
+ }
+
+ BundleWriterResult finish() {
+ var astBytes = _astWriter.finish();
+ var resolutionBytes = _resolutionWriter.finish();
+ return BundleWriterResult(
+ astBytes: astBytes,
+ resolutionBytes: resolutionBytes,
+ );
+ }
+}
+
+class BundleWriterAst {
+ final bool withInformative;
+ final ByteSink _byteSink = ByteSink();
+ BufferedSink sink;
+ final StringIndexer stringIndexer = StringIndexer();
+
+ final List<int> _libraryOffsets = [];
+
+ BundleWriterAst(this.withInformative) {
+ sink = BufferedSink(_byteSink);
+ sink.writeByte(withInformative ? 1 : 0);
+ }
+
+ Uint8List finish() {
+ var librariesOffset = sink.offset;
+ sink.writeUint30List(_libraryOffsets);
+
+ var stringTableOffset = stringIndexer.write(sink);
+
+ sink.writeUInt32(librariesOffset);
+ sink.writeUInt32(stringTableOffset);
+
+ sink.flushAndDestroy();
+ return _byteSink.builder.takeBytes();
+ }
+
+ /// Write the library name and offset, and pointers to [unitOffsets].
+ void writeLibrary(CompilationUnit definingUnit, List<int> unitOffsets) {
+ _libraryOffsets.add(sink.offset);
+
+ var name = '';
+ var nameOffset = -1;
+ var nameLength = 0;
+ for (var directive in definingUnit.directives) {
+ if (directive is LibraryDirective) {
+ name = directive.name.components.map((e) => e.name).join('.');
+ nameOffset = directive.name.offset;
+ nameLength = directive.name.length;
+ break;
+ }
+ }
+
+ var hasPartOfDirective = false;
+ for (var directive in definingUnit.directives) {
+ if (directive is PartOfDirective) {
+ hasPartOfDirective = true;
+ break;
+ }
+ }
+
+ _writeStringReference(name);
+ sink.writeUInt30(1 + nameOffset);
+ sink.writeUInt30(nameLength);
+ sink.writeByte(hasPartOfDirective ? 1 : 0);
+ sink.writeUint30List(unitOffsets);
+ }
+
+ /// Write the [node] into the [sink].
+ /// While visiting AST, store the resolution into [resolutionUnit].
+ ///
+ /// Return the pointer at [AstUnitFormat.headerOffset].
+ int writeUnit(CompilationUnit node, ResolutionUnit resolutionUnit) {
+ var headerOffset = sink.offset;
+
+ var unitWriter = AstBinaryWriter(
+ bundleWriterAst: this,
+ resolutionUnit: resolutionUnit,
+ );
+ node.accept(unitWriter);
+
+ var indexOffset = sink.offset;
+ sink.writeUInt30(headerOffset);
+
+ sink.writeUInt30(unitWriter.unitMemberIndexItems.length);
+ for (var declaration in unitWriter.unitMemberIndexItems) {
+ sink.writeUInt30(declaration.offset);
+ sink.writeByte(declaration.tag);
+ if (declaration.name != null) {
+ _writeStringReference(declaration.name);
+ } else {
+ sink.writeList(declaration.variableNames, _writeStringReference);
+ }
+ if (declaration.classIndexOffset != 0) {
+ sink.writeUInt30(declaration.classIndexOffset);
+ }
+ }
+
+ return indexOffset;
+ }
+
+ void _writeStringReference(String string) {
+ var index = stringIndexer[string];
+ sink.writeUInt30(index);
+ }
+}
+
+class BundleWriterResolution {
+ _BundleWriterReferences _references;
+ final ByteSink _byteSink = ByteSink();
+ BufferedSink _sink;
+ ResolutionSink _resolutionSink;
+
+ final StringIndexer _stringIndexer = StringIndexer();
+
+ final List<_ResolutionLibrary> _libraries = [];
+
+ BundleWriterResolution(Reference dynamicReference) {
+ _references = _BundleWriterReferences(dynamicReference);
+
+ _sink = BufferedSink(_byteSink);
+ _resolutionSink = ResolutionSink(
+ stringIndexer: _stringIndexer,
+ sink: _sink,
+ references: _references,
+ );
+ }
+
+ _ResolutionLibrary enterLibrary(LibraryToWrite libraryToWrite) {
+ var library = _ResolutionLibrary(
+ sink: _resolutionSink,
+ library: libraryToWrite,
+ );
+ _libraries.add(library);
+ return library;
+ }
+
+ Uint8List finish() {
+ var libraryOffsets = <int>[];
+ for (var library in _libraries) {
+ var unitOffsets = <int>[];
+ for (var unit in library.units) {
+ unitOffsets.add(_sink.offset);
+ _writeStringReference(unit.unit.uriStr);
+ _sink.writeByte(unit.unit.isSynthetic ? 1 : 0);
+ _sink.writeByte(unit.unit.partUriStr != null ? 1 : 0);
+ _writeStringReference(unit.unit.partUriStr ?? '');
+ _sink.writeUInt30(unit.directivesOffset);
+ _sink.writeUint30List(unit.offsets);
+ }
+ libraryOffsets.add(_sink.offset);
+ _writeStringReference(library.library.uriStr);
+ _sink.writeUint30List(unitOffsets);
+ _writeReferences(library.library.exports);
+ }
+
+ _references._clearIndexes();
+
+ var librariesOffset = _sink.offset;
+ _sink.writeUint30List(libraryOffsets);
+
+ var referencesOffset = _sink.offset;
+ _sink.writeUint30List(_references._referenceParents);
+ _writeStringList(_references._referenceNames);
+
+ var stringTableOffset = _stringIndexer.write(_sink);
+
+ // Write as Uint32 so that we know where it is.
+ _sink.writeUInt32(librariesOffset);
+ _sink.writeUInt32(referencesOffset);
+ _sink.writeUInt32(stringTableOffset);
+
+ _sink.flushAndDestroy();
+ return _byteSink.builder.takeBytes();
+ }
+
+ void _writeReferences(List<Reference> references) {
+ var length = references.length;
+ _sink.writeUInt30(length);
+
+ for (var reference in references) {
+ var index = _references._indexOfReference(reference);
+ _sink.writeUInt30(index);
+ }
+ }
+
+ void _writeStringList(List<String> values) {
+ _sink.writeUInt30(values.length);
+ for (var value in values) {
+ _writeStringReference(value);
+ }
+ }
+
+ void _writeStringReference(String string) {
+ var index = _stringIndexer[string];
+ _sink.writeUInt30(index);
+ }
+}
+
+class BundleWriterResult {
+ final Uint8List astBytes;
+ final Uint8List resolutionBytes;
+
+ BundleWriterResult({
+ @required this.astBytes,
+ @required this.resolutionBytes,
+ });
+}
+
+class LibraryToWrite {
+ final String uriStr;
+ final List<Reference> exports;
+ final List<UnitToWrite> units;
+
+ LibraryToWrite({
+ @required this.uriStr,
+ @required this.exports,
+ @required this.units,
+ });
+}
+
+class ResolutionSink {
+ final StringIndexer _stringIndexer;
+ final BufferedSink _sink;
+ final _BundleWriterReferences _references2;
+ final _LocalElementIndexer localElements = _LocalElementIndexer();
+
+ ResolutionSink({
+ @required StringIndexer stringIndexer,
+ @required BufferedSink sink,
+ @required _BundleWriterReferences references,
+ }) : _stringIndexer = stringIndexer,
+ _sink = sink,
+ _references2 = references;
+
+ int get offset => _sink.offset;
+
+ void writeByte(int byte) {
+ assert((byte & 0xFF) == byte);
+ _sink.addByte(byte);
+ }
+
+ /// TODO(scheglov) Triage places where we write elements.
+ /// Some of then cannot be members, e.g. type names.
+ void writeElement(Element element) {
+ if (element is Member) {
+ var declaration = element.declaration;
+ var isLegacy = element.isLegacy;
+
+ var typeArguments = _enclosingClassTypeArguments(
+ declaration,
+ element.substitution.map,
+ );
+
+ writeByte(
+ isLegacy
+ ? Tag.MemberLegacyWithTypeArguments
+ : Tag.MemberWithTypeArguments,
+ );
+
+ writeElement0(declaration);
+ _writeTypeList(typeArguments);
+ } else {
+ writeByte(Tag.RawElement);
+ writeElement0(element);
+ }
+ }
+
+ void writeElement0(Element element) {
+ assert(element is! Member, 'Use writeMemberOrElement()');
+ var elementIndex = _indexOfElement(element);
+ _sink.writeUInt30(elementIndex);
+ }
+
+ void writeStringList(List<String> values) {
+ _sink.writeUInt30(values.length);
+ for (var value in values) {
+ _writeStringReference(value);
+ }
+ }
+
+ void writeType(DartType type) {
+ if (type == null) {
+ writeByte(Tag.NullType);
+ } else if (type is DynamicType) {
+ writeByte(Tag.DynamicType);
+ } else if (type is FunctionType) {
+ _writeFunctionType(type);
+ } else if (type is InterfaceType) {
+ writeByte(Tag.InterfaceType);
+ // TODO(scheglov) Write raw
+ writeElement(type.element);
+ var typeArguments = type.typeArguments;
+ _sink.writeUInt30(typeArguments.length);
+ for (var i = 0; i < typeArguments.length; ++i) {
+ writeType(typeArguments[i]);
+ }
+ _writeNullabilitySuffix(type.nullabilitySuffix);
+ } else if (type is NeverType) {
+ writeByte(Tag.NeverType);
+ _writeNullabilitySuffix(type.nullabilitySuffix);
+ } else if (type is TypeParameterType) {
+ writeByte(Tag.TypeParameterType);
+ writeElement(type.element);
+ _writeNullabilitySuffix(type.nullabilitySuffix);
+ } else if (type is VoidType) {
+ writeByte(Tag.VoidType);
+ } else {
+ // TODO
+ throw UnimplementedError('${type.runtimeType}');
+ }
+ }
+
+ int _indexOfElement(Element element) {
+ if (element == null) return 0;
+ if (element is MultiplyDefinedElement) return 0;
+ assert(element is! Member);
+
+ // Positional parameters cannot be referenced outside of their scope,
+ // so don't have a reference, so are stored as local elements.
+ if (element is ParameterElementImpl && element.reference == null) {
+ return localElements[element] << 1 | 0x1;
+ }
+
+ // Type parameters cannot be referenced outside of their scope,
+ // so don't have a reference, so are stored as local elements.
+ if (element is TypeParameterElement) {
+ return localElements[element] << 1 | 0x1;
+ }
+
+ if (identical(element, DynamicElementImpl.instance)) {
+ return _references2._indexOfReference(_references2.dynamicReference) << 1;
+ }
+
+ var reference = (element as ElementImpl).reference;
+ return _references2._indexOfReference(reference) << 1;
+ }
+
+ void _writeFormalParameterKind(ParameterElement p) {
+ if (p.isRequiredPositional) {
+ writeByte(Tag.ParameterKindRequiredPositional);
+ } else if (p.isOptionalPositional) {
+ writeByte(Tag.ParameterKindOptionalPositional);
+ } else if (p.isRequiredNamed) {
+ writeByte(Tag.ParameterKindRequiredNamed);
+ } else if (p.isOptionalNamed) {
+ writeByte(Tag.ParameterKindOptionalNamed);
+ } else {
+ throw StateError('Unexpected parameter kind: $p');
+ }
+ }
+
+ void _writeFunctionType(FunctionType type) {
+ type = _toSyntheticFunctionType(type);
+
+ writeByte(Tag.FunctionType);
+
+ localElements.pushScope();
+
+ var typeParameters = type.typeFormals;
+ for (var typeParameter in type.typeFormals) {
+ localElements.declare(typeParameter);
+ }
+
+ _sink.writeUInt30(typeParameters.length);
+ for (var typeParameter in type.typeFormals) {
+ _writeStringReference(typeParameter.name);
+ }
+ for (var typeParameter in type.typeFormals) {
+ writeType(typeParameter.bound);
+ }
+
+ Element typedefElement;
+ List<DartType> typedefTypeArguments = const <DartType>[];
+ if (type.element is FunctionTypeAliasElement) {
+ typedefElement = type.element;
+ typedefTypeArguments = type.typeArguments;
+ }
+ // TODO(scheglov) Cleanup to always use FunctionTypeAliasElement.
+ if (type.element is GenericFunctionTypeElement &&
+ type.element.enclosingElement is FunctionTypeAliasElement) {
+ typedefElement = type.element.enclosingElement;
+ typedefTypeArguments = type.typeArguments;
+ }
+
+ writeElement(typedefElement);
+ _writeTypeList(typedefTypeArguments);
+
+ writeType(type.returnType);
+
+ var parameters = type.parameters;
+ _sink.writeUInt30(parameters.length);
+ for (var parameter in parameters) {
+ _writeFormalParameterKind(parameter);
+ assert(parameter.type != null);
+ writeType(parameter.type);
+ // TODO(scheglov) Don't write names of positional parameters
+ _writeStringReference(parameter.name);
+ }
+
+ _writeNullabilitySuffix(type.nullabilitySuffix);
+
+ localElements.popScope();
+ }
+
+ void _writeNullabilitySuffix(NullabilitySuffix suffix) {
+ writeByte(suffix.index);
+ }
+
+ void _writeStringReference(String string) {
+ var index = _stringIndexer[string];
+ _sink.writeUInt30(index);
+ }
+
+ void _writeTypeList(List<DartType> types) {
+ _sink.writeUInt30(types.length);
+ for (var type in types) {
+ writeType(type);
+ }
+ }
+
+ static List<DartType> _enclosingClassTypeArguments(
+ Element declaration,
+ Map<TypeParameterElement, DartType> substitution,
+ ) {
+ var enclosing = declaration.enclosingElement;
+ if (enclosing is TypeParameterizedElement) {
+ if (enclosing is! ClassElement && enclosing is! ExtensionElement) {
+ return const <DartType>[];
+ }
+
+ var typeParameters = enclosing.typeParameters;
+ if (typeParameters.isEmpty) {
+ return const <DartType>[];
+ }
+
+ return typeParameters
+ .map((typeParameter) => substitution[typeParameter])
+ .toList(growable: false);
+ }
+
+ return const <DartType>[];
+ }
+
+ static FunctionType _toSyntheticFunctionType(FunctionType type) {
+ var typeParameters = type.typeFormals;
+
+ if (typeParameters.isEmpty) return type;
+
+ var onlySyntheticTypeParameters = typeParameters.every((e) {
+ return e is TypeParameterElementImpl && e.linkedNode == null;
+ });
+ if (onlySyntheticTypeParameters) return type;
+
+ var parameters = getFreshTypeParameters(typeParameters);
+ return parameters.applyToFunctionType(type);
+ }
+}
+
+class ResolutionUnit {
+ final _ResolutionLibrary library;
+ final UnitToWrite unit;
+
+ /// The offset of the resolution data for directives.
+ final int directivesOffset;
+
+ /// The offsets of resolution data for each declaration - class, method, etc.
+ final List<int> offsets = [];
+
+ ResolutionUnit({
+ @required this.library,
+ @required this.unit,
+ @required this.directivesOffset,
+ });
+
+ /// Should be called on enter into a new declaration on which level
+ /// resolution is stored, e.g. [ClassDeclaration] (header), or
+ /// [MethodDeclaration] (header), or [FieldDeclaration] (all).
+ int enterDeclaration() {
+ var index = offsets.length;
+ offsets.add(library.sink.offset);
+ return index;
+ }
+}
+
+class StringIndexer {
+ final Map<String, int> _index = {};
+
+ int operator [](String string) {
+ var result = _index[string];
+
+ if (result == null) {
+ result = _index.length;
+ _index[string] = result;
+ }
+
+ return result;
+ }
+
+ int write(BufferedSink sink) {
+ var bytesOffset = sink.offset;
+
+ var length = _index.length;
+ var lengths = Uint32List(length);
+ var lengthsIndex = 0;
+ for (var key in _index.keys) {
+ var stringStart = sink.offset;
+ _writeWtf8(sink, key);
+ lengths[lengthsIndex++] = sink.offset - stringStart;
+ }
+
+ var resultOffset = sink.offset;
+
+ var lengthOfBytes = sink.offset - bytesOffset;
+ sink.writeUInt30(lengthOfBytes);
+ sink.writeUint30List(lengths);
+
+ return resultOffset;
+ }
+
+ /// Write [source] string into [sink].
+ static void _writeWtf8(BufferedSink sink, String source) {
+ var end = source.length;
+ if (end == 0) {
+ return;
+ }
+
+ int i = 0;
+ do {
+ var codeUnit = source.codeUnitAt(i++);
+ if (codeUnit < 128) {
+ // ASCII.
+ sink.addByte(codeUnit);
+ } else if (codeUnit < 0x800) {
+ // Two-byte sequence (11-bit unicode value).
+ sink.addByte(0xC0 | (codeUnit >> 6));
+ sink.addByte(0x80 | (codeUnit & 0x3f));
+ } else if ((codeUnit & 0xFC00) == 0xD800 &&
+ i < end &&
+ (source.codeUnitAt(i) & 0xFC00) == 0xDC00) {
+ // Surrogate pair -> four-byte sequence (non-BMP unicode value).
+ int codeUnit2 = source.codeUnitAt(i++);
+ int unicode =
+ 0x10000 + ((codeUnit & 0x3FF) << 10) + (codeUnit2 & 0x3FF);
+ sink.addByte(0xF0 | (unicode >> 18));
+ sink.addByte(0x80 | ((unicode >> 12) & 0x3F));
+ sink.addByte(0x80 | ((unicode >> 6) & 0x3F));
+ sink.addByte(0x80 | (unicode & 0x3F));
+ } else {
+ // Three-byte sequence (16-bit unicode value), including lone
+ // surrogates.
+ sink.addByte(0xE0 | (codeUnit >> 12));
+ sink.addByte(0x80 | ((codeUnit >> 6) & 0x3f));
+ sink.addByte(0x80 | (codeUnit & 0x3f));
+ }
+ } while (i < end);
+ }
+}
+
+class UnitToWrite {
+ final String uriStr;
+ final String partUriStr;
+ final CompilationUnit node;
+ final bool isSynthetic;
+
+ UnitToWrite({
+ @required this.uriStr,
+ @required this.partUriStr,
+ @required this.node,
+ @required this.isSynthetic,
+ });
+}
+
+class _BundleWriterReferences {
+ /// The `dynamic` class is declared in `dart:core`, but is not a class.
+ /// Also, it is static, so we cannot set `reference` for it.
+ /// So, we have to push it in a separate way.
+ final Reference dynamicReference;
+
+ /// References used in all libraries being linked.
+ /// Element references in nodes are indexes in this list.
+ final List<Reference> references = [null];
+
+ final List<int> _referenceParents = [0];
+ final List<String> _referenceNames = [''];
+
+ _BundleWriterReferences(this.dynamicReference);
+
+ /// We need indexes for references during linking, but once we are done,
+ /// we must clear indexes to make references ready for linking a next bundle.
+ void _clearIndexes() {
+ for (var reference in references) {
+ if (reference != null) {
+ reference.index = null;
+ }
+ }
+ }
+
+ int _indexOfReference(Reference reference) {
+ if (reference == null) return 0;
+ if (reference.parent == null) return 0;
+ if (reference.index != null) return reference.index;
+
+ var parentIndex = _indexOfReference(reference.parent);
+ _referenceParents.add(parentIndex);
+ _referenceNames.add(reference.name);
+
+ reference.index = references.length;
+ references.add(reference);
+ return reference.index;
+ }
+}
+
+class _LocalElementIndexer {
+ final Map<Element, int> _index = Map.identity();
+ final List<int> _scopes = [];
+ int _stackHeight = 0;
+
+ int operator [](Element element) {
+ return _index[element] ??
+ (throw ArgumentError('Unexpectedly not indexed: $element'));
+ }
+
+ void declare(Element element) {
+ _index[element] = _stackHeight++;
+ }
+
+ void popScope() {
+ _stackHeight = _scopes.removeLast();
+ }
+
+ void pushScope() {
+ _scopes.add(_stackHeight);
+ }
+}
+
+class _ResolutionLibrary {
+ final ResolutionSink sink;
+ final LibraryToWrite library;
+ final List<ResolutionUnit> units = [];
+
+ _ResolutionLibrary({
+ @required this.sink,
+ @required this.library,
+ });
+
+ ResolutionUnit enterUnit(UnitToWrite unitToWrite) {
+ var unit = ResolutionUnit(
+ library: this,
+ unit: unitToWrite,
+ directivesOffset: sink.offset,
+ );
+ units.add(unit);
+ return unit;
+ }
+}
diff --git a/pkg/analyzer/lib/src/summary2/data_reader.dart b/pkg/analyzer/lib/src/summary2/data_reader.dart
new file mode 100644
index 0000000..143685b
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/data_reader.dart
@@ -0,0 +1,225 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+import 'dart:typed_data';
+
+import 'package:meta/meta.dart';
+
+/// Helper for reading primitive types from bytes.
+class SummaryDataReader {
+ final Uint8List bytes;
+ int offset = 0;
+
+ _StringTable _stringTable;
+
+ final Float64List _doubleBuffer = Float64List(1);
+ Uint8List _doubleBufferUint8;
+
+ SummaryDataReader(this.bytes);
+
+ void createStringTable(int offset) {
+ _stringTable = _StringTable(bytes: bytes, startOffset: offset);
+ }
+
+ @pragma("vm:prefer-inline")
+ int readByte() {
+ return bytes[offset++];
+ }
+
+ double readDouble() {
+ _doubleBufferUint8 ??= _doubleBuffer.buffer.asUint8List();
+ _doubleBufferUint8[0] = readByte();
+ _doubleBufferUint8[1] = readByte();
+ _doubleBufferUint8[2] = readByte();
+ _doubleBufferUint8[3] = readByte();
+ _doubleBufferUint8[4] = readByte();
+ _doubleBufferUint8[5] = readByte();
+ _doubleBufferUint8[6] = readByte();
+ _doubleBufferUint8[7] = readByte();
+ return _doubleBuffer[0];
+ }
+
+ String readStringReference() {
+ return _stringTable[readUInt30()];
+ }
+
+ String readStringUtf8() {
+ var bytes = readUint8List();
+ return utf8.decode(bytes);
+ }
+
+ int readUInt30() {
+ var byte = readByte();
+ if (byte & 0x80 == 0) {
+ // 0xxxxxxx
+ return byte;
+ } else if (byte & 0x40 == 0) {
+ // 10xxxxxx
+ return ((byte & 0x3F) << 8) | readByte();
+ } else {
+ // 11xxxxxx
+ return ((byte & 0x3F) << 24) |
+ (readByte() << 16) |
+ (readByte() << 8) |
+ readByte();
+ }
+ }
+
+ Uint32List readUint30List() {
+ var length = readUInt30();
+ var result = Uint32List(length);
+ for (var i = 0; i < length; ++i) {
+ result[i] = readUInt30();
+ }
+ return result;
+ }
+
+ int readUint32() {
+ return (readByte() << 24) |
+ (readByte() << 16) |
+ (readByte() << 8) |
+ readByte();
+ }
+
+ Uint32List readUint32List() {
+ var length = readUint32();
+ var result = Uint32List(length);
+ for (var i = 0; i < length; ++i) {
+ result[i] = readUint32();
+ }
+ return result;
+ }
+
+ Uint8List readUint8List() {
+ var length = readUInt30();
+ var result = Uint8List.sublistView(bytes, offset, offset + length);
+ offset += length;
+ return result;
+ }
+
+ String stringOfIndex(int index) {
+ return _stringTable[index];
+ }
+}
+
+class _StringTable {
+ final Uint8List _bytes;
+ int _byteOffset;
+
+ Uint32List _offsets;
+ Uint32List _lengths;
+ List<String> _strings;
+
+ /// The structure of the table:
+ /// <bytes with encoded strings>
+ /// <the length of the bytes> <-- [startOffset]
+ /// <the number strings>
+ /// <the array of lengths of individual strings>
+ _StringTable({
+ @required Uint8List bytes,
+ @required int startOffset,
+ }) : _bytes = bytes {
+ _byteOffset = startOffset;
+
+ var offset = startOffset - _readUInt();
+ var length = _readUInt();
+
+ _offsets = Uint32List(length);
+ _lengths = Uint32List(length);
+ for (var i = 0; i < length; i++) {
+ var stringLength = _readUInt();
+ _offsets[i] = offset;
+ _lengths[i] = stringLength;
+ offset += stringLength;
+ }
+
+ _strings = List.filled(length, null, growable: false);
+ }
+
+ String operator [](int index) {
+ var result = _strings[index];
+
+ if (result == null) {
+ result = _readStringEntry(_offsets[index], _lengths[index]);
+ _strings[index] = result;
+ }
+
+ return result;
+ }
+
+ int _readByte() {
+ return _bytes[_byteOffset++];
+ }
+
+ String _readStringEntry(int start, int numBytes) {
+ var end = start + numBytes;
+ for (var i = start; i < end; i++) {
+ if (_bytes[i] > 127) {
+ return _decodeWtf8(_bytes, start, end);
+ }
+ }
+ return String.fromCharCodes(_bytes, start, end);
+ }
+
+ int _readUInt() {
+ var byte = _readByte();
+ if (byte & 0x80 == 0) {
+ // 0xxxxxxx
+ return byte;
+ } else if (byte & 0x40 == 0) {
+ // 10xxxxxx
+ return ((byte & 0x3F) << 8) | _readByte();
+ } else {
+ // 11xxxxxx
+ return ((byte & 0x3F) << 24) |
+ (_readByte() << 16) |
+ (_readByte() << 8) |
+ _readByte();
+ }
+ }
+
+ static String _decodeWtf8(Uint8List _bytes, int start, int end) {
+ // WTF-8 decoder that trusts its input, meaning that the correctness of
+ // the code depends on the bytes from start to end being valid and
+ // complete WTF-8. Instead of masking off the control bits from every
+ // byte, it simply xor's the byte values together at their appropriate
+ // bit shifts, and then xor's out all of the control bits at once.
+ Uint16List charCodes = Uint16List(end - start);
+ int i = start;
+ int j = 0;
+ while (i < end) {
+ int byte = _bytes[i++];
+ if (byte < 0x80) {
+ // ASCII.
+ charCodes[j++] = byte;
+ } else if (byte < 0xE0) {
+ // Two-byte sequence (11-bit unicode value).
+ int byte2 = _bytes[i++];
+ int value = (byte << 6) ^ byte2 ^ 0x3080;
+ assert(value >= 0x80 && value < 0x800);
+ charCodes[j++] = value;
+ } else if (byte < 0xF0) {
+ // Three-byte sequence (16-bit unicode value).
+ int byte2 = _bytes[i++];
+ int byte3 = _bytes[i++];
+ int value = (byte << 12) ^ (byte2 << 6) ^ byte3 ^ 0xE2080;
+ assert(value >= 0x800 && value < 0x10000);
+ charCodes[j++] = value;
+ } else {
+ // Four-byte sequence (non-BMP unicode value).
+ int byte2 = _bytes[i++];
+ int byte3 = _bytes[i++];
+ int byte4 = _bytes[i++];
+ int value =
+ (byte << 18) ^ (byte2 << 12) ^ (byte3 << 6) ^ byte4 ^ 0x3C82080;
+ assert(value >= 0x10000 && value < 0x110000);
+ charCodes[j++] = 0xD7C0 + (value >> 10);
+ charCodes[j++] = 0xDC00 + (value & 0x3FF);
+ }
+ }
+ assert(i == end);
+ return String.fromCharCodes(charCodes, 0, j);
+ }
+}
diff --git a/pkg/analyzer/lib/src/summary2/data_writer.dart b/pkg/analyzer/lib/src/summary2/data_writer.dart
new file mode 100644
index 0000000..5428e5b
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/data_writer.dart
@@ -0,0 +1,173 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+import 'dart:typed_data';
+
+/// Puts a buffer in front of a [Sink<List<int>>].
+class BufferedSink {
+ static const int SIZE = 100000;
+ static const int SAFE_SIZE = SIZE - 5;
+ static const int SMALL = 10000;
+
+ final Sink<List<int>> _sink;
+
+ int flushedLength = 0;
+
+ Uint8List _buffer = Uint8List(SIZE);
+ int length = 0;
+
+ final Float64List _doubleBuffer = Float64List(1);
+ Uint8List _doubleBufferUint8;
+
+ BufferedSink(this._sink);
+
+ int get offset => flushedLength + length;
+
+ @pragma("vm:prefer-inline")
+ void addByte(int byte) {
+ _buffer[length++] = byte;
+ if (length == SIZE) {
+ _sink.add(_buffer);
+ _buffer = Uint8List(SIZE);
+ length = 0;
+ flushedLength += SIZE;
+ }
+ }
+
+ @pragma("vm:prefer-inline")
+ void addByte2(int byte1, int byte2) {
+ if (length < SAFE_SIZE) {
+ _buffer[length++] = byte1;
+ _buffer[length++] = byte2;
+ } else {
+ addByte(byte1);
+ addByte(byte2);
+ }
+ }
+
+ @pragma("vm:prefer-inline")
+ void addByte4(int byte1, int byte2, int byte3, int byte4) {
+ if (length < SAFE_SIZE) {
+ _buffer[length++] = byte1;
+ _buffer[length++] = byte2;
+ _buffer[length++] = byte3;
+ _buffer[length++] = byte4;
+ } else {
+ addByte(byte1);
+ addByte(byte2);
+ addByte(byte3);
+ addByte(byte4);
+ }
+ }
+
+ void addBytes(Uint8List bytes) {
+ // Avoid copying a large buffer into the another large buffer. Also, if
+ // the bytes buffer is too large to fit in our own buffer, just emit both.
+ if (length + bytes.length < SIZE &&
+ (bytes.length < SMALL || length < SMALL)) {
+ _buffer.setRange(length, length + bytes.length, bytes);
+ length += bytes.length;
+ } else if (bytes.length < SMALL) {
+ // Flush as much as we can in the current buffer.
+ _buffer.setRange(length, SIZE, bytes);
+ _sink.add(_buffer);
+ // Copy over the remainder into a new buffer. It is guaranteed to fit
+ // because the input byte array is small.
+ int alreadyEmitted = SIZE - length;
+ int remainder = bytes.length - alreadyEmitted;
+ _buffer = Uint8List(SIZE);
+ _buffer.setRange(0, remainder, bytes, alreadyEmitted);
+ length = remainder;
+ flushedLength += SIZE;
+ } else {
+ flush();
+ _sink.add(bytes);
+ flushedLength += bytes.length;
+ }
+ }
+
+ void addDouble(double value) {
+ _doubleBufferUint8 ??= _doubleBuffer.buffer.asUint8List();
+ _doubleBuffer[0] = value;
+ addByte4(_doubleBufferUint8[0], _doubleBufferUint8[1],
+ _doubleBufferUint8[2], _doubleBufferUint8[3]);
+ addByte4(_doubleBufferUint8[4], _doubleBufferUint8[5],
+ _doubleBufferUint8[6], _doubleBufferUint8[7]);
+ }
+
+ void flush() {
+ _sink.add(_buffer.sublist(0, length));
+ _buffer = Uint8List(SIZE);
+ flushedLength += length;
+ length = 0;
+ }
+
+ void flushAndDestroy() {
+ _sink.add(_buffer.sublist(0, length));
+ }
+
+ @pragma("vm:prefer-inline")
+ void writeByte(int byte) {
+ assert((byte & 0xFF) == byte);
+ addByte(byte);
+ }
+
+ void writeList<T>(List<T> items, void Function(T x) writeItem) {
+ writeUInt30(items.length);
+ for (var i = 0; i < items.length; i++) {
+ writeItem(items[i]);
+ }
+ }
+
+ /// Write the [value] as UTF8 encoded byte array.
+ void writeStringUtf8(String value) {
+ var bytes = utf8.encode(value);
+ writeUint8List(bytes);
+ }
+
+ @pragma("vm:prefer-inline")
+ void writeUInt30(int value) {
+ assert(value >= 0 && value >> 30 == 0);
+ if (value < 0x80) {
+ addByte(value);
+ } else if (value < 0x4000) {
+ addByte2((value >> 8) | 0x80, value & 0xFF);
+ } else {
+ addByte4((value >> 24) | 0xC0, (value >> 16) & 0xFF, (value >> 8) & 0xFF,
+ value & 0xFF);
+ }
+ }
+
+ void writeUint30List(List<int> values) {
+ var length = values.length;
+ writeUInt30(length);
+ for (var i = 0; i < length; i++) {
+ writeUInt30(values[i]);
+ }
+ }
+
+ void writeUInt32(int value) {
+ addByte4((value >> 24) & 0xFF, (value >> 16) & 0xFF, (value >> 8) & 0xFF,
+ value & 0xFF);
+ }
+
+ void writeUint8List(Uint8List bytes) {
+ writeUInt30(bytes.length);
+ addBytes(bytes);
+ }
+}
+
+/// A [Sink] that directly writes data into a byte builder.
+class ByteSink implements Sink<List<int>> {
+ final BytesBuilder builder = BytesBuilder(copy: false);
+
+ @override
+ void add(List<int> data) {
+ builder.add(data);
+ }
+
+ @override
+ void close() {}
+}
diff --git a/pkg/analyzer/lib/src/summary2/default_types_builder.dart b/pkg/analyzer/lib/src/summary2/default_types_builder.dart
index 4a8d0c5..ad8c510 100644
--- a/pkg/analyzer/lib/src/summary2/default_types_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/default_types_builder.dart
@@ -10,7 +10,6 @@
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/resolver/variance.dart';
import 'package:analyzer/src/summary2/function_type_builder.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
import 'package:analyzer/src/summary2/named_type_builder.dart';
import 'package:analyzer/src/summary2/type_builder.dart';
import 'package:analyzer/src/util/graph.dart';
@@ -137,10 +136,11 @@
if (parameterList == null) return;
for (var parameter in parameterList.typeParameters) {
- var defaultType = LazyAst.getDefaultType(parameter);
+ var element = parameter.declaredElement as TypeParameterElementImpl;
+ var defaultType = element.defaultType;
if (defaultType is TypeBuilder) {
var builtType = defaultType.build();
- LazyAst.setDefaultType(parameter, builtType);
+ element.defaultType = builtType;
}
}
}
@@ -211,7 +211,8 @@
// Set computed TypeBuilder(s) as default types.
for (var i = 0; i < length; i++) {
- LazyAst.setDefaultType(nodes[i], bounds[i]);
+ var element = nodes[i].declaredElement as TypeParameterElementImpl;
+ element.defaultType = bounds[i];
}
}
@@ -235,6 +236,7 @@
void recurseParameters(List<TypeParameterElement> parameters) {
for (TypeParameterElementImpl parameter in parameters) {
TypeParameter parameterNode = parameter.linkedNode;
+ // TODO(scheglov) How to we skip already linked?
var bound = parameterNode.bound;
if (bound != null) {
var tails = _findRawTypePathsToDeclaration(
diff --git a/pkg/analyzer/lib/src/summary2/function_type_builder.dart b/pkg/analyzer/lib/src/summary2/function_type_builder.dart
index a4c8987..4fd730d 100644
--- a/pkg/analyzer/lib/src/summary2/function_type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/function_type_builder.dart
@@ -12,7 +12,6 @@
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_visitor.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
import 'package:analyzer/src/summary2/type_builder.dart';
/// The type builder for a [GenericFunctionType].
@@ -97,7 +96,6 @@
if (node != null) {
node.type = _type;
- LazyAst.setReturnType(node, builtReturnType ?? _dynamicType);
}
return _type;
diff --git a/pkg/analyzer/lib/src/summary2/informative_data.dart b/pkg/analyzer/lib/src/summary2/informative_data.dart
deleted file mode 100644
index acb0fa8..0000000
--- a/pkg/analyzer/lib/src/summary2/informative_data.dart
+++ /dev/null
@@ -1,436 +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/ast/ast.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/src/summary/format.dart';
-
-/// Create informative data for nodes that need it, and set IDs of this
-/// data to the nodes.
-List<UnlinkedInformativeDataBuilder> createInformativeData(
- CompilationUnit unit) {
- var visitor = _SetInformativeId();
- unit.accept(visitor);
- return visitor.dataList;
-}
-
-/// If [createInformativeData] set the informative data identifier for the
-/// [node], return it, otherwise return zero.
-int getInformativeId(AstNode node) {
- int id = node.getProperty(_SetInformativeId.ID);
- return id ?? 0;
-}
-
-class _SetInformativeId extends SimpleAstVisitor<void> {
- static final String ID = 'informativeId';
-
- final List<UnlinkedInformativeDataBuilder> dataList = [];
-
- void setData(AstNode node, UnlinkedInformativeDataBuilder data) {
- var id = 1 + dataList.length;
- node.setProperty(ID, id);
- dataList.add(data);
- }
-
- @override
- void visitClassDeclaration(ClassDeclaration node) {
- setData(
- node,
- UnlinkedInformativeDataBuilder.classDeclaration(
- codeOffset: node.offset,
- codeLength: node.length,
- documentationComment_tokens: _nodeCommentTokens(node),
- nameOffset: node.name.offset,
- ),
- );
-
- node.typeParameters?.accept(this);
- node.members.accept(this);
- }
-
- @override
- void visitClassTypeAlias(ClassTypeAlias node) {
- setData(
- node,
- UnlinkedInformativeDataBuilder.classTypeAlias(
- codeOffset: node.offset,
- codeLength: node.length,
- documentationComment_tokens: _nodeCommentTokens(node),
- nameOffset: node.name.offset,
- ),
- );
-
- node.typeParameters?.accept(this);
- }
-
- @override
- void visitCompilationUnit(CompilationUnit node) {
- setData(
- node,
- UnlinkedInformativeDataBuilder.compilationUnit(
- codeOffset: node.offset,
- codeLength: node.length,
- compilationUnit_lineStarts: node.lineInfo.lineStarts,
- ),
- );
-
- node.directives.accept(this);
- node.declarations.accept(this);
- }
-
- @override
- void visitConstructorDeclaration(ConstructorDeclaration node) {
- setData(
- node,
- UnlinkedInformativeDataBuilder.constructorDeclaration(
- codeOffset: node.offset,
- codeLength: node.length,
- documentationComment_tokens: _nodeCommentTokens(node),
- nameOffset: node.name?.offset ?? 0,
- constructorDeclaration_periodOffset: node.period?.offset ?? 0,
- constructorDeclaration_returnTypeOffset: node.returnType.offset,
- ),
- );
-
- node.parameters?.accept(this);
- }
-
- @override
- void visitDefaultFormalParameter(DefaultFormalParameter node) {
- var defaultValueCode = node.defaultValue?.toSource();
- setData(
- node,
- UnlinkedInformativeDataBuilder.defaultFormalParameter(
- codeOffset: node.offset,
- codeLength: node.length,
- defaultFormalParameter_defaultValueCode: defaultValueCode,
- ),
- );
-
- node.parameter.accept(this);
- }
-
- @override
- void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
- setData(
- node,
- UnlinkedInformativeDataBuilder.enumConstantDeclaration(
- codeOffset: node.offset,
- codeLength: node.length,
- documentationComment_tokens: _nodeCommentTokens(node),
- nameOffset: node.name.offset,
- ),
- );
- }
-
- @override
- void visitEnumDeclaration(EnumDeclaration node) {
- setData(
- node,
- UnlinkedInformativeDataBuilder.enumDeclaration(
- codeOffset: node.offset,
- codeLength: node.length,
- documentationComment_tokens: _nodeCommentTokens(node),
- nameOffset: node.name.offset,
- ),
- );
-
- node.constants.accept(this);
- }
-
- @override
- void visitExportDirective(ExportDirective node) {
- setData(
- node,
- UnlinkedInformativeDataBuilder.exportDirective(
- directiveKeywordOffset: node.keyword.offset,
- ),
- );
- node.combinators.accept(this);
- }
-
- @override
- void visitExtensionDeclaration(ExtensionDeclaration node) {
- setData(
- node,
- UnlinkedInformativeDataBuilder.extensionDeclaration(
- codeOffset: node.offset,
- codeLength: node.length,
- documentationComment_tokens: _nodeCommentTokens(node),
- nameOffset: node.name?.offset ?? 0,
- ),
- );
-
- node.typeParameters?.accept(this);
- node.members.accept(this);
- }
-
- @override
- void visitFieldDeclaration(FieldDeclaration node) {
- setData(
- node,
- UnlinkedInformativeDataBuilder.fieldDeclaration(
- documentationComment_tokens: _nodeCommentTokens(node),
- ),
- );
-
- node.fields.accept(this);
- }
-
- @override
- void visitFieldFormalParameter(FieldFormalParameter node) {
- setData(
- node,
- UnlinkedInformativeDataBuilder.fieldFormalParameter(
- codeOffset: node.offset,
- codeLength: node.length,
- nameOffset: node.identifier.offset,
- ),
- );
- }
-
- @override
- void visitFormalParameterList(FormalParameterList node) {
- node.parameters.accept(this);
- }
-
- @override
- void visitFunctionDeclaration(FunctionDeclaration node) {
- setData(
- node,
- UnlinkedInformativeDataBuilder.functionDeclaration(
- codeOffset: node.offset,
- codeLength: node.length,
- documentationComment_tokens: _nodeCommentTokens(node),
- nameOffset: node.name.offset,
- ),
- );
-
- node.functionExpression.accept(this);
- }
-
- @override
- void visitFunctionExpression(FunctionExpression node) {
- node.typeParameters?.accept(this);
- node.parameters?.accept(this);
- }
-
- @override
- void visitFunctionTypeAlias(FunctionTypeAlias node) {
- setData(
- node,
- UnlinkedInformativeDataBuilder.functionTypeAlias(
- codeOffset: node.offset,
- codeLength: node.length,
- documentationComment_tokens: _nodeCommentTokens(node),
- nameOffset: node.name.offset,
- ),
- );
-
- node.typeParameters?.accept(this);
- node.parameters.accept(this);
- }
-
- @override
- void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
- setData(
- node,
- UnlinkedInformativeDataBuilder.functionTypedFormalParameter(
- codeOffset: node.offset,
- codeLength: node.length,
- nameOffset: node.identifier.offset,
- ),
- );
- }
-
- @override
- void visitGenericFunctionType(GenericFunctionType node) {
- node.typeParameters?.accept(this);
- node.parameters.accept(this);
- }
-
- @override
- void visitGenericTypeAlias(GenericTypeAlias node) {
- setData(
- node,
- UnlinkedInformativeDataBuilder.genericTypeAlias(
- codeOffset: node.offset,
- codeLength: node.length,
- documentationComment_tokens: _nodeCommentTokens(node),
- nameOffset: node.name.offset,
- ),
- );
-
- node.typeParameters?.accept(this);
- node.type?.accept(this);
- }
-
- @override
- void visitHideCombinator(HideCombinator node) {
- setData(
- node,
- UnlinkedInformativeDataBuilder.hideCombinator(
- combinatorEnd: node.end,
- combinatorKeywordOffset: node.offset,
- ),
- );
- }
-
- @override
- void visitImportDirective(ImportDirective node) {
- setData(
- node,
- UnlinkedInformativeDataBuilder.importDirective(
- directiveKeywordOffset: node.keyword.offset,
- importDirective_prefixOffset: node.prefix?.offset ?? 0,
- ),
- );
- node.combinators.accept(this);
- }
-
- @override
- void visitLibraryDirective(LibraryDirective node) {
- setData(
- node,
- UnlinkedInformativeDataBuilder.libraryDirective(
- documentationComment_tokens: _nodeCommentTokens(node),
- ),
- );
- }
-
- @override
- void visitMethodDeclaration(MethodDeclaration node) {
- setData(
- node,
- UnlinkedInformativeDataBuilder.methodDeclaration(
- codeOffset: node.offset,
- codeLength: node.length,
- documentationComment_tokens: _nodeCommentTokens(node),
- nameOffset: node.name.offset,
- ),
- );
-
- node.typeParameters?.accept(this);
- node.parameters?.accept(this);
- }
-
- @override
- void visitMixinDeclaration(MixinDeclaration node) {
- setData(
- node,
- UnlinkedInformativeDataBuilder.mixinDeclaration(
- codeOffset: node.offset,
- codeLength: node.length,
- documentationComment_tokens: _nodeCommentTokens(node),
- nameOffset: node.name.offset,
- ),
- );
-
- node.typeParameters?.accept(this);
- node.members.accept(this);
- }
-
- @override
- void visitPartDirective(PartDirective node) {
- setData(
- node,
- UnlinkedInformativeDataBuilder.partDirective(
- directiveKeywordOffset: node.keyword.offset,
- ),
- );
- }
-
- @override
- void visitPartOfDirective(PartOfDirective node) {
- setData(
- node,
- UnlinkedInformativeDataBuilder.partDirective(
- directiveKeywordOffset: node.keyword.offset,
- ),
- );
- }
-
- @override
- void visitShowCombinator(ShowCombinator node) {
- setData(
- node,
- UnlinkedInformativeDataBuilder.showCombinator(
- combinatorEnd: node.end,
- combinatorKeywordOffset: node.offset,
- ),
- );
- }
-
- @override
- void visitSimpleFormalParameter(SimpleFormalParameter node) {
- setData(
- node,
- UnlinkedInformativeDataBuilder.simpleFormalParameter(
- codeOffset: node.offset,
- codeLength: node.length,
- nameOffset: node.identifier?.offset ?? 0,
- ),
- );
- }
-
- @override
- void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
- setData(
- node,
- UnlinkedInformativeDataBuilder.topLevelVariableDeclaration(
- documentationComment_tokens: _nodeCommentTokens(node),
- ),
- );
-
- node.variables.accept(this);
- }
-
- @override
- void visitTypeParameter(TypeParameter node) {
- setData(
- node,
- UnlinkedInformativeDataBuilder.typeParameter(
- codeOffset: node.offset,
- codeLength: node.length,
- nameOffset: node.name.offset,
- ),
- );
- }
-
- @override
- void visitTypeParameterList(TypeParameterList node) {
- node.typeParameters.accept(this);
- }
-
- @override
- void visitVariableDeclaration(VariableDeclaration node) {
- var variableList = node.parent as VariableDeclarationList;
- var isFirst = identical(variableList.variables[0], node);
- var codeOffset = (isFirst ? variableList.parent : node).offset;
- var codeLength = node.end - codeOffset;
-
- setData(
- node,
- UnlinkedInformativeDataBuilder.variableDeclaration(
- codeOffset: codeOffset,
- codeLength: codeLength,
- nameOffset: node.name.offset,
- ),
- );
- }
-
- @override
- void visitVariableDeclarationList(VariableDeclarationList node) {
- node.variables.accept(this);
- }
-
- static List<String> _commentTokens(Comment comment) {
- if (comment == null) return null;
- return comment.tokens.map((token) => token.lexeme).toList();
- }
-
- static List<String> _nodeCommentTokens(AnnotatedNode node) {
- return _commentTokens(node.documentationComment);
- }
-}
diff --git a/pkg/analyzer/lib/src/summary2/lazy_ast.dart b/pkg/analyzer/lib/src/summary2/lazy_ast.dart
deleted file mode 100644
index dea4fa9..0000000
--- a/pkg/analyzer/lib/src/summary2/lazy_ast.dart
+++ /dev/null
@@ -1,1974 +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/ast/ast.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/resolver/variance.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary2/ast_binary_flags.dart';
-import 'package:analyzer/src/summary2/ast_binary_reader.dart';
-import 'package:analyzer/src/summary2/linked_unit_context.dart';
-import 'package:pub_semver/pub_semver.dart';
-
-/// Accessor for reading AST lazily, or read data that is stored in IDL, but
-/// cannot be stored in AST, like inferred types.
-class LazyAst {
- static const _defaultTypeKey = 'lazyAst_defaultType';
- static const _genericFunctionTypeIdKey = 'lazyAst_genericFunctionTypeId';
- static const _hasOverrideInferenceKey = 'lazyAst_hasOverrideInference';
- static const _inheritsCovariantKey = 'lazyAst_isCovariant';
- static const _isSimplyBoundedKey = 'lazyAst_simplyBounded';
- static const _isOperatorEqualParameterTypeFromObjectKey =
- 'lazyAst_isOperatorEqualParameterTypeFromObject';
- static const _rawFunctionTypeKey = 'lazyAst_rawFunctionType';
- static const _returnTypeKey = 'lazyAst_returnType';
- static const _typeInferenceErrorKey = 'lazyAst_typeInferenceError';
- static const _typeKey = 'lazyAst_type';
- static const _varianceKey = 'lazyAst_variance';
-
- final LinkedNode data;
-
- LazyAst(this.data);
-
- static DartType getDefaultType(TypeParameter node) {
- return node.getProperty(_defaultTypeKey);
- }
-
- static int getGenericFunctionTypeId(GenericFunctionType node) {
- return node.getProperty(_genericFunctionTypeIdKey);
- }
-
- static bool getInheritsCovariant(AstNode node) {
- return node.getProperty(_inheritsCovariantKey) ?? false;
- }
-
- static DartType getRawFunctionType(AstNode node) {
- return node.getProperty(_rawFunctionTypeKey);
- }
-
- static DartType getReturnType(AstNode node) {
- return node.getProperty(_returnTypeKey);
- }
-
- static DartType getType(AstNode node) {
- return node.getProperty(_typeKey);
- }
-
- static TopLevelInferenceError getTypeInferenceError(AstNode node) {
- return node.getProperty(_typeInferenceErrorKey);
- }
-
- static Variance getVariance(TypeParameter node) {
- return node.getProperty(_varianceKey);
- }
-
- static bool hasOperatorEqualParameterTypeFromObject(AstNode node) {
- return node.getProperty(_isOperatorEqualParameterTypeFromObjectKey) ??
- false;
- }
-
- static bool hasOverrideInferenceDone(AstNode node) {
- return node.getProperty(_hasOverrideInferenceKey) ?? false;
- }
-
- static bool isSimplyBounded(AstNode node) {
- return node.getProperty(_isSimplyBoundedKey);
- }
-
- static void setDefaultType(TypeParameter node, DartType type) {
- node.setProperty(_defaultTypeKey, type);
- }
-
- static void setGenericFunctionTypeId(GenericFunctionType node, int id) {
- node.setProperty(_genericFunctionTypeIdKey, id);
- }
-
- static void setInheritsCovariant(AstNode node, bool value) {
- node.setProperty(_inheritsCovariantKey, value);
- }
-
- static void setOperatorEqualParameterTypeFromObject(AstNode node, bool b) {
- node.setProperty(_isOperatorEqualParameterTypeFromObjectKey, b);
- }
-
- static void setOverrideInferenceDone(AstNode node) {
- node.setProperty(_hasOverrideInferenceKey, true);
- }
-
- static void setRawFunctionType(AstNode node, DartType type) {
- node.setProperty(_rawFunctionTypeKey, type);
- }
-
- static void setReturnType(AstNode node, DartType type) {
- node.setProperty(_returnTypeKey, type);
- }
-
- static void setSimplyBounded(AstNode node, bool simplyBounded) {
- node.setProperty(_isSimplyBoundedKey, simplyBounded);
- }
-
- static void setType(AstNode node, DartType type) {
- node.setProperty(_typeKey, type);
- }
-
- static void setTypeInferenceError(
- AstNode node, TopLevelInferenceError error) {
- node.setProperty(_typeInferenceErrorKey, error);
- }
-
- static void setVariance(TypeParameter node, Variance variance) {
- return node.setProperty(_varianceKey, variance);
- }
-}
-
-class LazyClassDeclaration {
- static const _key = 'lazyAst';
-
- final LinkedNode data;
-
- bool _hasDocumentationComment = false;
- bool _hasExtendsClause = false;
- bool _hasImplementsClause = false;
- bool _hasMembers = false;
- bool _hasMetadata = false;
- bool _hasWithClause = false;
-
- LazyClassDeclaration(this.data);
-
- static LazyClassDeclaration get(ClassDeclaration node) {
- return node.getProperty(_key);
- }
-
- static int getCodeLength(
- LinkedUnitContext context,
- ClassDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null) {
- return context.getInformativeData(lazy.data)?.codeLength ?? 0;
- }
- return node.length;
- }
-
- static int getCodeOffset(
- LinkedUnitContext context,
- ClassDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null) {
- return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
- }
- return node.offset;
- }
-
- static void readDocumentationComment(
- LinkedUnitContext context,
- ClassDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasDocumentationComment) {
- node.documentationComment = context.createComment(lazy.data);
- lazy._hasDocumentationComment = true;
- }
- }
-
- static void readExtendsClause(
- AstBinaryReader reader,
- ClassDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasExtendsClause) {
- node.extendsClause = reader.readNode(
- lazy.data.classDeclaration_extendsClause,
- );
- lazy._hasExtendsClause = true;
- }
- }
-
- static void readImplementsClause(
- AstBinaryReader reader,
- ClassDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasImplementsClause) {
- node.implementsClause = reader.readNode(
- lazy.data.classOrMixinDeclaration_implementsClause,
- );
- lazy._hasImplementsClause = true;
- }
- }
-
- static void readMembers(
- AstBinaryReader reader,
- ClassDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasMembers) {
- var dataList = lazy.data.classOrMixinDeclaration_members;
- for (var i = 0; i < dataList.length; ++i) {
- var data = dataList[i];
- node.members[i] = reader.readNode(data);
- }
- lazy._hasMembers = true;
- }
- }
-
- static void readMetadata(
- AstBinaryReader reader,
- ClassDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasMetadata) {
- var dataList = lazy.data.annotatedNode_metadata;
- for (var i = 0; i < dataList.length; ++i) {
- var data = dataList[i];
- node.metadata[i] = reader.readNode(data);
- }
- lazy._hasMetadata = true;
- }
- }
-
- static void readWithClause(
- AstBinaryReader reader,
- ClassDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasWithClause) {
- node.withClause = reader.readNode(
- lazy.data.classDeclaration_withClause,
- );
- lazy._hasWithClause = true;
- }
- }
-
- static void setData(ClassDeclaration node, LinkedNode data) {
- node.setProperty(_key, LazyClassDeclaration(data));
- LazyAst.setSimplyBounded(node, data.simplyBoundable_isSimplyBounded);
- }
-}
-
-class LazyClassTypeAlias {
- static const _key = 'lazyAst';
-
- final LinkedNode data;
-
- bool _hasDocumentationComment = false;
- bool _hasImplementsClause = false;
- bool _hasMetadata = false;
- bool _hasSuperclass = false;
- bool _hasWithClause = false;
-
- LazyClassTypeAlias(this.data);
-
- static LazyClassTypeAlias get(ClassTypeAlias node) {
- return node.getProperty(_key);
- }
-
- static int getCodeLength(
- LinkedUnitContext context,
- ClassTypeAlias node,
- ) {
- var lazy = get(node);
- if (lazy != null) {
- return context.getInformativeData(lazy.data)?.codeLength ?? 0;
- }
- return node.length;
- }
-
- static int getCodeOffset(
- LinkedUnitContext context,
- ClassTypeAlias node,
- ) {
- var lazy = get(node);
- if (lazy != null) {
- return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
- }
- return node.offset;
- }
-
- static void readDocumentationComment(
- LinkedUnitContext context,
- ClassTypeAlias node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasDocumentationComment) {
- node.documentationComment = context.createComment(lazy.data);
- lazy._hasDocumentationComment = true;
- }
- }
-
- static void readImplementsClause(
- AstBinaryReader reader,
- ClassTypeAlias node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasImplementsClause) {
- node.implementsClause = reader.readNode(
- lazy.data.classTypeAlias_implementsClause,
- );
- lazy._hasImplementsClause = true;
- }
- }
-
- static void readMetadata(
- AstBinaryReader reader,
- ClassTypeAlias node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasMetadata) {
- var dataList = lazy.data.annotatedNode_metadata;
- for (var i = 0; i < dataList.length; ++i) {
- var data = dataList[i];
- node.metadata[i] = reader.readNode(data);
- }
- lazy._hasMetadata = true;
- }
- }
-
- static void readSuperclass(
- AstBinaryReader reader,
- ClassTypeAlias node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasSuperclass) {
- node.superclass = reader.readNode(
- lazy.data.classTypeAlias_superclass,
- );
- lazy._hasSuperclass = true;
- }
- }
-
- static void readWithClause(
- AstBinaryReader reader,
- ClassTypeAlias node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasWithClause) {
- node.withClause = reader.readNode(
- lazy.data.classTypeAlias_withClause,
- );
- lazy._hasWithClause = true;
- }
- }
-
- static void setData(ClassTypeAlias node, LinkedNode data) {
- node.setProperty(_key, LazyClassTypeAlias(data));
- LazyAst.setSimplyBounded(node, data.simplyBoundable_isSimplyBounded);
- }
-}
-
-class LazyCombinator {
- static const _key = 'lazyAst';
-
- final LinkedNode data;
-
- LazyCombinator(Combinator node, this.data) {
- node.setProperty(_key, this);
- }
-
- static LazyCombinator get(Combinator node) {
- return node.getProperty(_key);
- }
-
- static int getEnd(
- LinkedUnitContext context,
- Combinator node,
- ) {
- var lazy = get(node);
- if (lazy != null) {
- var informativeData = context.getInformativeData(lazy.data);
- return informativeData?.combinatorEnd ?? 0;
- }
- return node.end;
- }
-}
-
-class LazyCompilationUnit {
- static const _key = 'lazyAst';
-
- final LinkedNode data;
-
- LazyCompilationUnit(CompilationUnit node, this.data) {
- node.setProperty(_key, this);
- }
-
- static LazyCompilationUnit get(CompilationUnit node) {
- return node.getProperty(_key);
- }
-
- static LibraryLanguageVersion getLanguageVersion(CompilationUnit node) {
- var lazy = get(node);
- if (lazy != null) {
- var package = lazy.data.compilationUnit_languageVersion.package;
- var override = lazy.data.compilationUnit_languageVersion.override2;
- return LibraryLanguageVersion(
- package: Version(package.major, package.minor, 0),
- override: override != null
- ? Version(override.major, override.minor, 0)
- : null,
- );
- }
- return (node as CompilationUnitImpl).languageVersion;
- }
-}
-
-class LazyConstructorDeclaration {
- static const _key = 'lazyAst';
-
- final LinkedNode data;
-
- bool _hasBody = false;
- bool _hasDocumentationComment = false;
- bool _hasFormalParameters = false;
- bool _hasInitializers = false;
- bool _hasMetadata = false;
- bool _hasRedirectedConstructor = false;
-
- LazyConstructorDeclaration(this.data);
-
- static LazyConstructorDeclaration get(ConstructorDeclaration node) {
- return node.getProperty(_key);
- }
-
- static int getCodeLength(
- LinkedUnitContext context,
- ConstructorDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null) {
- return context.getInformativeData(lazy.data)?.codeLength ?? 0;
- }
- return node.length;
- }
-
- static int getCodeOffset(
- LinkedUnitContext context,
- ConstructorDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null) {
- return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
- }
- return node.offset;
- }
-
- static void readBody(
- AstBinaryReader reader,
- ConstructorDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasBody) {
- node.body = reader.readNode(
- lazy.data.constructorDeclaration_body,
- );
- lazy._hasBody = true;
- }
- }
-
- static void readDocumentationComment(
- LinkedUnitContext context,
- ConstructorDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasDocumentationComment) {
- node.documentationComment = context.createComment(lazy.data);
- lazy._hasDocumentationComment = true;
- }
- }
-
- static void readFormalParameters(
- AstBinaryReader reader,
- ConstructorDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasFormalParameters) {
- node.parameters = reader.readNode(
- lazy.data.constructorDeclaration_parameters,
- );
- lazy._hasFormalParameters = true;
- }
- }
-
- static void readInitializers(
- AstBinaryReader reader,
- ConstructorDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasInitializers) {
- var dataList = lazy.data.constructorDeclaration_initializers;
- for (var i = 0; i < dataList.length; ++i) {
- var data = dataList[i];
- node.initializers[i] = reader.readNode(data);
- }
- lazy._hasInitializers = true;
- }
- }
-
- static void readMetadata(
- AstBinaryReader reader,
- ConstructorDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasMetadata) {
- var dataList = lazy.data.annotatedNode_metadata;
- for (var i = 0; i < dataList.length; ++i) {
- var data = dataList[i];
- node.metadata[i] = reader.readNode(data);
- }
- lazy._hasMetadata = true;
- }
- }
-
- static void readRedirectedConstructor(
- AstBinaryReader reader,
- ConstructorDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasRedirectedConstructor) {
- node.redirectedConstructor = reader.readNode(
- lazy.data.constructorDeclaration_redirectedConstructor,
- );
- lazy._hasRedirectedConstructor = true;
- }
- }
-
- static void setData(ConstructorDeclaration node, LinkedNode data) {
- node.setProperty(_key, LazyConstructorDeclaration(data));
- }
-}
-
-class LazyDirective {
- static const _key = 'lazyAst';
- static const _uriKey = 'lazyAst_selectedUri';
-
- final LinkedNode data;
-
- bool _hasMetadata = false;
-
- LazyDirective(this.data);
-
- static LazyDirective get(Directive node) {
- return node.getProperty(_key);
- }
-
- static String getSelectedUri(UriBasedDirective node) {
- return node.getProperty(_uriKey);
- }
-
- static void readMetadata(AstBinaryReader reader, Directive node) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasMetadata) {
- var dataList = lazy.data.annotatedNode_metadata;
- for (var i = 0; i < dataList.length; ++i) {
- var data = dataList[i];
- node.metadata[i] = reader.readNode(data);
- }
- lazy._hasMetadata = true;
- }
- }
-
- static void setData(Directive node, LinkedNode data) {
- node.setProperty(_key, LazyDirective(data));
- if (node is NamespaceDirective) {
- node.setProperty(_uriKey, data.namespaceDirective_selectedUri);
- }
- }
-
- static void setSelectedUri(UriBasedDirective node, String uriStr) {
- node.setProperty(_uriKey, uriStr);
- }
-}
-
-class LazyEnumConstantDeclaration {
- static const _key = 'lazyAst';
-
- final LinkedNode data;
-
- bool _hasDocumentationComment = false;
- bool _hasMetadata = false;
-
- LazyEnumConstantDeclaration(this.data);
-
- static LazyEnumConstantDeclaration get(EnumConstantDeclaration node) {
- return node.getProperty(_key);
- }
-
- static int getCodeLength(
- LinkedUnitContext context,
- EnumConstantDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null) {
- return context.getInformativeData(lazy.data)?.codeLength ?? 0;
- }
- return node.length;
- }
-
- static int getCodeOffset(
- LinkedUnitContext context,
- EnumConstantDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null) {
- return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
- }
- return node.offset;
- }
-
- static void readDocumentationComment(
- LinkedUnitContext context,
- EnumConstantDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasDocumentationComment) {
- node.documentationComment = context.createComment(lazy.data);
- lazy._hasDocumentationComment = true;
- }
- }
-
- static void readMetadata(
- AstBinaryReader reader,
- EnumConstantDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasMetadata) {
- var dataList = lazy.data.annotatedNode_metadata;
- for (var i = 0; i < dataList.length; ++i) {
- var data = dataList[i];
- node.metadata[i] = reader.readNode(data);
- }
- lazy._hasMetadata = true;
- }
- }
-
- static void setData(EnumConstantDeclaration node, LinkedNode data) {
- node.setProperty(_key, LazyEnumConstantDeclaration(data));
- }
-}
-
-class LazyEnumDeclaration {
- static const _key = 'lazyAst';
-
- final LinkedNode data;
-
- bool _hasConstants = false;
- bool _hasDocumentationComment = false;
- bool _hasMetadata = false;
-
- LazyEnumDeclaration(this.data);
-
- static LazyEnumDeclaration get(EnumDeclaration node) {
- return node.getProperty(_key);
- }
-
- static int getCodeLength(
- LinkedUnitContext context,
- EnumDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null) {
- return context.getInformativeData(lazy.data)?.codeLength ?? 0;
- }
- return node.length;
- }
-
- static int getCodeOffset(
- LinkedUnitContext context,
- EnumDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null) {
- return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
- }
- return node.offset;
- }
-
- static void readConstants(
- AstBinaryReader reader,
- EnumDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasConstants) {
- var dataList = lazy.data.enumDeclaration_constants;
- for (var i = 0; i < dataList.length; ++i) {
- var data = dataList[i];
- node.constants[i] = reader.readNode(data);
- }
- lazy._hasConstants = true;
- }
- }
-
- static void readDocumentationComment(
- LinkedUnitContext context,
- EnumDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasDocumentationComment) {
- node.documentationComment = context.createComment(lazy.data);
- lazy._hasDocumentationComment = true;
- }
- }
-
- static void readMetadata(
- AstBinaryReader reader,
- EnumDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasMetadata) {
- var dataList = lazy.data.annotatedNode_metadata;
- for (var i = 0; i < dataList.length; ++i) {
- var data = dataList[i];
- node.metadata[i] = reader.readNode(data);
- }
- lazy._hasMetadata = true;
- }
- }
-
- static void setData(EnumDeclaration node, LinkedNode data) {
- node.setProperty(_key, LazyEnumDeclaration(data));
- }
-}
-
-class LazyExtensionDeclaration {
- static const _key = 'lazyAst';
-
- final LinkedNode data;
-
- bool _hasDocumentationComment = false;
- bool _hasExtendedType = false;
- bool _hasMembers = false;
- bool _hasMetadata = false;
-
- /// The name for use in `Reference`. If the extension is named, the name
- /// of the extension. If the extension is unnamed, a synthetic name.
- String _refName;
-
- LazyExtensionDeclaration(ExtensionDeclaration node, this.data) {
- node.setProperty(_key, this);
- if (data != null) {
- _refName = data.extensionDeclaration_refName;
- }
- }
-
- String get refName => _refName;
-
- void put(LinkedNodeBuilder builder) {
- assert(_refName != null);
- builder.extensionDeclaration_refName = _refName;
- }
-
- void setRefName(String referenceName) {
- _refName = referenceName;
- }
-
- static LazyExtensionDeclaration get(ExtensionDeclaration node) {
- LazyExtensionDeclaration lazy = node.getProperty(_key);
- if (lazy == null) {
- return LazyExtensionDeclaration(node, null);
- }
- return lazy;
- }
-
- static int getCodeLength(
- LinkedUnitContext context,
- ExtensionDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy?.data != null) {
- return context.getInformativeData(lazy.data)?.codeLength ?? 0;
- }
- return node.length;
- }
-
- static int getCodeOffset(
- LinkedUnitContext context,
- ExtensionDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy?.data != null) {
- return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
- }
- return node.offset;
- }
-
- static void readDocumentationComment(
- LinkedUnitContext context,
- ExtensionDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy?.data != null && !lazy._hasDocumentationComment) {
- node.documentationComment = context.createComment(lazy.data);
- lazy._hasDocumentationComment = true;
- }
- }
-
- static void readExtendedType(
- AstBinaryReader reader,
- ExtensionDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy?.data != null && !lazy._hasExtendedType) {
- (node as ExtensionDeclarationImpl).extendedType = reader.readNode(
- lazy.data.extensionDeclaration_extendedType,
- );
- lazy._hasExtendedType = true;
- }
- }
-
- static void readMembers(
- AstBinaryReader reader,
- ExtensionDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy?.data != null && !lazy._hasMembers) {
- var dataList = lazy.data.extensionDeclaration_members;
- for (var i = 0; i < dataList.length; ++i) {
- var data = dataList[i];
- node.members[i] = reader.readNode(data);
- }
- lazy._hasMembers = true;
- }
- }
-
- static void readMetadata(
- AstBinaryReader reader,
- ExtensionDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy?.data != null && !lazy._hasMetadata) {
- var dataList = lazy.data.annotatedNode_metadata;
- for (var i = 0; i < dataList.length; ++i) {
- var data = dataList[i];
- node.metadata[i] = reader.readNode(data);
- }
- lazy._hasMetadata = true;
- }
- }
-}
-
-class LazyFieldDeclaration {
- static const _key = 'lazyAst';
-
- final LinkedNode data;
-
- bool _hasDocumentationComment = false;
- bool _hasMetadata = false;
-
- LazyFieldDeclaration(this.data);
-
- static LazyFieldDeclaration get(FieldDeclaration node) {
- return node.getProperty(_key);
- }
-
- static void readDocumentationComment(
- LinkedUnitContext context,
- FieldDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasDocumentationComment) {
- node.documentationComment = context.createComment(lazy.data);
- lazy._hasDocumentationComment = true;
- }
- }
-
- static void readMetadata(
- AstBinaryReader reader,
- FieldDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasMetadata) {
- var dataList = lazy.data.annotatedNode_metadata;
- for (var i = 0; i < dataList.length; ++i) {
- var data = dataList[i];
- node.metadata[i] = reader.readNode(data);
- }
- lazy._hasMetadata = true;
- }
- }
-
- static void setData(FieldDeclaration node, LinkedNode data) {
- node.setProperty(_key, LazyFieldDeclaration(data));
- }
-}
-
-class LazyFormalParameter {
- static const _key = 'lazyAst';
-
- final LinkedNode data;
-
- bool _hasDefaultValue = false;
- bool _hasFormalParameters = false;
- bool _hasMetadata = false;
- bool _hasType = false;
- bool _hasTypeInferenceError = false;
- bool _hasTypeNode = false;
-
- LazyFormalParameter(this.data);
-
- static LazyFormalParameter get(FormalParameter node) {
- return node.getProperty(_key);
- }
-
- static int getCodeLength(
- LinkedUnitContext context,
- FormalParameter node,
- ) {
- var lazy = get(node);
- if (lazy != null) {
- return context.getInformativeData(lazy.data)?.codeLength ?? 0;
- }
- return node.length;
- }
-
- static int getCodeOffset(
- LinkedUnitContext context,
- FormalParameter node,
- ) {
- var lazy = get(node);
- if (lazy != null) {
- return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
- }
- 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,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasType) {
- var type = reader.readType(lazy.data.actualType);
- LazyAst.setType(node, type);
- lazy._hasType = true;
- }
- return LazyAst.getType(node);
- }
-
- static TopLevelInferenceError getTypeInferenceError(FormalParameter node) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasTypeInferenceError) {
- var error = lazy.data.topLevelTypeInferenceError;
- LazyAst.setTypeInferenceError(node, error);
- lazy._hasTypeInferenceError = true;
- }
- return LazyAst.getTypeInferenceError(node);
- }
-
- static bool hasDefaultValue(DefaultFormalParameter node) {
- var lazy = get(node);
- if (lazy != null) {
- return AstBinaryFlags.hasInitializer(lazy.data.flags);
- } else {
- return node.defaultValue != null;
- }
- }
-
- static void readDefaultValue(
- AstBinaryReader reader,
- DefaultFormalParameter node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasDefaultValue) {
- node.defaultValue = reader.readNode(
- lazy.data.defaultFormalParameter_defaultValue,
- );
- lazy._hasDefaultValue = true;
- }
- }
-
- static void readFormalParameters(
- AstBinaryReader reader,
- FormalParameter node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasFormalParameters) {
- if (node is FunctionTypedFormalParameter) {
- node.parameters = reader.readNode(
- lazy.data.functionTypedFormalParameter_formalParameters,
- );
- } else if (node is FieldFormalParameter) {
- node.parameters = reader.readNode(
- lazy.data.fieldFormalParameter_formalParameters,
- );
- }
- lazy._hasFormalParameters = true;
- }
- }
-
- static void readMetadata(
- AstBinaryReader reader,
- FormalParameter node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasMetadata) {
- var dataList = lazy.data.normalFormalParameter_metadata;
- for (var i = 0; i < dataList.length; ++i) {
- var data = dataList[i];
- node.metadata[i] = reader.readNode(data);
- }
- lazy._hasMetadata = true;
- }
- }
-
- static void readTypeNode(
- AstBinaryReader reader,
- FormalParameter node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasTypeNode) {
- if (node is SimpleFormalParameter) {
- node.type = reader.readNode(
- lazy.data.simpleFormalParameter_type,
- );
- }
- lazy._hasTypeNode = true;
- }
- }
-
- static void setData(FormalParameter node, LinkedNode data) {
- node.setProperty(_key, LazyFormalParameter(data));
- }
-}
-
-class LazyFunctionDeclaration {
- static const _key = 'lazyAst';
-
- final LinkedNode data;
-
- bool _hasDocumentationComment = false;
- bool _hasMetadata = false;
- bool _hasReturnType = false;
- bool _hasReturnTypeNode = false;
-
- LazyFunctionDeclaration(this.data);
-
- static LazyFunctionDeclaration get(FunctionDeclaration node) {
- return node.getProperty(_key);
- }
-
- static int getCodeLength(
- LinkedUnitContext context,
- FunctionDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null) {
- return context.getInformativeData(lazy.data)?.codeLength ?? 0;
- }
- return node.length;
- }
-
- static int getCodeOffset(
- LinkedUnitContext context,
- FunctionDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null) {
- return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
- }
- return node.offset;
- }
-
- static DartType getReturnType(
- AstBinaryReader reader,
- FunctionDeclaration node,
- ) {
- readFunctionExpression(reader, node);
-
- var lazy = get(node);
- if (lazy != null && !lazy._hasReturnType) {
- var type = reader.readType(lazy.data.actualReturnType);
- LazyAst.setReturnType(node, type);
- lazy._hasReturnType = true;
- }
-
- return LazyAst.getReturnType(node);
- }
-
- static void readDocumentationComment(
- LinkedUnitContext context,
- FunctionDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasDocumentationComment) {
- node.documentationComment = context.createComment(lazy.data);
- lazy._hasDocumentationComment = true;
- }
- }
-
- static void readFunctionExpression(
- AstBinaryReader reader,
- FunctionDeclaration node,
- ) {
- if (node.functionExpression == null) {
- var lazy = get(node);
- node.functionExpression = reader.readNode(
- lazy.data.functionDeclaration_functionExpression,
- );
- }
- }
-
- static void readMetadata(
- AstBinaryReader reader,
- FunctionDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasMetadata) {
- var dataList = lazy.data.annotatedNode_metadata;
- for (var i = 0; i < dataList.length; ++i) {
- var data = dataList[i];
- node.metadata[i] = reader.readNode(data);
- }
- lazy._hasMetadata = true;
- }
- }
-
- static void readReturnTypeNode(
- AstBinaryReader reader,
- FunctionDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasReturnTypeNode) {
- node.returnType = reader.readNode(
- lazy.data.functionDeclaration_returnType,
- );
- lazy._hasReturnTypeNode = true;
- }
- }
-
- static void setData(FunctionDeclaration node, LinkedNode data) {
- node.setProperty(_key, LazyFunctionDeclaration(data));
- }
-}
-
-class LazyFunctionExpression {
- static const _key = 'lazyAst';
-
- final LinkedNode data;
-
- bool _hasBody = false;
- bool _hasFormalParameters = false;
-
- LazyFunctionExpression(this.data);
-
- static LazyFunctionExpression get(FunctionExpression node) {
- return node.getProperty(_key);
- }
-
- static bool isAsynchronous(FunctionExpression node) {
- var lazy = get(node);
- if (lazy != null) {
- return AstBinaryFlags.isAsync(lazy.data.flags);
- } else {
- return node.body.isAsynchronous;
- }
- }
-
- static bool isGenerator(FunctionExpression node) {
- var lazy = get(node);
- if (lazy != null) {
- return AstBinaryFlags.isGenerator(lazy.data.flags);
- } else {
- return node.body.isGenerator;
- }
- }
-
- static void readBody(
- AstBinaryReader reader,
- FunctionExpression node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasBody) {
- node.body = reader.readNode(
- lazy.data.functionExpression_body,
- );
- lazy._hasBody = true;
- }
- }
-
- static void readFormalParameters(
- AstBinaryReader reader,
- FunctionExpression node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasFormalParameters) {
- node.parameters = reader.readNode(
- lazy.data.functionExpression_formalParameters,
- );
- lazy._hasFormalParameters = true;
- }
- }
-
- static void setData(FunctionExpression node, LinkedNode data) {
- node.setProperty(_key, LazyFunctionExpression(data));
- }
-}
-
-class LazyFunctionTypeAlias {
- static const _key = 'lazyAst';
- static const _hasSelfReferenceKey = 'lazyAst_hasSelfReferenceKey';
-
- final LinkedNode data;
-
- bool _hasDocumentationComment = false;
- bool _hasFormalParameters = false;
- bool _hasMetadata = false;
- bool _hasReturnType = false;
- bool _hasReturnTypeNode = false;
-
- LazyFunctionTypeAlias(this.data);
-
- static LazyFunctionTypeAlias get(FunctionTypeAlias node) {
- return node.getProperty(_key);
- }
-
- static int getCodeLength(
- LinkedUnitContext context,
- FunctionTypeAlias node,
- ) {
- var lazy = get(node);
- if (lazy != null) {
- return context.getInformativeData(lazy.data)?.codeLength ?? 0;
- }
- return node.length;
- }
-
- static int getCodeOffset(
- LinkedUnitContext context,
- FunctionTypeAlias node,
- ) {
- var lazy = get(node);
- if (lazy != null) {
- return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
- }
- return node.offset;
- }
-
- static bool getHasSelfReference(FunctionTypeAlias node) {
- return node.getProperty(_hasSelfReferenceKey);
- }
-
- static DartType getReturnType(
- AstBinaryReader reader,
- FunctionTypeAlias node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasReturnType) {
- var type = reader.readType(lazy.data.actualReturnType);
- LazyAst.setReturnType(node, type);
- lazy._hasReturnType = true;
- }
- return LazyAst.getReturnType(node);
- }
-
- static void readDocumentationComment(
- LinkedUnitContext context,
- FunctionTypeAlias node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasDocumentationComment) {
- node.documentationComment = context.createComment(lazy.data);
- lazy._hasDocumentationComment = true;
- }
- }
-
- static void readFormalParameters(
- AstBinaryReader reader,
- FunctionTypeAlias node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasFormalParameters) {
- node.parameters = reader.readNode(
- lazy.data.functionTypeAlias_formalParameters,
- );
- lazy._hasFormalParameters = true;
- }
- }
-
- static void readMetadata(
- AstBinaryReader reader,
- FunctionTypeAlias node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasMetadata) {
- var dataList = lazy.data.annotatedNode_metadata;
- for (var i = 0; i < dataList.length; ++i) {
- var data = dataList[i];
- node.metadata[i] = reader.readNode(data);
- }
- lazy._hasMetadata = true;
- }
- }
-
- static void readReturnTypeNode(
- AstBinaryReader reader,
- FunctionTypeAlias node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasReturnTypeNode) {
- node.returnType = reader.readNode(
- lazy.data.functionTypeAlias_returnType,
- );
- lazy._hasReturnTypeNode = true;
- }
- }
-
- static void setData(FunctionTypeAlias node, LinkedNode data) {
- node.setProperty(_key, LazyFunctionTypeAlias(data));
- LazyAst.setSimplyBounded(node, data.simplyBoundable_isSimplyBounded);
- }
-
- static void setHasSelfReference(FunctionTypeAlias node, bool value) {
- node.setProperty(_hasSelfReferenceKey, value);
- }
-}
-
-class LazyGenericTypeAlias {
- static const _key = 'lazyAst';
- static const _hasSelfReferenceKey = 'lazyAst_hasSelfReferenceKey';
-
- final LinkedNode data;
-
- bool _hasDocumentationComment = false;
- bool _hasFunction = false;
- bool _hasMetadata = false;
-
- LazyGenericTypeAlias(this.data);
-
- static LazyGenericTypeAlias get(GenericTypeAlias node) {
- return node.getProperty(_key);
- }
-
- static int getCodeLength(
- LinkedUnitContext context,
- GenericTypeAlias node,
- ) {
- var lazy = get(node);
- if (lazy != null) {
- return context.getInformativeData(lazy.data)?.codeLength ?? 0;
- }
- return node.length;
- }
-
- static int getCodeOffset(
- LinkedUnitContext context,
- GenericTypeAlias node,
- ) {
- var lazy = get(node);
- if (lazy != null) {
- return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
- }
- return node.offset;
- }
-
- static bool getHasSelfReference(GenericTypeAlias node) {
- return node.getProperty(_hasSelfReferenceKey);
- }
-
- static void readDocumentationComment(
- LinkedUnitContext context,
- GenericTypeAlias node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasDocumentationComment) {
- node.documentationComment = context.createComment(lazy.data);
- lazy._hasDocumentationComment = true;
- }
- }
-
- static void readFunctionType(
- AstBinaryReader reader,
- GenericTypeAlias node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasFunction) {
- node.functionType = reader.readNode(
- lazy.data.genericTypeAlias_functionType,
- );
- lazy._hasFunction = true;
- }
- }
-
- static void readMetadata(
- AstBinaryReader reader,
- GenericTypeAlias node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasMetadata) {
- var dataList = lazy.data.annotatedNode_metadata;
- for (var i = 0; i < dataList.length; ++i) {
- var data = dataList[i];
- node.metadata[i] = reader.readNode(data);
- }
- lazy._hasMetadata = true;
- }
- }
-
- static void setData(GenericTypeAlias node, LinkedNode data) {
- node.setProperty(_key, LazyGenericTypeAlias(data));
- LazyAst.setSimplyBounded(node, data.simplyBoundable_isSimplyBounded);
- }
-
- static void setHasSelfReference(GenericTypeAlias node, bool value) {
- node.setProperty(_hasSelfReferenceKey, value);
- }
-}
-
-class LazyMethodDeclaration {
- static const _key = 'lazyAst';
-
- final LinkedNode data;
-
- bool _hasBody = false;
- bool _hasDocumentationComment = false;
- bool _hasFormalParameters = false;
- bool _hasMetadata = false;
- bool _hasReturnType = false;
- bool _hasReturnTypeNode = false;
- bool _hasTypeInferenceError = false;
-
- LazyMethodDeclaration(this.data);
-
- static LazyMethodDeclaration get(MethodDeclaration node) {
- return node.getProperty(_key);
- }
-
- static int getCodeLength(
- LinkedUnitContext context,
- MethodDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null) {
- return context.getInformativeData(lazy.data)?.codeLength ?? 0;
- }
- return node.length;
- }
-
- static int getCodeOffset(
- LinkedUnitContext context,
- MethodDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null) {
- return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
- }
- return node.offset;
- }
-
- static DartType getReturnType(
- AstBinaryReader reader,
- MethodDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasReturnType) {
- var type = reader.readType(lazy.data.actualReturnType);
- LazyAst.setReturnType(node, type);
- lazy._hasReturnType = true;
- }
- return LazyAst.getReturnType(node);
- }
-
- static TopLevelInferenceError getTypeInferenceError(MethodDeclaration node) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasTypeInferenceError) {
- var error = lazy.data.topLevelTypeInferenceError;
- LazyAst.setTypeInferenceError(node, error);
- lazy._hasTypeInferenceError = true;
- }
- return LazyAst.getTypeInferenceError(node);
- }
-
- static bool isAbstract(MethodDeclaration node) {
- var lazy = get(node);
- if (lazy != null) {
- return AstBinaryFlags.isAbstract(lazy.data.flags);
- } else {
- return node.isAbstract;
- }
- }
-
- static bool isAsynchronous(MethodDeclaration node) {
- var lazy = get(node);
- if (lazy != null) {
- return AstBinaryFlags.isAsync(lazy.data.flags);
- } else {
- return node.body.isAsynchronous;
- }
- }
-
- static bool isGenerator(MethodDeclaration node) {
- var lazy = get(node);
- if (lazy != null) {
- return AstBinaryFlags.isGenerator(lazy.data.flags);
- } else {
- return node.body.isGenerator;
- }
- }
-
- static void readBody(
- AstBinaryReader reader,
- MethodDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasBody) {
- node.body = reader.readNode(
- lazy.data.methodDeclaration_body,
- );
- lazy._hasBody = true;
- }
- }
-
- static void readDocumentationComment(
- LinkedUnitContext context,
- MethodDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasDocumentationComment) {
- node.documentationComment = context.createComment(lazy.data);
- lazy._hasDocumentationComment = true;
- }
- }
-
- static void readFormalParameters(
- AstBinaryReader reader,
- MethodDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasFormalParameters) {
- node.parameters = reader.readNode(
- lazy.data.methodDeclaration_formalParameters,
- );
- lazy._hasFormalParameters = true;
- }
- }
-
- static void readMetadata(
- AstBinaryReader reader,
- MethodDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasMetadata) {
- var dataList = lazy.data.annotatedNode_metadata;
- for (var i = 0; i < dataList.length; ++i) {
- var data = dataList[i];
- node.metadata[i] = reader.readNode(data);
- }
- lazy._hasMetadata = true;
- }
- }
-
- static void readReturnTypeNode(
- AstBinaryReader reader,
- MethodDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasReturnTypeNode) {
- node.returnType = reader.readNode(
- lazy.data.methodDeclaration_returnType,
- );
- lazy._hasReturnTypeNode = true;
- }
- }
-
- static void setData(MethodDeclaration node, LinkedNode data) {
- node.setProperty(_key, LazyMethodDeclaration(data));
- }
-}
-
-class LazyMixinDeclaration {
- static const _key = 'lazyAst';
-
- final LinkedNode data;
-
- bool _hasDocumentationComment = false;
- bool _hasOnClause = false;
- bool _hasImplementsClause = false;
- bool _hasMembers = false;
- bool _hasMetadata = false;
-
- List<String> _superInvokedNames;
-
- LazyMixinDeclaration(MixinDeclaration node, this.data) {
- node.setProperty(_key, this);
- if (data != null) {
- LazyAst.setSimplyBounded(node, data.simplyBoundable_isSimplyBounded);
- }
- }
-
- List<String> getSuperInvokedNames() {
- return _superInvokedNames ??= data.mixinDeclaration_superInvokedNames;
- }
-
- void put(LinkedNodeBuilder builder) {
- builder.mixinDeclaration_superInvokedNames = _superInvokedNames ?? [];
- }
-
- void setSuperInvokedNames(List<String> value) {
- _superInvokedNames = value;
- }
-
- static LazyMixinDeclaration get(MixinDeclaration node) {
- LazyMixinDeclaration lazy = node.getProperty(_key);
- if (lazy == null) {
- return LazyMixinDeclaration(node, null);
- }
- return lazy;
- }
-
- static int getCodeLength(
- LinkedUnitContext context,
- MixinDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null) {
- return context.getInformativeData(lazy.data)?.codeLength ?? 0;
- }
- return node.length;
- }
-
- static int getCodeOffset(
- LinkedUnitContext context,
- MixinDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null) {
- return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
- }
- return node.offset;
- }
-
- static void readDocumentationComment(
- LinkedUnitContext context,
- MixinDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy.data != null && !lazy._hasDocumentationComment) {
- node.documentationComment = context.createComment(lazy.data);
- lazy._hasDocumentationComment = true;
- }
- }
-
- static void readImplementsClause(
- AstBinaryReader reader,
- MixinDeclarationImpl node,
- ) {
- var lazy = get(node);
- if (lazy.data != null && !lazy._hasImplementsClause) {
- node.implementsClause = reader.readNode(
- lazy.data.classOrMixinDeclaration_implementsClause,
- );
- lazy._hasImplementsClause = true;
- }
- }
-
- static void readMembers(
- AstBinaryReader reader,
- MixinDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy.data != null && !lazy._hasMembers) {
- var dataList = lazy.data.classOrMixinDeclaration_members;
- for (var i = 0; i < dataList.length; ++i) {
- var data = dataList[i];
- node.members[i] = reader.readNode(data);
- }
- lazy._hasMembers = true;
- }
- }
-
- static void readMetadata(
- AstBinaryReader reader,
- MixinDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy.data != null && !lazy._hasMetadata) {
- var dataList = lazy.data.annotatedNode_metadata;
- for (var i = 0; i < dataList.length; ++i) {
- var data = dataList[i];
- node.metadata[i] = reader.readNode(data);
- }
- lazy._hasMetadata = true;
- }
- }
-
- static void readOnClause(
- AstBinaryReader reader,
- MixinDeclarationImpl node,
- ) {
- var lazy = get(node);
- if (lazy.data != null && !lazy._hasOnClause) {
- node.onClause = reader.readNode(
- lazy.data.mixinDeclaration_onClause,
- );
- lazy._hasOnClause = true;
- }
- }
-}
-
-class LazyTopLevelVariableDeclaration {
- static const _key = 'lazyAst';
-
- final LinkedNode data;
-
- bool _hasDocumentationComment = false;
- bool _hasMetadata = false;
-
- LazyTopLevelVariableDeclaration(this.data);
-
- static LazyTopLevelVariableDeclaration get(TopLevelVariableDeclaration node) {
- return node.getProperty(_key);
- }
-
- static void readDocumentationComment(
- LinkedUnitContext context,
- TopLevelVariableDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasDocumentationComment) {
- node.documentationComment = context.createComment(lazy.data);
- lazy._hasDocumentationComment = true;
- }
- }
-
- static void readMetadata(
- AstBinaryReader reader,
- TopLevelVariableDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasMetadata) {
- var dataList = lazy.data.annotatedNode_metadata;
- for (var i = 0; i < dataList.length; ++i) {
- var data = dataList[i];
- node.metadata[i] = reader.readNode(data);
- }
- lazy._hasMetadata = true;
- }
- }
-
- static void setData(TopLevelVariableDeclaration node, LinkedNode data) {
- node.setProperty(_key, LazyTopLevelVariableDeclaration(data));
- }
-}
-
-class LazyTypeParameter {
- static const _key = 'lazyAst';
-
- final LinkedNode data;
-
- bool _hasBound = false;
- bool _hasDefaultType = false;
- bool _hasMetadata = false;
-
- LazyTypeParameter(this.data);
-
- static LazyTypeParameter get(TypeParameter node) {
- return node.getProperty(_key);
- }
-
- static int getCodeLength(
- LinkedUnitContext context,
- TypeParameter node,
- ) {
- var lazy = get(node);
- if (lazy != null) {
- return context.getInformativeData(lazy.data)?.codeLength ?? 0;
- }
- return node.length;
- }
-
- static int getCodeOffset(
- LinkedUnitContext context,
- TypeParameter node,
- ) {
- var lazy = get(node);
- if (lazy != null) {
- return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
- }
- return node.offset;
- }
-
- static DartType getDefaultType(AstBinaryReader reader, TypeParameter node) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasDefaultType) {
- lazy._hasDefaultType = true;
- var type = reader.readType(lazy.data.typeParameter_defaultType);
- LazyAst.setDefaultType(node, type);
- return type;
- }
- return LazyAst.getDefaultType(node);
- }
-
- static void readBound(AstBinaryReader reader, TypeParameter node) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasBound) {
- node.bound = reader.readNode(lazy.data.typeParameter_bound);
- lazy._hasBound = true;
- }
- }
-
- static void readMetadata(
- AstBinaryReader reader,
- TypeParameter node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasMetadata) {
- var dataList = lazy.data.annotatedNode_metadata;
- for (var i = 0; i < dataList.length; ++i) {
- var data = dataList[i];
- node.metadata[i] = reader.readNode(data);
- }
- lazy._hasMetadata = true;
- }
- }
-
- static void setData(TypeParameter node, LinkedNode data) {
- node.setProperty(_key, LazyTypeParameter(data));
- }
-}
-
-class LazyVariableDeclaration {
- static const _key = 'lazyAst';
-
- final LinkedNode data;
-
- bool _hasInitializer = false;
- bool _hasType = false;
- bool _hasTypeInferenceError = false;
-
- LazyVariableDeclaration(this.data);
-
- static LazyVariableDeclaration get(VariableDeclaration node) {
- return node.getProperty(_key);
- }
-
- static int getCodeLength(
- LinkedUnitContext context,
- VariableDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null) {
- return context.getInformativeData(lazy.data)?.codeLength ?? 0;
- }
- VariableDeclarationList parent = node.parent;
- if (parent.variables[0] == node) {
- return node.end - parent.offset;
- } else {
- return node.end - node.offset;
- }
- }
-
- static int getCodeOffset(
- LinkedUnitContext context,
- VariableDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null) {
- return context.getInformativeData(lazy.data)?.codeOffset ?? 0;
- }
- VariableDeclarationList parent = node.parent;
- if (parent.variables[0] == node) {
- return parent.offset;
- } else {
- return node.offset;
- }
- }
-
- static DartType getType(
- AstBinaryReader reader,
- VariableDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasType) {
- var type = reader.readType(lazy.data.actualType);
- LazyAst.setType(node, type);
- lazy._hasType = true;
- }
- return LazyAst.getType(node);
- }
-
- static TopLevelInferenceError getTypeInferenceError(
- VariableDeclaration node) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasTypeInferenceError) {
- var error = lazy.data.topLevelTypeInferenceError;
- LazyAst.setTypeInferenceError(node, error);
- lazy._hasTypeInferenceError = true;
- }
- return LazyAst.getTypeInferenceError(node);
- }
-
- static bool hasInitializer(VariableDeclaration node) {
- var lazy = get(node);
- if (lazy != null) {
- return AstBinaryFlags.hasInitializer(lazy.data.flags);
- } else {
- return node.initializer != null;
- }
- }
-
- static void readInitializer(
- AstBinaryReader reader,
- VariableDeclaration node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasInitializer) {
- node.initializer = reader.readNode(
- lazy.data.variableDeclaration_initializer,
- );
- lazy._hasInitializer = true;
- }
- }
-
- static void setData(VariableDeclaration node, LinkedNode data) {
- node.setProperty(_key, LazyVariableDeclaration(data));
- }
-}
-
-class LazyVariableDeclarationList {
- static const _key = 'lazyAst';
-
- final LinkedNode data;
-
- bool _hasTypeNode = false;
-
- LazyVariableDeclarationList(this.data);
-
- static LazyVariableDeclarationList get(VariableDeclarationList node) {
- return node.getProperty(_key);
- }
-
- static void readTypeNode(
- AstBinaryReader reader,
- VariableDeclarationList node,
- ) {
- var lazy = get(node);
- if (lazy != null && !lazy._hasTypeNode) {
- node.type = reader.readNode(
- lazy.data.variableDeclarationList_type,
- );
- lazy._hasTypeNode = true;
- }
- }
-
- static void setData(VariableDeclarationList node, LinkedNode data) {
- node.setProperty(_key, LazyVariableDeclarationList(data));
- }
-}
diff --git a/pkg/analyzer/lib/src/summary2/library_builder.dart b/pkg/analyzer/lib/src/summary2/library_builder.dart
index 14ab9ad3..63b7c10 100644
--- a/pkg/analyzer/lib/src/summary2/library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/library_builder.dart
@@ -4,19 +4,17 @@
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart' as ast;
+import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/ast/mixin_super_invoked_names.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/scope.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary2/combinator.dart';
import 'package:analyzer/src/summary2/constructor_initializer_resolver.dart';
import 'package:analyzer/src/summary2/default_value_resolver.dart';
import 'package:analyzer/src/summary2/export.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
import 'package:analyzer/src/summary2/link.dart';
-import 'package:analyzer/src/summary2/linked_bundle_context.dart';
+import 'package:analyzer/src/summary2/linked_library_context.dart';
import 'package:analyzer/src/summary2/linked_unit_context.dart';
import 'package:analyzer/src/summary2/metadata_resolver.dart';
import 'package:analyzer/src/summary2/reference.dart';
@@ -28,7 +26,7 @@
final Linker linker;
final Uri uri;
final Reference reference;
- final LinkedNodeLibraryBuilder node;
+ List<Reference> exports;
LinkedLibraryContext context;
@@ -43,11 +41,11 @@
final List<Export> exporters = [];
- LibraryBuilder(this.linker, this.uri, this.reference, this.node);
+ LibraryBuilder._(this.linker, this.uri, this.reference);
void addExporters() {
- var unitContext = context.units[0];
- for (var directive in unitContext.unit_withDirectives.directives) {
+ var unitContext = context.definingUnit;
+ for (var directive in unitContext.unit.directives) {
if (directive is ast.ExportDirective) {
Uri uri;
try {
@@ -89,8 +87,8 @@
/// Add top-level declaration of the library units to the local scope.
void addLocalDeclarations() {
- for (var unitContext in context.units) {
- var unitRef = reference.getChild('@unit').getChild(unitContext.uriStr);
+ for (var linkingUnit in context.units) {
+ var unitRef = reference.getChild('@unit').getChild(linkingUnit.uriStr);
var classRef = unitRef.getChild('@class');
var enumRef = unitRef.getChild('@enum');
var extensionRef = unitRef.getChild('@extension');
@@ -101,26 +99,34 @@
var setterRef = unitRef.getChild('@setter');
var variableRef = unitRef.getChild('@variable');
var nextUnnamedExtensionId = 0;
- for (var node in unitContext.unit.declarations) {
+ for (var node in linkingUnit.unit.declarations) {
if (node is ast.ClassDeclaration) {
var name = node.name.name;
var reference = classRef.getChild(name);
reference.node ??= node;
localScope.declare(name, reference);
+
+ ClassElementImpl.forLinkedNode(
+ linkingUnit.reference.element, reference, node);
} else if (node is ast.ClassTypeAlias) {
var name = node.name.name;
var reference = classRef.getChild(name);
reference.node ??= node;
localScope.declare(name, reference);
+
+ ClassElementImpl.forLinkedNode(
+ linkingUnit.reference.element, reference, node);
} else if (node is ast.EnumDeclaration) {
var name = node.name.name;
var reference = enumRef.getChild(name);
reference.node ??= node;
localScope.declare(name, reference);
+
+ EnumElementImpl.forLinkedNode(
+ linkingUnit.reference.element, reference, node);
} else if (node is ast.ExtensionDeclaration) {
var name = node.name?.name;
var refName = name ?? 'extension-${nextUnnamedExtensionId++}';
- LazyExtensionDeclaration.get(node).setRefName(refName);
var reference = extensionRef.getChild(refName);
reference.node ??= node;
@@ -128,19 +134,27 @@
if (name != null) {
localScope.declare(name, reference);
}
+
+ ExtensionElementImpl.forLinkedNode(
+ linkingUnit.reference.element, reference, node);
} else if (node is ast.FunctionDeclaration) {
var name = node.name.name;
- Reference containerRef;
+ Reference reference;
if (node.isGetter) {
- containerRef = getterRef;
+ reference = getterRef.getChild(name);
+ PropertyAccessorElementImpl.forLinkedNode(
+ linkingUnit.reference.element, reference, node);
} else if (node.isSetter) {
- containerRef = setterRef;
+ reference = setterRef.getChild(name);
+ PropertyAccessorElementImpl.forLinkedNode(
+ linkingUnit.reference.element, reference, node);
} else {
- containerRef = functionRef;
+ reference = functionRef.getChild(name);
+ FunctionElementImpl.forLinkedNode(
+ linkingUnit.reference.element, reference, node);
}
- var reference = containerRef.getChild(name);
reference.node ??= node;
if (node.isSetter) {
@@ -152,19 +166,27 @@
var name = node.name.name;
var reference = typeAliasRef.getChild(name);
reference.node ??= node;
-
localScope.declare(name, reference);
+
+ FunctionTypeAliasElementImpl.forLinkedNode(
+ linkingUnit.reference.element, reference, node);
} else if (node is ast.GenericTypeAlias) {
var name = node.name.name;
var reference = typeAliasRef.getChild(name);
- reference.node = node;
+ reference.node ??= node;
localScope.declare(name, reference);
+
+ FunctionTypeAliasElementImpl.forLinkedNode(
+ linkingUnit.reference.element, reference, node);
} else if (node is ast.MixinDeclaration) {
var name = node.name.name;
var reference = mixinRef.getChild(name);
reference.node ??= node;
localScope.declare(name, reference);
+
+ MixinElementImpl.forLinkedNode(
+ linkingUnit.reference.element, reference, node);
} else if (node is ast.TopLevelVariableDeclaration) {
for (var variable in node.variables.variables) {
var name = variable.name.name;
@@ -172,6 +194,9 @@
var reference = variableRef.getChild(name);
reference.node ??= node;
+ TopLevelVariableElementImpl.forLinkedNode(
+ linkingUnit.reference.element, reference, variable);
+
var getter = getterRef.getChild(name);
localScope.declare(name, getter);
@@ -181,7 +206,6 @@
}
}
} else {
- // TODO(scheglov) implement
throw UnimplementedError('${node.runtimeType}');
}
}
@@ -207,9 +231,50 @@
return true;
}
+ void buildDirectives() {
+ var exports = <ExportElement>[];
+ var imports = <ImportElement>[];
+ var hasCoreImport = false;
+
+ // Build elements directives in all units.
+ // Store elements only for the defining unit of the library.
+ var isDefiningUnit = true;
+ for (var unitContext in context.units) {
+ for (var node in unitContext.unit.directives) {
+ if (node is ast.ExportDirective) {
+ var exportElement = ExportElementImpl.forLinkedNode(element, node);
+ if (isDefiningUnit) {
+ exports.add(exportElement);
+ }
+ } else if (node is ast.ImportDirective) {
+ var importElement = ImportElementImpl.forLinkedNode(element, node);
+ if (isDefiningUnit) {
+ imports.add(importElement);
+ hasCoreImport |= importElement.importedLibrary?.isDartCore ?? false;
+ }
+ }
+ }
+ isDefiningUnit = false;
+ }
+
+ element.exports = exports;
+
+ if (!hasCoreImport) {
+ var dartCore = linker.elementFactory.libraryOfUri('dart:core');
+ imports.add(
+ ImportElementImpl(-1)
+ ..importedLibrary = dartCore
+ ..isSynthetic = true
+ ..uri = 'dart:core',
+ );
+ }
+ element.imports = imports;
+ }
+
void buildElement() {
- element = linker.elementFactory.libraryOfUri('$uri');
- scope = element.scope;
+ linker.elementFactory.createLibraryElementForLinking(context);
+ element = reference.element;
+ assert(element != null);
}
void buildInitialExportScope() {
@@ -218,6 +283,10 @@
});
}
+ void buildScope() {
+ scope = element.scope;
+ }
+
void collectMixinSuperInvokedNames() {
for (var unitContext in context.units) {
for (var declaration in unitContext.unit.declarations) {
@@ -229,8 +298,8 @@
executable.body.accept(collector);
}
}
- var lazy = LazyMixinDeclaration.get(declaration);
- lazy.setSuperInvokedNames(names.toList());
+ var element = declaration.declaredElement as MixinElementImpl;
+ element.superInvokedNames = names.toList();
}
}
}
@@ -274,7 +343,14 @@
try {
var uri = _selectAbsoluteUri(directive);
if (uri != null) {
- LazyDirective.setSelectedUri(directive, '$uri');
+ var library = linker.elementFactory.libraryOfUri('$uri');
+ if (directive is ast.ExportDirective) {
+ var exportElement = directive.element as ExportElementImpl;
+ exportElement.exportedLibrary = library;
+ } else if (directive is ast.ImportDirective) {
+ var importElement = directive.element as ImportElementImpl;
+ importElement.importedLibrary = library;
+ }
}
} on FormatException {
// ignored
@@ -284,11 +360,14 @@
}
void storeExportScope() {
- var linkingBundleContext = linker.linkingBundleContext;
- for (var reference in exportScope.map.values) {
- var index = linkingBundleContext.indexOfReference(reference);
- node.exports.add(index);
- }
+ exports = exportScope.map.values.toList();
+ linker.elementFactory.linkingExports['$uri'] = exports;
+
+ // TODO(scheglov) store for serialization
+ // for (var reference in exportScope.map.values) {
+ // var index = linkingBundleContext.indexOfReference(reference);
+ // context.exports.add(index);
+ // }
}
Uri _selectAbsoluteUri(ast.NamespaceDirective directive) {
@@ -318,45 +397,34 @@
}
static void build(Linker linker, LinkInputLibrary inputLibrary) {
- var libraryUri = inputLibrary.source.uri;
- var libraryUriStr = '$libraryUri';
- var libraryReference = linker.rootReference.getChild(libraryUriStr);
+ var uriStr = inputLibrary.uriStr;
+ var reference = linker.rootReference.getChild(uriStr);
- var libraryNode = LinkedNodeLibraryBuilder(
- uriStr: libraryUriStr,
- );
+ var elementFactory = linker.elementFactory;
+ var context = LinkedLibraryContext(elementFactory, uriStr, reference);
- var definingUnit = inputLibrary.units[0].unit;
- for (var directive in definingUnit.directives) {
- if (directive is ast.LibraryDirective) {
- var name = directive.name;
- libraryNode.name = name.components.map((id) => id.name).join('.');
- libraryNode.nameOffset = name.offset;
- libraryNode.nameLength = name.length;
- break;
- }
+ var unitRef = reference.getChild('@unit');
+ var unitIndex = 0;
+ for (var inputUnit in inputLibrary.units) {
+ var source = inputUnit.source;
+ var uriStr = source != null ? '${source.uri}' : '';
+ var reference = unitRef.getChild(uriStr);
+ context.units.add(
+ LinkedUnitContext(
+ context,
+ unitIndex++,
+ inputUnit.partUriStr,
+ uriStr,
+ reference,
+ inputUnit.isSynthetic,
+ unit: inputUnit.unit,
+ unitReader: null,
+ ),
+ );
}
- var builder = LibraryBuilder(
- linker,
- libraryUri,
- libraryReference,
- libraryNode,
- );
+ var builder = LibraryBuilder._(linker, inputLibrary.uri, reference);
linker.builders[builder.uri] = builder;
-
- builder.context = linker.bundleContext.addLinkingLibrary(
- libraryUriStr,
- libraryNode,
- inputLibrary,
- );
+ builder.context = context;
}
}
-
-class UnitBuilder {
- final Uri uri;
- final LinkedUnitContext context;
- final LinkedNode node;
-
- UnitBuilder(this.uri, this.context, this.node);
-}
diff --git a/pkg/analyzer/lib/src/summary2/link.dart b/pkg/analyzer/lib/src/summary2/link.dart
index 281f0dc..9295a32 100644
--- a/pkg/analyzer/lib/src/summary2/link.dart
+++ b/pkg/analyzer/lib/src/summary2/link.dart
@@ -2,24 +2,24 @@
// 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:typed_data';
+
import 'package:analyzer/dart/analysis/declared_variables.dart';
import 'package:analyzer/dart/ast/ast.dart' show CompilationUnit;
import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
import 'package:analyzer/src/generated/constant.dart';
import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary2/ast_binary_writer.dart';
+import 'package:analyzer/src/summary2/bundle_writer.dart';
import 'package:analyzer/src/summary2/library_builder.dart';
-import 'package:analyzer/src/summary2/linked_bundle_context.dart';
import 'package:analyzer/src/summary2/linked_element_factory.dart';
-import 'package:analyzer/src/summary2/linking_bundle_context.dart';
import 'package:analyzer/src/summary2/reference.dart';
import 'package:analyzer/src/summary2/simply_bounded.dart';
import 'package:analyzer/src/summary2/top_level_inference.dart';
import 'package:analyzer/src/summary2/type_alias.dart';
import 'package:analyzer/src/summary2/types_builder.dart';
import 'package:analyzer/src/summary2/variance_builder.dart';
+import 'package:meta/meta.dart';
var timerLinkingLinkingBundle = Stopwatch();
var timerLinkingRemoveBundle = Stopwatch();
@@ -27,34 +27,29 @@
LinkResult link(
LinkedElementFactory elementFactory,
List<LinkInputLibrary> inputLibraries,
+ bool withInformative,
) {
- var linker = Linker(elementFactory);
+ var linker = Linker(elementFactory, withInformative);
linker.link(inputLibraries);
- return LinkResult(linker.linkingBundle);
+ return LinkResult(
+ astBytes: linker.astBytes,
+ resolutionBytes: linker.resolutionBytes,
+ );
}
class Linker {
final LinkedElementFactory elementFactory;
-
- LinkedNodeBundleBuilder linkingBundle;
- LinkedBundleContext bundleContext;
- LinkingBundleContext linkingBundleContext;
+ final bool withInformative;
/// Libraries that are being linked.
final Map<Uri, LibraryBuilder> builders = {};
InheritanceManager3 inheritance; // TODO(scheglov) cache it
- Linker(this.elementFactory) {
- linkingBundleContext = LinkingBundleContext(
- elementFactory.dynamicRef,
- );
+ Uint8List astBytes;
+ Uint8List resolutionBytes;
- bundleContext = LinkedBundleContext.forAst(
- elementFactory,
- linkingBundleContext.references,
- );
- }
+ Linker(this.elementFactory, this.withInformative);
AnalysisContextImpl get analysisContext {
return elementFactory.analysisContext;
@@ -70,8 +65,6 @@
for (var inputLibrary in inputLibraries) {
LibraryBuilder.build(this, inputLibrary);
}
- // TODO(scheglov) do in build() ?
- elementFactory.addBundle(bundleContext);
_buildOutlines();
@@ -80,13 +73,13 @@
timerLinkingLinkingBundle.stop();
timerLinkingRemoveBundle.start();
- linkingBundleContext.clearIndexes();
- elementFactory.removeBundle(bundleContext);
+ elementFactory.removeBundle(
+ inputLibraries.map((e) => e.uriStr).toSet(),
+ );
timerLinkingRemoveBundle.stop();
}
void _buildOutlines() {
- _resolveUriDirectives();
_computeLibraryScopes();
_createTypeSystem();
_resolveTypes();
@@ -107,10 +100,19 @@
void _computeLibraryScopes() {
for (var library in builders.values) {
+ library.buildElement();
+ }
+
+ for (var library in builders.values) {
+ library.buildDirectives();
library.addLocalDeclarations();
}
for (var library in builders.values) {
+ library.resolveUriDirectives();
+ }
+
+ for (var library in builders.values) {
library.buildInitialExportScope();
}
@@ -159,34 +161,47 @@
}
for (var library in builders.values) {
- library.buildElement();
+ library.buildScope();
}
}
void _createLinkingBundle() {
- var linkingLibraries = <LinkedNodeLibraryBuilder>[];
- for (var builder in builders.values) {
- linkingLibraries.add(builder.node);
-
- for (var unitContext in builder.context.units) {
- var unit = unitContext.unit;
-
- var writer = AstBinaryWriter(linkingBundleContext);
- var unitLinkedNode = writer.writeUnit(unit);
- builder.node.units.add(
- LinkedNodeUnitBuilder(
- isSynthetic: unitContext.isSynthetic,
- partUriStr: unitContext.partUriStr,
- uriStr: unitContext.uriStr,
- node: unitLinkedNode,
- ),
- );
- }
- }
- linkingBundle = LinkedNodeBundleBuilder(
- references: linkingBundleContext.referencesBuilder,
- libraries: linkingLibraries,
+ var bundleWriter2 = BundleWriter(
+ withInformative,
+ elementFactory.dynamicRef,
);
+ var bundleWriterTimer = Stopwatch();
+
+ for (var builder in builders.values) {
+ bundleWriterTimer.start();
+ bundleWriter2.addLibrary(
+ LibraryToWrite(
+ uriStr: '${builder.uri}',
+ exports: builder.exports,
+ units: builder.context.units.map((e) {
+ return UnitToWrite(
+ uriStr: e.uriStr,
+ partUriStr: e.partUriStr,
+ node: e.unit,
+ isSynthetic: e.isSynthetic,
+ );
+ }).toList(),
+ ),
+ );
+ bundleWriterTimer.stop();
+ }
+
+ bundleWriterTimer.start();
+ var writeWriterResult = bundleWriter2.finish();
+ astBytes = writeWriterResult.astBytes;
+ resolutionBytes = writeWriterResult.resolutionBytes;
+ bundleWriterTimer.stop();
+ // print(
+ // '[bytes: ${astBytes.length + resolutionBytes.length}]'
+ // '[astBytes: ${astBytes.length}]'
+ // '[resolutionBytes: ${resolutionBytes.length}]'
+ // '[time: ${bundleWriterTimer.elapsedMilliseconds} ms]',
+ // );
}
void _createTypeSystem() {
@@ -229,15 +244,9 @@
library.resolveTypes(nodesToBuildType);
}
VarianceBuilder().perform(this);
- computeSimplyBounded(bundleContext, builders.values);
+ computeSimplyBounded(builders.values);
TypesBuilder().build(nodesToBuildType);
}
-
- void _resolveUriDirectives() {
- for (var library in builders.values) {
- library.resolveUriDirectives();
- }
- }
}
class LinkInputLibrary {
@@ -245,6 +254,10 @@
final List<LinkInputUnit> units;
LinkInputLibrary(this.source, this.units);
+
+ Uri get uri => source.uri;
+
+ String get uriStr => '$uri';
}
class LinkInputUnit {
@@ -259,10 +272,21 @@
this.isSynthetic,
this.unit,
);
+
+ String get uriStr {
+ if (source == null) {
+ return '';
+ }
+ return '${source.uri}';
+ }
}
class LinkResult {
- final LinkedNodeBundleBuilder bundle;
+ final Uint8List astBytes;
+ final Uint8List resolutionBytes;
- LinkResult(this.bundle);
+ LinkResult({
+ @required this.astBytes,
+ @required this.resolutionBytes,
+ });
}
diff --git a/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart b/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart
deleted file mode 100644
index 7047fb0..0000000
--- a/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart
+++ /dev/null
@@ -1,140 +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/element/element.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary2/informative_data.dart';
-import 'package:analyzer/src/summary2/link.dart';
-import 'package:analyzer/src/summary2/linked_element_factory.dart';
-import 'package:analyzer/src/summary2/linked_unit_context.dart';
-import 'package:analyzer/src/summary2/reference.dart';
-
-/// The context of a linked bundle, with shared references.
-class LinkedBundleContext {
- final LinkedElementFactory elementFactory;
- final LinkedNodeBundle _bundle;
- final List<Reference> _references;
- final Map<String, LinkedLibraryContext> libraryMap = {};
-
- LinkedBundleContext(this.elementFactory, this._bundle)
- : _references = List<Reference>(_bundle.references.name.length) {
- for (var library in _bundle.libraries) {
- var uriStr = library.uriStr;
- var reference = elementFactory.rootReference.getChild(uriStr);
- var libraryContext = LinkedLibraryContext(
- this,
- uriStr,
- reference,
- library,
- );
- libraryMap[uriStr] = libraryContext;
-
- var unitRef = reference.getChild('@unit');
- var units = library.units;
- for (var unitIndex = 0; unitIndex < units.length; ++unitIndex) {
- var unit = units[unitIndex];
- var uriStr = unit.uriStr;
- var reference = unitRef.getChild(uriStr);
- var unitContext = LinkedUnitContext(
- this,
- libraryContext,
- unitIndex,
- unit.partUriStr,
- uriStr,
- reference,
- unit.isSynthetic,
- unit,
- );
- libraryContext.units.add(unitContext);
- }
- }
- }
-
- LinkedBundleContext.forAst(this.elementFactory, this._references)
- : _bundle = null;
-
- /// Return `true` if this bundle is being linked.
- bool get isLinking => _bundle == null;
-
- LinkedLibraryContext addLinkingLibrary(
- String uriStr,
- LinkedNodeLibraryBuilder data,
- LinkInputLibrary inputLibrary,
- ) {
- var uriStr = data.uriStr;
- var reference = elementFactory.rootReference.getChild(uriStr);
- var libraryContext = LinkedLibraryContext(this, uriStr, reference, data);
- libraryMap[uriStr] = libraryContext;
-
- var unitRef = reference.getChild('@unit');
- var unitIndex = 0;
- for (var inputUnit in inputLibrary.units) {
- var source = inputUnit.source;
- var uriStr = source != null ? '${source.uri}' : '';
- var reference = unitRef.getChild(uriStr);
- createInformativeData(inputUnit.unit);
- libraryContext.units.add(
- LinkedUnitContext(
- this,
- libraryContext,
- unitIndex++,
- inputUnit.partUriStr,
- uriStr,
- reference,
- inputUnit.isSynthetic,
- null,
- unit: inputUnit.unit,
- ),
- );
- }
- return libraryContext;
- }
-
- T elementOfIndex<T extends Element>(int index) {
- var reference = referenceOfIndex(index);
- return elementFactory.elementOfReference(reference);
- }
-
- List<T> elementsOfIndexes<T extends Element>(List<int> indexList) {
- var result = List<T>(indexList.length);
- for (var i = 0; i < indexList.length; ++i) {
- var index = indexList[i];
- result[i] = elementOfIndex(index);
- }
- return result;
- }
-
- Reference referenceOfIndex(int index) {
- var reference = _references[index];
- if (reference != null) return reference;
-
- if (index == 0) {
- reference = elementFactory.rootReference;
- _references[index] = reference;
- return reference;
- }
-
- var parentIndex = _bundle.references.parent[index];
- var parent = referenceOfIndex(parentIndex);
-
- var name = _bundle.references.name[index];
- reference = parent.getChild(name);
- _references[index] = reference;
-
- return reference;
- }
-}
-
-class LinkedLibraryContext {
- final LinkedBundleContext context;
- final String uriStr;
- final Reference reference;
- final LinkedNodeLibrary node;
- final List<LinkedUnitContext> units = [];
-
- LinkedLibraryContext(this.context, this.uriStr, this.reference, this.node);
-
- LinkedUnitContext get definingUnit => units.first;
-}
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index abfaeec..58ca7e9 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -9,9 +9,8 @@
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type_provider.dart';
import 'package:analyzer/src/dart/resolver/scope.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
-import 'package:analyzer/src/summary2/linked_bundle_context.dart';
+import 'package:analyzer/src/summary2/bundle_reader.dart';
+import 'package:analyzer/src/summary2/linked_library_context.dart';
import 'package:analyzer/src/summary2/linked_unit_context.dart';
import 'package:analyzer/src/summary2/reference.dart';
@@ -19,7 +18,8 @@
final AnalysisContextImpl analysisContext;
final AnalysisSessionImpl analysisSession;
final Reference rootReference;
- final Map<String, LinkedLibraryContext> libraryMap = {};
+ final Map<String, List<Reference>> linkingExports = {};
+ final Map<String, LibraryReader> libraryReaders = {};
LinkedElementFactory(
this.analysisContext,
@@ -36,11 +36,11 @@
}
bool get hasDartCore {
- return libraryMap.containsKey('dart:core');
+ return libraryReaders.containsKey('dart:core');
}
- void addBundle(LinkedBundleContext context) {
- libraryMap.addAll(context.libraryMap);
+ void addBundle(BundleReader bundle) {
+ libraryReaders.addAll(bundle.libraryMap);
}
Namespace buildExportNamespace(Uri uri) {
@@ -64,6 +64,147 @@
return Namespace(exportedNames);
}
+ LibraryElementImpl createLibraryElementForLinking(
+ LinkedLibraryContext libraryContext,
+ ) {
+ var sourceFactory = analysisContext.sourceFactory;
+ var libraryUriStr = libraryContext.uriStr;
+ var librarySource = sourceFactory.forUri(libraryUriStr);
+
+ // The URI cannot be resolved, we don't know the library.
+ if (librarySource == null) return null;
+
+ var definingUnitContext = libraryContext.units[0];
+ var definingUnitNode = definingUnitContext.unit;
+
+ // TODO(scheglov) Do we need this?
+ var name = '';
+ var nameOffset = -1;
+ var nameLength = 0;
+ for (var directive in definingUnitNode.directives) {
+ if (directive is LibraryDirective) {
+ name = directive.name.components.map((e) => e.name).join('.');
+ nameOffset = directive.name.offset;
+ nameLength = directive.name.length;
+ break;
+ }
+ }
+
+ var libraryElement = LibraryElementImpl.forLinkedNode(
+ analysisContext,
+ analysisSession,
+ name,
+ nameOffset,
+ nameLength,
+ definingUnitContext,
+ libraryContext.reference,
+ definingUnitNode,
+ );
+ _setLibraryTypeSystem(libraryElement);
+
+ var units = <CompilationUnitElementImpl>[];
+ var unitContainerRef = libraryContext.reference.getChild('@unit');
+ for (var unitContext in libraryContext.units) {
+ var unitNode = unitContext.unit;
+
+ var unitSource = sourceFactory.forUri(unitContext.uriStr);
+ var unitElement = CompilationUnitElementImpl.forLinkedNode(
+ libraryElement,
+ unitContext,
+ unitContext.reference,
+ unitNode,
+ );
+ unitElement.lineInfo = unitNode.lineInfo;
+ unitElement.source = unitSource;
+ unitElement.librarySource = librarySource;
+ unitElement.uri = unitContext.partUriStr;
+ units.add(unitElement);
+ unitContainerRef.getChild(unitContext.uriStr).element = unitElement;
+ }
+
+ libraryElement.definingCompilationUnit = units[0];
+ libraryElement.parts = units.skip(1).toList();
+ libraryContext.reference.element = libraryElement;
+
+ return libraryElement;
+ }
+
+ LibraryElementImpl createLibraryElementForReading(String uriStr) {
+ var sourceFactory = analysisContext.sourceFactory;
+ var librarySource = sourceFactory.forUri(uriStr);
+
+ // The URI cannot be resolved, we don't know the library.
+ if (librarySource == null) return null;
+
+ var reader = libraryReaders[uriStr];
+ if (reader == null) {
+ throw ArgumentError(
+ 'Missing library: $uriStr\n'
+ 'Available libraries: ${libraryReaders.keys.toList()}',
+ );
+ }
+
+ var libraryContext = LinkedLibraryContext(this, uriStr, reader.reference);
+ var unitContainerRef = reader.reference.getChild('@unit');
+
+ var unitContexts = <LinkedUnitContext>[];
+ var indexInLibrary = 0;
+ var unitReaders = reader.units;
+ for (var unitReader in unitReaders) {
+ var unitReference = unitContainerRef.getChild(unitReader.uriStr);
+ var unitContext = LinkedUnitContext(
+ libraryContext,
+ indexInLibrary++,
+ unitReader.partUriStr,
+ unitReader.uriStr,
+ unitReference,
+ unitReader.isSynthetic,
+ unit: unitReader.unit,
+ unitReader: unitReader,
+ );
+ unitContexts.add(unitContext);
+ libraryContext.units.add(unitContext);
+ }
+
+ var definingUnitContext = unitContexts[0];
+ var libraryElement = LibraryElementImpl.forLinkedNode(
+ analysisContext,
+ analysisSession,
+ reader.name,
+ reader.nameOffset,
+ reader.nameLength,
+ definingUnitContext,
+ reader.reference,
+ unitReaders.first.unit,
+ );
+ _setLibraryTypeSystem(libraryElement);
+
+ var units = <CompilationUnitElementImpl>[];
+ for (var unitContext in unitContexts) {
+ var unitNode = unitContext.unit;
+
+ var unitSource = sourceFactory.forUri(unitContext.uriStr);
+ var unitElement = CompilationUnitElementImpl.forLinkedNode(
+ libraryElement,
+ unitContext,
+ unitContext.reference,
+ unitNode,
+ );
+ unitElement.lineInfo = unitNode.lineInfo;
+ unitElement.source = unitSource;
+ unitElement.librarySource = librarySource;
+ unitElement.uri = unitContext.partUriStr;
+ units.add(unitElement);
+ unitContainerRef.getChild(unitContext.uriStr).element = unitElement;
+ }
+
+ libraryElement.definingCompilationUnit = units[0];
+ libraryElement.parts = units.skip(1).toList();
+ reader.reference.element = libraryElement;
+
+ return libraryElement;
+ }
+
void createTypeProviders(
LibraryElementImpl dartCore,
LibraryElementImpl dartAsync,
@@ -103,34 +244,143 @@
return null;
}
- return _ElementRequest(this, reference).elementOfReference(reference);
+ if (reference.isLibrary) {
+ var uriStr = reference.name;
+ return createLibraryElementForReading(uriStr);
+ }
+
+ var parent = reference.parent.parent;
+ var parentElement = elementOfReference(parent);
+
+ // Named formal parameters are created when we apply resolution to the
+ // executable declaration, e.g. a constructor, or a method.
+ if (reference.isParameter) {
+ (parentElement as ExecutableElement).parameters;
+ assert(reference.element != null);
+ return reference.element;
+ }
+
+ // The default constructor might be synthetic, and has no node.
+ // TODO(scheglov) We resynthesize all constructors here.
+ if (reference.isConstructor && reference.name == '') {
+ return (parentElement as ClassElement).unnamedConstructor;
+ }
+
+ if (parentElement is EnumElementImpl) {
+ parentElement.constants;
+ assert(reference.element != null);
+ return reference.element;
+ }
+
+ if (reference.element != null) {
+ return reference.element;
+ }
+
+ if (reference.isUnit) {
+ assert(reference.element != null);
+ return reference.element;
+ }
+
+ if (reference.isPrefix) {
+ (parentElement as LibraryElement).prefixes;
+ assert(reference.element != null);
+ return reference.element;
+ }
+
+ // For class, mixin, extension - index members.
+ parent.nodeAccessor.readIndex();
+
+ // For any element - class, method, etc - read the node.
+ var node = reference.nodeAccessor.node;
+
+ if (node is ClassDeclaration) {
+ ClassElementImpl.forLinkedNode(parentElement, reference, node);
+ assert(reference.element != null);
+ return reference.element;
+ } else if (node is ClassTypeAlias) {
+ ClassElementImpl.forLinkedNode(parentElement, reference, node);
+ assert(reference.element != null);
+ return reference.element;
+ } else if (node is ConstructorDeclaration) {
+ ConstructorElementImpl.forLinkedNode(parentElement, reference, node);
+ var element = reference.element as ConstructorElementImpl;
+ assert(element != null);
+ return element;
+ } else if (node is EnumDeclaration) {
+ EnumElementImpl.forLinkedNode(parentElement, reference, node);
+ assert(reference.element != null);
+ return reference.element;
+ } else if (node is ExtensionDeclaration) {
+ ExtensionElementImpl.forLinkedNode(parentElement, reference, node);
+ assert(reference.element != null);
+ return reference.element;
+ } else if (node is FieldDeclaration) {
+ var variable = _variableDeclaration(node.fields, reference.name);
+ if (variable.isConst) {
+ ConstFieldElementImpl.forLinkedNode(parentElement, reference, variable);
+ } else {
+ FieldElementImpl.forLinkedNodeFactory(
+ parentElement, reference, variable);
+ }
+ assert(reference.element != null);
+ return reference.element;
+ } else if (node is FunctionDeclaration) {
+ if (node.propertyKeyword != null) {
+ _topLevelPropertyAccessor(parent, parentElement, reference, node);
+ } else {
+ FunctionElementImpl.forLinkedNode(parentElement, reference, node);
+ }
+ assert(reference.element != null);
+ return reference.element;
+ } else if (node is FunctionTypeAlias || node is GenericTypeAlias) {
+ FunctionTypeAliasElementImpl.forLinkedNode(
+ parentElement, reference, node);
+ assert(reference.element != null);
+ return reference.element;
+ } else if (node is MethodDeclaration) {
+ if (node.propertyKeyword != null) {
+ PropertyAccessorElementImpl.forLinkedNode(
+ parentElement, reference, node);
+ } else {
+ MethodElementImpl.forLinkedNode(parentElement, reference, node);
+ }
+ assert(reference.element != null);
+ return reference.element;
+ } else if (node is MixinDeclaration) {
+ MixinElementImpl.forLinkedNode(parentElement, reference, node);
+ assert(reference.element != null);
+ return reference.element;
+ } else if (node is TopLevelVariableDeclaration) {
+ var variable = _variableDeclaration(node.variables, reference.name);
+ if (variable.isConst) {
+ ConstTopLevelVariableElementImpl.forLinkedNode(
+ parentElement, reference, variable);
+ } else {
+ TopLevelVariableElementImpl.forLinkedNode(
+ parentElement, reference, variable);
+ }
+ assert(reference.element != null);
+ return reference.element;
+ }
+
+ throw UnimplementedError('$reference');
}
List<Reference> exportsOfLibrary(String uriStr) {
- var library = libraryMap[uriStr];
+ var linkingExportedReferences = linkingExports[uriStr];
+ if (linkingExportedReferences != null) {
+ return linkingExportedReferences;
+ }
+
+ var library = libraryReaders[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) {
- var index = exportIndexList[i];
- var reference = library.context.referenceOfIndex(index);
- exportReferences[i] = reference;
- }
- return exportReferences;
+ return library.exports;
}
bool isLibraryUri(String uriStr) {
- var libraryContext = libraryMap[uriStr];
- return !libraryContext.definingUnit.hasPartOfDirective;
+ var libraryContext = libraryReaders[uriStr];
+ return !libraryContext.hasPartOfDirective;
}
LibraryElementImpl libraryOfUri(String uriStr) {
@@ -140,8 +390,7 @@
/// We have linked the bundle, and need to disconnect its libraries, so
/// that the client can re-add the bundle, this time read from bytes.
- void removeBundle(LinkedBundleContext context) {
- var uriStrSet = context.libraryMap.keys.toSet();
+ void removeBundle(Set<String> uriStrSet) {
removeLibraries(uriStrSet);
// This is the bundle with dart:core and dart:async, based on full ASTs.
@@ -154,10 +403,10 @@
'${uriStrSet.toList()}',
);
}
- if (libraryMap.isNotEmpty) {
+ if (libraryReaders.isNotEmpty) {
throw StateError(
'Expected to link dart:core and dart:async first: '
- '${libraryMap.keys.toList()}',
+ '${libraryReaders.keys.toList()}',
);
}
analysisContext.clearTypeProvider();
@@ -169,7 +418,8 @@
/// any session level caches.
void removeLibraries(Set<String> uriStrSet) {
for (var uriStr in uriStrSet) {
- libraryMap.remove(uriStr);
+ libraryReaders.remove(uriStr);
+ linkingExports.remove(uriStr);
rootReference.removeChild(uriStr);
}
@@ -177,23 +427,6 @@
analysisSession.inheritanceManager.removeOfLibraries(uriStrSet);
}
- /// Set optional informative data for the unit.
- void setInformativeData(
- String libraryUriStr,
- String unitUriStr,
- List<UnlinkedInformativeData> informativeData,
- ) {
- var libraryContext = libraryMap[libraryUriStr];
- if (libraryContext != null) {
- for (var unitContext in libraryContext.units) {
- if (unitContext.uriStr == unitUriStr) {
- unitContext.informativeData = informativeData;
- return;
- }
- }
- }
- }
-
void _declareDartCoreDynamicNever() {
var dartCoreRef = rootReference.getChild('dart:core');
dartCoreRef.getChild('dynamic').element = DynamicElementImpl.instance;
@@ -218,341 +451,49 @@
libraryElement.createLoadLibraryFunction();
}
-}
-class _ElementRequest {
- final LinkedElementFactory elementFactory;
- final Reference input;
-
- _ElementRequest(this.elementFactory, this.input);
-
- ElementImpl elementOfReference(Reference reference) {
- if (reference.element != null) {
- return reference.element;
- }
-
- var parent2 = reference.parent.parent;
- if (parent2 == null) {
- return _createLibraryElement(reference);
- }
-
- var parentName = reference.parent.name;
-
- if (parentName == '@class') {
- var unit = elementOfReference(parent2);
- return _class(unit, reference);
- }
-
- if (parentName == '@constructor') {
- var class_ = elementOfReference(parent2);
- return _constructor(class_, reference);
- }
-
- if (parentName == '@enum') {
- var unit = elementOfReference(parent2);
- return _enum(unit, reference);
- }
-
- if (parentName == '@extension') {
- var unit = elementOfReference(parent2);
- return _extension(unit, reference);
- }
-
- if (parentName == '@field') {
- var enclosing = elementOfReference(parent2);
- return _field(enclosing, reference);
- }
-
- if (parentName == '@function') {
- CompilationUnitElementImpl enclosing = elementOfReference(parent2);
- return _function(enclosing, reference);
- }
-
- if (parentName == '@getter' || parentName == '@setter') {
- var enclosing = elementOfReference(parent2);
- return _accessor(enclosing, reference);
- }
-
- if (parentName == '@method') {
- var enclosing = elementOfReference(parent2);
- return _method(enclosing, reference);
- }
-
- if (parentName == '@mixin') {
- var unit = elementOfReference(parent2);
- return _mixin(unit, reference);
- }
-
- if (parentName == '@parameter') {
- ExecutableElementImpl enclosing = elementOfReference(parent2);
- return _parameter(enclosing, reference);
- }
-
- if (parentName == '@prefix') {
- LibraryElementImpl enclosing = elementOfReference(parent2);
- return _prefix(enclosing, reference);
- }
-
- if (parentName == '@typeAlias') {
- var unit = elementOfReference(parent2);
- return _typeAlias(unit, reference);
- }
-
- if (parentName == '@typeParameter') {
- var enclosing = elementOfReference(parent2);
- if (enclosing is ParameterElement) {
- (enclosing as ParameterElement).typeParameters;
- } else {
- (enclosing as TypeParameterizedElement).typeParameters;
- }
- assert(reference.element != null);
- return reference.element;
- }
-
- if (parentName == '@unit') {
- elementOfReference(parent2);
- // Creating a library fills all its units.
- assert(reference.element != null);
- return reference.element;
- }
-
- if (reference.name == '@function' && parent2.name == '@typeAlias') {
- var parent = reference.parent;
- FunctionTypeAliasElementImpl alias = elementOfReference(parent);
- return alias.function;
- }
-
- throw StateError('Not found: $input');
- }
-
- PropertyAccessorElementImpl _accessor(
- ElementImpl enclosing, Reference reference) {
- if (enclosing is ClassElementImpl) {
- enclosing.accessors;
- } else if (enclosing is CompilationUnitElementImpl) {
- enclosing.accessors;
- } else if (enclosing is EnumElementImpl) {
- enclosing.accessors;
- } else if (enclosing is ExtensionElementImpl) {
- enclosing.accessors;
- } else {
- throw StateError('${enclosing.runtimeType}');
- }
- // Requesting accessors sets elements for accessors and variables.
- assert(reference.element != null);
- return reference.element;
- }
-
- ClassElementImpl _class(
- CompilationUnitElementImpl unit, Reference reference) {
- if (reference.node == null) {
- _indexUnitElementDeclarations(unit);
- assert(reference.node != null, '$reference');
- }
- ClassElementImpl.forLinkedNode(unit, reference, reference.node);
- return reference.element;
- }
-
- ConstructorElementImpl _constructor(
- ClassElementImpl enclosing, Reference reference) {
- enclosing.constructors;
- // Requesting constructors sets elements for all of them.
- assert(reference.element != null);
- return reference.element;
- }
-
- LibraryElementImpl _createLibraryElement(Reference reference) {
- var uriStr = reference.name;
-
- var sourceFactory = elementFactory.analysisContext.sourceFactory;
- var librarySource = sourceFactory.forUri(uriStr);
-
- // The URI cannot be resolved, we don't know the library.
- if (librarySource == null) return null;
-
- var libraryContext = elementFactory.libraryMap[uriStr];
- if (libraryContext == null) {
- throw ArgumentError(
- 'Missing library: $uriStr\n'
- 'Available libraries: ${elementFactory.libraryMap.keys.toList()}',
- );
- }
- var libraryNode = libraryContext.node;
- var hasName = libraryNode.name.isNotEmpty;
-
- var definingUnitContext = libraryContext.definingUnit;
-
- var libraryElement = LibraryElementImpl.forLinkedNode(
- elementFactory.analysisContext,
- elementFactory.analysisSession,
- libraryNode.name,
- hasName ? libraryNode.nameOffset : -1,
- libraryNode.nameLength,
- definingUnitContext,
- reference,
- definingUnitContext.unit_withDeclarations,
- );
- elementFactory._setLibraryTypeSystem(libraryElement);
-
- var units = <CompilationUnitElementImpl>[];
- var unitContainerRef = reference.getChild('@unit');
- for (var unitContext in libraryContext.units) {
- var unitNode = unitContext.unit_withDeclarations;
-
- var unitSource = sourceFactory.forUri(unitContext.uriStr);
- var unitElement = CompilationUnitElementImpl.forLinkedNode(
- libraryElement,
- unitContext,
- unitContext.reference,
- unitNode,
- );
- unitElement.lineInfo = unitNode.lineInfo;
- unitElement.source = unitSource;
- unitElement.librarySource = librarySource;
- unitElement.uri = unitContext.partUriStr;
- units.add(unitElement);
- unitContainerRef.getChild(unitContext.uriStr).element = unitElement;
- }
-
- libraryElement.definingCompilationUnit = units[0];
- libraryElement.parts = units.skip(1).toList();
- reference.element = libraryElement;
-
- return libraryElement;
- }
-
- EnumElementImpl _enum(CompilationUnitElementImpl unit, Reference reference) {
- if (reference.node == null) {
- _indexUnitElementDeclarations(unit);
- assert(reference.node != null, '$reference');
- }
- EnumElementImpl.forLinkedNode(unit, reference, reference.node);
- return reference.element;
- }
-
- ExtensionElementImpl _extension(
- CompilationUnitElementImpl unit, Reference reference) {
- if (reference.node == null) {
- _indexUnitElementDeclarations(unit);
- assert(reference.node != null, '$reference');
- }
- ExtensionElementImpl.forLinkedNode(unit, reference, reference.node);
- return reference.element;
- }
-
- FieldElementImpl _field(ClassElementImpl enclosing, Reference reference) {
- enclosing.fields;
- // Requesting fields sets elements for all fields.
- assert(reference.element != null);
- return reference.element;
- }
-
- Element _function(CompilationUnitElementImpl enclosing, Reference reference) {
- enclosing.functions;
- assert(reference.element != null);
- return reference.element;
- }
-
- void _indexUnitElementDeclarations(CompilationUnitElementImpl unit) {
- var unitContext = unit.linkedContext;
- var unitRef = unit.reference;
- var unitNode = unit.linkedNode;
- _indexUnitDeclarations(unitContext, unitRef, unitNode);
- }
-
- MethodElementImpl _method(ElementImpl enclosing, Reference reference) {
- if (enclosing is ClassElementImpl) {
- enclosing.methods;
- } else if (enclosing is ExtensionElementImpl) {
- enclosing.methods;
- } else {
- throw StateError('${enclosing.runtimeType}');
- }
- // Requesting methods sets elements for all of them.
- assert(reference.element != null);
- return reference.element;
- }
-
- MixinElementImpl _mixin(
- CompilationUnitElementImpl unit, Reference reference) {
- if (reference.node == null) {
- _indexUnitElementDeclarations(unit);
- assert(reference.node != null, '$reference');
- }
- MixinElementImpl.forLinkedNode(unit, reference, reference.node);
- return reference.element;
- }
-
- Element _parameter(ExecutableElementImpl enclosing, Reference reference) {
- enclosing.parameters;
- assert(reference.element != null);
- return reference.element;
- }
-
- PrefixElementImpl _prefix(LibraryElementImpl library, Reference reference) {
- for (var import in library.imports) {
- import.prefix;
- }
- assert(reference.element != null);
- return reference.element;
- }
-
- FunctionTypeAliasElementImpl _typeAlias(
- CompilationUnitElementImpl unit, Reference reference) {
- if (reference.node == null) {
- _indexUnitElementDeclarations(unit);
- assert(reference.node != null, '$reference');
- }
- FunctionTypeAliasElementImpl.forLinkedNode(unit, reference, reference.node);
- return reference.element;
- }
-
- /// Index nodes for which we choose to create elements individually,
- /// for example [ClassDeclaration], so that its [Reference] has the node,
- /// and we can call the [ClassElementImpl] constructor.
- static void _indexUnitDeclarations(
- LinkedUnitContext unitContext,
- Reference unitRef,
- CompilationUnit unitNode,
+ void _topLevelPropertyAccessor(
+ Reference parentReference,
+ CompilationUnitElementImpl parentElement,
+ Reference reference,
+ FunctionDeclaration node,
) {
- var classRef = unitRef.getChild('@class');
- var enumRef = unitRef.getChild('@enum');
- var extensionRef = unitRef.getChild('@extension');
- var functionRef = unitRef.getChild('@function');
- var mixinRef = unitRef.getChild('@mixin');
- var typeAliasRef = unitRef.getChild('@typeAlias');
- var variableRef = unitRef.getChild('@variable');
- for (var declaration in unitNode.declarations) {
- if (declaration is ClassDeclaration) {
- var name = declaration.name.name;
- classRef.getChild(name).node = declaration;
- } else if (declaration is ClassTypeAlias) {
- var name = declaration.name.name;
- classRef.getChild(name).node = declaration;
- } else if (declaration is ExtensionDeclaration) {
- var refName = LazyExtensionDeclaration.get(declaration).refName;
- extensionRef.getChild(refName).node = declaration;
- } else if (declaration is EnumDeclaration) {
- var name = declaration.name.name;
- enumRef.getChild(name).node = declaration;
- } else if (declaration is FunctionDeclaration) {
- var name = declaration.name.name;
- functionRef.getChild(name).node = declaration;
- } else if (declaration is FunctionTypeAlias) {
- var name = declaration.name.name;
- typeAliasRef.getChild(name).node = declaration;
- } else if (declaration is GenericTypeAlias) {
- var name = declaration.name.name;
- typeAliasRef.getChild(name).node = declaration;
- } else if (declaration is MixinDeclaration) {
- var name = declaration.name.name;
- mixinRef.getChild(name).node = declaration;
- } else if (declaration is TopLevelVariableDeclaration) {
- for (var variable in declaration.variables.variables) {
- var name = variable.name.name;
- variableRef.getChild(name).node = declaration;
- }
+ var accessor = PropertyAccessorElementImpl.forLinkedNode(
+ parentElement, reference, node);
+
+ var name = reference.name;
+ var fieldRef = parentReference.getChild('@field').getChild(name);
+ var field = fieldRef.element as TopLevelVariableElementImpl;
+ if (field == null) {
+ field = TopLevelVariableElementImpl(name, -1);
+ fieldRef.element = field;
+ field.enclosingElement = parentElement;
+ field.isFinal = true;
+ field.isSynthetic = true;
+ }
+
+ var isSetter = node.isSetter;
+ if (isSetter) {
+ field.isFinal = false;
+ }
+
+ accessor.variable = field;
+ if (isSetter) {
+ field.setter = accessor;
+ } else {
+ field.getter = accessor;
+ }
+ }
+
+ static VariableDeclaration _variableDeclaration(
+ VariableDeclarationList variableList,
+ String name,
+ ) {
+ for (var variable in variableList.variables) {
+ if (variable.name.name == name) {
+ return variable;
}
}
+ throw StateError('No "$name" in: $variableList');
}
}
diff --git a/pkg/analyzer/lib/src/summary2/linked_library_context.dart b/pkg/analyzer/lib/src/summary2/linked_library_context.dart
new file mode 100644
index 0000000..e9c7e77
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/linked_library_context.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/summary2/linked_element_factory.dart';
+import 'package:analyzer/src/summary2/linked_unit_context.dart';
+import 'package:analyzer/src/summary2/reference.dart';
+
+class LinkedLibraryContext {
+ final LinkedElementFactory elementFactory;
+ final String uriStr;
+ final Reference reference;
+ final List<LinkedUnitContext> units = [];
+
+ LinkedLibraryContext(this.elementFactory, this.uriStr, this.reference);
+
+ LinkedUnitContext get definingUnit => units.first;
+}
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index ff54b07..b9d9dea 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -3,68 +3,36 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/standard_ast_factory.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/type_provider.dart';
-import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/dart/resolver/variance.dart';
-import 'package:analyzer/src/generated/testing/token_factory.dart';
-import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary2/ast_binary_reader.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
-import 'package:analyzer/src/summary2/linked_bundle_context.dart';
+import 'package:analyzer/src/summary2/bundle_reader.dart';
+import 'package:analyzer/src/summary2/linked_element_factory.dart';
+import 'package:analyzer/src/summary2/linked_library_context.dart';
import 'package:analyzer/src/summary2/reference.dart';
-import 'package:analyzer/src/summary2/type_builder.dart';
+import 'package:meta/meta.dart';
/// The context of a unit - the context of the bundle, and the unit tokens.
class LinkedUnitContext {
- final LinkedBundleContext bundleContext;
final LinkedLibraryContext libraryContext;
final int indexInLibrary;
final String partUriStr;
final String uriStr;
final Reference reference;
final bool isSynthetic;
- final LinkedNodeUnit data;
+ final CompilationUnit unit;
+ final UnitReader unitReader;
- /// Optional informative data for the unit.
- List<UnlinkedInformativeData> informativeData;
-
- AstBinaryReader _astReader;
-
- CompilationUnit _unit;
bool _hasDirectivesRead = false;
- /// Mapping from identifiers to synthetic type parameters.
- ///
- /// Synthetic type parameters are added when [readType] begins reading a
- /// [FunctionType], and removed when reading is done.
- final Map<int, TypeParameterElementImpl> _typeParameters = {};
+ LinkedUnitContext(this.libraryContext, this.indexInLibrary, this.partUriStr,
+ this.uriStr, this.reference, this.isSynthetic,
+ {@required this.unit, @required this.unitReader});
- int _nextSyntheticTypeParameterId = 0x10000;
-
- LinkedUnitContext(
- this.bundleContext,
- this.libraryContext,
- this.indexInLibrary,
- this.partUriStr,
- this.uriStr,
- this.reference,
- this.isSynthetic,
- this.data,
- {CompilationUnit unit}) {
- _astReader = AstBinaryReader(this);
- _astReader.isLazy = unit == null;
-
- _unit = unit;
- _hasDirectivesRead = _unit != null;
- }
+ LinkedElementFactory get elementFactory => libraryContext.elementFactory;
bool get hasPartOfDirective {
for (var directive in unit_withDirectives.directives) {
@@ -76,7 +44,7 @@
}
/// Return `true` if this unit is a part of a bundle that is being linked.
- bool get isLinking => bundleContext.isLinking;
+ bool get isLinking => unitReader == null;
TypeProvider get typeProvider {
var libraryReference = libraryContext.reference;
@@ -84,37 +52,43 @@
return libraryElement.typeProvider;
}
- CompilationUnit get unit => _unit;
-
CompilationUnit get unit_withDeclarations {
- _ensureUnitWithDeclarations();
- return _unit;
+ unitReader?.readDeclarations();
+ return unit;
}
+ /// Ensure that [unit] has directives ready (because we are linking,
+ /// and so always have full AST, or, if we are reading, we make sure
+ /// that we have them read).
CompilationUnit get unit_withDirectives {
- _ensureUnitWithDeclarations();
- if (!_hasDirectivesRead) {
- var directiveDataList = data.node.compilationUnit_directives;
- for (var i = 0; i < directiveDataList.length; ++i) {
- var directiveData = directiveDataList[i];
- _unit.directives[i] = _astReader.readNode(directiveData);
- }
+ if (unitReader != null && !_hasDirectivesRead) {
_hasDirectivesRead = true;
+ unitReader.readDirectives();
+ var libraryElement = libraryContext.reference.element;
+ for (var directive in unit.directives) {
+ if (directive is ExportDirective) {
+ if (directive.element == null) {
+ ExportElementImpl.forLinkedNode(libraryElement, directive);
+ }
+ } else if (directive is ImportDirective) {
+ if (directive.element == null) {
+ ImportElementImpl.forLinkedNode(libraryElement, directive);
+ }
+ }
+ }
}
- return _unit;
+ return unit;
}
- Comment createComment(LinkedNode data) {
- var informativeData = getInformativeData(data);
- var tokenStringList = informativeData?.documentationComment_tokens;
- if (tokenStringList == null || tokenStringList.isEmpty) {
- return null;
+ /// TODO(scheglov) make it static
+ void applyResolution(AstNode node) {
+ if (node is VariableDeclaration) {
+ node = node.parent.parent;
}
-
- var tokens = tokenStringList
- .map((lexeme) => TokenFactory.tokenFromString(lexeme))
- .toList();
- return astFactory.documentationComment(tokens);
+ if (node is HasAstLinkedContext) {
+ var astLinkedContext = (node as HasAstLinkedContext).linkedContext;
+ astLinkedContext?.applyResolution(this);
+ }
}
void createGenericFunctionTypeElement(int id, GenericFunctionTypeImpl node) {
@@ -128,133 +102,72 @@
node.declaredElement = element;
}
- /// Return the [LibraryElement] referenced in the [node].
- LibraryElement directiveLibrary(UriBasedDirective node) {
- var uriStr = LazyDirective.getSelectedUri(node);
- if (uriStr == null) return null;
- return bundleContext.elementFactory.libraryOfUri(uriStr);
- }
-
int getCodeLength(AstNode node) {
- if (node is ClassDeclaration) {
- return LazyClassDeclaration.getCodeLength(this, node);
- } else if (node is ClassTypeAlias) {
- return LazyClassTypeAlias.getCodeLength(this, node);
- } else if (node is CompilationUnit) {
+ if (node is HasAstLinkedContext) {
+ var linked = (node as HasAstLinkedContext).linkedContext;
+ return linked != null ? linked.codeLength : node.length;
+ }
+
+ if (node is CompilationUnitImpl) {
+ var data = node.summaryData as SummaryDataForCompilationUnit;
if (data != null) {
- return getInformativeData(data.node)?.codeLength ?? 0;
+ return data.codeLength;
} else {
return node.length;
}
- } else if (node is ConstructorDeclaration) {
- return LazyConstructorDeclaration.getCodeLength(this, node);
} else if (node is EnumConstantDeclaration) {
- return LazyEnumConstantDeclaration.getCodeLength(this, node);
- } else if (node is EnumDeclaration) {
- return LazyEnumDeclaration.getCodeLength(this, node);
- } else if (node is ExtensionDeclaration) {
- return LazyExtensionDeclaration.getCodeLength(this, node);
+ return node.length;
} else if (node is FormalParameter) {
- return LazyFormalParameter.getCodeLength(this, node);
- } else if (node is FunctionDeclaration) {
- return LazyFunctionDeclaration.getCodeLength(this, node);
- } else if (node is FunctionTypeAliasImpl) {
- return LazyFunctionTypeAlias.getCodeLength(this, node);
- } else if (node is GenericTypeAlias) {
- return LazyGenericTypeAlias.getCodeLength(this, node);
- } else if (node is MethodDeclaration) {
- return LazyMethodDeclaration.getCodeLength(this, node);
- } else if (node is MixinDeclaration) {
- return LazyMixinDeclaration.getCodeLength(this, node);
+ return node.length;
} else if (node is TypeParameter) {
- return LazyTypeParameter.getCodeLength(this, node);
+ return node.length;
} else if (node is VariableDeclaration) {
- return LazyVariableDeclaration.getCodeLength(this, node);
+ var parent2 = node.parent.parent;
+ var linked = (parent2 as HasAstLinkedContext).linkedContext;
+ return linked.getVariableDeclarationCodeLength(node);
}
throw UnimplementedError('${node.runtimeType}');
}
int getCodeOffset(AstNode node) {
- if (node is ClassDeclaration) {
- return LazyClassDeclaration.getCodeOffset(this, node);
- } else if (node is ClassTypeAlias) {
- return LazyClassTypeAlias.getCodeOffset(this, node);
- } else if (node is CompilationUnit) {
+ if (node is HasAstLinkedContext) {
+ var linked = (node as HasAstLinkedContext).linkedContext;
+ return linked != null ? linked.codeOffset : node.offset;
+ }
+
+ if (node is CompilationUnit) {
return 0;
- } else if (node is ConstructorDeclaration) {
- return LazyConstructorDeclaration.getCodeOffset(this, node);
} else if (node is EnumConstantDeclaration) {
- return LazyEnumConstantDeclaration.getCodeOffset(this, node);
- } else if (node is EnumDeclaration) {
- return LazyEnumDeclaration.getCodeOffset(this, node);
- } else if (node is ExtensionDeclaration) {
- return LazyExtensionDeclaration.getCodeOffset(this, node);
+ return node.offset;
} else if (node is FormalParameter) {
- return LazyFormalParameter.getCodeOffset(this, node);
- } else if (node is FunctionDeclaration) {
- return LazyFunctionDeclaration.getCodeOffset(this, node);
- } else if (node is FunctionTypeAliasImpl) {
- return LazyFunctionTypeAlias.getCodeOffset(this, node);
- } else if (node is GenericTypeAlias) {
- return LazyGenericTypeAlias.getCodeOffset(this, node);
- } else if (node is MethodDeclaration) {
- return LazyMethodDeclaration.getCodeOffset(this, node);
- } else if (node is MixinDeclaration) {
- return LazyMixinDeclaration.getCodeOffset(this, node);
+ return node.offset;
} else if (node is TypeParameter) {
- return LazyTypeParameter.getCodeOffset(this, node);
+ return node.offset;
} else if (node is VariableDeclaration) {
- return LazyVariableDeclaration.getCodeOffset(this, node);
+ var parent2 = node.parent.parent;
+ var linked = (parent2 as HasAstLinkedContext).linkedContext;
+ return linked.getVariableDeclarationCodeOffset(node);
}
throw UnimplementedError('${node.runtimeType}');
}
- int getCombinatorEnd(ShowCombinator node) {
- return LazyCombinator.getEnd(this, node);
- }
-
List<ConstructorInitializer> getConstructorInitializers(
ConstructorDeclaration node,
) {
- LazyConstructorDeclaration.readInitializers(_astReader, node);
return node.initializers;
}
ConstructorName getConstructorRedirected(ConstructorDeclaration node) {
- LazyConstructorDeclaration.readRedirectedConstructor(_astReader, node);
return node.redirectedConstructor;
}
- Iterable<ConstructorDeclaration> getConstructors(AstNode node) sync* {
+ List<ConstructorDeclaration> getConstructors(AstNode node) {
if (node is ClassOrMixinDeclaration) {
- var members = _getClassOrExtensionOrMixinMembers(node);
- for (var member in members) {
- if (member is ConstructorDeclaration) {
- yield member;
- }
- }
+ return _getClassOrExtensionOrMixinMembers(node)
+ .whereType<ConstructorDeclaration>()
+ .toList();
}
- }
-
- DartType getDefaultType(TypeParameter node) {
- var type = LazyTypeParameter.getDefaultType(_astReader, node);
- if (type is TypeBuilder) {
- type = (type as TypeBuilder).build();
- LazyAst.setDefaultType(node, type);
- }
- return type;
- }
-
- String getDefaultValueCode(AstNode node) {
- if (node is DefaultFormalParameter) {
- return LazyFormalParameter.getDefaultValueCode(this, node);
- }
- return null;
- }
-
- String getDefaultValueCodeData(LinkedNode data) {
- var informativeData = getInformativeData(data);
- return informativeData?.defaultFormalParameter_defaultValueCode;
+ return const <ConstructorDeclaration>[];
}
int getDirectiveOffset(Directive node) {
@@ -262,72 +175,22 @@
}
Comment getDocumentationComment(AstNode node) {
- if (node is ClassDeclaration) {
- LazyClassDeclaration.readDocumentationComment(this, node);
- return node.documentationComment;
- } else if (node is ClassTypeAlias) {
- LazyClassTypeAlias.readDocumentationComment(this, node);
- return node.documentationComment;
- } else if (node is ConstructorDeclaration) {
- LazyConstructorDeclaration.readDocumentationComment(this, node);
- return node.documentationComment;
- } else if (node is EnumConstantDeclaration) {
- LazyEnumConstantDeclaration.readDocumentationComment(this, node);
- return node.documentationComment;
- } else if (node is EnumDeclaration) {
- LazyEnumDeclaration.readDocumentationComment(this, node);
- return node.documentationComment;
- } else if (node is ExtensionDeclaration) {
- LazyExtensionDeclaration.readDocumentationComment(this, node);
- return node.documentationComment;
- } else if (node is FunctionDeclaration) {
- LazyFunctionDeclaration.readDocumentationComment(this, node);
- return node.documentationComment;
- } else if (node is FunctionTypeAlias) {
- LazyFunctionTypeAlias.readDocumentationComment(this, node);
- return node.documentationComment;
- } else if (node is GenericTypeAlias) {
- LazyGenericTypeAlias.readDocumentationComment(this, node);
- return node.documentationComment;
- } else if (node is MethodDeclaration) {
- LazyMethodDeclaration.readDocumentationComment(this, node);
- return node.documentationComment;
- } else if (node is MixinDeclaration) {
- LazyMixinDeclaration.readDocumentationComment(this, node);
- return node.documentationComment;
+ if (node is HasAstLinkedContext) {
+ var linkedContext = (node as HasAstLinkedContext).linkedContext;
+ linkedContext?.readDocumentationComment();
+ return (node as AnnotatedNode).documentationComment;
} else if (node is VariableDeclaration) {
- var parent2 = node.parent.parent;
- if (parent2 is FieldDeclaration) {
- LazyFieldDeclaration.readDocumentationComment(this, parent2);
- return parent2.documentationComment;
- } else if (parent2 is TopLevelVariableDeclaration) {
- LazyTopLevelVariableDeclaration.readDocumentationComment(
- this,
- parent2,
- );
- return parent2.documentationComment;
- } else {
- throw UnimplementedError('${parent2.runtimeType}');
- }
+ return getDocumentationComment(node.parent.parent);
} else {
throw UnimplementedError('${node.runtimeType}');
}
}
+ /// TODO(scheglov) inline
List<EnumConstantDeclaration> getEnumConstants(EnumDeclaration node) {
- LazyEnumDeclaration.readConstants(_astReader, node);
return node.constants;
}
- TypeAnnotation getExtendedType(ExtensionDeclaration node) {
- LazyExtensionDeclaration.readExtendedType(_astReader, node);
- return node.extendedType;
- }
-
- String getExtensionRefName(ExtensionDeclaration node) {
- return LazyExtensionDeclaration.get(node).refName;
- }
-
String getFieldFormalParameterName(AstNode node) {
if (node is DefaultFormalParameter) {
return getFieldFormalParameterName(node.parameter);
@@ -338,125 +201,97 @@
}
}
- Iterable<VariableDeclaration> getFields(CompilationUnitMember node) sync* {
+ List<VariableDeclaration> getFields(CompilationUnitMember node) {
+ var fields = <VariableDeclaration>[];
var members = _getClassOrExtensionOrMixinMembers(node);
for (var member in members) {
if (member is FieldDeclaration) {
- for (var field in member.fields.variables) {
- yield field;
- }
+ fields.addAll(member.fields.variables);
}
}
+ return fields;
+ }
+
+ String getFormalParameterName(FormalParameter node) {
+ if (node is DefaultFormalParameter) {
+ return getFormalParameterName(node.parameter);
+ } else if (node is NormalFormalParameter) {
+ return node.identifier?.name ?? '';
+ }
+ return null;
}
List<FormalParameter> getFormalParameters(AstNode node) {
if (node is ConstructorDeclaration) {
- LazyConstructorDeclaration.readFormalParameters(_astReader, node);
return node.parameters.parameters;
} else if (node is FunctionDeclaration) {
- LazyFunctionDeclaration.readFunctionExpression(_astReader, node);
return getFormalParameters(node.functionExpression);
} else if (node is FunctionExpression) {
- LazyFunctionExpression.readFormalParameters(_astReader, node);
return node.parameters?.parameters;
} else if (node is FormalParameter) {
if (node is DefaultFormalParameter) {
return getFormalParameters(node.parameter);
} else if (node is FieldFormalParameter) {
- LazyFormalParameter.readFormalParameters(_astReader, node);
return node.parameters?.parameters;
} else if (node is FunctionTypedFormalParameter) {
- LazyFormalParameter.readFormalParameters(_astReader, node);
return node.parameters.parameters;
} else {
return null;
}
} else if (node is FunctionTypeAlias) {
- LazyFunctionTypeAlias.readFormalParameters(_astReader, node);
return node.parameters.parameters;
} else if (node is GenericFunctionType) {
return node.parameters.parameters;
} else if (node is MethodDeclaration) {
- LazyMethodDeclaration.readFormalParameters(_astReader, node);
return node.parameters?.parameters;
} else {
throw UnimplementedError('${node.runtimeType}');
}
}
- Reference getGenericFunctionTypeReference(GenericFunctionType node) {
- var containerRef = reference.getChild('@genericFunctionType');
- var id = LazyAst.getGenericFunctionTypeId(node);
- return containerRef.getChild('$id');
- }
-
- GenericFunctionType getGeneticTypeAliasFunction(GenericTypeAlias node) {
- LazyGenericTypeAlias.readFunctionType(_astReader, node);
- return node.functionType;
- }
-
- bool getHasTypedefSelfReference(AstNode node) {
- if (node is FunctionTypeAlias) {
- return LazyFunctionTypeAlias.getHasSelfReference(node);
- } else if (node is GenericTypeAlias) {
- return LazyGenericTypeAlias.getHasSelfReference(node);
- }
- return false;
- }
-
ImplementsClause getImplementsClause(AstNode node) {
if (node is ClassDeclaration) {
- LazyClassDeclaration.readImplementsClause(_astReader, node);
return node.implementsClause;
} else if (node is ClassTypeAlias) {
- LazyClassTypeAlias.readImplementsClause(_astReader, node);
return node.implementsClause;
} else if (node is MixinDeclaration) {
- LazyMixinDeclaration.readImplementsClause(_astReader, node);
return node.implementsClause;
} else {
throw UnimplementedError('${node.runtimeType}');
}
}
- UnlinkedInformativeData getInformativeData(LinkedNode data) {
- if (informativeData == null) return null;
-
- var id = data.informativeId;
- if (id == 0) return null;
-
- return informativeData[id - 1];
- }
-
- bool getInheritsCovariant(AstNode node) {
+ Expression getInitializer(AstNode node) {
if (node is DefaultFormalParameter) {
- return getInheritsCovariant(node.parameter);
- } else if (node is FormalParameter) {
- return LazyAst.getInheritsCovariant(node);
+ return node.defaultValue;
} else if (node is VariableDeclaration) {
- return LazyAst.getInheritsCovariant(node);
+ return node.initializer;
} else {
throw StateError('${node.runtimeType}');
}
}
LibraryLanguageVersion getLanguageVersion(CompilationUnit node) {
- return LazyCompilationUnit.getLanguageVersion(node);
+ return (node as CompilationUnitImpl).languageVersion;
}
- Comment getLibraryDocumentationComment(CompilationUnit unit) {
- for (var directive in unit.directives) {
- if (directive is LibraryDirective) {
+ Comment getLibraryDocumentationComment() {
+ for (var directive in unit_withDirectives.directives) {
+ if (directive is LibraryDirectiveImpl) {
+ var data = directive.summaryData as SummaryDataForLibraryDirective;
+ data.readDocumentationComment();
return directive.documentationComment;
}
}
return null;
}
- List<Annotation> getLibraryMetadata(CompilationUnit unit) {
+ List<Annotation> getLibraryMetadata() {
+ unit_withDirectives;
+ unitReader.applyDirectivesResolution(this);
for (var directive in unit.directives) {
if (directive is LibraryDirective) {
- return getMetadata(directive);
+ return directive.metadata;
}
}
return const <Annotation>[];
@@ -464,80 +299,57 @@
List<Annotation> getMetadata(AstNode node) {
if (node is ClassDeclaration) {
- LazyClassDeclaration.readMetadata(_astReader, node);
return node.metadata;
} else if (node is ClassTypeAlias) {
- LazyClassTypeAlias.readMetadata(_astReader, node);
return node.metadata;
} else if (node is CompilationUnit) {
- assert(node == _unit);
+ assert(node == unit);
if (indexInLibrary != 0) {
return _getPartDirectiveAnnotation();
} else {
return const <Annotation>[];
}
} else if (node is ConstructorDeclaration) {
- LazyConstructorDeclaration.readMetadata(_astReader, node);
return node.metadata;
} else if (node is DefaultFormalParameter) {
return getMetadata(node.parameter);
} else if (node is Directive) {
- LazyDirective.readMetadata(_astReader, node);
return node.metadata;
} else if (node is EnumConstantDeclaration) {
- LazyEnumConstantDeclaration.readMetadata(_astReader, node);
return node.metadata;
} else if (node is EnumDeclaration) {
- LazyEnumDeclaration.readMetadata(_astReader, node);
return node.metadata;
} else if (node is ExtensionDeclaration) {
- LazyExtensionDeclaration.readMetadata(_astReader, node);
return node.metadata;
} else if (node is FormalParameter) {
- LazyFormalParameter.readMetadata(_astReader, node);
return node.metadata;
} else if (node is FunctionDeclaration) {
- LazyFunctionDeclaration.readMetadata(_astReader, node);
return node.metadata;
} else if (node is FunctionTypeAlias) {
- LazyFunctionTypeAlias.readMetadata(_astReader, node);
return node.metadata;
} else if (node is GenericTypeAlias) {
- LazyGenericTypeAlias.readMetadata(_astReader, node);
return node.metadata;
} else if (node is MethodDeclaration) {
- LazyMethodDeclaration.readMetadata(_astReader, node);
return node.metadata;
} else if (node is MixinDeclaration) {
- LazyMixinDeclaration.readMetadata(_astReader, node);
return node.metadata;
} else if (node is TypeParameter) {
- LazyTypeParameter.readMetadata(_astReader, node);
return node.metadata;
} else if (node is VariableDeclaration) {
var parent2 = node.parent.parent;
if (parent2 is FieldDeclaration) {
- LazyFieldDeclaration.readMetadata(_astReader, parent2);
return parent2.metadata;
} else if (parent2 is TopLevelVariableDeclaration) {
- LazyTopLevelVariableDeclaration.readMetadata(_astReader, parent2);
return parent2.metadata;
}
}
return const <Annotation>[];
}
- Iterable<MethodDeclaration> getMethods(CompilationUnitMember node) sync* {
- var members = _getClassOrExtensionOrMixinMembers(node);
- for (var member in members) {
- if (member is MethodDeclaration) {
- yield member;
- }
- }
- }
-
- List<String> getMixinSuperInvokedNames(MixinDeclaration node) {
- return LazyMixinDeclaration.get(node).getSuperInvokedNames();
+ List<MethodDeclaration> getMethods(CompilationUnitMember node) {
+ return _getClassOrExtensionOrMixinMembers(node)
+ .whereType<MethodDeclaration>()
+ .toList();
}
int getNameOffset(AstNode node) {
@@ -565,87 +377,24 @@
throw UnimplementedError('${node.runtimeType}');
}
- OnClause getOnClause(MixinDeclaration node) {
- LazyMixinDeclaration.readOnClause(_astReader, node);
- return node.onClause;
- }
-
/// Return the actual return type for the [node] - explicit or inferred.
DartType getReturnType(AstNode node) {
- if (node is FunctionDeclaration) {
- return LazyFunctionDeclaration.getReturnType(_astReader, node);
- } else if (node is FunctionTypeAlias) {
- return LazyFunctionTypeAlias.getReturnType(_astReader, node);
- } else if (node is GenericFunctionType) {
+ if (node is GenericFunctionType) {
return node.returnType?.type ?? DynamicTypeImpl.instance;
- } else if (node is MethodDeclaration) {
- return LazyMethodDeclaration.getReturnType(_astReader, node);
- } else {
- throw UnimplementedError('${node.runtimeType}');
}
- }
-
- TypeAnnotation getReturnTypeNode(AstNode node) {
- if (node is FunctionTypeAlias) {
- LazyFunctionTypeAlias.readReturnTypeNode(_astReader, node);
- return node.returnType;
- } else if (node is GenericFunctionType) {
- return node.returnType;
- } else if (node is FunctionDeclaration) {
- LazyFunctionDeclaration.readReturnTypeNode(_astReader, node);
- return node.returnType;
- } else if (node is MethodDeclaration) {
- LazyMethodDeclaration.readReturnTypeNode(_astReader, node);
- return node.returnType;
- } else {
- throw UnimplementedError('${node.runtimeType}');
- }
- }
-
- String getSelectedUri(UriBasedDirective node) {
- return LazyDirective.getSelectedUri(node);
+ throw UnimplementedError('${node.runtimeType}');
}
TypeName getSuperclass(AstNode node) {
if (node is ClassDeclaration) {
- LazyClassDeclaration.readExtendsClause(_astReader, node);
return node.extendsClause?.superclass;
} else if (node is ClassTypeAlias) {
- LazyClassTypeAlias.readSuperclass(_astReader, node);
return node.superclass;
} else {
throw StateError('${node.runtimeType}');
}
}
- /// Return the actual type for the [node] - explicit or inferred.
- DartType getType(AstNode node) {
- if (node is DefaultFormalParameter) {
- return getType(node.parameter);
- } else if (node is FormalParameter) {
- return LazyFormalParameter.getType(_astReader, node);
- } else if (node is VariableDeclaration) {
- return LazyVariableDeclaration.getType(_astReader, node);
- } else {
- throw UnimplementedError('${node.runtimeType}');
- }
- }
-
- TopLevelInferenceError getTypeInferenceError(AstNode node) {
- if (node is MethodDeclaration) {
- return LazyMethodDeclaration.getTypeInferenceError(node);
- } else if (node is VariableDeclaration) {
- return LazyVariableDeclaration.getTypeInferenceError(node);
- } else {
- return null;
- }
- }
-
- TypeAnnotation getTypeParameterBound(TypeParameter node) {
- LazyTypeParameter.readBound(_astReader, node);
- return node.bound;
- }
-
TypeParameterList getTypeParameters2(AstNode node) {
if (node is ClassDeclaration) {
return node.typeParameters;
@@ -660,7 +409,6 @@
} else if (node is FieldFormalParameter) {
return node.typeParameters;
} else if (node is FunctionDeclaration) {
- LazyFunctionDeclaration.readFunctionExpression(_astReader, node);
return getTypeParameters2(node.functionExpression);
} else if (node is FunctionExpression) {
return node.typeParameters;
@@ -683,36 +431,21 @@
}
}
- Variance getTypeParameterVariance(TypeParameter node) {
- return LazyAst.getVariance(node);
- }
-
WithClause getWithClause(AstNode node) {
if (node is ClassDeclaration) {
- LazyClassDeclaration.readWithClause(_astReader, node);
return node.withClause;
} else if (node is ClassTypeAlias) {
- LazyClassTypeAlias.readWithClause(_astReader, node);
return node.withClause;
} else {
throw UnimplementedError('${node.runtimeType}');
}
}
- bool hasDefaultValue(FormalParameter node) {
- if (node is DefaultFormalParameter) {
- return LazyFormalParameter.hasDefaultValue(node);
- }
- return false;
- }
-
bool hasImplicitReturnType(AstNode node) {
if (node is FunctionDeclaration) {
- LazyFunctionDeclaration.readReturnTypeNode(_astReader, node);
return node.returnType == null;
}
if (node is MethodDeclaration) {
- LazyMethodDeclaration.readReturnTypeNode(_astReader, node);
return node.returnType == null;
}
return false;
@@ -725,38 +458,26 @@
return node.type == null;
} else if (node is VariableDeclaration) {
VariableDeclarationList parent = node.parent;
- LazyVariableDeclarationList.readTypeNode(_astReader, parent);
return parent.type == null;
}
return false;
}
- bool hasInitializer(VariableDeclaration node) {
- return LazyVariableDeclaration.hasInitializer(node);
- }
-
- bool hasOperatorEqualParameterTypeFromObject(MethodDeclaration node) {
- return LazyAst.hasOperatorEqualParameterTypeFromObject(node);
- }
-
- bool hasOverrideInferenceDone(AstNode node) {
- // Only nodes in the libraries being linked might be not inferred yet.
- if (_astReader.isLazy) return true;
-
- return LazyAst.hasOverrideInferenceDone(node);
+ bool hasInitializer(VariableDeclarationImpl node) {
+ return node.initializer != null || node.hasInitializer;
}
bool isAbstract(AstNode node) {
if (node is ClassDeclaration) {
- return node.abstractKeyword != null;
+ return node.isAbstract;
} else if (node is ClassTypeAlias) {
- return node.abstractKeyword != null;
+ return node.isAbstract;
} else if (node is ConstructorDeclaration) {
return false;
} else if (node is FunctionDeclaration) {
return false;
} else if (node is MethodDeclaration) {
- return LazyMethodDeclaration.isAbstract(node);
+ return node.isAbstract;
} else if (node is VariableDeclaration) {
var parent = node.parent;
if (parent is VariableDeclarationList) {
@@ -779,12 +500,11 @@
if (node is ConstructorDeclaration) {
return false;
} else if (node is FunctionDeclaration) {
- LazyFunctionDeclaration.readFunctionExpression(_astReader, node);
return isAsynchronous(node.functionExpression);
} else if (node is FunctionExpression) {
- return LazyFunctionExpression.isAsynchronous(node);
+ return node.body.isAsynchronous;
} else if (node is MethodDeclaration) {
- return LazyMethodDeclaration.isAsynchronous(node);
+ return node.body.isAsynchronous;
} else {
throw UnimplementedError('${node.runtimeType}');
}
@@ -859,12 +579,11 @@
if (node is ConstructorDeclaration) {
return false;
} else if (node is FunctionDeclaration) {
- LazyFunctionDeclaration.readFunctionExpression(_astReader, node);
return isGenerator(node.functionExpression);
} else if (node is FunctionExpression) {
- return LazyFunctionExpression.isGenerator(node);
+ return node.body.isGenerator;
} else if (node is MethodDeclaration) {
- return LazyMethodDeclaration.isGenerator(node);
+ return node.body.isGenerator;
} else {
throw UnimplementedError('${node.runtimeType}');
}
@@ -908,10 +627,6 @@
}
}
- bool isSimplyBounded(AstNode node) {
- return LazyAst.isSimplyBounded(node);
- }
-
bool isStatic(AstNode node) {
if (node is FunctionDeclaration) {
return true;
@@ -924,141 +639,6 @@
throw UnimplementedError('${node.runtimeType}');
}
- Expression readInitializer(AstNode node) {
- if (node is DefaultFormalParameter) {
- LazyFormalParameter.readDefaultValue(_astReader, node);
- return node.defaultValue;
- } else if (node is VariableDeclaration) {
- LazyVariableDeclaration.readInitializer(_astReader, node);
- return node.initializer;
- } else {
- throw StateError('${node.runtimeType}');
- }
- }
-
- DartType readType(LinkedNodeType linkedType) {
- if (linkedType == null) return null;
-
- var kind = linkedType.kind;
- if (kind == LinkedNodeTypeKind.dynamic_) {
- return DynamicTypeImpl.instance;
- } else if (kind == LinkedNodeTypeKind.function) {
- var typeParameterDataList = linkedType.functionTypeParameters;
-
- var typeParametersLength = typeParameterDataList.length;
- var typeParameters = List<TypeParameterElement>(typeParametersLength);
- for (var i = 0; i < typeParametersLength; ++i) {
- var typeParameterData = typeParameterDataList[i];
- var element = TypeParameterElementImpl(typeParameterData.name, -1);
- typeParameters[i] = element;
- _typeParameters[_nextSyntheticTypeParameterId++] = element;
- }
-
- // Type parameters might use each other in bounds, including forward
- // references. So, we read bounds after reading all type parameters.
- for (var i = 0; i < typeParametersLength; ++i) {
- var typeParameterData = typeParameterDataList[i];
- TypeParameterElementImpl element = typeParameters[i];
- element.bound = readType(typeParameterData.bound);
- }
-
- var returnType = readType(linkedType.functionReturnType);
- var formalParameters = linkedType.functionFormalParameters.map((p) {
- var type = readType(p.type);
- var kind = _formalParameterKind(p.kind);
- return ParameterElementImpl.synthetic(p.name, type, kind);
- }).toList();
-
- for (var i = 0; i < typeParametersLength; ++i) {
- _typeParameters.remove(--_nextSyntheticTypeParameterId);
- }
-
- FunctionTypeAliasElement typedefElement;
- List<DartType> typedefTypeArguments = const <DartType>[];
- if (linkedType.functionTypedef != 0) {
- typedefElement =
- bundleContext.elementOfIndex(linkedType.functionTypedef);
- typedefTypeArguments =
- linkedType.functionTypedefTypeArguments.map(readType).toList();
- }
-
- var nullabilitySuffix = _nullabilitySuffix(linkedType.nullabilitySuffix);
-
- return FunctionTypeImpl(
- typeFormals: typeParameters,
- parameters: formalParameters,
- returnType: returnType,
- nullabilitySuffix: nullabilitySuffix,
- element: typedefElement,
- typeArguments: typedefTypeArguments,
- );
- } else if (kind == LinkedNodeTypeKind.interface) {
- var element = bundleContext.elementOfIndex(linkedType.interfaceClass);
- var nullabilitySuffix = _nullabilitySuffix(linkedType.nullabilitySuffix);
- return InterfaceTypeImpl(
- element: element,
- typeArguments: linkedType.interfaceTypeArguments.map(readType).toList(),
- nullabilitySuffix: nullabilitySuffix,
- );
- } else if (kind == LinkedNodeTypeKind.never) {
- var nullabilitySuffix = _nullabilitySuffix(linkedType.nullabilitySuffix);
- return NeverTypeImpl.instance.withNullability(nullabilitySuffix);
- } else if (kind == LinkedNodeTypeKind.typeParameter) {
- TypeParameterElement element;
- var id = linkedType.typeParameterId;
- if (id != 0) {
- element = _typeParameters[id];
- assert(element != null);
- } else {
- var index = linkedType.typeParameterElement;
- element = bundleContext.elementOfIndex(index);
- }
- var nullabilitySuffix = _nullabilitySuffix(linkedType.nullabilitySuffix);
- return TypeParameterTypeImpl(
- element: element,
- nullabilitySuffix: nullabilitySuffix,
- );
- } else if (kind == LinkedNodeTypeKind.void_) {
- return VoidTypeImpl.instance;
- } else {
- throw UnimplementedError('$kind');
- }
- }
-
- void setInheritsCovariant(AstNode node, bool value) {
- if (node is DefaultFormalParameter) {
- setInheritsCovariant(node.parameter, value);
- } else if (node is FormalParameter) {
- LazyAst.setInheritsCovariant(node, value);
- } else if (node is VariableDeclaration) {
- LazyAst.setInheritsCovariant(node, value);
- } else {
- throw StateError('${node.runtimeType}');
- }
- }
-
- void setOperatorEqualParameterTypeFromObject(AstNode node, bool value) {
- LazyAst.setOperatorEqualParameterTypeFromObject(node, value);
- }
-
- void setOverrideInferenceDone(AstNode node) {
- // TODO(scheglov) This assert fails, check how to avoid this.
-// assert(!_astReader.isLazy);
- LazyAst.setOverrideInferenceDone(node);
- }
-
- void setReturnType(AstNode node, DartType type) {
- LazyAst.setReturnType(node, type);
- }
-
- void setVariableType(AstNode node, DartType type) {
- if (node is DefaultFormalParameter) {
- setVariableType(node.parameter, type);
- } else {
- LazyAst.setType(node, type);
- }
- }
-
bool shouldBeConstFieldElement(AstNode node) {
if (node is VariableDeclaration) {
VariableDeclarationList variableList = node.parent;
@@ -1069,11 +649,19 @@
if (variableList.isFinal) {
var class_ = fieldDeclaration.parent;
- if (class_ is ClassOrMixinDeclaration) {
- for (var member in class_.members) {
- if (member is ConstructorDeclaration &&
- member.constKeyword != null) {
- return true;
+ if (class_ is ClassDeclaration) {
+ var hasLinkedContext = class_ as HasAstLinkedContext;
+ var linkedContext = hasLinkedContext.linkedContext;
+ // TODO(scheglov) Get rid of this check, exists only for linking.
+ // Maybe we should pre-create all elements before linking.
+ if (linkedContext != null) {
+ return linkedContext.isClassWithConstConstructor;
+ } else {
+ for (var member in class_.members) {
+ if (member is ConstructorDeclaration &&
+ member.constKeyword != null) {
+ return true;
+ }
}
}
}
@@ -1082,85 +670,49 @@
return false;
}
- Iterable<VariableDeclaration> topLevelVariables(CompilationUnit unit) sync* {
+ List<VariableDeclaration> topLevelVariables(CompilationUnit unit) {
+ var variables = <VariableDeclaration>[];
for (var declaration in unit.declarations) {
if (declaration is TopLevelVariableDeclaration) {
- for (var variable in declaration.variables.variables) {
- yield variable;
- }
+ variables.addAll(declaration.variables.variables);
}
}
- }
-
- void _ensureUnitWithDeclarations() {
- if (_unit == null) {
- _unit = _astReader.readNode(data.node);
-
- var informativeData = getInformativeData(data.node);
- var lineStarts = informativeData?.compilationUnit_lineStarts ?? [];
- if (lineStarts.isEmpty) {
- lineStarts = [0];
- }
- _unit.lineInfo = LineInfo(lineStarts);
- }
- }
-
- ParameterKind _formalParameterKind(LinkedNodeFormalParameterKind kind) {
- if (kind == LinkedNodeFormalParameterKind.optionalNamed) {
- return ParameterKind.NAMED;
- } else if (kind == LinkedNodeFormalParameterKind.optionalPositional) {
- return ParameterKind.POSITIONAL;
- } else if (kind == LinkedNodeFormalParameterKind.requiredNamed) {
- return ParameterKind.NAMED_REQUIRED;
- }
- return ParameterKind.REQUIRED;
+ return variables;
}
List<ClassMember> _getClassOrExtensionOrMixinMembers(
CompilationUnitMember node,
) {
- if (node is ClassDeclaration) {
- LazyClassDeclaration.readMembers(_astReader, node);
- return node.members;
- } else if (node is ClassTypeAlias) {
- return <ClassMember>[];
- } else if (node is ExtensionDeclaration) {
- LazyExtensionDeclaration.readMembers(_astReader, node);
- return node.members;
- } else if (node is MixinDeclaration) {
- LazyMixinDeclaration.readMembers(_astReader, node);
- return node.members;
+ var linkedContext = (node as HasAstLinkedContext).linkedContext;
+ if (linkedContext != null) {
+ return linkedContext.classMembers;
} else {
- throw StateError('${node.runtimeType}');
+ if (node is ClassDeclaration) {
+ return node.members;
+ } else if (node is ClassTypeAlias) {
+ return <ClassMember>[];
+ } else if (node is ExtensionDeclaration) {
+ return node.members;
+ } else if (node is MixinDeclaration) {
+ return node.members;
+ } else {
+ throw StateError('${node.runtimeType}');
+ }
}
}
NodeList<Annotation> _getPartDirectiveAnnotation() {
var definingContext = libraryContext.definingUnit;
- var unit = definingContext.unit;
+ var definingUnit = definingContext.unit_withDirectives;
var partDirectiveIndex = 0;
- for (var directive in unit.directives) {
+ for (var directive in definingUnit.directives) {
if (directive is PartDirective) {
partDirectiveIndex++;
if (partDirectiveIndex == indexInLibrary) {
- LazyDirective.readMetadata(definingContext._astReader, directive);
return directive.metadata;
}
}
}
throw StateError('Expected to find $indexInLibrary part directive.');
}
-
- static NullabilitySuffix _nullabilitySuffix(EntityRefNullabilitySuffix data) {
- switch (data) {
- case EntityRefNullabilitySuffix.starOrIrrelevant:
- return NullabilitySuffix.star;
- case EntityRefNullabilitySuffix.question:
- return NullabilitySuffix.question;
- case EntityRefNullabilitySuffix.none:
- return NullabilitySuffix.none;
- default:
- throw StateError('$data');
- }
- }
}
diff --git a/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart b/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart
deleted file mode 100644
index 81cf9c2b..0000000
--- a/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart
+++ /dev/null
@@ -1,223 +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/element/element.dart';
-import 'package:analyzer/dart/element/nullability_suffix.dart';
-import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/member.dart';
-import 'package:analyzer/src/dart/element/type_algebra.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary2/reference.dart';
-
-class LinkingBundleContext {
- /// The `dynamic` class is declared in `dart:core`, but is not a class.
- /// Also, it is static, so we cannot set `reference` for it.
- /// So, we have to push it in a separate way.
- final Reference dynamicReference;
-
- /// References used in all libraries being linked.
- /// Element references in nodes are indexes in this list.
- final List<Reference> references = [null];
-
- /// Data about [references].
- final LinkedNodeReferencesBuilder referencesBuilder =
- LinkedNodeReferencesBuilder(
- parent: [0],
- name: [''],
- );
-
- final Map<TypeParameterElement, int> _typeParameters = Map.identity();
- int _nextSyntheticTypeParameterId = 0x10000;
-
- LinkingBundleContext(this.dynamicReference);
-
- /// We need indexes for references during linking, but once we are done,
- /// we must clear indexes to make references ready for linking a next bundle.
- void clearIndexes() {
- for (var reference in references) {
- if (reference != null) {
- reference.index = null;
- }
- }
- }
-
- int idOfTypeParameter(TypeParameterElement element) {
- return _typeParameters[element];
- }
-
- int indexOfElement(Element element) {
- if (element == null) return 0;
- if (element is MultiplyDefinedElement) return 0;
- assert(element is! Member);
-
- if (identical(element, DynamicElementImpl.instance)) {
- return indexOfReference(dynamicReference);
- }
-
- var reference = (element as ElementImpl).reference;
- return indexOfReference(reference);
- }
-
- int indexOfReference(Reference reference) {
- if (reference == null) return 0;
- if (reference.parent == null) return 0;
- if (reference.index != null) return reference.index;
-
- var parentIndex = indexOfReference(reference.parent);
- referencesBuilder.parent.add(parentIndex);
- referencesBuilder.name.add(reference.name);
-
- reference.index = references.length;
- references.add(reference);
- return reference.index;
- }
-
- LinkedNodeTypeBuilder writeType(DartType type) {
- if (type == null) return null;
-
- if (type.isDynamic) {
- return LinkedNodeTypeBuilder(
- kind: LinkedNodeTypeKind.dynamic_,
- );
- } else if (type is FunctionType) {
- return _writeFunctionType(type);
- } else if (type is InterfaceType) {
- return LinkedNodeTypeBuilder(
- kind: LinkedNodeTypeKind.interface,
- interfaceClass: indexOfElement(type.element),
- interfaceTypeArguments: type.typeArguments.map(writeType).toList(),
- nullabilitySuffix: _nullabilitySuffix(type),
- );
- } else if (type is NeverType) {
- return LinkedNodeTypeBuilder(
- kind: LinkedNodeTypeKind.never,
- nullabilitySuffix: _nullabilitySuffix(type),
- );
- } else if (type is TypeParameterType) {
- TypeParameterElementImpl element = type.element;
- var id = _typeParameters[element];
- if (id != null) {
- return LinkedNodeTypeBuilder(
- kind: LinkedNodeTypeKind.typeParameter,
- nullabilitySuffix: _nullabilitySuffix(type),
- typeParameterId: id,
- );
- } else {
- var index = indexOfElement(element);
- return LinkedNodeTypeBuilder(
- kind: LinkedNodeTypeKind.typeParameter,
- nullabilitySuffix: _nullabilitySuffix(type),
- typeParameterElement: index,
- );
- }
- } else if (type is VoidType) {
- return LinkedNodeTypeBuilder(
- kind: LinkedNodeTypeKind.void_,
- );
- } else {
- throw UnimplementedError('(${type.runtimeType}) $type');
- }
- }
-
- LinkedNodeFormalParameterKind _formalParameterKind(ParameterElement p) {
- if (p.isRequiredPositional) {
- return LinkedNodeFormalParameterKind.requiredPositional;
- } else if (p.isRequiredNamed) {
- return LinkedNodeFormalParameterKind.requiredNamed;
- } else if (p.isOptionalPositional) {
- return LinkedNodeFormalParameterKind.optionalPositional;
- } else if (p.isOptionalNamed) {
- return LinkedNodeFormalParameterKind.optionalNamed;
- } else {
- throw StateError('Unexpected parameter kind: $p');
- }
- }
-
- FunctionType _toSyntheticFunctionType(FunctionType type) {
- var typeParameters = type.typeFormals;
-
- if (typeParameters.isEmpty) return type;
-
- var onlySyntheticTypeParameters = typeParameters.every((e) {
- return e is TypeParameterElementImpl && e.linkedNode == null;
- });
- if (onlySyntheticTypeParameters) return type;
-
- var parameters = getFreshTypeParameters(typeParameters);
- return parameters.applyToFunctionType(type);
- }
-
- LinkedNodeTypeBuilder _writeFunctionType(FunctionType type) {
- type = _toSyntheticFunctionType(type);
-
- var typeParameterBuilders = <LinkedNodeTypeTypeParameterBuilder>[];
-
- var typeParameters = type.typeFormals;
- for (var i = 0; i < typeParameters.length; ++i) {
- var typeParameter = typeParameters[i];
- _typeParameters[typeParameter] = _nextSyntheticTypeParameterId++;
- typeParameterBuilders.add(
- LinkedNodeTypeTypeParameterBuilder(name: typeParameter.name),
- );
- }
-
- for (var i = 0; i < typeParameters.length; ++i) {
- var typeParameter = typeParameters[i];
- typeParameterBuilders[i].bound = writeType(typeParameter.bound);
- }
-
- Element typedefElement;
- List<DartType> typedefTypeArguments = const <DartType>[];
- if (type.element is FunctionTypeAliasElement) {
- typedefElement = type.element;
- typedefTypeArguments = type.typeArguments;
- }
- // TODO(scheglov) Cleanup to always use FunctionTypeAliasElement.
- if (type.element is GenericFunctionTypeElement &&
- type.element.enclosingElement is FunctionTypeAliasElement) {
- typedefElement = type.element.enclosingElement;
- typedefTypeArguments = type.typeArguments;
- }
-
- var result = LinkedNodeTypeBuilder(
- kind: LinkedNodeTypeKind.function,
- functionFormalParameters: type.parameters
- .map((p) => LinkedNodeTypeFormalParameterBuilder(
- kind: _formalParameterKind(p),
- name: p.name,
- type: writeType(p.type),
- ))
- .toList(),
- functionReturnType: writeType(type.returnType),
- functionTypeParameters: typeParameterBuilders,
- functionTypedef: indexOfElement(typedefElement),
- functionTypedefTypeArguments:
- typedefTypeArguments.map(writeType).toList(),
- nullabilitySuffix: _nullabilitySuffix(type),
- );
-
- for (var typeParameter in typeParameters) {
- _typeParameters.remove(typeParameter);
- --_nextSyntheticTypeParameterId;
- }
-
- return result;
- }
-
- static EntityRefNullabilitySuffix _nullabilitySuffix(DartType type) {
- var nullabilitySuffix = type.nullabilitySuffix;
- switch (nullabilitySuffix) {
- case NullabilitySuffix.question:
- return EntityRefNullabilitySuffix.question;
- case NullabilitySuffix.star:
- return EntityRefNullabilitySuffix.starOrIrrelevant;
- case NullabilitySuffix.none:
- return EntityRefNullabilitySuffix.none;
- default:
- throw StateError('$nullabilitySuffix');
- }
- }
-}
diff --git a/pkg/analyzer/lib/src/summary2/named_type_builder.dart b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
index fdf0073..0b037aa 100644
--- a/pkg/analyzer/lib/src/summary2/named_type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
@@ -13,12 +13,13 @@
import 'package:analyzer/src/dart/element/type_algebra.dart';
import 'package:analyzer/src/dart/element/type_system.dart';
import 'package:analyzer/src/dart/element/type_visitor.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
import 'package:analyzer/src/summary2/type_builder.dart';
import 'package:meta/meta.dart';
/// The type builder for a [TypeName].
class NamedTypeBuilder extends TypeBuilder {
+ /// TODO(scheglov) Replace with `DartType` in `TypeAliasElementImpl`.
+ static const _rawFunctionTypeKey = '_rawFunctionType';
static DynamicTypeImpl get _dynamicType => DynamicTypeImpl.instance;
/// The type system of the library with the type name.
@@ -266,11 +267,11 @@
var typedefNode = element.linkedNode;
// Break a possible recursion.
- var existing = LazyAst.getRawFunctionType(typedefNode);
+ var existing = typedefNode.getProperty(_rawFunctionTypeKey) as DartType;
if (existing != null) {
return existing;
} else {
- LazyAst.setRawFunctionType(typedefNode, _dynamicType);
+ _setRawFunctionType(typedefNode, _dynamicType);
}
if (typedefNode is FunctionTypeAlias) {
@@ -280,12 +281,12 @@
parameterList: typedefNode.parameters,
hasQuestion: false,
);
- LazyAst.setRawFunctionType(typedefNode, result);
+ _setRawFunctionType(typedefNode, result);
return result;
} else if (typedefNode is GenericTypeAlias) {
var functionNode = typedefNode.functionType;
var functionType = _buildGenericFunctionType(functionNode);
- LazyAst.setRawFunctionType(typedefNode, functionType);
+ _setRawFunctionType(typedefNode, functionType);
return functionType;
} else {
throw StateError('(${element.runtimeType}) $element');
@@ -305,6 +306,10 @@
return List<DartType>.filled(length, _dynamicType);
}
+ static void _setRawFunctionType(AstNode node, DartType type) {
+ node.setProperty(_rawFunctionTypeKey, type);
+ }
+
static List<TypeParameterElement> _typeParameters(TypeParameterList node) {
if (node != null) {
return node.typeParameters
diff --git a/pkg/analyzer/lib/src/summary2/package_bundle_format.dart b/pkg/analyzer/lib/src/summary2/package_bundle_format.dart
new file mode 100644
index 0000000..cb47263
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/package_bundle_format.dart
@@ -0,0 +1,133 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:typed_data';
+
+import 'package:analyzer/src/summary2/data_reader.dart';
+import 'package:analyzer/src/summary2/data_writer.dart';
+import 'package:meta/meta.dart';
+
+class PackageBundleBuilder {
+ final List<PackageBundleLibrary> _libraries = [];
+
+ void addLibrary(String uriStr, List<String> unitUriStrList) {
+ _libraries.add(
+ PackageBundleLibrary(
+ uriStr,
+ unitUriStrList.map((e) => PackageBundleUnit(e)).toList(),
+ ),
+ );
+ }
+
+ Uint8List finish({
+ @required Uint8List astBytes,
+ @required Uint8List resolutionBytes,
+ PackageBundleSdk sdk,
+ }) {
+ var byteSink = ByteSink();
+ var sink = BufferedSink(byteSink);
+
+ if (sdk != null) {
+ sink.writeByte(1);
+ sdk._write(sink);
+ } else {
+ sink.writeByte(0);
+ }
+
+ sink.writeList(_libraries, (PackageBundleLibrary library) {
+ sink.writeStringUtf8(library.uriStr);
+ sink.writeList(
+ library.units,
+ (PackageBundleUnit unit) => sink.writeStringUtf8(unit.uriStr),
+ );
+ });
+
+ sink.writeUint8List(astBytes);
+ sink.writeUint8List(resolutionBytes);
+
+ sink.flushAndDestroy();
+ return byteSink.builder.takeBytes();
+ }
+}
+
+@internal
+class PackageBundleLibrary {
+ final String uriStr;
+ final List<PackageBundleUnit> units;
+
+ PackageBundleLibrary(this.uriStr, this.units);
+}
+
+class PackageBundleReader {
+ final List<PackageBundleLibrary> libraries = [];
+ PackageBundleSdk _sdk;
+ Uint8List _astBytes;
+ Uint8List _resolutionBytes;
+
+ PackageBundleReader(Uint8List bytes) {
+ var reader = SummaryDataReader(bytes);
+
+ var hasSdk = reader.readByte() != 0;
+ if (hasSdk) {
+ _sdk = PackageBundleSdk._fromReader(reader);
+ }
+
+ var librariesLength = reader.readUInt30();
+ for (var i = 0; i < librariesLength; i++) {
+ var uriStr = reader.readStringUtf8();
+ var unitsLength = reader.readUInt30();
+ var units = List.generate(unitsLength, (_) {
+ var uriStr = reader.readStringUtf8();
+ return PackageBundleUnit(uriStr);
+ });
+ libraries.add(
+ PackageBundleLibrary(uriStr, units),
+ );
+ }
+
+ _astBytes = reader.readUint8List();
+ _resolutionBytes = reader.readUint8List();
+ }
+
+ Uint8List get astBytes => _astBytes;
+
+ Uint8List get resolutionBytes => _resolutionBytes;
+
+ PackageBundleSdk get sdk => _sdk;
+}
+
+class PackageBundleSdk {
+ final int languageVersionMajor;
+ final int languageVersionMinor;
+
+ /// The content of the `allowed_experiments.json` from SDK.
+ final String allowedExperimentsJson;
+
+ PackageBundleSdk({
+ @required this.languageVersionMajor,
+ @required this.languageVersionMinor,
+ @required this.allowedExperimentsJson,
+ });
+
+ factory PackageBundleSdk._fromReader(SummaryDataReader reader) {
+ return PackageBundleSdk(
+ languageVersionMajor: reader.readUInt30(),
+ languageVersionMinor: reader.readUInt30(),
+ allowedExperimentsJson: reader.readStringUtf8(),
+ );
+ }
+
+ void _write(BufferedSink sink) {
+ sink.writeUInt30(languageVersionMajor);
+ sink.writeUInt30(languageVersionMinor);
+ sink.writeStringUtf8(allowedExperimentsJson);
+ }
+}
+
+@internal
+class PackageBundleUnit {
+ final String uriStr;
+
+ PackageBundleUnit(this.uriStr);
+}
diff --git a/pkg/analyzer/lib/src/summary2/package_bundle_reader.dart b/pkg/analyzer/lib/src/summary2/package_bundle_reader.dart
index 234ee2c..ec05912 100644
--- a/pkg/analyzer/lib/src/summary2/package_bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/package_bundle_reader.dart
@@ -2,4 +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.
-export 'package:analyzer/src/summary/idl.dart' show PackageBundle;
+import 'dart:typed_data';
+
+import 'package:analyzer/src/summary2/package_bundle_format.dart';
+
+class PackageBundle extends PackageBundleReader {
+ PackageBundle.fromBuffer(Uint8List bytes) : super(bytes);
+}
diff --git a/pkg/analyzer/lib/src/summary2/reference.dart b/pkg/analyzer/lib/src/summary2/reference.dart
index 7eb7f68..6cd096b 100644
--- a/pkg/analyzer/lib/src/summary2/reference.dart
+++ b/pkg/analyzer/lib/src/summary2/reference.dart
@@ -32,6 +32,10 @@
/// The simple name of the reference in its [parent].
final String name;
+ /// The node accessor, used to read nodes lazily.
+ /// Or `null` if a named container.
+ ReferenceNodeAccessor nodeAccessor;
+
/// The corresponding [AstNode], or `null` if a named container.
AstNode node;
@@ -59,16 +63,28 @@
bool get isClass => parent != null && parent.name == '@class';
+ bool get isConstructor => parent != null && parent.name == '@constructor';
+
bool get isDynamic => name == 'dynamic' && parent?.name == 'dart:core';
bool get isEnum => parent != null && parent.name == '@enum';
+ bool get isGetter => parent != null && parent.name == '@getter';
+
+ bool get isLibrary => parent != null && parent.isRoot;
+
+ bool get isParameter => parent != null && parent.name == '@parameter';
+
bool get isPrefix => parent != null && parent.name == '@prefix';
+ bool get isRoot => parent == null;
+
bool get isSetter => parent != null && parent.name == '@setter';
bool get isTypeAlias => parent != null && parent.name == '@typeAlias';
+ bool get isUnit => parent != null && parent.name == '@unit';
+
/// Return the child with the given name, or `null` if does not exist.
Reference operator [](String name) {
return _children != null ? _children[name] : null;
@@ -102,3 +118,13 @@
@override
String toString() => parent == null ? 'root' : '$parent::$name';
}
+
+abstract class ReferenceNodeAccessor {
+ /// Return the node that corresponds to this [Reference], read it if not yet.
+ AstNode get node;
+
+ /// Fill [Reference.nodeAccessor] for children.
+ ///
+ /// TODO(scheglov) only class reader has a meaningful implementation.
+ void readIndex();
+}
diff --git a/pkg/analyzer/lib/src/summary2/reference_resolver.dart b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
index 4083b28..d6f67f5 100644
--- a/pkg/analyzer/lib/src/summary2/reference_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
@@ -12,9 +12,7 @@
import 'package:analyzer/src/dart/element/scope.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_system.dart';
-import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary2/function_type_builder.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
import 'package:analyzer/src/summary2/linked_element_factory.dart';
import 'package:analyzer/src/summary2/linking_node_scope.dart';
import 'package:analyzer/src/summary2/named_type_builder.dart';
@@ -45,9 +43,6 @@
Reference reference;
Scope scope;
- /// Is `true` if the current [ClassDeclaration] has a const constructor.
- bool _hasConstConstructor = false;
-
ReferenceResolver(
this.nodesToBuildType,
this.elementFactory,
@@ -72,7 +67,7 @@
element.constructors; // create elements
element.methods; // create elements
- _createTypeParameterElements(node.typeParameters);
+ _createTypeParameterElements(element, node.typeParameters);
scope = TypeParameterScope(scope, element.typeParameters);
node.typeParameters?.accept(this);
@@ -83,14 +78,6 @@
scope = ClassScope(scope, element);
LinkingNodeContext(node, scope);
- _hasConstConstructor = false;
- for (var member in node.members) {
- if (member is ConstructorDeclaration && member.constKeyword != null) {
- _hasConstConstructor = true;
- break;
- }
- }
-
node.members.accept(this);
nodesToBuildType.addDeclaration(node);
@@ -106,7 +93,7 @@
var element = node.declaredElement as ClassElementImpl;
reference = element.reference;
- _createTypeParameterElements(node.typeParameters);
+ _createTypeParameterElements(element, node.typeParameters);
scope = TypeParameterScope(scope, element.typeParameters);
LinkingNodeContext(node, scope);
@@ -139,9 +126,6 @@
LinkingNodeContext(node, scope);
node.parameters?.accept(this);
- node.initializers.accept(
- _SetGenericFunctionTypeIdVisitor(this),
- );
scope = outerScope;
reference = outerReference;
@@ -150,9 +134,6 @@
@override
void visitDefaultFormalParameter(DefaultFormalParameter node) {
node.parameter.accept(this);
- node.defaultValue?.accept(
- _SetGenericFunctionTypeIdVisitor(this),
- );
}
@override
@@ -174,7 +155,7 @@
var element = node.declaredElement as ExtensionElementImpl;
reference = element.reference;
- _createTypeParameterElements(node.typeParameters);
+ _createTypeParameterElements(element, node.typeParameters);
scope = TypeParameterScope(scope, element.typeParameters);
node.typeParameters?.accept(this);
@@ -193,12 +174,6 @@
@override
void visitFieldDeclaration(FieldDeclaration node) {
node.fields.accept(this);
-
- if (node.fields.isConst ||
- !node.isStatic && node.fields.isFinal && _hasConstConstructor) {
- var visitor = _SetGenericFunctionTypeIdVisitor(this);
- node.fields.variables.accept(visitor);
- }
}
@override
@@ -210,7 +185,7 @@
reference = element.reference;
element.parameters; // create elements
- _createTypeParameterElements(node.typeParameters);
+ _createTypeParameterElements(element, node.typeParameters);
scope = TypeParameterScope(scope, element.typeParameters);
node.type?.accept(this);
@@ -236,7 +211,10 @@
reference = element.reference;
element.parameters; // create elements
- _createTypeParameterElements(node.functionExpression.typeParameters);
+ _createTypeParameterElements(
+ element,
+ node.functionExpression.typeParameters,
+ );
scope = TypeParameterScope(outerScope, element.typeParameters);
LinkingNodeContext(node, scope);
@@ -262,7 +240,7 @@
var element = node.declaredElement as FunctionTypeAliasElementImpl;
reference = element.reference;
- _createTypeParameterElements(node.typeParameters);
+ _createTypeParameterElements(element, node.typeParameters);
scope = TypeParameterScope(outerScope, element.typeParameters);
node.returnType?.accept(this);
@@ -288,7 +266,7 @@
reference = element.reference;
element.parameters; // create elements
- _createTypeParameterElements(node.typeParameters);
+ _createTypeParameterElements(element, node.typeParameters);
scope = TypeParameterScope(scope, element.typeParameters);
node.returnType?.accept(this);
@@ -305,9 +283,8 @@
var outerScope = scope;
var outerReference = reference;
+ // TODO(scheglov) remove reference
var id = _nextGenericFunctionTypeId++;
- LazyAst.setGenericFunctionTypeId(node, id);
-
var containerRef = unitReference.getChild('@genericFunctionType');
reference = containerRef.getChild('$id');
@@ -316,10 +293,9 @@
reference,
node,
);
- (node as GenericFunctionTypeImpl).declaredElement = element;
element.parameters; // create elements
- _createTypeParameterElements(node.typeParameters);
+ _createTypeParameterElements(element, node.typeParameters);
scope = TypeParameterScope(outerScope, element.typeParameters);
node.returnType?.accept(this);
@@ -343,13 +319,20 @@
var element = node.declaredElement as FunctionTypeAliasElementImpl;
reference = element.reference;
- _createTypeParameterElements(node.typeParameters);
+ _createTypeParameterElements(element, node.typeParameters);
scope = TypeParameterScope(outerScope, element.typeParameters);
node.typeParameters?.accept(this);
node.type?.accept(this);
nodesToBuildType.addDeclaration(node);
+ var aliasedType = node.type;
+ if (aliasedType is GenericFunctionTypeImpl) {
+ element.encloseElement(
+ aliasedType.declaredElement as GenericFunctionTypeElementImpl,
+ );
+ }
+
scope = outerScope;
reference = outerReference;
}
@@ -368,7 +351,7 @@
reference = element.reference;
element.parameters; // create elements
- _createTypeParameterElements(node.typeParameters);
+ _createTypeParameterElements(element, node.typeParameters);
scope = TypeParameterScope(scope, element.typeParameters);
LinkingNodeContext(node, scope);
@@ -393,7 +376,7 @@
element.constructors; // create elements
element.methods; // create elements
- _createTypeParameterElements(node.typeParameters);
+ _createTypeParameterElements(element, node.typeParameters);
scope = TypeParameterScope(scope, element.typeParameters);
node.typeParameters?.accept(this);
@@ -424,10 +407,6 @@
@override
void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
node.variables.accept(this);
- if (node.variables.isConst) {
- var visitor = _SetGenericFunctionTypeIdVisitor(this);
- node.variables.variables.accept(visitor);
- }
}
@override
@@ -507,25 +486,25 @@
node.mixinTypes.accept(this);
}
- void _createTypeParameterElement(TypeParameter node) {
- var outerReference = this.reference;
- var containerRef = outerReference.getChild('@typeParameter');
- var reference = containerRef.getChild(node.name.name);
- reference.node = node;
-
+ void _createTypeParameterElement(
+ ElementImpl enclosingElement,
+ TypeParameter node,
+ ) {
var element = TypeParameterElementImpl.forLinkedNode(
- outerReference.element,
- reference,
+ enclosingElement,
node,
);
node.name.staticElement = element;
}
- void _createTypeParameterElements(TypeParameterList typeParameterList) {
+ void _createTypeParameterElements(
+ ElementImpl enclosingElement,
+ TypeParameterList typeParameterList,
+ ) {
if (typeParameterList == null) return;
for (var typeParameter in typeParameterList.typeParameters) {
- _createTypeParameterElement(typeParameter);
+ _createTypeParameterElement(enclosingElement, typeParameter);
}
}
@@ -541,20 +520,3 @@
}
}
}
-
-/// For consistency we set identifiers for [GenericFunctionType]s in constant
-/// variable initializers, and instance final fields of classes with constant
-/// constructors.
-class _SetGenericFunctionTypeIdVisitor extends RecursiveAstVisitor<void> {
- final ReferenceResolver resolver;
-
- _SetGenericFunctionTypeIdVisitor(this.resolver);
-
- @override
- void visitGenericFunctionType(GenericFunctionType node) {
- var id = resolver._nextGenericFunctionTypeId++;
- LazyAst.setGenericFunctionTypeId(node, id);
-
- super.visitGenericFunctionType(node);
- }
-}
diff --git a/pkg/analyzer/lib/src/summary2/simply_bounded.dart b/pkg/analyzer/lib/src/summary2/simply_bounded.dart
index aa7d95f..8053556 100644
--- a/pkg/analyzer/lib/src/summary2/simply_bounded.dart
+++ b/pkg/analyzer/lib/src/summary2/simply_bounded.dart
@@ -7,18 +7,15 @@
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/summary/link.dart' as graph
show DependencyWalker, Node;
-import 'package:analyzer/src/summary2/lazy_ast.dart';
import 'package:analyzer/src/summary2/library_builder.dart';
-import 'package:analyzer/src/summary2/linked_bundle_context.dart';
/// Compute simple-boundedness for all classes and generic types aliases in
/// the source [libraryBuilders]. There might be dependencies between them,
/// so they all should be processed simultaneously.
void computeSimplyBounded(
- LinkedBundleContext bundleContext,
Iterable<LibraryBuilder> libraryBuilders,
) {
- var walker = SimplyBoundedDependencyWalker(bundleContext);
+ var walker = SimplyBoundedDependencyWalker();
var nodes = <SimplyBoundedNode>[];
for (var libraryBuilder in libraryBuilders) {
for (var unit in libraryBuilder.element.units) {
@@ -41,18 +38,30 @@
if (!node.isEvaluated) {
walker.walk(node);
}
- LazyAst.setSimplyBounded(node._node, node.isSimplyBounded);
+ var node2 = node._node;
+ if (node2 is ClassOrMixinDeclaration) {
+ var element = node2.declaredElement as ClassElementImpl;
+ element.isSimplyBounded = node.isSimplyBounded;
+ } else if (node2 is ClassTypeAlias) {
+ var element = node2.declaredElement as ClassElementImpl;
+ element.isSimplyBounded = node.isSimplyBounded;
+ } else if (node2 is GenericTypeAlias) {
+ var element = node2.declaredElement as FunctionTypeAliasElementImpl;
+ element.isSimplyBounded = node.isSimplyBounded;
+ } else if (node2 is FunctionTypeAlias) {
+ var element = node2.declaredElement as FunctionTypeAliasElementImpl;
+ element.isSimplyBounded = node.isSimplyBounded;
+ } else {
+ throw UnimplementedError('${node2.runtimeType}');
+ }
}
}
/// The graph walker for evaluating whether types are simply bounded.
class SimplyBoundedDependencyWalker
extends graph.DependencyWalker<SimplyBoundedNode> {
- final LinkedBundleContext bundleContext;
final Map<Element, SimplyBoundedNode> nodeMap = Map.identity();
- SimplyBoundedDependencyWalker(this.bundleContext);
-
@override
void evaluate(SimplyBoundedNode v) {
v._evaluate();
diff --git a/pkg/analyzer/lib/src/summary2/tokens_context.dart b/pkg/analyzer/lib/src/summary2/tokens_context.dart
index ab8ad17..95fd9c6 100644
--- a/pkg/analyzer/lib/src/summary2/tokens_context.dart
+++ b/pkg/analyzer/lib/src/summary2/tokens_context.dart
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary2/unlinked_token_type.dart';
/// The context for reading tokens.
class TokensContext {
diff --git a/pkg/analyzer/lib/src/summary2/tokens_writer.dart b/pkg/analyzer/lib/src/summary2/tokens_writer.dart
index 3e8bc74..e115141 100644
--- a/pkg/analyzer/lib/src/summary2/tokens_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/tokens_writer.dart
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary2/unlinked_token_type.dart';
class TokensWriter {
static UnlinkedTokenType astToBinaryTokenType(TokenType type) {
diff --git a/pkg/analyzer/lib/src/summary2/top_level_inference.dart b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
index 6639055..cafca28 100644
--- a/pkg/analyzer/lib/src/summary2/top_level_inference.dart
+++ b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
@@ -11,14 +11,12 @@
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_system.dart';
import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/link.dart' as graph
show DependencyWalker, Node;
import 'package:analyzer/src/summary2/ast_resolver.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
import 'package:analyzer/src/summary2/link.dart';
import 'package:analyzer/src/summary2/linking_node_scope.dart';
+import 'package:analyzer/src/task/inference_error.dart';
import 'package:analyzer/src/task/strong_mode.dart';
import 'package:meta/meta.dart';
@@ -159,7 +157,8 @@
_parameters.add(parameterNode);
_fields.add(fieldElement);
} else {
- LazyAst.setType(parameterNode, DynamicTypeImpl.instance);
+ (parameterElement as ParameterElementImpl).type =
+ DynamicTypeImpl.instance;
}
}
}
@@ -179,7 +178,6 @@
for (var i = 0; i < _parameters.length; ++i) {
var parameter = _parameters[i];
var type = _fields[i].type;
- LazyAst.setType(parameter, type);
(parameter.declaredElement as ParameterElementImpl).type = type;
}
isEvaluated = true;
@@ -189,7 +187,8 @@
void markCircular(List<_InferenceNode> cycle) {
for (var i = 0; i < _parameters.length; ++i) {
var parameterNode = _parameters[i];
- LazyAst.setType(parameterNode, DynamicTypeImpl.instance);
+ (parameterNode.declaredElement as ParameterElementImpl).type =
+ DynamicTypeImpl.instance;
}
isEvaluated = true;
}
@@ -322,8 +321,11 @@
void _addVariableNode(PropertyInducingElement element) {
if (element.isSynthetic) return;
- VariableDeclaration node = _getLinkedNode(element);
- if (LazyAst.getType(node) != null) return;
+ var node = _getLinkedNode(element) as VariableDeclaration;
+ var variableList = node.parent as VariableDeclarationList;
+ if (variableList.type != null) {
+ return;
+ }
if (node.initializer != null) {
var inferenceNode =
@@ -332,7 +334,7 @@
(element as PropertyInducingElementImpl).typeInference =
_PropertyInducingElementTypeInference(inferenceNode);
} else {
- LazyAst.setType(node, DynamicTypeImpl.instance);
+ (element as PropertyInducingElementImpl).type = DynamicTypeImpl.instance;
}
}
}
@@ -382,6 +384,10 @@
return false;
}
+ PropertyInducingElementImpl get _elementImpl {
+ return _node.declaredElement as PropertyInducingElementImpl;
+ }
+
@override
List<_InferenceNode> computeDependencies() {
_resolveInitializer(forDependencies: true);
@@ -401,7 +407,7 @@
for (var node in dependencies) {
if (node is _VariableInferenceNode &&
node.isImplicitlyTypedInstanceField) {
- LazyAst.setType(_node, DynamicTypeImpl.instance);
+ _elementImpl.type = DynamicTypeImpl.instance;
isEvaluated = true;
return const <_InferenceNode>[];
}
@@ -414,10 +420,10 @@
void evaluate() {
_resolveInitializer(forDependencies: false);
- if (LazyAst.getType(_node) == null) {
+ if (!_elementImpl.hasTypeInferred) {
var initializerType = _node.initializer.staticType;
initializerType = _refineType(initializerType);
- LazyAst.setType(_node, initializerType);
+ _elementImpl.type = initializerType;
}
isEvaluated = true;
@@ -425,19 +431,16 @@
@override
void markCircular(List<_InferenceNode> cycle) {
- LazyAst.setType(_node, DynamicTypeImpl.instance);
+ _elementImpl.type = DynamicTypeImpl.instance;
var cycleNames = <String>{};
for (var inferenceNode in cycle) {
cycleNames.add(inferenceNode.displayName);
}
- LazyAst.setTypeInferenceError(
- _node,
- TopLevelInferenceErrorBuilder(
- kind: TopLevelInferenceErrorKind.dependencyCycle,
- arguments: cycleNames.toList(),
- ),
+ _elementImpl.typeInferenceError = TopLevelInferenceError(
+ kind: TopLevelInferenceErrorKind.dependencyCycle,
+ arguments: cycleNames.toList(),
);
isEvaluated = true;
diff --git a/pkg/analyzer/lib/src/summary2/type_alias.dart b/pkg/analyzer/lib/src/summary2/type_alias.dart
index 0ee7be4..5fe9298 100644
--- a/pkg/analyzer/lib/src/summary2/type_alias.dart
+++ b/pkg/analyzer/lib/src/summary2/type_alias.dart
@@ -8,7 +8,6 @@
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
import 'package:analyzer/src/summary2/link.dart';
class TypeAliasSelfReferenceFinder {
@@ -26,20 +25,16 @@
if (node is FunctionTypeAlias) {
var finder = _Finder(node);
finder.functionTypeAlias(node);
- LazyFunctionTypeAlias.setHasSelfReference(
- node,
- finder.hasSelfReference,
- );
+ var element = node.declaredElement as FunctionTypeAliasElementImpl;
+ element.hasSelfReference = finder.hasSelfReference;
} else if (node is GenericTypeAlias) {
var finder = _Finder(node);
finder.genericTypeAlias(node);
- LazyGenericTypeAlias.setHasSelfReference(
- node,
- finder.hasSelfReference,
- );
if (finder.hasSelfReference) {
_sanitizeGenericTypeAlias(node);
}
+ var element = node.declaredElement as FunctionTypeAliasElementImpl;
+ element.hasSelfReference = finder.hasSelfReference;
}
}
}
diff --git a/pkg/analyzer/lib/src/summary2/types_builder.dart b/pkg/analyzer/lib/src/summary2/types_builder.dart
index 249c4eb..9ad85a2 100644
--- a/pkg/analyzer/lib/src/summary2/types_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/types_builder.dart
@@ -14,7 +14,6 @@
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_system.dart';
import 'package:analyzer/src/summary2/default_types_builder.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
import 'package:analyzer/src/summary2/type_builder.dart';
class NodesToBuildType {
@@ -90,7 +89,8 @@
returnType = _dynamicType;
}
}
- LazyAst.setReturnType(node, returnType);
+ var element = node.declaredElement as ExecutableElementImpl;
+ element.returnType = returnType;
} else if (node is FunctionTypeAlias) {
_functionTypeAlias(node);
} else if (node is FunctionTypedFormalParameter) {
@@ -108,16 +108,18 @@
returnType = _dynamicType;
}
}
- LazyAst.setReturnType(node, returnType);
+ var element = node.declaredElement as ExecutableElementImpl;
+ element.returnType = returnType;
} else if (node is MixinDeclaration) {
// TODO(scheglov) ???
} else if (node is SimpleFormalParameter) {
- LazyAst.setType(node, node.type?.type ?? _dynamicType);
+ var element = node.declaredElement as ParameterElementImpl;
+ element.type = node.type?.type ?? _dynamicType;
} else if (node is VariableDeclarationList) {
var type = node.type?.type;
if (type != null) {
for (var variable in node.variables) {
- LazyAst.setType(variable, type);
+ (variable.declaredElement as VariableElementImpl).type = type;
}
}
} else {
@@ -136,25 +138,24 @@
parameterList,
_nullability(node, node.question != null),
);
- LazyAst.setType(node, type);
+ var element = node.declaredElement as ParameterElementImpl;
+ element.type = type;
} else {
- LazyAst.setType(node, node.type?.type ?? _dynamicType);
+ var element = node.declaredElement as ParameterElementImpl;
+ element.type = node.type?.type ?? _dynamicType;
}
}
- List<ParameterElementImpl> _formalParameters(FormalParameterList node) {
+ List<ParameterElement> _formalParameters(FormalParameterList node) {
return node.parameters.asImpl.map((parameter) {
- return ParameterElementImpl.synthetic(
- parameter.identifier?.name ?? '',
- _getType(parameter),
- parameter.kind,
- );
+ return parameter.declaredElement;
}).toList();
}
void _functionTypeAlias(FunctionTypeAlias node) {
var returnTypeNode = node.returnType;
- LazyAst.setReturnType(node, returnTypeNode?.type ?? _dynamicType);
+ var element = node.declaredElement as FunctionTypeAliasElementImpl;
+ element.function.returnType = returnTypeNode?.type ?? _dynamicType;
}
void _functionTypedFormalParameter(FunctionTypedFormalParameter node) {
@@ -164,7 +165,8 @@
node.parameters,
_nullability(node, node.question != null),
);
- LazyAst.setType(node, type);
+ var element = node.declaredElement as ParameterElementImpl;
+ element.type = type;
}
bool _isNonNullableByDefault(AstNode node) {
@@ -193,13 +195,6 @@
.map<TypeParameterElement>((p) => p.declaredElement)
.toList();
}
-
- static DartType _getType(FormalParameter node) {
- if (node is DefaultFormalParameter) {
- return _getType(node.parameter);
- }
- return LazyAst.getType(node);
- }
}
/// Performs mixins inference in a [ClassDeclaration].
diff --git a/pkg/analyzer/lib/src/summary2/unlinked_token_type.dart b/pkg/analyzer/lib/src/summary2/unlinked_token_type.dart
new file mode 100644
index 0000000..e11b1e0
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/unlinked_token_type.dart
@@ -0,0 +1,146 @@
+/// Enum of token types, corresponding to AST token types.
+enum UnlinkedTokenType {
+ NOTHING,
+ ABSTRACT,
+ AMPERSAND,
+ AMPERSAND_AMPERSAND,
+ AMPERSAND_EQ,
+ AS,
+ ASSERT,
+ ASYNC,
+ AT,
+ AWAIT,
+ BACKPING,
+ BACKSLASH,
+ BANG,
+ BANG_EQ,
+ BANG_EQ_EQ,
+ BAR,
+ BAR_BAR,
+ BAR_EQ,
+ BREAK,
+ CARET,
+ CARET_EQ,
+ CASE,
+ CATCH,
+ CLASS,
+ CLOSE_CURLY_BRACKET,
+ CLOSE_PAREN,
+ CLOSE_SQUARE_BRACKET,
+ COLON,
+ COMMA,
+ CONST,
+ CONTINUE,
+ COVARIANT,
+ DEFAULT,
+ DEFERRED,
+ DO,
+ DOUBLE,
+ DYNAMIC,
+ ELSE,
+ ENUM,
+ EOF,
+ EQ,
+ EQ_EQ,
+ EQ_EQ_EQ,
+ EXPORT,
+ EXTENDS,
+ EXTERNAL,
+ FACTORY,
+ FALSE,
+ FINAL,
+ FINALLY,
+ FOR,
+ FUNCTION,
+ FUNCTION_KEYWORD,
+ GET,
+ GT,
+ GT_EQ,
+ GT_GT,
+ GT_GT_EQ,
+ GT_GT_GT,
+ GT_GT_GT_EQ,
+ HASH,
+ HEXADECIMAL,
+ HIDE,
+ IDENTIFIER,
+ IF,
+ IMPLEMENTS,
+ IMPORT,
+ IN,
+ INDEX,
+ INDEX_EQ,
+ INT,
+ INTERFACE,
+ IS,
+ LATE,
+ LIBRARY,
+ LT,
+ LT_EQ,
+ LT_LT,
+ LT_LT_EQ,
+ MINUS,
+ MINUS_EQ,
+ MINUS_MINUS,
+ MIXIN,
+ MULTI_LINE_COMMENT,
+ NATIVE,
+ NEW,
+ NULL,
+ OF,
+ ON,
+ OPEN_CURLY_BRACKET,
+ OPEN_PAREN,
+ OPEN_SQUARE_BRACKET,
+ OPERATOR,
+ PART,
+ PATCH,
+ PERCENT,
+ PERCENT_EQ,
+ PERIOD,
+ PERIOD_PERIOD,
+ PERIOD_PERIOD_PERIOD,
+ PERIOD_PERIOD_PERIOD_QUESTION,
+ PLUS,
+ PLUS_EQ,
+ PLUS_PLUS,
+ QUESTION,
+ QUESTION_PERIOD,
+ QUESTION_QUESTION,
+ QUESTION_QUESTION_EQ,
+ REQUIRED,
+ RETHROW,
+ RETURN,
+ SCRIPT_TAG,
+ SEMICOLON,
+ SET,
+ SHOW,
+ SINGLE_LINE_COMMENT,
+ SLASH,
+ SLASH_EQ,
+ SOURCE,
+ STAR,
+ STAR_EQ,
+ STATIC,
+ STRING,
+ STRING_INTERPOLATION_EXPRESSION,
+ STRING_INTERPOLATION_IDENTIFIER,
+ SUPER,
+ SWITCH,
+ SYNC,
+ THIS,
+ THROW,
+ TILDE,
+ TILDE_SLASH,
+ TILDE_SLASH_EQ,
+ TRUE,
+ TRY,
+ TYPEDEF,
+ VAR,
+ VOID,
+ WHILE,
+ WITH,
+ YIELD,
+ INOUT,
+ OUT,
+}
diff --git a/pkg/analyzer/lib/src/summary2/variance_builder.dart b/pkg/analyzer/lib/src/summary2/variance_builder.dart
index 51d0100..1ee6e95 100644
--- a/pkg/analyzer/lib/src/summary2/variance_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/variance_builder.dart
@@ -9,7 +9,6 @@
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/resolver/variance.dart';
import 'package:analyzer/src/summary2/function_type_builder.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
import 'package:analyzer/src/summary2/link.dart';
import 'package:analyzer/src/summary2/named_type_builder.dart';
import 'package:meta/meta.dart';
@@ -149,7 +148,7 @@
// Recursion detected, recover.
if (_visit.contains(node)) {
for (var parameter in parameterList.typeParameters) {
- LazyAst.setVariance(parameter, Variance.covariant);
+ _setVariance(parameter, Variance.covariant);
}
return;
}
@@ -171,7 +170,7 @@
node.parameters,
),
);
- LazyAst.setVariance(parameter, variance);
+ _setVariance(parameter, variance);
}
} finally {
_visit.remove(node);
@@ -198,7 +197,7 @@
// Recursion detected, recover.
if (_visit.contains(node)) {
for (var parameter in parameterList.typeParameters) {
- LazyAst.setVariance(parameter, Variance.covariant);
+ _setVariance(parameter, Variance.covariant);
}
return;
}
@@ -213,7 +212,7 @@
// Not a function type, recover.
if (type == null) {
for (var parameter in parameterList.typeParameters) {
- LazyAst.setVariance(parameter, Variance.covariant);
+ _setVariance(parameter, Variance.covariant);
}
}
@@ -221,7 +220,7 @@
try {
for (var parameter in parameterList.typeParameters) {
var variance = _compute(parameter.declaredElement, type);
- LazyAst.setVariance(parameter, variance);
+ _setVariance(parameter, variance);
}
} finally {
_visit.remove(node);
@@ -238,8 +237,13 @@
var varianceKeyword = parameterImpl.varianceKeyword;
if (varianceKeyword != null) {
var variance = Variance.fromKeywordString(varianceKeyword.lexeme);
- LazyAst.setVariance(parameter, variance);
+ _setVariance(parameter, variance);
}
}
}
+
+ static void _setVariance(TypeParameter node, Variance variance) {
+ var element = node.declaredElement as TypeParameterElementImpl;
+ element.variance = variance;
+ }
}
diff --git a/pkg/analyzer/lib/src/task/inference_error.dart b/pkg/analyzer/lib/src/task/inference_error.dart
new file mode 100644
index 0000000..4a686ff
--- /dev/null
+++ b/pkg/analyzer/lib/src/task/inference_error.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:meta/meta.dart';
+
+/// The top-level type inference error.
+class TopLevelInferenceError {
+ /// The kind of the error.
+ final TopLevelInferenceErrorKind kind;
+
+ /// The [kind] specific arguments.
+ final List<String> arguments;
+
+ TopLevelInferenceError({
+ @required this.kind,
+ @required this.arguments,
+ });
+}
+
+/// Enum used to indicate the kind of the error during top-level inference.
+enum TopLevelInferenceErrorKind {
+ none,
+ assignment,
+ instanceGetter,
+ dependencyCycle,
+ overrideConflictFieldType,
+ overrideNoCombinedSuperSignature,
+}
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 7db1cf7..7e57d0c 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -20,7 +20,7 @@
import 'package:analyzer/src/dart/element/type_system.dart';
import 'package:analyzer/src/error/codes.dart'
show CompileTimeErrorCode, StrongModeCode;
-import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/task/inference_error.dart';
import 'package:meta/meta.dart';
DartType _elementType(Element e) {
diff --git a/pkg/analyzer/lib/src/task/strong_mode.dart b/pkg/analyzer/lib/src/task/strong_mode.dart
index e6a5f7c..b303bf0 100644
--- a/pkg/analyzer/lib/src/task/strong_mode.dart
+++ b/pkg/analyzer/lib/src/task/strong_mode.dart
@@ -11,9 +11,7 @@
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_algebra.dart';
import 'package:analyzer/src/dart/element/type_system.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary2/lazy_ast.dart';
+import 'package:analyzer/src/task/inference_error.dart';
/// An object used to infer the type of instance fields and the return types of
/// instance methods within a single compilation unit.
@@ -287,11 +285,9 @@
type = typeSystem.nonNullifyLegacy(type);
field.type = type;
} else {
- LazyAst.setTypeInferenceError(
- field.linkedNode,
- TopLevelInferenceErrorBuilder(
- kind: TopLevelInferenceErrorKind.overrideConflictFieldType,
- ),
+ field.typeInferenceError = TopLevelInferenceError(
+ kind: TopLevelInferenceErrorKind.overrideConflictFieldType,
+ arguments: const <String>[],
);
}
return;
@@ -429,12 +425,9 @@
}
}
- LazyAst.setTypeInferenceError(
- element.linkedNode,
- TopLevelInferenceErrorBuilder(
- kind: TopLevelInferenceErrorKind.overrideNoCombinedSuperSignature,
- arguments: [conflictExplanation],
- ),
+ element.typeInferenceError = TopLevelInferenceError(
+ kind: TopLevelInferenceErrorKind.overrideNoCombinedSuperSignature,
+ arguments: [conflictExplanation],
);
}
}
diff --git a/pkg/analyzer/test/generated/error_suppression_test.dart b/pkg/analyzer/test/generated/error_suppression_test.dart
index 7c6e3d9..07a3c23 100644
--- a/pkg/analyzer/test/generated/error_suppression_test.dart
+++ b/pkg/analyzer/test/generated/error_suppression_test.dart
@@ -81,7 +81,7 @@
test_ignore_for_file_whitespace_variant() async {
await assertNoErrorsInCode('''
-//ignore_for_file: $ignoredCode , unnecessary_cast
+//ignore_for_file: unused_element , unnecessary_cast
int x = (0 as int); //UNNECESSARY_CAST
String _foo; //UNUSED_ELEMENT
''');
@@ -97,7 +97,7 @@
await assertErrorsInCode('''
//UNNECESSARY_CAST
int x = (0 as int);
-// ignore: $ignoredCode
+// ignore: unused_element
String _foo; //UNUSED_ELEMENT
''', [
error(HintCode.UNNECESSARY_CAST, 28, 8),
diff --git a/pkg/analyzer/test/generated/invalid_code_test.dart b/pkg/analyzer/test/generated/invalid_code_test.dart
index a116216..6ae242a 100644
--- a/pkg/analyzer/test/generated/invalid_code_test.dart
+++ b/pkg/analyzer/test/generated/invalid_code_test.dart
@@ -196,11 +196,11 @@
''');
}
- @failingTest
test_fuzz_12() async {
// This code crashed with summary2 because usually AST reader is lazy,
// so we did not read metadata `@b` for `c`. But default values must be
// read fully.
+ // Fixed 2020-11-12.
await _assertCanBeAnalyzed(r'''
void f({a = [for (@b c = 0;;)]}) {}
''');
@@ -337,6 +337,12 @@
''');
}
+ test_syntheticImportPrefix() async {
+ await _assertCanBeAnalyzed('''
+import 'dart:math' as;
+''');
+ }
+
test_typeBeforeAnnotation() async {
await _assertCanBeAnalyzed('''
class A {
diff --git a/pkg/analyzer/test/src/dart/resolution/method_declaration_test.dart b/pkg/analyzer/test/src/dart/resolution/method_declaration_test.dart
index 9f18387..d7f3f98 100644
--- a/pkg/analyzer/test/src/dart/resolution/method_declaration_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/method_declaration_test.dart
@@ -13,7 +13,8 @@
}
@reflectiveTest
-class MethodDeclarationResolutionTest extends PubPackageResolutionTest {
+class MethodDeclarationResolutionTest extends PubPackageResolutionTest
+ with WithNullSafetyMixin {
test_formalParameterScope_defaultValue() async {
await assertNoErrorsInCode('''
class A {
diff --git a/pkg/analyzer/test/src/diagnostics/assignment_of_do_not_store_test.dart b/pkg/analyzer/test/src/diagnostics/assignment_of_do_not_store_test.dart
index 664891c..e72359b 100644
--- a/pkg/analyzer/test/src/diagnostics/assignment_of_do_not_store_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/assignment_of_do_not_store_test.dart
@@ -238,7 +238,6 @@
}
test_topLevelVariable_libraryAnnotation() async {
- testFilePath;
newFile('$testPackageLibPath/library.dart', content: '''
@doNotStore
library lib;
diff --git a/pkg/analyzer/test/src/diagnostics/duplicate_field_formal_parameter_test.dart b/pkg/analyzer/test/src/diagnostics/duplicate_field_formal_parameter_test.dart
new file mode 100644
index 0000000..60961c5
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/duplicate_field_formal_parameter_test.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(DuplicateFieldFormalParameterTest);
+ });
+}
+
+@reflectiveTest
+class DuplicateFieldFormalParameterTest extends PubPackageResolutionTest
+ with WithNullSafetyMixin {
+ test_optional_named() async {
+ await assertErrorsInCode(r'''
+class A {
+ int a;
+ A({this.a = 0, this.a = 1});
+}
+''', [
+ error(CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER, 41, 1),
+ ]);
+ }
+
+ test_optional_positional() async {
+ await assertErrorsInCode(r'''
+class A {
+ int a;
+ A([this.a = 0, this.a = 1]);
+}
+''', [
+ error(CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER, 41, 1),
+ ]);
+ }
+
+ test_required_named() async {
+ await assertErrorsInCode(r'''
+class A {
+ int a;
+ A({required this.a, required this.a});
+}
+''', [
+ error(CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER, 55, 1),
+ ]);
+ }
+
+ test_required_positional() async {
+ await assertErrorsInCode(r'''
+class A {
+ int a;
+ A(this.a, this.a);
+}
+''', [
+ error(CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER, 36, 1),
+ ]);
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 3d1585b..05d7fb0 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -126,6 +126,8 @@
import 'deprecated_mixin_function_test.dart' as deprecated_mixin_function;
import 'division_optimization_test.dart' as division_optimization;
import 'duplicate_definition_test.dart' as duplicate_definition;
+import 'duplicate_field_formal_parameter_test.dart'
+ as duplicate_field_formal_parameter;
import 'duplicate_hidden_name_test.dart' as duplicate_hidden_name;
import 'duplicate_ignore_test.dart' as duplicate_ignore;
import 'duplicate_import_test.dart' as duplicate_import;
@@ -742,6 +744,7 @@
deprecated_mixin_function.main();
division_optimization.main();
duplicate_definition.main();
+ duplicate_field_formal_parameter.main();
duplicate_hidden_name.main();
duplicate_ignore.main();
duplicate_import.main();
diff --git a/pkg/analyzer/test/src/pubspec/pubspec_validator_test.dart b/pkg/analyzer/test/src/pubspec/pubspec_validator_test.dart
index 8e8944a..e815d5e 100644
--- a/pkg/analyzer/test/src/pubspec/pubspec_validator_test.dart
+++ b/pkg/analyzer/test/src/pubspec/pubspec_validator_test.dart
@@ -505,6 +505,23 @@
''');
}
+ test_pathNotPosix_error() {
+ newFolder('/foo');
+ newFile('/foo/pubspec.yaml', content: '''
+name: foo
+''');
+ assertErrors(r'''
+name: sample
+version: 0.1.0
+publish_to: none
+dependencies:
+ foo:
+ path: \foo
+''', [
+ PubspecWarningCode.PATH_NOT_POSIX,
+ ]);
+ }
+
test_unnecessaryDevDependency_error() {
assertErrors('''
name: sample
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index 45d46f2..721eb3c 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -11,7 +11,7 @@
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/task/inference_error.dart';
import 'package:meta/meta.dart';
import 'package:test/test.dart';
@@ -465,6 +465,12 @@
e.combinators.forEach(writeNamespaceCombinator);
buffer.writeln(';');
+
+ if (withFullyResolvedAst) {
+ _withIndent(() {
+ _writeResolvedMetadata(e.metadata);
+ });
+ }
}
}
@@ -605,6 +611,10 @@
writeList('(', ')', e.arguments.arguments, ', ', writeNode,
includeEmpty: true);
}
+ } else if (e is AsExpression) {
+ writeNode(e.expression);
+ buffer.write(' as ');
+ writeNode(e.type);
} else if (e is AssertInitializer) {
buffer.write('assert(');
writeNode(e.condition);
@@ -669,6 +679,10 @@
buffer.write(r'}');
} else if (e is InterpolationString) {
buffer.write(e.value.replaceAll("'", r"\'"));
+ } else if (e is IsExpression) {
+ writeNode(e.expression);
+ buffer.write(e.notOperator == null ? ' is ' : ' is! ');
+ writeNode(e.type);
} else if (e is ListLiteral) {
if (e.constKeyword != null) {
buffer.write('const ');
@@ -1203,6 +1217,7 @@
selfUriStr: selfUriStr,
sink: buffer,
indent: indent,
+ withNullability: annotateNullability,
),
);
}
diff --git a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
index af3b5a9..b8eaf24 100644
--- a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
+++ b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
@@ -34,6 +34,9 @@
/// The optional provider for code lines, might be `null`.
final CodeLinesProvider _codeLinesProvider;
+ /// If `true`, types should be printed with nullability suffixes.
+ final bool _withNullability;
+
String _indent = '';
ResolvedAstPrinter({
@@ -41,9 +44,11 @@
@required StringSink sink,
@required String indent,
CodeLinesProvider codeLinesProvider,
+ bool withNullability = false,
}) : _selfUriStr = selfUriStr,
_sink = sink,
_codeLinesProvider = codeLinesProvider,
+ _withNullability = withNullability,
_indent = indent;
@override
@@ -126,6 +131,10 @@
properties.addNode('leftHandSide', node.leftHandSide);
properties.addToken('operator', node.operator);
properties.addNode('rightHandSide', node.rightHandSide);
+ properties.addElement('readElement', node.readElement);
+ properties.addType('readType', node.readType);
+ properties.addElement('writeElement', node.writeElement);
+ properties.addType('writeType', node.writeType);
_addExpression(properties, node);
_addMethodReferenceExpression(properties, node);
_writeProperties(properties);
@@ -1030,6 +1039,12 @@
var properties = _Properties();
properties.addNode('operand', node.operand);
properties.addToken('operator', node.operator);
+ if (node.operator.type.isIncrementOperator) {
+ properties.addElement('readElement', node.readElement);
+ properties.addType('readType', node.readType);
+ properties.addElement('writeElement', node.writeElement);
+ properties.addType('writeType', node.writeType);
+ }
_addExpression(properties, node);
_addMethodReferenceExpression(properties, node);
_writeProperties(properties);
@@ -1058,6 +1073,12 @@
var properties = _Properties();
properties.addNode('operand', node.operand);
properties.addToken('operator', node.operator);
+ if (node.operator.type.isIncrementOperator) {
+ properties.addElement('readElement', node.readElement);
+ properties.addType('readType', node.readType);
+ properties.addElement('writeElement', node.writeElement);
+ properties.addType('writeType', node.writeType);
+ }
_addExpression(properties, node);
_addMethodReferenceExpression(properties, node);
_writeProperties(properties);
@@ -1666,7 +1687,7 @@
}
String _typeStr(DartType type) {
- return type?.getDisplayString(withNullability: false);
+ return type?.getDisplayString(withNullability: _withNullability);
}
void _withIndent(void Function() f) {
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
index 7b6be4a..7da23eb 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.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:typed_data';
+
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/null_safety_understanding_flag.dart';
@@ -12,12 +14,11 @@
import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary2/informative_data.dart';
+import 'package:analyzer/src/summary2/bundle_reader.dart';
import 'package:analyzer/src/summary2/link.dart';
-import 'package:analyzer/src/summary2/linked_bundle_context.dart';
import 'package:analyzer/src/summary2/linked_element_factory.dart';
import 'package:analyzer/src/summary2/reference.dart';
+import 'package:meta/meta.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'resynthesize_common.dart';
@@ -33,15 +34,15 @@
class ResynthesizeAst2Test extends ResynthesizeTestStrategyTwoPhase
with ResynthesizeTestCases {
/// The shared SDK bundle, computed once and shared among test invocations.
- static LinkedNodeBundle _sdkBundleNnbd;
+ static _SdkBundle _sdkBundleNullSafe;
/// The shared SDK bundle, computed once and shared among test invocations.
- static LinkedNodeBundle _sdkBundleLegacy;
+ static _SdkBundle _sdkBundleLegacy;
- LinkedNodeBundle get sdkBundle {
+ _SdkBundle get sdkBundle {
if (featureSet.isEnabled(Feature.non_nullable)) {
- if (_sdkBundleNnbd != null) {
- return _sdkBundleNnbd;
+ if (_sdkBundleNullSafe != null) {
+ return _sdkBundleNullSafe;
}
} else {
if (_sdkBundleLegacy != null) {
@@ -74,14 +75,18 @@
Reference.root(),
);
- var sdkLinkResult = link(elementFactory, inputLibraries);
+ var sdkLinkResult = link(elementFactory, inputLibraries, true);
- var bytes = sdkLinkResult.bundle.toBuffer();
- var sdkBundle = LinkedNodeBundle.fromBuffer(bytes);
if (featureSet.isEnabled(Feature.non_nullable)) {
- return _sdkBundleNnbd = sdkBundle;
+ return _sdkBundleNullSafe = _SdkBundle(
+ astBytes: sdkLinkResult.astBytes,
+ resolutionBytes: sdkLinkResult.resolutionBytes,
+ );
} else {
- return _sdkBundleLegacy = sdkBundle;
+ return _sdkBundleLegacy = _SdkBundle(
+ astBytes: sdkLinkResult.astBytes,
+ resolutionBytes: sdkLinkResult.resolutionBytes,
+ );
}
}
@@ -107,39 +112,27 @@
Reference.root(),
);
elementFactory.addBundle(
- LinkedBundleContext(elementFactory, sdkBundle),
+ BundleReader(
+ elementFactory: elementFactory,
+ astBytes: sdkBundle.astBytes,
+ resolutionBytes: sdkBundle.resolutionBytes,
+ ),
);
var linkResult = NullSafetyUnderstandingFlag.enableNullSafetyTypes(
() {
- return link(
- elementFactory,
- inputLibraries,
- );
+ return link(elementFactory, inputLibraries, true);
},
);
elementFactory.addBundle(
- LinkedBundleContext(elementFactory, linkResult.bundle),
+ BundleReader(
+ elementFactory: elementFactory,
+ astBytes: linkResult.astBytes,
+ resolutionBytes: linkResult.resolutionBytes,
+ ),
);
- // Set informative data.
- for (var inputLibrary in inputLibraries) {
- var libraryUriStr = '${inputLibrary.source.uri}';
- for (var inputUnit in inputLibrary.units) {
- var unitSource = inputUnit.source;
- if (unitSource != null) {
- var unitUriStr = '${unitSource.uri}';
- var informativeData = createInformativeData(inputUnit.unit);
- elementFactory.setInformativeData(
- libraryUriStr,
- unitUriStr,
- informativeData,
- );
- }
- }
- }
-
return elementFactory.libraryOfUri('${source.uri}');
}
@@ -232,3 +225,13 @@
@override
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
+
+class _SdkBundle {
+ final Uint8List astBytes;
+ final Uint8List resolutionBytes;
+
+ _SdkBundle({
+ @required this.astBytes,
+ @required this.resolutionBytes,
+ });
+}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 701ebb6..157bfc3 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -2719,6 +2719,97 @@
expect(library.isNonNullableByDefault, isTrue);
}
+ test_const_asExpression() async {
+ featureSet = enableNnbd;
+ var library = await checkLibrary('''
+const num a = 0;
+const b = a as int;
+''');
+ checkElementText(library, '''
+const num a = 0;
+const int b =
+ a/*location: test.dart;a?*/ as
+ int/*location: dart:core;int*/;
+''');
+ }
+
+ test_const_assignmentExpression() async {
+ featureSet = enableNnbd;
+ var library = await checkLibrary(r'''
+const a = 0;
+const b = (a += 1);
+''');
+ checkElementText(
+ library,
+ r'''
+const int a;
+ constantInitializer
+ IntegerLiteral
+ literal: 0
+ staticType: int
+const int b;
+ constantInitializer
+ ParenthesizedExpression
+ expression: AssignmentExpression
+ leftHandSide: SimpleIdentifier
+ staticElement: <null>
+ staticType: null
+ token: a
+ operator: +=
+ readElement: self::@getter::a
+ readType: int
+ rightHandSide: IntegerLiteral
+ literal: 1
+ staticType: int
+ staticElement: dart:core::@class::num::@method::+
+ staticType: int
+ writeElement: self::@getter::a
+ writeType: dynamic
+ staticType: int
+''',
+ annotateNullability: true,
+ withFullyResolvedAst: true,
+ );
+ }
+
+ test_const_cascadeExpression() async {
+ featureSet = enableNnbd;
+ var library = await checkLibrary(r'''
+const a = 0..isEven..abs();
+''');
+ checkElementText(
+ library,
+ r'''
+const int a;
+ constantInitializer
+ CascadeExpression
+ cascadeSections
+ PropertyAccess
+ operator: ..
+ propertyName: SimpleIdentifier
+ staticElement: dart:core::@class::int::@getter::isEven
+ staticType: bool
+ token: isEven
+ staticType: bool
+ MethodInvocation
+ argumentList: ArgumentList
+ methodName: SimpleIdentifier
+ staticElement: dart:core::@class::int::@method::abs
+ staticType: int Function()
+ token: abs
+ operator: ..
+ staticInvokeType: null
+ staticType: int
+ staticType: int
+ target: IntegerLiteral
+ literal: 0
+ staticType: int
+''',
+ annotateNullability: true,
+ withFullyResolvedAst: true,
+ );
+ }
+
test_const_classField() async {
var library = await checkLibrary(r'''
class C {
@@ -2791,6 +2882,50 @@
''');
}
+ test_const_indexExpression() async {
+ featureSet = enableNnbd;
+ var library = await checkLibrary(r'''
+const a = [0];
+const b = 0;
+const c = a[b];
+''');
+ checkElementText(
+ library,
+ r'''
+const List<int> a;
+ constantInitializer
+ ListLiteral
+ elements
+ IntegerLiteral
+ literal: 0
+ staticType: int
+ staticType: List<int>
+const int b;
+ constantInitializer
+ IntegerLiteral
+ literal: 0
+ staticType: int
+const int c;
+ constantInitializer
+ IndexExpression
+ index: SimpleIdentifier
+ staticElement: self::@getter::b
+ staticType: int
+ token: b
+ staticElement: MethodMember
+ base: dart:core::@class::List::@method::[]
+ substitution: {E: int}
+ staticType: int
+ target: SimpleIdentifier
+ staticElement: self::@getter::a
+ staticType: List<int>
+ token: a
+''',
+ annotateNullability: true,
+ withFullyResolvedAst: true,
+ );
+ }
+
test_const_inference_downward_list() async {
var library = await checkLibrary('''
class P<T> {
@@ -3253,6 +3388,20 @@
''');
}
+ test_const_isExpression() async {
+ featureSet = enableNnbd;
+ var library = await checkLibrary('''
+const a = 0;
+const b = a is int;
+''');
+ checkElementText(library, '''
+const int a = 0;
+const bool b =
+ a/*location: test.dart;a?*/ is
+ int/*location: dart:core;int*/;
+''');
+ }
+
test_const_length_ofClassConstField() async {
var library = await checkLibrary(r'''
class C {
@@ -3527,6 +3676,44 @@
withTypes: true);
}
+ test_const_methodInvocation() async {
+ featureSet = enableNnbd;
+ var library = await checkLibrary(r'''
+T f<T>(T a) => a;
+const b = f<int>(0);
+''');
+ checkElementText(
+ library,
+ r'''
+const int b;
+ constantInitializer
+ MethodInvocation
+ argumentList: ArgumentList
+ arguments
+ IntegerLiteral
+ literal: 0
+ staticType: int
+ methodName: SimpleIdentifier
+ staticElement: self::@function::f
+ staticType: T Function<T>(T)
+ token: f
+ staticInvokeType: null
+ staticType: int
+ typeArguments: TypeArgumentList
+ arguments
+ TypeName
+ name: SimpleIdentifier
+ staticElement: dart:core::@class::int
+ staticType: null
+ token: int
+ type: int
+T f(T a) {}
+''',
+ annotateNullability: true,
+ withFullyResolvedAst: true,
+ );
+ }
+
test_const_parameterDefaultValue_initializingFormal_functionTyped() async {
var library = await checkLibrary(r'''
class C {
@@ -3598,6 +3785,104 @@
''');
}
+ test_const_postfixExpression_increment() async {
+ featureSet = enableNnbd;
+ var library = await checkLibrary(r'''
+const a = 0;
+const b = a++;
+''');
+ checkElementText(
+ library,
+ r'''
+const int a;
+ constantInitializer
+ IntegerLiteral
+ literal: 0
+ staticType: int
+const int b;
+ constantInitializer
+ PostfixExpression
+ operand: SimpleIdentifier
+ staticElement: <null>
+ staticType: null
+ token: a
+ operator: ++
+ readElement: self::@getter::a
+ readType: int
+ staticElement: dart:core::@class::num::@method::+
+ staticType: int
+ writeElement: self::@getter::a
+ writeType: dynamic
+''',
+ annotateNullability: true,
+ withFullyResolvedAst: true,
+ );
+ }
+
+ test_const_postfixExpression_nullCheck() async {
+ featureSet = enableNnbd;
+ var library = await checkLibrary(r'''
+const int? a = 0;
+const b = a!;
+''');
+ checkElementText(
+ library,
+ r'''
+const int? a;
+ constantInitializer
+ IntegerLiteral
+ literal: 0
+ staticType: int
+const int b;
+ constantInitializer
+ PostfixExpression
+ operand: SimpleIdentifier
+ staticElement: self::@getter::a
+ staticType: int?
+ token: a
+ operator: !
+ staticElement: <null>
+ staticType: int
+''',
+ annotateNullability: true,
+ withFullyResolvedAst: true,
+ );
+ }
+
+ test_const_prefixExpression_increment() async {
+ featureSet = enableNnbd;
+ var library = await checkLibrary(r'''
+const a = 0;
+const b = ++a;
+''');
+ checkElementText(
+ library,
+ r'''
+const int a;
+ constantInitializer
+ IntegerLiteral
+ literal: 0
+ staticType: int
+const int b;
+ constantInitializer
+ PrefixExpression
+ operand: SimpleIdentifier
+ staticElement: <null>
+ staticType: null
+ token: a
+ operator: ++
+ readElement: self::@getter::a
+ readType: int
+ staticElement: dart:core::@class::num::@method::+
+ staticType: int
+ writeElement: self::@getter::a
+ writeType: dynamic
+''',
+ annotateNullability: true,
+ withFullyResolvedAst: true,
+ );
+ }
+
test_const_reference_staticField() async {
var library = await checkLibrary(r'''
class C {
@@ -4131,9 +4416,11 @@
const vNull = null;
const vBoolFalse = false;
const vBoolTrue = true;
-const vInt = 1;
+const vIntPositive = 1;
+const vIntNegative = -2;
const vIntLong1 = 0x7FFFFFFFFFFFFFFF;
const vIntLong2 = 0xFFFFFFFFFFFFFFFF;
+const vIntLong3 = 0x8000000000000000;
const vDouble = 2.3;
const vString = 'abc';
const vStringConcat = 'aaa' 'bbb';
@@ -4144,9 +4431,11 @@
const dynamic vNull = null;
const bool vBoolFalse = false;
const bool vBoolTrue = true;
-const int vInt = 1;
+const int vIntPositive = 1;
+const int vIntNegative = -2;
const int vIntLong1 = 9223372036854775807;
const int vIntLong2 = -1;
+const int vIntLong3 = -9223372036854775808;
const double vDouble = 2.3;
const String vString = 'abc';
const String vStringConcat = 'aaabbb';
@@ -4517,6 +4806,35 @@
''');
}
+ test_constructor_initializers_field_optionalPositionalParameter() async {
+ var library = await checkLibrary('''
+class A {
+ final int _f;
+ const A([int f = 0]) : _f = f;
+}
+''');
+ checkElementText(
+ library,
+ r'''
+class A {
+ final int _f;
+ const A([int f = 0]);
+ constantInitializers
+ ConstructorFieldInitializer
+ equals: =
+ expression: SimpleIdentifier
+ staticElement: f@41
+ staticType: int
+ token: f
+ fieldName: SimpleIdentifier
+ staticElement: self::@class::A::@field::_f
+ staticType: null
+ token: _f
+}
+''',
+ withFullyResolvedAst: true);
+ }
+
test_constructor_initializers_field_withParameter() async {
var library = await checkLibrary('''
class C {
@@ -6355,6 +6673,46 @@
''');
}
+ test_field_inferred_type_nonStatic_inherited_resolveInitializer() async {
+ var library = await checkLibrary(r'''
+const a = 0;
+abstract class A {
+ const A();
+ List<int> get f;
+}
+class B extends A {
+ const B();
+ final f = [a];
+}
+''');
+ checkElementText(
+ library,
+ r'''
+abstract class A {
+ List<int> get f;
+ const A();
+}
+class B extends A {
+ final List<int> f;
+ constantInitializer
+ ListLiteral
+ elements
+ SimpleIdentifier
+ staticElement: self::@getter::a
+ staticType: int
+ token: a
+ staticType: List<int>
+ const B();
+}
+const int a;
+ constantInitializer
+ IntegerLiteral
+ literal: 0
+ staticType: int
+''',
+ withFullyResolvedAst: true);
+ }
+
test_field_inferred_type_static_implicit_initialized() async {
var library = await checkLibrary('class C { static var v = 0; }');
checkElementText(library, r'''
@@ -6747,6 +7105,38 @@
''');
}
+ test_functionTypeAlias_enclosingElements() async {
+ var library = await checkLibrary(r'''
+typedef void F<T>(int a);
+''');
+ var unit = library.definingCompilationUnit;
+
+ var F = unit.functionTypeAliases[0];
+ expect(F.name, 'F');
+
+ var T = F.typeParameters[0];
+ expect(T.name, 'T');
+ expect(T.enclosingElement, same(F));
+
+ var function = F.function;
+ expect(function.enclosingElement, same(F));
+
+ var a = function.parameters[0];
+ expect(a.name, 'a');
+ expect(a.enclosingElement, same(function));
+ }
+
+ test_functionTypeAlias_type_element() async {
+ var library = await checkLibrary(r'''
+typedef T F<T>();
+F<int> a;
+''');
+ var unit = library.definingCompilationUnit;
+ var type = unit.topLevelVariables[0].type as FunctionType;
+ expect(type.element.enclosingElement, same(unit.functionTypeAliases[0]));
+ _assertTypeStrings(type.typeArguments, ['int*']);
+ }
+
test_functionTypeAlias_typeParameters_variance_contravariant() async {
var library = await checkLibrary(r'''
typedef void F<T>(T a);
@@ -7050,6 +7440,31 @@
''');
}
+ test_genericTypeAlias_enclosingElements() async {
+ var library = await checkLibrary(r'''
+typedef F<T> = void Function<U>(int a);
+''');
+ var unit = library.definingCompilationUnit;
+
+ var F = unit.functionTypeAliases[0];
+ expect(F.name, 'F');
+
+ var T = F.typeParameters[0];
+ expect(T.name, 'T');
+ expect(T.enclosingElement, same(F));
+
+ var function = F.function;
+ expect(function.enclosingElement, same(F));
+
+ var U = function.typeParameters[0];
+ expect(U.name, 'U');
+ expect(U.enclosingElement, same(function));
+
+ var a = function.parameters[0];
+ expect(a.name, 'a');
+ expect(a.enclosingElement, same(function));
+ }
+
test_genericTypeAlias_recursive() async {
var library = await checkLibrary('''
typedef F<X extends F> = Function(F);
@@ -7511,6 +7926,16 @@
''');
}
+ test_import_show_offsetEnd() async {
+ var library = await checkLibrary('''
+import "dart:math" show e, pi;
+''');
+ var import = library.imports[0];
+ var combinator = import.combinators[0] as ShowElementCombinator;
+ expect(combinator.offset, 19);
+ expect(combinator.end, 29);
+ }
+
test_import_uri() async {
allowMissingFiles = true;
var library = await checkLibrary('''
@@ -9367,15 +9792,54 @@
}
test_metadata_importDirective() async {
- addLibrarySource('/foo.dart', 'const b = null;');
+ addLibrarySource('/foo.dart', 'const b = 0;');
var library = await checkLibrary('@a import "foo.dart"; const a = b;');
- checkElementText(library, r'''
-@
- a/*location: test.dart;a?*/
+ checkElementText(
+ library,
+ '''
import 'foo.dart';
-const dynamic a =
- b/*location: foo.dart;b?*/;
+ metadata
+ Annotation
+ element: self::@getter::a
+ name: SimpleIdentifier
+ staticElement: self::@getter::a
+ staticType: null
+ token: a
+const int a;
+ constantInitializer
+ SimpleIdentifier
+ staticElement: ${toUriStr('/foo.dart')}::@getter::b
+ staticType: int
+ token: b
+''',
+ withFullyResolvedAst: true);
+ }
+
+ test_metadata_importDirective_hasShow() async {
+ var library = await checkLibrary(r'''
+@a
+import "dart:math" show Random;
+
+const a = 0;
''');
+ checkElementText(
+ library,
+ r'''
+import 'dart:math' show Random;
+ metadata
+ Annotation
+ element: self::@getter::a
+ name: SimpleIdentifier
+ staticElement: self::@getter::a
+ staticType: null
+ token: a
+const int a;
+ constantInitializer
+ IntegerLiteral
+ literal: 0
+ staticType: int
+''',
+ withFullyResolvedAst: true);
}
test_metadata_invalid_classDeclaration() async {
@@ -9570,6 +10034,23 @@
''');
}
+ test_metadata_partDirective2() async {
+ addSource('/a.dart', r'''
+part of 'test.dart';
+''');
+ addSource('/b.dart', r'''
+part of 'test.dart';
+''');
+ var library = await checkLibrary('''
+part 'a.dart';
+part 'b.dart';
+''');
+
+ // The difference with the test above is that we ask the part first.
+ // There was a bug that we were not loading library directives.
+ expect(library.parts[0].metadata, isEmpty);
+ }
+
test_metadata_prefixed_variable() async {
addLibrarySource('/a.dart', 'const b = null;');
var library = await checkLibrary('import "a.dart" as a; @a.b class C {}');
@@ -12084,6 +12565,21 @@
''');
}
+ test_variable_implicit() async {
+ var library = await checkLibrary('int get x => 0;');
+
+ // We intentionally don't check the text, because we want to test
+ // requesting individual elements, not all accessors/variables at once.
+ var getter = _elementOfDefiningUnit(library, '@getter', 'x')
+ as PropertyAccessorElementImpl;
+ var variable = getter.variable as TopLevelVariableElementImpl;
+ expect(variable, isNotNull);
+ expect(variable.isFinal, isTrue);
+ expect(variable.getter, same(getter));
+ expect('${variable.type}', 'int*');
+ expect(variable, same(_elementOfDefiningUnit(library, '@field', 'x')));
+ }
+
test_variable_implicit_type() async {
var library = await checkLibrary('var x;');
checkElementText(library, r'''
@@ -12345,11 +12841,32 @@
var typeStr = type.getDisplayString(withNullability: false);
expect(typeStr, expected);
}
+
+ void _assertTypeStrings(List<DartType> types, List<String> expected) {
+ var typeStringList = types.map((e) {
+ return e.getDisplayString(withNullability: true);
+ }).toList();
+ expect(typeStringList, expected);
+ }
+
+ Element _elementOfDefiningUnit(LibraryElementImpl library,
+ [String name1, String name2, String name3]) {
+ var unit = library.definingCompilationUnit as CompilationUnitElementImpl;
+ var reference = unit.reference;
+
+ [name1, name2, name3].takeWhile((e) => e != null).forEach((name) {
+ reference = reference.getChild(name);
+ });
+
+ var elementFactory = unit.linkedContext.elementFactory;
+ return elementFactory.elementOfReference(reference);
+ }
}
/// Mixin containing helper methods for testing summary resynthesis. Intended
/// to be applied to a class implementing [ResynthesizeTestStrategy].
-mixin ResynthesizeTestHelpers implements ResynthesizeTestStrategy {
+mixin ResynthesizeTestHelpers
+ implements ResynthesizeTestStrategy, ResourceProviderMixin {
Future<LibraryElementImpl /*!*/ > checkLibrary(String text,
{bool allowErrors = false, bool dumpSummaries = false}) async {
throw 42;
diff --git a/pkg/analyzer/test/src/summary/test_strategies.dart b/pkg/analyzer/test/src/summary/test_strategies.dart
index 8ec7cc3..9fab0f2 100644
--- a/pkg/analyzer/test/src/summary/test_strategies.dart
+++ b/pkg/analyzer/test/src/summary/test_strategies.dart
@@ -15,7 +15,6 @@
import 'package:analyzer/src/dart/scanner/scanner.dart';
import 'package:analyzer/src/generated/parser.dart';
import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/summarize_elements.dart';
import 'resynthesize_common.dart';
@@ -88,6 +87,4 @@
FeatureSet featureSet = FeatureSet.forTesting(sdkVersion: '2.7.0');
final Set<Source> serializedSources = <Source>{};
-
- PackageBundleAssembler bundleAssembler = PackageBundleAssembler();
}
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index 9188c8c..73d9ac2 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -152,9 +152,6 @@
var errorTypeMap = <Type, List<ErrorCode>>{};
for (ErrorCode code in errorCodeValues) {
Type type = code.runtimeType;
- if (type == HintCodeWithUniqueName) {
- type = HintCode;
- }
errorTypeMap.putIfAbsent(type, () => <ErrorCode>[]).add(code);
}
diff --git a/pkg/analyzer_cli/lib/src/build_mode.dart b/pkg/analyzer_cli/lib/src/build_mode.dart
index 3098758..f022eeb 100644
--- a/pkg/analyzer_cli/lib/src/build_mode.dart
+++ b/pkg/analyzer_cli/lib/src/build_mode.dart
@@ -4,6 +4,7 @@
import 'dart:io' as io;
import 'dart:isolate';
+import 'dart:typed_data';
import 'package:analyzer/dart/analysis/context_locator.dart' as api;
import 'package:analyzer/dart/analysis/declared_variables.dart';
@@ -20,18 +21,17 @@
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/analysis/session.dart';
-import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/source/source_resource.dart';
-import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/package_bundle_reader.dart';
-import 'package:analyzer/src/summary/summarize_elements.dart';
import 'package:analyzer/src/summary/summary_sdk.dart' show SummaryBasedDartSdk;
+import 'package:analyzer/src/summary2/bundle_reader.dart';
import 'package:analyzer/src/summary2/link.dart' as summary2;
-import 'package:analyzer/src/summary2/linked_bundle_context.dart' as summary2;
import 'package:analyzer/src/summary2/linked_element_factory.dart' as summary2;
+import 'package:analyzer/src/summary2/linked_library_context.dart' as summary2;
+import 'package:analyzer/src/summary2/package_bundle_format.dart';
import 'package:analyzer/src/summary2/reference.dart' as summary2;
import 'package:analyzer_cli/src/context_cache.dart';
import 'package:analyzer_cli/src/driver.dart';
@@ -170,14 +170,11 @@
AnalysisOptionsImpl analysisOptions;
Map<Uri, File> uriToFileMap;
final List<Source> explicitSources = <Source>[];
- final List<PackageBundle> unlinkedBundles = <PackageBundle>[];
SourceFactory sourceFactory;
DeclaredVariables declaredVariables;
AnalysisDriver analysisDriver;
- PackageBundleAssembler assembler;
-
summary2.LinkedElementFactory elementFactory;
// May be null.
@@ -244,24 +241,20 @@
}
// Write summary.
- assembler = PackageBundleAssembler();
if (_shouldOutputSummary) {
await logger.runAsync('Build and write output summary', () async {
// Build and assemble linked libraries.
- _computeLinkedLibraries2();
+ var bytes = _computeLinkedLibraries2();
// Write the whole package bundle.
- var bundle = assembler.assemble();
+ // TODO(scheglov) Remove support for `buildSummaryOutput`.
if (options.buildSummaryOutput != null) {
var file = io.File(options.buildSummaryOutput);
- file.writeAsBytesSync(bundle.toBuffer(),
- mode: io.FileMode.writeOnly);
+ file.writeAsBytesSync(bytes, mode: io.FileMode.writeOnly);
}
if (options.buildSummaryOutputSemantic != null) {
- bundle.flushInformative();
var file = io.File(options.buildSummaryOutputSemantic);
- file.writeAsBytesSync(bundle.toBuffer(),
- mode: io.FileMode.writeOnly);
+ file.writeAsBytesSync(bytes, mode: io.FileMode.writeOnly);
}
});
} else {
@@ -290,9 +283,9 @@
}
/// Use [elementFactory] filled with input summaries, and link libraries
- /// in [explicitSources] to produce linked libraries in [assembler].
- void _computeLinkedLibraries2() {
- logger.run('Link output summary2', () {
+ /// in [explicitSources] to produce linked summary bytes.
+ Uint8List _computeLinkedLibraries2() {
+ return logger.run('Link output summary2', () {
var inputLibraries = <summary2.LinkInputLibrary>[];
for (var librarySource in explicitSources) {
@@ -349,8 +342,19 @@
);
}
- var linkResult = summary2.link(elementFactory, inputLibraries);
- assembler.setBundle2(linkResult.bundle);
+ var linkResult = summary2.link(elementFactory, inputLibraries, false);
+
+ var bundleBuilder = PackageBundleBuilder();
+ for (var library in inputLibraries) {
+ bundleBuilder.addLibrary(
+ library.uriStr,
+ library.units.map((e) => e.uriStr).toList(),
+ );
+ }
+ return bundleBuilder.finish(
+ astBytes: linkResult.astBytes,
+ resolutionBytes: linkResult.resolutionBytes,
+ );
});
}
@@ -376,7 +380,7 @@
summaryDataStore = SummaryDataStore(<String>[]);
// Adds a bundle at `path` to `summaryDataStore`.
- PackageBundle addBundle(String path) {
+ PackageBundleReader addBundle(String path) {
var bundle = packageBundleProvider.get(path);
summaryDataStore.addBundle(path, bundle);
return bundle;
@@ -449,7 +453,11 @@
for (var bundle in summaryDataStore.bundles) {
elementFactory.addBundle(
- summary2.LinkedBundleContext(elementFactory, bundle.bundle2),
+ BundleReader(
+ elementFactory: elementFactory,
+ astBytes: bundle.astBytes,
+ resolutionBytes: bundle.resolutionBytes,
+ ),
);
}
}
@@ -567,9 +575,9 @@
DirectPackageBundleProvider(this.resourceProvider);
@override
- PackageBundle get(String path) {
+ PackageBundleReader get(String path) {
var bytes = io.File(path).readAsBytesSync();
- return PackageBundle.fromBuffer(bytes);
+ return PackageBundleReader(bytes);
}
}
@@ -610,10 +618,10 @@
}
}
-/// Provider for [PackageBundle]s by file paths.
+/// Provider for [PackageBundleReader]s by file paths.
abstract class PackageBundleProvider {
- /// Return the [PackageBundle] for the file with the given [path].
- PackageBundle get(String path);
+ /// Return the [PackageBundleReader] for the file with the given [path].
+ PackageBundleReader get(String path);
}
/// Wrapper for [InSummaryUriResolver] that tracks accesses to summaries.
@@ -667,7 +675,7 @@
/// Value object for [WorkerPackageBundleCache].
class WorkerPackageBundle {
final List<int> bytes;
- final PackageBundle bundle;
+ final PackageBundleReader bundle;
WorkerPackageBundle(this.bytes, this.bundle);
@@ -675,7 +683,7 @@
int get size => bytes.length * 3;
}
-/// Cache of [PackageBundle]s.
+/// Cache of [PackageBundleReader]s.
class WorkerPackageBundleCache {
final ResourceProvider resourceProvider;
final PerformanceLog logger;
@@ -685,23 +693,25 @@
: _cache = Cache<WorkerInput, WorkerPackageBundle>(
maxSizeBytes, (value) => value.size);
- /// Get the [PackageBundle] from the file with the given [path] in the context
+ /// Get the [PackageBundleReader] from the file with the given [path] in the context
/// of the given worker [inputs].
- PackageBundle get(Map<String, WorkerInput> inputs, String path) {
+ PackageBundleReader get(Map<String, WorkerInput> inputs, String path) {
var input = inputs[path];
// The input must be not null, otherwise we're not expected to read
// this file, but we check anyway to be safe.
if (input == null) {
logger.writeln('Read $path outside of the inputs.');
- var bytes = resourceProvider.getFile(path).readAsBytesSync();
- return PackageBundle.fromBuffer(bytes);
+ var file = resourceProvider.getFile(path);
+ var bytes = file.readAsBytesSync() as Uint8List;
+ return PackageBundleReader(bytes);
}
return _cache.get(input, () {
logger.writeln('Read $input.');
- var bytes = resourceProvider.getFile(path).readAsBytesSync();
- var bundle = PackageBundle.fromBuffer(bytes);
+ var file = resourceProvider.getFile(path);
+ var bytes = file.readAsBytesSync() as Uint8List;
+ var bundle = PackageBundleReader(bytes);
return WorkerPackageBundle(bytes, bundle);
}).bundle;
}
@@ -716,7 +726,7 @@
WorkerPackageBundleProvider(this.cache, this.inputs);
@override
- PackageBundle get(String path) {
+ PackageBundleReader get(String path) {
return cache.get(inputs, path);
}
}
diff --git a/pkg/analyzer_cli/test/driver_test.dart b/pkg/analyzer_cli/test/driver_test.dart
index 33f0529..0ec7a94 100644
--- a/pkg/analyzer_cli/test/driver_test.dart
+++ b/pkg/analyzer_cli/test/driver_test.dart
@@ -10,7 +10,7 @@
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary2/package_bundle_format.dart';
import 'package:analyzer/src/util/sdk.dart';
import 'package:analyzer_cli/src/ansi.dart' as ansi;
import 'package:analyzer_cli/src/driver.dart';
@@ -248,39 +248,25 @@
Future<void> test_import2_usedAsSupertype() async {
await _withTempDir(() async {
var a = await _buildPackage('a', [], 'class A {}');
- var b = await _buildPackage('b', [a], '''
+ var b = await _buildPackage('b', [], 'class B {}');
+ var c = await _buildPackage('c', [a], '''
import 'package:a/a.dart';
-class B extends A {}
+import 'package:b/b.dart';
+class C1 extends A {}
+class C2 extends B {}
''');
- // We don't invoke anything on class `B`, so don't ask its supertype.
- // So, no dependency on "a".
- await _assertDependencies('c', [a, b], '''
-import 'package:b/b.dart';
-B x;
-''', [b]);
-
- // We infer the type of `x` to `B`.
- // But we don't ask `B` for its supertype.
- // So, no dependency on "a".
- await _assertDependencies('c', [a, b], '''
-import 'package:b/b.dart';
-var x = B();
-''', [b]);
-
- // We perform full analysis, and check that `new B()` is assignable
- // to `B x`. This is trivially true, we don't need the supertype of `B`.
- // So, no dependency on "a".
- await _assertDependencies(
- 'c',
- [a, b],
- '''
-import 'package:b/b.dart';
-var x = B();
-''',
- [b],
- summaryOnly: false,
- );
+ // When we instantiate `C1`, we ask `C1` for its type parameters.
+ // So, we apply resolution to the whole `C1` header (not members).
+ // So, we request `A` that is the superclass of `C1`.
+ // So, dependency on "a".
+ //
+ // But we don't access `C2`, so don't use its supertype `B`.
+ // So, no dependency on "b".
+ await _assertDependencies('d', [a, b, c], '''
+import 'package:c/c.dart';
+C1 x;
+''', [a, c]);
});
}
@@ -442,13 +428,12 @@
]);
var output = File(outputPath);
expect(output.existsSync(), isTrue);
- var bundle = PackageBundle.fromBuffer(await output.readAsBytes());
+ var bundle = PackageBundleReader(await output.readAsBytes());
var testFileUri = 'file:///test_file.dart';
- var bundle2 = bundle.bundle2;
- expect(_linkedLibraryUriList(bundle2), [testFileUri]);
+ expect(_linkedLibraryUriList(bundle), [testFileUri]);
expect(
- _linkedLibraryUnitUriList(bundle2, testFileUri),
+ _linkedLibraryUnitUriList(bundle, testFileUri),
[testFileUri],
);
@@ -472,10 +457,9 @@
fileUri: aUri, additionalArgs: ['--build-summary-output=$aSum']);
expect(exitCode, ErrorSeverity.ERROR.ordinal);
var bytes = File(aSum).readAsBytesSync();
- var bundle = PackageBundle.fromBuffer(bytes);
- var bundle2 = bundle.bundle2;
- expect(_linkedLibraryUriList(bundle2), [aUri]);
- expect(_linkedLibraryUnitUriList(bundle2, aUri), [aUri, '']);
+ var bundle = PackageBundleReader(bytes);
+ expect(_linkedLibraryUriList(bundle), [aUri]);
+ expect(_linkedLibraryUnitUriList(bundle, aUri), [aUri, '']);
});
}
@@ -522,10 +506,9 @@
fileUri: aUri, additionalArgs: ['--build-summary-output=$aSum']);
expect(exitCode, 0);
var bytes = File(aSum).readAsBytesSync();
- var bundle = PackageBundle.fromBuffer(bytes);
- var bundle2 = bundle.bundle2;
- expect(_linkedLibraryUriList(bundle2), [aUri]);
- expect(_linkedLibraryUnitUriList(bundle2, aUri), [aUri]);
+ var bundle = PackageBundleReader(bytes);
+ expect(_linkedLibraryUriList(bundle), [aUri]);
+ expect(_linkedLibraryUnitUriList(bundle, aUri), [aUri]);
}
// Analyze package:bbb/b.dart and compute summary.
@@ -536,10 +519,9 @@
]);
expect(exitCode, 0);
var bytes = File(bSum).readAsBytesSync();
- var bundle = PackageBundle.fromBuffer(bytes);
- var bundle2 = bundle.bundle2;
- expect(_linkedLibraryUriList(bundle2), [bUri]);
- expect(_linkedLibraryUnitUriList(bundle2, bUri), [bUri]);
+ var bundle = PackageBundleReader(bytes);
+ expect(_linkedLibraryUriList(bundle), [bUri]);
+ expect(_linkedLibraryUnitUriList(bundle, bUri), [bUri]);
}
// Analyze package:ccc/c.dart and compute summary.
@@ -550,10 +532,9 @@
]);
expect(exitCode, 0);
var bytes = File(cSum).readAsBytesSync();
- var bundle = PackageBundle.fromBuffer(bytes);
- var bundle2 = bundle.bundle2;
- expect(_linkedLibraryUriList(bundle2), [cUri]);
- expect(_linkedLibraryUnitUriList(bundle2, cUri), [cUri]);
+ var bundle = PackageBundleReader(bytes);
+ expect(_linkedLibraryUriList(bundle), [cUri]);
+ expect(_linkedLibraryUnitUriList(bundle, cUri), [cUri]);
}
});
}
@@ -715,16 +696,16 @@
}
Iterable<String> _linkedLibraryUnitUriList(
- LinkedNodeBundle bundle2,
+ PackageBundleReader bundle,
String libraryUriStr,
) {
- var libraries = bundle2.libraries;
+ var libraries = bundle.libraries;
var library = libraries.singleWhere((l) => l.uriStr == libraryUriStr);
return library.units.map((u) => u.uriStr).toList();
}
- Iterable<String> _linkedLibraryUriList(LinkedNodeBundle bundle2) {
- var libraries = bundle2.libraries;
+ Iterable<String> _linkedLibraryUriList(PackageBundleReader bundle) {
+ var libraries = bundle.libraries;
return libraries.map((l) => l.uriStr).toList();
}
}
diff --git a/pkg/compiler/lib/src/inferrer/list_tracer.dart b/pkg/compiler/lib/src/inferrer/list_tracer.dart
index db86752..17bb7ed 100644
--- a/pkg/compiler/lib/src/inferrer/list_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/list_tracer.dart
@@ -6,6 +6,7 @@
import '../common/names.dart';
import '../elements/entities.dart';
+import '../native/behavior.dart';
import '../universe/selector.dart' show Selector;
import '../util/util.dart' show Setlet;
import 'node_tracer.dart';
@@ -162,10 +163,16 @@
@override
visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) {
super.visitStaticCallSiteTypeInformation(info);
+ final commonElements = inferrer.closedWorld.commonElements;
MemberEntity called = info.calledElement;
- if (inferrer.closedWorld.commonElements.isForeign(called) &&
- called.name == Identifiers.JS) {
- bailout('Used in JS ${info.debugName}');
+ if (commonElements.isForeign(called) && called.name == Identifiers.JS) {
+ NativeBehavior nativeBehavior = inferrer.closedWorld.elementMap
+ .getNativeBehaviorForJsCall(info.invocationNode);
+ // Assume side-effects means that the list has escaped to some unknown
+ // location.
+ if (nativeBehavior.sideEffects.hasSideEffects()) {
+ bailout('Used in JS ${info.debugName}');
+ }
}
}
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index 365500e..78664eb 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -968,6 +968,8 @@
: super(abstractValueDomain, context, call, enclosing, selector,
arguments, inLoop);
+ ir.StaticInvocation get invocationNode => _call as ir.StaticInvocation;
+
MemberTypeInformation _getCalledTypeInfo(InferrerEngine inferrer) {
return inferrer.types.getInferredTypeOfMember(calledElement);
}
diff --git a/pkg/compiler/test/inference/data/closure_tracer.dart b/pkg/compiler/test/inference/data/closure_tracer.dart
index 08105f7..edccdb3 100644
--- a/pkg/compiler/test/inference/data/closure_tracer.dart
+++ b/pkg/compiler/test/inference/data/closure_tracer.dart
@@ -51,22 +51,22 @@
return res;
}
-/*member: testStoredInMapOfList:[null|subclass=Object]*/
+/*member: testStoredInMapOfList:[null|exact=JSUInt31]*/
testStoredInMapOfList() {
var res;
- /*[null|subclass=Object]*/ closure(/*[null|subclass=Object]*/ a) => res = a;
+ /*[exact=JSUInt31]*/ closure(/*[exact=JSUInt31]*/ a) => res = a;
dynamic a = <dynamic>[closure];
dynamic b = <dynamic, dynamic>{'foo': 1};
b
- /*update: Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSUInt31]), map: {foo: [exact=JSUInt31], bar: Container([null|exact=JSExtendableArray], element: [null|subclass=Object], length: null)})*/
+ /*update: Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSUInt31]), map: {foo: [exact=JSUInt31], bar: Container([null|exact=JSExtendableArray], element: [subclass=Closure], length: 1)})*/
['bar'] = a;
b
- /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSUInt31]), map: {foo: [exact=JSUInt31], bar: Container([null|exact=JSExtendableArray], element: [null|subclass=Object], length: null)})*/
+ /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSExtendableArray], [exact=JSUInt31]), map: {foo: [exact=JSUInt31], bar: Container([null|exact=JSExtendableArray], element: [subclass=Closure], length: 1)})*/
['bar']
- /*Container([null|exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
+ /*Container([null|exact=JSExtendableArray], element: [subclass=Closure], length: 1)*/
[0](42);
return res;
}
diff --git a/pkg/compiler/test/inference/data/list_js.dart b/pkg/compiler/test/inference/data/list_js.dart
new file mode 100644
index 0000000..9b64060
--- /dev/null
+++ b/pkg/compiler/test/inference/data/list_js.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test effect of NativeBehavior on list tracing.
+
+/// ignore: IMPORT_INTERNAL_LIBRARY
+import 'dart:_foreign_helper' show JS;
+
+/*member: main:[null]*/
+main() {
+ test1();
+ test2();
+ test3();
+ test4();
+}
+
+/*member: test1:[null]*/
+test1() {
+ var list = [42];
+ JS('', '#', list); // '#' is by default a no-op.
+ witness1(list);
+}
+
+/*member: witness1:[null]*/
+witness1(
+ /*Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/ x) {}
+
+/*member: test2:[null]*/
+test2() {
+ var list = [42];
+ JS('effects:all;depends:all', '#', list);
+ witness2(list);
+}
+
+/*member: witness2:[null]*/
+witness2(
+ /*Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/ x) {}
+
+/*member: test3:[null]*/
+test3() {
+ var list = [42];
+ JS('', '#.slice(0)', list);
+ witness3(list);
+}
+
+/*member: witness3:[null]*/
+witness3(
+ /*Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/ x) {}
+
+/*member: test4:[null]*/
+test4() {
+ var list = [42];
+ JS('effects:none;depends:all', '#.slice(0)', list);
+ witness4(list);
+}
+
+/*member: witness4:[null]*/
+witness4(
+ /*Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/ x) {}
diff --git a/pkg/compiler/test/inference/data/map_tracer_keys.dart b/pkg/compiler/test/inference/data/map_tracer_keys.dart
index 20e469e..3f183a6 100644
--- a/pkg/compiler/test/inference/data/map_tracer_keys.dart
+++ b/pkg/compiler/test/inference/data/map_tracer_keys.dart
@@ -79,28 +79,28 @@
/*member: aDouble3:Union(null, [exact=JSDouble], [exact=JSExtendableArray])*/
dynamic aDouble3 = 42.5;
-/*member: aList3:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
+/*member: aList3:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
dynamic aList3 = [42];
-/*member: consume3:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
+/*member: consume3:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
consume3(
- /*Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/ x) =>
+ /*Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/ x) =>
x;
/*member: test3:[null]*/
test3() {
dynamic theMap = <dynamic, dynamic>{'a': 2.2, 'b': 3.3, 'c': 4.4};
theMap
- /*update: Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSDouble], [exact=JSExtendableArray]), map: {a: [exact=JSDouble], b: [exact=JSDouble], c: [exact=JSDouble], d: Container([null|exact=JSExtendableArray], element: [null|subclass=Object], length: null)})*/
+ /*update: Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSDouble], [exact=JSExtendableArray]), map: {a: [exact=JSDouble], b: [exact=JSDouble], c: [exact=JSDouble], d: Container([null|exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)})*/
['d'] = aList3;
/*iterator: [exact=LinkedHashMapKeyIterable]*/
/*current: [exact=LinkedHashMapKeyIterator]*/
/*moveNext: [exact=LinkedHashMapKeyIterator]*/
for (var key in theMap.
- /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSDouble], [exact=JSExtendableArray]), map: {a: [exact=JSDouble], b: [exact=JSDouble], c: [exact=JSDouble], d: Container([null|exact=JSExtendableArray], element: [null|subclass=Object], length: null)})*/
+ /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSDouble], [exact=JSExtendableArray]), map: {a: [exact=JSDouble], b: [exact=JSDouble], c: [exact=JSDouble], d: Container([null|exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)})*/
keys) {
aDouble3 = theMap
- /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSDouble], [exact=JSExtendableArray]), map: {a: [exact=JSDouble], b: [exact=JSDouble], c: [exact=JSDouble], d: Container([null|exact=JSExtendableArray], element: [null|subclass=Object], length: null)})*/
+ /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union(null, [exact=JSDouble], [exact=JSExtendableArray]), map: {a: [exact=JSDouble], b: [exact=JSDouble], c: [exact=JSDouble], d: Container([null|exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)})*/
[key];
}
// We have to reference it somewhere, so that it always gets resolved.
diff --git a/pkg/compiler/test/inference/list_tracer_test.dart b/pkg/compiler/test/inference/list_tracer_test.dart
index 9658374..4e23f1b 100644
--- a/pkg/compiler/test/inference/list_tracer_test.dart
+++ b/pkg/compiler/test/inference/list_tracer_test.dart
@@ -237,9 +237,7 @@
checkType('listEscapingInSetterValue', commonMasks.numType);
checkType('listEscapingInIndex', commonMasks.numType);
checkType('listEscapingInIndexSet', commonMasks.uint31Type);
- // TODO(johnniwinther): Since Iterable.iterableToString is part of the closed
- // world we find the `dynamicType` instead of `numType`.
- checkType('listEscapingTwiceInIndexSet', commonMasks.dynamicType);
+ checkType('listEscapingTwiceInIndexSet', commonMasks.numType);
checkType('listSetInNonFinalField', commonMasks.numType);
checkType('listWithChangedLength', commonMasks.uint31Type.nullable());
diff --git a/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart b/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart
index c208be1..1d521a5 100644
--- a/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart
+++ b/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart
@@ -128,3 +128,160 @@
}
return false;
}
+
+/// Returns `true` if [node] is the local variable holding the value of a
+/// lowered late variable.
+///
+/// For instance
+///
+/// late int local;
+///
+/// is lowered to (simplified):
+///
+/// int? #local = null;
+/// int #local#get() => #local != null ? #local : throw 'Uninitialized';
+/// void #local#set(int value) {
+/// #local = value;
+/// }
+///
+/// where '#local' is the local variable holding that value.
+///
+/// The default value of this variable is `null`.
+// TODO(johnniwinther): Enable these if the name of late locals is changed
+// to '${lateLocalPrefix}${name}'. See
+// backends can benefit from identifying late locals.
+/*bool isLateLoweredLocal(VariableDeclaration node) {
+ return node.name != null && isLateLoweredLocalName(node.name);
+}
+
+/// Returns `true` if [name] is the name of a local variable holding the value
+/// of a lowered late variable.
+bool isLateLoweredLocalName(String name) {
+ return name.startsWith(lateLocalPrefix) &&
+ !(name.endsWith(lateIsSetSuffix) ||
+ name.endsWith(lateLocalGetterSuffix) ||
+ name.endsWith(lateLocalSetterSuffix));
+}
+
+/// Returns the name of the original late local variable from the [name] of the
+/// local variable holding the value of the lowered late variable.
+///
+/// This method assumes that `isLateLoweredLocalName(name)` is `true`.
+String extractLateLoweredLocalNameFrom(String name) {
+ return name.substring(lateLocalPrefix.length);
+}*/
+
+/// Returns `true` if [node] is the local variable holding the marker for
+/// whether a lowered late local variable has been set or not.
+///
+/// For instance
+///
+/// late int? local;
+///
+/// is lowered to (simplified):
+///
+/// bool #local#isSet = false;
+/// int? #local = null;
+/// int #local#get() => _#field#isSet ? #local : throw 'Uninitialized';
+/// void #local#set(int value) {
+/// #local = value;
+/// #local#isSet = true;
+/// }
+///
+/// where '#local#isSet' is the local variable holding the marker.
+///
+/// The default value of this variable is `false`.
+bool isLateLoweredIsSetLocal(VariableDeclaration node) {
+ return node.name != null && isLateLoweredIsSetName(node.name);
+}
+
+/// Returns `true` if [name] is the name of a local variable holding the marker
+/// for whether a lowered late local variable has been set or not.
+bool isLateLoweredIsSetName(String name) {
+ return name.startsWith(lateLocalPrefix) && name.endsWith(lateIsSetSuffix);
+}
+
+/// Returns the name of the original late local variable from the [name] of the
+/// local variable holding the marker for whether the lowered late local
+/// variable has been set or not.
+///
+/// This method assumes that `isLateLoweredIsSetName(name)` is `true`.
+String extractLocalNameFromLateLoweredIsSet(String name) {
+ return name.substring(
+ lateLocalPrefix.length, name.length - lateIsSetSuffix.length);
+}
+
+/// Returns `true` if [node] is the local variable for the local function for
+/// reading the value of a lowered late variable.
+///
+/// For instance
+///
+/// late int local;
+///
+/// is lowered to (simplified):
+///
+/// int? #local = null;
+/// int #local#get() => #local != null ? #local : throw 'Uninitialized';
+/// void #local#set(int value) {
+/// #local = value;
+/// }
+///
+/// where '#local#get' is the local function for reading the variable.
+bool isLateLoweredLocalGetter(VariableDeclaration node) {
+ return node.name != null && isLateLoweredGetterName(node.name);
+}
+
+/// Returns `true` if [name] is the name of the local variable for the local
+/// function for reading the value of a lowered late variable.
+bool isLateLoweredGetterName(String name) {
+ return name.startsWith(lateLocalPrefix) &&
+ name.endsWith(lateLocalGetterSuffix);
+}
+
+/// Returns the name of the original late local variable from the [name] of the
+/// local variable for the local function for reading the value of the lowered
+/// late variable.
+///
+/// This method assumes that `isLateLoweredGetterName(name)` is `true`.
+String extractLocalNameFromLateLoweredGetter(String name) {
+ return name.substring(
+ lateLocalPrefix.length, name.length - lateLocalGetterSuffix.length);
+}
+
+/// Returns `true` if [node] is the local variable for the local function for
+/// setting the value of a lowered late variable.
+///
+/// For instance
+///
+/// late int local;
+///
+/// is lowered to (simplified):
+///
+/// int? #local = null;
+/// int #local#get() => #local != null ? #local : throw 'Uninitialized';
+/// void #local#set(int value) {
+/// #local = value;
+/// }
+///
+/// where '#local#set' is the local function for setting the value of the
+/// variable.
+bool isLateLoweredLocalSetter(VariableDeclaration node) {
+ return node.name != null && isLateLoweredSetterName(node.name);
+}
+
+/// Returns `true` if [name] is the name of the local variable for the local
+/// function for setting the value of a lowered late variable.
+bool isLateLoweredSetterName(String name) {
+ return name.startsWith(lateLocalPrefix) &&
+ name.endsWith(lateLocalSetterSuffix);
+}
+
+/// Returns the name of the original late local variable from the [name] of the
+/// local variable for the local function for setting the value of the lowered
+/// late variable.
+///
+/// This method assumes that `isLateLoweredSetterName(name)` is `true`.
+String extractLocalNameFromLateLoweredSetter(String name) {
+ return name.substring(
+ lateLocalPrefix.length, name.length - lateLocalSetterSuffix.length);
+}
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 7e91837..c2d9461 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -5803,9 +5803,7 @@
VariableDeclaration isSetVariable;
if (isSetEncoding == late_lowering.IsSetEncoding.useIsSetField) {
isSetVariable = new VariableDeclaration(
- '${late_lowering.lateLocalPrefix}'
- '${node.name}'
- '${late_lowering.lateIsSetSuffix}',
+ late_lowering.computeLateLocalIsSetName(node.name),
initializer: new BoolLiteral(false)..fileOffset = fileOffset,
type: inferrer.coreTypes.boolRawType(inferrer.library.nonNullable))
..fileOffset = fileOffset;
@@ -5827,11 +5825,9 @@
Expression createIsSetWrite(Expression value) =>
new VariableSet(isSetVariable, value);
- VariableDeclaration getVariable =
- new VariableDeclaration('${late_lowering.lateLocalPrefix}'
- '${node.name}'
- '${late_lowering.lateLocalGetterSuffix}')
- ..fileOffset = fileOffset;
+ VariableDeclaration getVariable = new VariableDeclaration(
+ late_lowering.computeLateLocalGetterName(node.name))
+ ..fileOffset = fileOffset;
FunctionDeclaration getter = new FunctionDeclaration(
getVariable,
new FunctionNode(
@@ -5863,11 +5859,9 @@
if (!node.isFinal || node.initializer == null) {
node.isLateFinalWithoutInitializer =
node.isFinal && node.initializer == null;
- VariableDeclaration setVariable =
- new VariableDeclaration('${late_lowering.lateLocalPrefix}'
- '${node.name}'
- '${late_lowering.lateLocalSetterSuffix}')
- ..fileOffset = fileOffset;
+ VariableDeclaration setVariable = new VariableDeclaration(
+ late_lowering.computeLateLocalSetterName(node.name))
+ ..fileOffset = fileOffset;
VariableDeclaration setterParameter =
new VariableDeclaration(null, type: node.type)
..fileOffset = fileOffset;
@@ -5917,6 +5911,8 @@
node.initializer = null;
}
node.type = inferrer.computeNullable(node.type);
+ node.lateName = node.name;
+ node.name = late_lowering.computeLateLocalName(node.name);
return new StatementInferenceResult.multiple(node.fileOffset, result);
}
@@ -5989,14 +5985,14 @@
declaredOrInferredType is! InvalidType) {
if (variable.isLate || variable.lateGetter != null) {
if (isDefinitelyUnassigned) {
+ String name = variable.lateName ?? variable.name;
return new ExpressionInferenceResult(
resultType,
inferrer.helper.wrapInProblem(
resultExpression,
- templateLateDefinitelyUnassignedError
- .withArguments(node.variable.name),
+ templateLateDefinitelyUnassignedError.withArguments(name),
node.fileOffset,
- node.variable.name.length));
+ name.length));
}
} else {
if (isUnassigned) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart b/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
index 05f9955..b7c839b 100644
--- a/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
@@ -1484,6 +1484,12 @@
// lowering is enabled.
DartType lateType;
+ // The original name of a lowered late variable.
+ //
+ // This is set in `InferenceVisitor.visitVariableDeclaration` when late
+ // lowering is enabled.
+ String lateName;
+
@override
bool get isAssignable {
if (isStaticLate) return true;
diff --git a/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart b/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart
index 74ca5c1..a2c6f50 100644
--- a/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart
@@ -592,3 +592,29 @@
}
throw new UnsupportedError("Unexpected IsSetStrategy $isSetStrategy");
}
+
+/// Returns the name used for the variable that holds the value of a late
+/// lowered local by the given [name].
+String computeLateLocalName(String name) {
+ // TODO(johnniwinther): Change this to '${lateLocalPrefix}${name}' if
+ // backends can benefit from identifying late locals.
+ return name;
+}
+
+/// Returns the name used for the 'isSet' variable of a late lowered local by
+/// the given [name].
+String computeLateLocalIsSetName(String name) {
+ return '${lateLocalPrefix}${name}${lateIsSetSuffix}';
+}
+
+/// Returns the name used for the getter function of a late lowered local by
+/// the given [name].
+String computeLateLocalGetterName(String name) {
+ return '${lateLocalPrefix}${name}${lateLocalGetterSuffix}';
+}
+
+/// Returns the name used for the setter function of a late lowered local by
+/// the given [name].
+String computeLateLocalSetterName(String name) {
+ return '${lateLocalPrefix}${name}${lateLocalSetterSuffix}';
+}
diff --git a/pkg/front_end/lib/src/fasta/util/direct_parser_ast.dart b/pkg/front_end/lib/src/fasta/util/direct_parser_ast.dart
index aa4bc82..9f2c1ae 100644
--- a/pkg/front_end/lib/src/fasta/util/direct_parser_ast.dart
+++ b/pkg/front_end/lib/src/fasta/util/direct_parser_ast.dart
@@ -6,6 +6,9 @@
import 'dart:io' show File;
+import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'
+ show ScannerConfiguration;
+
import 'package:_fe_analyzer_shared/src/parser/parser.dart'
show ClassMemberParser, Parser;
@@ -17,12 +20,21 @@
import 'package:front_end/src/fasta/util/direct_parser_ast_helper.dart';
DirectParserASTContentCompilationUnitEnd getAST(List<int> rawBytes,
- {bool includeBody: true, bool includeComments: false}) {
+ {bool includeBody: true,
+ bool includeComments: false,
+ bool enableExtensionMethods: false,
+ bool enableNonNullable: false,
+ bool enableTripleShift: false}) {
Uint8List bytes = new Uint8List(rawBytes.length + 1);
bytes.setRange(0, rawBytes.length, rawBytes);
- Utf8BytesScanner scanner =
- new Utf8BytesScanner(bytes, includeComments: includeComments);
+ ScannerConfiguration scannerConfiguration = new ScannerConfiguration(
+ enableExtensionMethods: enableExtensionMethods,
+ enableNonNullable: enableNonNullable,
+ enableTripleShift: enableTripleShift);
+
+ Utf8BytesScanner scanner = new Utf8BytesScanner(bytes,
+ includeComments: includeComments, configuration: scannerConfiguration);
Token firstToken = scanner.tokenize();
if (firstToken == null) {
throw "firstToken is null";
@@ -55,6 +67,331 @@
return true;
}
+ DirectParserASTContentClassDeclarationEnd asClass() {
+ if (!isClass()) throw "Not class";
+ return children.last;
+ }
+
+ bool isImport() {
+ if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+ return false;
+ }
+ if (children.first
+ is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
+ return false;
+ }
+ if (children.last is! DirectParserASTContentImportEnd) {
+ return false;
+ }
+
+ return true;
+ }
+
+ DirectParserASTContentImportEnd asImport() {
+ if (!isImport()) throw "Not import";
+ return children.last;
+ }
+
+ bool isExport() {
+ if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+ return false;
+ }
+ if (children.first
+ is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
+ return false;
+ }
+ if (children.last is! DirectParserASTContentExportEnd) {
+ return false;
+ }
+
+ return true;
+ }
+
+ DirectParserASTContentExportEnd asExport() {
+ if (!isExport()) throw "Not export";
+ return children.last;
+ }
+
+ bool isEnum() {
+ if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+ return false;
+ }
+ if (children.first
+ is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
+ return false;
+ }
+ if (children.last is! DirectParserASTContentEnumEnd) {
+ return false;
+ }
+
+ return true;
+ }
+
+ DirectParserASTContentEnumEnd asEnum() {
+ if (!isEnum()) throw "Not enum";
+ return children.last;
+ }
+
+ bool isTypedef() {
+ if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+ return false;
+ }
+ if (children.first
+ is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
+ return false;
+ }
+ if (children.last is! DirectParserASTContentFunctionTypeAliasEnd) {
+ return false;
+ }
+
+ return true;
+ }
+
+ DirectParserASTContentFunctionTypeAliasEnd asTypedef() {
+ if (!isTypedef()) throw "Not typedef";
+ return children.last;
+ }
+
+ bool isScript() {
+ if (this is! DirectParserASTContentScriptHandle) {
+ return false;
+ }
+ return true;
+ }
+
+ DirectParserASTContentScriptHandle asScript() {
+ if (!isScript()) throw "Not script";
+ return this;
+ }
+
+ bool isExtension() {
+ if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+ return false;
+ }
+ if (children.first
+ is! DirectParserASTContentExtensionDeclarationPreludeBegin) {
+ return false;
+ }
+ if (children.last is! DirectParserASTContentExtensionDeclarationEnd) {
+ return false;
+ }
+
+ return true;
+ }
+
+ DirectParserASTContentExtensionDeclarationEnd asExtension() {
+ if (!isExtension()) throw "Not extension";
+ return children.last;
+ }
+
+ bool isInvalidTopLevelDeclaration() {
+ if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+ return false;
+ }
+ if (children.first is! DirectParserASTContentTopLevelMemberBegin) {
+ return false;
+ }
+ if (children.last
+ is! DirectParserASTContentInvalidTopLevelDeclarationHandle) {
+ return false;
+ }
+
+ return true;
+ }
+
+ bool isRecoverableError() {
+ if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+ return false;
+ }
+ if (children.first
+ is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
+ return false;
+ }
+ if (children.last is! DirectParserASTContentRecoverableErrorHandle) {
+ return false;
+ }
+
+ return true;
+ }
+
+ bool isRecoverImport() {
+ if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+ return false;
+ }
+ if (children.first
+ is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
+ return false;
+ }
+ if (children.last is! DirectParserASTContentRecoverImportHandle) {
+ return false;
+ }
+
+ return true;
+ }
+
+ bool isMixinDeclaration() {
+ if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+ return false;
+ }
+ if (children.first
+ is! DirectParserASTContentClassOrNamedMixinApplicationPreludeBegin) {
+ return false;
+ }
+ if (children.last is! DirectParserASTContentMixinDeclarationEnd) {
+ return false;
+ }
+
+ return true;
+ }
+
+ DirectParserASTContentMixinDeclarationEnd asMixinDeclaration() {
+ if (!isMixinDeclaration()) throw "Not mixin declaration";
+ return children.last;
+ }
+
+ bool isNamedMixinDeclaration() {
+ if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+ return false;
+ }
+ if (children.first
+ is! DirectParserASTContentClassOrNamedMixinApplicationPreludeBegin) {
+ return false;
+ }
+ if (children.last is! DirectParserASTContentNamedMixinApplicationEnd) {
+ return false;
+ }
+
+ return true;
+ }
+
+ DirectParserASTContentNamedMixinApplicationEnd asNamedMixinDeclaration() {
+ if (!isNamedMixinDeclaration()) throw "Not named mixin declaration";
+ return children.last;
+ }
+
+ bool isTopLevelMethod() {
+ if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+ return false;
+ }
+ if (children.first is! DirectParserASTContentTopLevelMemberBegin) {
+ return false;
+ }
+ if (children.last is! DirectParserASTContentTopLevelMethodEnd) {
+ return false;
+ }
+
+ return true;
+ }
+
+ DirectParserASTContentTopLevelMethodEnd asTopLevelMethod() {
+ if (!isTopLevelMethod()) throw "Not top level method";
+ return children.last;
+ }
+
+ bool isTopLevelFields() {
+ if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+ return false;
+ }
+ if (children.first is! DirectParserASTContentTopLevelMemberBegin) {
+ return false;
+ }
+ if (children.last is! DirectParserASTContentTopLevelFieldsEnd) {
+ return false;
+ }
+
+ return true;
+ }
+
+ DirectParserASTContentTopLevelFieldsEnd asTopLevelFields() {
+ if (!isTopLevelFields()) throw "Not top level fields";
+ return children.last;
+ }
+
+ bool isLibraryName() {
+ if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+ return false;
+ }
+ if (children.first
+ is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
+ return false;
+ }
+ if (children.last is! DirectParserASTContentLibraryNameEnd) {
+ return false;
+ }
+
+ return true;
+ }
+
+ DirectParserASTContentLibraryNameEnd asLibraryName() {
+ if (!isLibraryName()) throw "Not library name";
+ return children.last;
+ }
+
+ bool isPart() {
+ if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+ return false;
+ }
+ if (children.first
+ is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
+ return false;
+ }
+ if (children.last is! DirectParserASTContentPartEnd) {
+ return false;
+ }
+
+ return true;
+ }
+
+ DirectParserASTContentPartEnd asPart() {
+ if (!isPart()) throw "Not part";
+ return children.last;
+ }
+
+ bool isPartOf() {
+ if (this is! DirectParserASTContentTopLevelDeclarationEnd) {
+ return false;
+ }
+ if (children.first
+ is! DirectParserASTContentUncategorizedTopLevelDeclarationBegin) {
+ return false;
+ }
+ if (children.last is! DirectParserASTContentPartOfEnd) {
+ return false;
+ }
+
+ return true;
+ }
+
+ DirectParserASTContentPartOfEnd asPartOf() {
+ if (!isPartOf()) throw "Not part of";
+ return children.last;
+ }
+
+ bool isMetadata() {
+ if (this is! DirectParserASTContentMetadataStarEnd) {
+ return false;
+ }
+ if (children.first is! DirectParserASTContentMetadataStarBegin) {
+ return false;
+ }
+ return true;
+ }
+
+ DirectParserASTContentMetadataStarEnd asMetadata() {
+ if (!isMetadata()) throw "Not metadata";
+ return this;
+ }
+
+ bool isFunctionBody() {
+ if (this is DirectParserASTContentBlockFunctionBodyEnd) return true;
+ return false;
+ }
+
+ DirectParserASTContentBlockFunctionBodyEnd asFunctionBody() {
+ if (!isFunctionBody()) throw "Not function body";
+ return this;
+ }
+
List<E> recursivelyFind<E extends DirectParserASTContent>() {
Set<E> result = {};
_recursivelyFindInternal(this, result);
@@ -72,6 +409,26 @@
_recursivelyFindInternal(child, result);
}
}
+
+ void debugDumpNodeRecursively({String indent = ""}) {
+ print("$indent${runtimeType} (${what}) "
+ "(${deprecatedArguments})");
+ if (children == null) return;
+ for (DirectParserASTContent child in children) {
+ child.debugDumpNodeRecursively(indent: " $indent");
+ }
+ }
+}
+
+extension MetadataStarExtension on DirectParserASTContentMetadataStarEnd {
+ List<DirectParserASTContentMetadataEnd> getMetadataEntries() {
+ List<DirectParserASTContentMetadataEnd> result = [];
+ for (DirectParserASTContent topLevel in children) {
+ if (topLevel is! DirectParserASTContentMetadataEnd) continue;
+ result.add(topLevel);
+ }
+ return result;
+ }
}
extension CompilationUnitExtension on DirectParserASTContentCompilationUnitEnd {
@@ -84,6 +441,78 @@
return result;
}
+ List<DirectParserASTContentTopLevelDeclarationEnd> getMixinDeclarations() {
+ List<DirectParserASTContentTopLevelDeclarationEnd> result = [];
+ for (DirectParserASTContent topLevel in children) {
+ if (!topLevel.isMixinDeclaration()) continue;
+ result.add(topLevel);
+ }
+ return result;
+ }
+
+ List<DirectParserASTContentImportEnd> getImports() {
+ List<DirectParserASTContentImportEnd> result = [];
+ for (DirectParserASTContent topLevel in children) {
+ if (!topLevel.isImport()) continue;
+ result.add(topLevel.children.last);
+ }
+ return result;
+ }
+
+ List<DirectParserASTContentExportEnd> getExports() {
+ List<DirectParserASTContentExportEnd> result = [];
+ for (DirectParserASTContent topLevel in children) {
+ if (!topLevel.isExport()) continue;
+ result.add(topLevel.children.last);
+ }
+ return result;
+ }
+
+ // List<DirectParserASTContentMetadataStarEnd> getMetadata() {
+ // List<DirectParserASTContentMetadataStarEnd> result = [];
+ // for (DirectParserASTContent topLevel in children) {
+ // if (!topLevel.isMetadata()) continue;
+ // result.add(topLevel);
+ // }
+ // return result;
+ // }
+
+ // List<DirectParserASTContentEnumEnd> getEnums() {
+ // List<DirectParserASTContentEnumEnd> result = [];
+ // for (DirectParserASTContent topLevel in children) {
+ // if (!topLevel.isEnum()) continue;
+ // result.add(topLevel.children.last);
+ // }
+ // return result;
+ // }
+
+ // List<DirectParserASTContentFunctionTypeAliasEnd> getTypedefs() {
+ // List<DirectParserASTContentFunctionTypeAliasEnd> result = [];
+ // for (DirectParserASTContent topLevel in children) {
+ // if (!topLevel.isTypedef()) continue;
+ // result.add(topLevel.children.last);
+ // }
+ // return result;
+ // }
+
+ // List<DirectParserASTContentMixinDeclarationEnd> getMixinDeclarations() {
+ // List<DirectParserASTContentMixinDeclarationEnd> result = [];
+ // for (DirectParserASTContent topLevel in children) {
+ // if (!topLevel.isMixinDeclaration()) continue;
+ // result.add(topLevel.children.last);
+ // }
+ // return result;
+ // }
+
+ // List<DirectParserASTContentTopLevelMethodEnd> getTopLevelMethods() {
+ // List<DirectParserASTContentTopLevelMethodEnd> result = [];
+ // for (DirectParserASTContent topLevel in children) {
+ // if (!topLevel.isTopLevelMethod()) continue;
+ // result.add(topLevel.children.last);
+ // }
+ // return result;
+ // }
+
DirectParserASTContentCompilationUnitBegin getBegin() {
return children.first;
}
@@ -91,10 +520,7 @@
extension TopLevelDeclarationExtension
on DirectParserASTContentTopLevelDeclarationEnd {
- DirectParserASTContentIdentifierHandle getClassIdentifier() {
- if (!isClass()) {
- throw "Not a class";
- }
+ DirectParserASTContentIdentifierHandle getIdentifier() {
for (DirectParserASTContent child in children) {
if (child is DirectParserASTContentIdentifierHandle) return child;
}
@@ -114,7 +540,18 @@
}
}
-extension ClassDeclaration on DirectParserASTContentClassDeclarationEnd {
+extension MixinDeclarationExtension
+ on DirectParserASTContentMixinDeclarationEnd {
+ DirectParserASTContentClassOrMixinBodyEnd getClassOrMixinBody() {
+ for (DirectParserASTContent child in children) {
+ if (child is DirectParserASTContentClassOrMixinBodyEnd) return child;
+ }
+ throw "Not found.";
+ }
+}
+
+extension ClassDeclarationExtension
+ on DirectParserASTContentClassDeclarationEnd {
DirectParserASTContentClassOrMixinBodyEnd getClassOrMixinBody() {
for (DirectParserASTContent child in children) {
if (child is DirectParserASTContentClassOrMixinBodyEnd) return child;
@@ -128,6 +565,24 @@
}
throw "Not found.";
}
+
+ DirectParserASTContentClassOrMixinImplementsHandle getClassImplements() {
+ for (DirectParserASTContent child in children) {
+ if (child is DirectParserASTContentClassOrMixinImplementsHandle) {
+ return child;
+ }
+ }
+ throw "Not found.";
+ }
+
+ DirectParserASTContentClassWithClauseHandle getClassWithClause() {
+ for (DirectParserASTContent child in children) {
+ if (child is DirectParserASTContentClassWithClauseHandle) {
+ return child;
+ }
+ }
+ return null;
+ }
}
extension ClassOrMixinBodyExtension
@@ -156,6 +611,18 @@
throw "Not found";
}
+ bool isClassFactoryMethod() {
+ DirectParserASTContent child = children[1];
+ if (child is DirectParserASTContentClassFactoryMethodEnd) return true;
+ return false;
+ }
+
+ DirectParserASTContentClassFactoryMethodEnd getClassFactoryMethod() {
+ DirectParserASTContent child = children[1];
+ if (child is DirectParserASTContentClassFactoryMethodEnd) return child;
+ throw "Not found";
+ }
+
bool isClassFields() {
DirectParserASTContent child = children[1];
if (child is DirectParserASTContentClassFieldsEnd) return true;
@@ -167,6 +634,72 @@
if (child is DirectParserASTContentClassFieldsEnd) return child;
throw "Not found";
}
+
+ bool isMixinFields() {
+ DirectParserASTContent child = children[1];
+ if (child is DirectParserASTContentMixinFieldsEnd) return true;
+ return false;
+ }
+
+ DirectParserASTContentMixinFieldsEnd getMixinFields() {
+ DirectParserASTContent child = children[1];
+ if (child is DirectParserASTContentMixinFieldsEnd) return child;
+ throw "Not found";
+ }
+
+ bool isMixinMethod() {
+ DirectParserASTContent child = children[1];
+ if (child is DirectParserASTContentMixinMethodEnd) return true;
+ return false;
+ }
+
+ DirectParserASTContentMixinMethodEnd getMixinMethod() {
+ DirectParserASTContent child = children[1];
+ if (child is DirectParserASTContentMixinMethodEnd) return child;
+ throw "Not found";
+ }
+
+ bool isMixinFactoryMethod() {
+ DirectParserASTContent child = children[1];
+ if (child is DirectParserASTContentMixinFactoryMethodEnd) return true;
+ return false;
+ }
+
+ DirectParserASTContentMixinFactoryMethodEnd getMixinFactoryMethod() {
+ DirectParserASTContent child = children[1];
+ if (child is DirectParserASTContentMixinFactoryMethodEnd) return child;
+ throw "Not found";
+ }
+
+ bool isMixinConstructor() {
+ DirectParserASTContent child = children[1];
+ if (child is DirectParserASTContentMixinConstructorEnd) return true;
+ return false;
+ }
+
+ DirectParserASTContentMixinConstructorEnd getMixinConstructor() {
+ DirectParserASTContent child = children[1];
+ if (child is DirectParserASTContentMixinConstructorEnd) return child;
+ throw "Not found";
+ }
+
+ bool isClassMethod() {
+ DirectParserASTContent child = children[1];
+ if (child is DirectParserASTContentClassMethodEnd) return true;
+ return false;
+ }
+
+ DirectParserASTContentClassMethodEnd getClassMethod() {
+ DirectParserASTContent child = children[1];
+ if (child is DirectParserASTContentClassMethodEnd) return child;
+ throw "Not found";
+ }
+
+ bool isClassRecoverableError() {
+ DirectParserASTContent child = children[1];
+ if (child is DirectParserASTContentRecoverableErrorHandle) return true;
+ return false;
+ }
}
extension ClassFieldsExtension on DirectParserASTContentClassFieldsEnd {
@@ -203,6 +736,17 @@
}
}
+extension ClassMethodExtension on DirectParserASTContentClassMethodEnd {
+ DirectParserASTContentBlockFunctionBodyEnd getBlockFunctionBody() {
+ for (DirectParserASTContent child in children) {
+ if (child is DirectParserASTContentBlockFunctionBodyEnd) {
+ return child;
+ }
+ }
+ return null;
+ }
+}
+
extension ClassConstructorExtension
on DirectParserASTContentClassConstructorEnd {
DirectParserASTContentFormalParametersEnd getFormalParameters() {
diff --git a/pkg/front_end/lib/src/testing/id_extractor.dart b/pkg/front_end/lib/src/testing/id_extractor.dart
index d63f675..f9fcbd3 100644
--- a/pkg/front_end/lib/src/testing/id_extractor.dart
+++ b/pkg/front_end/lib/src/testing/id_extractor.dart
@@ -4,6 +4,7 @@
import 'package:_fe_analyzer_shared/src/testing/id.dart';
import 'package:kernel/ast.dart';
+import '../api_prototype/lowering_predicates.dart';
/// Compute a canonical [Id] for kernel-based nodes.
Id computeMemberId(Member node) {
@@ -246,7 +247,12 @@
@override
visitFunctionDeclaration(FunctionDeclaration node) {
- computeForNode(node, computeDefaultNodeId(node));
+ computeForNode(
+ node,
+ computeDefaultNodeId(node,
+ // TODO(johnniwinther): Remove this when late lowered setter
+ // functions can have an offset.
+ skipNodeWithNoOffset: isLateLoweredLocalSetter(node.variable)));
super.visitFunctionDeclaration(node);
}
diff --git a/pkg/front_end/test/fasta/util/direct_parser_ast_test.dart b/pkg/front_end/test/fasta/util/direct_parser_ast_test.dart
new file mode 100644
index 0000000..4f2c82f
--- /dev/null
+++ b/pkg/front_end/test/fasta/util/direct_parser_ast_test.dart
@@ -0,0 +1,472 @@
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:front_end/src/fasta/util/direct_parser_ast.dart';
+import 'package:front_end/src/fasta/util/direct_parser_ast_helper.dart';
+
+Uri base;
+
+main(List<String> args) {
+ File script = new File.fromUri(Platform.script);
+ base = script.parent.uri;
+
+ testTopLevelStuff();
+ testClassStuff();
+ testMixinStuff();
+
+ if (!args.contains("--fast")) {
+ canParseTopLevelIshOfAllFrontendFiles();
+ }
+}
+
+void canParseTopLevelIshOfAllFrontendFiles() {
+ Directory directory = new Directory.fromUri(base.resolve("../../../"));
+ int processed = 0;
+ int errors = 0;
+ for (FileSystemEntity entry in directory.listSync(recursive: true)) {
+ if (entry is File) {
+ if (!entry.path.endsWith(".dart")) continue;
+ try {
+ processed++;
+ List<int> data = entry.readAsBytesSync();
+ DirectParserASTContentCompilationUnitEnd ast = getAST(data,
+ includeBody: true,
+ includeComments: true,
+ enableExtensionMethods: true,
+ enableNonNullable: false);
+ splitIntoChunks(ast, data);
+ for (DirectParserASTContent child in ast.children) {
+ if (child.isClass()) {
+ splitIntoChunks(child.asClass().getClassOrMixinBody(), data);
+ } else if (child.isMixinDeclaration()) {
+ splitIntoChunks(
+ child.asMixinDeclaration().getClassOrMixinBody(), data);
+ }
+ }
+ } catch (e, st) {
+ print("Failure on $entry:\n$e\n\n$st\n\n--------------\n\n");
+ errors++;
+ }
+ }
+ }
+ print("Processed $processed files in $directory. "
+ "Encountered $errors errors.");
+}
+
+void testTopLevelStuff() {
+ File file = new File.fromUri(
+ base.resolve("direct_parser_ast_test_data/top_level_stuff.txt"));
+ List<int> data = file.readAsBytesSync();
+ DirectParserASTContentCompilationUnitEnd ast = getAST(data,
+ includeBody: true,
+ includeComments: true,
+ enableExtensionMethods: true,
+ enableNonNullable: false);
+ expect(2, ast.getImports().length);
+ expect(2, ast.getExports().length);
+
+ List<String> foundChunks = splitIntoChunks(ast, data);
+ expect(22, foundChunks.length);
+ expect("library top_level_stuff;", foundChunks[0]);
+ expect('import "top_level_stuff_helper.dart";', foundChunks[1]);
+ expect('export "top_level_stuff_helper.dart";', foundChunks[2]);
+ expect(
+ 'import "top_level_stuff_helper.dart" show a, b, '
+ 'c hide d, e, f show foo;',
+ foundChunks[3]);
+ expect(
+ 'export "top_level_stuff_helper.dart" show a, b, '
+ 'c hide d, e, f show foo;',
+ foundChunks[4]);
+ expect("part 'top_level_stuff_helper.dart';", foundChunks[5]);
+ expect('@metadataOneOnThisOne("bla")\n', foundChunks[6]);
+ expect("@metadataTwoOnThisOne\n", foundChunks[7]);
+ expect("""void toplevelMethod() {
+ // no content
+}""", foundChunks[8]);
+ expect("""List<E> anotherTopLevelMethod<E>() {
+ return null;
+}""", foundChunks[9]);
+ expect("enum FooEnum { A, B, Bla }", foundChunks[10]);
+ expect("""class FooClass {
+ // no content.
+}""", foundChunks[11]);
+ expect("""mixin FooMixin {
+ // no content.
+}""", foundChunks[12]);
+ expect("""class A<T> {
+ // no content.
+}""", foundChunks[13]);
+ expect("typedef B = Function();", foundChunks[14]);
+ expect("""mixin C<T> on A<T> {
+ // no content.
+}""", foundChunks[15]);
+ expect("""extension D<T> on A<T> {
+ // no content.
+}""", foundChunks[16]);
+ expect("class E = A with FooClass;", foundChunks[17]);
+ expect("int field1;", foundChunks[18]);
+ expect("int field2, field3;", foundChunks[19]);
+ expect("int field4 = 42;", foundChunks[20]);
+ expect("@AnnotationAtEOF", foundChunks[21]);
+
+ file = new File.fromUri(
+ base.resolve("direct_parser_ast_test_data/top_level_stuff_helper.txt"));
+ data = file.readAsBytesSync();
+ ast = getAST(data,
+ includeBody: true,
+ includeComments: true,
+ enableExtensionMethods: true,
+ enableNonNullable: false);
+ foundChunks = splitIntoChunks(ast, data);
+ expect(1, foundChunks.length);
+ expect("part of 'top_level_stuff.txt';", foundChunks[0]);
+
+ file = new File.fromUri(
+ base.resolve("direct_parser_ast_test_data/script_handle.txt"));
+ data = file.readAsBytesSync();
+ ast = getAST(data,
+ includeBody: true,
+ includeComments: true,
+ enableExtensionMethods: true,
+ enableNonNullable: false);
+ foundChunks = splitIntoChunks(ast, data);
+ expect(1, foundChunks.length);
+ expect("#!/usr/bin/env dart -c", foundChunks[0]);
+}
+
+void testClassStuff() {
+ File file =
+ new File.fromUri(base.resolve("direct_parser_ast_test_data/class.txt"));
+ List<int> data = file.readAsBytesSync();
+ DirectParserASTContentCompilationUnitEnd ast = getAST(data,
+ includeBody: true,
+ includeComments: true,
+ enableExtensionMethods: true,
+ enableNonNullable: false);
+ List<DirectParserASTContentTopLevelDeclarationEnd> classes = ast.getClasses();
+ expect(2, classes.length);
+
+ DirectParserASTContentTopLevelDeclarationEnd decl = classes[0];
+ DirectParserASTContentClassDeclarationEnd cls = decl.asClass();
+ expect("Foo", decl.getIdentifier().token.lexeme);
+ DirectParserASTContentClassExtendsHandle extendsDecl = cls.getClassExtends();
+ expect("extends", extendsDecl.extendsKeyword?.lexeme);
+ DirectParserASTContentClassOrMixinImplementsHandle implementsDecl =
+ cls.getClassImplements();
+ expect("implements", implementsDecl.implementsKeyword?.lexeme);
+ DirectParserASTContentClassWithClauseHandle withClauseDecl =
+ cls.getClassWithClause();
+ expect(null, withClauseDecl);
+ List<DirectParserASTContentMemberEnd> members =
+ cls.getClassOrMixinBody().getMembers();
+ expect(5, members.length);
+ expect(members[0].isClassConstructor(), true);
+ expect(members[1].isClassFactoryMethod(), true);
+ expect(members[2].isClassMethod(), true);
+ expect(members[3].isClassMethod(), true);
+ expect(members[4].isClassFields(), true);
+
+ List<String> chunks = splitIntoChunks(cls.getClassOrMixinBody(), data);
+ expect(5, chunks.length);
+ expect("""Foo() {
+ // Constructor
+ }""", chunks[0]);
+ expect("factory Foo.factory() => Foo();", chunks[1]);
+ expect("""void method() {
+ // instance method.
+ }""", chunks[2]);
+ expect("""static void staticMethod() {
+ // static method.
+ }""", chunks[3]);
+ expect("int field1, field2 = 42;", chunks[4]);
+
+ chunks = processItem(
+ members[0].getClassConstructor().getBlockFunctionBody(), data);
+ expect(1, chunks.length);
+ expect("""{
+ // Constructor
+ }""", chunks[0]);
+ chunks =
+ processItem(members[2].getClassMethod().getBlockFunctionBody(), data);
+ expect(1, chunks.length);
+ expect("""{
+ // instance method.
+ }""", chunks[0]);
+ chunks =
+ processItem(members[3].getClassMethod().getBlockFunctionBody(), data);
+ expect(1, chunks.length);
+ expect("""{
+ // static method.
+ }""", chunks[0]);
+
+ // TODO: Move (something like) this into the check-all-files-thing.
+ for (DirectParserASTContentMemberEnd member
+ in cls.getClassOrMixinBody().getMembers()) {
+ if (member.isClassConstructor()) continue;
+ if (member.isClassFactoryMethod()) continue;
+ if (member.isClassFields()) continue;
+ if (member.isClassMethod()) continue;
+ throw "$member --- ${member.children}";
+ }
+
+ decl = classes[1];
+ cls = decl.asClass();
+ expect("Foo2", decl.getIdentifier().token.lexeme);
+ extendsDecl = cls.getClassExtends();
+ expect(null, extendsDecl.extendsKeyword?.lexeme);
+ implementsDecl = cls.getClassImplements();
+ expect(null, implementsDecl.implementsKeyword?.lexeme);
+ withClauseDecl = cls.getClassWithClause();
+ expect("with", withClauseDecl.withKeyword.lexeme);
+ members = cls.getClassOrMixinBody().getMembers();
+ expect(0, members.length);
+}
+
+void testMixinStuff() {
+ File file =
+ new File.fromUri(base.resolve("direct_parser_ast_test_data/mixin.txt"));
+ List<int> data = file.readAsBytesSync();
+ DirectParserASTContentCompilationUnitEnd ast = getAST(data,
+ includeBody: true,
+ includeComments: true,
+ enableExtensionMethods: true,
+ enableNonNullable: false);
+ List<DirectParserASTContentTopLevelDeclarationEnd> mixins =
+ ast.getMixinDeclarations();
+ expect(mixins.length, 1);
+
+ DirectParserASTContentTopLevelDeclarationEnd decl = mixins[0];
+ DirectParserASTContentMixinDeclarationEnd mxn = decl.asMixinDeclaration();
+ expect("B", decl.getIdentifier().token.lexeme);
+
+ List<DirectParserASTContentMemberEnd> members =
+ mxn.getClassOrMixinBody().getMembers();
+ expect(4, members.length);
+ expect(members[0].isMixinFields(), true);
+ expect(members[1].isMixinMethod(), true);
+ expect(members[2].isMixinFactoryMethod(), true);
+ expect(members[3].isMixinConstructor(), true);
+
+ List<String> chunks = splitIntoChunks(mxn.getClassOrMixinBody(), data);
+ expect(4, chunks.length);
+ expect("static int staticField = 0;", chunks[0]);
+ expect("""void foo() {
+ // empty
+ }""", chunks[1]);
+ expect("""factory B() {
+ // empty
+ }""", chunks[2]);
+ expect("""B.foo() {
+ // empty
+ }""", chunks[3]);
+}
+
+void expect<E>(E expect, E actual) {
+ if (expect != actual) throw "Expected '$expect' but got '$actual'";
+}
+
+List<String> splitIntoChunks(DirectParserASTContent ast, List<int> data) {
+ List<String> foundChunks = [];
+ for (DirectParserASTContent child in ast.children) {
+ foundChunks.addAll(processItem(child, data));
+ }
+ return foundChunks;
+}
+
+List<String> processItem(DirectParserASTContent item, List<int> data) {
+ if (item.isClass()) {
+ DirectParserASTContentClassDeclarationEnd cls = item.asClass();
+ return [
+ getCutContent(data, cls.beginToken.offset,
+ cls.endToken.offset + cls.endToken.length)
+ ];
+ } else if (item.isMetadata()) {
+ DirectParserASTContentMetadataStarEnd metadataStar = item.asMetadata();
+ List<DirectParserASTContentMetadataEnd> entries =
+ metadataStar.getMetadataEntries();
+ if (entries.isNotEmpty) {
+ List<String> chunks = [];
+ for (DirectParserASTContentMetadataEnd metadata in entries) {
+ chunks.add(getCutContent(
+ data, metadata.beginToken.offset, metadata.endToken.offset));
+ }
+ return chunks;
+ }
+ return const [];
+ } else if (item.isImport()) {
+ DirectParserASTContentImportEnd import = item.asImport();
+ return [
+ getCutContent(data, import.importKeyword.offset,
+ import.semicolon.offset + import.semicolon.length)
+ ];
+ } else if (item.isExport()) {
+ DirectParserASTContentExportEnd export = item.asExport();
+ return [
+ getCutContent(data, export.exportKeyword.offset,
+ export.semicolon.offset + export.semicolon.length)
+ ];
+ } else if (item.isLibraryName()) {
+ DirectParserASTContentLibraryNameEnd name = item.asLibraryName();
+ return [
+ getCutContent(data, name.libraryKeyword.offset,
+ name.semicolon.offset + name.semicolon.length)
+ ];
+ } else if (item.isPart()) {
+ DirectParserASTContentPartEnd part = item.asPart();
+ return [
+ getCutContent(data, part.partKeyword.offset,
+ part.semicolon.offset + part.semicolon.length)
+ ];
+ } else if (item.isPartOf()) {
+ DirectParserASTContentPartOfEnd partOf = item.asPartOf();
+ return [
+ getCutContent(data, partOf.partKeyword.offset,
+ partOf.semicolon.offset + partOf.semicolon.length)
+ ];
+ } else if (item.isTopLevelMethod()) {
+ DirectParserASTContentTopLevelMethodEnd method = item.asTopLevelMethod();
+ return [
+ getCutContent(data, method.beginToken.offset,
+ method.endToken.offset + method.endToken.length)
+ ];
+ } else if (item.isTopLevelFields()) {
+ DirectParserASTContentTopLevelFieldsEnd fields = item.asTopLevelFields();
+ return [
+ getCutContent(data, fields.beginToken.offset,
+ fields.endToken.offset + fields.endToken.length)
+ ];
+ } else if (item.isEnum()) {
+ DirectParserASTContentEnumEnd enm = item.asEnum();
+ return [
+ getCutContent(data, enm.enumKeyword.offset,
+ enm.leftBrace.endGroup.offset + enm.leftBrace.endGroup.length)
+ ];
+ } else if (item.isMixinDeclaration()) {
+ DirectParserASTContentMixinDeclarationEnd mixinDecl =
+ item.asMixinDeclaration();
+ return [
+ getCutContent(data, mixinDecl.mixinKeyword.offset,
+ mixinDecl.endToken.offset + mixinDecl.endToken.length)
+ ];
+ } else if (item.isNamedMixinDeclaration()) {
+ DirectParserASTContentNamedMixinApplicationEnd namedMixinDecl =
+ item.asNamedMixinDeclaration();
+ return [
+ getCutContent(data, namedMixinDecl.begin.offset,
+ namedMixinDecl.endToken.offset + namedMixinDecl.endToken.length)
+ ];
+ } else if (item.isTypedef()) {
+ DirectParserASTContentFunctionTypeAliasEnd typedefDecl = item.asTypedef();
+ return [
+ getCutContent(data, typedefDecl.typedefKeyword.offset,
+ typedefDecl.endToken.offset + typedefDecl.endToken.length)
+ ];
+ } else if (item.isExtension()) {
+ DirectParserASTContentExtensionDeclarationEnd extensionDecl =
+ item.asExtension();
+ return [
+ getCutContent(data, extensionDecl.extensionKeyword.offset,
+ extensionDecl.endToken.offset + extensionDecl.endToken.length)
+ ];
+ } else if (item.isScript()) {
+ DirectParserASTContentScriptHandle script = item.asScript();
+ return [
+ getCutContent(
+ data, script.token.offset, script.token.offset + script.token.length)
+ ];
+ } else if (item is DirectParserASTContentMemberEnd) {
+ if (item.isClassConstructor()) {
+ DirectParserASTContentClassConstructorEnd decl =
+ item.getClassConstructor();
+ return [
+ getCutContent(data, decl.beginToken.offset,
+ decl.endToken.offset + decl.endToken.length)
+ ];
+ } else if (item.isClassFactoryMethod()) {
+ DirectParserASTContentClassFactoryMethodEnd decl =
+ item.getClassFactoryMethod();
+ return [
+ getCutContent(data, decl.beginToken.offset,
+ decl.endToken.offset + decl.endToken.length)
+ ];
+ } else if (item.isClassMethod()) {
+ DirectParserASTContentClassMethodEnd decl = item.getClassMethod();
+ return [
+ getCutContent(data, decl.beginToken.offset,
+ decl.endToken.offset + decl.endToken.length)
+ ];
+ } else if (item.isClassFields()) {
+ DirectParserASTContentClassFieldsEnd decl = item.getClassFields();
+ return [
+ getCutContent(data, decl.beginToken.offset,
+ decl.endToken.offset + decl.endToken.length)
+ ];
+ } else if (item.isClassFields()) {
+ DirectParserASTContentClassFieldsEnd decl = item.getClassFields();
+ return [
+ getCutContent(data, decl.beginToken.offset,
+ decl.endToken.offset + decl.endToken.length)
+ ];
+ } else if (item.isMixinFields()) {
+ DirectParserASTContentMixinFieldsEnd decl = item.getMixinFields();
+ return [
+ getCutContent(data, decl.beginToken.offset,
+ decl.endToken.offset + decl.endToken.length)
+ ];
+ } else if (item.isMixinMethod()) {
+ DirectParserASTContentMixinMethodEnd decl = item.getMixinMethod();
+ return [
+ getCutContent(data, decl.beginToken.offset,
+ decl.endToken.offset + decl.endToken.length)
+ ];
+ } else if (item.isMixinFactoryMethod()) {
+ DirectParserASTContentMixinFactoryMethodEnd decl =
+ item.getMixinFactoryMethod();
+ return [
+ getCutContent(data, decl.beginToken.offset,
+ decl.endToken.offset + decl.endToken.length)
+ ];
+ } else if (item.isMixinConstructor()) {
+ DirectParserASTContentMixinConstructorEnd decl =
+ item.getMixinConstructor();
+ return [
+ getCutContent(data, decl.beginToken.offset,
+ decl.endToken.offset + decl.endToken.length)
+ ];
+ } else {
+ if (item.type == DirectParserASTType.BEGIN) return const [];
+ if (item.type == DirectParserASTType.HANDLE) return const [];
+ if (item.isClassRecoverableError()) return const [];
+ if (item.isRecoverableError()) return const [];
+ if (item.isRecoverImport()) return const [];
+ throw "Unknown: $item --- ${item.children}";
+ }
+ } else if (item.isFunctionBody()) {
+ DirectParserASTContentBlockFunctionBodyEnd decl = item.asFunctionBody();
+ return [
+ getCutContent(data, decl.beginToken.offset,
+ decl.endToken.offset + decl.endToken.length)
+ ];
+ } else {
+ if (item.type == DirectParserASTType.BEGIN) return const [];
+ if (item.type == DirectParserASTType.HANDLE) return const [];
+ if (item.isInvalidTopLevelDeclaration()) return const [];
+ if (item.isRecoverableError()) return const [];
+ if (item.isRecoverImport()) return const [];
+
+ throw "Unknown: $item --- ${item.children}";
+ }
+}
+
+List<int> _contentCache;
+String _contentCacheString;
+String getCutContent(List<int> content, int from, int to) {
+ if (identical(content, _contentCache)) {
+ // cache up to date.
+ } else {
+ _contentCache = content;
+ _contentCacheString = utf8.decode(content);
+ }
+ return _contentCacheString.substring(from, to);
+}
diff --git a/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/class.txt b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/class.txt
new file mode 100644
index 0000000..a6784da
--- /dev/null
+++ b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/class.txt
@@ -0,0 +1,21 @@
+class Foo extends Bar implements Baz {
+ Foo() {
+ // Constructor
+ }
+
+ factory Foo.factory() => Foo();
+
+ void method() {
+ // instance method.
+ }
+
+ static void staticMethod() {
+ // static method.
+ }
+
+ int field1, field2 = 42;
+}
+
+class Foo2 with Bar2 {
+ // empty
+}
\ No newline at end of file
diff --git a/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/mixin.txt b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/mixin.txt
new file mode 100644
index 0000000..031ace0
--- /dev/null
+++ b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/mixin.txt
@@ -0,0 +1,15 @@
+mixin B {
+ static int staticField = 0;
+ void foo() {
+ // empty
+ }
+
+ // Mixins cannot have constructors (or members with same name as mixin).
+ factory B() {
+ // empty
+ }
+
+ B.foo() {
+ // empty
+ }
+}
\ No newline at end of file
diff --git a/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/script_handle.txt b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/script_handle.txt
new file mode 100644
index 0000000..8e731aa
--- /dev/null
+++ b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/script_handle.txt
@@ -0,0 +1 @@
+#!/usr/bin/env dart -c
diff --git a/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/top_level_stuff.txt b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/top_level_stuff.txt
new file mode 100644
index 0000000..3cd024b
--- /dev/null
+++ b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/top_level_stuff.txt
@@ -0,0 +1,53 @@
+// Top level comment of sorts. With utf8 stuff → in it so offsets aren't byte
+// offset!
+
+library top_level_stuff;
+
+import "top_level_stuff_helper.dart";
+export "top_level_stuff_helper.dart";
+import "top_level_stuff_helper.dart" show a, b, c hide d, e, f show foo;
+export "top_level_stuff_helper.dart" show a, b, c hide d, e, f show foo;
+
+part 'top_level_stuff_helper.dart';
+
+@metadataOneOnThisOne("bla")
+@metadataTwoOnThisOne
+void toplevelMethod() {
+ // no content
+}
+
+List<E> anotherTopLevelMethod<E>() {
+ return null;
+}
+
+enum FooEnum { A, B, Bla }
+
+class FooClass {
+ // no content.
+}
+
+mixin FooMixin {
+ // no content.
+}
+
+class A<T> {
+ // no content.
+}
+
+typedef B = Function();
+
+mixin C<T> on A<T> {
+ // no content.
+}
+
+extension D<T> on A<T> {
+ // no content.
+}
+
+class E = A with FooClass;
+
+int field1;
+int field2, field3;
+int field4 = 42;
+
+@AnnotationAtEOF
\ No newline at end of file
diff --git a/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/top_level_stuff_helper.txt b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/top_level_stuff_helper.txt
new file mode 100644
index 0000000..b2c46c8
--- /dev/null
+++ b/pkg/front_end/test/fasta/util/direct_parser_ast_test_data/top_level_stuff_helper.txt
@@ -0,0 +1 @@
+part of 'top_level_stuff.txt';
\ No newline at end of file
diff --git a/pkg/front_end/test/predicates/data/late.dart b/pkg/front_end/test/predicates/data/late.dart
index 3218974..ebf80a8 100644
--- a/pkg/front_end/test/predicates/data/late.dart
+++ b/pkg/front_end/test/predicates/data/late.dart
@@ -120,3 +120,54 @@
/*member: Class.finalStaticNullableWithInitializer:lateFieldGetter*/
static late final int? finalStaticNullableWithInitializer = 0;
}
+
+method() {
+ late int /*
+ lateIsSetLocal,
+ lateLocalGetter,
+ lateLocalSetter
+ */
+ localNonNullableWithoutInitializer;
+ late final int
+ /*
+ lateIsSetLocal,
+ lateLocalGetter,
+ lateLocalSetter
+ */
+ finalLocalNonNullableWithoutInitializer;
+ late int? /*
+ lateIsSetLocal,
+ lateLocalGetter,
+ lateLocalSetter
+ */
+ localNullableWithoutInitializer;
+ late final int?
+ /*
+ lateIsSetLocal,
+ lateLocalGetter,
+ lateLocalSetter
+ */
+ finalLocalNullableWithoutInitializer;
+ late int /*
+ lateIsSetLocal,
+ lateLocalGetter,
+ lateLocalSetter
+ */
+ localNonNullableWithInitializer = 0;
+ late final int /*
+ lateIsSetLocal,
+ lateLocalGetter
+ */
+ finalLocalNonNullableWithInitializer = 0;
+ late int? /*
+ lateIsSetLocal,
+ lateLocalGetter,
+ lateLocalSetter
+ */
+ localNullableWithInitializer = 0;
+ late final int? /*
+ lateIsSetLocal,
+ lateLocalGetter
+ */
+ finalLocalNullableWithInitializer = 0;
+}
diff --git a/pkg/front_end/test/predicates/predicate_test.dart b/pkg/front_end/test/predicates/predicate_test.dart
index d2143dd..2f45e4e 100644
--- a/pkg/front_end/test/predicates/predicate_test.dart
+++ b/pkg/front_end/test/predicates/predicate_test.dart
@@ -9,6 +9,7 @@
import 'package:_fe_analyzer_shared/src/testing/id_testing.dart';
import 'package:_fe_analyzer_shared/src/testing/features.dart';
import 'package:front_end/src/api_prototype/experimental_flags.dart';
+import 'package:front_end/src/testing/id_extractor.dart';
import 'package:front_end/src/testing/id_testing_helper.dart';
import 'package:front_end/src/api_prototype/lowering_predicates.dart';
import 'package:kernel/ast.dart';
@@ -74,6 +75,9 @@
}
class PredicateDataExtractor extends CfeDataExtractor<Features> {
+ Map<String, Features> featureMap = {};
+ Map<String, NodeId> nodeIdMap = {};
+
PredicateDataExtractor(InternalCompilerResult compilerResult,
Map<Id, ActualData<Features>> actualMap)
: super(compilerResult, actualMap);
@@ -107,4 +111,45 @@
}
return null;
}
+
+ void visitProcedure(Procedure node) {
+ super.visitProcedure(node);
+ nodeIdMap.forEach((String name, NodeId id) {
+ Features features = featureMap[name];
+ if (features != null) {
+ TreeNode nodeWithOffset = computeTreeNodeWithOffset(node);
+ registerValue(
+ nodeWithOffset.location.file, id.value, id, features, name);
+ }
+ });
+ nodeIdMap.clear();
+ featureMap.clear();
+ }
+
+ void visitVariableDeclaration(VariableDeclaration node) {
+ String name;
+ String tag;
+ if (isLateLoweredIsSetLocal(node)) {
+ name = extractLocalNameFromLateLoweredIsSet(node.name);
+ tag = Tags.lateIsSetLocal;
+ } else if (isLateLoweredLocalGetter(node)) {
+ name = extractLocalNameFromLateLoweredGetter(node.name);
+ tag = Tags.lateLocalGetter;
+ } else if (isLateLoweredLocalSetter(node)) {
+ name = extractLocalNameFromLateLoweredSetter(node.name);
+ tag = Tags.lateLocalSetter;
+ } else if (node.name != null) {
+ name = node.name;
+ }
+ if (name != null) {
+ if (node.fileOffset != TreeNode.noOffset) {
+ nodeIdMap[name] ??= new NodeId(node.fileOffset, IdKind.node);
+ }
+ if (tag != null) {
+ Features features = featureMap[name] ??= new Features();
+ features.add(tag);
+ }
+ }
+ super.visitVariableDeclaration(node);
+ }
}
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index d9ac336..d67f2a8 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -223,6 +223,7 @@
edits
elapse
ell
+enm
entrypoint
entrypoints
eoo
@@ -372,6 +373,7 @@
invocation7d
invocation7e
ioo
+ish
isolate
isolates
issue41210b
@@ -461,6 +463,7 @@
moo
mul
mx
+mxn
mysdk
naively
naturally
diff --git a/pkg/front_end/tool/kernel_ast_file_rewriter.dart b/pkg/front_end/tool/kernel_ast_file_rewriter.dart
index 35c5daa..bdefeae 100644
--- a/pkg/front_end/tool/kernel_ast_file_rewriter.dart
+++ b/pkg/front_end/tool/kernel_ast_file_rewriter.dart
@@ -22,8 +22,7 @@
getAST(bytes, includeBody: true, includeComments: true);
Map<String, DirectParserASTContentTopLevelDeclarationEnd> classes = {};
for (DirectParserASTContentTopLevelDeclarationEnd cls in ast.getClasses()) {
- DirectParserASTContentIdentifierHandle identifier =
- cls.getClassIdentifier();
+ DirectParserASTContentIdentifierHandle identifier = cls.getIdentifier();
assert(classes[identifier.token] == null);
classes[identifier.token.toString()] = cls;
}
diff --git a/pkg/native_stack_traces/bin/decode.dart b/pkg/native_stack_traces/bin/decode.dart
index 9a7aee0..4ced1ca 100644
--- a/pkg/native_stack_traces/bin/decode.dart
+++ b/pkg/native_stack_traces/bin/decode.dart
@@ -300,12 +300,12 @@
if (options['help']) return print(_usages[options.command?.name]);
if (options.command == null) return errorWithUsage('no command provided');
- switch (options.command.name) {
+ switch (options.command!.name) {
case 'help':
- return help(options.command);
+ return help(options.command!);
case 'find':
- return find(options.command);
+ return find(options.command!);
case 'translate':
- return await translate(options.command);
+ return await translate(options.command!);
}
}
diff --git a/pkg/nnbd_migration/lib/src/edge_builder.dart b/pkg/nnbd_migration/lib/src/edge_builder.dart
index 7003df0..b348db7 100644
--- a/pkg/nnbd_migration/lib/src/edge_builder.dart
+++ b/pkg/nnbd_migration/lib/src/edge_builder.dart
@@ -2659,21 +2659,23 @@
node is Statement ? node : null, parts.condition);
} else if (parts is ForEachParts) {
Element lhsElement;
+ DecoratedType lhsType;
if (parts is ForEachPartsWithDeclaration) {
var variableElement = parts.loopVariable.declaredElement;
_flowAnalysis.declare(variableElement, true);
lhsElement = variableElement;
_dispatch(parts.loopVariable?.type);
+ lhsType = _variables.decoratedElementType(lhsElement);
} else if (parts is ForEachPartsWithIdentifier) {
lhsElement = parts.identifier.staticElement;
+ lhsType = _dispatch(parts.identifier);
} else {
throw StateError(
'Unexpected ForEachParts subtype: ${parts.runtimeType}');
}
var iterableType = _checkExpressionNotNull(parts.iterable);
DecoratedType elementType;
- if (lhsElement != null) {
- DecoratedType lhsType = _variables.decoratedElementType(lhsElement);
+ if (lhsType != null) {
var iterableTypeType = iterableType.type;
if (_typeSystem.isSubtypeOf(
iterableTypeType, typeProvider.iterableDynamicType)) {
diff --git a/pkg/nnbd_migration/lib/src/fix_builder.dart b/pkg/nnbd_migration/lib/src/fix_builder.dart
index ae77229..1d4748f 100644
--- a/pkg/nnbd_migration/lib/src/fix_builder.dart
+++ b/pkg/nnbd_migration/lib/src/fix_builder.dart
@@ -464,6 +464,15 @@
// correct post-migration type.
return variable.typeInternal;
}
+ if (variable is ParameterElement) {
+ var enclosingElement = variable.enclosingElement;
+ if (enclosingElement is PropertyAccessorElement &&
+ enclosingElement.isSynthetic) {
+ // This is the parameter of a synthetic getter, so it has the same
+ // type as the corresponding variable.
+ return _fixBuilder._computeMigratedType(enclosingElement.variable);
+ }
+ }
return _fixBuilder._computeMigratedType(variable);
});
diff --git a/pkg/nnbd_migration/lib/src/front_end/navigation_tree_renderer.dart b/pkg/nnbd_migration/lib/src/front_end/navigation_tree_renderer.dart
index eac183f..290f96e 100644
--- a/pkg/nnbd_migration/lib/src/front_end/navigation_tree_renderer.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/navigation_tree_renderer.dart
@@ -56,7 +56,8 @@
for (var entry in linksGroupedByDirectory.entries)
NavigationTreeDirectoryNode(
name: entry.key,
- path: pathContext.joinAll(entry.value.first.pathParts),
+ path: pathContext
+ .dirname(pathContext.joinAll(entry.value.first.pathParts)),
subtree: _renderNavigationSubtree(entry.value, depth + 1),
)..setSubtreeParents(),
for (var link in links.where((link) => link.depth == depth))
diff --git a/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart b/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart
index 136711e..6ec0a2e 100644
--- a/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart
@@ -510,7 +510,7 @@
void reportException(
Source source, AstNode node, Object exception, StackTrace stackTrace) {
listener.client.onException('''
-$exception
+$exception at offset ${node.offset} in $source ($node)
$stackTrace''');
}
diff --git a/pkg/nnbd_migration/lib/src/front_end/resources/index.html b/pkg/nnbd_migration/lib/src/front_end/resources/index.html
index c30f9ae..f56877d 100644
--- a/pkg/nnbd_migration/lib/src/front_end/resources/index.html
+++ b/pkg/nnbd_migration/lib/src/front_end/resources/index.html
@@ -25,7 +25,6 @@
<h1>Dart</h1>
<h2 class="before-apply">Proposed null safety changes</h2>
<h2 class="after-apply">✓ Null safety migration applied</h2>
- <h3 id="unit-name"> </h3>
<a target="_blank"
href="https://goo.gle/dart-null-safety-migration-tool">
<button class="action-button">
@@ -63,16 +62,26 @@
<div class="nav-tree"></div>
</div><!-- /nav-inner -->
</div><!-- /nav -->
- <div class="content">
- <div class="regions">
- <!-- The regions overlay code copy of the content to provide -->
- <!-- tooltips for modified regions. -->
- </div><!-- /regions -->
- <div class="code">
- <!-- Compilation unit content is written here. -->
- <p class="welcome">
- Select a source file on the left to preview the proposed edits.
- </p>
+ <div class="file">
+ <div class="title-bar">
+ <h3 id="unit-name"> </h3>
+ <span id="migrate-unit-status-icon-label">Migrate
+ <span
+ class="material-icons status-icon migrating"
+ id="migrate-unit-status-icon">check_box</span>
+ </span>
+ </div>
+ <div class="content">
+ <div class="regions">
+ <!-- The regions overlay code copy of the content to provide -->
+ <!-- tooltips for modified regions. -->
+ </div><!-- /regions -->
+ <div class="code">
+ <!-- Compilation unit content is written here. -->
+ <p class="welcome">
+ Select a source file on the left to preview the proposed edits.
+ </p>
+ </div>
</div>
</div><!-- /content -->
<div class="info-panel">
diff --git a/pkg/nnbd_migration/lib/src/front_end/resources/migration.css b/pkg/nnbd_migration/lib/src/front_end/resources/migration.css
index 556103b..257cfef 100644
--- a/pkg/nnbd_migration/lib/src/front_end/resources/migration.css
+++ b/pkg/nnbd_migration/lib/src/front_end/resources/migration.css
@@ -93,8 +93,7 @@
}
header h1,
-header h2,
-header h3 {
+header h2 {
display: inline-block;
font-family: "Google Sans","Roboto",sans-serif;
font-weight: 400;
@@ -113,13 +112,6 @@
top: -2px;
}
-header h3 {
- /* Shift text up */
- position: relative;
- top: -2px;
-}
-
-
header .action-button, header a {
right: 0px;
float: right;
@@ -222,23 +214,23 @@
color: #676767; /* $secondary-color */
}
-.nav-tree .status-icon.already-migrated {
+.status-icon.already-migrated {
color: #007a27; /* $light-green */
}
-.nav-tree .status-icon.opted-out {
+.status-icon.opted-out {
color: #676767; /* $secondary-color */
}
-.nav-tree .status-icon.opted-out:hover {
+.status-icon.opted-out:hover {
color: #ffffff;
}
-.nav-tree .status-icon.migrating {
+.status-icon.migrating {
color: #51c686; /* $dark-green */
}
-.nav-tree .status-icon.migrating:hover {
+.status-icon.migrating:hover {
color: #ffffff;
}
@@ -300,14 +292,41 @@
line-height: 1em;
}
-.content {
+.file {
flex: 4 300px;
+ font-family: "Google Sans","Roboto",sans-serif;
background: #12202f;
- font-family: "Roboto Mono", monospace;
- margin: 0 6px;
+ margin: 6px;
+ overflow: scroll;
+}
+
+.title-bar h3 {
+ display: inline-block;
+ font-weight: 400;
+ /* This aligns the title text with the content text, accounting for the width
+ * of the line numbers.
+ */
+ margin: 0.5em 24px 0.5em 63px;
+}
+
+.title-bar #migrate-unit-status-icon-label {
+ display: none;
+ user-select: none;
+}
+
+.title-bar #migrate-unit-status-icon-label.visible {
+ /* Change to 'inline' to enable the incremental migration feature. */
+ display: none;
+}
+
+.title-bar #migrate-unit-status-icon {
+ vertical-align: text-bottom;
+}
+
+.content {
+ font-family: "Roboto Mono",monospace;
position: relative;
white-space: pre;
- overflow: scroll;
}
.code {
@@ -659,7 +678,7 @@
* Adjustments to align material icons in the toolbar buttons.
*/
.action-button > span {
- position:relative;
+ position: relative;
top: -3px;
}
diff --git a/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart b/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart
index 6088d7e..b03dfe6 100644
--- a/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart
@@ -7422,7 +7422,7 @@
''';
String _index_html;
-// index_html md5 is 'f17972e91adf7afeeed745126e359ffb'
+// index_html md5 is '4dc4d54418f267d0f9189690626e0f2a'
String _index_html_base64 = '''
PGh0bWw+CjxoZWFkPgogICAgPHRpdGxlPk51bGwgU2FmZXR5IFByZXZpZXc8L3RpdGxlPgogICAgPHNj
cmlwdCBzcmM9Int7IGhpZ2hsaWdodEpzUGF0aCB9fSI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0Pnt7IGRh
@@ -7443,51 +7443,57 @@
YWx0PSJEYXJ0UGFkIExvZ28iIGNsYXNzPSJsb2dvIi8+CiAgICA8aDE+RGFydDwvaDE+CiAgICA8aDIg
Y2xhc3M9ImJlZm9yZS1hcHBseSI+UHJvcG9zZWQgbnVsbCBzYWZldHkgY2hhbmdlczwvaDI+CiAgICA8
aDIgY2xhc3M9ImFmdGVyLWFwcGx5Ij4mIzEwMDAzOyBOdWxsIHNhZmV0eSBtaWdyYXRpb24gYXBwbGll
-ZDwvaDI+CiAgICA8aDMgaWQ9InVuaXQtbmFtZSI+Jm5ic3A7PC9oMz4KICAgIDxhIHRhcmdldD0iX2Js
-YW5rIgogICAgICAgaHJlZj0iaHR0cHM6Ly9nb28uZ2xlL2RhcnQtbnVsbC1zYWZldHktbWlncmF0aW9u
-LXRvb2wiPgogICAgICA8YnV0dG9uIGNsYXNzPSJhY3Rpb24tYnV0dG9uIj4KICAgICAgICA8aSBjbGFz
-cz0ibWF0ZXJpYWwtaWNvbnMiPmxhdW5jaDwvaT4KICAgICAgICA8c3Bhbj5IZWxwPC9zcGFuPgogICAg
-ICA8L2J1dHRvbj4KICAgIDwvYT4KICAgIDxidXR0b24gY2xhc3M9ImFjdGlvbi1idXR0b24gYXBwbHkt
-bWlncmF0aW9uIj4KICAgICAgICA8aSBjbGFzcz0ibWF0ZXJpYWwtaWNvbnMiPmVkaXQ8L2k+CiAgICAg
-ICAgPHNwYW4gY2xhc3M9ImxhYmVsIj4KICAgICAgICAgIEFwcGx5IE1pZ3JhdGlvbgogICAgICAgIDwv
-c3Bhbj4KICAgIDwvYnV0dG9uPgogICAgPGJ1dHRvbiBjbGFzcz0iYWN0aW9uLWJ1dHRvbiBhcHBseS1t
-aWdyYXRpb24iIGRpc2FibGVkPgogICAgICAgIDxpIGNsYXNzPSJtYXRlcmlhbC1pY29ucyI+ZWRpdDwv
-aT4KICAgICAgICA8c3BhbiBjbGFzcz0ibGFiZWwiPgogICAgICAgICAgQXBwbHkgTWlncmF0aW9uCiAg
-ICAgICAgPC9zcGFuPgogICAgPC9idXR0b24+CiAgICA8YnV0dG9uIGNsYXNzPSJhY3Rpb24tYnV0dG9u
-IHJlcnVuLW1pZ3JhdGlvbiBiZWZvcmUtYXBwbHkiPgogICAgICA8c3BhbiBjbGFzcz0ib3B0aW9uYWwi
-PgogICAgICAgIDxpIGNsYXNzPSJtYXRlcmlhbC1pY29ucyI+cmVwbGF5PC9pPgogICAgICAgIFJlcnVu
-IEZyb20gU291cmNlcwogICAgICA8L3NwYW4+CiAgICAgIDxzcGFuIGNsYXNzPSJyZXF1aXJlZCI+CiAg
-ICAgICAgPGkgY2xhc3M9Im1hdGVyaWFsLWljb25zIj53YXJuaW5nPC9pPgogICAgICAgIFJlcnVuIFdp
-dGggQ2hhbmdlcwogICAgICA8L3NwYW4+CiAgICA8L2J1dHRvbj4KPC9oZWFkZXI+CjxkaXYgY2xhc3M9
-InBhbmVscyBob3Jpem9udGFsIj4KICAgIDxkaXYgY2xhc3M9Im5hdi1wYW5lbCI+CiAgICAgICAgPGRp
-diBjbGFzcz0ibmF2LWlubmVyIj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0icGFuZWwtaGVhZGluZyI+
-UHJvamVjdCBGaWxlczwvZGl2PgogICAgICAgICAgICA8ZGl2IGNsYXNzPSJuYXYtdHJlZSI+PC9kaXY+
-CiAgICAgICAgPC9kaXY+PCEtLSAvbmF2LWlubmVyIC0tPgogICAgPC9kaXY+PCEtLSAvbmF2IC0tPgog
-ICAgPGRpdiBjbGFzcz0iY29udGVudCI+CiAgICAgICAgPGRpdiBjbGFzcz0icmVnaW9ucyI+CiAgICAg
-ICAgICAgIDwhLS0gVGhlIHJlZ2lvbnMgb3ZlcmxheSBjb2RlIGNvcHkgb2YgdGhlIGNvbnRlbnQgdG8g
-cHJvdmlkZSAtLT4KICAgICAgICAgICAgPCEtLSB0b29sdGlwcyBmb3IgbW9kaWZpZWQgcmVnaW9ucy4g
-LS0+CiAgICAgICAgPC9kaXY+PCEtLSAvcmVnaW9ucyAtLT4KICAgICAgICA8ZGl2IGNsYXNzPSJjb2Rl
-Ij4KICAgICAgICAgICAgPCEtLSBDb21waWxhdGlvbiB1bml0IGNvbnRlbnQgaXMgd3JpdHRlbiBoZXJl
-LiAtLT4KICAgICAgICAgICAgPHAgY2xhc3M9IndlbGNvbWUiPgogICAgICAgICAgICAgICAgU2VsZWN0
-IGEgc291cmNlIGZpbGUgb24gdGhlIGxlZnQgdG8gcHJldmlldyB0aGUgcHJvcG9zZWQgZWRpdHMuCiAg
-ICAgICAgICAgIDwvcD4KICAgICAgICA8L2Rpdj4KICAgIDwvZGl2PjwhLS0gL2NvbnRlbnQgLS0+CiAg
-ICA8ZGl2IGNsYXNzPSJpbmZvLXBhbmVsIj4KICAgICAgICA8ZGl2IGNsYXNzPSJlZGl0LWxpc3QiPgog
-ICAgICAgICAgICA8ZGl2IGNsYXNzPSJwYW5lbC1oZWFkaW5nIj5Qcm9wb3NlZCBFZGl0czwvZGl2Pgog
-ICAgICAgICAgICA8ZGl2IGNsYXNzPSJwYW5lbC1jb250ZW50Ij48L2Rpdj4KICAgICAgICA8L2Rpdj48
-IS0tIC9lZGl0LWxpc3QgLS0+CiAgICAgICAgPGRpdiBjbGFzcz0iZWRpdC1wYW5lbCI+CiAgICAgICAg
-ICAgIDxkaXYgY2xhc3M9InBhbmVsLWhlYWRpbmciPkVkaXQgRGV0YWlsczwvZGl2PgogICAgICAgICAg
-ICA8ZGl2IGNsYXNzPSJwYW5lbC1jb250ZW50Ij4KICAgICAgICAgICAgICAgIDxwIGNsYXNzPSJwbGFj
-ZWhvbGRlciI+U2VlIGRldGFpbHMgYWJvdXQgYSBwcm9wb3NlZCBlZGl0LjwvcD4KICAgICAgICAgICAg
-PC9kaXY+PCEtLSAvcGFuZWwtY29udGVudCAtLT4KICAgICAgICA8L2Rpdj48IS0tIC9lZGl0LXBhbmVs
-IC0tPgogICAgPC9kaXY+PCEtLSAvaW5mby1wYW5lbCAtLT4KPC9kaXY+PCEtLSAvcGFuZWxzIC0tPgo8
-Zm9vdGVyPgogIDxidXR0b24gY2xhc3M9InJlcG9ydC1wcm9ibGVtIj5TZW5kIEZlZWRiYWNrPC9idXR0
-b24+CiAgICA8c3BhbiBjbGFzcz0id2lkZSI+IDwvc3Bhbj4KICAgIDxkaXYgY2xhc3M9InNkay12ZXJz
-aW9uIj5CYXNlZCBvbiA8c3BhbiBpZD0ic2RrLXZlcnNpb24iPnt7IHNka1ZlcnNpb24gfX08L3NwYW4+
-PC9kaXY+CjwvZm9vdGVyPgo8L2JvZHk+CjwvaHRtbD4K
+ZDwvaDI+CiAgICA8YSB0YXJnZXQ9Il9ibGFuayIKICAgICAgIGhyZWY9Imh0dHBzOi8vZ29vLmdsZS9k
+YXJ0LW51bGwtc2FmZXR5LW1pZ3JhdGlvbi10b29sIj4KICAgICAgPGJ1dHRvbiBjbGFzcz0iYWN0aW9u
+LWJ1dHRvbiI+CiAgICAgICAgPGkgY2xhc3M9Im1hdGVyaWFsLWljb25zIj5sYXVuY2g8L2k+CiAgICAg
+ICAgPHNwYW4+SGVscDwvc3Bhbj4KICAgICAgPC9idXR0b24+CiAgICA8L2E+CiAgICA8YnV0dG9uIGNs
+YXNzPSJhY3Rpb24tYnV0dG9uIGFwcGx5LW1pZ3JhdGlvbiI+CiAgICAgICAgPGkgY2xhc3M9Im1hdGVy
+aWFsLWljb25zIj5lZGl0PC9pPgogICAgICAgIDxzcGFuIGNsYXNzPSJsYWJlbCI+CiAgICAgICAgICBB
+cHBseSBNaWdyYXRpb24KICAgICAgICA8L3NwYW4+CiAgICA8L2J1dHRvbj4KICAgIDxidXR0b24gY2xh
+c3M9ImFjdGlvbi1idXR0b24gYXBwbHktbWlncmF0aW9uIiBkaXNhYmxlZD4KICAgICAgICA8aSBjbGFz
+cz0ibWF0ZXJpYWwtaWNvbnMiPmVkaXQ8L2k+CiAgICAgICAgPHNwYW4gY2xhc3M9ImxhYmVsIj4KICAg
+ICAgICAgIEFwcGx5IE1pZ3JhdGlvbgogICAgICAgIDwvc3Bhbj4KICAgIDwvYnV0dG9uPgogICAgPGJ1
+dHRvbiBjbGFzcz0iYWN0aW9uLWJ1dHRvbiByZXJ1bi1taWdyYXRpb24gYmVmb3JlLWFwcGx5Ij4KICAg
+ICAgPHNwYW4gY2xhc3M9Im9wdGlvbmFsIj4KICAgICAgICA8aSBjbGFzcz0ibWF0ZXJpYWwtaWNvbnMi
+PnJlcGxheTwvaT4KICAgICAgICBSZXJ1biBGcm9tIFNvdXJjZXMKICAgICAgPC9zcGFuPgogICAgICA8
+c3BhbiBjbGFzcz0icmVxdWlyZWQiPgogICAgICAgIDxpIGNsYXNzPSJtYXRlcmlhbC1pY29ucyI+d2Fy
+bmluZzwvaT4KICAgICAgICBSZXJ1biBXaXRoIENoYW5nZXMKICAgICAgPC9zcGFuPgogICAgPC9idXR0
+b24+CjwvaGVhZGVyPgo8ZGl2IGNsYXNzPSJwYW5lbHMgaG9yaXpvbnRhbCI+CiAgICA8ZGl2IGNsYXNz
+PSJuYXYtcGFuZWwiPgogICAgICAgIDxkaXYgY2xhc3M9Im5hdi1pbm5lciI+CiAgICAgICAgICAgIDxk
+aXYgY2xhc3M9InBhbmVsLWhlYWRpbmciPlByb2plY3QgRmlsZXM8L2Rpdj4KICAgICAgICAgICAgPGRp
+diBjbGFzcz0ibmF2LXRyZWUiPjwvZGl2PgogICAgICAgIDwvZGl2PjwhLS0gL25hdi1pbm5lciAtLT4K
+ICAgIDwvZGl2PjwhLS0gL25hdiAtLT4KICAgIDxkaXYgY2xhc3M9ImZpbGUiPgogICAgICAgIDxkaXYg
+Y2xhc3M9InRpdGxlLWJhciI+CiAgICAgICAgICAgIDxoMyBpZD0idW5pdC1uYW1lIj4mbmJzcDs8L2gz
+PgogICAgICAgICAgICA8c3BhbiBpZD0ibWlncmF0ZS11bml0LXN0YXR1cy1pY29uLWxhYmVsIj5NaWdy
+YXRlCiAgICAgICAgICAgICAgICA8c3BhbgogICAgICAgICAgICAgICAgICAgIGNsYXNzPSJtYXRlcmlh
+bC1pY29ucyBzdGF0dXMtaWNvbiBtaWdyYXRpbmciCiAgICAgICAgICAgICAgICAgICAgaWQ9Im1pZ3Jh
+dGUtdW5pdC1zdGF0dXMtaWNvbiI+Y2hlY2tfYm94PC9zcGFuPgogICAgICAgICAgICA8L3NwYW4+CiAg
+ICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0iY29udGVudCI+CiAgICAgICAgICAgIDxkaXYg
+Y2xhc3M9InJlZ2lvbnMiPgogICAgICAgICAgICAgICAgPCEtLSBUaGUgcmVnaW9ucyBvdmVybGF5IGNv
+ZGUgY29weSBvZiB0aGUgY29udGVudCB0byBwcm92aWRlIC0tPgogICAgICAgICAgICAgICAgPCEtLSB0
+b29sdGlwcyBmb3IgbW9kaWZpZWQgcmVnaW9ucy4gLS0+CiAgICAgICAgICAgIDwvZGl2PjwhLS0gL3Jl
+Z2lvbnMgLS0+CiAgICAgICAgICAgIDxkaXYgY2xhc3M9ImNvZGUiPgogICAgICAgICAgICAgICAgPCEt
+LSBDb21waWxhdGlvbiB1bml0IGNvbnRlbnQgaXMgd3JpdHRlbiBoZXJlLiAtLT4KICAgICAgICAgICAg
+ICAgIDxwIGNsYXNzPSJ3ZWxjb21lIj4KICAgICAgICAgICAgICAgICAgICBTZWxlY3QgYSBzb3VyY2Ug
+ZmlsZSBvbiB0aGUgbGVmdCB0byBwcmV2aWV3IHRoZSBwcm9wb3NlZCBlZGl0cy4KICAgICAgICAgICAg
+ICAgIDwvcD4KICAgICAgICAgICAgPC9kaXY+CiAgICAgICAgPC9kaXY+CiAgICA8L2Rpdj48IS0tIC9j
+b250ZW50IC0tPgogICAgPGRpdiBjbGFzcz0iaW5mby1wYW5lbCI+CiAgICAgICAgPGRpdiBjbGFzcz0i
+ZWRpdC1saXN0Ij4KICAgICAgICAgICAgPGRpdiBjbGFzcz0icGFuZWwtaGVhZGluZyI+UHJvcG9zZWQg
+RWRpdHM8L2Rpdj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0icGFuZWwtY29udGVudCI+PC9kaXY+CiAg
+ICAgICAgPC9kaXY+PCEtLSAvZWRpdC1saXN0IC0tPgogICAgICAgIDxkaXYgY2xhc3M9ImVkaXQtcGFu
+ZWwiPgogICAgICAgICAgICA8ZGl2IGNsYXNzPSJwYW5lbC1oZWFkaW5nIj5FZGl0IERldGFpbHM8L2Rp
+dj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0icGFuZWwtY29udGVudCI+CiAgICAgICAgICAgICAgICA8
+cCBjbGFzcz0icGxhY2Vob2xkZXIiPlNlZSBkZXRhaWxzIGFib3V0IGEgcHJvcG9zZWQgZWRpdC48L3A+
+CiAgICAgICAgICAgIDwvZGl2PjwhLS0gL3BhbmVsLWNvbnRlbnQgLS0+CiAgICAgICAgPC9kaXY+PCEt
+LSAvZWRpdC1wYW5lbCAtLT4KICAgIDwvZGl2PjwhLS0gL2luZm8tcGFuZWwgLS0+CjwvZGl2PjwhLS0g
+L3BhbmVscyAtLT4KPGZvb3Rlcj4KICA8YnV0dG9uIGNsYXNzPSJyZXBvcnQtcHJvYmxlbSI+U2VuZCBG
+ZWVkYmFjazwvYnV0dG9uPgogICAgPHNwYW4gY2xhc3M9IndpZGUiPiA8L3NwYW4+CiAgICA8ZGl2IGNs
+YXNzPSJzZGstdmVyc2lvbiI+QmFzZWQgb24gPHNwYW4gaWQ9InNkay12ZXJzaW9uIj57eyBzZGtWZXJz
+aW9uIH19PC9zcGFuPjwvZGl2Pgo8L2Zvb3Rlcj4KPC9ib2R5Pgo8L2h0bWw+Cg==
''';
String _migration_css;
-// migration_css md5 is '21f8c4df3ccf665d538de0d63b257763'
+// migration_css md5 is 'cb4dfc4d6f9dd25370605e3a5e35ace6'
String _migration_css_base64 = '''
LyogQ29weXJpZ2h0IChjKSAyMDE5LCB0aGUgRGFydCBwcm9qZWN0IGF1dGhvcnMuIFBsZWFzZSBzZWUg
dGhlIEFVVEhPUlMgZmlsZSAgKi8KLyogZm9yIGRldGFpbHMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFVz
@@ -7523,178 +7529,185 @@
IGRpc3BsYXk6IG5vbmU7Cn0KCi5wcm9wb3NlZDpub3QoLm5lZWRzLXJlcnVuKSAuYXBwbHktbWlncmF0
aW9uW2Rpc2FibGVkXSB7CiAgZGlzcGxheTogbm9uZTsKfQoKaGVhZGVyIHsKICBiYWNrZ3JvdW5kLWNv
bG9yOiAjMWMyODM0OwogIGhlaWdodDogNDhweDsKICBwYWRkaW5nLWxlZnQ6IDI0cHg7CiAgYWxpZ24t
-aXRlbXM6IGNlbnRlcjsKICB6LWluZGV4OiA0Owp9CgpoZWFkZXIgaDEsCmhlYWRlciBoMiwKaGVhZGVy
-IGgzIHsKICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7CiAgZm9udC1mYW1pbHk6ICJHb29nbGUgU2FucyIs
-IlJvYm90byIsc2Fucy1zZXJpZjsKICBmb250LXdlaWdodDogNDAwOwogIG1hcmdpbi1yaWdodDogMjRw
-eDsKfQoKaDEgewogIGZvbnQtc2l6ZTogMS41ZW07Cn0KCmhlYWRlciBoMiB7CiAgZm9udC1zaXplOiAx
-LjJlbTsKCiAgLyogU2hpZnQgdGV4dCB1cCAqLwogIHBvc2l0aW9uOiByZWxhdGl2ZTsKICB0b3A6IC0y
-cHg7Cn0KCmhlYWRlciBoMyB7CiAgLyogU2hpZnQgdGV4dCB1cCAqLwogIHBvc2l0aW9uOiByZWxhdGl2
-ZTsKICB0b3A6IC0ycHg7Cn0KCgpoZWFkZXIgLmFjdGlvbi1idXR0b24sIGhlYWRlciBhIHsKICByaWdo
-dDogMHB4OwogIGZsb2F0OiByaWdodDsKICBtYXJnaW46IDEwcHg7Cn0KCmhlYWRlciBpbWcubG9nbyB7
-CiAgaGVpZ2h0OiAyNHB4OwogIHdpZHRoOiAyNHB4OwogIG1hcmdpbi1yaWdodDogOHB4OwogIHBvc2l0
-aW9uOiByZWxhdGl2ZTsKICB0b3A6IDRweDsKfQoKZm9vdGVyIC5yZXBvcnQtcHJvYmxlbSB7CiAgcmln
-aHQ6IDBweDsKICBtYXJnaW46IDRweCA4cHg7Cn0KCi5yZXJ1bi1taWdyYXRpb24gLnJlcXVpcmVkIHsK
-ICBkaXNwbGF5OiBub25lOwp9CgoubmVlZHMtcmVydW4gLnJlcnVuLW1pZ3JhdGlvbiAucmVxdWlyZWQg
-ewogIGRpc3BsYXk6IGluaXRpYWw7Cn0KCi5uZWVkcy1yZXJ1biAucmVydW4tbWlncmF0aW9uIC5vcHRp
-b25hbCB7CiAgZGlzcGxheTpub25lOwp9Cgpmb290ZXIgewogIGNvbG9yOiAjY2NjOwogIGJhY2tncm91
-bmQtY29sb3I6ICMyNzMyM2E7CiAgZGlzcGxheTogZmxleDsKICBmbGV4LWRpcmVjdGlvbjogcm93Owog
-IGFsaWduLWl0ZW1zOiBjZW50ZXI7CiAgcGFkZGluZzogOHB4IDAgOHB4IDI0cHg7Cn0KCmZvb3RlciAu
-d2lkZSB7CiAgZmxleDogMTsKfQoKZm9vdGVyIC5zZGstdmVyc2lvbiB7CiAgbWFyZ2luLXJpZ2h0OiAz
-MnB4Owp9CgouaG9yaXpvbnRhbCB7CiAgZGlzcGxheTogZmxleDsKfQoKLnBhbmVscyB7CiAgYmFja2dy
-b3VuZC1jb2xvcjogIzEyMWEyNTsKICBmbGV4OiAxOwogIG92ZXJmbG93OiBoaWRkZW47Cn0KCi5wYW5l
-bC1oZWFkaW5nIHsKICBjb2xvcjogIzY3Njc2NzsKICBtYXJnaW46IDhweDsKfQoKLm5hdi1saW5rLAou
-cmVnaW9uIHsKICBjdXJzb3I6IHBvaW50ZXI7Cn0KCi5uYXYtcGFuZWwgewogIGJhY2tncm91bmQtY29s
-b3I6ICMxMjIwMmY7CiAgZmxleDogMSAyMDBweDsKICBtYXJnaW46IDA7CiAgb3ZlcmZsb3c6IHNjcm9s
-bDsKICB1c2VyLXNlbGVjdDogbm9uZTsKfQoKLm5hdi1pbm5lciB7CiAgcGFkZGluZzogMCAwIDdweCA3
-cHg7Cn0KCi5maXhlZCB7CiAgcG9zaXRpb246IGZpeGVkOwogIHRvcDogMDsKfQoKLnJvb3QgewogIG1h
-cmdpbjogMDsKICBkaXNwbGF5OiBub25lOwp9CgoubmF2LXRyZWUgPiB1bCB7CiAgcGFkZGluZy1sZWZ0
-OiA2cHg7Cn0KCi5uYXYtdHJlZSAubWF0ZXJpYWwtaWNvbnMgewogIGZvbnQtc2l6ZTogMjBweDsKICBw
-b3NpdGlvbjogcmVsYXRpdmU7CiAgdG9wOiA1cHg7CiAgbWFyZ2luLXJpZ2h0OiA4cHg7CiAgY29sb3I6
-ICM2NzY3Njc7IC8qICRzZWNvbmRhcnktY29sb3IgKi8KfQoKLm5hdi10cmVlIC5zdGF0dXMtaWNvbi5h
-bHJlYWR5LW1pZ3JhdGVkIHsKICBjb2xvcjogIzAwN2EyNzsgLyogJGxpZ2h0LWdyZWVuICovCn0KCi5u
-YXYtdHJlZSAuc3RhdHVzLWljb24ub3B0ZWQtb3V0IHsKICBjb2xvcjogIzY3Njc2NzsgLyogJHNlY29u
-ZGFyeS1jb2xvciAqLwp9CgoubmF2LXRyZWUgLnN0YXR1cy1pY29uLm9wdGVkLW91dDpob3ZlciB7CiAg
-Y29sb3I6ICNmZmZmZmY7Cn0KCi5uYXYtdHJlZSAuc3RhdHVzLWljb24ubWlncmF0aW5nIHsKICBjb2xv
-cjogIzUxYzY4NjsgLyogJGRhcmstZ3JlZW4gKi8KfQoKLm5hdi10cmVlIC5zdGF0dXMtaWNvbi5taWdy
-YXRpbmc6aG92ZXIgewogIGNvbG9yOiAjZmZmZmZmOwp9CgoubmF2LWlubmVyIHVsIHsKICBwYWRkaW5n
-LWxlZnQ6IDEycHg7CiAgbWFyZ2luOiAwOwp9CgoubmF2LWlubmVyIGxpIHsKICBsaXN0LXN0eWxlLXR5
-cGU6IG5vbmU7CiAgd2hpdGUtc3BhY2U6IG5vd3JhcDsKfQoKLm5hdi1pbm5lciBsaTpub3QoLmRpcikg
-ewogIG1hcmdpbi1sZWZ0OiAyMHB4OwogIG1hcmdpbi1ib3R0b206IDNweDsKfQoKLm5hdi1pbm5lciBs
-aS5kaXIgLmFycm93IHsKICBjdXJzb3I6IHBvaW50ZXI7CiAgZGlzcGxheTogaW5saW5lLWJsb2NrOwog
-IGZvbnQtc2l6ZTogMTBweDsKICBtYXJnaW4tcmlnaHQ6IDRweDsKICB0cmFuc2l0aW9uOiB0cmFuc2Zv
-cm0gMC41cyBlYXNlLW91dDsKfQoKLm5hdi1pbm5lciBsaS5kaXIgLmFycm93LmNvbGxhcHNlZCB7CiAg
-dHJhbnNmb3JtOiByb3RhdGUoLTkwZGVnKTsKfQoKLm5hdi1pbm5lciB1bCB7CiAgLyogYSBtYXgtaGVp
-Z2h0IGlzIGFkZGVkIHRvIGVhY2ggZWxlbWVudCBhdCBydW50aW1lLiAqLwogIHRyYW5zaXRpb246IG1h
-eC1oZWlnaHQgMC41cyBlYXNlLW91dDsKfQoKLm5hdi1pbm5lciB1bC5jb2xsYXBzZWQgewogIG1heC1o
-ZWlnaHQ6IDAgIWltcG9ydGFudDsKICBvdmVyZmxvdzogaGlkZGVuOwp9CgoubmF2LWlubmVyIC5zZWxl
-Y3RlZC1maWxlIHsKICBjb2xvcjogd2hpdGU7CiAgY3Vyc29yOiBpbmhlcml0OwogIGZvbnQtd2VpZ2h0
-OiA2MDA7CiAgdGV4dC1kZWNvcmF0aW9uOiBub25lOwp9CgouZWRpdC1jb3VudCB7CiAgYmFja2dyb3Vu
-ZC1jb2xvcjogIzY3Njc2NzsKICBib3JkZXItcmFkaXVzOiAxMHB4OwogIGNvbG9yOiAjZmZmOwogIGRp
-c3BsYXk6IGlubGluZS1ibG9jazsKICBmb250LXNpemU6IDExcHg7CiAgZm9udC13ZWlnaHQ6IDYwMDsK
-ICBtYXJnaW4tbGVmdDogNXB4OwogIG1pbi13aWR0aDogMjVweDsKICBwYWRkaW5nOiA0cHggMCAycHgg
-MDsKICB0ZXh0LWFsaWduOiBjZW50ZXI7CiAgbGluZS1oZWlnaHQ6IDFlbTsKfQoKLmNvbnRlbnQgewog
-IGZsZXg6IDQgMzAwcHg7CiAgYmFja2dyb3VuZDogIzEyMjAyZjsKICBmb250LWZhbWlseTogIlJvYm90
-byBNb25vIiwgbW9ub3NwYWNlOwogIG1hcmdpbjogMCA2cHg7CiAgcG9zaXRpb246IHJlbGF0aXZlOwog
-IHdoaXRlLXNwYWNlOiBwcmU7CiAgb3ZlcmZsb3c6IHNjcm9sbDsKfQoKLmNvZGUgewogIHBhZGRpbmc6
-IDAuNWVtOwogIHBvc2l0aW9uOiBhYnNvbHV0ZTsKICBsZWZ0OiAwOwogIHRvcDogMDsKICBtYXJnaW4t
-bGVmdDogNTZweDsKfQoKLmNvZGUgLndlbGNvbWUgewogIGZvbnQtZmFtaWx5OiAiR29vZ2xlIFNhbnMi
-LCJSb2JvdG8iLHNhbnMtc2VyaWY7CiAgZm9udC1zaXplOiAxOHB4OwogIG1hcmdpbi1yaWdodDogNjJw
-eDsKICBjb2xvcjogIzc3NzsKfQoKLmNvZGUgLm5hdi1saW5rIHsKICBjb2xvcjogIzE2YWRjYTsKICB0
-ZXh0LWRlY29yYXRpb24tbGluZTogbm9uZTsKfQoKLmNvZGUgLm5hdi1saW5rOnZpc2l0ZWQgewogIGNv
-bG9yOiAjMTM5YmI1OyAvKiAjMTZhZGNhIGRhcmtlbmVkIDEwJSAqLwogIHRleHQtZGVjb3JhdGlvbi1s
-aW5lOiBub25lOwp9CgouY29kZSAubmF2LWxpbms6aG92ZXIgewogIHRleHQtZGVjb3JhdGlvbi1saW5l
-OiB1bmRlcmxpbmU7CiAgZm9udC13ZWlnaHQ6IDYwMDsKfQoKLnJlZ2lvbnMgewogIHBhZGRpbmc6IDAu
-NWVtOwogIHBvc2l0aW9uOiBhYnNvbHV0ZTsKICBsZWZ0OiAwOwogIHRvcDogMDsKfQoKLnJlZ2lvbnMg
-dGFibGUgewogIGJvcmRlci1zcGFjaW5nOiAwOwogIGZvbnQtc2l6ZTogaW5oZXJpdDsKfQoKLnJlZ2lv
-bnMgdGQgewogIGJvcmRlcjogbm9uZTsKICAvKiBUaGUgY29udGVudCBvZiB0aGUgcmVnaW9ucyBpcyBu
-b3QgdmlzaWJsZTsgdGhlIHVzZXIgaW5zdGVhZCB3aWxsIHNlZSB0aGUKICAgKiBoaWdobGlnaHRlZCBj
-b3B5IG9mIHRoZSBjb250ZW50LiAqLwogIGNvbG9yOiByZ2JhKDI1NSwgMjU1LCAyNTUsIDApOwogIHBh
-ZGRpbmc6IDA7CiAgd2hpdGUtc3BhY2U6IHByZTsKfQoKLnJlZ2lvbnMgdGQ6ZW1wdHk6YWZ0ZXIgewog
-IGNvbnRlbnQ6ICJcMDBhMCI7Cn0KCi5yZWdpb25zIHRyLmhpZ2hsaWdodCB0ZDpsYXN0LWNoaWxkIHsK
-ICBiYWNrZ3JvdW5kLWNvbG9yOiAjNDQ0NDQ0OwogIGNvbG9yOiB3aGl0ZTsKfQoKLnJlZ2lvbnMgdGQu
-bGluZS1ubyB7CiAgYm9yZGVyLXJpZ2h0OiBzb2xpZCAjMTIyMDJmIDJweDsKICBjb2xvcjogIzk5OTk5
-OTsKICBwYWRkaW5nLXJpZ2h0OiA0cHg7CiAgdGV4dC1hbGlnbjogcmlnaHQ7CiAgdmlzaWJpbGl0eTog
-dmlzaWJsZTsKICB3aWR0aDogNTBweDsKICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7Cn0KCi5yZWdpb25z
-IHRyLmhpZ2hsaWdodCB0ZC5saW5lLW5vIHsKICBib3JkZXItcmlnaHQ6IHNvbGlkICNjY2MgMnB4Owp9
-CgoucmVnaW9uIHsKICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7CiAgcG9zaXRpb246IHJlbGF0aXZlOwog
-IHZpc2liaWxpdHk6IHZpc2libGU7CiAgei1pbmRleDogMjAwOwp9CgoucmVnaW9uLmFkZGVkLXJlZ2lv
-biB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzE3OGFmZDsKICBjb2xvcjogI2ZmZjsKfQoKLnJlZ2lvbi5y
-ZW1vdmVkLXJlZ2lvbiB7CiAgYmFja2dyb3VuZC1jb2xvcjogI0ZBNTU3ZDsgLyogJGRhcmstcGluayAq
-LwogIGNvbG9yOiAjZmZmOwp9CgoucmVnaW9uLmluZm9ybWF0aXZlLXJlZ2lvbiB7CiAgYmFja2dyb3Vu
-ZC1jb2xvcjogIzI2Mzk1MjsKICBjb2xvcjogI2ZmZjsKICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7CiAg
-aGVpZ2h0OiAxNXB4OwogIHBvc2l0aW9uOiByZWxhdGl2ZTsKfQoKLnRhcmdldCB7CiAgYmFja2dyb3Vu
-ZC1jb2xvcjogIzQ0NDsKICBwb3NpdGlvbjogcmVsYXRpdmU7CiAgdmlzaWJpbGl0eTogdmlzaWJsZTsK
-ICBmb250LXdlaWdodDogNjAwOwp9CgouaW5mby1wYW5lbCB7CiAgZmxleDogMSAyMDBweDsKICBtYXJn
-aW46IDA7CiAgaGVpZ2h0OiAxMDAlOwogIGRpc3BsYXk6IGZsZXg7CiAgZmxleC1kaXJlY3Rpb246IGNv
-bHVtbjsKfQoKLmluZm8tcGFuZWwgLmVkaXQtcGFuZWwgewogIGJhY2tncm91bmQtY29sb3I6ICMxMjIw
-MmY7CiAgb3ZlcmZsb3c6IGF1dG87Cn0KCi5pbmZvLXBhbmVsIC5wYW5lbC1jb250ZW50IHsKICBwYWRk
-aW5nOiA3cHg7Cn0KCi5pbmZvLXBhbmVsIC5wYW5lbC1jb250ZW50PiA6Zmlyc3QtY2hpbGQgewogIG1h
-cmdpbi10b3A6IDA7Cn0KCi5pbmZvLXBhbmVsIC5ub3dyYXAgewogIHdoaXRlLXNwYWNlOiBub3dyYXA7
-Cn0KCi5pbmZvLXBhbmVsIHVsLAouaW5mby1wYW5lbCBvbCB7CiAgcGFkZGluZy1sZWZ0OiAyMHB4Owp9
-CgouaW5mby1wYW5lbCBsaSB7CiAgbWFyZ2luOiAwIDAgNXB4IDA7Cn0KCi5pbmZvLXBhbmVsIGEgewog
-IGNvbG9yOiAjMTM5YmI1Owp9CgouaW5mby1wYW5lbCBhOmhvdmVyIHsKICBjb2xvcjogIzFlYzdlNzsg
-LyogIzEzOWJiNSBsaWdodGVuZWQgMjAlICovCn0KCi5pbmZvLXBhbmVsIC5lZGl0LWxpc3QgewogIGJh
-Y2tncm91bmQtY29sb3I6ICMxMjIwMmY7CiAgb3ZlcmZsb3c6IGF1dG87Cn0KCi5lZGl0LXBhbmVsIHsK
-ICBtYXJnaW4tdG9wOiA2cHg7CiAgZmxleDogMSAxMDBweDsKfQoKLmVkaXQtbGlzdCB7CiAgZmxleDog
-MiAxMDBweDsKfQoKLmVkaXQtbGlzdCAuZWRpdCB7CiAgbWFyZ2luOiAzcHggMDsKfQoKLmVkaXQtbGlz
-dCAuZWRpdC1saW5rIHsKICBjdXJzb3I6IHBvaW50ZXI7Cn0KCi5wb3B1cC1wYW5lIHsKICBkaXNwbGF5
-OiBub25lOwogIHBvc2l0aW9uOiBmaXhlZDsKICB0b3A6IDE1MHB4OwogIGxlZnQ6IDE1MHB4OwogIHJp
-Z2h0OiAxNTBweDsKICBib3R0b206IDE1MHB4OwogIGJvcmRlcjogMXB4IHNvbGlkIGJsYWNrOwogIGJv
-cmRlci10b3A6IDJweCBzb2xpZCBibGFjazsKICBib3JkZXItcmFkaXVzOiA3cHg7CiAgYm94LXNoYWRv
-dzogMHB4IDBweCAyMHB4IDJweCAjYjRiZmNiMjI7CiAgei1pbmRleDogNDAwOwogIGJhY2tncm91bmQ6
-ICMyYjMwMzY7CiAgcGFkZGluZzogMjBweDsKfQoKLnBvcHVwLXBhbmUgLmNsb3NlIHsKICBwb3NpdGlv
-bjogYWJzb2x1dGU7CiAgcmlnaHQ6IDEwcHg7CiAgdG9wOiAxMHB4OwogIGN1cnNvcjogcG9pbnRlcjsK
-ICB0ZXh0LXNoYWRvdzogMXB4IDFweCAycHggIzg4ODsKICBib3gtc2hhZG93OiAxcHggMXB4IDJweCAj
-MTExOwp9CgoucG9wdXAtcGFuZSBoMiB7CiAgcGFkZGluZzogMjFweDsKICBoZWlnaHQ6IDEwJTsKICBt
-YXJnaW46IDBweDsKICBib3gtc2l6aW5nOiBib3JkZXItYm94Owp9CgoucG9wdXAtcGFuZSBwIHsKICBo
-ZWlnaHQ6IDEwJTsKICBib3gtc2l6aW5nOiBib3JkZXItYm94OwogIHBhZGRpbmc6IDBweCAyMHB4Owp9
-CgoucG9wdXAtcGFuZSBwcmUgewogIGJhY2tncm91bmQ6ICMxMjIwMmY7CiAgcGFkZGluZzogMjBweDsK
-ICBib3R0b206IDBweDsKICBvdmVyZmxvdzogYXV0byBzY3JvbGw7CiAgaGVpZ2h0OiA2NSU7CiAgbWFy
-Z2luOiAwcHg7CiAgYm94LXNpemluZzogYm9yZGVyLWJveDsKfQoKLnBvcHVwLXBhbmUgLmJ1dHRvbi5i
-b3R0b20gewogIG1hcmdpbjogMjBweCAwcHg7CiAgZGlzcGxheTogYmxvY2s7CiAgdGV4dC1hbGlnbjog
-Y2VudGVyOwp9CgoucmVydW5uaW5nLXBhbmUgewogIGRpc3BsYXk6IG5vbmU7Cn0KCmJvZHkucmVydW5u
-aW5nIC5yZXJ1bm5pbmctcGFuZSB7CiAgZGlzcGxheTogYmxvY2s7CiAgcG9zaXRpb246IGZpeGVkOwog
-IHRvcDogMHB4OwogIGJvdHRvbTogMHB4OwogIGxlZnQ6IDBweDsKICByaWdodDogMHB4OwogIGJhY2tn
-cm91bmQtY29sb3I6ICMwMDAwMDBBQTsgLyogdHJhbnNsdWNlbnQgYmxhY2sgKi8KICB6LWluZGV4OiA0
-MDA7Cn0KCi5yZXJ1bm5pbmctcGFuZSBoMSB7CiAgcG9zaXRpb246IGFic29sdXRlOwogIHRvcDogNTAl
-OwogIGxlZnQ6IDUwJTsKICB0cmFuc2Zvcm06IHRyYW5zbGF0ZSgtNTAlLCAtNTAlKTsKfQoKLmVkaXQt
-cGFuZWwgLnR5cGUtZGVzY3JpcHRpb24gewogIC8qIEZyb20gRGFydFBhZCAkZGFyay1vcmFuZ2UgKi8K
-ICBjb2xvcjogI2ZmOTE2ZTsKICBmb250LWZhbWlseTogbW9ub3NwYWNlOwp9Cgp1bC50cmFjZSB7CiAg
-Zm9udC1zaXplOiAxM3B4OwogIGxpc3Qtc3R5bGUtdHlwZTogbm9uZTsKICBwYWRkaW5nLWxlZnQ6IDBw
-eDsKfQoKdWwudHJhY2UgbGkgewogIGNvbG9yOiB3aGl0ZTsKfQoKdWwudHJhY2UgbGkgLmZ1bmN0aW9u
-IHsKICAvKiBmcm9tIC5obGpzLXZhcmlhYmxlICovCiAgY29sb3I6ICMxNmFkY2E7CiAgZm9udC1mYW1p
-bHk6IG1vbm9zcGFjZTsKICBmb250LXdlaWdodDogNjAwOwp9Cgp1bC50cmFjZSBsaSBwLmRyYXdlciB7
-CiAgbWFyZ2luOiAzcHggMHB4OwogIHBhZGRpbmc6IDBweCAwcHggMHB4IDE0cHg7Cn0KCnVsLnRyYWNl
-IGxpIHAuZHJhd2VyIGJ1dHRvbiB7CiAgbWFyZ2luLXJpZ2h0OiAzcHg7Cn0KCi5lbGV2YXRpb24tejQg
-ewogIGJveC1zaGFkb3c6IDBweCAycHggNHB4IC0xcHggcmdiYSgwLCAwLCAwLCAwLjIpLAogICAgICAw
-cHggNHB4IDVweCAwcHggcmdiYSgwLCAwLCAwLCAwLjE0KSwKICAgICAgMHB4IDFweCAxMHB4IDBweCBy
-Z2JhKDAsIDAsIDAsIC4xMik7Cn0KCmEgewogIGNvbG9yOiAjY2NjOwogIGZpbGw6ICNjY2M7CiAgdGV4
-dC1kZWNvcmF0aW9uOiBub25lOwp9CgphOmhvdmVyIHsKICBjb2xvcjogI2RiZGJkYjsgLyogI2NjYyBs
-aWdodGVudGVkIDMwJSovCiAgZmlsbDogI2ZmZjsKfQoKLmFkZC1oaW50LWxpbmsgewogIGRpc3BsYXk6
-IGlubGluZS1ibG9jazsKICBtYXJnaW46IDNweDsKfQoKLmFkZC1oaW50LWxpbms6aG92ZXIgewogIGNv
-bG9yOiAjZmZmOwp9CgpoZWFkZXIgYnV0dG9uIHsKICB0ZXh0LXRyYW5zZm9ybTogdXBwZXJjYXNlOwp9
-CgpoZWFkZXIgYSB7CiAgbWFyZ2luOiAwOwp9CgovKiBDYXJlZnVsIGhlcmUuIGBhLmJ1dHRvbmAgaXMg
-cmVwZXRpdGl2ZSBidXQgcmVxdWlyZWQgdG8gZ2V0IGNvcnJlY3QKICogc3BlY2lmaWNpdHkgKi8KYnV0
-dG9uLCAuYnV0dG9uLCBhLmJ1dHRvbiB7CiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgyMiwgMTM4LCAy
-NTMsIDAuMTUpOwogIGJvcmRlcjogbm9uZTsKICBib3JkZXItcmFkaXVzOiAzcHg7CiAgcGFkZGluZzog
-M3B4IDEwcHg7CiAgZm9udC13ZWlnaHQ6IDUwMDsKICBmb250LWZvbnQ6IFJvYm90bywgc2Fucy1zZXJp
-ZjsKICBjb2xvcjogI2ZmZjsKfQoKYnV0dG9uOmhvdmVyLCAuYnV0dG9uOmhvdmVyIHsKICBiYWNrZ3Jv
-dW5kLWNvbG9yOiByZ2JhKDIyLCAxMzgsIDI1MywgMC4yOSk7CiAgY3Vyc29yOiBwb2ludGVyOwp9Cgpi
-dXR0b25bZGlzYWJsZWRdIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDI1NSwyNTUsMjU1LC4xMik7
-CiAgY29sb3I6IHJnYmEoMjU1LDI1NSwyNTUsLjM3KTsKICBjdXJzb3I6IG5vdC1hbGxvd2VkOwp9Cgov
-KiBDaGFuZ2UgZWRpdCBwYW5lbCBidXR0b24gY29sb3JzICovCi5lZGl0LXBhbmVsIC5idXR0b24sIC5l
-ZGl0LXBhbmVsIGJ1dHRvbiB7CiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSg2MywgMTA0LCAxNDgsIDAu
-Nik7CiAgY29sb3I6IHdoaXRlOwp9Ci5lZGl0LXBhbmVsIC5idXR0b246aG92ZXIsIC5lZGl0LXBhbmVs
-IGJ1dHRvbjpob3ZlciB7CiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgxMDEsIDE1MywgMjA4LCAwLjYp
-OwogIGNvbG9yOiB3aGl0ZTsKfQoKLyoKICogQWRqdXN0bWVudHMgdG8gYWxpZ24gbWF0ZXJpYWwgaWNv
-bnMgaW4gdGhlIHRvb2xiYXIgYnV0dG9ucy4KKi8KLmFjdGlvbi1idXR0b24gPiBzcGFuIHsKICBwb3Np
-dGlvbjpyZWxhdGl2ZTsKICB0b3A6IC0zcHg7Cn0KCi5hY3Rpb24tYnV0dG9uIC5tYXRlcmlhbC1pY29u
-cyB7CiAgdG9wOiA0cHg7Cn0KCi8qIERvbid0IHNoaWZ0IHRoZSBpY29uIHdoZW4gaXQncyBhIGRpcmVj
-dCBjaGlsZCBvZiB0aGUgYnV0dG9uICovCi5hY3Rpb24tYnV0dG9uID4gLm1hdGVyaWFsLWljb25zIHsK
-ICB0b3A6IDFweDsKfQoKLyogU2hpZnQgdGhlIHRleHQgdG8gY2VudGVyIHdpdGggdGhlIGljb24uICov
-Ci5hY3Rpb24tYnV0dG9uID4gc3Bhbi5sYWJlbCB7CiAgcG9zaXRpb246cmVsYXRpdmU7CiAgdG9wOiAt
-NHB4Owp9CgouYWN0aW9uLWJ1dHRvbiAubWF0ZXJpYWwtaWNvbnMgewogIGZvbnQtc2l6ZTogMjBweDsK
-ICBwb3NpdGlvbjogcmVsYXRpdmU7Cn0KCi5wbGFjZWhvbGRlciB7CiAgY29sb3I6ICM3Nzc7CiAgdGV4
-dC1hbGlnbjogY2VudGVyOwogIG1hcmdpbi10b3A6IDNlbSAhaW1wb3J0YW50Owp9CgovKioKICogSExK
-UyBPdmVycmlkZXMKICovCi5obGpzIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMTIyMDJmOyAvKiAkZGFy
-ay1jb2RlLWJhY2tncm91bmQtY29sb3IgKi8KICBjb2xvcjogI2MwYzJjNTsgLyogJGRhcmstZWRpdG9y
-LXRleHQgKi8KICBkaXNwbGF5OiBibG9jazsKICBvdmVyZmxvdy14OiBhdXRvOwogIHBhZGRpbmc6IDAu
-NWVtOwogIC8qKgogICAqIFRoaXMgYWxsb3dzIHRoZSBwZXItbGluZSBoaWdobGlnaHRzIHRvIHNob3cu
-CiAgICovCiAgYmFja2dyb3VuZDogbm9uZTsKfQoKLmhsanMta2V5d29yZCwKLmhsanMtc2VsZWN0b3It
-dGFnLAouaGxqcy1kZWxldGlvbiB7CiAgY29sb3I6ICM1MWM2ODY7IC8qIGNtLWtleXdvcmQgKi8KfQoK
-LmhsanMtbnVtYmVyIHsKICBjb2xvcjogIzYyNzk3ODsgLyogY20tbnVtYmVyICovCn0KCi5obGpzLWNv
-bW1lbnQgewogIGNvbG9yOiAjOTE5OGI0OyAvKiBjbS1jb21tZW50ICovCn0KCi5obGpzLWxpdGVyYWwg
-ewogIGNvbG9yOiAjZWU4NjY2OyAvKiBjbS1hdG9tICovCn0KCi5obGpzLXN0cmluZyB7CiAgY29sb3I6
-ICNlNTUwNzQ7IC8qIGNtLXN0cmluZyAqLwp9CgouaGxqcy12YXJpYWJsZSB7CiAgY29sb3I6ICMxNmFk
-Y2E7IC8qIGNtLXZhcmlhYmxlICovCn0KCi5obGpzLWxpbmsgewogIGNvbG9yOiAjZTU1MDc0OyAvKiBj
-bS1zdHJpbmcgKi8KfQouaGxqcy1zZWN0aW9uLAouaGxqcy10eXBlLAouaGxqcy1idWlsdF9pbiwKLmhs
-anMtdGl0bGUgewogIGNvbG9yOiAjZWU4NjY2OyAvKiBjbS12YXJpYWJsZS0yICovCn0KCi5obGpzLWFk
-ZGl0aW9uIHsKICBjb2xvcjogIzI2Mzk1MjsgLyogJGRhcmstc2VsZWN0aW9uLWNvbG9yICovCn0KCi5o
-bGpzLW1ldGEgewogIGNvbG9yOiAjNjI3OTc4Owp9Cg==
+aXRlbXM6IGNlbnRlcjsKICB6LWluZGV4OiA0Owp9CgpoZWFkZXIgaDEsCmhlYWRlciBoMiB7CiAgZGlz
+cGxheTogaW5saW5lLWJsb2NrOwogIGZvbnQtZmFtaWx5OiAiR29vZ2xlIFNhbnMiLCJSb2JvdG8iLHNh
+bnMtc2VyaWY7CiAgZm9udC13ZWlnaHQ6IDQwMDsKICBtYXJnaW4tcmlnaHQ6IDI0cHg7Cn0KCmgxIHsK
+ICBmb250LXNpemU6IDEuNWVtOwp9CgpoZWFkZXIgaDIgewogIGZvbnQtc2l6ZTogMS4yZW07CgogIC8q
+IFNoaWZ0IHRleHQgdXAgKi8KICBwb3NpdGlvbjogcmVsYXRpdmU7CiAgdG9wOiAtMnB4Owp9CgpoZWFk
+ZXIgLmFjdGlvbi1idXR0b24sIGhlYWRlciBhIHsKICByaWdodDogMHB4OwogIGZsb2F0OiByaWdodDsK
+ICBtYXJnaW46IDEwcHg7Cn0KCmhlYWRlciBpbWcubG9nbyB7CiAgaGVpZ2h0OiAyNHB4OwogIHdpZHRo
+OiAyNHB4OwogIG1hcmdpbi1yaWdodDogOHB4OwogIHBvc2l0aW9uOiByZWxhdGl2ZTsKICB0b3A6IDRw
+eDsKfQoKZm9vdGVyIC5yZXBvcnQtcHJvYmxlbSB7CiAgcmlnaHQ6IDBweDsKICBtYXJnaW46IDRweCA4
+cHg7Cn0KCi5yZXJ1bi1taWdyYXRpb24gLnJlcXVpcmVkIHsKICBkaXNwbGF5OiBub25lOwp9CgoubmVl
+ZHMtcmVydW4gLnJlcnVuLW1pZ3JhdGlvbiAucmVxdWlyZWQgewogIGRpc3BsYXk6IGluaXRpYWw7Cn0K
+Ci5uZWVkcy1yZXJ1biAucmVydW4tbWlncmF0aW9uIC5vcHRpb25hbCB7CiAgZGlzcGxheTpub25lOwp9
+Cgpmb290ZXIgewogIGNvbG9yOiAjY2NjOwogIGJhY2tncm91bmQtY29sb3I6ICMyNzMyM2E7CiAgZGlz
+cGxheTogZmxleDsKICBmbGV4LWRpcmVjdGlvbjogcm93OwogIGFsaWduLWl0ZW1zOiBjZW50ZXI7CiAg
+cGFkZGluZzogOHB4IDAgOHB4IDI0cHg7Cn0KCmZvb3RlciAud2lkZSB7CiAgZmxleDogMTsKfQoKZm9v
+dGVyIC5zZGstdmVyc2lvbiB7CiAgbWFyZ2luLXJpZ2h0OiAzMnB4Owp9CgouaG9yaXpvbnRhbCB7CiAg
+ZGlzcGxheTogZmxleDsKfQoKLnBhbmVscyB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzEyMWEyNTsKICBm
+bGV4OiAxOwogIG92ZXJmbG93OiBoaWRkZW47Cn0KCi5wYW5lbC1oZWFkaW5nIHsKICBjb2xvcjogIzY3
+Njc2NzsKICBtYXJnaW46IDhweDsKfQoKLm5hdi1saW5rLAoucmVnaW9uIHsKICBjdXJzb3I6IHBvaW50
+ZXI7Cn0KCi5uYXYtcGFuZWwgewogIGJhY2tncm91bmQtY29sb3I6ICMxMjIwMmY7CiAgZmxleDogMSAy
+MDBweDsKICBtYXJnaW46IDA7CiAgb3ZlcmZsb3c6IHNjcm9sbDsKICB1c2VyLXNlbGVjdDogbm9uZTsK
+fQoKLm5hdi1pbm5lciB7CiAgcGFkZGluZzogMCAwIDdweCA3cHg7Cn0KCi5maXhlZCB7CiAgcG9zaXRp
+b246IGZpeGVkOwogIHRvcDogMDsKfQoKLnJvb3QgewogIG1hcmdpbjogMDsKICBkaXNwbGF5OiBub25l
+Owp9CgoubmF2LXRyZWUgPiB1bCB7CiAgcGFkZGluZy1sZWZ0OiA2cHg7Cn0KCi5uYXYtdHJlZSAubWF0
+ZXJpYWwtaWNvbnMgewogIGZvbnQtc2l6ZTogMjBweDsKICBwb3NpdGlvbjogcmVsYXRpdmU7CiAgdG9w
+OiA1cHg7CiAgbWFyZ2luLXJpZ2h0OiA4cHg7CiAgY29sb3I6ICM2NzY3Njc7IC8qICRzZWNvbmRhcnkt
+Y29sb3IgKi8KfQoKLnN0YXR1cy1pY29uLmFscmVhZHktbWlncmF0ZWQgewogIGNvbG9yOiAjMDA3YTI3
+OyAvKiAkbGlnaHQtZ3JlZW4gKi8KfQoKLnN0YXR1cy1pY29uLm9wdGVkLW91dCB7CiAgY29sb3I6ICM2
+NzY3Njc7IC8qICRzZWNvbmRhcnktY29sb3IgKi8KfQoKLnN0YXR1cy1pY29uLm9wdGVkLW91dDpob3Zl
+ciB7CiAgY29sb3I6ICNmZmZmZmY7Cn0KCi5zdGF0dXMtaWNvbi5taWdyYXRpbmcgewogIGNvbG9yOiAj
+NTFjNjg2OyAvKiAkZGFyay1ncmVlbiAqLwp9Cgouc3RhdHVzLWljb24ubWlncmF0aW5nOmhvdmVyIHsK
+ICBjb2xvcjogI2ZmZmZmZjsKfQoKLm5hdi1pbm5lciB1bCB7CiAgcGFkZGluZy1sZWZ0OiAxMnB4Owog
+IG1hcmdpbjogMDsKfQoKLm5hdi1pbm5lciBsaSB7CiAgbGlzdC1zdHlsZS10eXBlOiBub25lOwogIHdo
+aXRlLXNwYWNlOiBub3dyYXA7Cn0KCi5uYXYtaW5uZXIgbGk6bm90KC5kaXIpIHsKICBtYXJnaW4tbGVm
+dDogMjBweDsKICBtYXJnaW4tYm90dG9tOiAzcHg7Cn0KCi5uYXYtaW5uZXIgbGkuZGlyIC5hcnJvdyB7
+CiAgY3Vyc29yOiBwb2ludGVyOwogIGRpc3BsYXk6IGlubGluZS1ibG9jazsKICBmb250LXNpemU6IDEw
+cHg7CiAgbWFyZ2luLXJpZ2h0OiA0cHg7CiAgdHJhbnNpdGlvbjogdHJhbnNmb3JtIDAuNXMgZWFzZS1v
+dXQ7Cn0KCi5uYXYtaW5uZXIgbGkuZGlyIC5hcnJvdy5jb2xsYXBzZWQgewogIHRyYW5zZm9ybTogcm90
+YXRlKC05MGRlZyk7Cn0KCi5uYXYtaW5uZXIgdWwgewogIC8qIGEgbWF4LWhlaWdodCBpcyBhZGRlZCB0
+byBlYWNoIGVsZW1lbnQgYXQgcnVudGltZS4gKi8KICB0cmFuc2l0aW9uOiBtYXgtaGVpZ2h0IDAuNXMg
+ZWFzZS1vdXQ7Cn0KCi5uYXYtaW5uZXIgdWwuY29sbGFwc2VkIHsKICBtYXgtaGVpZ2h0OiAwICFpbXBv
+cnRhbnQ7CiAgb3ZlcmZsb3c6IGhpZGRlbjsKfQoKLm5hdi1pbm5lciAuc2VsZWN0ZWQtZmlsZSB7CiAg
+Y29sb3I6IHdoaXRlOwogIGN1cnNvcjogaW5oZXJpdDsKICBmb250LXdlaWdodDogNjAwOwogIHRleHQt
+ZGVjb3JhdGlvbjogbm9uZTsKfQoKLmVkaXQtY291bnQgewogIGJhY2tncm91bmQtY29sb3I6ICM2NzY3
+Njc7CiAgYm9yZGVyLXJhZGl1czogMTBweDsKICBjb2xvcjogI2ZmZjsKICBkaXNwbGF5OiBpbmxpbmUt
+YmxvY2s7CiAgZm9udC1zaXplOiAxMXB4OwogIGZvbnQtd2VpZ2h0OiA2MDA7CiAgbWFyZ2luLWxlZnQ6
+IDVweDsKICBtaW4td2lkdGg6IDI1cHg7CiAgcGFkZGluZzogNHB4IDAgMnB4IDA7CiAgdGV4dC1hbGln
+bjogY2VudGVyOwogIGxpbmUtaGVpZ2h0OiAxZW07Cn0KCi5maWxlIHsKICBmbGV4OiA0IDMwMHB4Owog
+IGZvbnQtZmFtaWx5OiAiR29vZ2xlIFNhbnMiLCJSb2JvdG8iLHNhbnMtc2VyaWY7CiAgYmFja2dyb3Vu
+ZDogIzEyMjAyZjsKICBtYXJnaW46IDZweDsKICBvdmVyZmxvdzogc2Nyb2xsOwp9CgoudGl0bGUtYmFy
+IGgzIHsKICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7CiAgZm9udC13ZWlnaHQ6IDQwMDsKICAvKiBUaGlz
+IGFsaWducyB0aGUgdGl0bGUgdGV4dCB3aXRoIHRoZSBjb250ZW50IHRleHQsIGFjY291bnRpbmcgZm9y
+IHRoZSB3aWR0aAogICAqIG9mIHRoZSBsaW5lIG51bWJlcnMuCiAgICovCiAgbWFyZ2luOiAwLjVlbSAy
+NHB4IDAuNWVtIDYzcHg7Cn0KCi50aXRsZS1iYXIgI21pZ3JhdGUtdW5pdC1zdGF0dXMtaWNvbi1sYWJl
+bCB7CiAgZGlzcGxheTogbm9uZTsKICB1c2VyLXNlbGVjdDogbm9uZTsKfQoKLnRpdGxlLWJhciAjbWln
+cmF0ZS11bml0LXN0YXR1cy1pY29uLWxhYmVsLnZpc2libGUgewogIC8qIENoYW5nZSB0byAnaW5saW5l
+JyB0byBlbmFibGUgdGhlIGluY3JlbWVudGFsIG1pZ3JhdGlvbiBmZWF0dXJlLiAqLwogIGRpc3BsYXk6
+IG5vbmU7Cn0KCi50aXRsZS1iYXIgI21pZ3JhdGUtdW5pdC1zdGF0dXMtaWNvbiB7CiAgdmVydGljYWwt
+YWxpZ246IHRleHQtYm90dG9tOwp9CgouY29udGVudCB7CiAgZm9udC1mYW1pbHk6ICJSb2JvdG8gTW9u
+byIsbW9ub3NwYWNlOwogIHBvc2l0aW9uOiByZWxhdGl2ZTsKICB3aGl0ZS1zcGFjZTogcHJlOwp9Cgou
+Y29kZSB7CiAgcGFkZGluZzogMC41ZW07CiAgcG9zaXRpb246IGFic29sdXRlOwogIGxlZnQ6IDA7CiAg
+dG9wOiAwOwogIG1hcmdpbi1sZWZ0OiA1NnB4Owp9CgouY29kZSAud2VsY29tZSB7CiAgZm9udC1mYW1p
+bHk6ICJHb29nbGUgU2FucyIsIlJvYm90byIsc2Fucy1zZXJpZjsKICBmb250LXNpemU6IDE4cHg7CiAg
+bWFyZ2luLXJpZ2h0OiA2MnB4OwogIGNvbG9yOiAjNzc3Owp9CgouY29kZSAubmF2LWxpbmsgewogIGNv
+bG9yOiAjMTZhZGNhOwogIHRleHQtZGVjb3JhdGlvbi1saW5lOiBub25lOwp9CgouY29kZSAubmF2LWxp
+bms6dmlzaXRlZCB7CiAgY29sb3I6ICMxMzliYjU7IC8qICMxNmFkY2EgZGFya2VuZWQgMTAlICovCiAg
+dGV4dC1kZWNvcmF0aW9uLWxpbmU6IG5vbmU7Cn0KCi5jb2RlIC5uYXYtbGluazpob3ZlciB7CiAgdGV4
+dC1kZWNvcmF0aW9uLWxpbmU6IHVuZGVybGluZTsKICBmb250LXdlaWdodDogNjAwOwp9CgoucmVnaW9u
+cyB7CiAgcGFkZGluZzogMC41ZW07CiAgcG9zaXRpb246IGFic29sdXRlOwogIGxlZnQ6IDA7CiAgdG9w
+OiAwOwp9CgoucmVnaW9ucyB0YWJsZSB7CiAgYm9yZGVyLXNwYWNpbmc6IDA7CiAgZm9udC1zaXplOiBp
+bmhlcml0Owp9CgoucmVnaW9ucyB0ZCB7CiAgYm9yZGVyOiBub25lOwogIC8qIFRoZSBjb250ZW50IG9m
+IHRoZSByZWdpb25zIGlzIG5vdCB2aXNpYmxlOyB0aGUgdXNlciBpbnN0ZWFkIHdpbGwgc2VlIHRoZQog
+ICAqIGhpZ2hsaWdodGVkIGNvcHkgb2YgdGhlIGNvbnRlbnQuICovCiAgY29sb3I6IHJnYmEoMjU1LCAy
+NTUsIDI1NSwgMCk7CiAgcGFkZGluZzogMDsKICB3aGl0ZS1zcGFjZTogcHJlOwp9CgoucmVnaW9ucyB0
+ZDplbXB0eTphZnRlciB7CiAgY29udGVudDogIlwwMGEwIjsKfQoKLnJlZ2lvbnMgdHIuaGlnaGxpZ2h0
+IHRkOmxhc3QtY2hpbGQgewogIGJhY2tncm91bmQtY29sb3I6ICM0NDQ0NDQ7CiAgY29sb3I6IHdoaXRl
+Owp9CgoucmVnaW9ucyB0ZC5saW5lLW5vIHsKICBib3JkZXItcmlnaHQ6IHNvbGlkICMxMjIwMmYgMnB4
+OwogIGNvbG9yOiAjOTk5OTk5OwogIHBhZGRpbmctcmlnaHQ6IDRweDsKICB0ZXh0LWFsaWduOiByaWdo
+dDsKICB2aXNpYmlsaXR5OiB2aXNpYmxlOwogIHdpZHRoOiA1MHB4OwogIGRpc3BsYXk6IGlubGluZS1i
+bG9jazsKfQoKLnJlZ2lvbnMgdHIuaGlnaGxpZ2h0IHRkLmxpbmUtbm8gewogIGJvcmRlci1yaWdodDog
+c29saWQgI2NjYyAycHg7Cn0KCi5yZWdpb24gewogIGRpc3BsYXk6IGlubGluZS1ibG9jazsKICBwb3Np
+dGlvbjogcmVsYXRpdmU7CiAgdmlzaWJpbGl0eTogdmlzaWJsZTsKICB6LWluZGV4OiAyMDA7Cn0KCi5y
+ZWdpb24uYWRkZWQtcmVnaW9uIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMTc4YWZkOwogIGNvbG9yOiAj
+ZmZmOwp9CgoucmVnaW9uLnJlbW92ZWQtcmVnaW9uIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjRkE1NTdk
+OyAvKiAkZGFyay1waW5rICovCiAgY29sb3I6ICNmZmY7Cn0KCi5yZWdpb24uaW5mb3JtYXRpdmUtcmVn
+aW9uIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMjYzOTUyOwogIGNvbG9yOiAjZmZmOwogIGRpc3BsYXk6
+IGlubGluZS1ibG9jazsKICBoZWlnaHQ6IDE1cHg7CiAgcG9zaXRpb246IHJlbGF0aXZlOwp9CgoudGFy
+Z2V0IHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjNDQ0OwogIHBvc2l0aW9uOiByZWxhdGl2ZTsKICB2aXNp
+YmlsaXR5OiB2aXNpYmxlOwogIGZvbnQtd2VpZ2h0OiA2MDA7Cn0KCi5pbmZvLXBhbmVsIHsKICBmbGV4
+OiAxIDIwMHB4OwogIG1hcmdpbjogMDsKICBoZWlnaHQ6IDEwMCU7CiAgZGlzcGxheTogZmxleDsKICBm
+bGV4LWRpcmVjdGlvbjogY29sdW1uOwp9CgouaW5mby1wYW5lbCAuZWRpdC1wYW5lbCB7CiAgYmFja2dy
+b3VuZC1jb2xvcjogIzEyMjAyZjsKICBvdmVyZmxvdzogYXV0bzsKfQoKLmluZm8tcGFuZWwgLnBhbmVs
+LWNvbnRlbnQgewogIHBhZGRpbmc6IDdweDsKfQoKLmluZm8tcGFuZWwgLnBhbmVsLWNvbnRlbnQ+IDpm
+aXJzdC1jaGlsZCB7CiAgbWFyZ2luLXRvcDogMDsKfQoKLmluZm8tcGFuZWwgLm5vd3JhcCB7CiAgd2hp
+dGUtc3BhY2U6IG5vd3JhcDsKfQoKLmluZm8tcGFuZWwgdWwsCi5pbmZvLXBhbmVsIG9sIHsKICBwYWRk
+aW5nLWxlZnQ6IDIwcHg7Cn0KCi5pbmZvLXBhbmVsIGxpIHsKICBtYXJnaW46IDAgMCA1cHggMDsKfQoK
+LmluZm8tcGFuZWwgYSB7CiAgY29sb3I6ICMxMzliYjU7Cn0KCi5pbmZvLXBhbmVsIGE6aG92ZXIgewog
+IGNvbG9yOiAjMWVjN2U3OyAvKiAjMTM5YmI1IGxpZ2h0ZW5lZCAyMCUgKi8KfQoKLmluZm8tcGFuZWwg
+LmVkaXQtbGlzdCB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzEyMjAyZjsKICBvdmVyZmxvdzogYXV0bzsK
+fQoKLmVkaXQtcGFuZWwgewogIG1hcmdpbi10b3A6IDZweDsKICBmbGV4OiAxIDEwMHB4Owp9CgouZWRp
+dC1saXN0IHsKICBmbGV4OiAyIDEwMHB4Owp9CgouZWRpdC1saXN0IC5lZGl0IHsKICBtYXJnaW46IDNw
+eCAwOwp9CgouZWRpdC1saXN0IC5lZGl0LWxpbmsgewogIGN1cnNvcjogcG9pbnRlcjsKfQoKLnBvcHVw
+LXBhbmUgewogIGRpc3BsYXk6IG5vbmU7CiAgcG9zaXRpb246IGZpeGVkOwogIHRvcDogMTUwcHg7CiAg
+bGVmdDogMTUwcHg7CiAgcmlnaHQ6IDE1MHB4OwogIGJvdHRvbTogMTUwcHg7CiAgYm9yZGVyOiAxcHgg
+c29saWQgYmxhY2s7CiAgYm9yZGVyLXRvcDogMnB4IHNvbGlkIGJsYWNrOwogIGJvcmRlci1yYWRpdXM6
+IDdweDsKICBib3gtc2hhZG93OiAwcHggMHB4IDIwcHggMnB4ICNiNGJmY2IyMjsKICB6LWluZGV4OiA0
+MDA7CiAgYmFja2dyb3VuZDogIzJiMzAzNjsKICBwYWRkaW5nOiAyMHB4Owp9CgoucG9wdXAtcGFuZSAu
+Y2xvc2UgewogIHBvc2l0aW9uOiBhYnNvbHV0ZTsKICByaWdodDogMTBweDsKICB0b3A6IDEwcHg7CiAg
+Y3Vyc29yOiBwb2ludGVyOwogIHRleHQtc2hhZG93OiAxcHggMXB4IDJweCAjODg4OwogIGJveC1zaGFk
+b3c6IDFweCAxcHggMnB4ICMxMTE7Cn0KCi5wb3B1cC1wYW5lIGgyIHsKICBwYWRkaW5nOiAyMXB4Owog
+IGhlaWdodDogMTAlOwogIG1hcmdpbjogMHB4OwogIGJveC1zaXppbmc6IGJvcmRlci1ib3g7Cn0KCi5w
+b3B1cC1wYW5lIHAgewogIGhlaWdodDogMTAlOwogIGJveC1zaXppbmc6IGJvcmRlci1ib3g7CiAgcGFk
+ZGluZzogMHB4IDIwcHg7Cn0KCi5wb3B1cC1wYW5lIHByZSB7CiAgYmFja2dyb3VuZDogIzEyMjAyZjsK
+ICBwYWRkaW5nOiAyMHB4OwogIGJvdHRvbTogMHB4OwogIG92ZXJmbG93OiBhdXRvIHNjcm9sbDsKICBo
+ZWlnaHQ6IDY1JTsKICBtYXJnaW46IDBweDsKICBib3gtc2l6aW5nOiBib3JkZXItYm94Owp9CgoucG9w
+dXAtcGFuZSAuYnV0dG9uLmJvdHRvbSB7CiAgbWFyZ2luOiAyMHB4IDBweDsKICBkaXNwbGF5OiBibG9j
+azsKICB0ZXh0LWFsaWduOiBjZW50ZXI7Cn0KCi5yZXJ1bm5pbmctcGFuZSB7CiAgZGlzcGxheTogbm9u
+ZTsKfQoKYm9keS5yZXJ1bm5pbmcgLnJlcnVubmluZy1wYW5lIHsKICBkaXNwbGF5OiBibG9jazsKICBw
+b3NpdGlvbjogZml4ZWQ7CiAgdG9wOiAwcHg7CiAgYm90dG9tOiAwcHg7CiAgbGVmdDogMHB4OwogIHJp
+Z2h0OiAwcHg7CiAgYmFja2dyb3VuZC1jb2xvcjogIzAwMDAwMEFBOyAvKiB0cmFuc2x1Y2VudCBibGFj
+ayAqLwogIHotaW5kZXg6IDQwMDsKfQoKLnJlcnVubmluZy1wYW5lIGgxIHsKICBwb3NpdGlvbjogYWJz
+b2x1dGU7CiAgdG9wOiA1MCU7CiAgbGVmdDogNTAlOwogIHRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUs
+IC01MCUpOwp9CgouZWRpdC1wYW5lbCAudHlwZS1kZXNjcmlwdGlvbiB7CiAgLyogRnJvbSBEYXJ0UGFk
+ICRkYXJrLW9yYW5nZSAqLwogIGNvbG9yOiAjZmY5MTZlOwogIGZvbnQtZmFtaWx5OiBtb25vc3BhY2U7
+Cn0KCnVsLnRyYWNlIHsKICBmb250LXNpemU6IDEzcHg7CiAgbGlzdC1zdHlsZS10eXBlOiBub25lOwog
+IHBhZGRpbmctbGVmdDogMHB4Owp9Cgp1bC50cmFjZSBsaSB7CiAgY29sb3I6IHdoaXRlOwp9Cgp1bC50
+cmFjZSBsaSAuZnVuY3Rpb24gewogIC8qIGZyb20gLmhsanMtdmFyaWFibGUgKi8KICBjb2xvcjogIzE2
+YWRjYTsKICBmb250LWZhbWlseTogbW9ub3NwYWNlOwogIGZvbnQtd2VpZ2h0OiA2MDA7Cn0KCnVsLnRy
+YWNlIGxpIHAuZHJhd2VyIHsKICBtYXJnaW46IDNweCAwcHg7CiAgcGFkZGluZzogMHB4IDBweCAwcHgg
+MTRweDsKfQoKdWwudHJhY2UgbGkgcC5kcmF3ZXIgYnV0dG9uIHsKICBtYXJnaW4tcmlnaHQ6IDNweDsK
+fQoKLmVsZXZhdGlvbi16NCB7CiAgYm94LXNoYWRvdzogMHB4IDJweCA0cHggLTFweCByZ2JhKDAsIDAs
+IDAsIDAuMiksCiAgICAgIDBweCA0cHggNXB4IDBweCByZ2JhKDAsIDAsIDAsIDAuMTQpLAogICAgICAw
+cHggMXB4IDEwcHggMHB4IHJnYmEoMCwgMCwgMCwgLjEyKTsKfQoKYSB7CiAgY29sb3I6ICNjY2M7CiAg
+ZmlsbDogI2NjYzsKICB0ZXh0LWRlY29yYXRpb246IG5vbmU7Cn0KCmE6aG92ZXIgewogIGNvbG9yOiAj
+ZGJkYmRiOyAvKiAjY2NjIGxpZ2h0ZW50ZWQgMzAlKi8KICBmaWxsOiAjZmZmOwp9CgouYWRkLWhpbnQt
+bGluayB7CiAgZGlzcGxheTogaW5saW5lLWJsb2NrOwogIG1hcmdpbjogM3B4Owp9CgouYWRkLWhpbnQt
+bGluazpob3ZlciB7CiAgY29sb3I6ICNmZmY7Cn0KCmhlYWRlciBidXR0b24gewogIHRleHQtdHJhbnNm
+b3JtOiB1cHBlcmNhc2U7Cn0KCmhlYWRlciBhIHsKICBtYXJnaW46IDA7Cn0KCi8qIENhcmVmdWwgaGVy
+ZS4gYGEuYnV0dG9uYCBpcyByZXBldGl0aXZlIGJ1dCByZXF1aXJlZCB0byBnZXQgY29ycmVjdAogKiBz
+cGVjaWZpY2l0eSAqLwpidXR0b24sIC5idXR0b24sIGEuYnV0dG9uIHsKICBiYWNrZ3JvdW5kLWNvbG9y
+OiByZ2JhKDIyLCAxMzgsIDI1MywgMC4xNSk7CiAgYm9yZGVyOiBub25lOwogIGJvcmRlci1yYWRpdXM6
+IDNweDsKICBwYWRkaW5nOiAzcHggMTBweDsKICBmb250LXdlaWdodDogNTAwOwogIGZvbnQtZm9udDog
+Um9ib3RvLCBzYW5zLXNlcmlmOwogIGNvbG9yOiAjZmZmOwp9CgpidXR0b246aG92ZXIsIC5idXR0b246
+aG92ZXIgewogIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMjIsIDEzOCwgMjUzLCAwLjI5KTsKICBjdXJz
+b3I6IHBvaW50ZXI7Cn0KCmJ1dHRvbltkaXNhYmxlZF0gewogIGJhY2tncm91bmQtY29sb3I6IHJnYmEo
+MjU1LDI1NSwyNTUsLjEyKTsKICBjb2xvcjogcmdiYSgyNTUsMjU1LDI1NSwuMzcpOwogIGN1cnNvcjog
+bm90LWFsbG93ZWQ7Cn0KCi8qIENoYW5nZSBlZGl0IHBhbmVsIGJ1dHRvbiBjb2xvcnMgKi8KLmVkaXQt
+cGFuZWwgLmJ1dHRvbiwgLmVkaXQtcGFuZWwgYnV0dG9uIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2Jh
+KDYzLCAxMDQsIDE0OCwgMC42KTsKICBjb2xvcjogd2hpdGU7Cn0KLmVkaXQtcGFuZWwgLmJ1dHRvbjpo
+b3ZlciwgLmVkaXQtcGFuZWwgYnV0dG9uOmhvdmVyIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDEw
+MSwgMTUzLCAyMDgsIDAuNik7CiAgY29sb3I6IHdoaXRlOwp9CgovKgogKiBBZGp1c3RtZW50cyB0byBh
+bGlnbiBtYXRlcmlhbCBpY29ucyBpbiB0aGUgdG9vbGJhciBidXR0b25zLgoqLwouYWN0aW9uLWJ1dHRv
+biA+IHNwYW4gewogIHBvc2l0aW9uOiByZWxhdGl2ZTsKICB0b3A6IC0zcHg7Cn0KCi5hY3Rpb24tYnV0
+dG9uIC5tYXRlcmlhbC1pY29ucyB7CiAgdG9wOiA0cHg7Cn0KCi8qIERvbid0IHNoaWZ0IHRoZSBpY29u
+IHdoZW4gaXQncyBhIGRpcmVjdCBjaGlsZCBvZiB0aGUgYnV0dG9uICovCi5hY3Rpb24tYnV0dG9uID4g
+Lm1hdGVyaWFsLWljb25zIHsKICB0b3A6IDFweDsKfQoKLyogU2hpZnQgdGhlIHRleHQgdG8gY2VudGVy
+IHdpdGggdGhlIGljb24uICovCi5hY3Rpb24tYnV0dG9uID4gc3Bhbi5sYWJlbCB7CiAgcG9zaXRpb246
+cmVsYXRpdmU7CiAgdG9wOiAtNHB4Owp9CgouYWN0aW9uLWJ1dHRvbiAubWF0ZXJpYWwtaWNvbnMgewog
+IGZvbnQtc2l6ZTogMjBweDsKICBwb3NpdGlvbjogcmVsYXRpdmU7Cn0KCi5wbGFjZWhvbGRlciB7CiAg
+Y29sb3I6ICM3Nzc7CiAgdGV4dC1hbGlnbjogY2VudGVyOwogIG1hcmdpbi10b3A6IDNlbSAhaW1wb3J0
+YW50Owp9CgovKioKICogSExKUyBPdmVycmlkZXMKICovCi5obGpzIHsKICBiYWNrZ3JvdW5kLWNvbG9y
+OiAjMTIyMDJmOyAvKiAkZGFyay1jb2RlLWJhY2tncm91bmQtY29sb3IgKi8KICBjb2xvcjogI2MwYzJj
+NTsgLyogJGRhcmstZWRpdG9yLXRleHQgKi8KICBkaXNwbGF5OiBibG9jazsKICBvdmVyZmxvdy14OiBh
+dXRvOwogIHBhZGRpbmc6IDAuNWVtOwogIC8qKgogICAqIFRoaXMgYWxsb3dzIHRoZSBwZXItbGluZSBo
+aWdobGlnaHRzIHRvIHNob3cuCiAgICovCiAgYmFja2dyb3VuZDogbm9uZTsKfQoKLmhsanMta2V5d29y
+ZCwKLmhsanMtc2VsZWN0b3ItdGFnLAouaGxqcy1kZWxldGlvbiB7CiAgY29sb3I6ICM1MWM2ODY7IC8q
+IGNtLWtleXdvcmQgKi8KfQoKLmhsanMtbnVtYmVyIHsKICBjb2xvcjogIzYyNzk3ODsgLyogY20tbnVt
+YmVyICovCn0KCi5obGpzLWNvbW1lbnQgewogIGNvbG9yOiAjOTE5OGI0OyAvKiBjbS1jb21tZW50ICov
+Cn0KCi5obGpzLWxpdGVyYWwgewogIGNvbG9yOiAjZWU4NjY2OyAvKiBjbS1hdG9tICovCn0KCi5obGpz
+LXN0cmluZyB7CiAgY29sb3I6ICNlNTUwNzQ7IC8qIGNtLXN0cmluZyAqLwp9CgouaGxqcy12YXJpYWJs
+ZSB7CiAgY29sb3I6ICMxNmFkY2E7IC8qIGNtLXZhcmlhYmxlICovCn0KCi5obGpzLWxpbmsgewogIGNv
+bG9yOiAjZTU1MDc0OyAvKiBjbS1zdHJpbmcgKi8KfQouaGxqcy1zZWN0aW9uLAouaGxqcy10eXBlLAou
+aGxqcy1idWlsdF9pbiwKLmhsanMtdGl0bGUgewogIGNvbG9yOiAjZWU4NjY2OyAvKiBjbS12YXJpYWJs
+ZS0yICovCn0KCi5obGpzLWFkZGl0aW9uIHsKICBjb2xvcjogIzI2Mzk1MjsgLyogJGRhcmstc2VsZWN0
+aW9uLWNvbG9yICovCn0KCi5obGpzLW1ldGEgewogIGNvbG9yOiAjNjI3OTc4Owp9Cg==
''';
String _migration_js;
-// migration_dart md5 is 'd3aab70422b08e7815a20fda6689a30f'
+// migration_dart md5 is 'fd54888536280a9cc3c222ccaf1597fa'
String _migration_js_base64 = '''
KGZ1bmN0aW9uIGRhcnRQcm9ncmFtKCl7ZnVuY3Rpb24gY29weVByb3BlcnRpZXMoYSxiKXt2YXIgcz1P
YmplY3Qua2V5cyhhKQpmb3IodmFyIHI9MDtyPHMubGVuZ3RoO3IrKyl7dmFyIHE9c1tyXQpiW3FdPWFb
@@ -7946,2807 +7959,2830 @@
OmZ1bmN0aW9uKGEpe3ZhciBzCmlmKGEgaW5zdGFuY2VvZiBILmJxKXJldHVybiBhLmIKaWYoYT09bnVs
bClyZXR1cm4gbmV3IEguWE8oYSkKcz1hLiRjYWNoZWRUcmFjZQppZihzIT1udWxsKXJldHVybiBzCnJl
dHVybiBhLiRjYWNoZWRUcmFjZT1uZXcgSC5YTyhhKX0sCkI3OmZ1bmN0aW9uKGEsYil7dmFyIHMscixx
-LHA9YS5sZW5ndGgKZm9yKHM9MDtzPHA7cz1xKXtyPXMrMQpxPXIrMQpiLlkoMCxhW3NdLGFbcl0pfXJl
-dHVybiBifSwKZnQ6ZnVuY3Rpb24oYSxiLGMsZCxlLGYpe3QuWS5hKGEpCnN3aXRjaChILnVQKGIpKXtj
-YXNlIDA6cmV0dXJuIGEuJDAoKQpjYXNlIDE6cmV0dXJuIGEuJDEoYykKY2FzZSAyOnJldHVybiBhLiQy
-KGMsZCkKY2FzZSAzOnJldHVybiBhLiQzKGMsZCxlKQpjYXNlIDQ6cmV0dXJuIGEuJDQoYyxkLGUsZil9
-dGhyb3cgSC5iKG5ldyBQLkNEKCJVbnN1cHBvcnRlZCBudW1iZXIgb2YgYXJndW1lbnRzIGZvciB3cmFw
-cGVkIGNsb3N1cmUiKSl9LAp0UjpmdW5jdGlvbihhLGIpe3ZhciBzCmlmKGE9PW51bGwpcmV0dXJuIG51
-bGwKcz1hLiRpZGVudGl0eQppZighIXMpcmV0dXJuIHMKcz1mdW5jdGlvbihjLGQsZSl7cmV0dXJuIGZ1
-bmN0aW9uKGYsZyxoLGkpe3JldHVybiBlKGMsZCxmLGcsaCxpKX19KGEsYixILmZ0KQphLiRpZGVudGl0
-eT1zCnJldHVybiBzfSwKaUE6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIHMscixxLHAsbyxuLG0s
-bD1iWzBdLGs9bC4kY2FsbE5hbWUsaj1lP09iamVjdC5jcmVhdGUobmV3IEguengoKS5jb25zdHJ1Y3Rv
-ci5wcm90b3R5cGUpOk9iamVjdC5jcmVhdGUobmV3IEguclQobnVsbCxudWxsLG51bGwsIiIpLmNvbnN0
-cnVjdG9yLnByb3RvdHlwZSkKai4kaW5pdGlhbGl6ZT1qLmNvbnN0cnVjdG9yCmlmKGUpcz1mdW5jdGlv
-biBzdGF0aWNfdGVhcl9vZmYoKXt0aGlzLiRpbml0aWFsaXplKCl9CmVsc2V7cj0kLnlqCmlmKHR5cGVv
-ZiByIT09Im51bWJlciIpcmV0dXJuIHIuaCgpCiQueWo9cisxCnI9bmV3IEZ1bmN0aW9uKCJhLGIsYyxk
-IityLCJ0aGlzLiRpbml0aWFsaXplKGEsYixjLGQiK3IrIikiKQpzPXJ9ai5jb25zdHJ1Y3Rvcj1zCnMu
-cHJvdG90eXBlPWoKaWYoIWUpe3E9SC5ieChhLGwsZikKcS4kcmVmbGVjdGlvbkluZm89ZH1lbHNle2ou
-JHN0YXRpY19uYW1lPWcKcT1sfWouJFM9SC5pbShkLGUsZikKaltrXT1xCmZvcihwPXEsbz0xO288Yi5s
-ZW5ndGg7KytvKXtuPWJbb10KbT1uLiRjYWxsTmFtZQppZihtIT1udWxsKXtuPWU/bjpILmJ4KGEsbixm
-KQpqW21dPW59aWYobz09PWMpe24uJHJlZmxlY3Rpb25JbmZvPWQKcD1ufX1qLiRDPXAKai4kUj1sLiRS
-CmouJEQ9bC4kRApyZXR1cm4gc30sCmltOmZ1bmN0aW9uKGEsYixjKXt2YXIgcwppZih0eXBlb2YgYT09
-Im51bWJlciIpcmV0dXJuIGZ1bmN0aW9uKGQsZSl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGQoZSl9
-fShILkJwLGEpCmlmKHR5cGVvZiBhPT0ic3RyaW5nIil7aWYoYil0aHJvdyBILmIoIkNhbm5vdCBjb21w
-dXRlIHNpZ25hdHVyZSBmb3Igc3RhdGljIHRlYXJvZmYuIikKcz1jP0guUFc6SC5UbgpyZXR1cm4gZnVu
-Y3Rpb24oZCxlKXtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gZSh0aGlzLGQpfX0oYSxzKX10aHJvdyBI
-LmIoIkVycm9yIGluIGZ1bmN0aW9uVHlwZSBvZiB0ZWFyb2ZmIil9LAp2cTpmdW5jdGlvbihhLGIsYyxk
-KXt2YXIgcz1ILkRWCnN3aXRjaChiPy0xOmEpe2Nhc2UgMDpyZXR1cm4gZnVuY3Rpb24oZSxmKXtyZXR1
-cm4gZnVuY3Rpb24oKXtyZXR1cm4gZih0aGlzKVtlXSgpfX0oYyxzKQpjYXNlIDE6cmV0dXJuIGZ1bmN0
-aW9uKGUsZil7cmV0dXJuIGZ1bmN0aW9uKGcpe3JldHVybiBmKHRoaXMpW2VdKGcpfX0oYyxzKQpjYXNl
-IDI6cmV0dXJuIGZ1bmN0aW9uKGUsZil7cmV0dXJuIGZ1bmN0aW9uKGcsaCl7cmV0dXJuIGYodGhpcylb
-ZV0oZyxoKX19KGMscykKY2FzZSAzOnJldHVybiBmdW5jdGlvbihlLGYpe3JldHVybiBmdW5jdGlvbihn
-LGgsaSl7cmV0dXJuIGYodGhpcylbZV0oZyxoLGkpfX0oYyxzKQpjYXNlIDQ6cmV0dXJuIGZ1bmN0aW9u
-KGUsZil7cmV0dXJuIGZ1bmN0aW9uKGcsaCxpLGope3JldHVybiBmKHRoaXMpW2VdKGcsaCxpLGopfX0o
-YyxzKQpjYXNlIDU6cmV0dXJuIGZ1bmN0aW9uKGUsZil7cmV0dXJuIGZ1bmN0aW9uKGcsaCxpLGosayl7
-cmV0dXJuIGYodGhpcylbZV0oZyxoLGksaixrKX19KGMscykKZGVmYXVsdDpyZXR1cm4gZnVuY3Rpb24o
-ZSxmKXtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gZS5hcHBseShmKHRoaXMpLGFyZ3VtZW50cyl9fShk
-LHMpfX0sCmJ4OmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscCxvLG4sbQppZihjKXJldHVybiBILkhm
-KGEsYikKcz1iLiRzdHViTmFtZQpyPWIubGVuZ3RoCnE9YVtzXQpwPWI9PW51bGw/cT09bnVsbDpiPT09
-cQpvPSFwfHxyPj0yNwppZihvKXJldHVybiBILnZxKHIsIXAscyxiKQppZihyPT09MCl7cD0kLnlqCmlm
-KHR5cGVvZiBwIT09Im51bWJlciIpcmV0dXJuIHAuaCgpCiQueWo9cCsxCm49InNlbGYiK3AKcmV0dXJu
-IG5ldyBGdW5jdGlvbigicmV0dXJuIGZ1bmN0aW9uKCl7dmFyICIrbisiID0gdGhpcy4iK0guRWooSC5v
-TigpKSsiO3JldHVybiAiK24rIi4iK0guRWoocykrIigpO30iKSgpfW09ImFiY2RlZmdoaWprbG1ub3Bx
-cnN0dXZ3eHl6Ii5zcGxpdCgiIikuc3BsaWNlKDAscikuam9pbigiLCIpCnA9JC55agppZih0eXBlb2Yg
-cCE9PSJudW1iZXIiKXJldHVybiBwLmgoKQokLnlqPXArMQptKz1wCnJldHVybiBuZXcgRnVuY3Rpb24o
-InJldHVybiBmdW5jdGlvbigiK20rIil7cmV0dXJuIHRoaXMuIitILkVqKEgub04oKSkrIi4iK0guRWoo
-cykrIigiK20rIik7fSIpKCl9LApaNDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcz1ILkRWLHI9SC55Uwpz
-d2l0Y2goYj8tMTphKXtjYXNlIDA6dGhyb3cgSC5iKG5ldyBILkVxKCJJbnRlcmNlcHRlZCBmdW5jdGlv
-biB3aXRoIG5vIGFyZ3VtZW50cy4iKSkKY2FzZSAxOnJldHVybiBmdW5jdGlvbihlLGYsZyl7cmV0dXJu
-IGZ1bmN0aW9uKCl7cmV0dXJuIGYodGhpcylbZV0oZyh0aGlzKSl9fShjLHMscikKY2FzZSAyOnJldHVy
-biBmdW5jdGlvbihlLGYsZyl7cmV0dXJuIGZ1bmN0aW9uKGgpe3JldHVybiBmKHRoaXMpW2VdKGcodGhp
-cyksaCl9fShjLHMscikKY2FzZSAzOnJldHVybiBmdW5jdGlvbihlLGYsZyl7cmV0dXJuIGZ1bmN0aW9u
-KGgsaSl7cmV0dXJuIGYodGhpcylbZV0oZyh0aGlzKSxoLGkpfX0oYyxzLHIpCmNhc2UgNDpyZXR1cm4g
-ZnVuY3Rpb24oZSxmLGcpe3JldHVybiBmdW5jdGlvbihoLGksail7cmV0dXJuIGYodGhpcylbZV0oZyh0
-aGlzKSxoLGksail9fShjLHMscikKY2FzZSA1OnJldHVybiBmdW5jdGlvbihlLGYsZyl7cmV0dXJuIGZ1
-bmN0aW9uKGgsaSxqLGspe3JldHVybiBmKHRoaXMpW2VdKGcodGhpcyksaCxpLGosayl9fShjLHMscikK
-Y2FzZSA2OnJldHVybiBmdW5jdGlvbihlLGYsZyl7cmV0dXJuIGZ1bmN0aW9uKGgsaSxqLGssbCl7cmV0
-dXJuIGYodGhpcylbZV0oZyh0aGlzKSxoLGksaixrLGwpfX0oYyxzLHIpCmRlZmF1bHQ6cmV0dXJuIGZ1
-bmN0aW9uKGUsZixnLGgpe3JldHVybiBmdW5jdGlvbigpe2g9W2codGhpcyldCkFycmF5LnByb3RvdHlw
-ZS5wdXNoLmFwcGx5KGgsYXJndW1lbnRzKQpyZXR1cm4gZS5hcHBseShmKHRoaXMpLGgpfX0oZCxzLHIp
-fX0sCkhmOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbyxuLG09SC5vTigpLGw9JC5QNAppZihsPT1u
-dWxsKWw9JC5QND1ILkUyKCJyZWNlaXZlciIpCnM9Yi4kc3R1Yk5hbWUKcj1iLmxlbmd0aApxPWFbc10K
-cD1iPT1udWxsP3E9PW51bGw6Yj09PXEKbz0hcHx8cj49MjgKaWYobylyZXR1cm4gSC5aNChyLCFwLHMs
-YikKaWYocj09PTEpe3A9InJldHVybiBmdW5jdGlvbigpe3JldHVybiB0aGlzLiIrSC5FaihtKSsiLiIr
-SC5FaihzKSsiKHRoaXMuIitsKyIpOyIKbz0kLnlqCmlmKHR5cGVvZiBvIT09Im51bWJlciIpcmV0dXJu
-IG8uaCgpCiQueWo9bysxCnJldHVybiBuZXcgRnVuY3Rpb24ocCtvKyJ9IikoKX1uPSJhYmNkZWZnaGlq
-a2xtbm9wcXJzdHV2d3h5eiIuc3BsaXQoIiIpLnNwbGljZSgwLHItMSkuam9pbigiLCIpCnA9InJldHVy
-biBmdW5jdGlvbigiK24rIil7cmV0dXJuIHRoaXMuIitILkVqKG0pKyIuIitILkVqKHMpKyIodGhpcy4i
-K2wrIiwgIituKyIpOyIKbz0kLnlqCmlmKHR5cGVvZiBvIT09Im51bWJlciIpcmV0dXJuIG8uaCgpCiQu
-eWo9bysxCnJldHVybiBuZXcgRnVuY3Rpb24ocCtvKyJ9IikoKX0sCktxOmZ1bmN0aW9uKGEsYixjLGQs
-ZSxmLGcpe3JldHVybiBILmlBKGEsYixjLGQsISFlLCEhZixnKX0sClRuOmZ1bmN0aW9uKGEsYil7cmV0
-dXJuIEguY0Uodi50eXBlVW5pdmVyc2UsSC56KGEuYSksYil9LApQVzpmdW5jdGlvbihhLGIpe3JldHVy
-biBILmNFKHYudHlwZVVuaXZlcnNlLEgueihhLmMpLGIpfSwKRFY6ZnVuY3Rpb24oYSl7cmV0dXJuIGEu
-YX0sCnlTOmZ1bmN0aW9uKGEpe3JldHVybiBhLmN9LApvTjpmdW5jdGlvbigpe3ZhciBzPSQubUoKcmV0
-dXJuIHM9PW51bGw/JC5tSj1ILkUyKCJzZWxmIik6c30sCkUyOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxw
-PW5ldyBILnJUKCJzZWxmIiwidGFyZ2V0IiwicmVjZWl2ZXIiLCJuYW1lIiksbz1KLkVwKE9iamVjdC5n
-ZXRPd25Qcm9wZXJ0eU5hbWVzKHApLHQuVykKZm9yKHM9by5sZW5ndGgscj0wO3I8czsrK3Ipe3E9b1ty
-XQppZihwW3FdPT09YSlyZXR1cm4gcX10aHJvdyBILmIoUC54WSgiRmllbGQgbmFtZSAiK2ErIiBub3Qg
-Zm91bmQuIikpfSwKb1Q6ZnVuY3Rpb24oYSl7aWYoYT09bnVsbClILmZPKCJib29sZWFuIGV4cHJlc3Np
-b24gbXVzdCBub3QgYmUgbnVsbCIpCnJldHVybiBhfSwKZk86ZnVuY3Rpb24oYSl7dGhyb3cgSC5iKG5l
-dyBILmtZKGEpKX0sCmFnOmZ1bmN0aW9uKGEpe3Rocm93IEguYihuZXcgUC5jKGEpKX0sCllnOmZ1bmN0
-aW9uKGEpe3JldHVybiB2LmdldElzb2xhdGVUYWcoYSl9LApCbzpmdW5jdGlvbihhKXtyZXR1cm4gSC52
-KG5ldyBILm4oYSkpfSwKaXc6ZnVuY3Rpb24oYSxiLGMpe09iamVjdC5kZWZpbmVQcm9wZXJ0eShhLGIs
-e3ZhbHVlOmMsZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVlfSl9
-LAp3MzpmdW5jdGlvbihhKXt2YXIgcyxyLHEscCxvLG49SC5oKCQuTkYuJDEoYSkpLG09JC5ud1tuXQpp
+LHA9YS5sZW5ndGgKZm9yKHM9MDtzPHA7cz1xKXtyPXMrMQpxPXIrMQpiLlk1KDAsYVtzXSxhW3JdKX1y
+ZXR1cm4gYn0sCmZ0OmZ1bmN0aW9uKGEsYixjLGQsZSxmKXt0LlkuYShhKQpzd2l0Y2goSC51UChiKSl7
+Y2FzZSAwOnJldHVybiBhLiQwKCkKY2FzZSAxOnJldHVybiBhLiQxKGMpCmNhc2UgMjpyZXR1cm4gYS4k
+MihjLGQpCmNhc2UgMzpyZXR1cm4gYS4kMyhjLGQsZSkKY2FzZSA0OnJldHVybiBhLiQ0KGMsZCxlLGYp
+fXRocm93IEguYihuZXcgUC5DRCgiVW5zdXBwb3J0ZWQgbnVtYmVyIG9mIGFyZ3VtZW50cyBmb3Igd3Jh
+cHBlZCBjbG9zdXJlIikpfSwKdFI6ZnVuY3Rpb24oYSxiKXt2YXIgcwppZihhPT1udWxsKXJldHVybiBu
+dWxsCnM9YS4kaWRlbnRpdHkKaWYoISFzKXJldHVybiBzCnM9ZnVuY3Rpb24oYyxkLGUpe3JldHVybiBm
+dW5jdGlvbihmLGcsaCxpKXtyZXR1cm4gZShjLGQsZixnLGgsaSl9fShhLGIsSC5mdCkKYS4kaWRlbnRp
+dHk9cwpyZXR1cm4gc30sCmlBOmZ1bmN0aW9uKGEsYixjLGQsZSxmLGcpe3ZhciBzLHIscSxwLG8sbixt
+LGw9YlswXSxrPWwuJGNhbGxOYW1lLGo9ZT9PYmplY3QuY3JlYXRlKG5ldyBILnp4KCkuY29uc3RydWN0
+b3IucHJvdG90eXBlKTpPYmplY3QuY3JlYXRlKG5ldyBILnJUKG51bGwsbnVsbCxudWxsLCIiKS5jb25z
+dHJ1Y3Rvci5wcm90b3R5cGUpCmouJGluaXRpYWxpemU9ai5jb25zdHJ1Y3RvcgppZihlKXM9ZnVuY3Rp
+b24gc3RhdGljX3RlYXJfb2ZmKCl7dGhpcy4kaW5pdGlhbGl6ZSgpfQplbHNle3I9JC55agppZih0eXBl
+b2YgciE9PSJudW1iZXIiKXJldHVybiByLmgoKQokLnlqPXIrMQpyPW5ldyBGdW5jdGlvbigiYSxiLGMs
+ZCIrciwidGhpcy4kaW5pdGlhbGl6ZShhLGIsYyxkIityKyIpIikKcz1yfWouY29uc3RydWN0b3I9cwpz
+LnByb3RvdHlwZT1qCmlmKCFlKXtxPUguYngoYSxsLGYpCnEuJHJlZmxlY3Rpb25JbmZvPWR9ZWxzZXtq
+LiRzdGF0aWNfbmFtZT1nCnE9bH1qLiRTPUguaW0oZCxlLGYpCmpba109cQpmb3IocD1xLG89MTtvPGIu
+bGVuZ3RoOysrbyl7bj1iW29dCm09bi4kY2FsbE5hbWUKaWYobSE9bnVsbCl7bj1lP246SC5ieChhLG4s
+ZikKalttXT1ufWlmKG89PT1jKXtuLiRyZWZsZWN0aW9uSW5mbz1kCnA9bn19ai4kQz1wCmouJFI9bC4k
+UgpqLiREPWwuJEQKcmV0dXJuIHN9LAppbTpmdW5jdGlvbihhLGIsYyl7dmFyIHMKaWYodHlwZW9mIGE9
+PSJudW1iZXIiKXJldHVybiBmdW5jdGlvbihkLGUpe3JldHVybiBmdW5jdGlvbigpe3JldHVybiBkKGUp
+fX0oSC5CcCxhKQppZih0eXBlb2YgYT09InN0cmluZyIpe2lmKGIpdGhyb3cgSC5iKCJDYW5ub3QgY29t
+cHV0ZSBzaWduYXR1cmUgZm9yIHN0YXRpYyB0ZWFyb2ZmLiIpCnM9Yz9ILlBXOkguVG4KcmV0dXJuIGZ1
+bmN0aW9uKGQsZSl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGUodGhpcyxkKX19KGEscyl9dGhyb3cg
+SC5iKCJFcnJvciBpbiBmdW5jdGlvblR5cGUgb2YgdGVhcm9mZiIpfSwKdnE6ZnVuY3Rpb24oYSxiLGMs
+ZCl7dmFyIHM9SC5EVgpzd2l0Y2goYj8tMTphKXtjYXNlIDA6cmV0dXJuIGZ1bmN0aW9uKGUsZil7cmV0
+dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGYodGhpcylbZV0oKX19KGMscykKY2FzZSAxOnJldHVybiBmdW5j
+dGlvbihlLGYpe3JldHVybiBmdW5jdGlvbihnKXtyZXR1cm4gZih0aGlzKVtlXShnKX19KGMscykKY2Fz
+ZSAyOnJldHVybiBmdW5jdGlvbihlLGYpe3JldHVybiBmdW5jdGlvbihnLGgpe3JldHVybiBmKHRoaXMp
+W2VdKGcsaCl9fShjLHMpCmNhc2UgMzpyZXR1cm4gZnVuY3Rpb24oZSxmKXtyZXR1cm4gZnVuY3Rpb24o
+ZyxoLGkpe3JldHVybiBmKHRoaXMpW2VdKGcsaCxpKX19KGMscykKY2FzZSA0OnJldHVybiBmdW5jdGlv
+bihlLGYpe3JldHVybiBmdW5jdGlvbihnLGgsaSxqKXtyZXR1cm4gZih0aGlzKVtlXShnLGgsaSxqKX19
+KGMscykKY2FzZSA1OnJldHVybiBmdW5jdGlvbihlLGYpe3JldHVybiBmdW5jdGlvbihnLGgsaSxqLGsp
+e3JldHVybiBmKHRoaXMpW2VdKGcsaCxpLGosayl9fShjLHMpCmRlZmF1bHQ6cmV0dXJuIGZ1bmN0aW9u
+KGUsZil7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGUuYXBwbHkoZih0aGlzKSxhcmd1bWVudHMpfX0o
+ZCxzKX19LApieDpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHAsbyxuLG0KaWYoYylyZXR1cm4gSC5I
+ZihhLGIpCnM9Yi4kc3R1Yk5hbWUKcj1iLmxlbmd0aApxPWFbc10KcD1iPT1udWxsP3E9PW51bGw6Yj09
+PXEKbz0hcHx8cj49MjcKaWYobylyZXR1cm4gSC52cShyLCFwLHMsYikKaWYocj09PTApe3A9JC55agpp
+Zih0eXBlb2YgcCE9PSJudW1iZXIiKXJldHVybiBwLmgoKQokLnlqPXArMQpuPSJzZWxmIitwCnJldHVy
+biBuZXcgRnVuY3Rpb24oInJldHVybiBmdW5jdGlvbigpe3ZhciAiK24rIiA9IHRoaXMuIitILkVqKEgu
+b04oKSkrIjtyZXR1cm4gIituKyIuIitILkVqKHMpKyIoKTt9IikoKX1tPSJhYmNkZWZnaGlqa2xtbm9w
+cXJzdHV2d3h5eiIuc3BsaXQoIiIpLnNwbGljZSgwLHIpLmpvaW4oIiwiKQpwPSQueWoKaWYodHlwZW9m
+IHAhPT0ibnVtYmVyIilyZXR1cm4gcC5oKCkKJC55aj1wKzEKbSs9cApyZXR1cm4gbmV3IEZ1bmN0aW9u
+KCJyZXR1cm4gZnVuY3Rpb24oIittKyIpe3JldHVybiB0aGlzLiIrSC5FaihILm9OKCkpKyIuIitILkVq
+KHMpKyIoIittKyIpO30iKSgpfSwKWjQ6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHM9SC5EVixyPUgueVMK
+c3dpdGNoKGI/LTE6YSl7Y2FzZSAwOnRocm93IEguYihuZXcgSC5FcSgiSW50ZXJjZXB0ZWQgZnVuY3Rp
+b24gd2l0aCBubyBhcmd1bWVudHMuIikpCmNhc2UgMTpyZXR1cm4gZnVuY3Rpb24oZSxmLGcpe3JldHVy
+biBmdW5jdGlvbigpe3JldHVybiBmKHRoaXMpW2VdKGcodGhpcykpfX0oYyxzLHIpCmNhc2UgMjpyZXR1
+cm4gZnVuY3Rpb24oZSxmLGcpe3JldHVybiBmdW5jdGlvbihoKXtyZXR1cm4gZih0aGlzKVtlXShnKHRo
+aXMpLGgpfX0oYyxzLHIpCmNhc2UgMzpyZXR1cm4gZnVuY3Rpb24oZSxmLGcpe3JldHVybiBmdW5jdGlv
+bihoLGkpe3JldHVybiBmKHRoaXMpW2VdKGcodGhpcyksaCxpKX19KGMscyxyKQpjYXNlIDQ6cmV0dXJu
+IGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4gZnVuY3Rpb24oaCxpLGope3JldHVybiBmKHRoaXMpW2VdKGco
+dGhpcyksaCxpLGopfX0oYyxzLHIpCmNhc2UgNTpyZXR1cm4gZnVuY3Rpb24oZSxmLGcpe3JldHVybiBm
+dW5jdGlvbihoLGksaixrKXtyZXR1cm4gZih0aGlzKVtlXShnKHRoaXMpLGgsaSxqLGspfX0oYyxzLHIp
+CmNhc2UgNjpyZXR1cm4gZnVuY3Rpb24oZSxmLGcpe3JldHVybiBmdW5jdGlvbihoLGksaixrLGwpe3Jl
+dHVybiBmKHRoaXMpW2VdKGcodGhpcyksaCxpLGosayxsKX19KGMscyxyKQpkZWZhdWx0OnJldHVybiBm
+dW5jdGlvbihlLGYsZyxoKXtyZXR1cm4gZnVuY3Rpb24oKXtoPVtnKHRoaXMpXQpBcnJheS5wcm90b3R5
+cGUucHVzaC5hcHBseShoLGFyZ3VtZW50cykKcmV0dXJuIGUuYXBwbHkoZih0aGlzKSxoKX19KGQscyxy
+KX19LApIZjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixtPUgub04oKSxsPSQuUDQKaWYobD09
+bnVsbClsPSQuUDQ9SC5FMigicmVjZWl2ZXIiKQpzPWIuJHN0dWJOYW1lCnI9Yi5sZW5ndGgKcT1hW3Nd
+CnA9Yj09bnVsbD9xPT1udWxsOmI9PT1xCm89IXB8fHI+PTI4CmlmKG8pcmV0dXJuIEguWjQociwhcCxz
+LGIpCmlmKHI9PT0xKXtwPSJyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy4iK0guRWoobSkrIi4i
+K0guRWoocykrIih0aGlzLiIrbCsiKTsiCm89JC55agppZih0eXBlb2YgbyE9PSJudW1iZXIiKXJldHVy
+biBvLmgoKQokLnlqPW8rMQpyZXR1cm4gbmV3IEZ1bmN0aW9uKHArbysifSIpKCl9bj0iYWJjZGVmZ2hp
+amtsbW5vcHFyc3R1dnd4eXoiLnNwbGl0KCIiKS5zcGxpY2UoMCxyLTEpLmpvaW4oIiwiKQpwPSJyZXR1
+cm4gZnVuY3Rpb24oIituKyIpe3JldHVybiB0aGlzLiIrSC5FaihtKSsiLiIrSC5FaihzKSsiKHRoaXMu
+IitsKyIsICIrbisiKTsiCm89JC55agppZih0eXBlb2YgbyE9PSJudW1iZXIiKXJldHVybiBvLmgoKQok
+LnlqPW8rMQpyZXR1cm4gbmV3IEZ1bmN0aW9uKHArbysifSIpKCl9LApLcTpmdW5jdGlvbihhLGIsYyxk
+LGUsZixnKXtyZXR1cm4gSC5pQShhLGIsYyxkLCEhZSwhIWYsZyl9LApUbjpmdW5jdGlvbihhLGIpe3Jl
+dHVybiBILmNFKHYudHlwZVVuaXZlcnNlLEgueihhLmEpLGIpfSwKUFc6ZnVuY3Rpb24oYSxiKXtyZXR1
+cm4gSC5jRSh2LnR5cGVVbml2ZXJzZSxILnooYS5jKSxiKX0sCkRWOmZ1bmN0aW9uKGEpe3JldHVybiBh
+LmF9LAp5UzpmdW5jdGlvbihhKXtyZXR1cm4gYS5jfSwKb046ZnVuY3Rpb24oKXt2YXIgcz0kLm1KCnJl
+dHVybiBzPT1udWxsPyQubUo9SC5FMigic2VsZiIpOnN9LApFMjpmdW5jdGlvbihhKXt2YXIgcyxyLHEs
+cD1uZXcgSC5yVCgic2VsZiIsInRhcmdldCIsInJlY2VpdmVyIiwibmFtZSIpLG89Si5FcChPYmplY3Qu
+Z2V0T3duUHJvcGVydHlOYW1lcyhwKSx0LlcpCmZvcihzPW8ubGVuZ3RoLHI9MDtyPHM7KytyKXtxPW9b
+cl0KaWYocFtxXT09PWEpcmV0dXJuIHF9dGhyb3cgSC5iKFAueFkoIkZpZWxkIG5hbWUgIithKyIgbm90
+IGZvdW5kLiIpKX0sCm9UOmZ1bmN0aW9uKGEpe2lmKGE9PW51bGwpSC5mTygiYm9vbGVhbiBleHByZXNz
+aW9uIG11c3Qgbm90IGJlIG51bGwiKQpyZXR1cm4gYX0sCmZPOmZ1bmN0aW9uKGEpe3Rocm93IEguYihu
+ZXcgSC5rWShhKSl9LAphZzpmdW5jdGlvbihhKXt0aHJvdyBILmIobmV3IFAuYyhhKSl9LApZZzpmdW5j
+dGlvbihhKXtyZXR1cm4gdi5nZXRJc29sYXRlVGFnKGEpfSwKQm86ZnVuY3Rpb24oYSl7cmV0dXJuIEgu
+dihuZXcgSC5uKGEpKX0sCml3OmZ1bmN0aW9uKGEsYixjKXtPYmplY3QuZGVmaW5lUHJvcGVydHkoYSxi
+LHt2YWx1ZTpjLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFibGU6dHJ1ZX0p
+fSwKdzM6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuPUguaCgkLk5GLiQxKGEpKSxtPSQubndbbl0K
+aWYobSE9bnVsbCl7T2JqZWN0LmRlZmluZVByb3BlcnR5KGEsdi5kaXNwYXRjaFByb3BlcnR5TmFtZSx7
+dmFsdWU6bSxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpy
+ZXR1cm4gbS5pfXM9JC52dltuXQppZihzIT1udWxsKXJldHVybiBzCnI9di5pbnRlcmNlcHRvcnNCeVRh
+Z1tuXQppZihyPT1udWxsKXtxPUguaygkLlRYLiQyKGEsbikpCmlmKHEhPW51bGwpe209JC5ud1txXQpp
ZihtIT1udWxsKXtPYmplY3QuZGVmaW5lUHJvcGVydHkoYSx2LmRpc3BhdGNoUHJvcGVydHlOYW1lLHt2
YWx1ZTptLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFibGU6dHJ1ZX0pCnJl
-dHVybiBtLml9cz0kLnZ2W25dCmlmKHMhPW51bGwpcmV0dXJuIHMKcj12LmludGVyY2VwdG9yc0J5VGFn
-W25dCmlmKHI9PW51bGwpe3E9SC5rKCQuVFguJDIoYSxuKSkKaWYocSE9bnVsbCl7bT0kLm53W3FdCmlm
-KG0hPW51bGwpe09iamVjdC5kZWZpbmVQcm9wZXJ0eShhLHYuZGlzcGF0Y2hQcm9wZXJ0eU5hbWUse3Zh
-bHVlOm0sZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVlfSkKcmV0
-dXJuIG0uaX1zPSQudnZbcV0KaWYocyE9bnVsbClyZXR1cm4gcwpyPXYuaW50ZXJjZXB0b3JzQnlUYWdb
-cV0Kbj1xfX1pZihyPT1udWxsKXJldHVybiBudWxsCnM9ci5wcm90b3R5cGUKcD1uWzBdCmlmKHA9PT0i
-ISIpe209SC5WYShzKQokLm53W25dPW0KT2JqZWN0LmRlZmluZVByb3BlcnR5KGEsdi5kaXNwYXRjaFBy
-b3BlcnR5TmFtZSx7dmFsdWU6bSxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJh
-YmxlOnRydWV9KQpyZXR1cm4gbS5pfWlmKHA9PT0ifiIpeyQudnZbbl09cwpyZXR1cm4gc31pZihwPT09
-Ii0iKXtvPUguVmEocykKT2JqZWN0LmRlZmluZVByb3BlcnR5KE9iamVjdC5nZXRQcm90b3R5cGVPZihh
-KSx2LmRpc3BhdGNoUHJvcGVydHlOYW1lLHt2YWx1ZTpvLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6
-dHJ1ZSxjb25maWd1cmFibGU6dHJ1ZX0pCnJldHVybiBvLml9aWYocD09PSIrIilyZXR1cm4gSC5MYyhh
-LHMpCmlmKHA9PT0iKiIpdGhyb3cgSC5iKFAuU1kobikpCmlmKHYubGVhZlRhZ3Nbbl09PT10cnVlKXtv
-PUguVmEocykKT2JqZWN0LmRlZmluZVByb3BlcnR5KE9iamVjdC5nZXRQcm90b3R5cGVPZihhKSx2LmRp
-c3BhdGNoUHJvcGVydHlOYW1lLHt2YWx1ZTpvLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxj
-b25maWd1cmFibGU6dHJ1ZX0pCnJldHVybiBvLml9ZWxzZSByZXR1cm4gSC5MYyhhLHMpfSwKTGM6ZnVu
-Y3Rpb24oYSxiKXt2YXIgcz1PYmplY3QuZ2V0UHJvdG90eXBlT2YoYSkKT2JqZWN0LmRlZmluZVByb3Bl
-cnR5KHMsdi5kaXNwYXRjaFByb3BlcnR5TmFtZSx7dmFsdWU6Si5RdShiLHMsbnVsbCxudWxsKSxlbnVt
-ZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpyZXR1cm4gYn0sClZh
-OmZ1bmN0aW9uKGEpe3JldHVybiBKLlF1KGEsITEsbnVsbCwhIWEuJGlYail9LApWRjpmdW5jdGlvbihh
-LGIsYyl7dmFyIHM9Yi5wcm90b3R5cGUKaWYodi5sZWFmVGFnc1thXT09PXRydWUpcmV0dXJuIEguVmEo
-cykKZWxzZSByZXR1cm4gSi5RdShzLGMsbnVsbCxudWxsKX0sClhEOmZ1bmN0aW9uKCl7aWYoITA9PT0k
-LkJ2KXJldHVybgokLkJ2PSEwCkguWjEoKX0sCloxOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbyxuLG0s
-bAokLm53PU9iamVjdC5jcmVhdGUobnVsbCkKJC52dj1PYmplY3QuY3JlYXRlKG51bGwpCkgua08oKQpz
-PXYuaW50ZXJjZXB0b3JzQnlUYWcKcj1PYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhzKQppZih0eXBl
-b2Ygd2luZG93IT0idW5kZWZpbmVkIil7d2luZG93CnE9ZnVuY3Rpb24oKXt9CmZvcihwPTA7cDxyLmxl
-bmd0aDsrK3Ape289cltwXQpuPSQueDcuJDEobykKaWYobiE9bnVsbCl7bT1ILlZGKG8sc1tvXSxuKQpp
-ZihtIT1udWxsKXtPYmplY3QuZGVmaW5lUHJvcGVydHkobix2LmRpc3BhdGNoUHJvcGVydHlOYW1lLHt2
-YWx1ZTptLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFibGU6dHJ1ZX0pCnEu
-cHJvdG90eXBlPW59fX19Zm9yKHA9MDtwPHIubGVuZ3RoOysrcCl7bz1yW3BdCmlmKC9eW0EtWmEtel9d
-Ly50ZXN0KG8pKXtsPXNbb10Kc1siISIrb109bApzWyJ+IitvXT1sCnNbIi0iK29dPWwKc1siKyIrb109
-bApzWyIqIitvXT1sfX19LAprTzpmdW5jdGlvbigpe3ZhciBzLHIscSxwLG8sbixtPUMuWXEoKQptPUgu
-dWQoQy5LVSxILnVkKEMuZlEsSC51ZChDLmk3LEgudWQoQy5pNyxILnVkKEMueGksSC51ZChDLmRrLEgu
-dWQoQy53YihDLk80KSxtKSkpKSkpKQppZih0eXBlb2YgZGFydE5hdGl2ZURpc3BhdGNoSG9va3NUcmFu
-c2Zvcm1lciE9InVuZGVmaW5lZCIpe3M9ZGFydE5hdGl2ZURpc3BhdGNoSG9va3NUcmFuc2Zvcm1lcgpp
-Zih0eXBlb2Ygcz09ImZ1bmN0aW9uIilzPVtzXQppZihzLmNvbnN0cnVjdG9yPT1BcnJheSlmb3Iocj0w
-O3I8cy5sZW5ndGg7KytyKXtxPXNbcl0KaWYodHlwZW9mIHE9PSJmdW5jdGlvbiIpbT1xKG0pfHxtfX1w
-PW0uZ2V0VGFnCm89bS5nZXRVbmtub3duVGFnCm49bS5wcm90b3R5cGVGb3JUYWcKJC5ORj1uZXcgSC5k
-QyhwKQokLlRYPW5ldyBILndOKG8pCiQueDc9bmV3IEguVlgobil9LAp1ZDpmdW5jdGlvbihhLGIpe3Jl
-dHVybiBhKGIpfHxifSwKdjQ6ZnVuY3Rpb24oYSxiLGMsZCxlLGYpe3ZhciBzPWI/Im0iOiIiLHI9Yz8i
-IjoiaSIscT1kPyJ1IjoiIixwPWU/InMiOiIiLG89Zj8iZyI6IiIsbj1mdW5jdGlvbihnLGgpe3RyeXty
-ZXR1cm4gbmV3IFJlZ0V4cChnLGgpfWNhdGNoKG0pe3JldHVybiBtfX0oYSxzK3IrcStwK28pCmlmKG4g
-aW5zdGFuY2VvZiBSZWdFeHApcmV0dXJuIG4KdGhyb3cgSC5iKFAucnIoIklsbGVnYWwgUmVnRXhwIHBh
-dHRlcm4gKCIrU3RyaW5nKG4pKyIpIixhLG51bGwpKX0sClNROmZ1bmN0aW9uKGEsYixjKXt2YXIgcwpp
-Zih0eXBlb2YgYj09InN0cmluZyIpcmV0dXJuIGEuaW5kZXhPZihiLGMpPj0wCmVsc2UgaWYoYiBpbnN0
-YW5jZW9mIEguVlIpe3M9Qy54Qi5HKGEsYykKcmV0dXJuIGIuYi50ZXN0KHMpfWVsc2V7cz1KLkZMKGIs
-Qy54Qi5HKGEsYykpCnJldHVybiFzLmdsMChzKX19LApBNDpmdW5jdGlvbihhKXtpZihhLmluZGV4T2Yo
-IiQiLDApPj0wKXJldHVybiBhLnJlcGxhY2UoL1wkL2csIiQkJCQiKQpyZXR1cm4gYX0sCmVBOmZ1bmN0
-aW9uKGEpe2lmKC9bW1xde30oKSorPy5cXF4kfF0vLnRlc3QoYSkpcmV0dXJuIGEucmVwbGFjZSgvW1tc
-XXt9KCkqKz8uXFxeJHxdL2csIlxcJCYiKQpyZXR1cm4gYX0sCnlzOmZ1bmN0aW9uKGEsYixjKXt2YXIg
-cz1ILm5NKGEsYixjKQpyZXR1cm4gc30sCm5NOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscAppZihi
-PT09IiIpe2lmKGE9PT0iIilyZXR1cm4gYwpzPWEubGVuZ3RoCmZvcihyPWMscT0wO3E8czsrK3Epcj1y
-K2FbcV0rYwpyZXR1cm4gci5jaGFyQ29kZUF0KDApPT0wP3I6cn1wPWEuaW5kZXhPZihiLDApCmlmKHA8
-MClyZXR1cm4gYQppZihhLmxlbmd0aDw1MDB8fGMuaW5kZXhPZigiJCIsMCk+PTApcmV0dXJuIGEuc3Bs
-aXQoYikuam9pbihjKQpyZXR1cm4gYS5yZXBsYWNlKG5ldyBSZWdFeHAoSC5lQShiKSwnZycpLEguQTQo
-YykpfSwKUEQ6ZnVuY3Rpb24gUEQoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKV1U6ZnVuY3Rpb24g
-V1UoKXt9LApMUDpmdW5jdGlvbiBMUChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1j
-Cl8uJHRpPWR9LApYUjpmdW5jdGlvbiBYUihhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApMSTpmdW5j
-dGlvbiBMSShhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5hPWEKXy5jPWIKXy5kPWMKXy5lPWQKXy5mPWV9
-LApDajpmdW5jdGlvbiBDaihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApmOTpmdW5j
-dGlvbiBmOShhLGIsYyxkLGUsZil7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApfLmU9
-ZQpfLmY9Zn0sClcwOmZ1bmN0aW9uIFcwKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAphejpmdW5jdGlv
-biBheihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LAp2VjpmdW5jdGlvbiB2VihhKXt0
-aGlzLmE9YX0sCnRlOmZ1bmN0aW9uIHRlKGEpe3RoaXMuYT1hfSwKYnE6ZnVuY3Rpb24gYnEoYSxiKXt0
-aGlzLmE9YQp0aGlzLmI9Yn0sClhPOmZ1bmN0aW9uIFhPKGEpe3RoaXMuYT1hCnRoaXMuYj1udWxsfSwK
-VHA6ZnVuY3Rpb24gVHAoKXt9LApsYzpmdW5jdGlvbiBsYygpe30sCnp4OmZ1bmN0aW9uIHp4KCl7fSwK
-clQ6ZnVuY3Rpb24gclQoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZH0s
-CkVxOmZ1bmN0aW9uIEVxKGEpe3RoaXMuYT1hfSwKa1k6ZnVuY3Rpb24ga1koYSl7dGhpcy5hPWF9LApr
-cjpmdW5jdGlvbiBrcigpe30sCk41OmZ1bmN0aW9uIE41KGEpe3ZhciBfPXRoaXMKXy5hPTAKXy5mPV8u
-ZT1fLmQ9Xy5jPV8uYj1udWxsCl8ucj0wCl8uJHRpPWF9LAp2aDpmdW5jdGlvbiB2aChhLGIpe3ZhciBf
-PXRoaXMKXy5hPWEKXy5iPWIKXy5kPV8uYz1udWxsfSwKaTU6ZnVuY3Rpb24gaTUoYSxiKXt0aGlzLmE9
-YQp0aGlzLiR0aT1ifSwKTjY6ZnVuY3Rpb24gTjYoYSxiLGMpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIK
-Xy5kPV8uYz1udWxsCl8uJHRpPWN9LApkQzpmdW5jdGlvbiBkQyhhKXt0aGlzLmE9YX0sCndOOmZ1bmN0
-aW9uIHdOKGEpe3RoaXMuYT1hfSwKVlg6ZnVuY3Rpb24gVlgoYSl7dGhpcy5hPWF9LApWUjpmdW5jdGlv
-biBWUihhLGIpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5kPV8uYz1udWxsfSwKRUs6ZnVuY3Rpb24g
-RUsoYSl7dGhpcy5iPWF9LApLVzpmdW5jdGlvbiBLVyhhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhp
-cy5jPWN9LApQYjpmdW5jdGlvbiBQYihhLGIsYyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9Ywpf
-LmQ9bnVsbH0sCnRROmZ1bmN0aW9uIHRRKGEsYil7dGhpcy5hPWEKdGhpcy5jPWJ9LAp1bjpmdW5jdGlv
-biB1bihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApTZDpmdW5jdGlvbiBTZChhLGIs
-Yyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9bnVsbH0sClhGOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBhfSwKb2Q6ZnVuY3Rpb24oYSxiLGMpe2lmKGE+Pj4wIT09YXx8YT49Yyl0aHJvdyBILmIoSC5I
-WShiLGEpKX0sCnJNOmZ1bmN0aW9uKGEsYixjKXt2YXIgcwppZighKGE+Pj4wIT09YSkpcz1iPj4+MCE9
-PWJ8fGE+Ynx8Yj5jCmVsc2Ugcz0hMAppZihzKXRocm93IEguYihILmF1KGEsYixjKSkKcmV0dXJuIGJ9
-LApFVDpmdW5jdGlvbiBFVCgpe30sCkxaOmZ1bmN0aW9uIExaKCl7fSwKRGc6ZnVuY3Rpb24gRGcoKXt9
-LApQZzpmdW5jdGlvbiBQZygpe30sCnhqOmZ1bmN0aW9uIHhqKCl7fSwKZEU6ZnVuY3Rpb24gZEUoKXt9
-LApaQTpmdW5jdGlvbiBaQSgpe30sCmRUOmZ1bmN0aW9uIGRUKCl7fSwKUHE6ZnVuY3Rpb24gUHEoKXt9
-LAplRTpmdW5jdGlvbiBlRSgpe30sClY2OmZ1bmN0aW9uIFY2KCl7fSwKUkc6ZnVuY3Rpb24gUkcoKXt9
-LApWUDpmdW5jdGlvbiBWUCgpe30sCldCOmZ1bmN0aW9uIFdCKCl7fSwKWkc6ZnVuY3Rpb24gWkcoKXt9
-LApjejpmdW5jdGlvbihhLGIpe3ZhciBzPWIuYwpyZXR1cm4gcz09bnVsbD9iLmM9SC5CKGEsYi56LCEw
-KTpzfSwKeFo6ZnVuY3Rpb24oYSxiKXt2YXIgcz1iLmMKcmV0dXJuIHM9PW51bGw/Yi5jPUguSihhLCJi
-OCIsW2Iuel0pOnN9LApRMTpmdW5jdGlvbihhKXt2YXIgcz1hLnkKaWYocz09PTZ8fHM9PT03fHxzPT09
-OClyZXR1cm4gSC5RMShhLnopCnJldHVybiBzPT09MTF8fHM9PT0xMn0sCm1EOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBhLmN5fSwKTjA6ZnVuY3Rpb24oYSl7cmV0dXJuIEguRSh2LnR5cGVVbml2ZXJzZSxhLCExKX0s
-ClBMOmZ1bmN0aW9uKGEsYixhMCxhMSl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQs
-Yz1iLnkKc3dpdGNoKGMpe2Nhc2UgNTpjYXNlIDE6Y2FzZSAyOmNhc2UgMzpjYXNlIDQ6cmV0dXJuIGIK
-Y2FzZSA2OnM9Yi56CnI9SC5QTChhLHMsYTAsYTEpCmlmKHI9PT1zKXJldHVybiBiCnJldHVybiBILkMo
-YSxyLCEwKQpjYXNlIDc6cz1iLnoKcj1ILlBMKGEscyxhMCxhMSkKaWYocj09PXMpcmV0dXJuIGIKcmV0
-dXJuIEguQihhLHIsITApCmNhc2UgODpzPWIuegpyPUguUEwoYSxzLGEwLGExKQppZihyPT09cylyZXR1
-cm4gYgpyZXR1cm4gSC5mKGEsciwhMCkKY2FzZSA5OnE9Yi5RCnA9SC5iWihhLHEsYTAsYTEpCmlmKHA9
-PT1xKXJldHVybiBiCnJldHVybiBILkooYSxiLnoscCkKY2FzZSAxMDpvPWIuegpuPUguUEwoYSxvLGEw
-LGExKQptPWIuUQpsPUguYlooYSxtLGEwLGExKQppZihuPT09byYmbD09PW0pcmV0dXJuIGIKcmV0dXJu
-IEguYShhLG4sbCkKY2FzZSAxMTprPWIuegpqPUguUEwoYSxrLGEwLGExKQppPWIuUQpoPUgucVQoYSxp
-LGEwLGExKQppZihqPT09ayYmaD09PWkpcmV0dXJuIGIKcmV0dXJuIEguZChhLGosaCkKY2FzZSAxMjpn
-PWIuUQphMSs9Zy5sZW5ndGgKZj1ILmJaKGEsZyxhMCxhMSkKbz1iLnoKbj1ILlBMKGEsbyxhMCxhMSkK
-aWYoZj09PWcmJm49PT1vKXJldHVybiBiCnJldHVybiBILkQoYSxuLGYsITApCmNhc2UgMTM6ZT1iLnoK
-aWYoZTxhMSlyZXR1cm4gYgpkPWEwW2UtYTFdCmlmKGQ9PW51bGwpcmV0dXJuIGIKcmV0dXJuIGQKZGVm
-YXVsdDp0aHJvdyBILmIoUC5oVigiQXR0ZW1wdGVkIHRvIHN1YnN0aXR1dGUgdW5leHBlY3RlZCBSVEkg
-a2luZCAiK2MpKX19LApiWjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyLHEscCxvPWIubGVuZ3RoLG49
-W10KZm9yKHM9ITEscj0wO3I8bzsrK3Ipe3E9YltyXQpwPUguUEwoYSxxLGMsZCkKaWYocCE9PXEpcz0h
-MApuLnB1c2gocCl9cmV0dXJuIHM/bjpifSwKdk86ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixxLHAs
-byxuLG09Yi5sZW5ndGgsbD1bXQpmb3Iocz0hMSxyPTA7cjxtO3IrPTMpe3E9YltyXQpwPWJbcisxXQpv
-PWJbcisyXQpuPUguUEwoYSxvLGMsZCkKaWYobiE9PW8pcz0hMApsLnB1c2gocSkKbC5wdXNoKHApCmwu
-cHVzaChuKX1yZXR1cm4gcz9sOmJ9LApxVDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyPWIuYSxxPUgu
-YlooYSxyLGMsZCkscD1iLmIsbz1ILmJaKGEscCxjLGQpLG49Yi5jLG09SC52TyhhLG4sYyxkKQppZihx
-PT09ciYmbz09PXAmJm09PT1uKXJldHVybiBiCnM9bmV3IEguRygpCnMuYT1xCnMuYj1vCnMuYz1tCnJl
-dHVybiBzfSwKVk06ZnVuY3Rpb24oYSxiKXthW3YuYXJyYXlSdGldPWIKcmV0dXJuIGF9LApKUzpmdW5j
-dGlvbihhKXt2YXIgcz1hLiRTCmlmKHMhPW51bGwpe2lmKHR5cGVvZiBzPT0ibnVtYmVyIilyZXR1cm4g
-SC5CcChzKQpyZXR1cm4gYS4kUygpfXJldHVybiBudWxsfSwKVWU6ZnVuY3Rpb24oYSxiKXt2YXIgcwpp
-ZihILlExKGIpKWlmKGEgaW5zdGFuY2VvZiBILlRwKXtzPUguSlMoYSkKaWYocyE9bnVsbClyZXR1cm4g
-c31yZXR1cm4gSC56KGEpfSwKejpmdW5jdGlvbihhKXt2YXIgcwppZihhIGluc3RhbmNlb2YgUC5NaCl7
-cz1hLiR0aQpyZXR1cm4gcyE9bnVsbD9zOkguVlUoYSl9aWYoQXJyYXkuaXNBcnJheShhKSlyZXR1cm4g
-SC50NihhKQpyZXR1cm4gSC5WVShKLmlhKGEpKX0sCnQ2OmZ1bmN0aW9uKGEpe3ZhciBzPWFbdi5hcnJh
-eVJ0aV0scj10LngKaWYocz09bnVsbClyZXR1cm4gcgppZihzLmNvbnN0cnVjdG9yIT09ci5jb25zdHJ1
-Y3RvcilyZXR1cm4gcgpyZXR1cm4gc30sCkxoOmZ1bmN0aW9uKGEpe3ZhciBzPWEuJHRpCnJldHVybiBz
-IT1udWxsP3M6SC5WVShhKX0sClZVOmZ1bmN0aW9uKGEpe3ZhciBzPWEuY29uc3RydWN0b3Iscj1zLiRj
-Y2FjaGUKaWYociE9bnVsbClyZXR1cm4gcgpyZXR1cm4gSC5yOShhLHMpfSwKcjk6ZnVuY3Rpb24oYSxi
-KXt2YXIgcz1hIGluc3RhbmNlb2YgSC5UcD9hLl9fcHJvdG9fXy5fX3Byb3RvX18uY29uc3RydWN0b3I6
-YixyPUguYWkodi50eXBlVW5pdmVyc2Uscy5uYW1lKQpiLiRjY2FjaGU9cgpyZXR1cm4gcn0sCkJwOmZ1
-bmN0aW9uKGEpe3ZhciBzLHIscQpILnVQKGEpCnM9di50eXBlcwpyPXNbYV0KaWYodHlwZW9mIHI9PSJz
-dHJpbmciKXtxPUguRSh2LnR5cGVVbml2ZXJzZSxyLCExKQpzW2FdPXEKcmV0dXJuIHF9cmV0dXJuIHJ9
-LApLeDpmdW5jdGlvbihhKXt2YXIgcyxyLHEscD1hLngKaWYocCE9bnVsbClyZXR1cm4gcApzPWEuY3kK
-cj1zLnJlcGxhY2UoL1wqL2csIiIpCmlmKHI9PT1zKXJldHVybiBhLng9bmV3IEgubFkoYSkKcT1ILkUo
-di50eXBlVW5pdmVyc2UsciwhMCkKcD1xLngKcmV0dXJuIGEueD1wPT1udWxsP3EueD1uZXcgSC5sWShx
-KTpwfSwKSko6ZnVuY3Rpb24oYSl7dmFyIHMscixxPXRoaXMscD10LksKaWYocT09PXApcmV0dXJuIEgu
-UkUocSxhLEgua2UpCmlmKCFILkE4KHEpKWlmKCEocT09PXQuXykpcD1xPT09cAplbHNlIHA9ITAKZWxz
-ZSBwPSEwCmlmKHApcmV0dXJuIEguUkUocSxhLEguSXcpCnA9cS55CnM9cD09PTY/cS56OnEKaWYocz09
-PXQuUylyPUgub2sKZWxzZSBpZihzPT09dC5nUnx8cz09PXQuZGkpcj1ILktICmVsc2UgaWYocz09PXQu
-TilyPUguTU0KZWxzZSByPXM9PT10Lnk/SC5sOm51bGwKaWYociE9bnVsbClyZXR1cm4gSC5SRShxLGEs
-cikKaWYocy55PT09OSl7cD1zLnoKaWYocy5RLmV2ZXJ5KEguY2MpKXtxLnI9IiRpIitwCnJldHVybiBI
-LlJFKHEsYSxILnQ0KX19ZWxzZSBpZihwPT09NylyZXR1cm4gSC5SRShxLGEsSC5BUSkKcmV0dXJuIEgu
-UkUocSxhLEguWU8pfSwKUkU6ZnVuY3Rpb24oYSxiLGMpe2EuYj1jCnJldHVybiBhLmIoYil9LApBdTpm
-dW5jdGlvbihhKXt2YXIgcyxyLHE9dGhpcwppZighSC5BOChxKSlpZighKHE9PT10Ll8pKXM9cT09PXQu
-SwplbHNlIHM9ITAKZWxzZSBzPSEwCmlmKHMpcj1ILmhuCmVsc2UgaWYocT09PXQuSylyPUguVGkKZWxz
-ZSByPUgubDQKcS5hPXIKcmV0dXJuIHEuYShhKX0sClFqOmZ1bmN0aW9uKGEpe3ZhciBzLHI9YS55Cmlm
-KCFILkE4KGEpKWlmKCEoYT09PXQuXykpaWYoIShhPT09dC5jRikpaWYociE9PTcpcz1yPT09OCYmSC5R
-aihhLnopfHxhPT09dC5QfHxhPT09dC5UCmVsc2Ugcz0hMAplbHNlIHM9ITAKZWxzZSBzPSEwCmVsc2Ug
-cz0hMApyZXR1cm4gc30sCllPOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMKaWYoYT09bnVsbClyZXR1cm4g
-SC5RaihzKQpyZXR1cm4gSC5XZSh2LnR5cGVVbml2ZXJzZSxILlVlKGEscyksbnVsbCxzLG51bGwpfSwK
-QVE6ZnVuY3Rpb24oYSl7aWYoYT09bnVsbClyZXR1cm4hMApyZXR1cm4gdGhpcy56LmIoYSl9LAp0NDpm
-dW5jdGlvbihhKXt2YXIgcyxyPXRoaXMKaWYoYT09bnVsbClyZXR1cm4gSC5RaihyKQpzPXIucgppZihh
-IGluc3RhbmNlb2YgUC5NaClyZXR1cm4hIWFbc10KcmV0dXJuISFKLmlhKGEpW3NdfSwKT3o6ZnVuY3Rp
-b24oYSl7dmFyIHM9dGhpcwppZihhPT1udWxsKXJldHVybiBhCmVsc2UgaWYocy5iKGEpKXJldHVybiBh
-CkgubTQoYSxzKX0sCmw0OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMKaWYoYT09bnVsbClyZXR1cm4gYQpl
-bHNlIGlmKHMuYihhKSlyZXR1cm4gYQpILm00KGEscyl9LAptNDpmdW5jdGlvbihhLGIpe3Rocm93IEgu
-YihILlpjKEguV0soYSxILlVlKGEsYiksSC5kbShiLG51bGwpKSkpfSwKRGg6ZnVuY3Rpb24oYSxiLGMs
-ZCl7dmFyIHM9bnVsbAppZihILldlKHYudHlwZVVuaXZlcnNlLGEscyxiLHMpKXJldHVybiBhCnRocm93
-IEguYihILlpjKCJUaGUgdHlwZSBhcmd1bWVudCAnIitILkVqKEguZG0oYSxzKSkrIicgaXMgbm90IGEg
-c3VidHlwZSBvZiB0aGUgdHlwZSB2YXJpYWJsZSBib3VuZCAnIitILkVqKEguZG0oYixzKSkrIicgb2Yg
-dHlwZSB2YXJpYWJsZSAnIitILkVqKGMpKyInIGluICciK0guRWooZCkrIicuIikpfSwKV0s6ZnVuY3Rp
-b24oYSxiLGMpe3ZhciBzPVAucChhKSxyPUguZG0oYj09bnVsbD9ILnooYSk6YixudWxsKQpyZXR1cm4g
-cysiOiB0eXBlICciK0guRWoocikrIicgaXMgbm90IGEgc3VidHlwZSBvZiB0eXBlICciK0guRWooYykr
-IicifSwKWmM6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILmlNKCJUeXBlRXJyb3I6ICIrYSl9LApxOmZ1
-bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILmlNKCJUeXBlRXJyb3I6ICIrSC5XSyhhLG51bGwsYikpfSwK
-a2U6ZnVuY3Rpb24oYSl7cmV0dXJuIGEhPW51bGx9LApUaTpmdW5jdGlvbihhKXtyZXR1cm4gYX0sCkl3
-OmZ1bmN0aW9uKGEpe3JldHVybiEwfSwKaG46ZnVuY3Rpb24oYSl7cmV0dXJuIGF9LApsOmZ1bmN0aW9u
-KGEpe3JldHVybiEwPT09YXx8ITE9PT1hfSwKcDg6ZnVuY3Rpb24oYSl7aWYoITA9PT1hKXJldHVybiEw
-CmlmKCExPT09YSlyZXR1cm4hMQp0aHJvdyBILmIoSC5xKGEsImJvb2wiKSl9LAp5ODpmdW5jdGlvbihh
-KXtpZighMD09PWEpcmV0dXJuITAKaWYoITE9PT1hKXJldHVybiExCmlmKGE9PW51bGwpcmV0dXJuIGEK
-dGhyb3cgSC5iKEgucShhLCJib29sIikpfSwKZHA6ZnVuY3Rpb24oYSl7aWYoITA9PT1hKXJldHVybiEw
-CmlmKCExPT09YSlyZXR1cm4hMQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihILnEoYSwiYm9v
-bD8iKSl9LApGRzpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciIpcmV0dXJuIGEKdGhyb3cg
-SC5iKEgucShhLCJkb3VibGUiKSl9LApHSDpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciIp
-cmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsImRvdWJsZSIpKX0sClFr
-OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gYQppZihhPT1udWxsKXJldHVy
-biBhCnRocm93IEguYihILnEoYSwiZG91YmxlPyIpKX0sCm9rOmZ1bmN0aW9uKGEpe3JldHVybiB0eXBl
-b2YgYT09Im51bWJlciImJk1hdGguZmxvb3IoYSk9PT1hfSwKSVo6ZnVuY3Rpb24oYSl7aWYodHlwZW9m
-IGE9PSJudW1iZXIiJiZNYXRoLmZsb29yKGEpPT09YSlyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsImlu
-dCIpKX0sCnVQOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIiYmTWF0aC5mbG9vcihhKT09
-PWEpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsImludCIpKX0sClVj
-OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIiYmTWF0aC5mbG9vcihhKT09PWEpcmV0dXJu
-IGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsImludD8iKSl9LApLSDpmdW5jdGlv
-bihhKXtyZXR1cm4gdHlwZW9mIGE9PSJudW1iZXIifSwKejU6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9
-PSJudW1iZXIiKXJldHVybiBhCnRocm93IEguYihILnEoYSwibnVtIikpfSwKVzE6ZnVuY3Rpb24oYSl7
-aWYodHlwZW9mIGE9PSJudW1iZXIiKXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cgSC5i
-KEgucShhLCJudW0iKSl9LApjVTpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciIpcmV0dXJu
-IGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsIm51bT8iKSl9LApNTTpmdW5jdGlv
-bihhKXtyZXR1cm4gdHlwZW9mIGE9PSJzdHJpbmcifSwKQnQ6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9
-PSJzdHJpbmciKXJldHVybiBhCnRocm93IEguYihILnEoYSwiU3RyaW5nIikpfSwKaDpmdW5jdGlvbihh
-KXtpZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBI
-LmIoSC5xKGEsIlN0cmluZyIpKX0sCms6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJzdHJpbmciKXJl
-dHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cgSC5iKEgucShhLCJTdHJpbmc/IikpfSwKaW86
-ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEKZm9yKHM9IiIscj0iIixxPTA7cTxhLmxlbmd0aDsrK3Escj0i
-LCAiKXMrPUMueEIuaChyLEguZG0oYVtxXSxiKSkKcmV0dXJuIHN9LApiSTpmdW5jdGlvbihhNSxhNixh
-Nyl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQsYyxiLGEsYTAsYTEsYTIsYTMsYTQ9
-IiwgIgppZihhNyE9bnVsbCl7cz1hNy5sZW5ndGgKaWYoYTY9PW51bGwpe2E2PUguVk0oW10sdC5zKQpy
-PW51bGx9ZWxzZSByPWE2Lmxlbmd0aApxPWE2Lmxlbmd0aApmb3IocD1zO3A+MDstLXApQy5ObS5pKGE2
-LCJUIisocStwKSkKZm9yKG89dC5XLG49dC5fLG09dC5LLGw9IjwiLGs9IiIscD0wO3A8czsrK3Asaz1h
-NCl7bCs9awpqPWE2Lmxlbmd0aAppPWotMS1wCmlmKGk8MClyZXR1cm4gSC5PSChhNixpKQpsPUMueEIu
-aChsLGE2W2ldKQpoPWE3W3BdCmc9aC55CmlmKCEoZz09PTJ8fGc9PT0zfHxnPT09NHx8Zz09PTV8fGg9
-PT1vKSlpZighKGg9PT1uKSlqPWg9PT1tCmVsc2Ugaj0hMAplbHNlIGo9ITAKaWYoIWopbCs9Qy54Qi5o
-KCIgZXh0ZW5kcyAiLEguZG0oaCxhNikpfWwrPSI+In1lbHNle2w9IiIKcj1udWxsfW89YTUuegpmPWE1
-LlEKZT1mLmEKZD1lLmxlbmd0aApjPWYuYgpiPWMubGVuZ3RoCmE9Zi5jCmEwPWEubGVuZ3RoCmExPUgu
-ZG0obyxhNikKZm9yKGEyPSIiLGEzPSIiLHA9MDtwPGQ7KytwLGEzPWE0KWEyKz1DLnhCLmgoYTMsSC5k
-bShlW3BdLGE2KSkKaWYoYj4wKXthMis9YTMrIlsiCmZvcihhMz0iIixwPTA7cDxiOysrcCxhMz1hNClh
-Mis9Qy54Qi5oKGEzLEguZG0oY1twXSxhNikpCmEyKz0iXSJ9aWYoYTA+MCl7YTIrPWEzKyJ7Igpmb3Io
-YTM9IiIscD0wO3A8YTA7cCs9MyxhMz1hNCl7YTIrPWEzCmlmKGFbcCsxXSlhMis9InJlcXVpcmVkICIK
-YTIrPUouYmIoSC5kbShhW3ArMl0sYTYpLCIgIikrYVtwXX1hMis9In0ifWlmKHIhPW51bGwpe2E2LnRv
-U3RyaW5nCmE2Lmxlbmd0aD1yfXJldHVybiBsKyIoIithMisiKSA9PiAiK0guRWooYTEpfSwKZG06ZnVu
-Y3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbSxsPWEueQppZihsPT09NSlyZXR1cm4iZXJhc2VkIgpp
-ZihsPT09MilyZXR1cm4iZHluYW1pYyIKaWYobD09PTMpcmV0dXJuInZvaWQiCmlmKGw9PT0xKXJldHVy
-biJOZXZlciIKaWYobD09PTQpcmV0dXJuImFueSIKaWYobD09PTYpe3M9SC5kbShhLnosYikKcmV0dXJu
-IHN9aWYobD09PTcpe3I9YS56CnM9SC5kbShyLGIpCnE9ci55CnJldHVybiBKLmJiKHE9PT0xMXx8cT09
-PTEyP0MueEIuaCgiKCIscykrIikiOnMsIj8iKX1pZihsPT09OClyZXR1cm4iRnV0dXJlT3I8IitILkVq
-KEguZG0oYS56LGIpKSsiPiIKaWYobD09PTkpe3A9SC5vMyhhLnopCm89YS5RCnJldHVybiBvLmxlbmd0
-aCE9PTA/cCsoIjwiK0guaW8obyxiKSsiPiIpOnB9aWYobD09PTExKXJldHVybiBILmJJKGEsYixudWxs
-KQppZihsPT09MTIpcmV0dXJuIEguYkkoYS56LGIsYS5RKQppZihsPT09MTMpe2IudG9TdHJpbmcKbj1h
-LnoKbT1iLmxlbmd0aApuPW0tMS1uCmlmKG48MHx8bj49bSlyZXR1cm4gSC5PSChiLG4pCnJldHVybiBi
-W25dfXJldHVybiI/In0sCm8zOmZ1bmN0aW9uKGEpe3ZhciBzLHI9SC5KZyhhKQppZihyIT1udWxsKXJl
-dHVybiByCnM9Im1pbmlmaWVkOiIrYQpyZXR1cm4gc30sClFvOmZ1bmN0aW9uKGEsYil7dmFyIHM9YS50
-UltiXQpmb3IoO3R5cGVvZiBzPT0ic3RyaW5nIjspcz1hLnRSW3NdCnJldHVybiBzfSwKYWk6ZnVuY3Rp
-b24oYSxiKXt2YXIgcyxyLHEscCxvLG49YS5lVCxtPW5bYl0KaWYobT09bnVsbClyZXR1cm4gSC5FKGEs
-YiwhMSkKZWxzZSBpZih0eXBlb2YgbT09Im51bWJlciIpe3M9bQpyPUgubShhLDUsIiMiKQpxPVtdCmZv
-cihwPTA7cDxzOysrcClxLnB1c2gocikKbz1ILkooYSxiLHEpCm5bYl09bwpyZXR1cm4gb31lbHNlIHJl
-dHVybiBtfSwKeGI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSC5JeChhLnRSLGIpfSwKRkY6ZnVuY3Rpb24o
-YSxiKXtyZXR1cm4gSC5JeChhLmVULGIpfSwKRTpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj1hLmVDLHE9
-ci5nZXQoYikKaWYocSE9bnVsbClyZXR1cm4gcQpzPUguaShILm8oYSxudWxsLGIsYykpCnIuc2V0KGIs
-cykKcmV0dXJuIHN9LApjRTpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxPWIuY2gKaWYocT09bnVsbClx
-PWIuY2g9bmV3IE1hcCgpCnM9cS5nZXQoYykKaWYocyE9bnVsbClyZXR1cm4gcwpyPUguaShILm8oYSxi
-LGMsITApKQpxLnNldChjLHIpCnJldHVybiByfSwKdjU6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscSxw
-PWIuY3gKaWYocD09bnVsbClwPWIuY3g9bmV3IE1hcCgpCnM9Yy5jeQpyPXAuZ2V0KHMpCmlmKHIhPW51
-bGwpcmV0dXJuIHIKcT1ILmEoYSxiLGMueT09PTEwP2MuUTpbY10pCnAuc2V0KHMscSkKcmV0dXJuIHF9
-LApCRDpmdW5jdGlvbihhLGIpe2IuYT1ILkF1CmIuYj1ILkpKCnJldHVybiBifSwKbTpmdW5jdGlvbihh
-LGIsYyl7dmFyIHMscixxPWEuZUMuZ2V0KGMpCmlmKHEhPW51bGwpcmV0dXJuIHEKcz1uZXcgSC5KYyhu
-dWxsLG51bGwpCnMueT1iCnMuY3k9YwpyPUguQkQoYSxzKQphLmVDLnNldChjLHIpCnJldHVybiByfSwK
-QzpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj1iLmN5KyIqIixxPWEuZUMuZ2V0KHIpCmlmKHEhPW51bGwp
-cmV0dXJuIHEKcz1ILlo3KGEsYixyLGMpCmEuZUMuc2V0KHIscykKcmV0dXJuIHN9LApaNzpmdW5jdGlv
-bihhLGIsYyxkKXt2YXIgcyxyLHEKaWYoZCl7cz1iLnkKaWYoIUguQTgoYikpcj1iPT09dC5QfHxiPT09
-dC5UfHxzPT09N3x8cz09PTYKZWxzZSByPSEwCmlmKHIpcmV0dXJuIGJ9cT1uZXcgSC5KYyhudWxsLG51
-bGwpCnEueT02CnEuej1iCnEuY3k9YwpyZXR1cm4gSC5CRChhLHEpfSwKQjpmdW5jdGlvbihhLGIsYyl7
-dmFyIHMscj1iLmN5KyI/IixxPWEuZUMuZ2V0KHIpCmlmKHEhPW51bGwpcmV0dXJuIHEKcz1ILmxsKGEs
-YixyLGMpCmEuZUMuc2V0KHIscykKcmV0dXJuIHN9LApsbDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxy
-LHEscAppZihkKXtzPWIueQppZighSC5BOChiKSlpZighKGI9PT10LlB8fGI9PT10LlQpKWlmKHMhPT03
-KXI9cz09PTgmJkgubFIoYi56KQplbHNlIHI9ITAKZWxzZSByPSEwCmVsc2Ugcj0hMAppZihyKXJldHVy
-biBiCmVsc2UgaWYocz09PTF8fGI9PT10LmNGKXJldHVybiB0LlAKZWxzZSBpZihzPT09Nil7cT1iLnoK
-aWYocS55PT09OCYmSC5sUihxLnopKXJldHVybiBxCmVsc2UgcmV0dXJuIEguY3ooYSxiKX19cD1uZXcg
-SC5KYyhudWxsLG51bGwpCnAueT03CnAuej1iCnAuY3k9YwpyZXR1cm4gSC5CRChhLHApfSwKZjpmdW5j
-dGlvbihhLGIsYyl7dmFyIHMscj1iLmN5KyIvIixxPWEuZUMuZ2V0KHIpCmlmKHEhPW51bGwpcmV0dXJu
-IHEKcz1ILmVWKGEsYixyLGMpCmEuZUMuc2V0KHIscykKcmV0dXJuIHN9LAplVjpmdW5jdGlvbihhLGIs
-YyxkKXt2YXIgcyxyLHEKaWYoZCl7cz1iLnkKaWYoIUguQTgoYikpaWYoIShiPT09dC5fKSlyPWI9PT10
-LksKZWxzZSByPSEwCmVsc2Ugcj0hMAppZihyfHxiPT09dC5LKXJldHVybiBiCmVsc2UgaWYocz09PTEp
-cmV0dXJuIEguSihhLCJiOCIsW2JdKQplbHNlIGlmKGI9PT10LlB8fGI9PT10LlQpcmV0dXJuIHQuYkd9
-cT1uZXcgSC5KYyhudWxsLG51bGwpCnEueT04CnEuej1iCnEuY3k9YwpyZXR1cm4gSC5CRChhLHEpfSwK
-SDpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT0iIitiKyJeIixwPWEuZUMuZ2V0KHEpCmlmKHAhPW51bGwp
-cmV0dXJuIHAKcz1uZXcgSC5KYyhudWxsLG51bGwpCnMueT0xMwpzLno9YgpzLmN5PXEKcj1ILkJEKGEs
-cykKYS5lQy5zZXQocSxyKQpyZXR1cm4gcn0sClV4OmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPWEubGVu
-Z3RoCmZvcihzPSIiLHI9IiIscT0wO3E8cDsrK3Escj0iLCIpcys9cithW3FdLmN5CnJldHVybiBzfSwK
-UzQ6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG09YS5sZW5ndGgKZm9yKHM9IiIscj0iIixxPTA7
-cTxtO3ErPTMscj0iLCIpe3A9YVtxXQpvPWFbcSsxXT8iISI6IjoiCm49YVtxKzJdLmN5CnMrPXIrcCtv
-K259cmV0dXJuIHN9LApKOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscD1iCmlmKGMubGVuZ3RoIT09
-MClwKz0iPCIrSC5VeChjKSsiPiIKcz1hLmVDLmdldChwKQppZihzIT1udWxsKXJldHVybiBzCnI9bmV3
-IEguSmMobnVsbCxudWxsKQpyLnk9OQpyLno9YgpyLlE9YwppZihjLmxlbmd0aD4wKXIuYz1jWzBdCnIu
-Y3k9cApxPUguQkQoYSxyKQphLmVDLnNldChwLHEpCnJldHVybiBxfSwKYTpmdW5jdGlvbihhLGIsYyl7
-dmFyIHMscixxLHAsbyxuCmlmKGIueT09PTEwKXtzPWIuegpyPWIuUS5jb25jYXQoYyl9ZWxzZXtyPWMK
-cz1ifXE9cy5jeSsoIjs8IitILlV4KHIpKyI+IikKcD1hLmVDLmdldChxKQppZihwIT1udWxsKXJldHVy
-biBwCm89bmV3IEguSmMobnVsbCxudWxsKQpvLnk9MTAKby56PXMKby5RPXIKby5jeT1xCm49SC5CRChh
-LG8pCmEuZUMuc2V0KHEsbikKcmV0dXJuIG59LApkOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscCxv
-LG49Yi5jeSxtPWMuYSxsPW0ubGVuZ3RoLGs9Yy5iLGo9ay5sZW5ndGgsaT1jLmMsaD1pLmxlbmd0aCxn
-PSIoIitILlV4KG0pCmlmKGo+MCl7cz1sPjA/IiwiOiIiCnI9SC5VeChrKQpnKz1zKyJbIityKyJdIn1p
-ZihoPjApe3M9bD4wPyIsIjoiIgpyPUguUzQoaSkKZys9cysieyIrcisifSJ9cT1uKyhnKyIpIikKcD1h
-LmVDLmdldChxKQppZihwIT1udWxsKXJldHVybiBwCm89bmV3IEguSmMobnVsbCxudWxsKQpvLnk9MTEK
-by56PWIKby5RPWMKby5jeT1xCnI9SC5CRChhLG8pCmEuZUMuc2V0KHEscikKcmV0dXJuIHJ9LApEOmZ1
-bmN0aW9uKGEsYixjLGQpe3ZhciBzLHI9Yi5jeSsoIjwiK0guVXgoYykrIj4iKSxxPWEuZUMuZ2V0KHIp
-CmlmKHEhPW51bGwpcmV0dXJuIHEKcz1ILmh3KGEsYixjLHIsZCkKYS5lQy5zZXQocixzKQpyZXR1cm4g
-c30sCmh3OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHMscixxLHAsbyxuLG0sbAppZihlKXtzPWMubGVu
-Z3RoCnI9bmV3IEFycmF5KHMpCmZvcihxPTAscD0wO3A8czsrK3Ape289Y1twXQppZihvLnk9PT0xKXty
-W3BdPW87KytxfX1pZihxPjApe249SC5QTChhLGIsciwwKQptPUguYlooYSxjLHIsMCkKcmV0dXJuIEgu
-RChhLG4sbSxjIT09bSl9fWw9bmV3IEguSmMobnVsbCxudWxsKQpsLnk9MTIKbC56PWIKbC5RPWMKbC5j
-eT1kCnJldHVybiBILkJEKGEsbCl9LApvOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybnt1OmEsZTpiLHI6
-YyxzOltdLHA6MCxuOmR9fSwKaTpmdW5jdGlvbihhKXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixpLGgs
-Zz1hLnIsZj1hLnMKZm9yKHM9Zy5sZW5ndGgscj0wO3I8czspe3E9Zy5jaGFyQ29kZUF0KHIpCmlmKHE+
-PTQ4JiZxPD01NylyPUguQShyKzEscSxnLGYpCmVsc2UgaWYoKCgocXwzMik+Pj4wKS05NyY2NTUzNSk8
-MjZ8fHE9PT05NXx8cT09PTM2KXI9SC50KGEscixnLGYsITEpCmVsc2UgaWYocT09PTQ2KXI9SC50KGEs
-cixnLGYsITApCmVsc2V7KytyCnN3aXRjaChxKXtjYXNlIDQ0OmJyZWFrCmNhc2UgNTg6Zi5wdXNoKCEx
-KQpicmVhawpjYXNlIDMzOmYucHVzaCghMCkKYnJlYWsKY2FzZSA1OTpmLnB1c2goSC5LKGEudSxhLmUs
-Zi5wb3AoKSkpCmJyZWFrCmNhc2UgOTQ6Zi5wdXNoKEguSChhLnUsZi5wb3AoKSkpCmJyZWFrCmNhc2Ug
-MzU6Zi5wdXNoKEgubShhLnUsNSwiIyIpKQpicmVhawpjYXNlIDY0OmYucHVzaChILm0oYS51LDIsIkAi
-KSkKYnJlYWsKY2FzZSAxMjY6Zi5wdXNoKEgubShhLnUsMywifiIpKQpicmVhawpjYXNlIDYwOmYucHVz
-aChhLnApCmEucD1mLmxlbmd0aApicmVhawpjYXNlIDYyOnA9YS51Cm89Zi5zcGxpY2UoYS5wKQpILnIo
-YS51LGEuZSxvKQphLnA9Zi5wb3AoKQpuPWYucG9wKCkKaWYodHlwZW9mIG49PSJzdHJpbmciKWYucHVz
-aChILkoocCxuLG8pKQplbHNle209SC5LKHAsYS5lLG4pCnN3aXRjaChtLnkpe2Nhc2UgMTE6Zi5wdXNo
-KEguRChwLG0sbyxhLm4pKQpicmVhawpkZWZhdWx0OmYucHVzaChILmEocCxtLG8pKQpicmVha319YnJl
-YWsKY2FzZSAzODpILkkoYSxmKQpicmVhawpjYXNlIDQyOmw9YS51CmYucHVzaChILkMobCxILksobCxh
-LmUsZi5wb3AoKSksYS5uKSkKYnJlYWsKY2FzZSA2MzpsPWEudQpmLnB1c2goSC5CKGwsSC5LKGwsYS5l
-LGYucG9wKCkpLGEubikpCmJyZWFrCmNhc2UgNDc6bD1hLnUKZi5wdXNoKEguZihsLEguSyhsLGEuZSxm
-LnBvcCgpKSxhLm4pKQpicmVhawpjYXNlIDQwOmYucHVzaChhLnApCmEucD1mLmxlbmd0aApicmVhawpj
-YXNlIDQxOnA9YS51Cms9bmV3IEguRygpCmo9cC5zRUEKaT1wLnNFQQpuPWYucG9wKCkKaWYodHlwZW9m
-IG49PSJudW1iZXIiKXN3aXRjaChuKXtjYXNlLTE6aj1mLnBvcCgpCmJyZWFrCmNhc2UtMjppPWYucG9w
-KCkKYnJlYWsKZGVmYXVsdDpmLnB1c2gobikKYnJlYWt9ZWxzZSBmLnB1c2gobikKbz1mLnNwbGljZShh
-LnApCkgucihhLnUsYS5lLG8pCmEucD1mLnBvcCgpCmsuYT1vCmsuYj1qCmsuYz1pCmYucHVzaChILmQo
-cCxILksocCxhLmUsZi5wb3AoKSksaykpCmJyZWFrCmNhc2UgOTE6Zi5wdXNoKGEucCkKYS5wPWYubGVu
-Z3RoCmJyZWFrCmNhc2UgOTM6bz1mLnNwbGljZShhLnApCkgucihhLnUsYS5lLG8pCmEucD1mLnBvcCgp
-CmYucHVzaChvKQpmLnB1c2goLTEpCmJyZWFrCmNhc2UgMTIzOmYucHVzaChhLnApCmEucD1mLmxlbmd0
-aApicmVhawpjYXNlIDEyNTpvPWYuc3BsaWNlKGEucCkKSC55KGEudSxhLmUsbykKYS5wPWYucG9wKCkK
-Zi5wdXNoKG8pCmYucHVzaCgtMikKYnJlYWsKZGVmYXVsdDp0aHJvdyJCYWQgY2hhcmFjdGVyICIrcX19
-fWg9Zi5wb3AoKQpyZXR1cm4gSC5LKGEudSxhLmUsaCl9LApBOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBz
-LHIscT1iLTQ4CmZvcihzPWMubGVuZ3RoO2E8czsrK2Epe3I9Yy5jaGFyQ29kZUF0KGEpCmlmKCEocj49
-NDgmJnI8PTU3KSlicmVhawpxPXEqMTArKHItNDgpfWQucHVzaChxKQpyZXR1cm4gYX0sCnQ6ZnVuY3Rp
-b24oYSxiLGMsZCxlKXt2YXIgcyxyLHEscCxvLG4sbT1iKzEKZm9yKHM9Yy5sZW5ndGg7bTxzOysrbSl7
-cj1jLmNoYXJDb2RlQXQobSkKaWYocj09PTQ2KXtpZihlKWJyZWFrCmU9ITB9ZWxzZXtpZighKCgoKHJ8
-MzIpPj4+MCktOTcmNjU1MzUpPDI2fHxyPT09OTV8fHI9PT0zNikpcT1yPj00OCYmcjw9NTcKZWxzZSBx
-PSEwCmlmKCFxKWJyZWFrfX1wPWMuc3Vic3RyaW5nKGIsbSkKaWYoZSl7cz1hLnUKbz1hLmUKaWYoby55
-PT09MTApbz1vLnoKbj1ILlFvKHMsby56KVtwXQppZihuPT1udWxsKUgudignTm8gIicrcCsnIiBpbiAi
-JytILm1EKG8pKyciJykKZC5wdXNoKEguY0UocyxvLG4pKX1lbHNlIGQucHVzaChwKQpyZXR1cm4gbX0s
-Ckk6ZnVuY3Rpb24oYSxiKXt2YXIgcz1iLnBvcCgpCmlmKDA9PT1zKXtiLnB1c2goSC5tKGEudSwxLCIw
-JiIpKQpyZXR1cm59aWYoMT09PXMpe2IucHVzaChILm0oYS51LDQsIjEmIikpCnJldHVybn10aHJvdyBI
-LmIoUC5oVigiVW5leHBlY3RlZCBleHRlbmRlZCBvcGVyYXRpb24gIitILkVqKHMpKSl9LApLOmZ1bmN0
-aW9uKGEsYixjKXtpZih0eXBlb2YgYz09InN0cmluZyIpcmV0dXJuIEguSihhLGMsYS5zRUEpCmVsc2Ug
-aWYodHlwZW9mIGM9PSJudW1iZXIiKXJldHVybiBILlRWKGEsYixjKQplbHNlIHJldHVybiBjfSwKcjpm
-dW5jdGlvbihhLGIsYyl7dmFyIHMscj1jLmxlbmd0aApmb3Iocz0wO3M8cjsrK3MpY1tzXT1ILksoYSxi
-LGNbc10pfSwKeTpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj1jLmxlbmd0aApmb3Iocz0yO3M8cjtzKz0z
-KWNbc109SC5LKGEsYixjW3NdKX0sClRWOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHE9Yi55CmlmKHE9
-PT0xMCl7aWYoYz09PTApcmV0dXJuIGIuegpzPWIuUQpyPXMubGVuZ3RoCmlmKGM8PXIpcmV0dXJuIHNb
-Yy0xXQpjLT1yCmI9Yi56CnE9Yi55fWVsc2UgaWYoYz09PTApcmV0dXJuIGIKaWYocSE9PTkpdGhyb3cg
-SC5iKFAuaFYoIkluZGV4ZWQgYmFzZSBtdXN0IGJlIGFuIGludGVyZmFjZSB0eXBlIikpCnM9Yi5RCmlm
-KGM8PXMubGVuZ3RoKXJldHVybiBzW2MtMV0KdGhyb3cgSC5iKFAuaFYoIkJhZCBpbmRleCAiK2MrIiBm
-b3IgIitiLncoMCkpKX0sCldlOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHMscixxLHAsbyxuLG0sbCxr
-LGoKaWYoYj09PWQpcmV0dXJuITAKaWYoIUguQTgoZCkpaWYoIShkPT09dC5fKSlzPWQ9PT10LksKZWxz
-ZSBzPSEwCmVsc2Ugcz0hMAppZihzKXJldHVybiEwCnI9Yi55CmlmKHI9PT00KXJldHVybiEwCmlmKEgu
-QTgoYikpcmV0dXJuITEKaWYoYi55IT09MSlzPWI9PT10LlB8fGI9PT10LlQKZWxzZSBzPSEwCmlmKHMp
-cmV0dXJuITAKcT1yPT09MTMKaWYocSlpZihILldlKGEsY1tiLnpdLGMsZCxlKSlyZXR1cm4hMApwPWQu
-eQppZihyPT09NilyZXR1cm4gSC5XZShhLGIueixjLGQsZSkKaWYocD09PTYpe3M9ZC56CnJldHVybiBI
-LldlKGEsYixjLHMsZSl9aWYocj09PTgpe2lmKCFILldlKGEsYi56LGMsZCxlKSlyZXR1cm4hMQpyZXR1
-cm4gSC5XZShhLEgueFooYSxiKSxjLGQsZSl9aWYocj09PTcpe3M9SC5XZShhLGIueixjLGQsZSkKcmV0
-dXJuIHN9aWYocD09PTgpe2lmKEguV2UoYSxiLGMsZC56LGUpKXJldHVybiEwCnJldHVybiBILldlKGEs
-YixjLEgueFooYSxkKSxlKX1pZihwPT09Nyl7cz1ILldlKGEsYixjLGQueixlKQpyZXR1cm4gc31pZihx
-KXJldHVybiExCnM9ciE9PTExCmlmKCghc3x8cj09PTEyKSYmZD09PXQuWSlyZXR1cm4hMAppZihwPT09
-MTIpe2lmKGI9PT10LkQpcmV0dXJuITAKaWYociE9PTEyKXJldHVybiExCm89Yi5RCm49ZC5RCm09by5s
-ZW5ndGgKaWYobSE9PW4ubGVuZ3RoKXJldHVybiExCmM9Yz09bnVsbD9vOm8uY29uY2F0KGMpCmU9ZT09
-bnVsbD9uOm4uY29uY2F0KGUpCmZvcihsPTA7bDxtOysrbCl7az1vW2xdCmo9bltsXQppZighSC5XZShh
-LGssYyxqLGUpfHwhSC5XZShhLGosZSxrLGMpKXJldHVybiExfXJldHVybiBILmJPKGEsYi56LGMsZC56
-LGUpfWlmKHA9PT0xMSl7aWYoYj09PXQuRClyZXR1cm4hMAppZihzKXJldHVybiExCnJldHVybiBILmJP
-KGEsYixjLGQsZSl9aWYocj09PTkpe2lmKHAhPT05KXJldHVybiExCnJldHVybiBILnBHKGEsYixjLGQs
-ZSl9cmV0dXJuITF9LApiTzpmdW5jdGlvbihhMixhMyxhNCxhNSxhNil7dmFyIHMscixxLHAsbyxuLG0s
-bCxrLGosaSxoLGcsZixlLGQsYyxiLGEsYTAsYTEKaWYoIUguV2UoYTIsYTMueixhNCxhNS56LGE2KSly
-ZXR1cm4hMQpzPWEzLlEKcj1hNS5RCnE9cy5hCnA9ci5hCm89cS5sZW5ndGgKbj1wLmxlbmd0aAppZihv
-Pm4pcmV0dXJuITEKbT1uLW8KbD1zLmIKaz1yLmIKaj1sLmxlbmd0aAppPWsubGVuZ3RoCmlmKG8rajxu
-K2kpcmV0dXJuITEKZm9yKGg9MDtoPG87KytoKXtnPXFbaF0KaWYoIUguV2UoYTIscFtoXSxhNixnLGE0
-KSlyZXR1cm4hMX1mb3IoaD0wO2g8bTsrK2gpe2c9bFtoXQppZighSC5XZShhMixwW28raF0sYTYsZyxh
-NCkpcmV0dXJuITF9Zm9yKGg9MDtoPGk7KytoKXtnPWxbbStoXQppZighSC5XZShhMixrW2hdLGE2LGcs
-YTQpKXJldHVybiExfWY9cy5jCmU9ci5jCmQ9Zi5sZW5ndGgKYz1lLmxlbmd0aApmb3IoYj0wLGE9MDth
-PGM7YSs9Myl7YTA9ZVthXQpmb3IoOyEwOyl7aWYoYj49ZClyZXR1cm4hMQphMT1mW2JdCmIrPTMKaWYo
-YTA8YTEpcmV0dXJuITEKaWYoYTE8YTApY29udGludWUKZz1mW2ItMV0KaWYoIUguV2UoYTIsZVthKzJd
-LGE2LGcsYTQpKXJldHVybiExCmJyZWFrfX1yZXR1cm4hMH0sCnBHOmZ1bmN0aW9uKGEsYixjLGQsZSl7
-dmFyIHMscixxLHAsbyxuLG0sbCxrPWIueixqPWQuegppZihrPT09ail7cz1iLlEKcj1kLlEKcT1zLmxl
-bmd0aApmb3IocD0wO3A8cTsrK3Ape289c1twXQpuPXJbcF0KaWYoIUguV2UoYSxvLGMsbixlKSlyZXR1
-cm4hMX1yZXR1cm4hMH1pZihkPT09dC5LKXJldHVybiEwCm09SC5RbyhhLGspCmlmKG09PW51bGwpcmV0
-dXJuITEKbD1tW2pdCmlmKGw9PW51bGwpcmV0dXJuITEKcT1sLmxlbmd0aApyPWQuUQpmb3IocD0wO3A8
-cTsrK3ApaWYoIUguV2UoYSxILmNFKGEsYixsW3BdKSxjLHJbcF0sZSkpcmV0dXJuITEKcmV0dXJuITB9
-LApsUjpmdW5jdGlvbihhKXt2YXIgcyxyPWEueQppZighKGE9PT10LlB8fGE9PT10LlQpKWlmKCFILkE4
-KGEpKWlmKHIhPT03KWlmKCEocj09PTYmJkgubFIoYS56KSkpcz1yPT09OCYmSC5sUihhLnopCmVsc2Ug
-cz0hMAplbHNlIHM9ITAKZWxzZSBzPSEwCmVsc2Ugcz0hMApyZXR1cm4gc30sCmNjOmZ1bmN0aW9uKGEp
-e3ZhciBzCmlmKCFILkE4KGEpKWlmKCEoYT09PXQuXykpcz1hPT09dC5LCmVsc2Ugcz0hMAplbHNlIHM9
-ITAKcmV0dXJuIHN9LApBODpmdW5jdGlvbihhKXt2YXIgcz1hLnkKcmV0dXJuIHM9PT0yfHxzPT09M3x8
-cz09PTR8fHM9PT01fHxhPT09dC5XfSwKSXg6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHE9T2JqZWN0Lmtl
-eXMoYikscD1xLmxlbmd0aApmb3Iocz0wO3M8cDsrK3Mpe3I9cVtzXQphW3JdPWJbcl19fSwKSmM6ZnVu
-Y3Rpb24gSmMoYSxiKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8ueD1fLnI9Xy5jPW51bGwKXy55PTAK
-Xy5jeT1fLmN4PV8uY2g9Xy5RPV8uej1udWxsfSwKRzpmdW5jdGlvbiBHKCl7dGhpcy5jPXRoaXMuYj10
-aGlzLmE9bnVsbH0sCmxZOmZ1bmN0aW9uIGxZKGEpe3RoaXMuYT1hfSwKa1M6ZnVuY3Rpb24ga1MoKXt9
-LAppTTpmdW5jdGlvbiBpTShhKXt0aGlzLmE9YX0sClI5OmZ1bmN0aW9uKGEpe3JldHVybiB0LncuYihh
-KXx8dC5CLmIoYSl8fHQuZHouYihhKXx8dC5JLmIoYSl8fHQuQS5iKGEpfHx0Lmc0LmIoYSl8fHQuZzIu
-YihhKX0sCkpnOmZ1bmN0aW9uKGEpe3JldHVybiB2Lm1hbmdsZWRHbG9iYWxOYW1lc1thXX19LEo9ewpR
-dTpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm57aTphLHA6YixlOmMseDpkfX0sCmtzOmZ1bmN0aW9uKGEp
-e3ZhciBzLHIscSxwLG89YVt2LmRpc3BhdGNoUHJvcGVydHlOYW1lXQppZihvPT1udWxsKWlmKCQuQnY9
-PW51bGwpe0guWEQoKQpvPWFbdi5kaXNwYXRjaFByb3BlcnR5TmFtZV19aWYobyE9bnVsbCl7cz1vLnAK
-aWYoITE9PT1zKXJldHVybiBvLmkKaWYoITA9PT1zKXJldHVybiBhCnI9T2JqZWN0LmdldFByb3RvdHlw
-ZU9mKGEpCmlmKHM9PT1yKXJldHVybiBvLmkKaWYoby5lPT09cil0aHJvdyBILmIoUC5TWSgiUmV0dXJu
-IGludGVyY2VwdG9yIGZvciAiK0guRWoocyhhLG8pKSkpfXE9YS5jb25zdHJ1Y3RvcgpwPXE9PW51bGw/
-bnVsbDpxW0ouUlAoKV0KaWYocCE9bnVsbClyZXR1cm4gcApwPUgudzMoYSkKaWYocCE9bnVsbClyZXR1
-cm4gcAppZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gQy5ERwpzPU9iamVjdC5nZXRQcm90b3R5
-cGVPZihhKQppZihzPT1udWxsKXJldHVybiBDLlpRCmlmKHM9PT1PYmplY3QucHJvdG90eXBlKXJldHVy
-biBDLlpRCmlmKHR5cGVvZiBxPT0iZnVuY3Rpb24iKXtPYmplY3QuZGVmaW5lUHJvcGVydHkocSxKLlJQ
-KCkse3ZhbHVlOkMudkIsZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0
-cnVlfSkKcmV0dXJuIEMudkJ9cmV0dXJuIEMudkJ9LApSUDpmdW5jdGlvbigpe3ZhciBzPSQuem0KcmV0
-dXJuIHM9PW51bGw/JC56bT12LmdldElzb2xhdGVUYWcoIl8kZGFydF9qcyIpOnN9LApRaTpmdW5jdGlv
-bihhLGIpe2lmKGE8MHx8YT40Mjk0OTY3Mjk1KXRocm93IEguYihQLlRFKGEsMCw0Mjk0OTY3Mjk1LCJs
-ZW5ndGgiLG51bGwpKQpyZXR1cm4gSi5weShuZXcgQXJyYXkoYSksYil9LApLaDpmdW5jdGlvbihhLGIp
-e2lmKGE8MCl0aHJvdyBILmIoUC54WSgiTGVuZ3RoIG11c3QgYmUgYSBub24tbmVnYXRpdmUgaW50ZWdl
-cjogIithKSkKcmV0dXJuIEguVk0obmV3IEFycmF5KGEpLGIuQygiamQ8MD4iKSl9LApweTpmdW5jdGlv
-bihhLGIpe3JldHVybiBKLkVwKEguVk0oYSxiLkMoImpkPDA+IikpLGIpfSwKRXA6ZnVuY3Rpb24oYSxi
-KXthLmZpeGVkJGxlbmd0aD1BcnJheQpyZXR1cm4gYX0sCnpDOmZ1bmN0aW9uKGEpe2EuZml4ZWQkbGVu
-Z3RoPUFycmF5CmEuaW1tdXRhYmxlJGxpc3Q9QXJyYXkKcmV0dXJuIGF9LApHYTpmdW5jdGlvbihhKXtp
-ZihhPDI1Nilzd2l0Y2goYSl7Y2FzZSA5OmNhc2UgMTA6Y2FzZSAxMTpjYXNlIDEyOmNhc2UgMTM6Y2Fz
-ZSAzMjpjYXNlIDEzMzpjYXNlIDE2MDpyZXR1cm4hMApkZWZhdWx0OnJldHVybiExfXN3aXRjaChhKXtj
-YXNlIDU3NjA6Y2FzZSA4MTkyOmNhc2UgODE5MzpjYXNlIDgxOTQ6Y2FzZSA4MTk1OmNhc2UgODE5Njpj
-YXNlIDgxOTc6Y2FzZSA4MTk4OmNhc2UgODE5OTpjYXNlIDgyMDA6Y2FzZSA4MjAxOmNhc2UgODIwMjpj
-YXNlIDgyMzI6Y2FzZSA4MjMzOmNhc2UgODIzOTpjYXNlIDgyODc6Y2FzZSAxMjI4ODpjYXNlIDY1Mjc5
-OnJldHVybiEwCmRlZmF1bHQ6cmV0dXJuITF9fSwKbW06ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCmZvcihz
-PWEubGVuZ3RoO2I8czspe3I9Qy54Qi5XKGEsYikKaWYociE9PTMyJiZyIT09MTMmJiFKLkdhKHIpKWJy
-ZWFrOysrYn1yZXR1cm4gYn0sCmMxOmZ1bmN0aW9uKGEsYil7dmFyIHMscgpmb3IoO2I+MDtiPXMpe3M9
-Yi0xCnI9Qy54Qi5PMihhLHMpCmlmKHIhPT0zMiYmciE9PTEzJiYhSi5HYShyKSlicmVha31yZXR1cm4g
-Yn0sClRKOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gSi5xSS5wcm90b3R5
-cGUKaWYodHlwZW9mIGE9PSJzdHJpbmciKXJldHVybiBKLkRyLnByb3RvdHlwZQppZihhPT1udWxsKXJl
-dHVybiBhCmlmKGEuY29uc3RydWN0b3I9PUFycmF5KXJldHVybiBKLmpkLnByb3RvdHlwZQppZih0eXBl
-b2YgYSE9Im9iamVjdCIpe2lmKHR5cGVvZiBhPT0iZnVuY3Rpb24iKXJldHVybiBKLmM1LnByb3RvdHlw
-ZQpyZXR1cm4gYX1pZihhIGluc3RhbmNlb2YgUC5NaClyZXR1cm4gYQpyZXR1cm4gSi5rcyhhKX0sClU2
-OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gSi5Eci5wcm90b3R5cGUKaWYo
-YT09bnVsbClyZXR1cm4gYQppZihhLmNvbnN0cnVjdG9yPT1BcnJheSlyZXR1cm4gSi5qZC5wcm90b3R5
-cGUKaWYodHlwZW9mIGEhPSJvYmplY3QiKXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gSi5j
-NS5wcm90b3R5cGUKcmV0dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAuTWgpcmV0dXJuIGEKcmV0dXJuIEou
-a3MoYSl9LApZRTpmdW5jdGlvbihhKXtpZihhPT1udWxsKXJldHVybiBhCmlmKHR5cGVvZiBhIT0ib2Jq
-ZWN0Iil7aWYodHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIEouYzUucHJvdG90eXBlCnJldHVybiBh
-fWlmKGEgaW5zdGFuY2VvZiBQLk1oKXJldHVybiBhCnJldHVybiBKLmtzKGEpfSwKaWE6ZnVuY3Rpb24o
-YSl7aWYodHlwZW9mIGE9PSJudW1iZXIiKXtpZihNYXRoLmZsb29yKGEpPT1hKXJldHVybiBKLmJVLnBy
-b3RvdHlwZQpyZXR1cm4gSi5WQS5wcm90b3R5cGV9aWYodHlwZW9mIGE9PSJzdHJpbmciKXJldHVybiBK
-LkRyLnByb3RvdHlwZQppZihhPT1udWxsKXJldHVybiBKLndlLnByb3RvdHlwZQppZih0eXBlb2YgYT09
-ImJvb2xlYW4iKXJldHVybiBKLnlFLnByb3RvdHlwZQppZihhLmNvbnN0cnVjdG9yPT1BcnJheSlyZXR1
-cm4gSi5qZC5wcm90b3R5cGUKaWYodHlwZW9mIGEhPSJvYmplY3QiKXtpZih0eXBlb2YgYT09ImZ1bmN0
-aW9uIilyZXR1cm4gSi5jNS5wcm90b3R5cGUKcmV0dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAuTWgpcmV0
-dXJuIGEKcmV0dXJuIEoua3MoYSl9LApyWTpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09InN0cmluZyIp
-cmV0dXJuIEouRHIucHJvdG90eXBlCmlmKGE9PW51bGwpcmV0dXJuIGEKaWYoIShhIGluc3RhbmNlb2Yg
-UC5NaCkpcmV0dXJuIEoua2QucHJvdG90eXBlCnJldHVybiBhfSwKdmQ6ZnVuY3Rpb24oYSl7aWYodHlw
-ZW9mIGE9PSJudW1iZXIiKXJldHVybiBKLnFJLnByb3RvdHlwZQppZihhPT1udWxsKXJldHVybiBhCmlm
-KCEoYSBpbnN0YW5jZW9mIFAuTWgpKXJldHVybiBKLmtkLnByb3RvdHlwZQpyZXR1cm4gYX0sCncxOmZ1
-bmN0aW9uKGEpe2lmKGE9PW51bGwpcmV0dXJuIGEKaWYoYS5jb25zdHJ1Y3Rvcj09QXJyYXkpcmV0dXJu
-IEouamQucHJvdG90eXBlCmlmKHR5cGVvZiBhIT0ib2JqZWN0Iil7aWYodHlwZW9mIGE9PSJmdW5jdGlv
-biIpcmV0dXJuIEouYzUucHJvdG90eXBlCnJldHVybiBhfWlmKGEgaW5zdGFuY2VvZiBQLk1oKXJldHVy
-biBhCnJldHVybiBKLmtzKGEpfSwKQTU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi53MShhKS5lUihhLGIp
-fSwKRWg6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBKLllFKGEpLm1LKGEsYixjKX0sCkVsOmZ1bmN0aW9u
-KGEsYil7cmV0dXJuIEoudzEoYSkuZHIoYSxiKX0sCkY3OmZ1bmN0aW9uKGEpe3JldHVybiBKLlU2KGEp
-LmdvcihhKX0sCkZMOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouclkoYSkuZGQoYSxiKX0sCkdBOmZ1bmN0
-aW9uKGEsYil7cmV0dXJuIEoudzEoYSkuRShhLGIpfSwKSG06ZnVuY3Rpb24oYSl7cmV0dXJuIEouVTYo
-YSkuZ0EoYSl9LApJVDpmdW5jdGlvbihhKXtyZXR1cm4gSi53MShhKS5nbShhKX0sCkp5OmZ1bmN0aW9u
-KGEsYil7cmV0dXJuIEouaWEoYSkuZTcoYSxiKX0sCktWOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouclko
-YSkuRyhhLGIpfSwKTHQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEouWUUoYSkud2coYSl9LApNMTpmdW5jdGlv
-bihhLGIsYyl7cmV0dXJuIEoudzEoYSkuRTIoYSxiLGMpfSwKTXU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4g
-Si5ZRShhKS5zRChhLGIpfSwKUXo6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5yWShhKS5XKGEsYil9LApS
-TTpmdW5jdGlvbihhLGIpe2lmKGE9PW51bGwpcmV0dXJuIGI9PW51bGwKaWYodHlwZW9mIGEhPSJvYmpl
-Y3QiKXJldHVybiBiIT1udWxsJiZhPT09YgpyZXR1cm4gSi5pYShhKS5ETihhLGIpfSwKUlg6ZnVuY3Rp
-b24oYSl7cmV0dXJuIEoudzEoYSkuYnIoYSl9LApUMDpmdW5jdGlvbihhKXtyZXR1cm4gSi5yWShhKS5i
-UyhhKX0sClZ1OmZ1bmN0aW9uKGEpe3JldHVybiBKLnZkKGEpLnpRKGEpfSwKYTY6ZnVuY3Rpb24oYSxi
-KXtyZXR1cm4gSi5yWShhKS5PMihhLGIpfSwKYlQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEouWUUoYSkuRDQo
-YSl9LApiYjpmdW5jdGlvbihhLGIpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIiYmdHlwZW9mIGI9PSJudW1i
-ZXIiKXJldHVybiBhK2IKcmV0dXJuIEouVEooYSkuaChhLGIpfSwKY0g6ZnVuY3Rpb24oYSl7cmV0dXJu
-IEouclkoYSkuaGMoYSl9LApkUjpmdW5jdGlvbihhKXtyZXR1cm4gSi5ZRShhKS5nRChhKX0sCmRaOmZ1
-bmN0aW9uKGEsYixjLGQpe3JldHVybiBKLllFKGEpLk9uKGEsYixjLGQpfSwKZGc6ZnVuY3Rpb24oYSxi
-LGMsZCl7cmV0dXJuIEouclkoYSkuaTcoYSxiLGMsZCl9LApkaDpmdW5jdGlvbihhKXtyZXR1cm4gSi5Z
-RShhKS5GRihhKX0sCmRyOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouWUUoYSkuc2E0KGEsYil9LApoZjpm
-dW5jdGlvbihhKXtyZXR1cm4gSi5pYShhKS5naU8oYSl9LAppZzpmdW5jdGlvbihhKXtyZXR1cm4gSi5Z
-RShhKS5nUWcoYSl9LApqOmZ1bmN0aW9uKGEpe3JldHVybiBKLmlhKGEpLncoYSl9LApsNTpmdW5jdGlv
-bihhLGIpe3JldHVybiBKLllFKGEpLnNoZihhLGIpfSwKbGQ6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBK
-LnJZKGEpLk5qKGEsYixjKX0sCnA0OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouclkoYSkuVGMoYSxiKX0s
-CnEwOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSi5yWShhKS5RaShhLGIsYyl9LApxRjpmdW5jdGlvbihh
-KXtyZXR1cm4gSi5ZRShhKS5nVmwoYSl9LAp0SDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEouWUUoYSku
-cGsoYSxiLGMpfSwKdTk6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBKLncxKGEpLlkoYSxiLGMpfSwKdVU6
-ZnVuY3Rpb24oYSl7cmV0dXJuIEouVTYoYSkuZ2wwKGEpfSwKd2Y6ZnVuY3Rpb24oYSxiKXtyZXR1cm4g
-Si5ZRShhKS5zUk4oYSxiKX0sCng5OmZ1bmN0aW9uKGEsYil7aWYodHlwZW9mIGI9PT0ibnVtYmVyIilp
-ZihhLmNvbnN0cnVjdG9yPT1BcnJheXx8dHlwZW9mIGE9PSJzdHJpbmcifHxILndWKGEsYVt2LmRpc3Bh
-dGNoUHJvcGVydHlOYW1lXSkpaWYoYj4+PjA9PT1iJiZiPGEubGVuZ3RoKXJldHVybiBhW2JdCnJldHVy
-biBKLlU2KGEpLnEoYSxiKX0sCnpsOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouVTYoYSkudGcoYSxiKX0s
-Ckd2OmZ1bmN0aW9uIEd2KCl7fSwKeUU6ZnVuY3Rpb24geUUoKXt9LAp3ZTpmdW5jdGlvbiB3ZSgpe30s
-Ck1GOmZ1bmN0aW9uIE1GKCl7fSwKaUM6ZnVuY3Rpb24gaUMoKXt9LAprZDpmdW5jdGlvbiBrZCgpe30s
-CmM1OmZ1bmN0aW9uIGM1KCl7fSwKamQ6ZnVuY3Rpb24gamQoYSl7dGhpcy4kdGk9YX0sClBvOmZ1bmN0
-aW9uIFBvKGEpe3RoaXMuJHRpPWF9LAptMTpmdW5jdGlvbiBtMShhLGIsYyl7dmFyIF89dGhpcwpfLmE9
-YQpfLmI9YgpfLmM9MApfLmQ9bnVsbApfLiR0aT1jfSwKcUk6ZnVuY3Rpb24gcUkoKXt9LApiVTpmdW5j
-dGlvbiBiVSgpe30sClZBOmZ1bmN0aW9uIFZBKCl7fSwKRHI6ZnVuY3Rpb24gRHIoKXt9fSxQPXsKT2o6
-ZnVuY3Rpb24oKXt2YXIgcyxyLHE9e30KaWYoc2VsZi5zY2hlZHVsZUltbWVkaWF0ZSE9bnVsbClyZXR1
-cm4gUC5FWCgpCmlmKHNlbGYuTXV0YXRpb25PYnNlcnZlciE9bnVsbCYmc2VsZi5kb2N1bWVudCE9bnVs
-bCl7cz1zZWxmLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImRpdiIpCnI9c2VsZi5kb2N1bWVudC5jcmVh
-dGVFbGVtZW50KCJzcGFuIikKcS5hPW51bGwKbmV3IHNlbGYuTXV0YXRpb25PYnNlcnZlcihILnRSKG5l
-dyBQLnRoKHEpLDEpKS5vYnNlcnZlKHMse2NoaWxkTGlzdDp0cnVlfSkKcmV0dXJuIG5ldyBQLmhhKHEs
-cyxyKX1lbHNlIGlmKHNlbGYuc2V0SW1tZWRpYXRlIT1udWxsKXJldHVybiBQLnl0KCkKcmV0dXJuIFAu
-cVcoKX0sClpWOmZ1bmN0aW9uKGEpe3NlbGYuc2NoZWR1bGVJbW1lZGlhdGUoSC50UihuZXcgUC5Wcyh0
-Lk0uYShhKSksMCkpfSwKb0E6ZnVuY3Rpb24oYSl7c2VsZi5zZXRJbW1lZGlhdGUoSC50UihuZXcgUC5G
-dCh0Lk0uYShhKSksMCkpfSwKQno6ZnVuY3Rpb24oYSl7dC5NLmEoYSkKUC5RTigwLGEpfSwKUU46ZnVu
-Y3Rpb24oYSxiKXt2YXIgcz1uZXcgUC5XMygpCnMuQ1koYSxiKQpyZXR1cm4gc30sCkZYOmZ1bmN0aW9u
-KGEpe3JldHVybiBuZXcgUC5paChuZXcgUC52cygkLlgzLGEuQygidnM8MD4iKSksYS5DKCJpaDwwPiIp
-KX0sCkRJOmZ1bmN0aW9uKGEsYil7YS4kMigwLG51bGwpCmIuYj0hMApyZXR1cm4gYi5hfSwKalE6ZnVu
-Y3Rpb24oYSxiKXtQLkplKGEsYil9LAp5QzpmdW5jdGlvbihhLGIpe2IuYU0oMCxhKX0sCmYzOmZ1bmN0
-aW9uKGEsYil7Yi53MChILlJ1KGEpLEgudHMoYSkpfSwKSmU6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHE9
-bmV3IFAuV00oYikscD1uZXcgUC5TWChiKQppZihhIGluc3RhbmNlb2YgUC52cylhLlFkKHEscCx0Lnop
-CmVsc2V7cz10LnoKaWYodC5kLmIoYSkpYS5TcShxLHAscykKZWxzZXtyPW5ldyBQLnZzKCQuWDMsdC5j
-KQpyLmE9NApyLmM9YQpyLlFkKHEscCxzKX19fSwKbHo6ZnVuY3Rpb24oYSl7dmFyIHM9ZnVuY3Rpb24o
-YixjKXtyZXR1cm4gZnVuY3Rpb24oZCxlKXt3aGlsZSh0cnVlKXRyeXtiKGQsZSkKYnJlYWt9Y2F0Y2go
-cil7ZT1yCmQ9Y319fShhLDEpCnJldHVybiAkLlgzLkxqKG5ldyBQLkdzKHMpLHQuSCx0LlMsdC56KX0s
-CklHOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5GeShhLDEpfSwKVGg6ZnVuY3Rpb24oKXtyZXR1cm4g
-Qy53UX0sClltOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5GeShhLDMpfSwKbDA6ZnVuY3Rpb24oYSxi
-KXtyZXR1cm4gbmV3IFAucTQoYSxiLkMoInE0PDA+IikpfSwKazM6ZnVuY3Rpb24oYSxiKXt2YXIgcyxy
-LHEKYi5hPTEKdHJ5e2EuU3EobmV3IFAucFYoYiksbmV3IFAuVTcoYiksdC5QKX1jYXRjaChxKXtzPUgu
-UnUocSkKcj1ILnRzKHEpClAucmIobmV3IFAudnIoYixzLHIpKX19LApBOTpmdW5jdGlvbihhLGIpe3Zh
-ciBzLHIscQpmb3Iocz10LmM7cj1hLmEscj09PTI7KWE9cy5hKGEuYykKaWYocj49NCl7cT1iLmFoKCkK
-Yi5hPWEuYQpiLmM9YS5jClAuSFooYixxKX1lbHNle3E9dC5GLmEoYi5jKQpiLmE9MgpiLmM9YQphLmpR
-KHEpfX0sCkhaOmZ1bmN0aW9uKGEwLGExKXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxmLGUs
-ZCxjPW51bGwsYj17fSxhPWIuYT1hMApmb3Iocz10Lm4scj10LkYscT10LmQ7ITA7KXtwPXt9Cm89YS5h
-PT09OAppZihhMT09bnVsbCl7aWYobyl7bj1zLmEoYS5jKQpQLkwyKGMsYyxhLmIsbi5hLG4uYil9cmV0
-dXJufXAuYT1hMQptPWExLmEKZm9yKGE9YTE7bSE9bnVsbDthPW0sbT1sKXthLmE9bnVsbApQLkhaKGIu
-YSxhKQpwLmE9bQpsPW0uYX1rPWIuYQpqPWsuYwpwLmI9bwpwLmM9agppPSFvCmlmKGkpe2g9YS5jCmg9
-KGgmMSkhPT0wfHwoaCYxNSk9PT04fWVsc2UgaD0hMAppZihoKXtnPWEuYi5iCmlmKG8pe2g9ay5iPT09
-ZwpoPSEoaHx8aCl9ZWxzZSBoPSExCmlmKGgpe3MuYShqKQpQLkwyKGMsYyxrLmIsai5hLGouYikKcmV0
-dXJufWY9JC5YMwppZihmIT09ZykkLlgzPWcKZWxzZSBmPWMKYT1hLmMKaWYoKGEmMTUpPT09OCluZXcg
-UC5SVChwLGIsbykuJDAoKQplbHNlIGlmKGkpe2lmKChhJjEpIT09MCluZXcgUC5ycShwLGopLiQwKCl9
-ZWxzZSBpZigoYSYyKSE9PTApbmV3IFAuUlcoYixwKS4kMCgpCmlmKGYhPW51bGwpJC5YMz1mCmE9cC5j
-CmlmKHEuYihhKSl7ZT1wLmEuYgppZihhLmE+PTQpe2Q9ci5hKGUuYykKZS5jPW51bGwKYTE9ZS5OOChk
-KQplLmE9YS5hCmUuYz1hLmMKYi5hPWEKY29udGludWV9ZWxzZSBQLkE5KGEsZSkKcmV0dXJufX1lPXAu
-YS5iCmQ9ci5hKGUuYykKZS5jPW51bGwKYTE9ZS5OOChkKQphPXAuYgprPXAuYwppZighYSl7ZS4kdGku
-Yy5hKGspCmUuYT00CmUuYz1rfWVsc2V7cy5hKGspCmUuYT04CmUuYz1rfWIuYT1lCmE9ZX19LApWSDpm
-dW5jdGlvbihhLGIpe3ZhciBzCmlmKHQuYWcuYihhKSlyZXR1cm4gYi5MaihhLHQueix0LkssdC5sKQpz
-PXQuYkkKaWYocy5iKGEpKXJldHVybiBzLmEoYSkKdGhyb3cgSC5iKFAuTDMoYSwib25FcnJvciIsIkVy
-cm9yIGhhbmRsZXIgbXVzdCBhY2NlcHQgb25lIE9iamVjdCBvciBvbmUgT2JqZWN0IGFuZCBhIFN0YWNr
-VHJhY2UgYXMgYXJndW1lbnRzLCBhbmQgcmV0dXJuIGEgYSB2YWxpZCByZXN1bHQiKSl9LApwdTpmdW5j
-dGlvbigpe3ZhciBzLHIKZm9yKHM9JC5TNjtzIT1udWxsO3M9JC5TNil7JC5tZz1udWxsCnI9cy5iCiQu
-UzY9cgppZihyPT1udWxsKSQuazg9bnVsbApzLmEuJDAoKX19LAplTjpmdW5jdGlvbigpeyQuVUQ9ITAK
-dHJ5e1AucHUoKX1maW5hbGx5eyQubWc9bnVsbAokLlVEPSExCmlmKCQuUzYhPW51bGwpJC51dCgpLiQx
-KFAuVUkoKSl9fSwKZVc6ZnVuY3Rpb24oYSl7dmFyIHM9bmV3IFAuT00oYSkscj0kLms4CmlmKHI9PW51
-bGwpeyQuUzY9JC5rOD1zCmlmKCEkLlVEKSQudXQoKS4kMShQLlVJKCkpfWVsc2UgJC5rOD1yLmI9c30s
-CnJSOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPSQuUzYKaWYocD09bnVsbCl7UC5lVyhhKQokLm1nPSQu
-azgKcmV0dXJufXM9bmV3IFAuT00oYSkKcj0kLm1nCmlmKHI9PW51bGwpe3MuYj1wCiQuUzY9JC5tZz1z
-fWVsc2V7cT1yLmIKcy5iPXEKJC5tZz1yLmI9cwppZihxPT1udWxsKSQuazg9c319LApyYjpmdW5jdGlv
-bihhKXt2YXIgcz1udWxsLHI9JC5YMwppZihDLk5VPT09cil7UC5UayhzLHMsQy5OVSxhKQpyZXR1cm59
-UC5UayhzLHMscix0Lk0uYShyLkdZKGEpKSl9LApRdzpmdW5jdGlvbihhLGIpe0guY2IoYSwic3RyZWFt
-Iix0LkspCnJldHVybiBuZXcgUC54SShiLkMoInhJPDA+IikpfSwKVGw6ZnVuY3Rpb24oYSxiKXt2YXIg
-cz1ILmNiKGEsImVycm9yIix0LkspCnJldHVybiBuZXcgUC5DdyhzLGI9PW51bGw/UC52MChhKTpiKX0s
-CnYwOmZ1bmN0aW9uKGEpe3ZhciBzCmlmKHQuci5iKGEpKXtzPWEuZ0lJKCkKaWYocyE9bnVsbClyZXR1
-cm4gc31yZXR1cm4gQy5wZH0sCkwyOmZ1bmN0aW9uKGEsYixjLGQsZSl7UC5yUihuZXcgUC5wSyhkLGUp
-KX0sClQ4OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHMscj0kLlgzCmlmKHI9PT1jKXJldHVybiBkLiQw
-KCkKJC5YMz1jCnM9cgp0cnl7cj1kLiQwKCkKcmV0dXJuIHJ9ZmluYWxseXskLlgzPXN9fSwKeXY6ZnVu
-Y3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIHMscj0kLlgzCmlmKHI9PT1jKXJldHVybiBkLiQxKGUpCiQu
-WDM9YwpzPXIKdHJ5e3I9ZC4kMShlKQpyZXR1cm4gcn1maW5hbGx5eyQuWDM9c319LApReDpmdW5jdGlv
-bihhLGIsYyxkLGUsZixnLGgsaSl7dmFyIHMscj0kLlgzCmlmKHI9PT1jKXJldHVybiBkLiQyKGUsZikK
-JC5YMz1jCnM9cgp0cnl7cj1kLiQyKGUsZikKcmV0dXJuIHJ9ZmluYWxseXskLlgzPXN9fSwKVGs6ZnVu
-Y3Rpb24oYSxiLGMsZCl7dmFyIHMKdC5NLmEoZCkKcz1DLk5VIT09YwppZihzKWQ9ISghc3x8ITEpP2Mu
-R1koZCk6Yy5SVChkLHQuSCkKUC5lVyhkKX0sCnRoOmZ1bmN0aW9uIHRoKGEpe3RoaXMuYT1hfSwKaGE6
-ZnVuY3Rpb24gaGEoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKVnM6ZnVuY3Rpb24g
-VnMoYSl7dGhpcy5hPWF9LApGdDpmdW5jdGlvbiBGdChhKXt0aGlzLmE9YX0sClczOmZ1bmN0aW9uIFcz
-KCl7fSwKeUg6ZnVuY3Rpb24geUgoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCmloOmZ1bmN0aW9uIGlo
-KGEsYil7dGhpcy5hPWEKdGhpcy5iPSExCnRoaXMuJHRpPWJ9LApXTTpmdW5jdGlvbiBXTShhKXt0aGlz
-LmE9YX0sClNYOmZ1bmN0aW9uIFNYKGEpe3RoaXMuYT1hfSwKR3M6ZnVuY3Rpb24gR3MoYSl7dGhpcy5h
-PWF9LApGeTpmdW5jdGlvbiBGeShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKR1Y6ZnVuY3Rpb24gR1Yo
-YSxiKXt2YXIgXz10aGlzCl8uYT1hCl8uZD1fLmM9Xy5iPW51bGwKXy4kdGk9Yn0sCnE0OmZ1bmN0aW9u
-IHE0KGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sClBmOmZ1bmN0aW9uIFBmKCl7fSwKWmY6ZnVuY3Rp
-b24gWmYoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKRmU6ZnVuY3Rpb24gRmUoYSxiLGMsZCxlKXt2
-YXIgXz10aGlzCl8uYT1udWxsCl8uYj1hCl8uYz1iCl8uZD1jCl8uZT1kCl8uJHRpPWV9LAp2czpmdW5j
-dGlvbiB2cyhhLGIpe3ZhciBfPXRoaXMKXy5hPTAKXy5iPWEKXy5jPW51bGwKXy4kdGk9Yn0sCmRhOmZ1
-bmN0aW9uIGRhKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApvUTpmdW5jdGlvbiBvUShhLGIpe3RoaXMu
-YT1hCnRoaXMuYj1ifSwKcFY6ZnVuY3Rpb24gcFYoYSl7dGhpcy5hPWF9LApVNzpmdW5jdGlvbiBVNyhh
-KXt0aGlzLmE9YX0sCnZyOmZ1bmN0aW9uIHZyKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9
-Y30sCnJ0OmZ1bmN0aW9uIHJ0KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApLRjpmdW5jdGlvbiBLRihh
-LGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKWkw6ZnVuY3Rpb24gWkwoYSxiLGMpe3RoaXMuYT1hCnRoaXMu
-Yj1iCnRoaXMuYz1jfSwKUlQ6ZnVuY3Rpb24gUlQoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMu
-Yz1jfSwKalo6ZnVuY3Rpb24galooYSl7dGhpcy5hPWF9LApycTpmdW5jdGlvbiBycShhLGIpe3RoaXMu
-YT1hCnRoaXMuYj1ifSwKUlc6ZnVuY3Rpb24gUlcoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCk9NOmZ1
-bmN0aW9uIE9NKGEpe3RoaXMuYT1hCnRoaXMuYj1udWxsfSwKcWg6ZnVuY3Rpb24gcWgoKXt9LApCNTpm
-dW5jdGlvbiBCNShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKdU86ZnVuY3Rpb24gdU8oYSxiKXt0aGlz
-LmE9YQp0aGlzLmI9Yn0sCk1POmZ1bmN0aW9uIE1PKCl7fSwKa1Q6ZnVuY3Rpb24ga1QoKXt9LAp4STpm
-dW5jdGlvbiB4SShhKXt0aGlzLiR0aT1hfSwKQ3c6ZnVuY3Rpb24gQ3coYSxiKXt0aGlzLmE9YQp0aGlz
-LmI9Yn0sCm0wOmZ1bmN0aW9uIG0wKCl7fSwKcEs6ZnVuY3Rpb24gcEsoYSxiKXt0aGlzLmE9YQp0aGlz
-LmI9Yn0sCkppOmZ1bmN0aW9uIEppKCl7fSwKaGo6ZnVuY3Rpb24gaGooYSxiLGMpe3RoaXMuYT1hCnRo
-aXMuYj1iCnRoaXMuYz1jfSwKVnA6ZnVuY3Rpb24gVnAoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCk9S
-OmZ1bmN0aW9uIE9SKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCkVGOmZ1bmN0aW9u
-KGEsYixjKXtyZXR1cm4gYi5DKCJAPDA+IikuS3EoYykuQygiRm88MSwyPiIpLmEoSC5CNyhhLG5ldyBI
-Lk41KGIuQygiQDwwPiIpLktxKGMpLkMoIk41PDEsMj4iKSkpKX0sCkZsOmZ1bmN0aW9uKGEsYil7cmV0
-dXJuIG5ldyBILk41KGEuQygiQDwwPiIpLktxKGIpLkMoIk41PDEsMj4iKSl9LApMczpmdW5jdGlvbihh
-KXtyZXR1cm4gbmV3IFAuYjYoYS5DKCJiNjwwPiIpKX0sClQyOmZ1bmN0aW9uKCl7dmFyIHM9T2JqZWN0
-LmNyZWF0ZShudWxsKQpzWyI8bm9uLWlkZW50aWZpZXIta2V5PiJdPXMKZGVsZXRlIHNbIjxub24taWRl
-bnRpZmllci1rZXk+Il0KcmV0dXJuIHN9LApyajpmdW5jdGlvbihhLGIsYyl7dmFyIHM9bmV3IFAubG0o
-YSxiLGMuQygibG08MD4iKSkKcy5jPWEuZQpyZXR1cm4gc30sCkVQOmZ1bmN0aW9uKGEsYixjKXt2YXIg
-cyxyCmlmKFAuaEIoYSkpe2lmKGI9PT0iKCImJmM9PT0iKSIpcmV0dXJuIiguLi4pIgpyZXR1cm4gYisi
-Li4uIitjfXM9SC5WTShbXSx0LnMpCkMuTm0uaSgkLnhnLGEpCnRyeXtQLlZyKGEscyl9ZmluYWxseXtp
-ZigwPj0kLnhnLmxlbmd0aClyZXR1cm4gSC5PSCgkLnhnLC0xKQokLnhnLnBvcCgpfXI9UC52ZyhiLHQu
-dS5hKHMpLCIsICIpK2MKcmV0dXJuIHIuY2hhckNvZGVBdCgwKT09MD9yOnJ9LApXRTpmdW5jdGlvbihh
-LGIsYyl7dmFyIHMscgppZihQLmhCKGEpKXJldHVybiBiKyIuLi4iK2MKcz1uZXcgUC5SbihiKQpDLk5t
-LmkoJC54ZyxhKQp0cnl7cj1zCnIuYT1QLnZnKHIuYSxhLCIsICIpfWZpbmFsbHl7aWYoMD49JC54Zy5s
-ZW5ndGgpcmV0dXJuIEguT0goJC54ZywtMSkKJC54Zy5wb3AoKX1zLmErPWMKcj1zLmEKcmV0dXJuIHIu
-Y2hhckNvZGVBdCgwKT09MD9yOnJ9LApoQjpmdW5jdGlvbihhKXt2YXIgcyxyCmZvcihzPSQueGcubGVu
-Z3RoLHI9MDtyPHM7KytyKWlmKGE9PT0kLnhnW3JdKXJldHVybiEwCnJldHVybiExfSwKVnI6ZnVuY3Rp
-b24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbSxsPWEuZ20oYSksaz0wLGo9MAp3aGlsZSghMCl7aWYoIShr
-PDgwfHxqPDMpKWJyZWFrCmlmKCFsLkYoKSlyZXR1cm4Kcz1ILkVqKGwuZ2woKSkKQy5ObS5pKGIscykK
-ays9cy5sZW5ndGgrMjsrK2p9aWYoIWwuRigpKXtpZihqPD01KXJldHVybgppZigwPj1iLmxlbmd0aCly
-ZXR1cm4gSC5PSChiLC0xKQpyPWIucG9wKCkKaWYoMD49Yi5sZW5ndGgpcmV0dXJuIEguT0goYiwtMSkK
-cT1iLnBvcCgpfWVsc2V7cD1sLmdsKCk7KytqCmlmKCFsLkYoKSl7aWYoajw9NCl7Qy5ObS5pKGIsSC5F
-aihwKSkKcmV0dXJufXI9SC5FaihwKQppZigwPj1iLmxlbmd0aClyZXR1cm4gSC5PSChiLC0xKQpxPWIu
-cG9wKCkKays9ci5sZW5ndGgrMn1lbHNle289bC5nbCgpOysragpmb3IoO2wuRigpO3A9byxvPW4pe249
-bC5nbCgpOysragppZihqPjEwMCl7d2hpbGUoITApe2lmKCEoaz43NSYmaj4zKSlicmVhawppZigwPj1i
-Lmxlbmd0aClyZXR1cm4gSC5PSChiLC0xKQprLT1iLnBvcCgpLmxlbmd0aCsyOy0tan1DLk5tLmkoYiwi
-Li4uIikKcmV0dXJufX1xPUguRWoocCkKcj1ILkVqKG8pCmsrPXIubGVuZ3RoK3EubGVuZ3RoKzR9fWlm
-KGo+Yi5sZW5ndGgrMil7ays9NQptPSIuLi4ifWVsc2UgbT1udWxsCndoaWxlKCEwKXtpZighKGs+ODAm
-JmIubGVuZ3RoPjMpKWJyZWFrCmlmKDA+PWIubGVuZ3RoKXJldHVybiBILk9IKGIsLTEpCmstPWIucG9w
-KCkubGVuZ3RoKzIKaWYobT09bnVsbCl7ays9NQptPSIuLi4ifX1pZihtIT1udWxsKUMuTm0uaShiLG0p
-CkMuTm0uaShiLHEpCkMuTm0uaShiLHIpfSwKdE06ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHE9UC5Mcyhi
-KQpmb3Iocz1hLmxlbmd0aCxyPTA7cjxhLmxlbmd0aDthLmxlbmd0aD09PXN8fCgwLEgubGspKGEpLCsr
-cilxLmkoMCxiLmEoYVtyXSkpCnJldHVybiBxfSwKbk86ZnVuY3Rpb24oYSl7dmFyIHMscj17fQppZihQ
-LmhCKGEpKXJldHVybiJ7Li4ufSIKcz1uZXcgUC5SbigiIikKdHJ5e0MuTm0uaSgkLnhnLGEpCnMuYSs9
-InsiCnIuYT0hMAphLksoMCxuZXcgUC5yYShyLHMpKQpzLmErPSJ9In1maW5hbGx5e2lmKDA+PSQueGcu
-bGVuZ3RoKXJldHVybiBILk9IKCQueGcsLTEpCiQueGcucG9wKCl9cj1zLmEKcmV0dXJuIHIuY2hhckNv
-ZGVBdCgwKT09MD9yOnJ9LApiNjpmdW5jdGlvbiBiNihhKXt2YXIgXz10aGlzCl8uYT0wCl8uZj1fLmU9
-Xy5kPV8uYz1fLmI9bnVsbApfLnI9MApfLiR0aT1hfSwKYm46ZnVuY3Rpb24gYm4oYSl7dGhpcy5hPWEK
-dGhpcy5jPXRoaXMuYj1udWxsfSwKbG06ZnVuY3Rpb24gbG0oYSxiLGMpe3ZhciBfPXRoaXMKXy5hPWEK
-Xy5iPWIKXy5kPV8uYz1udWxsCl8uJHRpPWN9LAptVzpmdW5jdGlvbiBtVygpe30sCnV5OmZ1bmN0aW9u
-IHV5KCl7fSwKbEQ6ZnVuY3Rpb24gbEQoKXt9LAppbDpmdW5jdGlvbiBpbCgpe30sCnJhOmZ1bmN0aW9u
-IHJhKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApZazpmdW5jdGlvbiBZaygpe30sCnlROmZ1bmN0aW9u
-IHlRKGEpe3RoaXMuYT1hfSwKS1A6ZnVuY3Rpb24gS1AoKXt9LApQbjpmdW5jdGlvbiBQbigpe30sCkdq
-OmZ1bmN0aW9uIEdqKGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCmxmOmZ1bmN0aW9uIGxmKCl7fSwK
-Vmo6ZnVuY3Rpb24gVmooKXt9LApYdjpmdW5jdGlvbiBYdigpe30sCm5ZOmZ1bmN0aW9uIG5ZKCl7fSwK
-V1k6ZnVuY3Rpb24gV1koKXt9LApSVTpmdW5jdGlvbiBSVSgpe30sCnBSOmZ1bmN0aW9uIHBSKCl7fSwK
-QlM6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscAppZih0eXBlb2YgYSE9InN0cmluZyIpdGhyb3cgSC5i
-KEgudEwoYSkpCnM9bnVsbAp0cnl7cz1KU09OLnBhcnNlKGEpfWNhdGNoKHEpe3I9SC5SdShxKQpwPVAu
-cnIoU3RyaW5nKHIpLG51bGwsbnVsbCkKdGhyb3cgSC5iKHApfXA9UC5RZShzKQpyZXR1cm4gcH0sClFl
-OmZ1bmN0aW9uKGEpe3ZhciBzCmlmKGE9PW51bGwpcmV0dXJuIG51bGwKaWYodHlwZW9mIGEhPSJvYmpl
-Y3QiKXJldHVybiBhCmlmKE9iamVjdC5nZXRQcm90b3R5cGVPZihhKSE9PUFycmF5LnByb3RvdHlwZSly
-ZXR1cm4gbmV3IFAudXcoYSxPYmplY3QuY3JlYXRlKG51bGwpKQpmb3Iocz0wO3M8YS5sZW5ndGg7Kytz
-KWFbc109UC5RZShhW3NdKQpyZXR1cm4gYX0sCmt5OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIKaWYo
-YiBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpe3M9YgpkPXMubGVuZ3RoCmlmKGQtYzwxNSlyZXR1cm4gbnVs
-bApyPVAuQ0coYSxzLGMsZCkKaWYociE9bnVsbCYmYSlpZihyLmluZGV4T2YoIlx1ZmZmZCIpPj0wKXJl
-dHVybiBudWxsCnJldHVybiByfXJldHVybiBudWxsfSwKQ0c6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHM9
-YT8kLkhHKCk6JC5yZigpCmlmKHM9PW51bGwpcmV0dXJuIG51bGwKaWYoMD09PWMmJmQ9PT1iLmxlbmd0
-aClyZXR1cm4gUC5SYihzLGIpCnJldHVybiBQLlJiKHMsYi5zdWJhcnJheShjLFAuakIoYyxkLGIubGVu
-Z3RoKSkpfSwKUmI6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCnRyeXtzPWEuZGVjb2RlKGIpCnJldHVybiBz
-fWNhdGNoKHIpe0guUnUocil9cmV0dXJuIG51bGx9LAp4TTpmdW5jdGlvbihhLGIsYyxkLGUsZil7aWYo
-Qy5qbi56WShmLDQpIT09MCl0aHJvdyBILmIoUC5ycigiSW52YWxpZCBiYXNlNjQgcGFkZGluZywgcGFk
-ZGVkIGxlbmd0aCBtdXN0IGJlIG11bHRpcGxlIG9mIGZvdXIsIGlzICIrZixhLGMpKQppZihkK2UhPT1m
-KXRocm93IEguYihQLnJyKCJJbnZhbGlkIGJhc2U2NCBwYWRkaW5nLCAnPScgbm90IGF0IHRoZSBlbmQi
-LGEsYikpCmlmKGU+Mil0aHJvdyBILmIoUC5ycigiSW52YWxpZCBiYXNlNjQgcGFkZGluZywgbW9yZSB0
-aGFuIHR3byAnPScgY2hhcmFjdGVycyIsYSxiKSl9LApHeTpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIG5l
-dyBQLlVkKGEsYil9LApOQzpmdW5jdGlvbihhKXtyZXR1cm4gYS5MdCgpfSwKVWc6ZnVuY3Rpb24oYSxi
-KXtyZXR1cm4gbmV3IFAudHUoYSxbXSxQLkN5KCkpfSwKdVg6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHI9
-bmV3IFAuUm4oIiIpLHE9UC5VZyhyLGIpCnEuaVUoYSkKcz1yLmEKcmV0dXJuIHMuY2hhckNvZGVBdCgw
-KT09MD9zOnN9LApqNDpmdW5jdGlvbihhKXtzd2l0Y2goYSl7Y2FzZSA2NTpyZXR1cm4iTWlzc2luZyBl
-eHRlbnNpb24gYnl0ZSIKY2FzZSA2NzpyZXR1cm4iVW5leHBlY3RlZCBleHRlbnNpb24gYnl0ZSIKY2Fz
-ZSA2OTpyZXR1cm4iSW52YWxpZCBVVEYtOCBieXRlIgpjYXNlIDcxOnJldHVybiJPdmVybG9uZyBlbmNv
-ZGluZyIKY2FzZSA3MzpyZXR1cm4iT3V0IG9mIHVuaWNvZGUgcmFuZ2UiCmNhc2UgNzU6cmV0dXJuIkVu
-Y29kZWQgc3Vycm9nYXRlIgpjYXNlIDc3OnJldHVybiJVbmZpbmlzaGVkIFVURi04IG9jdGV0IHNlcXVl
-bmNlIgpkZWZhdWx0OnJldHVybiIifX0sCmp5OmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscD1jLWIs
-bz1uZXcgVWludDhBcnJheShwKQpmb3Iocz1KLlU2KGEpLHI9MDtyPHA7KytyKXtxPXMucShhLGIrcikK
-aWYodHlwZW9mIHEhPT0ibnVtYmVyIilyZXR1cm4gcS56TSgpCmlmKChxJjQyOTQ5NjcwNDApPj4+MCE9
-PTApcT0yNTUKaWYocj49cClyZXR1cm4gSC5PSChvLHIpCm9bcl09cX1yZXR1cm4gb30sCnV3OmZ1bmN0
-aW9uIHV3KGEsYil7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPW51bGx9LAppODpmdW5jdGlvbiBpOChh
-KXt0aGlzLmE9YX0sCnBnOmZ1bmN0aW9uIHBnKCl7fSwKYzI6ZnVuY3Rpb24gYzIoKXt9LApDVjpmdW5j
-dGlvbiBDVigpe30sClU4OmZ1bmN0aW9uIFU4KCl7fSwKVWs6ZnVuY3Rpb24gVWsoKXt9LAp3STpmdW5j
-dGlvbiB3SSgpe30sClppOmZ1bmN0aW9uIFppKCl7fSwKVWQ6ZnVuY3Rpb24gVWQoYSxiKXt0aGlzLmE9
-YQp0aGlzLmI9Yn0sCks4OmZ1bmN0aW9uIEs4KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApieTpmdW5j
-dGlvbiBieSgpe30sCm9qOmZ1bmN0aW9uIG9qKGEpe3RoaXMuYj1hfSwKTXg6ZnVuY3Rpb24gTXgoYSl7
-dGhpcy5hPWF9LApTaDpmdW5jdGlvbiBTaCgpe30sCnRpOmZ1bmN0aW9uIHRpKGEsYil7dGhpcy5hPWEK
-dGhpcy5iPWJ9LAp0dTpmdW5jdGlvbiB0dShhLGIsYyl7dGhpcy5jPWEKdGhpcy5hPWIKdGhpcy5iPWN9
-LAp1NTpmdW5jdGlvbiB1NSgpe30sCkUzOmZ1bmN0aW9uIEUzKCl7fSwKUnc6ZnVuY3Rpb24gUncoYSl7
-dGhpcy5iPTAKdGhpcy5jPWF9LApHWTpmdW5jdGlvbiBHWShhKXt0aGlzLmE9YX0sCmJ6OmZ1bmN0aW9u
-IGJ6KGEpe3RoaXMuYT1hCnRoaXMuYj0xNgp0aGlzLmM9MH0sClFBOmZ1bmN0aW9uKGEsYil7dmFyIHM9
-SC5IcChhLGIpCmlmKHMhPW51bGwpcmV0dXJuIHMKdGhyb3cgSC5iKFAucnIoYSxudWxsLG51bGwpKX0s
-Cm9zOmZ1bmN0aW9uKGEpe2lmKGEgaW5zdGFuY2VvZiBILlRwKXJldHVybiBhLncoMCkKcmV0dXJuIklu
-c3RhbmNlIG9mICciK0guRWooSC5NKGEpKSsiJyJ9LApPODpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxy
-PWM/Si5LaChhLGQpOkouUWkoYSxkKQppZihhIT09MCYmYiE9bnVsbClmb3Iocz0wO3M8ci5sZW5ndGg7
-KytzKXJbc109YgpyZXR1cm4gcn0sCkNIOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyPUguVk0oW10sYy5D
-KCJqZDwwPiIpKQpmb3Iocz1KLklUKGEpO3MuRigpOylDLk5tLmkocixjLmEocy5nbCgpKSkKaWYoYily
-ZXR1cm4gcgpyZXR1cm4gSi5FcChyLGMpfSwKWTE6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzCmlmKGIpcmV0
-dXJuIFAuZXYoYSxjKQpzPUouRXAoUC5ldihhLGMpLGMpCnJldHVybiBzfSwKZXY6ZnVuY3Rpb24oYSxi
-KXt2YXIgcyxyPUguVk0oW10sYi5DKCJqZDwwPiIpKQpmb3Iocz1KLklUKGEpO3MuRigpOylDLk5tLmko
-cixzLmdsKCkpCnJldHVybiByfSwKQUY6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi56QyhQLkNIKGEsITEs
-YikpfSwKSE06ZnVuY3Rpb24oYSxiLGMpe2lmKHQuYm0uYihhKSlyZXR1cm4gSC5mdyhhLGIsUC5qQihi
-LGMsYS5sZW5ndGgpKQpyZXR1cm4gUC5idyhhLGIsYyl9LApPbzpmdW5jdGlvbihhKXtyZXR1cm4gSC5M
-dyhhKX0sCmJ3OmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscCxvPW51bGwKaWYoYjwwKXRocm93IEgu
-YihQLlRFKGIsMCxhLmxlbmd0aCxvLG8pKQpzPWM9PW51bGwKaWYoIXMmJmM8Yil0aHJvdyBILmIoUC5U
-RShjLGIsYS5sZW5ndGgsbyxvKSkKcj1uZXcgSC5hNyhhLGEubGVuZ3RoLEgueihhKS5DKCJhNzxsRC5F
-PiIpKQpmb3IocT0wO3E8YjsrK3EpaWYoIXIuRigpKXRocm93IEguYihQLlRFKGIsMCxxLG8sbykpCnA9
-W10KaWYocylmb3IoO3IuRigpOylwLnB1c2goci5kKQplbHNlIGZvcihxPWI7cTxjOysrcSl7aWYoIXIu
-RigpKXRocm93IEguYihQLlRFKGMsYixxLG8sbykpCnAucHVzaChyLmQpfXJldHVybiBILmVUKHApfSwK
-bnU6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILlZSKGEsSC52NChhLCExLCEwLCExLCExLCExKSl9LAp2
-ZzpmdW5jdGlvbihhLGIsYyl7dmFyIHM9Si5JVChiKQppZighcy5GKCkpcmV0dXJuIGEKaWYoYy5sZW5n
-dGg9PT0wKXtkbyBhKz1ILkVqKHMuZ2woKSkKd2hpbGUocy5GKCkpfWVsc2V7YSs9SC5FaihzLmdsKCkp
-CmZvcig7cy5GKCk7KWE9YStjK0guRWoocy5nbCgpKX1yZXR1cm4gYX0sCmxyOmZ1bmN0aW9uKGEsYixj
-LGQpe3JldHVybiBuZXcgUC5tcChhLGIsYyxkKX0sCnVvOmZ1bmN0aW9uKCl7dmFyIHM9SC5NMCgpCmlm
-KHMhPW51bGwpcmV0dXJuIFAuaEsocykKdGhyb3cgSC5iKFAuTDQoIidVcmkuYmFzZScgaXMgbm90IHN1
-cHBvcnRlZCIpKX0sCmVQOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIscSxwLG8sbixtPSIwMTIzNDU2
-Nzg5QUJDREVGIgppZihjPT09Qy54TSl7cz0kLno0KCkuYgppZih0eXBlb2YgYiE9InN0cmluZyIpSC52
-KEgudEwoYikpCnM9cy50ZXN0KGIpfWVsc2Ugcz0hMQppZihzKXJldHVybiBiCkguTGgoYykuQygiVWsu
-UyIpLmEoYikKcj1jLmdaRSgpLldKKGIpCmZvcihzPXIubGVuZ3RoLHE9MCxwPSIiO3E8czsrK3Epe289
-cltxXQppZihvPDEyOCl7bj1vPj4+NAppZihuPj04KXJldHVybiBILk9IKGEsbikKbj0oYVtuXSYxPDwo
-byYxNSkpIT09MH1lbHNlIG49ITEKaWYobilwKz1ILkx3KG8pCmVsc2UgcD1kJiZvPT09MzI/cCsiKyI6
-cCsiJSIrbVtvPj4+NCYxNV0rbVtvJjE1XX1yZXR1cm4gcC5jaGFyQ29kZUF0KDApPT0wP3A6cH0sCkdx
-OmZ1bmN0aW9uKGEpe3ZhciBzPU1hdGguYWJzKGEpLHI9YTwwPyItIjoiIgppZihzPj0xMDAwKXJldHVy
-biIiK2EKaWYocz49MTAwKXJldHVybiByKyIwIitzCmlmKHM+PTEwKXJldHVybiByKyIwMCIrcwpyZXR1
-cm4gcisiMDAwIitzfSwKVng6ZnVuY3Rpb24oYSl7aWYoYT49MTAwKXJldHVybiIiK2EKaWYoYT49MTAp
-cmV0dXJuIjAiK2EKcmV0dXJuIjAwIithfSwKaDA6ZnVuY3Rpb24oYSl7aWYoYT49MTApcmV0dXJuIiIr
-YQpyZXR1cm4iMCIrYX0sCnA6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJudW1iZXIifHxILmwoYSl8
-fG51bGw9PWEpcmV0dXJuIEouaihhKQppZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIEpTT04uc3Ry
-aW5naWZ5KGEpCnJldHVybiBQLm9zKGEpfSwKaFY6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLkM2KGEp
-fSwKeFk6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLnUoITEsbnVsbCxudWxsLGEpfSwKTDM6ZnVuY3Rp
-b24oYSxiLGMpe3JldHVybiBuZXcgUC51KCEwLGEsYixjKX0sCk1SOmZ1bmN0aW9uKGEsYixjKXtyZXR1
-cm4gYX0sCk83OmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBQLmJKKG51bGwsbnVsbCwhMCxhLGIsIlZh
-bHVlIG5vdCBpbiByYW5nZSIpfSwKVEU6ZnVuY3Rpb24oYSxiLGMsZCxlKXtyZXR1cm4gbmV3IFAuYkoo
-YixjLCEwLGEsZCwiSW52YWxpZCB2YWx1ZSIpfSwKd0E6ZnVuY3Rpb24oYSxiLGMsZCl7aWYoYTxifHxh
-PmMpdGhyb3cgSC5iKFAuVEUoYSxiLGMsZCxudWxsKSkKcmV0dXJuIGF9LApqQjpmdW5jdGlvbihhLGIs
-Yyl7aWYoMD5hfHxhPmMpdGhyb3cgSC5iKFAuVEUoYSwwLGMsInN0YXJ0IixudWxsKSkKaWYoYiE9bnVs
-bCl7aWYoYT5ifHxiPmMpdGhyb3cgSC5iKFAuVEUoYixhLGMsImVuZCIsbnVsbCkpCnJldHVybiBifXJl
-dHVybiBjfSwKazE6ZnVuY3Rpb24oYSxiKXtpZihhPDApdGhyb3cgSC5iKFAuVEUoYSwwLG51bGwsYixu
-dWxsKSkKcmV0dXJuIGF9LApDZjpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciBzPUgudVAoZT09bnVsbD9K
-LkhtKGIpOmUpCnJldHVybiBuZXcgUC5lWShzLCEwLGEsYywiSW5kZXggb3V0IG9mIHJhbmdlIil9LApM
-NDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAudWIoYSl9LApTWTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3
-IFAuZHMoYSl9LApQVjpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAubGooYSl9LAphNDpmdW5jdGlvbihh
-KXtyZXR1cm4gbmV3IFAuVVYoYSl9LApycjpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIG5ldyBQLmFFKGEs
-YixjKX0sCmhLOmZ1bmN0aW9uKGE1KXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxmLGUsZCxj
-LGIsYSxhMCxhMSxhMixhMz1udWxsLGE0PWE1Lmxlbmd0aAppZihhND49NSl7cz0oKEouUXooYTUsNCle
-NTgpKjN8Qy54Qi5XKGE1LDApXjEwMHxDLnhCLlcoYTUsMSleOTd8Qy54Qi5XKGE1LDIpXjExNnxDLnhC
-LlcoYTUsMyleOTcpPj4+MAppZihzPT09MClyZXR1cm4gUC5LRChhNDxhND9DLnhCLk5qKGE1LDAsYTQp
-OmE1LDUsYTMpLmdsUigpCmVsc2UgaWYocz09PTMyKXJldHVybiBQLktEKEMueEIuTmooYTUsNSxhNCks
-MCxhMykuZ2xSKCl9cj1QLk84KDgsMCwhMSx0LlMpCkMuTm0uWShyLDAsMCkKQy5ObS5ZKHIsMSwtMSkK
-Qy5ObS5ZKHIsMiwtMSkKQy5ObS5ZKHIsNywtMSkKQy5ObS5ZKHIsMywwKQpDLk5tLlkociw0LDApCkMu
-Tm0uWShyLDUsYTQpCkMuTm0uWShyLDYsYTQpCmlmKFAuVUIoYTUsMCxhNCwwLHIpPj0xNClDLk5tLlko
-ciw3LGE0KQpxPXJbMV0KaWYocT49MClpZihQLlVCKGE1LDAscSwyMCxyKT09PTIwKXJbN109cQpwPXJb
-Ml0rMQpvPXJbM10Kbj1yWzRdCm09cls1XQpsPXJbNl0KaWYobDxtKW09bAppZihuPHApbj1tCmVsc2Ug
-aWYobjw9cSluPXErMQppZihvPHApbz1uCms9cls3XTwwCmlmKGspaWYocD5xKzMpe2o9YTMKaz0hMX1l
-bHNle2k9bz4wCmlmKGkmJm8rMT09PW4pe2o9YTMKaz0hMX1lbHNle2lmKCEobTxhNCYmbT09PW4rMiYm
-Si5xMChhNSwiLi4iLG4pKSloPW0+bisyJiZKLnEwKGE1LCIvLi4iLG0tMykKZWxzZSBoPSEwCmlmKGgp
-e2o9YTMKaz0hMX1lbHNle2lmKHE9PT00KWlmKEoucTAoYTUsImZpbGUiLDApKXtpZihwPD0wKXtpZigh
-Qy54Qi5RaShhNSwiLyIsbikpe2c9ImZpbGU6Ly8vIgpzPTN9ZWxzZXtnPSJmaWxlOi8vIgpzPTJ9YTU9
-ZytDLnhCLk5qKGE1LG4sYTQpCnEtPTAKaT1zLTAKbSs9aQpsKz1pCmE0PWE1Lmxlbmd0aApwPTcKbz03
-Cm49N31lbHNlIGlmKG49PT1tKXsrK2wKZj1tKzEKYTU9Qy54Qi5pNyhhNSxuLG0sIi8iKTsrK2E0Cm09
-Zn1qPSJmaWxlIn1lbHNlIGlmKEMueEIuUWkoYTUsImh0dHAiLDApKXtpZihpJiZvKzM9PT1uJiZDLnhC
-LlFpKGE1LCI4MCIsbysxKSl7bC09MwplPW4tMwptLT0zCmE1PUMueEIuaTcoYTUsbyxuLCIiKQphNC09
-MwpuPWV9aj0iaHR0cCJ9ZWxzZSBqPWEzCmVsc2UgaWYocT09PTUmJkoucTAoYTUsImh0dHBzIiwwKSl7
-aWYoaSYmbys0PT09biYmSi5xMChhNSwiNDQzIixvKzEpKXtsLT00CmU9bi00Cm0tPTQKYTU9Si5kZyhh
-NSxvLG4sIiIpCmE0LT0zCm49ZX1qPSJodHRwcyJ9ZWxzZSBqPWEzCms9ITB9fX1lbHNlIGo9YTMKaWYo
-ayl7aT1hNS5sZW5ndGgKaWYoYTQ8aSl7YTU9Si5sZChhNSwwLGE0KQpxLT0wCnAtPTAKby09MApuLT0w
-Cm0tPTAKbC09MH1yZXR1cm4gbmV3IFAuVWYoYTUscSxwLG8sbixtLGwsail9aWYoaj09bnVsbClpZihx
-PjApaj1QLlBpKGE1LDAscSkKZWxzZXtpZihxPT09MCl7UC5SMyhhNSwwLCJJbnZhbGlkIGVtcHR5IHNj
-aGVtZSIpCkguQmkodS5nKX1qPSIifWlmKHA+MCl7ZD1xKzMKYz1kPHA/UC56UihhNSxkLHAtMSk6IiIK
-Yj1QLk9lKGE1LHAsbywhMSkKaT1vKzEKaWYoaTxuKXthPUguSHAoSi5sZChhNSxpLG4pLGEzKQphMD1Q
-LndCKGE9PW51bGw/SC52KFAucnIoIkludmFsaWQgcG9ydCIsYTUsaSkpOmEsail9ZWxzZSBhMD1hM31l
-bHNle2EwPWEzCmI9YTAKYz0iIn1hMT1QLmthKGE1LG4sbSxhMyxqLGIhPW51bGwpCmEyPW08bD9QLmxl
-KGE1LG0rMSxsLGEzKTphMwpyZXR1cm4gbmV3IFAuRG4oaixjLGIsYTAsYTEsYTIsbDxhND9QLnRHKGE1
-LGwrMSxhNCk6YTMpfSwKTXQ6ZnVuY3Rpb24oYSl7SC5oKGEpCnJldHVybiBQLmt1KGEsMCxhLmxlbmd0
-aCxDLnhNLCExKX0sCldYOmZ1bmN0aW9uKGEpe3ZhciBzPXQuTgpyZXR1cm4gQy5ObS5OMChILlZNKGEu
-c3BsaXQoIiYiKSx0LnMpLFAuRmwocyxzKSxuZXcgUC5uMShDLnhNKSx0LkopfSwKSGg6ZnVuY3Rpb24o
-YSxiLGMpe3ZhciBzLHIscSxwLG8sbixtPSJJUHY0IGFkZHJlc3Mgc2hvdWxkIGNvbnRhaW4gZXhhY3Rs
-eSA0IHBhcnRzIixsPSJlYWNoIHBhcnQgbXVzdCBiZSBpbiB0aGUgcmFuZ2UgMC4uMjU1IixrPW5ldyBQ
-LmNTKGEpLGo9bmV3IFVpbnQ4QXJyYXkoNCkKZm9yKHM9YixyPXMscT0wO3M8YzsrK3Mpe3A9Qy54Qi5P
-MihhLHMpCmlmKHAhPT00Nil7aWYoKHBeNDgpPjkpay4kMigiaW52YWxpZCBjaGFyYWN0ZXIiLHMpfWVs
-c2V7aWYocT09PTMpay4kMihtLHMpCm89UC5RQShDLnhCLk5qKGEscixzKSxudWxsKQppZihvPjI1NSlr
-LiQyKGwscikKbj1xKzEKaWYocT49NClyZXR1cm4gSC5PSChqLHEpCmpbcV09bwpyPXMrMQpxPW59fWlm
-KHEhPT0zKWsuJDIobSxjKQpvPVAuUUEoQy54Qi5OaihhLHIsYyksbnVsbCkKaWYobz4yNTUpay4kMihs
-LHIpCmlmKHE+PTQpcmV0dXJuIEguT0goaixxKQpqW3FdPW8KcmV0dXJuIGp9LAplZzpmdW5jdGlvbihh
-LGIsYTApe3ZhciBzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZSxkPW5ldyBQLlZDKGEpLGM9bmV3
-IFAuSlQoZCxhKQppZihhLmxlbmd0aDwyKWQuJDEoImFkZHJlc3MgaXMgdG9vIHNob3J0IikKcz1ILlZN
-KFtdLHQuYSkKZm9yKHI9YixxPXIscD0hMSxvPSExO3I8YTA7KytyKXtuPUMueEIuTzIoYSxyKQppZihu
-PT09NTgpe2lmKHI9PT1iKXsrK3IKaWYoQy54Qi5PMihhLHIpIT09NTgpZC4kMigiaW52YWxpZCBzdGFy
-dCBjb2xvbi4iLHIpCnE9cn1pZihyPT09cSl7aWYocClkLiQyKCJvbmx5IG9uZSB3aWxkY2FyZCBgOjpg
-IGlzIGFsbG93ZWQiLHIpCkMuTm0uaShzLC0xKQpwPSEwfWVsc2UgQy5ObS5pKHMsYy4kMihxLHIpKQpx
-PXIrMX1lbHNlIGlmKG49PT00NilvPSEwfWlmKHMubGVuZ3RoPT09MClkLiQxKCJ0b28gZmV3IHBhcnRz
-IikKbT1xPT09YTAKbD1DLk5tLmdyWihzKQppZihtJiZsIT09LTEpZC4kMigiZXhwZWN0ZWQgYSBwYXJ0
-IGFmdGVyIGxhc3QgYDpgIixhMCkKaWYoIW0paWYoIW8pQy5ObS5pKHMsYy4kMihxLGEwKSkKZWxzZXtr
-PVAuSGgoYSxxLGEwKQpDLk5tLmkocywoa1swXTw8OHxrWzFdKT4+PjApCkMuTm0uaShzLChrWzJdPDw4
-fGtbM10pPj4+MCl9aWYocCl7aWYocy5sZW5ndGg+NylkLiQxKCJhbiBhZGRyZXNzIHdpdGggYSB3aWxk
-Y2FyZCBtdXN0IGhhdmUgbGVzcyB0aGFuIDcgcGFydHMiKX1lbHNlIGlmKHMubGVuZ3RoIT09OClkLiQx
-KCJhbiBhZGRyZXNzIHdpdGhvdXQgYSB3aWxkY2FyZCBtdXN0IGNvbnRhaW4gZXhhY3RseSA4IHBhcnRz
-IikKaj1uZXcgVWludDhBcnJheSgxNikKZm9yKGw9cy5sZW5ndGgsaT05LWwscj0wLGg9MDtyPGw7Kyty
-KXtnPXNbcl0KaWYoZz09PS0xKWZvcihmPTA7ZjxpOysrZil7aWYoaDwwfHxoPj0xNilyZXR1cm4gSC5P
-SChqLGgpCmpbaF09MAplPWgrMQppZihlPj0xNilyZXR1cm4gSC5PSChqLGUpCmpbZV09MApoKz0yfWVs
-c2V7ZT1DLmpuLndHKGcsOCkKaWYoaDwwfHxoPj0xNilyZXR1cm4gSC5PSChqLGgpCmpbaF09ZQplPWgr
-MQppZihlPj0xNilyZXR1cm4gSC5PSChqLGUpCmpbZV09ZyYyNTUKaCs9Mn19cmV0dXJuIGp9LApLTDpm
-dW5jdGlvbihhLGIsYyxkLGUsZixnKXt2YXIgcyxyLHEscCxvLG4KZj1mPT1udWxsPyIiOlAuUGkoZiww
-LGYubGVuZ3RoKQpnPVAuelIoZywwLGc9PW51bGw/MDpnLmxlbmd0aCkKYT1QLk9lKGEsMCxhPT1udWxs
-PzA6YS5sZW5ndGgsITEpCnM9UC5sZShudWxsLDAsMCxlKQpyPVAudEcobnVsbCwwLDApCmQ9UC53Qihk
-LGYpCnE9Zj09PSJmaWxlIgppZihhPT1udWxsKXA9Zy5sZW5ndGghPT0wfHxkIT1udWxsfHxxCmVsc2Ug
-cD0hMQppZihwKWE9IiIKcD1hPT1udWxsCm89IXAKYj1QLmthKGIsMCxiPT1udWxsPzA6Yi5sZW5ndGgs
-YyxmLG8pCm49Zi5sZW5ndGg9PT0wCmlmKG4mJnAmJiFDLnhCLm4oYiwiLyIpKWI9UC53RihiLCFufHxv
-KQplbHNlIGI9UC54ZShiKQpyZXR1cm4gbmV3IFAuRG4oZixnLHAmJkMueEIubihiLCIvLyIpPyIiOmEs
-ZCxiLHMscil9LAp3SzpmdW5jdGlvbihhKXtpZihhPT09Imh0dHAiKXJldHVybiA4MAppZihhPT09Imh0
-dHBzIilyZXR1cm4gNDQzCnJldHVybiAwfSwKUjM6ZnVuY3Rpb24oYSxiLGMpe3Rocm93IEguYihQLnJy
-KGMsYSxiKSl9LApYZDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixpLGg9
-bnVsbCxnPWIubGVuZ3RoCmlmKGchPT0wKXtxPTAKd2hpbGUoITApe2lmKCEocTxnKSl7cz0iIgpyPTAK
-YnJlYWt9aWYoQy54Qi5XKGIscSk9PT02NCl7cz1DLnhCLk5qKGIsMCxxKQpyPXErMQpicmVha30rK3F9
-aWYocjxnJiZDLnhCLlcoYixyKT09PTkxKXtmb3IocD1yLG89LTE7cDxnOysrcCl7bj1DLnhCLlcoYixw
-KQppZihuPT09MzcmJm88MCl7bT1DLnhCLlFpKGIsIjI1IixwKzEpP3ArMjpwCm89cApwPW19ZWxzZSBp
-ZihuPT09OTMpYnJlYWt9aWYocD09PWcpdGhyb3cgSC5iKFAucnIoIkludmFsaWQgSVB2NiBob3N0IGVu
-dHJ5LiIsYixyKSkKbD1vPDA/cDpvClAuZWcoYixyKzEsbCk7KytwCmlmKHAhPT1nJiZDLnhCLlcoYixw
-KSE9PTU4KXRocm93IEguYihQLnJyKCJJbnZhbGlkIGVuZCBvZiBhdXRob3JpdHkiLGIscCkpfWVsc2Ug
-cD1yCndoaWxlKCEwKXtpZighKHA8Zykpe2s9aApicmVha31pZihDLnhCLlcoYixwKT09PTU4KXtqPUMu
-eEIuRyhiLHArMSkKaz1qLmxlbmd0aCE9PTA/UC5RQShqLGgpOmgKYnJlYWt9KytwfWk9Qy54Qi5Oaihi
-LHIscCl9ZWxzZXtrPWgKaT1rCnM9IiJ9cmV0dXJuIFAuS0woaSxoLEguVk0oYy5zcGxpdCgiLyIpLHQu
-cyksayxkLGEscyl9LAprRTpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8KZm9yKHM9YS5sZW5ndGgs
-cj0wO3I8czsrK3Ipe3E9YVtyXQpxLnRvU3RyaW5nCnA9Si5VNihxKQpvPXAuZ0EocSkKaWYoMD5vKUgu
-dihQLlRFKDAsMCxwLmdBKHEpLG51bGwsbnVsbCkpCmlmKEguU1EocSwiLyIsMCkpe3M9UC5MNCgiSWxs
-ZWdhbCBwYXRoIGNoYXJhY3RlciAiK0guRWoocSkpCnRocm93IEguYihzKX19fSwKSE46ZnVuY3Rpb24o
-YSxiLGMpe3ZhciBzLHIscQpmb3Iocz1ILnFDKGEsYyxudWxsLEgudDYoYSkuYykscz1uZXcgSC5hNyhz
-LHMuZ0Eocykscy4kdGkuQygiYTc8YUwuRT4iKSk7cy5GKCk7KXtyPXMuZApxPVAubnUoJ1siKi86PD4/
-XFxcXHxdJykKci50b1N0cmluZwppZihILlNRKHIscSwwKSl7cz1QLkw0KCJJbGxlZ2FsIGNoYXJhY3Rl
-ciBpbiBwYXRoOiAiK3IpCnRocm93IEguYihzKX19fSwKcmc6ZnVuY3Rpb24oYSxiKXt2YXIgcwppZigh
-KDY1PD1hJiZhPD05MCkpcz05Nzw9YSYmYTw9MTIyCmVsc2Ugcz0hMAppZihzKXJldHVybgpzPVAuTDQo
-IklsbGVnYWwgZHJpdmUgbGV0dGVyICIrUC5PbyhhKSkKdGhyb3cgSC5iKHMpfSwKd0I6ZnVuY3Rpb24o
-YSxiKXtpZihhIT1udWxsJiZhPT09UC53SyhiKSlyZXR1cm4gbnVsbApyZXR1cm4gYX0sCk9lOmZ1bmN0
-aW9uKGEsYixjLGQpe3ZhciBzLHIscSxwLG8sbgppZihhPT1udWxsKXJldHVybiBudWxsCmlmKGI9PT1j
-KXJldHVybiIiCmlmKEMueEIuTzIoYSxiKT09PTkxKXtzPWMtMQppZihDLnhCLk8yKGEscykhPT05Myl7
-UC5SMyhhLGIsIk1pc3NpbmcgZW5kIGBdYCB0byBtYXRjaCBgW2AgaW4gaG9zdCIpCkguQmkodS5nKX1y
-PWIrMQpxPVAudG8oYSxyLHMpCmlmKHE8cyl7cD1xKzEKbz1QLk9BKGEsQy54Qi5RaShhLCIyNSIscCk/
-cSszOnAscywiJTI1Iil9ZWxzZSBvPSIiClAuZWcoYSxyLHEpCnJldHVybiBDLnhCLk5qKGEsYixxKS50
-b0xvd2VyQ2FzZSgpK28rIl0ifWZvcihuPWI7bjxjOysrbilpZihDLnhCLk8yKGEsbik9PT01OCl7cT1D
-LnhCLlhVKGEsIiUiLGIpCnE9cT49YiYmcTxjP3E6YwppZihxPGMpe3A9cSsxCm89UC5PQShhLEMueEIu
-UWkoYSwiMjUiLHApP3ErMzpwLGMsIiUyNSIpfWVsc2Ugbz0iIgpQLmVnKGEsYixxKQpyZXR1cm4iWyIr
-Qy54Qi5OaihhLGIscSkrbysiXSJ9cmV0dXJuIFAuT0woYSxiLGMpfSwKdG86ZnVuY3Rpb24oYSxiLGMp
-e3ZhciBzPUMueEIuWFUoYSwiJSIsYikKcmV0dXJuIHM+PWImJnM8Yz9zOmN9LApPQTpmdW5jdGlvbihh
-LGIsYyxkKXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixpPWQhPT0iIj9uZXcgUC5SbihkKTpudWxsCmZv
-cihzPWIscj1zLHE9ITA7czxjOyl7cD1DLnhCLk8yKGEscykKaWYocD09PTM3KXtvPVAucnYoYSxzLCEw
-KQpuPW89PW51bGwKaWYobiYmcSl7cys9Mwpjb250aW51ZX1pZihpPT1udWxsKWk9bmV3IFAuUm4oIiIp
-Cm09aS5hKz1DLnhCLk5qKGEscixzKQppZihuKW89Qy54Qi5OaihhLHMscyszKQplbHNlIGlmKG89PT0i
-JSIpe1AuUjMoYSxzLCJab25lSUQgc2hvdWxkIG5vdCBjb250YWluICUgYW55bW9yZSIpCkguQmkodS5n
-KX1pLmE9bStvCnMrPTMKcj1zCnE9ITB9ZWxzZXtpZihwPDEyNyl7bj1wPj4+NAppZihuPj04KXJldHVy
-biBILk9IKEMuRjMsbikKbj0oQy5GM1tuXSYxPDwocCYxNSkpIT09MH1lbHNlIG49ITEKaWYobil7aWYo
-cSYmNjU8PXAmJjkwPj1wKXtpZihpPT1udWxsKWk9bmV3IFAuUm4oIiIpCmlmKHI8cyl7aS5hKz1DLnhC
-Lk5qKGEscixzKQpyPXN9cT0hMX0rK3N9ZWxzZXtpZigocCY2NDUxMik9PT01NTI5NiYmcysxPGMpe2w9
-Qy54Qi5PMihhLHMrMSkKaWYoKGwmNjQ1MTIpPT09NTYzMjApe3A9KHAmMTAyMyk8PDEwfGwmMTAyM3w2
-NTUzNgprPTJ9ZWxzZSBrPTF9ZWxzZSBrPTEKaj1DLnhCLk5qKGEscixzKQppZihpPT1udWxsKXtpPW5l
-dyBQLlJuKCIiKQpuPWl9ZWxzZSBuPWkKbi5hKz1qCm4uYSs9UC56WChwKQpzKz1rCnI9c319fWlmKGk9
-PW51bGwpcmV0dXJuIEMueEIuTmooYSxiLGMpCmlmKHI8YylpLmErPUMueEIuTmooYSxyLGMpCm49aS5h
-CnJldHVybiBuLmNoYXJDb2RlQXQoMCk9PTA/bjpufSwKT0w6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIs
-cSxwLG8sbixtLGwsayxqLGkKZm9yKHM9YixyPXMscT1udWxsLHA9ITA7czxjOyl7bz1DLnhCLk8yKGEs
-cykKaWYobz09PTM3KXtuPVAucnYoYSxzLCEwKQptPW49PW51bGwKaWYobSYmcCl7cys9Mwpjb250aW51
-ZX1pZihxPT1udWxsKXE9bmV3IFAuUm4oIiIpCmw9Qy54Qi5OaihhLHIscykKaz1xLmErPSFwP2wudG9M
-b3dlckNhc2UoKTpsCmlmKG0pe249Qy54Qi5OaihhLHMscyszKQpqPTN9ZWxzZSBpZihuPT09IiUiKXtu
-PSIlMjUiCmo9MX1lbHNlIGo9MwpxLmE9aytuCnMrPWoKcj1zCnA9ITB9ZWxzZXtpZihvPDEyNyl7bT1v
-Pj4+NAppZihtPj04KXJldHVybiBILk9IKEMuZWEsbSkKbT0oQy5lYVttXSYxPDwobyYxNSkpIT09MH1l
-bHNlIG09ITEKaWYobSl7aWYocCYmNjU8PW8mJjkwPj1vKXtpZihxPT1udWxsKXE9bmV3IFAuUm4oIiIp
-CmlmKHI8cyl7cS5hKz1DLnhCLk5qKGEscixzKQpyPXN9cD0hMX0rK3N9ZWxzZXtpZihvPD05Myl7bT1v
-Pj4+NAppZihtPj04KXJldHVybiBILk9IKEMuYWssbSkKbT0oQy5ha1ttXSYxPDwobyYxNSkpIT09MH1l
-bHNlIG09ITEKaWYobSl7UC5SMyhhLHMsIkludmFsaWQgY2hhcmFjdGVyIikKSC5CaSh1LmcpfWVsc2V7
-aWYoKG8mNjQ1MTIpPT09NTUyOTYmJnMrMTxjKXtpPUMueEIuTzIoYSxzKzEpCmlmKChpJjY0NTEyKT09
-PTU2MzIwKXtvPShvJjEwMjMpPDwxMHxpJjEwMjN8NjU1MzYKaj0yfWVsc2Ugaj0xfWVsc2Ugaj0xCmw9
-Qy54Qi5OaihhLHIscykKaWYoIXApbD1sLnRvTG93ZXJDYXNlKCkKaWYocT09bnVsbCl7cT1uZXcgUC5S
-bigiIikKbT1xfWVsc2UgbT1xCm0uYSs9bAptLmErPVAuelgobykKcys9agpyPXN9fX19aWYocT09bnVs
-bClyZXR1cm4gQy54Qi5OaihhLGIsYykKaWYocjxjKXtsPUMueEIuTmooYSxyLGMpCnEuYSs9IXA/bC50
-b0xvd2VyQ2FzZSgpOmx9bT1xLmEKcmV0dXJuIG0uY2hhckNvZGVBdCgwKT09MD9tOm19LApQaTpmdW5j
-dGlvbihhLGIsYyl7dmFyIHMscixxLHAsbz11LmcKaWYoYj09PWMpcmV0dXJuIiIKaWYoIVAuRXQoSi5y
-WShhKS5XKGEsYikpKXtQLlIzKGEsYiwiU2NoZW1lIG5vdCBzdGFydGluZyB3aXRoIGFscGhhYmV0aWMg
-Y2hhcmFjdGVyIikKSC5CaShvKX1mb3Iocz1iLHI9ITE7czxjOysrcyl7cT1DLnhCLlcoYSxzKQppZihx
-PDEyOCl7cD1xPj4+NAppZihwPj04KXJldHVybiBILk9IKEMubUsscCkKcD0oQy5tS1twXSYxPDwocSYx
-NSkpIT09MH1lbHNlIHA9ITEKaWYoIXApe1AuUjMoYSxzLCJJbGxlZ2FsIHNjaGVtZSBjaGFyYWN0ZXIi
-KQpILkJpKG8pfWlmKDY1PD1xJiZxPD05MClyPSEwfWE9Qy54Qi5OaihhLGIsYykKcmV0dXJuIFAuWWEo
-cj9hLnRvTG93ZXJDYXNlKCk6YSl9LApZYTpmdW5jdGlvbihhKXtpZihhPT09Imh0dHAiKXJldHVybiJo
-dHRwIgppZihhPT09ImZpbGUiKXJldHVybiJmaWxlIgppZihhPT09Imh0dHBzIilyZXR1cm4iaHR0cHMi
-CmlmKGE9PT0icGFja2FnZSIpcmV0dXJuInBhY2thZ2UiCnJldHVybiBhfSwKelI6ZnVuY3Rpb24oYSxi
-LGMpe2lmKGE9PW51bGwpcmV0dXJuIiIKcmV0dXJuIFAuUEkoYSxiLGMsQy50bywhMSl9LAprYTpmdW5j
-dGlvbihhLGIsYyxkLGUsZil7dmFyIHMscixxPWU9PT0iZmlsZSIscD1xfHxmCmlmKGE9PW51bGwpe2lm
-KGQ9PW51bGwpcmV0dXJuIHE/Ii8iOiIiCnM9SC50NihkKQpyPW5ldyBILmxKKGQscy5DKCJxVSgxKSIp
-LmEobmV3IFAuUlooKSkscy5DKCJsSjwxLHFVPiIpKS5IKDAsIi8iKX1lbHNlIGlmKGQhPW51bGwpdGhy
-b3cgSC5iKFAueFkoIkJvdGggcGF0aCBhbmQgcGF0aFNlZ21lbnRzIHNwZWNpZmllZCIpKQplbHNlIHI9
-UC5QSShhLGIsYyxDLldkLCEwKQppZihyLmxlbmd0aD09PTApe2lmKHEpcmV0dXJuIi8ifWVsc2UgaWYo
-cCYmIUMueEIubihyLCIvIikpcj0iLyIrcgpyZXR1cm4gUC5KcihyLGUsZil9LApKcjpmdW5jdGlvbihh
-LGIsYyl7dmFyIHM9Yi5sZW5ndGg9PT0wCmlmKHMmJiFjJiYhQy54Qi5uKGEsIi8iKSlyZXR1cm4gUC53
-RihhLCFzfHxjKQpyZXR1cm4gUC54ZShhKX0sCmxlOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHI9e30K
-aWYoYSE9bnVsbCl7aWYoZCE9bnVsbCl0aHJvdyBILmIoUC54WSgiQm90aCBxdWVyeSBhbmQgcXVlcnlQ
-YXJhbWV0ZXJzIHNwZWNpZmllZCIpKQpyZXR1cm4gUC5QSShhLGIsYyxDLlZDLCEwKX1pZihkPT1udWxs
-KXJldHVybiBudWxsCnM9bmV3IFAuUm4oIiIpCnIuYT0iIgpkLksoMCxuZXcgUC55NShuZXcgUC5NRShy
-LHMpKSkKcj1zLmEKcmV0dXJuIHIuY2hhckNvZGVBdCgwKT09MD9yOnJ9LAp0RzpmdW5jdGlvbihhLGIs
-Yyl7aWYoYT09bnVsbClyZXR1cm4gbnVsbApyZXR1cm4gUC5QSShhLGIsYyxDLlZDLCEwKX0sCnJ2OmZ1
-bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscCxvLG49YisyCmlmKG4+PWEubGVuZ3RoKXJldHVybiIlIgpz
-PUMueEIuTzIoYSxiKzEpCnI9Qy54Qi5PMihhLG4pCnE9SC5vbyhzKQpwPUgub28ocikKaWYocTwwfHxw
-PDApcmV0dXJuIiUiCm89cSoxNitwCmlmKG88MTI3KXtuPUMuam4ud0cobyw0KQppZihuPj04KXJldHVy
-biBILk9IKEMuRjMsbikKbj0oQy5GM1tuXSYxPDwobyYxNSkpIT09MH1lbHNlIG49ITEKaWYobilyZXR1
-cm4gSC5MdyhjJiY2NTw9byYmOTA+PW8/KG98MzIpPj4+MDpvKQppZihzPj05N3x8cj49OTcpcmV0dXJu
-IEMueEIuTmooYSxiLGIrMykudG9VcHBlckNhc2UoKQpyZXR1cm4gbnVsbH0sCnpYOmZ1bmN0aW9uKGEp
-e3ZhciBzLHIscSxwLG8sbixtLGwsaz0iMDEyMzQ1Njc4OUFCQ0RFRiIKaWYoYTwxMjgpe3M9bmV3IFVp
-bnQ4QXJyYXkoMykKc1swXT0zNwpzWzFdPUMueEIuVyhrLGE+Pj40KQpzWzJdPUMueEIuVyhrLGEmMTUp
-fWVsc2V7aWYoYT4yMDQ3KWlmKGE+NjU1MzUpe3I9MjQwCnE9NH1lbHNle3I9MjI0CnE9M31lbHNle3I9
-MTkyCnE9Mn1wPTMqcQpzPW5ldyBVaW50OEFycmF5KHApCmZvcihvPTA7LS1xLHE+PTA7cj0xMjgpe249
-Qy5qbi5iZihhLDYqcSkmNjN8cgppZihvPj1wKXJldHVybiBILk9IKHMsbykKc1tvXT0zNwptPW8rMQps
-PUMueEIuVyhrLG4+Pj40KQppZihtPj1wKXJldHVybiBILk9IKHMsbSkKc1ttXT1sCmw9bysyCm09Qy54
-Qi5XKGssbiYxNSkKaWYobD49cClyZXR1cm4gSC5PSChzLGwpCnNbbF09bQpvKz0zfX1yZXR1cm4gUC5I
-TShzLDAsbnVsbCl9LApQSTpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciBzPVAuVWwoYSxiLGMsZCxlKQpy
-ZXR1cm4gcz09bnVsbD9DLnhCLk5qKGEsYixjKTpzfSwKVWw6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIg
-cyxyLHEscCxvLG4sbSxsLGssaj1udWxsCmZvcihzPSFlLHI9YixxPXIscD1qO3I8Yzspe289Qy54Qi5P
-MihhLHIpCmlmKG88MTI3KXtuPW8+Pj40CmlmKG4+PTgpcmV0dXJuIEguT0goZCxuKQpuPShkW25dJjE8
-PChvJjE1KSkhPT0wfWVsc2Ugbj0hMQppZihuKSsrcgplbHNle2lmKG89PT0zNyl7bT1QLnJ2KGEsciwh
-MSkKaWYobT09bnVsbCl7cis9Mwpjb250aW51ZX1pZigiJSI9PT1tKXttPSIlMjUiCmw9MX1lbHNlIGw9
-M31lbHNle2lmKHMpaWYobzw9OTMpe249bz4+PjQKaWYobj49OClyZXR1cm4gSC5PSChDLmFrLG4pCm49
-KEMuYWtbbl0mMTw8KG8mMTUpKSE9PTB9ZWxzZSBuPSExCmVsc2Ugbj0hMQppZihuKXtQLlIzKGEsciwi
-SW52YWxpZCBjaGFyYWN0ZXIiKQpILkJpKHUuZykKbD1qCm09bH1lbHNle2lmKChvJjY0NTEyKT09PTU1
-Mjk2KXtuPXIrMQppZihuPGMpe2s9Qy54Qi5PMihhLG4pCmlmKChrJjY0NTEyKT09PTU2MzIwKXtvPShv
-JjEwMjMpPDwxMHxrJjEwMjN8NjU1MzYKbD0yfWVsc2UgbD0xfWVsc2UgbD0xfWVsc2UgbD0xCm09UC56
-WChvKX19aWYocD09bnVsbCl7cD1uZXcgUC5SbigiIikKbj1wfWVsc2Ugbj1wCm4uYSs9Qy54Qi5Oaihh
-LHEscikKbi5hKz1ILkVqKG0pCmlmKHR5cGVvZiBsIT09Im51bWJlciIpcmV0dXJuIEgucFkobCkKcis9
-bApxPXJ9fWlmKHA9PW51bGwpcmV0dXJuIGoKaWYocTxjKXAuYSs9Qy54Qi5OaihhLHEsYykKcz1wLmEK
-cmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9LAp5QjpmdW5jdGlvbihhKXtpZihDLnhCLm4oYSwi
-LiIpKXJldHVybiEwCnJldHVybiBDLnhCLk9ZKGEsIi8uIikhPT0tMX0sCnhlOmZ1bmN0aW9uKGEpe3Zh
-ciBzLHIscSxwLG8sbixtCmlmKCFQLnlCKGEpKXJldHVybiBhCnM9SC5WTShbXSx0LnMpCmZvcihyPWEu
-c3BsaXQoIi8iKSxxPXIubGVuZ3RoLHA9ITEsbz0wO288cTsrK28pe249cltvXQppZihKLlJNKG4sIi4u
-Iikpe209cy5sZW5ndGgKaWYobSE9PTApe2lmKDA+PW0pcmV0dXJuIEguT0gocywtMSkKcy5wb3AoKQpp
-ZihzLmxlbmd0aD09PTApQy5ObS5pKHMsIiIpfXA9ITB9ZWxzZSBpZigiLiI9PT1uKXA9ITAKZWxzZXtD
-Lk5tLmkocyxuKQpwPSExfX1pZihwKUMuTm0uaShzLCIiKQpyZXR1cm4gQy5ObS5IKHMsIi8iKX0sCndG
-OmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbyxuCmlmKCFQLnlCKGEpKXJldHVybiFiP1AuQzEoYSk6
-YQpzPUguVk0oW10sdC5zKQpmb3Iocj1hLnNwbGl0KCIvIikscT1yLmxlbmd0aCxwPSExLG89MDtvPHE7
-KytvKXtuPXJbb10KaWYoIi4uIj09PW4paWYocy5sZW5ndGghPT0wJiZDLk5tLmdyWihzKSE9PSIuLiIp
-e2lmKDA+PXMubGVuZ3RoKXJldHVybiBILk9IKHMsLTEpCnMucG9wKCkKcD0hMH1lbHNle0MuTm0uaShz
-LCIuLiIpCnA9ITF9ZWxzZSBpZigiLiI9PT1uKXA9ITAKZWxzZXtDLk5tLmkocyxuKQpwPSExfX1yPXMu
-bGVuZ3RoCmlmKHIhPT0wKWlmKHI9PT0xKXtpZigwPj1yKXJldHVybiBILk9IKHMsMCkKcj1zWzBdLmxl
-bmd0aD09PTB9ZWxzZSByPSExCmVsc2Ugcj0hMAppZihyKXJldHVybiIuLyIKaWYocHx8Qy5ObS5ncloo
-cyk9PT0iLi4iKUMuTm0uaShzLCIiKQppZighYil7aWYoMD49cy5sZW5ndGgpcmV0dXJuIEguT0gocyww
-KQpDLk5tLlkocywwLFAuQzEoc1swXSkpfXJldHVybiBDLk5tLkgocywiLyIpfSwKQzE6ZnVuY3Rpb24o
-YSl7dmFyIHMscixxLHA9YS5sZW5ndGgKaWYocD49MiYmUC5FdChKLlF6KGEsMCkpKWZvcihzPTE7czxw
-Oysrcyl7cj1DLnhCLlcoYSxzKQppZihyPT09NTgpcmV0dXJuIEMueEIuTmooYSwwLHMpKyIlM0EiK0Mu
-eEIuRyhhLHMrMSkKaWYocjw9MTI3KXtxPXI+Pj40CmlmKHE+PTgpcmV0dXJuIEguT0goQy5tSyxxKQpx
-PShDLm1LW3FdJjE8PChyJjE1KSk9PT0wfWVsc2UgcT0hMAppZihxKWJyZWFrfXJldHVybiBhfSwKbW46
-ZnVuY3Rpb24oYSl7dmFyIHMscixxLHA9YS5nRmooKSxvPXAubGVuZ3RoCmlmKG8+MCYmSi5IbShwWzBd
-KT09PTImJkouYTYocFswXSwxKT09PTU4KXtpZigwPj1vKXJldHVybiBILk9IKHAsMCkKUC5yZyhKLmE2
-KHBbMF0sMCksITEpClAuSE4ocCwhMSwxKQpzPSEwfWVsc2V7UC5ITihwLCExLDApCnM9ITF9cj1hLmd0
-VCgpJiYhcz8iXFwiOiIiCmlmKGEuZ2NqKCkpe3E9YS5nSmYoYSkKaWYocS5sZW5ndGghPT0wKXI9cisi
-XFwiK3ErIlxcIn1yPVAudmcocixwLCJcXCIpCm89cyYmbz09PTE/cisiXFwiOnIKcmV0dXJuIG8uY2hh
-ckNvZGVBdCgwKT09MD9vOm99LApJaDpmdW5jdGlvbihhLGIpe3ZhciBzLHIscQpmb3Iocz0wLHI9MDty
-PDI7KytyKXtxPUMueEIuVyhhLGIrcikKaWYoNDg8PXEmJnE8PTU3KXM9cyoxNitxLTQ4CmVsc2V7cXw9
-MzIKaWYoOTc8PXEmJnE8PTEwMilzPXMqMTYrcS04NwplbHNlIHRocm93IEguYihQLnhZKCJJbnZhbGlk
-IFVSTCBlbmNvZGluZyIpKX19cmV0dXJuIHN9LAprdTpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciBzLHIs
-cSxwLG89Si5yWShhKSxuPWIKd2hpbGUoITApe2lmKCEobjxjKSl7cz0hMApicmVha31yPW8uVyhhLG4p
-CmlmKHI8PTEyNylpZihyIT09MzcpcT1lJiZyPT09NDMKZWxzZSBxPSEwCmVsc2UgcT0hMAppZihxKXtz
-PSExCmJyZWFrfSsrbn1pZihzKXtpZihDLnhNIT09ZClxPSExCmVsc2UgcT0hMAppZihxKXJldHVybiBv
-Lk5qKGEsYixjKQplbHNlIHA9bmV3IEgucWooby5OaihhLGIsYykpfWVsc2V7cD1ILlZNKFtdLHQuYSkK
-Zm9yKG49YjtuPGM7KytuKXtyPW8uVyhhLG4pCmlmKHI+MTI3KXRocm93IEguYihQLnhZKCJJbGxlZ2Fs
-IHBlcmNlbnQgZW5jb2RpbmcgaW4gVVJJIikpCmlmKHI9PT0zNyl7aWYobiszPmEubGVuZ3RoKXRocm93
-IEguYihQLnhZKCJUcnVuY2F0ZWQgVVJJIikpCkMuTm0uaShwLFAuSWgoYSxuKzEpKQpuKz0yfWVsc2Ug
-aWYoZSYmcj09PTQzKUMuTm0uaShwLDMyKQplbHNlIEMuTm0uaShwLHIpfX10LkwuYShwKQpyZXR1cm4g
-Qy5vRS5XSihwKX0sCkV0OmZ1bmN0aW9uKGEpe3ZhciBzPWF8MzIKcmV0dXJuIDk3PD1zJiZzPD0xMjJ9
-LApLRDpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHAsbyxuLG0sbCxrPSJJbnZhbGlkIE1JTUUgdHlw
-ZSIsaj1ILlZNKFtiLTFdLHQuYSkKZm9yKHM9YS5sZW5ndGgscj1iLHE9LTEscD1udWxsO3I8czsrK3Ip
-e3A9Qy54Qi5XKGEscikKaWYocD09PTQ0fHxwPT09NTkpYnJlYWsKaWYocD09PTQ3KXtpZihxPDApe3E9
-cgpjb250aW51ZX10aHJvdyBILmIoUC5ycihrLGEscikpfX1pZihxPDAmJnI+Yil0aHJvdyBILmIoUC5y
-cihrLGEscikpCmZvcig7cCE9PTQ0Oyl7Qy5ObS5pKGoscik7KytyCmZvcihvPS0xO3I8czsrK3Ipe3A9
-Qy54Qi5XKGEscikKaWYocD09PTYxKXtpZihvPDApbz1yfWVsc2UgaWYocD09PTU5fHxwPT09NDQpYnJl
-YWt9aWYobz49MClDLk5tLmkoaixvKQplbHNle249Qy5ObS5nclooaikKaWYocCE9PTQ0fHxyIT09bis3
-fHwhQy54Qi5RaShhLCJiYXNlNjQiLG4rMSkpdGhyb3cgSC5iKFAucnIoIkV4cGVjdGluZyAnPSciLGEs
-cikpCmJyZWFrfX1DLk5tLmkoaixyKQptPXIrMQppZigoai5sZW5ndGgmMSk9PT0xKWE9Qy5oOS55cihh
-LG0scykKZWxzZXtsPVAuVWwoYSxtLHMsQy5WQywhMCkKaWYobCE9bnVsbClhPUMueEIuaTcoYSxtLHMs
-bCl9cmV0dXJuIG5ldyBQLlBFKGEsaixjKX0sCktOOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbyxuLG09
-IjAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3
-eHl6LS5ffiEkJicoKSorLDs9IixsPSIuIixrPSI6IixqPSIvIixpPSI/IixoPSIjIixnPUguVk0obmV3
-IEFycmF5KDIyKSx0LmdOKQpmb3Iocz0wO3M8MjI7KytzKWdbc109bmV3IFVpbnQ4QXJyYXkoOTYpCnI9
-bmV3IFAueUkoZykKcT1uZXcgUC5jNigpCnA9bmV3IFAucWQoKQpvPXQuZ2MKbj1vLmEoci4kMigwLDIy
-NSkpCnEuJDMobixtLDEpCnEuJDMobixsLDE0KQpxLiQzKG4saywzNCkKcS4kMyhuLGosMykKcS4kMyhu
-LGksMTcyKQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoMTQsMjI1KSkKcS4kMyhuLG0sMSkKcS4kMyhu
-LGwsMTUpCnEuJDMobixrLDM0KQpxLiQzKG4saiwyMzQpCnEuJDMobixpLDE3MikKcS4kMyhuLGgsMjA1
-KQpuPW8uYShyLiQyKDE1LDIyNSkpCnEuJDMobixtLDEpCnEuJDMobiwiJSIsMjI1KQpxLiQzKG4saywz
-NCkKcS4kMyhuLGosOSkKcS4kMyhuLGksMTcyKQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoMSwyMjUp
-KQpxLiQzKG4sbSwxKQpxLiQzKG4saywzNCkKcS4kMyhuLGosMTApCnEuJDMobixpLDE3MikKcS4kMyhu
-LGgsMjA1KQpuPW8uYShyLiQyKDIsMjM1KSkKcS4kMyhuLG0sMTM5KQpxLiQzKG4saiwxMzEpCnEuJDMo
-bixsLDE0NikKcS4kMyhuLGksMTcyKQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoMywyMzUpKQpxLiQz
-KG4sbSwxMSkKcS4kMyhuLGosNjgpCnEuJDMobixsLDE4KQpxLiQzKG4saSwxNzIpCnEuJDMobixoLDIw
-NSkKbj1vLmEoci4kMig0LDIyOSkpCnEuJDMobixtLDUpCnAuJDMobiwiQVoiLDIyOSkKcS4kMyhuLGss
-MTAyKQpxLiQzKG4sIkAiLDY4KQpxLiQzKG4sIlsiLDIzMikKcS4kMyhuLGosMTM4KQpxLiQzKG4saSwx
-NzIpCnEuJDMobixoLDIwNSkKbj1vLmEoci4kMig1LDIyOSkpCnEuJDMobixtLDUpCnAuJDMobiwiQVoi
-LDIyOSkKcS4kMyhuLGssMTAyKQpxLiQzKG4sIkAiLDY4KQpxLiQzKG4saiwxMzgpCnEuJDMobixpLDE3
-MikKcS4kMyhuLGgsMjA1KQpuPW8uYShyLiQyKDYsMjMxKSkKcC4kMyhuLCIxOSIsNykKcS4kMyhuLCJA
-Iiw2OCkKcS4kMyhuLGosMTM4KQpxLiQzKG4saSwxNzIpCnEuJDMobixoLDIwNSkKbj1vLmEoci4kMig3
-LDIzMSkpCnAuJDMobiwiMDkiLDcpCnEuJDMobiwiQCIsNjgpCnEuJDMobixqLDEzOCkKcS4kMyhuLGks
-MTcyKQpxLiQzKG4saCwyMDUpCnEuJDMoby5hKHIuJDIoOCw4KSksIl0iLDUpCm49by5hKHIuJDIoOSwy
-MzUpKQpxLiQzKG4sbSwxMSkKcS4kMyhuLGwsMTYpCnEuJDMobixqLDIzNCkKcS4kMyhuLGksMTcyKQpx
-LiQzKG4saCwyMDUpCm49by5hKHIuJDIoMTYsMjM1KSkKcS4kMyhuLG0sMTEpCnEuJDMobixsLDE3KQpx
-LiQzKG4saiwyMzQpCnEuJDMobixpLDE3MikKcS4kMyhuLGgsMjA1KQpuPW8uYShyLiQyKDE3LDIzNSkp
-CnEuJDMobixtLDExKQpxLiQzKG4saiw5KQpxLiQzKG4saSwxNzIpCnEuJDMobixoLDIwNSkKbj1vLmEo
-ci4kMigxMCwyMzUpKQpxLiQzKG4sbSwxMSkKcS4kMyhuLGwsMTgpCnEuJDMobixqLDIzNCkKcS4kMyhu
-LGksMTcyKQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoMTgsMjM1KSkKcS4kMyhuLG0sMTEpCnEuJDMo
-bixsLDE5KQpxLiQzKG4saiwyMzQpCnEuJDMobixpLDE3MikKcS4kMyhuLGgsMjA1KQpuPW8uYShyLiQy
-KDE5LDIzNSkpCnEuJDMobixtLDExKQpxLiQzKG4saiwyMzQpCnEuJDMobixpLDE3MikKcS4kMyhuLGgs
-MjA1KQpuPW8uYShyLiQyKDExLDIzNSkpCnEuJDMobixtLDExKQpxLiQzKG4saiwxMCkKcS4kMyhuLGks
-MTcyKQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoMTIsMjM2KSkKcS4kMyhuLG0sMTIpCnEuJDMobixp
-LDEyKQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoMTMsMjM3KSkKcS4kMyhuLG0sMTMpCnEuJDMobixp
-LDEzKQpwLiQzKG8uYShyLiQyKDIwLDI0NSkpLCJheiIsMjEpCnI9by5hKHIuJDIoMjEsMjQ1KSkKcC4k
-MyhyLCJheiIsMjEpCnAuJDMociwiMDkiLDIxKQpxLiQzKHIsIistLiIsMjEpCnJldHVybiBnfSwKVUI6
-ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgcyxyLHEscCxvLG49JC52WigpCmZvcihzPUouclkoYSkscj1i
-O3I8YzsrK3Ipe2lmKGQ8MHx8ZD49bi5sZW5ndGgpcmV0dXJuIEguT0gobixkKQpxPW5bZF0KcD1zLlco
-YSxyKV45NgpvPXFbcD45NT8zMTpwXQpkPW8mMzEKQy5ObS5ZKGUsbz4+PjUscil9cmV0dXJuIGR9LApX
-RjpmdW5jdGlvbiBXRihhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKaVA6ZnVuY3Rpb24gaVAoYSxiKXt0
-aGlzLmE9YQp0aGlzLmI9Yn0sClhTOmZ1bmN0aW9uIFhTKCl7fSwKQzY6ZnVuY3Rpb24gQzYoYSl7dGhp
-cy5hPWF9LApFejpmdW5jdGlvbiBFeigpe30sCkY6ZnVuY3Rpb24gRigpe30sCnU6ZnVuY3Rpb24gdShh
-LGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kfSwKYko6ZnVuY3Rpb24gYkoo
-YSxiLGMsZCxlLGYpe3ZhciBfPXRoaXMKXy5lPWEKXy5mPWIKXy5hPWMKXy5iPWQKXy5jPWUKXy5kPWZ9
-LAplWTpmdW5jdGlvbiBlWShhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5mPWEKXy5hPWIKXy5iPWMKXy5j
-PWQKXy5kPWV9LAptcDpmdW5jdGlvbiBtcChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8u
-Yz1jCl8uZD1kfSwKdWI6ZnVuY3Rpb24gdWIoYSl7dGhpcy5hPWF9LApkczpmdW5jdGlvbiBkcyhhKXt0
-aGlzLmE9YX0sCmxqOmZ1bmN0aW9uIGxqKGEpe3RoaXMuYT1hfSwKVVY6ZnVuY3Rpb24gVVYoYSl7dGhp
-cy5hPWF9LAprNTpmdW5jdGlvbiBrNSgpe30sCktZOmZ1bmN0aW9uIEtZKCl7fSwKYzpmdW5jdGlvbiBj
-KGEpe3RoaXMuYT1hfSwKQ0Q6ZnVuY3Rpb24gQ0QoYSl7dGhpcy5hPWF9LAphRTpmdW5jdGlvbiBhRShh
-LGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApjWDpmdW5jdGlvbiBjWCgpe30sCkFuOmZ1
-bmN0aW9uIEFuKCl7fSwKTjM6ZnVuY3Rpb24gTjMoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMu
-JHRpPWN9LApjODpmdW5jdGlvbiBjOCgpe30sCk1oOmZ1bmN0aW9uIE1oKCl7fSwKWmQ6ZnVuY3Rpb24g
-WmQoKXt9LApSbjpmdW5jdGlvbiBSbihhKXt0aGlzLmE9YX0sCm4xOmZ1bmN0aW9uIG4xKGEpe3RoaXMu
-YT1hfSwKY1M6ZnVuY3Rpb24gY1MoYSl7dGhpcy5hPWF9LApWQzpmdW5jdGlvbiBWQyhhKXt0aGlzLmE9
-YX0sCkpUOmZ1bmN0aW9uIEpUKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApEbjpmdW5jdGlvbiBEbihh
-LGIsYyxkLGUsZixnKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kCl8uZT1lCl8uZj1m
-Cl8ucj1nCl8ueD1udWxsCl8ueT0hMQpfLno9bnVsbApfLlE9ITEKXy5jaD1udWxsCl8uY3g9ITEKXy5j
-eT1udWxsCl8uZGI9ITF9LApSWjpmdW5jdGlvbiBSWigpe30sCk1FOmZ1bmN0aW9uIE1FKGEsYil7dGhp
-cy5hPWEKdGhpcy5iPWJ9LAp5NTpmdW5jdGlvbiB5NShhKXt0aGlzLmE9YX0sClBFOmZ1bmN0aW9uIFBF
-KGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCnlJOmZ1bmN0aW9uIHlJKGEpe3RoaXMu
-YT1hfSwKYzY6ZnVuY3Rpb24gYzYoKXt9LApxZDpmdW5jdGlvbiBxZCgpe30sClVmOmZ1bmN0aW9uIFVm
-KGEsYixjLGQsZSxmLGcsaCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApfLmU9ZQpf
-LmY9ZgpfLnI9ZwpfLng9aApfLnk9bnVsbH0sCnFlOmZ1bmN0aW9uIHFlKGEsYixjLGQsZSxmLGcpe3Zh
-ciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWQKXy5lPWUKXy5mPWYKXy5yPWcKXy54PW51bGwK
-Xy55PSExCl8uej1udWxsCl8uUT0hMQpfLmNoPW51bGwKXy5jeD0hMQpfLmN5PW51bGwKXy5kYj0hMX0s
-CmlKOmZ1bmN0aW9uIGlKKCl7fSwKamc6ZnVuY3Rpb24gamcoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0s
-ClRhOmZ1bmN0aW9uIFRhKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApCZjpmdW5jdGlvbiBCZihhLGIp
-e3RoaXMuYT1hCnRoaXMuYj1ifSwKQXM6ZnVuY3Rpb24gQXMoKXt9LApHRTpmdW5jdGlvbiBHRShhKXt0
-aGlzLmE9YX0sCk43OmZ1bmN0aW9uIE43KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp1UTpmdW5jdGlv
-biB1USgpe30sCmhGOmZ1bmN0aW9uIGhGKCl7fSwKUjQ6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixx
-CkgueTgoYikKdC5qLmEoZCkKaWYoSC5vVChiKSl7cz1bY10KQy5ObS5GVihzLGQpCmQ9c31yPXQuegpx
-PVAuQ0goSi5NMShkLFAudzAoKSxyKSwhMCxyKQp0LlkuYShhKQpyZXR1cm4gUC53WShILkVrKGEscSxu
-dWxsKSl9LApEbTpmdW5jdGlvbihhLGIsYyl7dmFyIHMKdHJ5e2lmKE9iamVjdC5pc0V4dGVuc2libGUo
-YSkmJiFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYSxiKSl7T2JqZWN0LmRlZmlu
-ZVByb3BlcnR5KGEsYix7dmFsdWU6Y30pCnJldHVybiEwfX1jYXRjaChzKXtILlJ1KHMpfXJldHVybiEx
-fSwKT206ZnVuY3Rpb24oYSxiKXtpZihPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwo
-YSxiKSlyZXR1cm4gYVtiXQpyZXR1cm4gbnVsbH0sCndZOmZ1bmN0aW9uKGEpe2lmKGE9PW51bGx8fHR5
-cGVvZiBhPT0ic3RyaW5nInx8dHlwZW9mIGE9PSJudW1iZXIifHxILmwoYSkpcmV0dXJuIGEKaWYoYSBp
-bnN0YW5jZW9mIFAuRTQpcmV0dXJuIGEuYQppZihILlI5KGEpKXJldHVybiBhCmlmKHQuYWsuYihhKSly
-ZXR1cm4gYQppZihhIGluc3RhbmNlb2YgUC5pUClyZXR1cm4gSC5vMihhKQppZih0LlkuYihhKSlyZXR1
-cm4gUC5oRShhLCIkZGFydF9qc0Z1bmN0aW9uIixuZXcgUC5QQygpKQpyZXR1cm4gUC5oRShhLCJfJGRh
-cnRfanNPYmplY3QiLG5ldyBQLm10KCQua0koKSkpfSwKaEU6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPVAu
-T20oYSxiKQppZihzPT1udWxsKXtzPWMuJDEoYSkKUC5EbShhLGIscyl9cmV0dXJuIHN9LApkVTpmdW5j
-dGlvbihhKXt2YXIgcyxyCmlmKGE9PW51bGx8fHR5cGVvZiBhPT0ic3RyaW5nInx8dHlwZW9mIGE9PSJu
-dW1iZXIifHx0eXBlb2YgYT09ImJvb2xlYW4iKXJldHVybiBhCmVsc2UgaWYoYSBpbnN0YW5jZW9mIE9i
-amVjdCYmSC5SOShhKSlyZXR1cm4gYQplbHNlIGlmKGEgaW5zdGFuY2VvZiBPYmplY3QmJnQuYWsuYihh
-KSlyZXR1cm4gYQplbHNlIGlmKGEgaW5zdGFuY2VvZiBEYXRlKXtzPUgudVAoYS5nZXRUaW1lKCkpCmlm
-KE1hdGguYWJzKHMpPD04NjRlMTMpcj0hMQplbHNlIHI9ITAKaWYocilILnYoUC54WSgiRGF0ZVRpbWUg
-aXMgb3V0c2lkZSB2YWxpZCByYW5nZTogIitzKSkKSC5jYighMSwiaXNVdGMiLHQueSkKcmV0dXJuIG5l
-dyBQLmlQKHMsITEpfWVsc2UgaWYoYS5jb25zdHJ1Y3Rvcj09PSQua0koKSlyZXR1cm4gYS5vCmVsc2Ug
-cmV0dXJuIFAuTkQoYSl9LApORDpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1
-cm4gUC5pUShhLCQudygpLG5ldyBQLk56KCkpCmlmKGEgaW5zdGFuY2VvZiBBcnJheSlyZXR1cm4gUC5p
-UShhLCQuUjgoKSxuZXcgUC5RUygpKQpyZXR1cm4gUC5pUShhLCQuUjgoKSxuZXcgUC5ucCgpKX0sCmlR
-OmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1QLk9tKGEsYikKaWYocz09bnVsbHx8IShhIGluc3RhbmNlb2Yg
-T2JqZWN0KSl7cz1jLiQxKGEpClAuRG0oYSxiLHMpfXJldHVybiBzfSwKUEM6ZnVuY3Rpb24gUEMoKXt9
-LAptdDpmdW5jdGlvbiBtdChhKXt0aGlzLmE9YX0sCk56OmZ1bmN0aW9uIE56KCl7fSwKUVM6ZnVuY3Rp
-b24gUVMoKXt9LApucDpmdW5jdGlvbiBucCgpe30sCkU0OmZ1bmN0aW9uIEU0KGEpe3RoaXMuYT1hfSwK
-cjc6ZnVuY3Rpb24gcjcoYSl7dGhpcy5hPWF9LApUejpmdW5jdGlvbiBUeihhLGIpe3RoaXMuYT1hCnRo
-aXMuJHRpPWJ9LApjbzpmdW5jdGlvbiBjbygpe30sCm5kOmZ1bmN0aW9uIG5kKCl7fSwKS2U6ZnVuY3Rp
-b24gS2UoYSl7dGhpcy5hPWF9LApoaTpmdW5jdGlvbiBoaSgpe319LFc9ewp4MzpmdW5jdGlvbigpe3Jl
-dHVybiB3aW5kb3d9LApacjpmdW5jdGlvbigpe3JldHVybiBkb2N1bWVudH0sCko2OmZ1bmN0aW9uKGEp
-e3ZhciBzPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImEiKQppZihhIT1udWxsKUMueG4uc0xVKHMsYSkK
-cmV0dXJuIHN9LApVOTpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj1kb2N1bWVudC5ib2R5CnIudG9TdHJp
-bmcKcz1DLlJZLnI2KHIsYSxiLGMpCnMudG9TdHJpbmcKcj10LmFjCnI9bmV3IEguVTUobmV3IFcuZTco
-cyksci5DKCJhMihsRC5FKSIpLmEobmV3IFcuQ3YoKSksci5DKCJVNTxsRC5FPiIpKQpyZXR1cm4gdC5o
-LmEoci5ncjgocikpfSwKclM6ZnVuY3Rpb24oYSl7dmFyIHMscixxPSJlbGVtZW50IHRhZyB1bmF2YWls
-YWJsZSIKdHJ5e3M9Si5ZRShhKQppZih0eXBlb2Ygcy5nbnMoYSk9PSJzdHJpbmciKXE9cy5nbnMoYSl9
-Y2F0Y2gocil7SC5SdShyKX1yZXR1cm4gcX0sCkMwOmZ1bmN0aW9uKGEsYil7YT1hK2ImNTM2ODcwOTEx
-CmE9YSsoKGEmNTI0Mjg3KTw8MTApJjUzNjg3MDkxMQpyZXR1cm4gYV5hPj4+Nn0sCnJFOmZ1bmN0aW9u
-KGEsYixjLGQpe3ZhciBzPVcuQzAoVy5DMChXLkMwKFcuQzAoMCxhKSxiKSxjKSxkKSxyPXMrKChzJjY3
-MTA4ODYzKTw8MykmNTM2ODcwOTExCnJePXI+Pj4xMQpyZXR1cm4gcisoKHImMTYzODMpPDwxNSkmNTM2
-ODcwOTExfSwKVE46ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHE9YS5jbGFzc0xpc3QKZm9yKHM9Yi5sZW5n
-dGgscj0wO3I8Yi5sZW5ndGg7Yi5sZW5ndGg9PT1zfHwoMCxILmxrKShiKSwrK3IpcS5hZGQoYltyXSl9
-LApKRTpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciBzPVcuYUYobmV3IFcudk4oYyksdC5CKQppZihzIT1u
-dWxsJiYhMClKLmRaKGEsYixzLCExKQpyZXR1cm4gbmV3IFcueEMoYSxiLHMsITEsZS5DKCJ4QzwwPiIp
-KX0sClR3OmZ1bmN0aW9uKGEpe3ZhciBzPVcuSjYobnVsbCkscj13aW5kb3cubG9jYXRpb24Kcz1uZXcg
-Vy5KUShuZXcgVy5tayhzLHIpKQpzLkNZKGEpCnJldHVybiBzfSwKcUQ6ZnVuY3Rpb24oYSxiLGMsZCl7
-dC5oLmEoYSkKSC5oKGIpCkguaChjKQp0LmNyLmEoZCkKcmV0dXJuITB9LApRVzpmdW5jdGlvbihhLGIs
-YyxkKXt2YXIgcyxyLHEKdC5oLmEoYSkKSC5oKGIpCkguaChjKQpzPXQuY3IuYShkKS5hCnI9cy5hCkMu
-eG4uc0xVKHIsYykKcT1yLmhvc3RuYW1lCnM9cy5iCmlmKCEocT09cy5ob3N0bmFtZSYmci5wb3J0PT1z
-LnBvcnQmJnIucHJvdG9jb2w9PXMucHJvdG9jb2wpKWlmKHE9PT0iIilpZihyLnBvcnQ9PT0iIil7cz1y
-LnByb3RvY29sCnM9cz09PSI6Inx8cz09PSIifWVsc2Ugcz0hMQplbHNlIHM9ITEKZWxzZSBzPSEwCnJl
-dHVybiBzfSwKQmw6ZnVuY3Rpb24oKXt2YXIgcz10Lk4scj1QLnRNKEMuUXgscykscT10LmQwLmEobmV3
-IFcuSUEoKSkscD1ILlZNKFsiVEVNUExBVEUiXSx0LnMpCnM9bmV3IFcuY3QocixQLkxzKHMpLFAuTHMo
-cyksUC5McyhzKSxudWxsKQpzLkNZKG51bGwsbmV3IEgubEooQy5ReCxxLHQuZmopLHAsbnVsbCkKcmV0
-dXJuIHN9LApxYzpmdW5jdGlvbihhKXt2YXIgcwppZihhPT1udWxsKXJldHVybiBudWxsCmlmKCJwb3N0
-TWVzc2FnZSIgaW4gYSl7cz1XLlAxKGEpCmlmKHQuYVMuYihzKSlyZXR1cm4gcwpyZXR1cm4gbnVsbH1l
-bHNlIHJldHVybiB0LmNoLmEoYSl9LApQMTpmdW5jdGlvbihhKXtpZihhPT09d2luZG93KXJldHVybiB0
-LmNpLmEoYSkKZWxzZSByZXR1cm4gbmV3IFcuZFcoKX0sCmFGOmZ1bmN0aW9uKGEsYil7dmFyIHM9JC5Y
-MwppZihzPT09Qy5OVSlyZXR1cm4gYQpyZXR1cm4gcy5QeShhLGIpfSwKcUU6ZnVuY3Rpb24gcUUoKXt9
-LApHaDpmdW5jdGlvbiBHaCgpe30sCmZZOmZ1bmN0aW9uIGZZKCl7fSwKbkI6ZnVuY3Rpb24gbkIoKXt9
-LApBejpmdW5jdGlvbiBBeigpe30sClFQOmZ1bmN0aW9uIFFQKCl7fSwKbng6ZnVuY3Rpb24gbngoKXt9
-LApvSjpmdW5jdGlvbiBvSigpe30sCmlkOmZ1bmN0aW9uIGlkKCl7fSwKUUY6ZnVuY3Rpb24gUUYoKXt9
-LApOaDpmdW5jdGlvbiBOaCgpe30sCmFlOmZ1bmN0aW9uIGFlKCl7fSwKSUI6ZnVuY3Rpb24gSUIoKXt9
-LApuNzpmdW5jdGlvbiBuNygpe30sCnd6OmZ1bmN0aW9uIHd6KGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9
-Yn0sCmN2OmZ1bmN0aW9uIGN2KCl7fSwKQ3Y6ZnVuY3Rpb24gQ3YoKXt9LAplYTpmdW5jdGlvbiBlYSgp
-e30sCkQwOmZ1bmN0aW9uIEQwKCl7fSwKaEg6ZnVuY3Rpb24gaEgoKXt9LApoNDpmdW5jdGlvbiBoNCgp
-e30sCmJyOmZ1bmN0aW9uIGJyKCl7fSwKVmI6ZnVuY3Rpb24gVmIoKXt9LApmSjpmdW5jdGlvbiBmSigp
-e30sCndhOmZ1bmN0aW9uIHdhKCl7fSwKU2c6ZnVuY3Rpb24gU2coKXt9LAp1ODpmdW5jdGlvbiB1OCgp
-e30sCkFqOmZ1bmN0aW9uIEFqKCl7fSwKZTc6ZnVuY3Rpb24gZTcoYSl7dGhpcy5hPWF9LAp1SDpmdW5j
-dGlvbiB1SCgpe30sCkJIOmZ1bmN0aW9uIEJIKCl7fSwKU046ZnVuY3Rpb24gU04oKXt9LApldzpmdW5j
-dGlvbiBldygpe30sCmxwOmZ1bmN0aW9uIGxwKCl7fSwKVGI6ZnVuY3Rpb24gVGIoKXt9LApJdjpmdW5j
-dGlvbiBJdigpe30sCldQOmZ1bmN0aW9uIFdQKCl7fSwKeVk6ZnVuY3Rpb24geVkoKXt9LAp3NjpmdW5j
-dGlvbiB3Nigpe30sCks1OmZ1bmN0aW9uIEs1KCl7fSwKQ206ZnVuY3Rpb24gQ20oKXt9LApDUTpmdW5j
-dGlvbiBDUSgpe30sCnc0OmZ1bmN0aW9uIHc0KCl7fSwKcmg6ZnVuY3Rpb24gcmgoKXt9LApjZjpmdW5j
-dGlvbiBjZigpe30sCmk3OmZ1bmN0aW9uIGk3KGEpe3RoaXMuYT1hfSwKU3k6ZnVuY3Rpb24gU3koYSl7
-dGhpcy5hPWF9LApLUzpmdW5jdGlvbiBLUyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQTM6ZnVuY3Rp
-b24gQTMoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCkk0OmZ1bmN0aW9uIEk0KGEpe3RoaXMuYT1hfSwK
-Rms6ZnVuY3Rpb24gRmsoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKUk86ZnVuY3Rpb24gUk8oYSxi
-LGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLiR0aT1kfSwKZXU6ZnVuY3Rpb24gZXUo
-YSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLiR0aT1kfSwKeEM6ZnVuY3Rpb24g
-eEMoYSxiLGMsZCxlKXt2YXIgXz10aGlzCl8uYj1hCl8uYz1iCl8uZD1jCl8uZT1kCl8uJHRpPWV9LAp2
-TjpmdW5jdGlvbiB2TihhKXt0aGlzLmE9YX0sCkpROmZ1bmN0aW9uIEpRKGEpe3RoaXMuYT1hfSwKR206
-ZnVuY3Rpb24gR20oKXt9LAp2RDpmdW5jdGlvbiB2RChhKXt0aGlzLmE9YX0sClV2OmZ1bmN0aW9uIFV2
-KGEpe3RoaXMuYT1hfSwKRWc6ZnVuY3Rpb24gRWcoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMu
-Yz1jfSwKbTY6ZnVuY3Rpb24gbTYoKXt9LApFbzpmdW5jdGlvbiBFbygpe30sCldrOmZ1bmN0aW9uIFdr
-KCl7fSwKY3Q6ZnVuY3Rpb24gY3QoYSxiLGMsZCxlKXt2YXIgXz10aGlzCl8uZT1hCl8uYT1iCl8uYj1j
-Cl8uYz1kCl8uZD1lfSwKSUE6ZnVuY3Rpb24gSUEoKXt9LApPdzpmdW5jdGlvbiBPdygpe30sClc5OmZ1
-bmN0aW9uIFc5KGEsYixjKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz0tMQpfLmQ9bnVsbApfLiR0
-aT1jfSwKZFc6ZnVuY3Rpb24gZFcoKXt9LAptazpmdW5jdGlvbiBtayhhLGIpe3RoaXMuYT1hCnRoaXMu
-Yj1ifSwKS286ZnVuY3Rpb24gS28oYSl7dGhpcy5hPWEKdGhpcy5iPSExfSwKZm06ZnVuY3Rpb24gZm0o
-YSl7dGhpcy5hPWF9LApMZTpmdW5jdGlvbiBMZSgpe30sCks3OmZ1bmN0aW9uIEs3KCl7fSwKckI6ZnVu
-Y3Rpb24gckIoKXt9LApYVzpmdW5jdGlvbiBYVygpe30sCm9hOmZ1bmN0aW9uIG9hKCl7fX0sTT17Ck9Y
-OmZ1bmN0aW9uKGEpe3N3aXRjaChhKXtjYXNlIEMuQWQ6cmV0dXJuIkFkZCAvKj8qLyBoaW50IgpjYXNl
-IEMubmU6cmV0dXJuIkFkZCAvKiEqLyBoaW50IgpjYXNlIEMud1Y6cmV0dXJuIlJlbW92ZSAvKj8qLyBo
-aW50IgpjYXNlIEMuZlI6cmV0dXJuIlJlbW92ZSAvKiEqLyBoaW50IgpjYXNlIEMubXk6cmV0dXJuIkNo
-YW5nZSB0byAvKj8qLyBoaW50IgpjYXNlIEMucng6cmV0dXJuIkNoYW5nZSB0byAvKiEqLyBoaW50In1y
-ZXR1cm4gbnVsbH0sCkg3OmZ1bmN0aW9uIEg3KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApZRjpmdW5j
-dGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixtLGwKZm9yKHM9Yi5sZW5ndGgscj0xO3I8czsrK3Ipe2lm
-KGJbcl09PW51bGx8fGJbci0xXSE9bnVsbCljb250aW51ZQpmb3IoO3M+PTE7cz1xKXtxPXMtMQppZihi
-W3FdIT1udWxsKWJyZWFrfXA9bmV3IFAuUm4oIiIpCm89YSsiKCIKcC5hPW8Kbj1ILnQ2KGIpCm09bi5D
-KCJuSDwxPiIpCmw9bmV3IEgubkgoYiwwLHMsbSkKbC5IZChiLDAscyxuLmMpCm09bytuZXcgSC5sSihs
-LG0uQygicVUoYUwuRSkiKS5hKG5ldyBNLk5vKCkpLG0uQygibEo8YUwuRSxxVT4iKSkuSCgwLCIsICIp
-CnAuYT1tCnAuYT1tKygiKTogcGFydCAiKyhyLTEpKyIgd2FzIG51bGwsIGJ1dCBwYXJ0ICIrcisiIHdh
-cyBub3QuIikKdGhyb3cgSC5iKFAueFkocC53KDApKSl9fSwKbEk6ZnVuY3Rpb24gbEkoYSl7dGhpcy5h
-PWF9LApxNzpmdW5jdGlvbiBxNygpe30sCk5vOmZ1bmN0aW9uIE5vKCl7fX0sVT17Cm56OmZ1bmN0aW9u
-KGEpe3ZhciBzPUgudVAoYS5xKDAsIm5vZGVJZCIpKQpyZXR1cm4gbmV3IFUuTEwoQy5ObS5IdChDLnJr
-LG5ldyBVLk1EKGEpKSxzKX0sCkxMOmZ1bmN0aW9uIExMKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApN
-RDpmdW5jdGlvbiBNRChhKXt0aGlzLmE9YX0sCmpmOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwCmlmKGE9
-PW51bGwpcz1udWxsCmVsc2V7cz1ILlZNKFtdLHQuZDcpCmZvcihyPUouSVQodC5VLmEoYSkpO3IuRigp
-Oyl7cT1yLmdsKCkKcD1KLlU2KHEpCnMucHVzaChuZXcgVS5TZShILmgocC5xKHEsImRlc2NyaXB0aW9u
-IikpLEguaChwLnEocSwiaHJlZiIpKSkpfX1yZXR1cm4gc30sCk5kOmZ1bmN0aW9uKGEpe3ZhciBzLHIK
-aWYoYT09bnVsbClzPW51bGwKZWxzZXtzPUguVk0oW10sdC5hQSkKZm9yKHI9Si5JVCh0LlUuYShhKSk7
-ci5GKCk7KXMucHVzaChVLk5mKHIuZ2woKSkpfXJldHVybiBzfSwKTmY6ZnVuY3Rpb24oYSl7dmFyIHM9
-Si5VNihhKSxyPUguaChzLnEoYSwiZGVzY3JpcHRpb24iKSkscT1ILlZNKFtdLHQuYUopCmZvcihzPUou
-SVQodC5VLmEocy5xKGEsImVudHJpZXMiKSkpO3MuRigpOylxLnB1c2goVS5SaihzLmdsKCkpKQpyZXR1
-cm4gbmV3IFUueUQocixxKX0sClJqOmZ1bmN0aW9uKGEpe3ZhciBzLHI9Si5VNihhKSxxPUguaChyLnEo
-YSwiZGVzY3JpcHRpb24iKSkscD1ILmgoci5xKGEsImZ1bmN0aW9uIikpLG89ci5xKGEsImxpbmsiKQpp
-ZihvPT1udWxsKW89bnVsbAplbHNle3M9Si5VNihvKQpvPW5ldyBVLk1sKEguaChzLnEobywiaHJlZiIp
-KSxILnVQKHMucShvLCJsaW5lIikpLEguaChzLnEobywicGF0aCIpKSl9cj10LmZLLmEoci5xKGEsImhp
-bnRBY3Rpb25zIikpCnI9cj09bnVsbD9udWxsOkouTTEocixuZXcgVS5hTigpLHQuYVgpCnI9cj09bnVs
-bD9udWxsOnIuYnIoMCkKcmV0dXJuIG5ldyBVLndiKHEscCxvLHI9PW51bGw/Qy5kbjpyKX0sCmQyOmZ1
-bmN0aW9uIGQyKGEsYixjLGQsZSxmKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kCl8u
-ZT1lCl8uZj1mfSwKU2U6ZnVuY3Rpb24gU2UoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCk1sOmZ1bmN0
-aW9uIE1sKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCnlEOmZ1bmN0aW9uIHlEKGEs
-Yil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp3YjpmdW5jdGlvbiB3YihhLGIsYyxkKXt2YXIgXz10aGlzCl8u
-YT1hCl8uYj1iCl8uYz1jCl8uZD1kfSwKYU46ZnVuY3Rpb24gYU4oKXt9LApiMDpmdW5jdGlvbiBiMCgp
-e319LEI9ewp3UjpmdW5jdGlvbigpe3JldHVybiBuZXcgQi5xcCgiIiwiIiwiIixDLkR4KX0sCllmOmZ1
-bmN0aW9uKGEpe3ZhciBzLHIscSxwLG8sbixtLGwsaz1ILmgoYS5xKDAsInJlZ2lvbnMiKSksaj1ILmgo
-YS5xKDAsIm5hdmlnYXRpb25Db250ZW50IikpLGk9SC5oKGEucSgwLCJzb3VyY2VDb2RlIikpLGg9UC5G
-bCh0LlgsdC5kXykKZm9yKHM9dC50LmEoYS5xKDAsImVkaXRzIikpLHM9cy5nUHUocykscz1zLmdtKHMp
-LHI9dC5VLHE9dC5oNDtzLkYoKTspe3A9cy5nbCgpCm89cC5hCm49SC5WTShbXSxxKQpmb3IocD1KLklU
-KHIuYShwLmIpKTtwLkYoKTspe209cC5nbCgpCmw9Si5VNihtKQpuLnB1c2gobmV3IEIuajgoSC51UChs
-LnEobSwibGluZSIpKSxILmgobC5xKG0sImV4cGxhbmF0aW9uIikpLEgudVAobC5xKG0sIm9mZnNldCIp
-KSkpfWguWSgwLG8sbil9cmV0dXJuIG5ldyBCLnFwKGssaixpLGgpfSwKajg6ZnVuY3Rpb24gajgoYSxi
-LGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKcXA6ZnVuY3Rpb24gcXAoYSxiLGMsZCl7dmFy
-IF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZH0sCmZ2OmZ1bmN0aW9uIGZ2KCl7fSwKT1M6ZnVu
-Y3Rpb24oYSl7dmFyIHMKaWYoIShhPj02NSYmYTw9OTApKXM9YT49OTcmJmE8PTEyMgplbHNlIHM9ITAK
-cmV0dXJuIHN9LApZdTpmdW5jdGlvbihhLGIpe3ZhciBzPWEubGVuZ3RoLHI9YisyCmlmKHM8cilyZXR1
-cm4hMQppZighQi5PUyhDLnhCLk8yKGEsYikpKXJldHVybiExCmlmKEMueEIuTzIoYSxiKzEpIT09NTgp
-cmV0dXJuITEKaWYocz09PXIpcmV0dXJuITAKcmV0dXJuIEMueEIuTzIoYSxyKT09PTQ3fX0sVD17bVE6
-ZnVuY3Rpb24gbVEoKXt9fSxMPXsKSXE6ZnVuY3Rpb24oKXtDLkJaLkIoZG9jdW1lbnQsIkRPTUNvbnRl
-bnRMb2FkZWQiLG5ldyBMLmUoKSkKQy5vbC5CKHdpbmRvdywicG9wc3RhdGUiLG5ldyBMLkwoKSl9LApr
-ejpmdW5jdGlvbihhKXt2YXIgcyxyPXQuZy5hKGEucGFyZW50Tm9kZSkucXVlcnlTZWxlY3RvcigiOnNj
-b3BlID4gdWwiKSxxPXIuc3R5bGUscD0iIitDLkNELnpRKHIub2Zmc2V0SGVpZ2h0KSoyKyJweCIKcS5t
-YXhIZWlnaHQ9cApxPUoucUYoYSkKcD1xLiR0aQpzPXAuQygifigxKT8iKS5hKG5ldyBMLld4KHIsYSkp
-CnQuWi5hKG51bGwpClcuSkUocS5hLHEuYixzLCExLHAuYyl9LAp5WDpmdW5jdGlvbihhLGIpe3ZhciBz
-LHIscSxwLG8sbixtPSJxdWVyeVNlbGVjdG9yQWxsIixsPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYSks
-az10LmcKbC50b1N0cmluZwpzPXQuaApILkRoKGsscywiVCIsbSkKcj10LlIKcT1uZXcgVy53eihsLnF1
-ZXJ5U2VsZWN0b3JBbGwoIi5uYXYtbGluayIpLHIpCnEuSyhxLG5ldyBMLkFPKGIpKQpILkRoKGsscywi
-VCIsbSkKcD1uZXcgVy53eihsLnF1ZXJ5U2VsZWN0b3JBbGwoIi5yZWdpb24iKSxyKQppZighcC5nbDAo
-cCkpe289bC5xdWVyeVNlbGVjdG9yKCJ0YWJsZVtkYXRhLXBhdGhdIikKby50b1N0cmluZwpwLksocCxu
-ZXcgTC5IbyhvLmdldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KG8pKS5PKCJwYXRo
-IikpKSl9SC5EaChrLHMsIlQiLG0pCm49bmV3IFcud3oobC5xdWVyeVNlbGVjdG9yQWxsKCIuYWRkLWhp
-bnQtbGluayIpLHIpCm4uSyhuLG5ldyBMLklDKCkpfSwKUTY6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPW5l
-dyBYTUxIdHRwUmVxdWVzdCgpCkMuRHQuZW8ocywiR0VUIixMLlE0KGEsYiksITApCnMuc2V0UmVxdWVz
-dEhlYWRlcigiQ29udGVudC1UeXBlIiwiYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD1VVEYtOCIpCnJl
-dHVybiBMLkxVKHMsbnVsbCxjLkMoIjAqIikpfSwKdHk6ZnVuY3Rpb24oYSxiKXt2YXIgcz1uZXcgWE1M
-SHR0cFJlcXVlc3QoKSxyPXQuWApDLkR0LmVvKHMsIlBPU1QiLEwuUTQoYSxQLkZsKHIscikpLCEwKQpz
-LnNldFJlcXVlc3RIZWFkZXIoIkNvbnRlbnQtVHlwZSIsImFwcGxpY2F0aW9uL2pzb247IGNoYXJzZXQ9
-VVRGLTgiKQpyZXR1cm4gTC5MVShzLGIsdC50KX0sCkxVOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gTC5U
-ZyhhLGIsYyxjLkMoIjAqIikpfSwKVGc6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHM9MCxyPVAuRlgoZCks
-cSxwPTIsbyxuPVtdLG0sbCxrLGosaSxoLGcsZgp2YXIgJGFzeW5jJExVPVAubHooZnVuY3Rpb24oZSxh
-MCl7aWYoZT09PTEpe289YTAKcz1wfXdoaWxlKHRydWUpc3dpdGNoKHMpe2Nhc2UgMDppPW5ldyBQLlpm
-KG5ldyBQLnZzKCQuWDMsdC5nViksdC5iQykKaD10LmViCmc9aC5hKG5ldyBMLmZDKGksYSkpCnQuWi5h
-KG51bGwpCmw9dC5lUQpXLkpFKGEsImxvYWQiLGcsITEsbCkKVy5KRShhLCJlcnJvciIsaC5hKGkuZ1lK
-KCkpLCExLGwpCmEuc2VuZChiPT1udWxsP251bGw6Qy5DdC5PQihiLG51bGwpKQpwPTQKcz03CnJldHVy
-biBQLmpRKGkuYSwkYXN5bmMkTFUpCmNhc2UgNzpwPTIKcz02CmJyZWFrCmNhc2UgNDpwPTMKZj1vCkgu
-UnUoZikKbT1ILnRzKGYpCmg9UC5UbCgiRXJyb3IgcmVhY2hpbmcgbWlncmF0aW9uIHByZXZpZXcgc2Vy
-dmVyLiIsbSkKdGhyb3cgSC5iKGgpCnM9NgpicmVhawpjYXNlIDM6cz0yCmJyZWFrCmNhc2UgNjpqPUMu
-Q3QucFcoMCxhLnJlc3BvbnNlVGV4dCxudWxsKQppZihhLnN0YXR1cz09PTIwMCl7cT1jLkMoIjAqIiku
-YShqKQpzPTEKYnJlYWt9ZWxzZSB0aHJvdyBILmIoaikKY2FzZSAxOnJldHVybiBQLnlDKHEscikKY2Fz
-ZSAyOnJldHVybiBQLmYzKG8scil9fSkKcmV0dXJuIFAuREkoJGFzeW5jJExVLHIpfSwKYUs6ZnVuY3Rp
-b24oYSl7dmFyIHM9UC5oSyhhKS5naFkoKS5xKDAsImxpbmUiKQpyZXR1cm4gcz09bnVsbD9udWxsOkgu
-SHAocyxudWxsKX0sCkc2OmZ1bmN0aW9uKGEpe3ZhciBzPVAuaEsoYSkuZ2hZKCkucSgwLCJvZmZzZXQi
-KQpyZXR1cm4gcz09bnVsbD9udWxsOkguSHAocyxudWxsKX0sCmk2OmZ1bmN0aW9uKGEpe3JldHVybiBM
-Lm5XKHQuTy5hKGEpKX0sCm5XOmZ1bmN0aW9uKGEpe3ZhciBzPTAscj1QLkZYKHQueikscT0xLHAsbz1b
-XSxuLG0sbCxrLGosaSxoCnZhciAkYXN5bmMkaTY9UC5seihmdW5jdGlvbihiLGMpe2lmKGI9PT0xKXtw
-PWMKcz1xfXdoaWxlKHRydWUpc3dpdGNoKHMpe2Nhc2UgMDppPXQuZy5hKFcucWMoYS5jdXJyZW50VGFy
-Z2V0KSkuZ2V0QXR0cmlidXRlKCJocmVmIikKYS5wcmV2ZW50RGVmYXVsdCgpCnE9MwprPWRvY3VtZW50
-Cm49Qy5DRC56UShrLnF1ZXJ5U2VsZWN0b3IoIi5jb250ZW50Iikuc2Nyb2xsVG9wKQpzPTYKcmV0dXJu
-IFAualEoTC50eShpLG51bGwpLCRhc3luYyRpNikKY2FzZSA2OnM9NwpyZXR1cm4gUC5qUShMLkc3KHdp
-bmRvdy5sb2NhdGlvbi5wYXRobmFtZSxudWxsLG51bGwsITEsbnVsbCksJGFzeW5jJGk2KQpjYXNlIDc6
-az1rLnF1ZXJ5U2VsZWN0b3IoIi5jb250ZW50IikKay50b1N0cmluZwprLnNjcm9sbFRvcD1KLlZ1KG4p
-CnE9MQpzPTUKYnJlYWsKY2FzZSAzOnE9MgpoPXAKbT1ILlJ1KGgpCmw9SC50cyhoKQpMLkMyKCJDb3Vs
-ZCBub3QgYWRkL3JlbW92ZSBoaW50IixtLGwpCnM9NQpicmVhawpjYXNlIDI6cz0xCmJyZWFrCmNhc2Ug
-NTpyZXR1cm4gUC55QyhudWxsLHIpCmNhc2UgMTpyZXR1cm4gUC5mMyhwLHIpfX0pCnJldHVybiBQLkRJ
-KCRhc3luYyRpNixyKX0sCkMyOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscD0iZXhjZXB0aW9uIixv
-PSJzdGFja1RyYWNlIixuPXQudC5iKGIpJiZKLlJNKGIucSgwLCJzdWNjZXNzIiksITEpJiZiLng0KHAp
-JiZiLng0KG8pLG09Si5pYShiKQppZihuKXtzPUguaChtLnEoYixwKSkKYz1tLnEoYixvKX1lbHNlIHM9
-bS53KGIpCm49ZG9jdW1lbnQKcj1uLnF1ZXJ5U2VsZWN0b3IoIi5wb3B1cC1wYW5lIikKci5xdWVyeVNl
-bGVjdG9yKCJoMiIpLmlubmVyVGV4dD1hCnIucXVlcnlTZWxlY3RvcigicCIpLmlubmVyVGV4dD1zCnIu
-cXVlcnlTZWxlY3RvcigicHJlIikuaW5uZXJUZXh0PUouaihjKQpxPXQuZGQuYShyLnF1ZXJ5U2VsZWN0
-b3IoImEuYm90dG9tIikpCm09dC5YOyhxJiZDLnhuKS5zTFUocSxQLlhkKCJodHRwcyIsImdpdGh1Yi5j
-b20iLCJkYXJ0LWxhbmcvc2RrL2lzc3Vlcy9uZXciLFAuRUYoWyJ0aXRsZSIsIkN1c3RvbWVyLXJlcG9y
-dGVkIGlzc3VlIHdpdGggTk5CRCBtaWdyYXRpb24gdG9vbDogIithLCJsYWJlbHMiLHUuZCwiYm9keSIs
-YSsiXG5cbkVycm9yOiAiK0guRWoocykrIlxuXG5QbGVhc2UgZmlsbCBpbiB0aGUgZm9sbG93aW5nOlxu
-XG4qKk5hbWUgb2YgcGFja2FnZSBiZWluZyBtaWdyYXRlZCAoaWYgcHVibGljKSoqOlxuKipXaGF0IEkg
-d2FzIGRvaW5nIHdoZW4gdGhpcyBpc3N1ZSBvY2N1cnJlZCoqOlxuKipJcyBpdCBwb3NzaWJsZSB0byB3
-b3JrIGFyb3VuZCB0aGlzIGlzc3VlKio6XG4qKkhhcyB0aGlzIGlzc3VlIGhhcHBlbmVkIGJlZm9yZSwg
-YW5kIGlmIHNvLCBob3cgb2Z0ZW4qKjpcbioqRGFydCBTREsgdmVyc2lvbioqOiAiK0guRWoobi5nZXRF
-bGVtZW50QnlJZCgic2RrLXZlcnNpb24iKS50ZXh0Q29udGVudCkrIlxuKipBZGRpdGlvbmFsIGRldGFp
-bHMqKjpcblxuVGhhbmtzIGZvciBmaWxpbmchXG5cblN0YWNrdHJhY2U6IF9hdXRvIHBvcHVsYXRlZCBi
-eSBtaWdyYXRpb24gcHJldmlldyB0b29sLl9cblxuYGBgXG4iK0guRWooYykrIlxuYGBgXG4iXSxtLG0p
-KS5nbkQoKSkKbT1xLnN0eWxlCm0uZGlzcGxheT0iaW5pdGlhbCIKbj1yLnN0eWxlCm4uZGlzcGxheT0i
-aW5pdGlhbCIKbj1hKyI6ICIrSC5FaihiKQp3aW5kb3cKaWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmlu
-ZWQiKXdpbmRvdy5jb25zb2xlLmVycm9yKG4pCndpbmRvdwpuPUguRWooYykKaWYodHlwZW9mIGNvbnNv
-bGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLmVycm9yKG4pfSwKdDI6ZnVuY3Rpb24oYSxiLGMp
-e3ZhciBzLHIscSxwLG89dC5nLmEoVy5xYyhhLmN1cnJlbnRUYXJnZXQpKQphLnByZXZlbnREZWZhdWx0
-KCkKcz1vLmdldEF0dHJpYnV0ZSgiaHJlZiIpCnI9TC5VcyhzKQpxPUwuRzYocykKcD1MLmFLKHMpCmlm
-KHEhPW51bGwpTC5hZihyLHEscCxiLG5ldyBMLm5UKHIscSxwKSkKZWxzZSBMLmFmKHIsbnVsbCxudWxs
-LGIsbmV3IEwuTlkocikpfSwKSzA6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHA9ZG9jdW1lbnQucXVlcnlT
-ZWxlY3RvcigiLnBvcHVwLXBhbmUiKQpwLnF1ZXJ5U2VsZWN0b3IoImgyIikuaW5uZXJUZXh0PSJGYWls
-ZWQgdG8gcmVydW4gZnJvbSBzb3VyY2VzIgpwLnF1ZXJ5U2VsZWN0b3IoInAiKS5pbm5lclRleHQ9IlNv
-dXJjZXMgY29udGFpbiBzdGF0aWMgYW5hbHlzaXMgZXJyb3JzOiIKcz1wLnF1ZXJ5U2VsZWN0b3IoInBy
-ZSIpCnI9Si5FbChhLHQuYXcpCnE9SC5MaChyKQpzLmlubmVyVGV4dD1uZXcgSC5sSihyLHEuQygicVUq
-KGxELkUpIikuYShuZXcgTC51ZSgpKSxxLkMoImxKPGxELkUscVUqPiIpKS5IKDAsIlxuIikKcT1wLnF1
-ZXJ5U2VsZWN0b3IoImEuYm90dG9tIikuc3R5bGUKcS5kaXNwbGF5PSJub25lIgpzPXAuc3R5bGUKcy5k
-aXNwbGF5PSJpbml0aWFsIn0sCnZVOmZ1bmN0aW9uKCl7dmFyIHM9ZG9jdW1lbnQKSC5EaCh0LmcsdC5o
-LCJUIiwicXVlcnlTZWxlY3RvckFsbCIpCnM9bmV3IFcud3oocy5xdWVyeVNlbGVjdG9yQWxsKCIuY29k
-ZSIpLHQuUikKcy5LKHMsbmV3IEwuZVgoKSl9LApoWDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEwuWXco
-YSxiLGMpfSwKWXc6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPTAscj1QLkZYKHQueikscT0xLHAsbz1bXSxu
-LG0sbCxrLGosaSxoLGcKdmFyICRhc3luYyRoWD1QLmx6KGZ1bmN0aW9uKGQsZSl7aWYoZD09PTEpe3A9
-ZQpzPXF9d2hpbGUodHJ1ZSlzd2l0Y2gocyl7Y2FzZSAwOnE9MwpqPXQuWApzPTYKcmV0dXJuIFAualEo
-TC5RNihhLFAuRUYoWyJyZWdpb24iLCJyZWdpb24iLCJvZmZzZXQiLEguRWooYildLGosaiksdC50KSwk
-YXN5bmMkaFgpCmNhc2UgNjpuPWUKaj1uCmk9Si5VNihqKQptPW5ldyBVLmQyKFUuamYoaS5xKGosImVk
-aXRzIikpLEguaChpLnEoaiwiZXhwbGFuYXRpb24iKSksSC51UChpLnEoaiwibGluZSIpKSxILmgoaS5x
-KGosImRpc3BsYXlQYXRoIikpLEguaChpLnEoaiwidXJpUGF0aCIpKSxVLk5kKGkucShqLCJ0cmFjZXMi
-KSkpCkwuVDEobSkKTC5GcihhLGIsYykKTC55WCgiLmVkaXQtcGFuZWwgLnBhbmVsLWNvbnRlbnQiLCEx
-KQpxPTEKcz01CmJyZWFrCmNhc2UgMzpxPTIKZz1wCmw9SC5SdShnKQprPUgudHMoZykKTC5DMigiQ291
-bGQgbm90IGxvYWQgZWRpdCBkZXRhaWxzIixsLGspCnM9NQpicmVhawpjYXNlIDI6cz0xCmJyZWFrCmNh
-c2UgNTpyZXR1cm4gUC55QyhudWxsLHIpCmNhc2UgMTpyZXR1cm4gUC5mMyhwLHIpfX0pCnJldHVybiBQ
-LkRJKCRhc3luYyRoWCxyKX0sCkc3OmZ1bmN0aW9uKGEsYixjLGQsZSl7cmV0dXJuIEwuTDUoYSxiLGMs
-ZCxlKX0sCkw1OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHM9MCxyPVAuRlgodC5IKSxxLHA9MixvLG49
-W10sbSxsLGssaixpLGgsZwp2YXIgJGFzeW5jJEc3PVAubHooZnVuY3Rpb24oZixhMCl7aWYoZj09PTEp
-e289YTAKcz1wfXdoaWxlKHRydWUpc3dpdGNoKHMpe2Nhc2UgMDppZighSi5wNChhLCIuZGFydCIpKXtM
-LkJFKGEsQi53UigpLGQpCkwuQlgoYSxudWxsKQppZihlIT1udWxsKWUuJDAoKQpzPTEKYnJlYWt9cD00
-Cmk9dC5YCnM9NwpyZXR1cm4gUC5qUShMLlE2KGEsUC5FRihbImlubGluZSIsInRydWUiXSxpLGkpLHQu
-dCksJGFzeW5jJEc3KQpjYXNlIDc6bT1hMApMLkJFKGEsQi5ZZihtKSxkKQpMLmZHKGIsYykKbD1MLlVz
-KGEpCkwuQlgobCxiKQppZihlIT1udWxsKWUuJDAoKQpwPTIKcz02CmJyZWFrCmNhc2UgNDpwPTMKZz1v
-Cms9SC5SdShnKQpqPUgudHMoZykKTC5DMigiQ291bGQgbm90IGxvYWQgZGFydCBmaWxlICIrYSxrLGop
-CnM9NgpicmVhawpjYXNlIDM6cz0yCmJyZWFrCmNhc2UgNjpjYXNlIDE6cmV0dXJuIFAueUMocSxyKQpj
-YXNlIDI6cmV0dXJuIFAuZjMobyxyKX19KQpyZXR1cm4gUC5ESSgkYXN5bmMkRzcscil9LApHZTpmdW5j
-dGlvbigpe3ZhciBzPTAscj1QLkZYKHQueikscT0xLHAsbz1bXSxuLG0sbCxrLGosaSxoCnZhciAkYXN5
-bmMkR2U9UC5seihmdW5jdGlvbihhLGIpe2lmKGE9PT0xKXtwPWIKcz1xfXdoaWxlKHRydWUpc3dpdGNo
-KHMpe2Nhc2UgMDppPSIvX3ByZXZpZXcvbmF2aWdhdGlvblRyZWUuanNvbiIKcT0zCnM9NgpyZXR1cm4g
-UC5qUShMLlE2KGksQy5DTSx0Lm0pLCRhc3luYyRHZSkKY2FzZSA2Om49YgptPWRvY3VtZW50LnF1ZXJ5
-U2VsZWN0b3IoIi5uYXYtdHJlZSIpCkoubDUobSwiIikKTC50WChtLEwubUsobiksITEpCnE9MQpzPTUK
-YnJlYWsKY2FzZSAzOnE9MgpoPXAKbD1ILlJ1KGgpCms9SC50cyhoKQpMLkMyKCJDb3VsZCBub3QgbG9h
-ZCBuYXZpZ2F0aW9uIHRyZWUiLGwsaykKcz01CmJyZWFrCmNhc2UgMjpzPTEKYnJlYWsKY2FzZSA1OnJl
-dHVybiBQLnlDKG51bGwscikKY2FzZSAxOnJldHVybiBQLmYzKHAscil9fSkKcmV0dXJuIFAuREkoJGFz
-eW5jJEdlLHIpfSwKcU86ZnVuY3Rpb24oYSl7dmFyIHMscj1hLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgp
-LHE9Qy5DRC56USgkLmZpKCkub2Zmc2V0SGVpZ2h0KSxwPXdpbmRvdy5pbm5lckhlaWdodCxvPUMuQ0Qu
-elEoJC5EVygpLm9mZnNldEhlaWdodCkKaWYodHlwZW9mIHAhPT0ibnVtYmVyIilyZXR1cm4gcC5ITigp
-CnM9ci5ib3R0b20Kcy50b1N0cmluZwppZihzPnAtKG8rMTQpKUouZGgoYSkKZWxzZXtwPXIudG9wCnAu
-dG9TdHJpbmcKaWYocDxxKzE0KUouZGgoYSl9fSwKZkc6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxv
-CmlmKGEhPW51bGwpe3M9ZG9jdW1lbnQKcj1zLmdldEVsZW1lbnRCeUlkKCJvIitILkVqKGEpKQpxPXMu
-cXVlcnlTZWxlY3RvcigiLmxpbmUtIitILkVqKGIpKQppZihyIT1udWxsKXtMLnFPKHIpCkouZFIociku
-aSgwLCJ0YXJnZXQiKX1lbHNlIGlmKHEhPW51bGwpTC5xTyhxLnBhcmVudEVsZW1lbnQpCmlmKHEhPW51
-bGwpSi5kUih0LmcuYShxLnBhcmVudE5vZGUpKS5pKDAsImhpZ2hsaWdodCIpfWVsc2V7cz1kb2N1bWVu
-dApwPXQuZwpILkRoKHAsdC5oLCJUIiwicXVlcnlTZWxlY3RvckFsbCIpCnM9cy5xdWVyeVNlbGVjdG9y
-QWxsKCIubGluZS1ubyIpCm89bmV3IFcud3oocyx0LlIpCmlmKG8uZ0Eobyk9PT0wKXJldHVybgpMLnFP
-KHAuYShDLnQ1Lmd0SChzKSkpfX0sCmFmOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHMscixxPUwuRzYo
-d2luZG93LmxvY2F0aW9uLmhyZWYpLHA9TC5hSyh3aW5kb3cubG9jYXRpb24uaHJlZikKaWYocSE9bnVs
-bCl7cz1kb2N1bWVudC5nZXRFbGVtZW50QnlJZCgibyIrSC5FaihxKSkKaWYocyE9bnVsbClKLmRSKHMp
-LlIoMCwidGFyZ2V0Iil9aWYocCE9bnVsbCl7cj1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIubGluZS0i
-K0guRWoocCkpCmlmKHIhPW51bGwpSi5kUihyLnBhcmVudEVsZW1lbnQpLlIoMCwiaGlnaGxpZ2h0Iil9
-aWYoYT09d2luZG93LmxvY2F0aW9uLnBhdGhuYW1lKXtMLmZHKGIsYykKZS4kMCgpfWVsc2UgTC5HNyhh
-LGIsYyxkLGUpfSwKUTQ6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHE9UC5oSyhhKSxwPXQuWApwPVAuRmwo
-cCxwKQpmb3Iocz1xLmdoWSgpLHM9cy5nUHUocykscz1zLmdtKHMpO3MuRigpOyl7cj1zLmdsKCkKcC5Z
-KDAsci5hLHIuYil9Zm9yKHM9Yi5nUHUoYikscz1zLmdtKHMpO3MuRigpOyl7cj1zLmdsKCkKcC5ZKDAs
-ci5hLHIuYil9cC5ZKDAsImF1dGhUb2tlbiIsJC5VRSgpKQpyZXR1cm4gcS5ubSgwLHApLmduRCgpfSwK
-VDE6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGo9JC5oTCgpCkoubDUoaiwiIikKaWYo
-YT09bnVsbCl7cz1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJwIikKQy5MdC5zYTQocywiU2VlIGRldGFp
-bHMgYWJvdXQgYSBwcm9wb3NlZCBlZGl0LiIpCkMuTHQuc0QocyxILlZNKFsicGxhY2Vob2xkZXIiXSx0
-LmkpKQpqLmFwcGVuZENoaWxkKHMpCkMuTHQuRkYocykKcmV0dXJufXI9YS5kCnE9JC5uVSgpCnA9cS56
-ZihyKQpvPWEuYgpuPWRvY3VtZW50Cm09cS5IUChyLEouVDAobi5xdWVyeVNlbGVjdG9yKCIucm9vdCIp
-LnRleHRDb250ZW50KSkKbD1hLmMKaz1uLmNyZWF0ZUVsZW1lbnQoInAiKQpqLmFwcGVuZENoaWxkKGsp
-CmsuYXBwZW5kQ2hpbGQobi5jcmVhdGVUZXh0Tm9kZShILkVqKG8pKyIgYXQgIikpCnE9dC5YCnE9Vy5K
-NihMLlE0KGEuZSxQLkVGKFsibGluZSIsSi5qKGwpXSxxLHEpKSkKcS5hcHBlbmRDaGlsZChuLmNyZWF0
-ZVRleHROb2RlKEguRWoobSkrIjoiK0guRWoobCkrIi4iKSkKay5hcHBlbmRDaGlsZChxKQpKLmRoKGsp
-CkwuQ0MoYSxqLHApCkwuRnooYSxqKX0sCkxIOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscCxvLG4s
-bSxsLGssaixpLGgsZyxmLGU9JC55UCgpCkoubDUoZSwiIikKaWYoYi5nQShiKT09PTApe3M9ZG9jdW1l
-bnQKcj1zLmNyZWF0ZUVsZW1lbnQoInAiKQplLmFwcGVuZENoaWxkKHIpCnIuYXBwZW5kQ2hpbGQocy5j
-cmVhdGVUZXh0Tm9kZSgiTm8gcHJvcG9zZWQgZWRpdHMiKSl9ZWxzZSBmb3IoZT1iLmdQdShiKSxlPWUu
-Z20oZSkscz10LlgscT10LmsscD1xLkMoIn4oMSk/Iiksbz10LloscT1xLmM7ZS5GKCk7KXtuPWUuZ2wo
-KQptPWRvY3VtZW50CnI9bS5jcmVhdGVFbGVtZW50KCJwIikKbD0kLnlQKCkKbC5hcHBlbmRDaGlsZChy
-KQpyLmFwcGVuZENoaWxkKG0uY3JlYXRlVGV4dE5vZGUoSC5FaihuLmEpKyI6IikpCms9bS5jcmVhdGVF
-bGVtZW50KCJ1bCIpCmwuYXBwZW5kQ2hpbGQoaykKZm9yKG49Si5JVChuLmIpO24uRigpOyl7bD1uLmds
-KCkKaj1tLmNyZWF0ZUVsZW1lbnQoImxpIikKay5hcHBlbmRDaGlsZChqKQpKLmRSKGopLmkoMCwiZWRp
-dCIpCmk9bS5jcmVhdGVFbGVtZW50KCJhIikKai5hcHBlbmRDaGlsZChpKQppLmNsYXNzTGlzdC5hZGQo
-ImVkaXQtbGluayIpCmg9bC5jCmc9SC5FaihoKQppLnNldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5
-KG5ldyBXLmk3KGkpKS5PKCJvZmZzZXQiKSxnKQpmPWwuYQpnPUguRWooZikKaS5zZXRBdHRyaWJ1dGUo
-ImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhpKSkuTygibGluZSIpLGcpCmkuYXBwZW5kQ2hpbGQobS5j
-cmVhdGVUZXh0Tm9kZSgibGluZSAiK0guRWooZikpKQppLnNldEF0dHJpYnV0ZSgiaHJlZiIsTC5RNCh3
-aW5kb3cubG9jYXRpb24ucGF0aG5hbWUsUC5FRihbImxpbmUiLEguRWooZiksIm9mZnNldCIsSC5Faiho
-KV0scyxzKSkpCmc9cC5hKG5ldyBMLkVFKGgsZixhKSkKby5hKG51bGwpClcuSkUoaSwiY2xpY2siLGcs
-ITEscSkKai5hcHBlbmRDaGlsZChtLmNyZWF0ZVRleHROb2RlKCI6ICIrSC5FaihsLmIpKSl9fWlmKGMp
-TC5UMShudWxsKX0sCkZyOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHE9d2luZG93LmxvY2F0aW9uLHA9
-UC5oSygocSYmQy5FeCkuZ0RyKHEpK0guRWooYSkpCnE9dC5YCnE9UC5GbChxLHEpCmlmKGIhPW51bGwp
-cS5ZKDAsIm9mZnNldCIsSC5FaihiKSkKaWYoYyE9bnVsbClxLlkoMCwibGluZSIsSC5FaihjKSkKcS5Z
-KDAsImF1dGhUb2tlbiIsJC5VRSgpKQpwPXAubm0oMCxxKQpxPXdpbmRvdy5oaXN0b3J5CnM9dC56CnI9
-cC5nbkQoKQpxLnRvU3RyaW5nCnEucHVzaFN0YXRlKG5ldyBQLkJmKFtdLFtdKS5QdihQLkZsKHMscykp
-LCIiLHIpfSwKRW46ZnVuY3Rpb24oYSl7dmFyIHM9Si5iYihkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIu
-cm9vdCIpLnRleHRDb250ZW50LCIvIikKaWYoQy54Qi5uKGEscykpcmV0dXJuIEMueEIuRyhhLHMubGVu
-Z3RoKQplbHNlIHJldHVybiBhfSwKQlg6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyPXt9CnIuYT1hCmE9TC5F
-bihhKQpyLmE9YQpKLmRyKCQuRDkoKSxhKQpzPWRvY3VtZW50CkguRGgodC5nLHQuaCwiVCIsInF1ZXJ5
-U2VsZWN0b3JBbGwiKQpzPW5ldyBXLnd6KHMucXVlcnlTZWxlY3RvckFsbCgiLm5hdi1wYW5lbCAubmF2
-LWxpbmsiKSx0LlIpCnMuSyhzLG5ldyBMLlZTKHIpKX0sCkJFOmZ1bmN0aW9uKGEsYixjKXt2YXIgcz0i
-LnJlZ2lvbnMiLHI9ZG9jdW1lbnQscT1yLnF1ZXJ5U2VsZWN0b3IocykscD1yLnF1ZXJ5U2VsZWN0b3Io
-Ii5jb2RlIikKSi50SChxLGIuYSwkLktHKCkpCkoudEgocCxiLmIsJC5LRygpKQpMLkxIKGEsYi5kLGMp
-CmlmKGIuYy5sZW5ndGg8MmU1KUwudlUoKQpMLnlYKCIuY29kZSIsITApCkwueVgocywhMCl9LAp0WDpm
-dW5jdGlvbihhLGIsYTApe3ZhciBzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZT0ibWF0ZXJpYWwt
-aWNvbnMiLGQ9ZG9jdW1lbnQsYz1kLmNyZWF0ZUVsZW1lbnQoInVsIikKYS5hcHBlbmRDaGlsZChjKQpm
-b3Iocz1iLmxlbmd0aCxyPXQuWCxxPXQuWixwPTA7cDxiLmxlbmd0aDtiLmxlbmd0aD09PXN8fCgwLEgu
-bGspKGIpLCsrcCl7bz1iW3BdCm49ZC5jcmVhdGVFbGVtZW50KCJsaSIpCmMuYXBwZW5kQ2hpbGQobikK
-aWYobyBpbnN0YW5jZW9mIEwudnQpe0ouZFIobikuaSgwLCJkaXIiKQpuLnNldEF0dHJpYnV0ZSgiZGF0
-YS0iK25ldyBXLlN5KG5ldyBXLmk3KG4pKS5PKCJuYW1lIiksby5jKQptPWQuY3JlYXRlRWxlbWVudCgi
-c3BhbiIpCm4uYXBwZW5kQ2hpbGQobSkKbD1KLllFKG0pCmwuZ0QobSkuaSgwLCJhcnJvdyIpCmwuc2hm
-KG0sIiYjeDI1QkM7IikKaz1kLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpKLmRSKGspLmkoMCxlKQprLmlu
-bmVyVGV4dD0iZm9sZGVyX29wZW4iCm4uYXBwZW5kQ2hpbGQoaykKbi5hcHBlbmRDaGlsZChkLmNyZWF0
-ZVRleHROb2RlKG8uYSkpCkwudFgobixvLmQsITEpCkwua3oobSl9ZWxzZSBpZihvIGluc3RhbmNlb2Yg
-TC5jRCl7bD1kLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpKLmRSKGwpLmkoMCxlKQpsLmlubmVyVGV4dD0i
-aW5zZXJ0X2RyaXZlX2ZpbGUiCm4uYXBwZW5kQ2hpbGQobCkKaj1kLmNyZWF0ZUVsZW1lbnQoImEiKQpu
-LmFwcGVuZENoaWxkKGopCmw9Si5ZRShqKQpsLmdEKGopLmkoMCwibmF2LWxpbmsiKQpqLnNldEF0dHJp
-YnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KGopKS5PKCJuYW1lIiksby5jKQpqLnNldEF0dHJp
-YnV0ZSgiaHJlZiIsTC5RNChvLmQsUC5GbChyLHIpKSkKai5hcHBlbmRDaGlsZChkLmNyZWF0ZVRleHRO
-b2RlKG8uYSkpCmw9bC5nVmwoaikKaT1sLiR0aQpoPWkuQygifigxKT8iKS5hKG5ldyBMLlREKCkpCnEu
-YShudWxsKQpXLkpFKGwuYSxsLmIsaCwhMSxpLmMpCmc9by5lCmlmKHR5cGVvZiBnIT09Im51bWJlciIp
-cmV0dXJuIGcub3MoKQppZihnPjApe2Y9ZC5jcmVhdGVFbGVtZW50KCJzcGFuIikKbi5hcHBlbmRDaGls
-ZChmKQpKLmRSKGYpLmkoMCwiZWRpdC1jb3VudCIpCmw9IiIrZysiICIKaWYoZz09PTEpaT0icHJvcG9z
-ZWQgZWRpdCIKZWxzZSBpPSJwcm9wb3NlZCBlZGl0cyIKZi5zZXRBdHRyaWJ1dGUoInRpdGxlIixsK2kp
-CmYuYXBwZW5kQ2hpbGQoZC5jcmVhdGVUZXh0Tm9kZShDLmpuLncoZykpKX19fX0sCnV6OmZ1bmN0aW9u
-KGEsYixjKXt2YXIgcz1kb2N1bWVudCxyPXMuY3JlYXRlRWxlbWVudCgiYnV0dG9uIikscT10LmsscD1x
-LkMoIn4oMSk/IikuYShuZXcgTC5tMihhLGMpKQp0LlouYShudWxsKQpXLkpFKHIsImNsaWNrIixwLCEx
-LHEuYykKci5hcHBlbmRDaGlsZChzLmNyZWF0ZVRleHROb2RlKE0uT1goYS5hKSkpCmIuYXBwZW5kQ2hp
-bGQocil9LApGejpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixtLGwsayxqLGksaD1hLmEKaWYo
-aD09bnVsbClyZXR1cm4Kcz1kb2N1bWVudApyPXMuY3JlYXRlRWxlbWVudCgicCIpCnE9Yi5hcHBlbmRD
-aGlsZChyKQpyPXMuY3JlYXRlRWxlbWVudCgic3BhbiIpCnA9dC5pCkouTXUocixILlZNKFsidHlwZS1k
-ZXNjcmlwdGlvbiJdLHApKQpyLmFwcGVuZENoaWxkKHMuY3JlYXRlVGV4dE5vZGUoIkFjdGlvbnMiKSkK
-cS5hcHBlbmRDaGlsZChyKQpxLmFwcGVuZENoaWxkKHMuY3JlYXRlVGV4dE5vZGUoIjoiKSkKbz1zLmNy
-ZWF0ZUVsZW1lbnQoInAiKQpiLmFwcGVuZENoaWxkKG8pCmZvcihyPWgubGVuZ3RoLG49dC5RLG09MDtt
-PGgubGVuZ3RoO2gubGVuZ3RoPT09cnx8KDAsSC5saykoaCksKyttKXtsPWhbbV0Kaz1zLmNyZWF0ZUVs
-ZW1lbnQoImEiKQpvLmFwcGVuZENoaWxkKGspCmsuYXBwZW5kQ2hpbGQocy5jcmVhdGVUZXh0Tm9kZShs
-LmEpKQprLnNldEF0dHJpYnV0ZSgiaHJlZiIsbC5iKQpqPW4uYShILlZNKFsiYWRkLWhpbnQtbGluayIs
-ImJlZm9yZS1hcHBseSIsImJ1dHRvbiJdLHApKQppPUouZFIoaykKaS5WMSgwKQppLkZWKDAsail9fSwK
-Q0M6ZnVuY3Rpb24oYTQsYTUsYTYpe3ZhciBzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZSxkLGMs
-YixhLGEwLGExLGEyLGEzCmZvcihzPWE0LmYscj1zLmxlbmd0aCxxPXQuaSxwPXQuUSxvPTA7bzxzLmxl
-bmd0aDtzLmxlbmd0aD09PXJ8fCgwLEgubGspKHMpLCsrbyl7bj1zW29dCm09ZG9jdW1lbnQKbD1tLmNy
-ZWF0ZUVsZW1lbnQoInAiKQprPXAuYShILlZNKFsidHJhY2UiXSxxKSkKaj1KLmRSKGwpCmouVjEoMCkK
-ai5GVigwLGspCmk9YTUuYXBwZW5kQ2hpbGQobCkKbD1tLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQprPXAu
-YShILlZNKFsidHlwZS1kZXNjcmlwdGlvbiJdLHEpKQpqPUouZFIobCkKai5WMSgwKQpqLkZWKDAsaykK
-bC5hcHBlbmRDaGlsZChtLmNyZWF0ZVRleHROb2RlKG4uYSkpCmkuYXBwZW5kQ2hpbGQobCkKaS5hcHBl
-bmRDaGlsZChtLmNyZWF0ZVRleHROb2RlKCI6IikpCmw9bS5jcmVhdGVFbGVtZW50KCJ1bCIpCms9cC5h
-KEguVk0oWyJ0cmFjZSJdLHEpKQpqPUouZFIobCkKai5WMSgwKQpqLkZWKDAsaykKaD1pLmFwcGVuZENo
-aWxkKGwpCmZvcihsPW4uYixrPWwubGVuZ3RoLGc9MDtnPGwubGVuZ3RoO2wubGVuZ3RoPT09a3x8KDAs
-SC5saykobCksKytnKXtmPWxbZ10KZT1tLmNyZWF0ZUVsZW1lbnQoImxpIikKaC5hcHBlbmRDaGlsZChl
-KQpkPW0uY3JlYXRlRWxlbWVudCgic3BhbiIpCmM9cC5hKEguVk0oWyJmdW5jdGlvbiJdLHEpKQpqPUou
-ZFIoZCkKai5WMSgwKQpqLkZWKDAsYykKYz1mLmIKTC5rRChkLGM9PW51bGw/InVua25vd24iOmMpCmUu
-YXBwZW5kQ2hpbGQoZCkKYj1mLmMKaWYoYiE9bnVsbCl7ZS5hcHBlbmRDaGlsZChtLmNyZWF0ZVRleHRO
-b2RlKCIgKCIpKQphPWIuYgphMD1tLmNyZWF0ZUVsZW1lbnQoImEiKQphMC5hcHBlbmRDaGlsZChtLmNy
-ZWF0ZVRleHROb2RlKEguRWooYi5jKSsiOiIrSC5FaihhKSkpCmEwLnNldEF0dHJpYnV0ZSgiaHJlZiIs
-Yi5hKQphMC5jbGFzc0xpc3QuYWRkKCJuYXYtbGluayIpCmUuYXBwZW5kQ2hpbGQoYTApCmUuYXBwZW5k
-Q2hpbGQobS5jcmVhdGVUZXh0Tm9kZSgiKSIpKX1lLmFwcGVuZENoaWxkKG0uY3JlYXRlVGV4dE5vZGUo
-IjogIikpCmQ9Zi5hCkwua0QoZSxkPT1udWxsPyJ1bmtub3duIjpkKQpkPWYuZAppZihkLmxlbmd0aCE9
-PTApe2M9bS5jcmVhdGVFbGVtZW50KCJwIikKYTE9cC5hKEguVk0oWyJkcmF3ZXIiLCJiZWZvcmUtYXBw
-bHkiXSxxKSkKaj1KLmRSKGMpCmouVjEoMCkKai5GVigwLGExKQphMj1lLmFwcGVuZENoaWxkKGMpCmZv
-cihjPWQubGVuZ3RoLGEzPTA7YTM8ZC5sZW5ndGg7ZC5sZW5ndGg9PT1jfHwoMCxILmxrKShkKSwrK2Ez
-KUwudXooZFthM10sYTIsYil9fX19LApVczpmdW5jdGlvbihhKXtyZXR1cm4gSi5VNihhKS50ZyhhLCI/
-Iik/Qy54Qi5OaihhLDAsQy54Qi5PWShhLCI/IikpOmF9LAprRDpmdW5jdGlvbihhLGIpe3ZhciBzLHIs
-cT1ILlZNKGIuc3BsaXQoIi4iKSx0LnMpLHA9Qy5ObS5ndEgocSksbz1kb2N1bWVudAphLmFwcGVuZENo
-aWxkKG8uY3JlYXRlVGV4dE5vZGUocCkpCmZvcihwPUgucUMocSwxLG51bGwsdC5OKSxwPW5ldyBILmE3
-KHAscC5nQShwKSxwLiR0aS5DKCJhNzxhTC5FPiIpKSxzPUouWUUoYSk7cC5GKCk7KXtyPXAuZApzLm56
-KGEsImJlZm9yZWVuZCIsIiYjODIwMzsuIixudWxsLG51bGwpCmEuYXBwZW5kQ2hpbGQoby5jcmVhdGVU
-ZXh0Tm9kZShyKSl9fSwKZTpmdW5jdGlvbiBlKCl7fSwKVlc6ZnVuY3Rpb24gVlcoYSxiLGMpe3RoaXMu
-YT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKb1o6ZnVuY3Rpb24gb1ooKXt9LApqcjpmdW5jdGlvbiBqcigp
-e30sCnFsOmZ1bmN0aW9uIHFsKCl7fSwKSGk6ZnVuY3Rpb24gSGkoKXt9LApCVDpmdW5jdGlvbiBCVCgp
-e30sClBZOmZ1bmN0aW9uIFBZKCl7fSwKTDpmdW5jdGlvbiBMKCl7fSwKV3g6ZnVuY3Rpb24gV3goYSxi
-KXt0aGlzLmE9YQp0aGlzLmI9Yn0sCkFPOmZ1bmN0aW9uIEFPKGEpe3RoaXMuYT1hfSwKZE46ZnVuY3Rp
-b24gZE4oYSl7dGhpcy5hPWF9LApIbzpmdW5jdGlvbiBIbyhhKXt0aGlzLmE9YX0sCnh6OmZ1bmN0aW9u
-IHh6KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApJQzpmdW5jdGlvbiBJQygpe30sCmZDOmZ1bmN0aW9u
-IGZDKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApuVDpmdW5jdGlvbiBuVChhLGIsYyl7dGhpcy5hPWEK
-dGhpcy5iPWIKdGhpcy5jPWN9LApOWTpmdW5jdGlvbiBOWShhKXt0aGlzLmE9YX0sCnVlOmZ1bmN0aW9u
-IHVlKCl7fSwKZVg6ZnVuY3Rpb24gZVgoKXt9LApFRTpmdW5jdGlvbiBFRShhLGIsYyl7dGhpcy5hPWEK
-dGhpcy5iPWIKdGhpcy5jPWN9LApRTDpmdW5jdGlvbiBRTChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwK
-VlM6ZnVuY3Rpb24gVlMoYSl7dGhpcy5hPWF9LApURDpmdW5jdGlvbiBURCgpe30sCm0yOmZ1bmN0aW9u
-IG0yKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApYQTpmdW5jdGlvbiBYQSgpe30sClpzOmZ1bmN0aW9u
-KGEpe3ZhciBzLHIscT1KLlU2KGEpCmlmKEwucDIoSC5oKHEucShhLCJ0eXBlIikpKT09PUMuWTIpe3M9
-SC5oKHEucShhLCJuYW1lIikpCnI9SC5oKHEucShhLCJwYXRoIikpCnE9cS5xKGEsInN1YnRyZWUiKQpx
-PW5ldyBMLnZ0KHE9PW51bGw/bnVsbDpMLm1LKHEpLHMscikKcS5MVigpCnJldHVybiBxfWVsc2V7cz1I
-LmgocS5xKGEsIm5hbWUiKSkKcj1ILmgocS5xKGEsInBhdGgiKSkKcmV0dXJuIG5ldyBMLmNEKEguaChx
-LnEoYSwiaHJlZiIpKSxILnVQKHEucShhLCJlZGl0Q291bnQiKSksSC55OChxLnEoYSwid2FzRXhwbGlj
-aXRseU9wdGVkT3V0IikpLEwudkIoSC51UChxLnEoYSwibWlncmF0aW9uU3RhdHVzIikpKSxzLHIpfX0s
-Cm1LOmZ1bmN0aW9uKGEpe3ZhciBzLHI9SC5WTShbXSx0LmNRKQpmb3Iocz1KLklUKHQuVS5hKGEpKTtz
-LkYoKTspci5wdXNoKEwuWnMocy5nbCgpKSkKcmV0dXJuIHJ9LApWRDpmdW5jdGlvbihhKXt2YXIgcyxy
-LHE9SC5WTShbXSx0LkcpCmZvcihzPWEubGVuZ3RoLHI9MDtyPGEubGVuZ3RoO2EubGVuZ3RoPT09c3x8
-KDAsSC5saykoYSksKytyKXEucHVzaChhW3JdLkx0KCkpCnJldHVybiBxfSwKdkI6ZnVuY3Rpb24oYSl7
-aWYoYT09bnVsbClyZXR1cm4gbnVsbAppZihhPj4+MCE9PWF8fGE+PTQpcmV0dXJuIEguT0goQy5sMCxh
-KQpyZXR1cm4gQy5sMFthXX0sCnAyOmZ1bmN0aW9uKGEpe3N3aXRjaChhKXtjYXNlImRpcmVjdG9yeSI6
-cmV0dXJuIEMuWTIKY2FzZSJmaWxlIjpyZXR1cm4gQy5yZgpkZWZhdWx0OnRocm93IEguYihQLlBWKCJV
-bnJlY29nbml6ZWQgbmF2aWdhdGlvbiB0cmVlIG5vZGUgdHlwZTogIitILkVqKGEpKSl9fSwKdnQ6ZnVu
-Y3Rpb24gdnQoYSxiLGMpe3ZhciBfPXRoaXMKXy5kPWEKXy5hPWIKXy5iPW51bGwKXy5jPWN9LApjRDpm
-dW5jdGlvbiBjRChhLGIsYyxkLGUsZil7dmFyIF89dGhpcwpfLmQ9YQpfLmU9YgpfLmY9YwpfLnI9ZApf
-LmE9ZQpfLmI9bnVsbApfLmM9Zn0sCkQ4OmZ1bmN0aW9uIEQ4KCl7fSwKTzk6ZnVuY3Rpb24gTzkoYSl7
-dGhpcy5iPWF9LApHYjpmdW5jdGlvbiBHYihhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKSVY6ZnVuY3Rp
-b24gSVYoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmQ9YQpfLmU9YgpfLmY9YwpfLnI9ZH19LFg9ewpDTDpm
-dW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbj1iLnhaKGEpCmIuaEsoYSkKaWYobiE9bnVsbClhPUou
-S1YoYSxuLmxlbmd0aCkKcz10LnMKcj1ILlZNKFtdLHMpCnE9SC5WTShbXSxzKQpzPWEubGVuZ3RoCmlm
-KHMhPT0wJiZiLnI0KEMueEIuVyhhLDApKSl7aWYoMD49cylyZXR1cm4gSC5PSChhLDApCkMuTm0uaShx
-LGFbMF0pCnA9MX1lbHNle0MuTm0uaShxLCIiKQpwPTB9Zm9yKG89cDtvPHM7KytvKWlmKGIucjQoQy54
-Qi5XKGEsbykpKXtDLk5tLmkocixDLnhCLk5qKGEscCxvKSkKQy5ObS5pKHEsYVtvXSkKcD1vKzF9aWYo
-cDxzKXtDLk5tLmkocixDLnhCLkcoYSxwKSkKQy5ObS5pKHEsIiIpfXJldHVybiBuZXcgWC5XRChiLG4s
-cixxKX0sCldEOmZ1bmN0aW9uIFdEKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5kPWMK
-Xy5lPWR9LApJNzpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFguZHYoYSl9LApkdjpmdW5jdGlvbiBkdihh
-KXt0aGlzLmE9YX19LE89ewpSaDpmdW5jdGlvbigpe3ZhciBzLHI9bnVsbAppZihQLnVvKCkuZ0ZpKCkh
-PT0iZmlsZSIpcmV0dXJuICQuRWIoKQpzPVAudW8oKQppZighQy54Qi5UYyhzLmdJaShzKSwiLyIpKXJl
-dHVybiAkLkViKCkKaWYoUC5LTChyLCJhL2IiLHIscixyLHIscikudDQoKT09PSJhXFxiIilyZXR1cm4g
-JC5LaygpCnJldHVybiAkLmJEKCl9LAp6TDpmdW5jdGlvbiB6TCgpe319LEU9e09GOmZ1bmN0aW9uIE9G
-KGEsYixjKXt0aGlzLmQ9YQp0aGlzLmU9Ygp0aGlzLmY9Y319LEY9e3J1OmZ1bmN0aW9uIHJ1KGEsYixj
-LGQpe3ZhciBfPXRoaXMKXy5kPWEKXy5lPWIKXy5mPWMKXy5yPWR9fSxEPXsKYWI6ZnVuY3Rpb24oKXt2
-YXIgcyxyLHEscCxvPW51bGwKdHJ5e289UC51bygpfWNhdGNoKHMpe2lmKHQuZzguYihILlJ1KHMpKSl7
-cj0kLkZmCmlmKHIhPW51bGwpcmV0dXJuIHIKdGhyb3cgc31lbHNlIHRocm93IHN9aWYoSi5STShvLCQu
-STYpKXtyPSQuRmYKci50b1N0cmluZwpyZXR1cm4gcn0kLkk2PW8KaWYoJC5IaygpPT0kLkViKCkpcj0k
-LkZmPW8uWkkoIi4iKS53KDApCmVsc2V7cT1vLnQ0KCkKcD1xLmxlbmd0aC0xCnI9JC5GZj1wPT09MD9x
-OkMueEIuTmoocSwwLHApfXIudG9TdHJpbmcKcmV0dXJuIHJ9fQp2YXIgdz1bQyxILEosUCxXLE0sVSxC
-LFQsTCxYLE8sRSxGLERdCmh1bmtIZWxwZXJzLnNldEZ1bmN0aW9uTmFtZXNJZk5lY2Vzc2FyeSh3KQp2
-YXIgJD17fQpILkZLLnByb3RvdHlwZT17fQpKLkd2LnByb3RvdHlwZT17CkROOmZ1bmN0aW9uKGEsYil7
-cmV0dXJuIGE9PT1ifSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBILmVRKGEpfSwKdzpmdW5jdGlvbihh
-KXtyZXR1cm4iSW5zdGFuY2Ugb2YgJyIrSC5FaihILk0oYSkpKyInIn0sCmU3OmZ1bmN0aW9uKGEsYil7
-dC5vLmEoYikKdGhyb3cgSC5iKFAubHIoYSxiLmdXYSgpLGIuZ25kKCksYi5nVm0oKSkpfX0KSi55RS5w
-cm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiBTdHJpbmcoYSl9LApnaU86ZnVuY3Rpb24oYSl7
-cmV0dXJuIGE/NTE5MDE4OjIxODE1OX0sCiRpYTI6MX0KSi53ZS5wcm90b3R5cGU9ewpETjpmdW5jdGlv
-bihhLGIpe3JldHVybiBudWxsPT1ifSwKdzpmdW5jdGlvbihhKXtyZXR1cm4ibnVsbCJ9LApnaU86ZnVu
-Y3Rpb24oYSl7cmV0dXJuIDB9LAplNzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlNqKGEsdC5vLmEo
-YikpfSwKJGljODoxfQpKLk1GLnByb3RvdHlwZT17CmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gMH0sCnc6
-ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmluZyhhKX0sCiRpdm06MX0KSi5pQy5wcm90b3R5cGU9e30KSi5r
-ZC5wcm90b3R5cGU9e30KSi5jNS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzPWFbJC53KCld
-CmlmKHM9PW51bGwpcmV0dXJuIHRoaXMudChhKQpyZXR1cm4iSmF2YVNjcmlwdCBmdW5jdGlvbiBmb3Ig
-IitILkVqKEouaihzKSl9LAokaUVIOjF9CkouamQucHJvdG90eXBlPXsKZHI6ZnVuY3Rpb24oYSxiKXty
-ZXR1cm4gbmV3IEgualYoYSxILnQ2KGEpLkMoIkA8MT4iKS5LcShiKS5DKCJqVjwxLDI+IikpfSwKaTpm
-dW5jdGlvbihhLGIpe0gudDYoYSkuYy5hKGIpCmlmKCEhYS5maXhlZCRsZW5ndGgpSC52KFAuTDQoImFk
-ZCIpKQphLnB1c2goYil9LApXNDpmdW5jdGlvbihhLGIpe3ZhciBzCmlmKCEhYS5maXhlZCRsZW5ndGgp
-SC52KFAuTDQoInJlbW92ZUF0IikpCnM9YS5sZW5ndGgKaWYoYj49cyl0aHJvdyBILmIoUC5PNyhiLG51
-bGwpKQpyZXR1cm4gYS5zcGxpY2UoYiwxKVswXX0sClVHOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyCkgu
-dDYoYSkuQygiY1g8MT4iKS5hKGMpCmlmKCEhYS5maXhlZCRsZW5ndGgpSC52KFAuTDQoImluc2VydEFs
-bCIpKQpQLndBKGIsMCxhLmxlbmd0aCwiaW5kZXgiKQppZighdC5iLmIoYykpYz1KLlJYKGMpCnM9Si5I
-bShjKQphLmxlbmd0aD1hLmxlbmd0aCtzCnI9YitzCnRoaXMuWVcoYSxyLGEubGVuZ3RoLGEsYikKdGhp
-cy52ZyhhLGIscixjKX0sCkZWOmZ1bmN0aW9uKGEsYil7dmFyIHMKSC50NihhKS5DKCJjWDwxPiIpLmEo
-YikKaWYoISFhLmZpeGVkJGxlbmd0aClILnYoUC5MNCgiYWRkQWxsIikpCmZvcihzPUouSVQoYik7cy5G
-KCk7KWEucHVzaChzLmdsKCkpfSwKRTI6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPUgudDYoYSkKcmV0dXJu
-IG5ldyBILmxKKGEscy5LcShjKS5DKCIxKDIpIikuYShiKSxzLkMoIkA8MT4iKS5LcShjKS5DKCJsSjwx
-LDI+IikpfSwKSDpmdW5jdGlvbihhLGIpe3ZhciBzLHI9UC5POChhLmxlbmd0aCwiIiwhMSx0Lk4pCmZv
-cihzPTA7czxhLmxlbmd0aDsrK3MpdGhpcy5ZKHIscyxILkVqKGFbc10pKQpyZXR1cm4gci5qb2luKGIp
-fSwKZVI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSC5xQyhhLGIsbnVsbCxILnQ2KGEpLmMpfSwKTjA6ZnVu
-Y3Rpb24oYSxiLGMsZCl7dmFyIHMscixxCmQuYShiKQpILnQ2KGEpLktxKGQpLkMoIjEoMSwyKSIpLmEo
-YykKcz1hLmxlbmd0aApmb3Iocj1iLHE9MDtxPHM7KytxKXtyPWMuJDIocixhW3FdKQppZihhLmxlbmd0
-aCE9PXMpdGhyb3cgSC5iKFAuYTQoYSkpfXJldHVybiByfSwKSHQ6ZnVuY3Rpb24oYSxiKXt2YXIgcyxy
-LHEscCxvCkgudDYoYSkuQygiYTIoMSkiKS5hKGIpCnM9YS5sZW5ndGgKZm9yKHI9bnVsbCxxPSExLHA9
-MDtwPHM7KytwKXtvPWFbcF0KaWYoSC5vVChiLiQxKG8pKSl7aWYocSl0aHJvdyBILmIoSC5BbSgpKQpy
-PW8KcT0hMH1pZihzIT09YS5sZW5ndGgpdGhyb3cgSC5iKFAuYTQoYSkpfWlmKHEpcmV0dXJuIHIKdGhy
-b3cgSC5iKEguV3AoKSl9LApFOmZ1bmN0aW9uKGEsYil7aWYoYjwwfHxiPj1hLmxlbmd0aClyZXR1cm4g
-SC5PSChhLGIpCnJldHVybiBhW2JdfSwKZ3RIOmZ1bmN0aW9uKGEpe2lmKGEubGVuZ3RoPjApcmV0dXJu
-IGFbMF0KdGhyb3cgSC5iKEguV3AoKSl9LApnclo6ZnVuY3Rpb24oYSl7dmFyIHM9YS5sZW5ndGgKaWYo
-cz4wKXJldHVybiBhW3MtMV0KdGhyb3cgSC5iKEguV3AoKSl9LApZVzpmdW5jdGlvbihhLGIsYyxkLGUp
-e3ZhciBzLHIscSxwLG8KSC50NihhKS5DKCJjWDwxPiIpLmEoZCkKaWYoISFhLmltbXV0YWJsZSRsaXN0
-KUgudihQLkw0KCJzZXRSYW5nZSIpKQpQLmpCKGIsYyxhLmxlbmd0aCkKcz1jLWIKaWYocz09PTApcmV0
-dXJuClAuazEoZSwic2tpcENvdW50IikKaWYodC5qLmIoZCkpe3I9ZApxPWV9ZWxzZXtyPUouQTUoZCxl
-KS50dCgwLCExKQpxPTB9cD1KLlU2KHIpCmlmKHErcz5wLmdBKHIpKXRocm93IEguYihILmFyKCkpCmlm
-KHE8Yilmb3Iobz1zLTE7bz49MDstLW8pYVtiK29dPXAucShyLHErbykKZWxzZSBmb3Iobz0wO288czsr
-K28pYVtiK29dPXAucShyLHErbyl9LAp2ZzpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gdGhpcy5ZVyhh
-LGIsYyxkLDApfSwKVnI6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCkgudDYoYSkuQygiYTIoMSkiKS5hKGIp
-CnM9YS5sZW5ndGgKZm9yKHI9MDtyPHM7KytyKXtpZihILm9UKGIuJDEoYVtyXSkpKXJldHVybiEwCmlm
-KGEubGVuZ3RoIT09cyl0aHJvdyBILmIoUC5hNChhKSl9cmV0dXJuITF9LAp0ZzpmdW5jdGlvbihhLGIp
-e3ZhciBzCmZvcihzPTA7czxhLmxlbmd0aDsrK3MpaWYoSi5STShhW3NdLGIpKXJldHVybiEwCnJldHVy
-biExfSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aD09PTB9LApnb3I6ZnVuY3Rpb24oYSl7
-cmV0dXJuIGEubGVuZ3RoIT09MH0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFAuV0UoYSwiWyIsIl0iKX0s
-CnR0OmZ1bmN0aW9uKGEsYil7dmFyIHM9SC5WTShhLnNsaWNlKDApLEgudDYoYSkpCnJldHVybiBzfSwK
-YnI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMudHQoYSwhMCl9LApnbTpmdW5jdGlvbihhKXtyZXR1cm4g
-bmV3IEoubTEoYSxhLmxlbmd0aCxILnQ2KGEpLkMoIm0xPDE+IikpfSwKZ2lPOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBILmVRKGEpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKc0E6ZnVuY3Rpb24o
-YSxiKXtpZighIWEuZml4ZWQkbGVuZ3RoKUgudihQLkw0KCJzZXQgbGVuZ3RoIikpCmlmKGI8MCl0aHJv
-dyBILmIoUC5URShiLDAsbnVsbCwibmV3TGVuZ3RoIixudWxsKSkKYS5sZW5ndGg9Yn0sCnE6ZnVuY3Rp
-b24oYSxiKXtILnVQKGIpCmlmKGI+PWEubGVuZ3RofHxiPDApdGhyb3cgSC5iKEguSFkoYSxiKSkKcmV0
-dXJuIGFbYl19LApZOmZ1bmN0aW9uKGEsYixjKXtILnQ2KGEpLmMuYShjKQppZighIWEuaW1tdXRhYmxl
-JGxpc3QpSC52KFAuTDQoImluZGV4ZWQgc2V0IikpCmlmKGI+PWEubGVuZ3RofHxiPDApdGhyb3cgSC5i
-KEguSFkoYSxiKSkKYVtiXT1jfSwKJGliUToxLAokaWNYOjEsCiRpek06MX0KSi5Qby5wcm90b3R5cGU9
-e30KSi5tMS5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmR9LApGOmZ1bmN0aW9u
-KCl7dmFyIHMscj10aGlzLHE9ci5hLHA9cS5sZW5ndGgKaWYoci5iIT09cCl0aHJvdyBILmIoSC5sayhx
-KSkKcz1yLmMKaWYocz49cCl7ci5zTShudWxsKQpyZXR1cm4hMX1yLnNNKHFbc10pOysrci5jCnJldHVy
-biEwfSwKc006ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLkMoIjE/IikuYShhKX0sCiRpQW46MX0K
-Si5xSS5wcm90b3R5cGU9ewp6UTpmdW5jdGlvbihhKXtpZihhPjApe2lmKGEhPT0xLzApcmV0dXJuIE1h
-dGgucm91bmQoYSl9ZWxzZSBpZihhPi0xLzApcmV0dXJuIDAtTWF0aC5yb3VuZCgwLWEpCnRocm93IEgu
-YihQLkw0KCIiK2ErIi5yb3VuZCgpIikpfSwKdzpmdW5jdGlvbihhKXtpZihhPT09MCYmMS9hPDApcmV0
-dXJuIi0wLjAiCmVsc2UgcmV0dXJuIiIrYX0sCmdpTzpmdW5jdGlvbihhKXt2YXIgcyxyLHEscCxvPWF8
-MAppZihhPT09bylyZXR1cm4gbyY1MzY4NzA5MTEKcz1NYXRoLmFicyhhKQpyPU1hdGgubG9nKHMpLzAu
-NjkzMTQ3MTgwNTU5OTQ1M3wwCnE9TWF0aC5wb3coMixyKQpwPXM8MT9zL3E6cS9zCnJldHVybigocCo5
-MDA3MTk5MjU0NzQwOTkyfDApKyhwKjM1NDIyNDMxODExNzY1MjF8MCkpKjU5OTE5NytyKjEyNTkmNTM2
-ODcwOTExfSwKelk6ZnVuY3Rpb24oYSxiKXt2YXIgcz1hJWIKaWYocz09PTApcmV0dXJuIDAKaWYocz4w
-KXJldHVybiBzCmlmKGI8MClyZXR1cm4gcy1iCmVsc2UgcmV0dXJuIHMrYn0sCkJVOmZ1bmN0aW9uKGEs
-Yil7cmV0dXJuKGF8MCk9PT1hP2EvYnwwOnRoaXMuREooYSxiKX0sCkRKOmZ1bmN0aW9uKGEsYil7dmFy
-IHM9YS9iCmlmKHM+PS0yMTQ3NDgzNjQ4JiZzPD0yMTQ3NDgzNjQ3KXJldHVybiBzfDAKaWYocz4wKXtp
-ZihzIT09MS8wKXJldHVybiBNYXRoLmZsb29yKHMpfWVsc2UgaWYocz4tMS8wKXJldHVybiBNYXRoLmNl
-aWwocykKdGhyb3cgSC5iKFAuTDQoIlJlc3VsdCBvZiB0cnVuY2F0aW5nIGRpdmlzaW9uIGlzICIrSC5F
-aihzKSsiOiAiK0guRWooYSkrIiB+LyAiK2IpKX0sCndHOmZ1bmN0aW9uKGEsYil7dmFyIHMKaWYoYT4w
-KXM9dGhpcy5wMyhhLGIpCmVsc2V7cz1iPjMxPzMxOmIKcz1hPj5zPj4+MH1yZXR1cm4gc30sCmJmOmZ1
-bmN0aW9uKGEsYil7aWYoYjwwKXRocm93IEguYihILnRMKGIpKQpyZXR1cm4gdGhpcy5wMyhhLGIpfSwK
-cDM6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYj4zMT8wOmE+Pj5ifSwKJGlDUDoxLAokaVpaOjF9CkouYlUu
-cHJvdG90eXBlPXskaUlmOjF9CkouVkEucHJvdG90eXBlPXt9CkouRHIucHJvdG90eXBlPXsKTzI6ZnVu
-Y3Rpb24oYSxiKXtpZihiPDApdGhyb3cgSC5iKEguSFkoYSxiKSkKaWYoYj49YS5sZW5ndGgpSC52KEgu
-SFkoYSxiKSkKcmV0dXJuIGEuY2hhckNvZGVBdChiKX0sClc6ZnVuY3Rpb24oYSxiKXtpZihiPj1hLmxl
-bmd0aCl0aHJvdyBILmIoSC5IWShhLGIpKQpyZXR1cm4gYS5jaGFyQ29kZUF0KGIpfSwKZGQ6ZnVuY3Rp
-b24oYSxiKXtyZXR1cm4gbmV3IEgudW4oYixhLDApfSwKaDpmdW5jdGlvbihhLGIpe2lmKHR5cGVvZiBi
-IT0ic3RyaW5nIil0aHJvdyBILmIoUC5MMyhiLG51bGwsbnVsbCkpCnJldHVybiBhK2J9LApUYzpmdW5j
-dGlvbihhLGIpe3ZhciBzPWIubGVuZ3RoLHI9YS5sZW5ndGgKaWYocz5yKXJldHVybiExCnJldHVybiBi
-PT09dGhpcy5HKGEsci1zKX0sCmk3OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzPVAuakIoYixjLGEubGVu
-Z3RoKSxyPWEuc3Vic3RyaW5nKDAsYikscT1hLnN1YnN0cmluZyhzKQpyZXR1cm4gcitkK3F9LApRaTpm
-dW5jdGlvbihhLGIsYyl7dmFyIHMKaWYoYzwwfHxjPmEubGVuZ3RoKXRocm93IEguYihQLlRFKGMsMCxh
-Lmxlbmd0aCxudWxsLG51bGwpKQpzPWMrYi5sZW5ndGgKaWYocz5hLmxlbmd0aClyZXR1cm4hMQpyZXR1
-cm4gYj09PWEuc3Vic3RyaW5nKGMscyl9LApuOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuUWkoYSxi
-LDApfSwKTmo6ZnVuY3Rpb24oYSxiLGMpe2lmKGM9PW51bGwpYz1hLmxlbmd0aAppZihiPDApdGhyb3cg
-SC5iKFAuTzcoYixudWxsKSkKaWYoYj5jKXRocm93IEguYihQLk83KGIsbnVsbCkpCmlmKGM+YS5sZW5n
-dGgpdGhyb3cgSC5iKFAuTzcoYyxudWxsKSkKcmV0dXJuIGEuc3Vic3RyaW5nKGIsYyl9LApHOmZ1bmN0
-aW9uKGEsYil7cmV0dXJuIHRoaXMuTmooYSxiLG51bGwpfSwKaGM6ZnVuY3Rpb24oYSl7cmV0dXJuIGEu
-dG9Mb3dlckNhc2UoKX0sCmJTOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPWEudHJpbSgpLG89cC5sZW5n
-dGgKaWYobz09PTApcmV0dXJuIHAKaWYodGhpcy5XKHAsMCk9PT0xMzMpe3M9Si5tbShwLDEpCmlmKHM9
-PT1vKXJldHVybiIifWVsc2Ugcz0wCnI9by0xCnE9dGhpcy5PMihwLHIpPT09MTMzP0ouYzEocCxyKTpv
-CmlmKHM9PT0wJiZxPT09bylyZXR1cm4gcApyZXR1cm4gcC5zdWJzdHJpbmcocyxxKX0sCkl4OmZ1bmN0
-aW9uKGEsYil7dmFyIHMscgppZigwPj1iKXJldHVybiIiCmlmKGI9PT0xfHxhLmxlbmd0aD09PTApcmV0
-dXJuIGEKaWYoYiE9PWI+Pj4wKXRocm93IEguYihDLkVxKQpmb3Iocz1hLHI9IiI7ITA7KXtpZigoYiYx
-KT09PTEpcj1zK3IKYj1iPj4+MQppZihiPT09MClicmVhawpzKz1zfXJldHVybiByfSwKWFU6ZnVuY3Rp
-b24oYSxiLGMpe3ZhciBzCmlmKGM8MHx8Yz5hLmxlbmd0aCl0aHJvdyBILmIoUC5URShjLDAsYS5sZW5n
-dGgsbnVsbCxudWxsKSkKcz1hLmluZGV4T2YoYixjKQpyZXR1cm4gc30sCk9ZOmZ1bmN0aW9uKGEsYil7
-cmV0dXJuIHRoaXMuWFUoYSxiLDApfSwKUGs6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIKaWYoYz09bnVs
-bCljPWEubGVuZ3RoCmVsc2UgaWYoYzwwfHxjPmEubGVuZ3RoKXRocm93IEguYihQLlRFKGMsMCxhLmxl
-bmd0aCxudWxsLG51bGwpKQpzPWIubGVuZ3RoCnI9YS5sZW5ndGgKaWYoYytzPnIpYz1yLXMKcmV0dXJu
-IGEubGFzdEluZGV4T2YoYixjKX0sCmNuOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuUGsoYSxiLG51
-bGwpfSwKSXM6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPWEubGVuZ3RoCmlmKGM+cyl0aHJvdyBILmIoUC5U
-RShjLDAscyxudWxsLG51bGwpKQpyZXR1cm4gSC5TUShhLGIsYyl9LAp0ZzpmdW5jdGlvbihhLGIpe3Jl
-dHVybiB0aGlzLklzKGEsYiwwKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIGF9LApnaU86ZnVuY3Rpb24o
-YSl7dmFyIHMscixxCmZvcihzPWEubGVuZ3RoLHI9MCxxPTA7cTxzOysrcSl7cj1yK2EuY2hhckNvZGVB
-dChxKSY1MzY4NzA5MTEKcj1yKygociY1MjQyODcpPDwxMCkmNTM2ODcwOTExCnJePXI+PjZ9cj1yKygo
-ciY2NzEwODg2Myk8PDMpJjUzNjg3MDkxMQpyXj1yPj4xMQpyZXR1cm4gcisoKHImMTYzODMpPDwxNSkm
-NTM2ODcwOTExfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIp
-e0gudVAoYikKaWYoYj49YS5sZW5ndGh8fCExKXRocm93IEguYihILkhZKGEsYikpCnJldHVybiBhW2Jd
-fSwKJGl2WDoxLAokaXFVOjF9CkguQlIucHJvdG90eXBlPXsKZ206ZnVuY3Rpb24oYSl7dmFyIHM9SC5M
-aCh0aGlzKQpyZXR1cm4gbmV3IEguRTcoSi5JVCh0aGlzLmdPTigpKSxzLkMoIkA8MT4iKS5LcShzLlFb
-MV0pLkMoIkU3PDEsMj4iKSl9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gSi5IbSh0aGlzLmdPTigpKX0s
-CmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gSi51VSh0aGlzLmdPTigpKX0sCmdvcjpmdW5jdGlvbihhKXty
-ZXR1cm4gSi5GNyh0aGlzLmdPTigpKX0sCmVSOmZ1bmN0aW9uKGEsYil7dmFyIHM9SC5MaCh0aGlzKQpy
-ZXR1cm4gSC5HSihKLkE1KHRoaXMuZ09OKCksYikscy5jLHMuUVsxXSl9LApFOmZ1bmN0aW9uKGEsYil7
-cmV0dXJuIEguTGgodGhpcykuUVsxXS5hKEouR0EodGhpcy5nT04oKSxiKSl9LAp3OmZ1bmN0aW9uKGEp
-e3JldHVybiBKLmoodGhpcy5nT04oKSl9fQpILkU3LnByb3RvdHlwZT17CkY6ZnVuY3Rpb24oKXtyZXR1
-cm4gdGhpcy5hLkYoKX0sCmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuJHRpLlFbMV0uYSh0aGlzLmEu
-Z2woKSl9LAokaUFuOjF9CkguWnkucHJvdG90eXBlPXsKZ09OOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMu
-YX19Ckgub2wucHJvdG90eXBlPXskaWJROjF9CkguVXEucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIp
-e3JldHVybiB0aGlzLiR0aS5RWzFdLmEoSi54OSh0aGlzLmEsSC51UChiKSkpfSwKWTpmdW5jdGlvbihh
-LGIsYyl7dmFyIHM9dGhpcy4kdGkKSi51OSh0aGlzLmEsYixzLmMuYShzLlFbMV0uYShjKSkpfSwKJGli
-UToxLAokaXpNOjF9CkgualYucHJvdG90eXBlPXsKZHI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IEgu
-alYodGhpcy5hLHRoaXMuJHRpLkMoIkA8MT4iKS5LcShiKS5DKCJqVjwxLDI+IikpfSwKZ09OOmZ1bmN0
-aW9uKCl7cmV0dXJuIHRoaXMuYX19Ckgubi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzPXRo
-aXMuYQpyZXR1cm4gcyE9bnVsbD8iTGF0ZUluaXRpYWxpemF0aW9uRXJyb3I6ICIrczoiTGF0ZUluaXRp
-YWxpemF0aW9uRXJyb3IifX0KSC5yMy5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzPSJSZWFj
-aGFiaWxpdHlFcnJvcjogIit0aGlzLmEKcmV0dXJuIHN9fQpILnFqLnByb3RvdHlwZT17CmdBOmZ1bmN0
-aW9uKGEpe3JldHVybiB0aGlzLmEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe3JldHVybiBDLnhCLk8y
-KHRoaXMuYSxILnVQKGIpKX19CkguR00ucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iTnVs
-bCBpcyBub3QgYSB2YWxpZCB2YWx1ZSBmb3IgdGhlIHBhcmFtZXRlciAnIit0aGlzLmErIicgb2YgdHlw
-ZSAnIitILkt4KHRoaXMuJHRpLmMpLncoMCkrIicifX0KSC5iUS5wcm90b3R5cGU9e30KSC5hTC5wcm90
-b3R5cGU9ewpnbTpmdW5jdGlvbihhKXt2YXIgcz10aGlzCnJldHVybiBuZXcgSC5hNyhzLHMuZ0Eocyks
-SC5MaChzKS5DKCJhNzxhTC5FPiIpKX0sCmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nQSh0aGlz
-KT09PTB9LApIOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHA9dGhpcyxvPXAuZ0EocCkKaWYoYi5sZW5n
-dGghPT0wKXtpZihvPT09MClyZXR1cm4iIgpzPUguRWoocC5FKDAsMCkpCmlmKG8hPT1wLmdBKHApKXRo
-cm93IEguYihQLmE0KHApKQpmb3Iocj1zLHE9MTtxPG87KytxKXtyPXIrYitILkVqKHAuRSgwLHEpKQpp
-ZihvIT09cC5nQShwKSl0aHJvdyBILmIoUC5hNChwKSl9cmV0dXJuIHIuY2hhckNvZGVBdCgwKT09MD9y
-OnJ9ZWxzZXtmb3IocT0wLHI9IiI7cTxvOysrcSl7cis9SC5FaihwLkUoMCxxKSkKaWYobyE9PXAuZ0Eo
-cCkpdGhyb3cgSC5iKFAuYTQocCkpfXJldHVybiByLmNoYXJDb2RlQXQoMCk9PTA/cjpyfX0sCmV2OmZ1
-bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuR0coMCxILkxoKHRoaXMpLkMoImEyKGFMLkUpIikuYShiKSl9
-LApFMjpmdW5jdGlvbihhLGIsYyl7dmFyIHM9SC5MaCh0aGlzKQpyZXR1cm4gbmV3IEgubEoodGhpcyxz
-LktxKGMpLkMoIjEoYUwuRSkiKS5hKGIpLHMuQygiQDxhTC5FPiIpLktxKGMpLkMoImxKPDEsMj4iKSl9
-LAplUjpmdW5jdGlvbihhLGIpe3JldHVybiBILnFDKHRoaXMsYixudWxsLEguTGgodGhpcykuQygiYUwu
-RSIpKX0sCnR0OmZ1bmN0aW9uKGEsYil7cmV0dXJuIFAuWTEodGhpcywhMCxILkxoKHRoaXMpLkMoImFM
-LkUiKSl9LApicjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy50dChhLCEwKX19CkgubkgucHJvdG90eXBl
-PXsKSGQ6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscj10aGlzLmIKUC5rMShyLCJzdGFydCIpCnM9dGhp
-cy5jCmlmKHMhPW51bGwpe1AuazEocywiZW5kIikKaWYocj5zKXRocm93IEguYihQLlRFKHIsMCxzLCJz
-dGFydCIsbnVsbCkpfX0sCmdVRDpmdW5jdGlvbigpe3ZhciBzPUouSG0odGhpcy5hKSxyPXRoaXMuYwpp
-ZihyPT1udWxsfHxyPnMpcmV0dXJuIHMKcmV0dXJuIHJ9LApnQXM6ZnVuY3Rpb24oKXt2YXIgcz1KLkht
-KHRoaXMuYSkscj10aGlzLmIKaWYocj5zKXJldHVybiBzCnJldHVybiByfSwKZ0E6ZnVuY3Rpb24oYSl7
-dmFyIHMscj1KLkhtKHRoaXMuYSkscT10aGlzLmIKaWYocT49cilyZXR1cm4gMApzPXRoaXMuYwppZihz
-PT1udWxsfHxzPj1yKXJldHVybiByLXEKaWYodHlwZW9mIHMhPT0ibnVtYmVyIilyZXR1cm4gcy5ITigp
-CnJldHVybiBzLXF9LApFOmZ1bmN0aW9uKGEsYil7dmFyIHM9dGhpcyxyPXMuZ0FzKCkrYgppZihiPDB8
-fHI+PXMuZ1VEKCkpdGhyb3cgSC5iKFAuQ2YoYixzLCJpbmRleCIsbnVsbCxudWxsKSkKcmV0dXJuIEou
-R0Eocy5hLHIpfSwKZVI6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHE9dGhpcwpQLmsxKGIsImNvdW50IikK
-cz1xLmIrYgpyPXEuYwppZihyIT1udWxsJiZzPj1yKXJldHVybiBuZXcgSC5NQihxLiR0aS5DKCJNQjwx
-PiIpKQpyZXR1cm4gSC5xQyhxLmEscyxyLHEuJHRpLmMpfSwKdHQ6ZnVuY3Rpb24oYSxiKXt2YXIgcyxy
-LHEscD10aGlzLG89cC5iLG49cC5hLG09Si5VNihuKSxsPW0uZ0Eobiksaz1wLmMKaWYoayE9bnVsbCYm
-azxsKWw9awppZih0eXBlb2YgbCE9PSJudW1iZXIiKXJldHVybiBsLkhOKCkKcz1sLW8KaWYoczw9MCl7
-bj1KLlFpKDAscC4kdGkuYykKcmV0dXJuIG59cj1QLk84KHMsbS5FKG4sbyksITEscC4kdGkuYykKZm9y
-KHE9MTtxPHM7KytxKXtDLk5tLlkocixxLG0uRShuLG8rcSkpCmlmKG0uZ0Eobik8bCl0aHJvdyBILmIo
-UC5hNChwKSl9cmV0dXJuIHJ9fQpILmE3LnByb3RvdHlwZT17CmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRo
-aXMuZH0sCkY6ZnVuY3Rpb24oKXt2YXIgcyxyPXRoaXMscT1yLmEscD1KLlU2KHEpLG89cC5nQShxKQpp
-ZihyLmIhPT1vKXRocm93IEguYihQLmE0KHEpKQpzPXIuYwppZihzPj1vKXtyLnNJKG51bGwpCnJldHVy
-biExfXIuc0kocC5FKHEscykpOysrci5jCnJldHVybiEwfSwKc0k6ZnVuY3Rpb24oYSl7dGhpcy5kPXRo
-aXMuJHRpLkMoIjE/IikuYShhKX0sCiRpQW46MX0KSC5pMS5wcm90b3R5cGU9ewpnbTpmdW5jdGlvbihh
-KXt2YXIgcz1ILkxoKHRoaXMpCnJldHVybiBuZXcgSC5NSChKLklUKHRoaXMuYSksdGhpcy5iLHMuQygi
-QDwxPiIpLktxKHMuUVsxXSkuQygiTUg8MSwyPiIpKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiBKLkht
-KHRoaXMuYSl9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIEoudVUodGhpcy5hKX0sCkU6ZnVuY3Rpb24o
-YSxiKXtyZXR1cm4gdGhpcy5iLiQxKEouR0EodGhpcy5hLGIpKX19CkgueHkucHJvdG90eXBlPXskaWJR
-OjF9CkguTUgucHJvdG90eXBlPXsKRjpmdW5jdGlvbigpe3ZhciBzPXRoaXMscj1zLmIKaWYoci5GKCkp
-e3Muc0kocy5jLiQxKHIuZ2woKSkpCnJldHVybiEwfXMuc0kobnVsbCkKcmV0dXJuITF9LApnbDpmdW5j
-dGlvbigpe3JldHVybiB0aGlzLmF9LApzSTpmdW5jdGlvbihhKXt0aGlzLmE9dGhpcy4kdGkuQygiMj8i
-KS5hKGEpfX0KSC5sSi5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gSi5IbSh0aGlzLmEp
-fSwKRTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmIuJDEoSi5HQSh0aGlzLmEsYikpfX0KSC5VNS5w
-cm90b3R5cGU9ewpnbTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEguU08oSi5JVCh0aGlzLmEpLHRoaXMu
-Yix0aGlzLiR0aS5DKCJTTzwxPiIpKX19CkguU08ucHJvdG90eXBlPXsKRjpmdW5jdGlvbigpe3ZhciBz
-LHIKZm9yKHM9dGhpcy5hLHI9dGhpcy5iO3MuRigpOylpZihILm9UKHIuJDEocy5nbCgpKSkpcmV0dXJu
-ITAKcmV0dXJuITF9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmEuZ2woKX19CkguQU0ucHJvdG90
-eXBlPXsKZVI6ZnVuY3Rpb24oYSxiKXtQLk1SKGIsImNvdW50Iix0LlMpClAuazEoYiwiY291bnQiKQpy
-ZXR1cm4gbmV3IEguQU0odGhpcy5hLHRoaXMuYitiLEguTGgodGhpcykuQygiQU08MT4iKSl9LApnbTpm
-dW5jdGlvbihhKXtyZXR1cm4gbmV3IEguVTEoSi5JVCh0aGlzLmEpLHRoaXMuYixILkxoKHRoaXMpLkMo
-IlUxPDE+IikpfX0KSC5kNS5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXt2YXIgcz1KLkhtKHRoaXMu
-YSktdGhpcy5iCmlmKHM+PTApcmV0dXJuIHMKcmV0dXJuIDB9LAplUjpmdW5jdGlvbihhLGIpe1AuTVIo
-YiwiY291bnQiLHQuUykKUC5rMShiLCJjb3VudCIpCnJldHVybiBuZXcgSC5kNSh0aGlzLmEsdGhpcy5i
-K2IsdGhpcy4kdGkpfSwKJGliUToxfQpILlUxLnByb3RvdHlwZT17CkY6ZnVuY3Rpb24oKXt2YXIgcyxy
-CmZvcihzPXRoaXMuYSxyPTA7cjx0aGlzLmI7KytyKXMuRigpCnRoaXMuYj0wCnJldHVybiBzLkYoKX0s
-CmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYS5nbCgpfX0KSC5NQi5wcm90b3R5cGU9ewpnbTpmdW5j
-dGlvbihhKXtyZXR1cm4gQy5Hd30sCmdsMDpmdW5jdGlvbihhKXtyZXR1cm4hMH0sCmdBOmZ1bmN0aW9u
-KGEpe3JldHVybiAwfSwKRTpmdW5jdGlvbihhLGIpe3Rocm93IEguYihQLlRFKGIsMCwwLCJpbmRleCIs
-bnVsbCkpfSwKZVI6ZnVuY3Rpb24oYSxiKXtQLmsxKGIsImNvdW50IikKcmV0dXJuIHRoaXN9fQpILkZ1
-LnByb3RvdHlwZT17CkY6ZnVuY3Rpb24oKXtyZXR1cm4hMX0sCmdsOmZ1bmN0aW9uKCl7dGhyb3cgSC5i
-KEguV3AoKSl9LAokaUFuOjF9CkgudTYucHJvdG90eXBlPXsKZ206ZnVuY3Rpb24oYSl7cmV0dXJuIG5l
-dyBILkpCKEouSVQodGhpcy5hKSx0aGlzLiR0aS5DKCJKQjwxPiIpKX19CkguSkIucHJvdG90eXBlPXsK
-RjpmdW5jdGlvbigpe3ZhciBzLHIKZm9yKHM9dGhpcy5hLHI9dGhpcy4kdGkuYztzLkYoKTspaWYoci5i
-KHMuZ2woKSkpcmV0dXJuITAKcmV0dXJuITF9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLiR0aS5j
-LmEodGhpcy5hLmdsKCkpfSwKJGlBbjoxfQpILlNVLnByb3RvdHlwZT17fQpILlJlLnByb3RvdHlwZT17
-Clk6ZnVuY3Rpb24oYSxiLGMpe0guTGgodGhpcykuQygiUmUuRSIpLmEoYykKdGhyb3cgSC5iKFAuTDQo
-IkNhbm5vdCBtb2RpZnkgYW4gdW5tb2RpZmlhYmxlIGxpc3QiKSl9fQpILncyLnByb3RvdHlwZT17fQpI
-Lnd2LnByb3RvdHlwZT17CmdpTzpmdW5jdGlvbihhKXt2YXIgcz10aGlzLl9oYXNoQ29kZQppZihzIT1u
-dWxsKXJldHVybiBzCnM9NjY0NTk3KkouaGYodGhpcy5hKSY1MzY4NzA5MTEKdGhpcy5faGFzaENvZGU9
-cwpyZXR1cm4gc30sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuJ1N5bWJvbCgiJytILkVqKHRoaXMuYSkrJyIp
-J30sCkROOmZ1bmN0aW9uKGEsYil7aWYoYj09bnVsbClyZXR1cm4hMQpyZXR1cm4gYiBpbnN0YW5jZW9m
-IEgud3YmJnRoaXMuYT09Yi5hfSwKJGlHRDoxfQpILlFDLnByb3RvdHlwZT17fQpILlBELnByb3RvdHlw
-ZT17fQpILldVLnByb3RvdHlwZT17CmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nQSh0aGlzKT09
-PTB9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBQLm5PKHRoaXMpfSwKWTpmdW5jdGlvbihhLGIsYyl7dmFy
-IHM9SC5MaCh0aGlzKQpzLmMuYShiKQpzLlFbMV0uYShjKQpILmRjKCkKSC5CaSh1LmcpfSwKZ1B1OmZ1
-bmN0aW9uKGEpe3JldHVybiB0aGlzLnE0KGEsSC5MaCh0aGlzKS5DKCJOMzwxLDI+IikpfSwKcTQ6ZnVu
-Y3Rpb24oYSxiKXt2YXIgcz10aGlzCnJldHVybiBQLmwwKGZ1bmN0aW9uKCl7dmFyIHI9YQp2YXIgcT0w
-LHA9MSxvLG4sbSxsLGsKcmV0dXJuIGZ1bmN0aW9uICRhc3luYyRnUHUoYyxkKXtpZihjPT09MSl7bz1k
-CnE9cH13aGlsZSh0cnVlKXN3aXRjaChxKXtjYXNlIDA6bj1zLmdWKCksbj1uLmdtKG4pLG09SC5MaChz
-KSxtPW0uQygiQDwxPiIpLktxKG0uUVsxXSkuQygiTjM8MSwyPiIpCmNhc2UgMjppZighbi5GKCkpe3E9
-MwpicmVha31sPW4uZ2woKQprPXMucSgwLGwpCmsudG9TdHJpbmcKcT00CnJldHVybiBuZXcgUC5OMyhs
-LGssbSkKY2FzZSA0OnE9MgpicmVhawpjYXNlIDM6cmV0dXJuIFAuVGgoKQpjYXNlIDE6cmV0dXJuIFAu
-WW0obyl9fX0sYil9LAokaVowOjF9CkguTFAucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJu
-IHRoaXMuYX0sCng0OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhIT0ic3RyaW5nIilyZXR1cm4hMQppZigi
-X19wcm90b19fIj09PWEpcmV0dXJuITEKcmV0dXJuIHRoaXMuYi5oYXNPd25Qcm9wZXJ0eShhKX0sCnE6
-ZnVuY3Rpb24oYSxiKXtpZighdGhpcy54NChiKSlyZXR1cm4gbnVsbApyZXR1cm4gdGhpcy5xUChiKX0s
-CnFQOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmJbSC5oKGEpXX0sCks6ZnVuY3Rpb24oYSxiKXt2YXIg
-cyxyLHEscCxvPUguTGgodGhpcykKby5DKCJ+KDEsMikiKS5hKGIpCnM9dGhpcy5jCmZvcihyPXMubGVu
-Z3RoLG89by5RWzFdLHE9MDtxPHI7KytxKXtwPXNbcV0KYi4kMihwLG8uYSh0aGlzLnFQKHApKSl9fSwK
-Z1Y6ZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEguWFIodGhpcyxILkxoKHRoaXMpLkMoIlhSPDE+IikpfX0K
-SC5YUi5wcm90b3R5cGU9ewpnbTpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmEuYwpyZXR1cm4gbmV3IEou
-bTEocyxzLmxlbmd0aCxILnQ2KHMpLkMoIm0xPDE+IikpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRo
-aXMuYS5jLmxlbmd0aH19CkguTEkucHJvdG90eXBlPXsKZ1dhOmZ1bmN0aW9uKCl7dmFyIHM9dGhpcy5h
-CnJldHVybiBzfSwKZ25kOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbz10aGlzCmlmKG8uYz09PTEpcmV0
-dXJuIEMuaFUKcz1vLmQKcj1zLmxlbmd0aC1vLmUubGVuZ3RoLW8uZgppZihyPT09MClyZXR1cm4gQy5o
-VQpxPVtdCmZvcihwPTA7cDxyOysrcCl7aWYocD49cy5sZW5ndGgpcmV0dXJuIEguT0gocyxwKQpxLnB1
-c2goc1twXSl9cmV0dXJuIEouekMocSl9LApnVm06ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvLG4sbSxs
-LGs9dGhpcwppZihrLmMhPT0wKXJldHVybiBDLldPCnM9ay5lCnI9cy5sZW5ndGgKcT1rLmQKcD1xLmxl
-bmd0aC1yLWsuZgppZihyPT09MClyZXR1cm4gQy5XTwpvPW5ldyBILk41KHQuZW8pCmZvcihuPTA7bjxy
-Oysrbil7aWYobj49cy5sZW5ndGgpcmV0dXJuIEguT0gocyxuKQptPXNbbl0KbD1wK24KaWYobDwwfHxs
-Pj1xLmxlbmd0aClyZXR1cm4gSC5PSChxLGwpCm8uWSgwLG5ldyBILnd2KG0pLHFbbF0pfXJldHVybiBu
-ZXcgSC5QRChvLHQuZ0YpfSwKJGl2UToxfQpILkNqLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7
-dmFyIHMKSC5oKGEpCnM9dGhpcy5hCnMuYj1zLmIrIiQiK0guRWooYSkKQy5ObS5pKHRoaXMuYixhKQpD
-Lk5tLmkodGhpcy5jLGIpOysrcy5hfSwKJFM6MTJ9CkguZjkucHJvdG90eXBlPXsKcVM6ZnVuY3Rpb24o
-YSl7dmFyIHMscixxPXRoaXMscD1uZXcgUmVnRXhwKHEuYSkuZXhlYyhhKQppZihwPT1udWxsKXJldHVy
-biBudWxsCnM9T2JqZWN0LmNyZWF0ZShudWxsKQpyPXEuYgppZihyIT09LTEpcy5hcmd1bWVudHM9cFty
-KzFdCnI9cS5jCmlmKHIhPT0tMSlzLmFyZ3VtZW50c0V4cHI9cFtyKzFdCnI9cS5kCmlmKHIhPT0tMSlz
-LmV4cHI9cFtyKzFdCnI9cS5lCmlmKHIhPT0tMSlzLm1ldGhvZD1wW3IrMV0Kcj1xLmYKaWYociE9PS0x
-KXMucmVjZWl2ZXI9cFtyKzFdCnJldHVybiBzfX0KSC5XMC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEp
-e3ZhciBzPXRoaXMuYgppZihzPT1udWxsKXJldHVybiJOb1N1Y2hNZXRob2RFcnJvcjogIitILkVqKHRo
-aXMuYSkKcmV0dXJuIk5vU3VjaE1ldGhvZEVycm9yOiBtZXRob2Qgbm90IGZvdW5kOiAnIitzKyInIG9u
-IG51bGwifX0KSC5hei5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzLHI9dGhpcyxxPSJOb1N1
-Y2hNZXRob2RFcnJvcjogbWV0aG9kIG5vdCBmb3VuZDogJyIscD1yLmIKaWYocD09bnVsbClyZXR1cm4i
-Tm9TdWNoTWV0aG9kRXJyb3I6ICIrSC5FaihyLmEpCnM9ci5jCmlmKHM9PW51bGwpcmV0dXJuIHErcCsi
-JyAoIitILkVqKHIuYSkrIikiCnJldHVybiBxK3ArIicgb24gJyIrcysiJyAoIitILkVqKHIuYSkrIiki
-fX0KSC52Vi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuYQpyZXR1cm4gcy5sZW5n
-dGg9PT0wPyJFcnJvciI6IkVycm9yOiAiK3N9fQpILnRlLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7
-cmV0dXJuIlRocm93IG9mIG51bGwgKCciKyh0aGlzLmE9PT1udWxsPyJudWxsIjoidW5kZWZpbmVkIikr
-IicgZnJvbSBKYXZhU2NyaXB0KSJ9LAokaVJ6OjF9CkguYnEucHJvdG90eXBlPXt9CkguWE8ucHJvdG90
-eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgcyxyPXRoaXMuYgppZihyIT1udWxsKXJldHVybiByCnI9dGhp
-cy5hCnM9ciE9PW51bGwmJnR5cGVvZiByPT09Im9iamVjdCI/ci5zdGFjazpudWxsCnJldHVybiB0aGlz
-LmI9cz09bnVsbD8iIjpzfSwKJGlHejoxfQpILlRwLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFy
-IHM9dGhpcy5jb25zdHJ1Y3RvcixyPXM9PW51bGw/bnVsbDpzLm5hbWUKcmV0dXJuIkNsb3N1cmUgJyIr
-SC5OUShyPT1udWxsPyJ1bmtub3duIjpyKSsiJyJ9LAokaUVIOjEsCmdLdTpmdW5jdGlvbigpe3JldHVy
-biB0aGlzfSwKJEM6IiQxIiwKJFI6MSwKJEQ6bnVsbH0KSC5sYy5wcm90b3R5cGU9e30KSC56eC5wcm90
-b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuJHN0YXRpY19uYW1lCmlmKHM9PW51bGwpcmV0
-dXJuIkNsb3N1cmUgb2YgdW5rbm93biBzdGF0aWMgbWV0aG9kIgpyZXR1cm4iQ2xvc3VyZSAnIitILk5R
-KHMpKyInIn19CkguclQucHJvdG90eXBlPXsKRE46ZnVuY3Rpb24oYSxiKXt2YXIgcz10aGlzCmlmKGI9
-PW51bGwpcmV0dXJuITEKaWYocz09PWIpcmV0dXJuITAKaWYoIShiIGluc3RhbmNlb2YgSC5yVCkpcmV0
-dXJuITEKcmV0dXJuIHMuYT09PWIuYSYmcy5iPT09Yi5iJiZzLmM9PT1iLmN9LApnaU86ZnVuY3Rpb24o
-YSl7dmFyIHMscj10aGlzLmMKaWYocj09bnVsbClzPUguZVEodGhpcy5hKQplbHNlIHM9dHlwZW9mIHIh
-PT0ib2JqZWN0Ij9KLmhmKHIpOkguZVEocikKcj1ILmVRKHRoaXMuYikKaWYodHlwZW9mIHMhPT0ibnVt
-YmVyIilyZXR1cm4gcy53TygpCnJldHVybihzXnIpPj4+MH0sCnc6ZnVuY3Rpb24oYSl7dmFyIHM9dGhp
-cy5jCmlmKHM9PW51bGwpcz10aGlzLmEKcmV0dXJuIkNsb3N1cmUgJyIrSC5Faih0aGlzLmQpKyInIG9m
-ICIrKCJJbnN0YW5jZSBvZiAnIitILkVqKEguTShzKSkrIiciKX19CkguRXEucHJvdG90eXBlPXsKdzpm
-dW5jdGlvbihhKXtyZXR1cm4iUnVudGltZUVycm9yOiAiK3RoaXMuYX19Ckgua1kucHJvdG90eXBlPXsK
-dzpmdW5jdGlvbihhKXtyZXR1cm4iQXNzZXJ0aW9uIGZhaWxlZDogIitQLnAodGhpcy5hKX19Ckgua3Iu
-cHJvdG90eXBlPXt9CkguTjUucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYX0s
-CmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hPT09MH0sCmdWOmZ1bmN0aW9uKCl7cmV0dXJuIG5l
-dyBILmk1KHRoaXMsSC5MaCh0aGlzKS5DKCJpNTwxPiIpKX0sCng0OmZ1bmN0aW9uKGEpe3ZhciBzLHIK
-aWYodHlwZW9mIGE9PSJzdHJpbmciKXtzPXRoaXMuYgppZihzPT1udWxsKXJldHVybiExCnJldHVybiB0
-aGlzLlh1KHMsYSl9ZWxzZXtyPXRoaXMuQ1goYSkKcmV0dXJuIHJ9fSwKQ1g6ZnVuY3Rpb24oYSl7dmFy
-IHM9dGhpcy5kCmlmKHM9PW51bGwpcmV0dXJuITEKcmV0dXJuIHRoaXMuRmgodGhpcy5CdChzLEouaGYo
-YSkmMHgzZmZmZmZmKSxhKT49MH0sCnE6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvPXRoaXMsbj1u
-dWxsCmlmKHR5cGVvZiBiPT0ic3RyaW5nIil7cz1vLmIKaWYocz09bnVsbClyZXR1cm4gbgpyPW8uajIo
-cyxiKQpxPXI9PW51bGw/bjpyLmIKcmV0dXJuIHF9ZWxzZSBpZih0eXBlb2YgYj09Im51bWJlciImJihi
-JjB4M2ZmZmZmZik9PT1iKXtwPW8uYwppZihwPT1udWxsKXJldHVybiBuCnI9by5qMihwLGIpCnE9cj09
-bnVsbD9uOnIuYgpyZXR1cm4gcX1lbHNlIHJldHVybiBvLmFhKGIpfSwKYWE6ZnVuY3Rpb24oYSl7dmFy
-IHMscixxPXRoaXMuZAppZihxPT1udWxsKXJldHVybiBudWxsCnM9dGhpcy5CdChxLEouaGYoYSkmMHgz
-ZmZmZmZmKQpyPXRoaXMuRmgocyxhKQppZihyPDApcmV0dXJuIG51bGwKcmV0dXJuIHNbcl0uYn0sClk6
-ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscSxwLG8sbixtPXRoaXMsbD1ILkxoKG0pCmwuYy5hKGIpCmwu
-UVsxXS5hKGMpCmlmKHR5cGVvZiBiPT0ic3RyaW5nIil7cz1tLmIKbS5FSChzPT1udWxsP20uYj1tLnpL
-KCk6cyxiLGMpfWVsc2UgaWYodHlwZW9mIGI9PSJudW1iZXIiJiYoYiYweDNmZmZmZmYpPT09Yil7cj1t
-LmMKbS5FSChyPT1udWxsP20uYz1tLnpLKCk6cixiLGMpfWVsc2V7cT1tLmQKaWYocT09bnVsbClxPW0u
-ZD1tLnpLKCkKcD1KLmhmKGIpJjB4M2ZmZmZmZgpvPW0uQnQocSxwKQppZihvPT1udWxsKW0uRUkocSxw
-LFttLkhuKGIsYyldKQplbHNle249bS5GaChvLGIpCmlmKG4+PTApb1tuXS5iPWMKZWxzZSBvLnB1c2go
-bS5IbihiLGMpKX19fSwKSzpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT10aGlzCkguTGgocSkuQygifigx
-LDIpIikuYShiKQpzPXEuZQpyPXEucgpmb3IoO3MhPW51bGw7KXtiLiQyKHMuYSxzLmIpCmlmKHIhPT1x
-LnIpdGhyb3cgSC5iKFAuYTQocSkpCnM9cy5jfX0sCkVIOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyPXRo
-aXMscT1ILkxoKHIpCnEuYy5hKGIpCnEuUVsxXS5hKGMpCnM9ci5qMihhLGIpCmlmKHM9PW51bGwpci5F
-SShhLGIsci5IbihiLGMpKQplbHNlIHMuYj1jfSwKa3M6ZnVuY3Rpb24oKXt0aGlzLnI9dGhpcy5yKzEm
-NjcxMDg4NjN9LApIbjpmdW5jdGlvbihhLGIpe3ZhciBzPXRoaXMscj1ILkxoKHMpLHE9bmV3IEgudmgo
-ci5jLmEoYSksci5RWzFdLmEoYikpCmlmKHMuZT09bnVsbClzLmU9cy5mPXEKZWxzZXtyPXMuZgpyLnRv
-U3RyaW5nCnEuZD1yCnMuZj1yLmM9cX0rK3MuYQpzLmtzKCkKcmV0dXJuIHF9LApGaDpmdW5jdGlvbihh
-LGIpe3ZhciBzLHIKaWYoYT09bnVsbClyZXR1cm4tMQpzPWEubGVuZ3RoCmZvcihyPTA7cjxzOysrcilp
-ZihKLlJNKGFbcl0uYSxiKSlyZXR1cm4gcgpyZXR1cm4tMX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFAu
-bk8odGhpcyl9LApqMjpmdW5jdGlvbihhLGIpe3JldHVybiBhW2JdfSwKQnQ6ZnVuY3Rpb24oYSxiKXty
-ZXR1cm4gYVtiXX0sCkVJOmZ1bmN0aW9uKGEsYixjKXthW2JdPWN9LApybjpmdW5jdGlvbihhLGIpe2Rl
-bGV0ZSBhW2JdfSwKWHU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5qMihhLGIpIT1udWxsfSwKeks6
-ZnVuY3Rpb24oKXt2YXIgcz0iPG5vbi1pZGVudGlmaWVyLWtleT4iLHI9T2JqZWN0LmNyZWF0ZShudWxs
-KQp0aGlzLkVJKHIscyxyKQp0aGlzLnJuKHIscykKcmV0dXJuIHJ9LAokaUZvOjF9CkgudmgucHJvdG90
-eXBlPXt9CkguaTUucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5hfSwKZ2ww
-OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuYT09PTB9LApnbTpmdW5jdGlvbihhKXt2YXIgcz10aGlz
-LmEscj1uZXcgSC5ONihzLHMucix0aGlzLiR0aS5DKCJONjwxPiIpKQpyLmM9cy5lCnJldHVybiByfSwK
-dGc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5hLng0KGIpfX0KSC5ONi5wcm90b3R5cGU9ewpnbDpm
-dW5jdGlvbigpe3JldHVybiB0aGlzLmR9LApGOmZ1bmN0aW9uKCl7dmFyIHMscj10aGlzLHE9ci5hCmlm
-KHIuYiE9PXEucil0aHJvdyBILmIoUC5hNChxKSkKcz1yLmMKaWYocz09bnVsbCl7ci5zcVkobnVsbCkK
-cmV0dXJuITF9ZWxzZXtyLnNxWShzLmEpCnIuYz1zLmMKcmV0dXJuITB9fSwKc3FZOmZ1bmN0aW9uKGEp
-e3RoaXMuZD10aGlzLiR0aS5DKCIxPyIpLmEoYSl9LAokaUFuOjF9CkguZEMucHJvdG90eXBlPXsKJDE6
-ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYShhKX0sCiRTOjR9Ckgud04ucHJvdG90eXBlPXsKJDI6ZnVu
-Y3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5hKGEsYil9LAokUzo0Nn0KSC5WWC5wcm90b3R5cGU9ewokMTpm
-dW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hKEguaChhKSl9LAokUzo0MX0KSC5WUi5wcm90b3R5cGU9ewp3
-OmZ1bmN0aW9uKGEpe3JldHVybiJSZWdFeHAvIit0aGlzLmErIi8iK3RoaXMuYi5mbGFnc30sCmdIYzpm
-dW5jdGlvbigpe3ZhciBzPXRoaXMscj1zLmMKaWYociE9bnVsbClyZXR1cm4gcgpyPXMuYgpyZXR1cm4g
-cy5jPUgudjQocy5hLHIubXVsdGlsaW5lLCFyLmlnbm9yZUNhc2Usci51bmljb2RlLHIuZG90QWxsLCEw
-KX0sCmRkOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILktXKHRoaXMsYiwwKX0sClVaOmZ1bmN0aW9u
-KGEsYil7dmFyIHMscj10aGlzLmdIYygpCnIubGFzdEluZGV4PWIKcz1yLmV4ZWMoYSkKaWYocz09bnVs
-bClyZXR1cm4gbnVsbApyZXR1cm4gbmV3IEguRUsocyl9LAokaXZYOjEsCiRpd0w6MX0KSC5FSy5wcm90
-b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7dmFyIHMKSC51UChiKQpzPXRoaXMuYgppZihiPj1zLmxlbmd0
-aClyZXR1cm4gSC5PSChzLGIpCnJldHVybiBzW2JdfSwKJGlPZDoxLAokaWliOjF9CkguS1cucHJvdG90
-eXBlPXsKZ206ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILlBiKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX19
-CkguUGIucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKRjpmdW5jdGlvbigp
-e3ZhciBzLHIscSxwLG8sbixtPXRoaXMsbD1tLmIKaWYobD09bnVsbClyZXR1cm4hMQpzPW0uYwpyPWwu
-bGVuZ3RoCmlmKHM8PXIpe3E9bS5hCnA9cS5VWihsLHMpCmlmKHAhPW51bGwpe20uZD1wCnM9cC5iCm89
-cy5pbmRleApuPW8rc1swXS5sZW5ndGgKaWYobz09PW4pe2lmKHEuYi51bmljb2RlKXtzPW0uYwpxPXMr
-MQppZihxPHIpe3M9Qy54Qi5PMihsLHMpCmlmKHM+PTU1Mjk2JiZzPD01NjMxOSl7cz1DLnhCLk8yKGws
-cSkKcz1zPj01NjMyMCYmczw9NTczNDN9ZWxzZSBzPSExfWVsc2Ugcz0hMX1lbHNlIHM9ITEKbj0ocz9u
-KzE6bikrMX1tLmM9bgpyZXR1cm4hMH19bS5iPW0uZD1udWxsCnJldHVybiExfSwKJGlBbjoxfQpILnRR
-LnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILnVQKGIpCmlmKGIhPT0wKUgudihQLk83KGIsbnVs
-bCkpCnJldHVybiB0aGlzLmN9LAokaU9kOjF9CkgudW4ucHJvdG90eXBlPXsKZ206ZnVuY3Rpb24oYSl7
-cmV0dXJuIG5ldyBILlNkKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX19CkguU2QucHJvdG90eXBlPXsKRjpm
-dW5jdGlvbigpe3ZhciBzLHIscT10aGlzLHA9cS5jLG89cS5iLG49by5sZW5ndGgsbT1xLmEsbD1tLmxl
-bmd0aAppZihwK24+bCl7cS5kPW51bGwKcmV0dXJuITF9cz1tLmluZGV4T2YobyxwKQppZihzPDApe3Eu
-Yz1sKzEKcS5kPW51bGwKcmV0dXJuITF9cj1zK24KcS5kPW5ldyBILnRRKHMsbykKcS5jPXI9PT1xLmM/
-cisxOnIKcmV0dXJuITB9LApnbDpmdW5jdGlvbigpe3ZhciBzPXRoaXMuZApzLnRvU3RyaW5nCnJldHVy
-biBzfSwKJGlBbjoxfQpILkVULnByb3RvdHlwZT17JGlFVDoxLCRpQVM6MX0KSC5MWi5wcm90b3R5cGU9
-ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LAokaVhqOjF9CkguRGcucHJvdG90eXBlPXsK
-cTpmdW5jdGlvbihhLGIpe0gudVAoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfSwKWTpm
-dW5jdGlvbihhLGIsYyl7SC5HSChjKQpILm9kKGIsYSxhLmxlbmd0aCkKYVtiXT1jfSwKJGliUToxLAok
-aWNYOjEsCiRpek06MX0KSC5QZy5wcm90b3R5cGU9ewpZOmZ1bmN0aW9uKGEsYixjKXtILnVQKGMpCkgu
-b2QoYixhLGEubGVuZ3RoKQphW2JdPWN9LAokaWJROjEsCiRpY1g6MSwKJGl6TToxfQpILnhqLnByb3Rv
-dHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILnVQKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVti
-XX19CkguZEUucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe0gudVAoYikKSC5vZChiLGEsYS5sZW5n
-dGgpCnJldHVybiBhW2JdfX0KSC5aQS5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7SC51UChiKQpI
-Lm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpILmRULnByb3RvdHlwZT17CnE6ZnVuY3Rpb24o
-YSxiKXtILnVQKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguUHEucHJvdG90eXBl
-PXsKcTpmdW5jdGlvbihhLGIpe0gudVAoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfX0K
-SC5lRS5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LApxOmZ1bmN0aW9u
-KGEsYil7SC51UChiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpILlY2LnByb3RvdHlw
-ZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILnVQKGIp
-Ckgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX0sCiRpVjY6MSwKJGluNjoxfQpILlJHLnByb3Rv
-dHlwZT17fQpILlZQLnByb3RvdHlwZT17fQpILldCLnByb3RvdHlwZT17fQpILlpHLnByb3RvdHlwZT17
-fQpILkpjLnByb3RvdHlwZT17CkM6ZnVuY3Rpb24oYSl7cmV0dXJuIEguY0Uodi50eXBlVW5pdmVyc2Us
-dGhpcyxhKX0sCktxOmZ1bmN0aW9uKGEpe3JldHVybiBILnY1KHYudHlwZVVuaXZlcnNlLHRoaXMsYSl9
-fQpILkcucHJvdG90eXBlPXt9CkgubFkucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4gSC5k
-bSh0aGlzLmEsbnVsbCl9fQpILmtTLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
-YX19CkguaU0ucHJvdG90eXBlPXt9ClAudGgucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHM9
-dGhpcy5hLHI9cy5hCnMuYT1udWxsCnIuJDAoKX0sCiRTOjl9ClAuaGEucHJvdG90eXBlPXsKJDE6ZnVu
-Y3Rpb24oYSl7dmFyIHMscgp0aGlzLmEuYT10Lk0uYShhKQpzPXRoaXMuYgpyPXRoaXMuYwpzLmZpcnN0
-Q2hpbGQ/cy5yZW1vdmVDaGlsZChyKTpzLmFwcGVuZENoaWxkKHIpfSwKJFM6MzR9ClAuVnMucHJvdG90
-eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuJDAoKX0sCiRDOiIkMCIsCiRSOjAsCiRTOjF9ClAuRnQu
-cHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuJDAoKX0sCiRDOiIkMCIsCiRSOjAsCiRTOjF9
-ClAuVzMucHJvdG90eXBlPXsKQ1k6ZnVuY3Rpb24oYSxiKXtpZihzZWxmLnNldFRpbWVvdXQhPW51bGwp
-c2VsZi5zZXRUaW1lb3V0KEgudFIobmV3IFAueUgodGhpcyxiKSwwKSxhKQplbHNlIHRocm93IEguYihQ
-Lkw0KCJgc2V0VGltZW91dCgpYCBub3QgZm91bmQuIikpfX0KUC55SC5wcm90b3R5cGU9ewokMDpmdW5j
-dGlvbigpe3RoaXMuYi4kMCgpfSwKJEM6IiQwIiwKJFI6MCwKJFM6MH0KUC5paC5wcm90b3R5cGU9ewph
-TTpmdW5jdGlvbihhLGIpe3ZhciBzLHI9dGhpcyxxPXIuJHRpCnEuQygiMS8/IikuYShiKQppZighci5i
-KXIuYS5YZihiKQplbHNle3M9ci5hCmlmKHEuQygiYjg8MT4iKS5iKGIpKXMuY1UoYikKZWxzZSBzLlgy
-KHEuYy5hKGIpKX19LAp3MDpmdW5jdGlvbihhLGIpe3ZhciBzCmlmKGI9PW51bGwpYj1QLnYwKGEpCnM9
-dGhpcy5hCmlmKHRoaXMuYilzLlpMKGEsYikKZWxzZSBzLk5rKGEsYil9fQpQLldNLnByb3RvdHlwZT17
-CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuJDIoMCxhKX0sCiRTOjUyfQpQLlNYLnByb3RvdHlw
-ZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhpcy5hLiQyKDEsbmV3IEguYnEoYSx0LmwuYShiKSkpfSwKJEM6
-IiQyIiwKJFI6MiwKJFM6MjR9ClAuR3MucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0aGlzLmEo
-SC51UChhKSxiKX0sCiRTOjI2fQpQLkZ5LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIkl0
-ZXJhdGlvbk1hcmtlcigiK3RoaXMuYisiLCAiK0guRWoodGhpcy5hKSsiKSJ9fQpQLkdWLnByb3RvdHlw
-ZT17CmdsOmZ1bmN0aW9uKCl7dmFyIHM9dGhpcy5jCmlmKHM9PW51bGwpcmV0dXJuIHRoaXMuJHRpLmMu
-YSh0aGlzLmIpCnJldHVybiBzLmdsKCl9LApGOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbyxuLG09dGhp
-cwpmb3Iocz1tLiR0aS5DKCJBbjwxPiIpOyEwOyl7cj1tLmMKaWYociE9bnVsbClpZihyLkYoKSlyZXR1
-cm4hMAplbHNlIG0uc1g5KG51bGwpCnE9ZnVuY3Rpb24oYSxiLGMpe3ZhciBsLGs9Ygp3aGlsZSh0cnVl
-KXRyeXtyZXR1cm4gYShrLGwpfWNhdGNoKGope2w9agprPWN9fShtLmEsMCwxKQppZihxIGluc3RhbmNl
-b2YgUC5GeSl7cD1xLmIKaWYocD09PTIpe289bS5kCmlmKG89PW51bGx8fG8ubGVuZ3RoPT09MCl7bS5z
-RUMobnVsbCkKcmV0dXJuITF9aWYoMD49by5sZW5ndGgpcmV0dXJuIEguT0gobywtMSkKbS5hPW8ucG9w
-KCkKY29udGludWV9ZWxzZXtyPXEuYQppZihwPT09Myl0aHJvdyByCmVsc2V7bj1zLmEoSi5JVChyKSkK
-aWYobiBpbnN0YW5jZW9mIFAuR1Ype3I9bS5kCmlmKHI9PW51bGwpcj1tLmQ9W10KQy5ObS5pKHIsbS5h
-KQptLmE9bi5hCmNvbnRpbnVlfWVsc2V7bS5zWDkobikKY29udGludWV9fX19ZWxzZXttLnNFQyhxKQpy
-ZXR1cm4hMH19cmV0dXJuITF9LApzRUM6ZnVuY3Rpb24oYSl7dGhpcy5iPXRoaXMuJHRpLkMoIjE/Iiku
-YShhKX0sCnNYOTpmdW5jdGlvbihhKXt0aGlzLmM9dGhpcy4kdGkuQygiQW48MT4/IikuYShhKX0sCiRp
-QW46MX0KUC5xNC5wcm90b3R5cGU9ewpnbTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuR1YodGhpcy5h
-KCksdGhpcy4kdGkuQygiR1Y8MT4iKSl9fQpQLlBmLnByb3RvdHlwZT17CncwOmZ1bmN0aW9uKGEsYil7
-dmFyIHMKSC5jYihhLCJlcnJvciIsdC5LKQpzPXRoaXMuYQppZihzLmEhPT0wKXRocm93IEguYihQLlBW
-KCJGdXR1cmUgYWxyZWFkeSBjb21wbGV0ZWQiKSkKaWYoYj09bnVsbCliPVAudjAoYSkKcy5OayhhLGIp
-fSwKcG06ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMudzAoYSxudWxsKX19ClAuWmYucHJvdG90eXBlPXsK
-YU06ZnVuY3Rpb24oYSxiKXt2YXIgcyxyPXRoaXMuJHRpCnIuQygiMS8/IikuYShiKQpzPXRoaXMuYQpp
-ZihzLmEhPT0wKXRocm93IEguYihQLlBWKCJGdXR1cmUgYWxyZWFkeSBjb21wbGV0ZWQiKSkKcy5YZihy
-LkMoIjEvIikuYShiKSl9fQpQLkZlLnByb3RvdHlwZT17CkhSOmZ1bmN0aW9uKGEpe2lmKCh0aGlzLmMm
-MTUpIT09NilyZXR1cm4hMApyZXR1cm4gdGhpcy5iLmIuYnYodC5hbC5hKHRoaXMuZCksYS5hLHQueSx0
-LkspfSwKS3c6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5lLHI9dC56LHE9dC5LLHA9dGhpcy4kdGkuQygi
-Mi8iKSxvPXRoaXMuYi5iCmlmKHQuYWcuYihzKSlyZXR1cm4gcC5hKG8ucnAocyxhLmEsYS5iLHIscSx0
-LmwpKQplbHNlIHJldHVybiBwLmEoby5idih0LmJJLmEocyksYS5hLHIscSkpfX0KUC52cy5wcm90b3R5
-cGU9ewpTcTpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHA9dGhpcy4kdGkKcC5LcShjKS5DKCIxLygy
-KSIpLmEoYSkKcz0kLlgzCmlmKHMhPT1DLk5VKXtjLkMoIkA8MC8+IikuS3EocC5jKS5DKCIxKDIpIiku
-YShhKQppZihiIT1udWxsKWI9UC5WSChiLHMpfXI9bmV3IFAudnMocyxjLkMoInZzPDA+IikpCnE9Yj09
-bnVsbD8xOjMKdGhpcy54ZihuZXcgUC5GZShyLHEsYSxiLHAuQygiQDwxPiIpLktxKGMpLkMoIkZlPDEs
-Mj4iKSkpCnJldHVybiByfSwKVzc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5TcShhLG51bGwsYil9
-LApRZDpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj10aGlzLiR0aQpyLktxKGMpLkMoIjEvKDIpIikuYShh
-KQpzPW5ldyBQLnZzKCQuWDMsYy5DKCJ2czwwPiIpKQp0aGlzLnhmKG5ldyBQLkZlKHMsMTksYSxiLHIu
-QygiQDwxPiIpLktxKGMpLkMoIkZlPDEsMj4iKSkpCnJldHVybiBzfSwKeGY6ZnVuY3Rpb24oYSl7dmFy
-IHMscj10aGlzLHE9ci5hCmlmKHE8PTEpe2EuYT10LkYuYShyLmMpCnIuYz1hfWVsc2V7aWYocT09PTIp
-e3M9dC5jLmEoci5jKQpxPXMuYQppZihxPDQpe3MueGYoYSkKcmV0dXJufXIuYT1xCnIuYz1zLmN9UC5U
-ayhudWxsLG51bGwsci5iLHQuTS5hKG5ldyBQLmRhKHIsYSkpKX19LApqUTpmdW5jdGlvbihhKXt2YXIg
-cyxyLHEscCxvLG4sbT10aGlzLGw9e30KbC5hPWEKaWYoYT09bnVsbClyZXR1cm4Kcz1tLmEKaWYoczw9
-MSl7cj10LkYuYShtLmMpCm0uYz1hCmlmKHIhPW51bGwpe3E9YS5hCmZvcihwPWE7cSE9bnVsbDtwPXEs
-cT1vKW89cS5hCnAuYT1yfX1lbHNle2lmKHM9PT0yKXtuPXQuYy5hKG0uYykKcz1uLmEKaWYoczw0KXtu
-LmpRKGEpCnJldHVybn1tLmE9cwptLmM9bi5jfWwuYT1tLk44KGEpClAuVGsobnVsbCxudWxsLG0uYix0
-Lk0uYShuZXcgUC5vUShsLG0pKSl9fSwKYWg6ZnVuY3Rpb24oKXt2YXIgcz10LkYuYSh0aGlzLmMpCnRo
-aXMuYz1udWxsCnJldHVybiB0aGlzLk44KHMpfSwKTjg6ZnVuY3Rpb24oYSl7dmFyIHMscixxCmZvcihz
-PWEscj1udWxsO3MhPW51bGw7cj1zLHM9cSl7cT1zLmEKcy5hPXJ9cmV0dXJuIHJ9LApISDpmdW5jdGlv
-bihhKXt2YXIgcyxyPXRoaXMscT1yLiR0aQpxLkMoIjEvIikuYShhKQppZihxLkMoImI4PDE+IikuYihh
-KSlpZihxLmIoYSkpUC5BOShhLHIpCmVsc2UgUC5rMyhhLHIpCmVsc2V7cz1yLmFoKCkKcS5jLmEoYSkK
-ci5hPTQKci5jPWEKUC5IWihyLHMpfX0sClgyOmZ1bmN0aW9uKGEpe3ZhciBzLHI9dGhpcwpyLiR0aS5j
-LmEoYSkKcz1yLmFoKCkKci5hPTQKci5jPWEKUC5IWihyLHMpfSwKWkw6ZnVuY3Rpb24oYSxiKXt2YXIg
-cyxyLHE9dGhpcwp0LmwuYShiKQpzPXEuYWgoKQpyPVAuVGwoYSxiKQpxLmE9OApxLmM9cgpQLkhaKHEs
-cyl9LApYZjpmdW5jdGlvbihhKXt2YXIgcz10aGlzLiR0aQpzLkMoIjEvIikuYShhKQppZihzLkMoImI4
-PDE+IikuYihhKSl7dGhpcy5jVShhKQpyZXR1cm59dGhpcy53VShzLmMuYShhKSl9LAp3VTpmdW5jdGlv
-bihhKXt2YXIgcz10aGlzCnMuJHRpLmMuYShhKQpzLmE9MQpQLlRrKG51bGwsbnVsbCxzLmIsdC5NLmEo
-bmV3IFAucnQocyxhKSkpfSwKY1U6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcyxyPXMuJHRpCnIuQygiYjg8
-MT4iKS5hKGEpCmlmKHIuYihhKSl7aWYoYS5hPT09OCl7cy5hPTEKUC5UayhudWxsLG51bGwscy5iLHQu
-TS5hKG5ldyBQLktGKHMsYSkpKX1lbHNlIFAuQTkoYSxzKQpyZXR1cm59UC5rMyhhLHMpfSwKTms6ZnVu
-Y3Rpb24oYSxiKXt0aGlzLmE9MQpQLlRrKG51bGwsbnVsbCx0aGlzLmIsdC5NLmEobmV3IFAuWkwodGhp
-cyxhLGIpKSl9LAokaWI4OjF9ClAuZGEucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtQLkhaKHRoaXMu
-YSx0aGlzLmIpfSwKJFM6MH0KUC5vUS5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe1AuSFoodGhpcy5i
-LHRoaXMuYS5hKX0sCiRTOjB9ClAucFYucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHM9dGhp
-cy5hCnMuYT0wCnMuSEgoYSl9LAokUzo5fQpQLlU3LnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7
-dGhpcy5hLlpMKGEsdC5sLmEoYikpfSwKJEM6IiQyIiwKJFI6MiwKJFM6Mjl9ClAudnIucHJvdG90eXBl
-PXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuWkwodGhpcy5iLHRoaXMuYyl9LAokUzowfQpQLnJ0LnByb3Rv
-dHlwZT17CiQwOmZ1bmN0aW9uKCl7dGhpcy5hLlgyKHRoaXMuYil9LAokUzowfQpQLktGLnByb3RvdHlw
-ZT17CiQwOmZ1bmN0aW9uKCl7UC5BOSh0aGlzLmIsdGhpcy5hKX0sCiRTOjB9ClAuWkwucHJvdG90eXBl
-PXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuWkwodGhpcy5iLHRoaXMuYyl9LAokUzowfQpQLlJULnByb3Rv
-dHlwZT17CiQwOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbyxuLG09dGhpcyxsPW51bGwKdHJ5e3E9bS5h
-LmEKbD1xLmIuYi56eih0LmZPLmEocS5kKSx0LnopfWNhdGNoKHApe3M9SC5SdShwKQpyPUgudHMocCkK
-aWYobS5jKXtxPXQubi5hKG0uYi5hLmMpLmEKbz1zCm89cT09bnVsbD9vPT1udWxsOnE9PT1vCnE9b31l
-bHNlIHE9ITEKbz1tLmEKaWYocSlvLmM9dC5uLmEobS5iLmEuYykKZWxzZSBvLmM9UC5UbChzLHIpCm8u
-Yj0hMApyZXR1cm59aWYobCBpbnN0YW5jZW9mIFAudnMmJmwuYT49NCl7aWYobC5hPT09OCl7cT1tLmEK
-cS5jPXQubi5hKGwuYykKcS5iPSEwfXJldHVybn1pZih0LmQuYihsKSl7bj1tLmIuYQpxPW0uYQpxLmM9
-bC5XNyhuZXcgUC5qWihuKSx0LnopCnEuYj0hMX19LAokUzowfQpQLmpaLnByb3RvdHlwZT17CiQxOmZ1
-bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9LAokUzozMn0KUC5ycS5wcm90b3R5cGU9ewokMDpmdW5jdGlv
-bigpe3ZhciBzLHIscSxwLG8sbixtLGwKdHJ5e3E9dGhpcy5hCnA9cS5hCm89cC4kdGkKbj1vLmMKbT1u
-LmEodGhpcy5iKQpxLmM9cC5iLmIuYnYoby5DKCIyLygxKSIpLmEocC5kKSxtLG8uQygiMi8iKSxuKX1j
-YXRjaChsKXtzPUguUnUobCkKcj1ILnRzKGwpCnE9dGhpcy5hCnEuYz1QLlRsKHMscikKcS5iPSEwfX0s
-CiRTOjB9ClAuUlcucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvLG4sbSxsLGs9
-dGhpcwp0cnl7cz10Lm4uYShrLmEuYS5jKQpwPWsuYgppZihILm9UKHAuYS5IUihzKSkmJnAuYS5lIT1u
-dWxsKXtwLmM9cC5hLkt3KHMpCnAuYj0hMX19Y2F0Y2gobyl7cj1ILlJ1KG8pCnE9SC50cyhvKQpwPXQu
-bi5hKGsuYS5hLmMpCm49cC5hCm09cgpsPWsuYgppZihuPT1udWxsP209PW51bGw6bj09PW0pbC5jPXAK
-ZWxzZSBsLmM9UC5UbChyLHEpCmwuYj0hMH19LAokUzowfQpQLk9NLnByb3RvdHlwZT17fQpQLnFoLnBy
-b3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3ZhciBzLHIscT10aGlzLHA9e30sbz1uZXcgUC52cygkLlgz
-LHQuZkopCnAuYT0wCnM9SC5MaChxKQpyPXMuQygifigxKT8iKS5hKG5ldyBQLkI1KHAscSkpCnQuWi5h
-KG5ldyBQLnVPKHAsbykpClcuSkUocS5hLHEuYixyLCExLHMuYykKcmV0dXJuIG99fQpQLkI1LnByb3Rv
-dHlwZT17CiQxOmZ1bmN0aW9uKGEpe0guTGgodGhpcy5iKS5jLmEoYSk7Kyt0aGlzLmEuYX0sCiRTOmZ1
-bmN0aW9uKCl7cmV0dXJuIEguTGgodGhpcy5iKS5DKCJ+KDEpIil9fQpQLnVPLnByb3RvdHlwZT17CiQw
-OmZ1bmN0aW9uKCl7dGhpcy5iLkhIKHRoaXMuYS5hKX0sCiRTOjB9ClAuTU8ucHJvdG90eXBlPXt9ClAu
-a1QucHJvdG90eXBlPXt9ClAueEkucHJvdG90eXBlPXt9ClAuQ3cucHJvdG90eXBlPXsKdzpmdW5jdGlv
-bihhKXtyZXR1cm4gSC5Faih0aGlzLmEpfSwKJGlYUzoxLApnSUk6ZnVuY3Rpb24oKXtyZXR1cm4gdGhp
-cy5ifX0KUC5tMC5wcm90b3R5cGU9eyRpUW06MX0KUC5wSy5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigp
-e3ZhciBzPUguYih0aGlzLmEpCnMuc3RhY2s9Si5qKHRoaXMuYikKdGhyb3cgc30sCiRTOjB9ClAuSmku
-cHJvdG90eXBlPXsKYkg6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHA9bnVsbAp0Lk0uYShhKQp0cnl7aWYo
-Qy5OVT09PSQuWDMpe2EuJDAoKQpyZXR1cm59UC5UOChwLHAsdGhpcyxhLHQuSCl9Y2F0Y2gocSl7cz1I
-LlJ1KHEpCnI9SC50cyhxKQpQLkwyKHAscCx0aGlzLHMsdC5sLmEocikpfX0sCkRsOmZ1bmN0aW9uKGEs
-YixjKXt2YXIgcyxyLHEscD1udWxsCmMuQygifigwKSIpLmEoYSkKYy5hKGIpCnRyeXtpZihDLk5VPT09
-JC5YMyl7YS4kMShiKQpyZXR1cm59UC55dihwLHAsdGhpcyxhLGIsdC5ILGMpfWNhdGNoKHEpe3M9SC5S
-dShxKQpyPUgudHMocSkKUC5MMihwLHAsdGhpcyxzLHQubC5hKHIpKX19LApSVDpmdW5jdGlvbihhLGIp
-e3JldHVybiBuZXcgUC5oaih0aGlzLGIuQygiMCgpIikuYShhKSxiKX0sCkdZOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBuZXcgUC5WcCh0aGlzLHQuTS5hKGEpKX0sClB5OmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBQ
-Lk9SKHRoaXMsYi5DKCJ+KDApIikuYShhKSxiKX0sCnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbnVsbH0s
-Cnp6OmZ1bmN0aW9uKGEsYil7Yi5DKCIwKCkiKS5hKGEpCmlmKCQuWDM9PT1DLk5VKXJldHVybiBhLiQw
-KCkKcmV0dXJuIFAuVDgobnVsbCxudWxsLHRoaXMsYSxiKX0sCmJ2OmZ1bmN0aW9uKGEsYixjLGQpe2Mu
-QygiQDwwPiIpLktxKGQpLkMoIjEoMikiKS5hKGEpCmQuYShiKQppZigkLlgzPT09Qy5OVSlyZXR1cm4g
-YS4kMShiKQpyZXR1cm4gUC55dihudWxsLG51bGwsdGhpcyxhLGIsYyxkKX0sCnJwOmZ1bmN0aW9uKGEs
-YixjLGQsZSxmKXtkLkMoIkA8MD4iKS5LcShlKS5LcShmKS5DKCIxKDIsMykiKS5hKGEpCmUuYShiKQpm
-LmEoYykKaWYoJC5YMz09PUMuTlUpcmV0dXJuIGEuJDIoYixjKQpyZXR1cm4gUC5ReChudWxsLG51bGws
-dGhpcyxhLGIsYyxkLGUsZil9LApMajpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gYi5DKCJAPDA+Iiku
-S3EoYykuS3EoZCkuQygiMSgyLDMpIikuYShhKX19ClAuaGoucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24o
-KXtyZXR1cm4gdGhpcy5hLnp6KHRoaXMuYix0aGlzLmMpfSwKJFM6ZnVuY3Rpb24oKXtyZXR1cm4gdGhp
-cy5jLkMoIjAoKSIpfX0KUC5WcC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmEu
-YkgodGhpcy5iKX0sCiRTOjB9ClAuT1IucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHM9dGhp
-cy5jCnJldHVybiB0aGlzLmEuRGwodGhpcy5iLHMuYShhKSxzKX0sCiRTOmZ1bmN0aW9uKCl7cmV0dXJu
-IHRoaXMuYy5DKCJ+KDApIil9fQpQLmI2LnByb3RvdHlwZT17CmdtOmZ1bmN0aW9uKGEpe3ZhciBzPXRo
-aXMscj1uZXcgUC5sbShzLHMucixILkxoKHMpLkMoImxtPDE+IikpCnIuYz1zLmUKcmV0dXJuIHJ9LApn
-QTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmE9
-PT0wfSwKZ29yOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEhPT0wfSwKdGc6ZnVuY3Rpb24oYSxiKXt2
-YXIgcyxyCmlmKHR5cGVvZiBiPT0ic3RyaW5nIiYmYiE9PSJfX3Byb3RvX18iKXtzPXRoaXMuYgppZihz
-PT1udWxsKXJldHVybiExCnJldHVybiB0LmUuYShzW2JdKSE9bnVsbH1lbHNle3I9dGhpcy5QUihiKQpy
-ZXR1cm4gcn19LApQUjpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmQKaWYocz09bnVsbClyZXR1cm4hMQpy
-ZXR1cm4gdGhpcy5ERihzW3RoaXMuTihhKV0sYSk+PTB9LAppOmZ1bmN0aW9uKGEsYil7dmFyIHMscixx
-PXRoaXMKSC5MaChxKS5jLmEoYikKaWYodHlwZW9mIGI9PSJzdHJpbmciJiZiIT09Il9fcHJvdG9fXyIp
-e3M9cS5iCnJldHVybiBxLmJRKHM9PW51bGw/cS5iPVAuVDIoKTpzLGIpfWVsc2UgaWYodHlwZW9mIGI9
-PSJudW1iZXIiJiYoYiYxMDczNzQxODIzKT09PWIpe3I9cS5jCnJldHVybiBxLmJRKHI9PW51bGw/cS5j
-PVAuVDIoKTpyLGIpfWVsc2UgcmV0dXJuIHEuQjcoYil9LApCNzpmdW5jdGlvbihhKXt2YXIgcyxyLHEs
-cD10aGlzCkguTGgocCkuYy5hKGEpCnM9cC5kCmlmKHM9PW51bGwpcz1wLmQ9UC5UMigpCnI9cC5OKGEp
-CnE9c1tyXQppZihxPT1udWxsKXNbcl09W3AueW8oYSldCmVsc2V7aWYocC5ERihxLGEpPj0wKXJldHVy
-biExCnEucHVzaChwLnlvKGEpKX1yZXR1cm4hMH0sClI6ZnVuY3Rpb24oYSxiKXt2YXIgcz10aGlzCmlm
-KHR5cGVvZiBiPT0ic3RyaW5nIiYmYiE9PSJfX3Byb3RvX18iKXJldHVybiBzLkwocy5iLGIpCmVsc2Ug
-aWYodHlwZW9mIGI9PSJudW1iZXIiJiYoYiYxMDczNzQxODIzKT09PWIpcmV0dXJuIHMuTChzLmMsYikK
-ZWxzZSByZXR1cm4gcy5xZyhiKX0sCnFnOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG89dGhpcyxuPW8u
-ZAppZihuPT1udWxsKXJldHVybiExCnM9by5OKGEpCnI9bltzXQpxPW8uREYocixhKQppZihxPDApcmV0
-dXJuITEKcD1yLnNwbGljZShxLDEpWzBdCmlmKDA9PT1yLmxlbmd0aClkZWxldGUgbltzXQpvLkdTKHAp
-CnJldHVybiEwfSwKYlE6ZnVuY3Rpb24oYSxiKXtILkxoKHRoaXMpLmMuYShiKQppZih0LmUuYShhW2Jd
-KSE9bnVsbClyZXR1cm4hMQphW2JdPXRoaXMueW8oYikKcmV0dXJuITB9LApMOmZ1bmN0aW9uKGEsYil7
-dmFyIHMKaWYoYT09bnVsbClyZXR1cm4hMQpzPXQuZS5hKGFbYl0pCmlmKHM9PW51bGwpcmV0dXJuITEK
-dGhpcy5HUyhzKQpkZWxldGUgYVtiXQpyZXR1cm4hMH0sClM6ZnVuY3Rpb24oKXt0aGlzLnI9dGhpcy5y
-KzEmMTA3Mzc0MTgyM30sCnlvOmZ1bmN0aW9uKGEpe3ZhciBzLHI9dGhpcyxxPW5ldyBQLmJuKEguTGgo
-cikuYy5hKGEpKQppZihyLmU9PW51bGwpci5lPXIuZj1xCmVsc2V7cz1yLmYKcy50b1N0cmluZwpxLmM9
-cwpyLmY9cy5iPXF9KytyLmEKci5TKCkKcmV0dXJuIHF9LApHUzpmdW5jdGlvbihhKXt2YXIgcz10aGlz
-LHI9YS5jLHE9YS5iCmlmKHI9PW51bGwpcy5lPXEKZWxzZSByLmI9cQppZihxPT1udWxsKXMuZj1yCmVs
-c2UgcS5jPXI7LS1zLmEKcy5TKCl9LApOOmZ1bmN0aW9uKGEpe3JldHVybiBKLmhmKGEpJjEwNzM3NDE4
-MjN9LApERjpmdW5jdGlvbihhLGIpe3ZhciBzLHIKaWYoYT09bnVsbClyZXR1cm4tMQpzPWEubGVuZ3Ro
-CmZvcihyPTA7cjxzOysrcilpZihKLlJNKGFbcl0uYSxiKSlyZXR1cm4gcgpyZXR1cm4tMX19ClAuYm4u
-cHJvdG90eXBlPXt9ClAubG0ucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwK
-RjpmdW5jdGlvbigpe3ZhciBzPXRoaXMscj1zLmMscT1zLmEKaWYocy5iIT09cS5yKXRocm93IEguYihQ
-LmE0KHEpKQplbHNlIGlmKHI9PW51bGwpe3Muc2oobnVsbCkKcmV0dXJuITF9ZWxzZXtzLnNqKHMuJHRp
-LkMoIjE/IikuYShyLmEpKQpzLmM9ci5iCnJldHVybiEwfX0sCnNqOmZ1bmN0aW9uKGEpe3RoaXMuZD10
-aGlzLiR0aS5DKCIxPyIpLmEoYSl9LAokaUFuOjF9ClAubVcucHJvdG90eXBlPXt9ClAudXkucHJvdG90
-eXBlPXskaWJROjEsJGljWDoxLCRpek06MX0KUC5sRC5wcm90b3R5cGU9ewpnbTpmdW5jdGlvbihhKXty
-ZXR1cm4gbmV3IEguYTcoYSx0aGlzLmdBKGEpLEgueihhKS5DKCJhNzxsRC5FPiIpKX0sCkU6ZnVuY3Rp
-b24oYSxiKXtyZXR1cm4gdGhpcy5xKGEsYil9LApLOmZ1bmN0aW9uKGEsYil7dmFyIHMscgpILnooYSku
-QygifihsRC5FKSIpLmEoYikKcz10aGlzLmdBKGEpCmZvcihyPTA7cjxzOysrcil7Yi4kMSh0aGlzLnEo
-YSxyKSkKaWYocyE9PXRoaXMuZ0EoYSkpdGhyb3cgSC5iKFAuYTQoYSkpfX0sCmdsMDpmdW5jdGlvbihh
-KXtyZXR1cm4gdGhpcy5nQShhKT09PTB9LApnb3I6ZnVuY3Rpb24oYSl7cmV0dXJuIXRoaXMuZ2wwKGEp
-fSwKRTI6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPUgueihhKQpyZXR1cm4gbmV3IEgubEooYSxzLktxKGMp
-LkMoIjEobEQuRSkiKS5hKGIpLHMuQygiQDxsRC5FPiIpLktxKGMpLkMoImxKPDEsMj4iKSl9LAplUjpm
-dW5jdGlvbihhLGIpe3JldHVybiBILnFDKGEsYixudWxsLEgueihhKS5DKCJsRC5FIikpfSwKZHI6ZnVu
-Y3Rpb24oYSxiKXtyZXR1cm4gbmV3IEgualYoYSxILnooYSkuQygiQDxsRC5FPiIpLktxKGIpLkMoImpW
-PDEsMj4iKSl9LApkdTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcwpILnooYSkuQygibEQuRT8iKS5hKGQp
-ClAuakIoYixjLHRoaXMuZ0EoYSkpCmZvcihzPWI7czxjOysrcyl0aGlzLlkoYSxzLGQpfSwKdzpmdW5j
-dGlvbihhKXtyZXR1cm4gUC5XRShhLCJbIiwiXSIpfX0KUC5pbC5wcm90b3R5cGU9e30KUC5yYS5wcm90
-b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciBzLHI9dGhpcy5hCmlmKCFyLmEpdGhpcy5iLmErPSIs
-ICIKci5hPSExCnI9dGhpcy5iCnM9ci5hKz1ILkVqKGEpCnIuYT1zKyI6ICIKci5hKz1ILkVqKGIpfSwK
-JFM6MTB9ClAuWWsucHJvdG90eXBlPXsKSzpmdW5jdGlvbihhLGIpe3ZhciBzLHIKSC5MaCh0aGlzKS5D
-KCJ+KFlrLkssWWsuVikiKS5hKGIpCmZvcihzPUouSVQodGhpcy5nVigpKTtzLkYoKTspe3I9cy5nbCgp
-CmIuJDIocix0aGlzLnEoMCxyKSl9fSwKZ1B1OmZ1bmN0aW9uKGEpe3JldHVybiBKLk0xKHRoaXMuZ1Yo
-KSxuZXcgUC55USh0aGlzKSxILkxoKHRoaXMpLkMoIk4zPFlrLkssWWsuVj4iKSl9LAp4NDpmdW5jdGlv
-bihhKXtyZXR1cm4gSi56bCh0aGlzLmdWKCksYSl9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gSi5IbSh0
-aGlzLmdWKCkpfSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiBKLnVVKHRoaXMuZ1YoKSl9LAp3OmZ1bmN0
-aW9uKGEpe3JldHVybiBQLm5PKHRoaXMpfSwKJGlaMDoxfQpQLnlRLnByb3RvdHlwZT17CiQxOmZ1bmN0
-aW9uKGEpe3ZhciBzPXRoaXMuYSxyPUguTGgocykKci5DKCJZay5LIikuYShhKQpyZXR1cm4gbmV3IFAu
-TjMoYSxzLnEoMCxhKSxyLkMoIkA8WWsuSz4iKS5LcShyLkMoIllrLlYiKSkuQygiTjM8MSwyPiIpKX0s
-CiRTOmZ1bmN0aW9uKCl7cmV0dXJuIEguTGgodGhpcy5hKS5DKCJOMzxZay5LLFlrLlY+KFlrLkspIil9
-fQpQLktQLnByb3RvdHlwZT17Clk6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPUguTGgodGhpcykKcy5jLmEo
-YikKcy5RWzFdLmEoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBtb2RpZnkgdW5tb2RpZmlhYmxlIG1h
-cCIpKX19ClAuUG4ucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEucSgwLGIp
-fSwKWTpmdW5jdGlvbihhLGIsYyl7dmFyIHM9SC5MaCh0aGlzKQp0aGlzLmEuWSgwLHMuYy5hKGIpLHMu
-UVsxXS5hKGMpKX0sCng0OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEueDQoYSl9LApLOmZ1bmN0aW9u
-KGEsYil7dGhpcy5hLksoMCxILkxoKHRoaXMpLkMoIn4oMSwyKSIpLmEoYikpfSwKZ2wwOmZ1bmN0aW9u
-KGEpe3ZhciBzPXRoaXMuYQpyZXR1cm4gcy5nbDAocyl9LApnQTpmdW5jdGlvbihhKXt2YXIgcz10aGlz
-LmEKcmV0dXJuIHMuZ0Eocyl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBKLmoodGhpcy5hKX0sCmdQdTpm
-dW5jdGlvbihhKXt2YXIgcz10aGlzLmEKcmV0dXJuIHMuZ1B1KHMpfSwKJGlaMDoxfQpQLkdqLnByb3Rv
-dHlwZT17fQpQLmxmLnByb3RvdHlwZT17CmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nQSh0aGlz
-KT09PTB9LApnb3I6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ0EodGhpcykhPT0wfSwKRlY6ZnVuY3Rp
-b24oYSxiKXt2YXIgcwpmb3Iocz1KLklUKEguTGgodGhpcykuQygiY1g8bGYuRT4iKS5hKGIpKTtzLkYo
-KTspdGhpcy5pKDAscy5nbCgpKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFAuV0UodGhpcywieyIsIn0i
-KX0sCkg6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyPXRoaXMuZ20odGhpcykKaWYoIXIuRigpKXJldHVybiIi
-CmlmKGI9PT0iIil7cz0iIgpkbyBzKz1ILkVqKHIuZCkKd2hpbGUoci5GKCkpfWVsc2V7cz1ILkVqKHIu
-ZCkKZm9yKDtyLkYoKTspcz1zK2IrSC5FaihyLmQpfXJldHVybiBzLmNoYXJDb2RlQXQoMCk9PTA/czpz
-fSwKZVI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSC5iSyh0aGlzLGIsSC5MaCh0aGlzKS5DKCJsZi5FIikp
-fSwKRTpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwPSJpbmRleCIKSC5jYihiLHAsdC5TKQpQLmsxKGIs
-cCkKZm9yKHM9dGhpcy5nbSh0aGlzKSxyPTA7cy5GKCk7KXtxPXMuZAppZihiPT09cilyZXR1cm4gcTsr
-K3J9dGhyb3cgSC5iKFAuQ2YoYix0aGlzLHAsbnVsbCxyKSl9fQpQLlZqLnByb3RvdHlwZT17JGliUTox
-LCRpY1g6MSwkaXh1OjF9ClAuWHYucHJvdG90eXBlPXskaWJROjEsJGljWDoxLCRpeHU6MX0KUC5uWS5w
-cm90b3R5cGU9e30KUC5XWS5wcm90b3R5cGU9e30KUC5SVS5wcm90b3R5cGU9e30KUC5wUi5wcm90b3R5
-cGU9e30KUC51dy5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7dmFyIHMscj10aGlzLmIKaWYocj09
-bnVsbClyZXR1cm4gdGhpcy5jLnEoMCxiKQplbHNlIGlmKHR5cGVvZiBiIT0ic3RyaW5nIilyZXR1cm4g
-bnVsbAplbHNle3M9cltiXQpyZXR1cm4gdHlwZW9mIHM9PSJ1bmRlZmluZWQiP3RoaXMuZmIoYik6c319
-LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5iPT1udWxsP3RoaXMuYy5hOnRoaXMuQ2YoKS5sZW5n
-dGh9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ0EodGhpcyk9PT0wfSwKZ1Y6ZnVuY3Rpb24o
-KXtpZih0aGlzLmI9PW51bGwpe3ZhciBzPXRoaXMuYwpyZXR1cm4gbmV3IEguaTUocyxILkxoKHMpLkMo
-Imk1PDE+IikpfXJldHVybiBuZXcgUC5pOCh0aGlzKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIs
-cT10aGlzCmlmKHEuYj09bnVsbClxLmMuWSgwLGIsYykKZWxzZSBpZihxLng0KGIpKXtzPXEuYgpzW2Jd
-PWMKcj1xLmEKaWYocj09bnVsbD9zIT1udWxsOnIhPT1zKXJbYl09bnVsbH1lbHNlIHEuWEsoKS5ZKDAs
-YixjKX0sCng0OmZ1bmN0aW9uKGEpe2lmKHRoaXMuYj09bnVsbClyZXR1cm4gdGhpcy5jLng0KGEpCnJl
-dHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5hLGEpfSwKSzpmdW5j
-dGlvbihhLGIpe3ZhciBzLHIscSxwLG89dGhpcwp0LmNBLmEoYikKaWYoby5iPT1udWxsKXJldHVybiBv
-LmMuSygwLGIpCnM9by5DZigpCmZvcihyPTA7cjxzLmxlbmd0aDsrK3Ipe3E9c1tyXQpwPW8uYltxXQpp
-Zih0eXBlb2YgcD09InVuZGVmaW5lZCIpe3A9UC5RZShvLmFbcV0pCm8uYltxXT1wfWIuJDIocSxwKQpp
-ZihzIT09by5jKXRocm93IEguYihQLmE0KG8pKX19LApDZjpmdW5jdGlvbigpe3ZhciBzPXQuYk0uYSh0
-aGlzLmMpCmlmKHM9PW51bGwpcz10aGlzLmM9SC5WTShPYmplY3Qua2V5cyh0aGlzLmEpLHQucykKcmV0
-dXJuIHN9LApYSzpmdW5jdGlvbigpe3ZhciBzLHIscSxwLG8sbj10aGlzCmlmKG4uYj09bnVsbClyZXR1
-cm4gbi5jCnM9UC5GbCh0Lk4sdC56KQpyPW4uQ2YoKQpmb3IocT0wO3A9ci5sZW5ndGgscTxwOysrcSl7
-bz1yW3FdCnMuWSgwLG8sbi5xKDAsbykpfWlmKHA9PT0wKUMuTm0uaShyLCIiKQplbHNlIEMuTm0uc0Eo
-ciwwKQpuLmE9bi5iPW51bGwKcmV0dXJuIG4uYz1zfSwKZmI6ZnVuY3Rpb24oYSl7dmFyIHMKaWYoIU9i
-amVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLmEsYSkpcmV0dXJuIG51bGwKcz1Q
-LlFlKHRoaXMuYVthXSkKcmV0dXJuIHRoaXMuYlthXT1zfX0KUC5pOC5wcm90b3R5cGU9ewpnQTpmdW5j
-dGlvbihhKXt2YXIgcz10aGlzLmEKcmV0dXJuIHMuZ0Eocyl9LApFOmZ1bmN0aW9uKGEsYil7dmFyIHM9
-dGhpcy5hCmlmKHMuYj09bnVsbClzPXMuZ1YoKS5FKDAsYikKZWxzZXtzPXMuQ2YoKQppZihiPDB8fGI+
-PXMubGVuZ3RoKXJldHVybiBILk9IKHMsYikKcz1zW2JdfXJldHVybiBzfSwKZ206ZnVuY3Rpb24oYSl7
-dmFyIHM9dGhpcy5hCmlmKHMuYj09bnVsbCl7cz1zLmdWKCkKcz1zLmdtKHMpfWVsc2V7cz1zLkNmKCkK
-cz1uZXcgSi5tMShzLHMubGVuZ3RoLEgudDYocykuQygibTE8MT4iKSl9cmV0dXJuIHN9LAp0ZzpmdW5j
-dGlvbihhLGIpe3JldHVybiB0aGlzLmEueDQoYil9fQpQLnBnLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9u
-KCl7dmFyIHMscgp0cnl7cz1uZXcgVGV4dERlY29kZXIoInV0Zi04Iix7ZmF0YWw6dHJ1ZX0pCnJldHVy
-biBzfWNhdGNoKHIpe0guUnUocil9cmV0dXJuIG51bGx9LAokUzoxMX0KUC5jMi5wcm90b3R5cGU9ewok
-MDpmdW5jdGlvbigpe3ZhciBzLHIKdHJ5e3M9bmV3IFRleHREZWNvZGVyKCJ1dGYtOCIse2ZhdGFsOmZh
-bHNlfSkKcmV0dXJuIHN9Y2F0Y2gocil7SC5SdShyKX1yZXR1cm4gbnVsbH0sCiRTOjExfQpQLkNWLnBy
-b3RvdHlwZT17CnlyOmZ1bmN0aW9uKGEwLGExLGEyKXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixpLGgs
-ZyxmLGUsZCxjLGIsYT0iSW52YWxpZCBiYXNlNjQgZW5jb2RpbmcgbGVuZ3RoICIKYTI9UC5qQihhMSxh
-MixhMC5sZW5ndGgpCnM9JC5WNygpCmZvcihyPWExLHE9cixwPW51bGwsbz0tMSxuPS0xLG09MDtyPGEy
-O3I9bCl7bD1yKzEKaz1DLnhCLlcoYTAscikKaWYoaz09PTM3KXtqPWwrMgppZihqPD1hMil7aT1ILm9v
-KEMueEIuVyhhMCxsKSkKaD1ILm9vKEMueEIuVyhhMCxsKzEpKQpnPWkqMTYraC0oaCYyNTYpCmlmKGc9
-PT0zNylnPS0xCmw9an1lbHNlIGc9LTF9ZWxzZSBnPWsKaWYoMDw9ZyYmZzw9MTI3KXtpZihnPDB8fGc+
-PXMubGVuZ3RoKXJldHVybiBILk9IKHMsZykKZj1zW2ddCmlmKGY+PTApe2c9Qy54Qi5PMigiQUJDREVG
-R0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLyIs
-ZikKaWYoZz09PWspY29udGludWUKaz1nfWVsc2V7aWYoZj09PS0xKXtpZihvPDApe2U9cD09bnVsbD9u
-dWxsOnAuYS5sZW5ndGgKaWYoZT09bnVsbCllPTAKbz1lKyhyLXEpCm49cn0rK20KaWYoaz09PTYxKWNv
-bnRpbnVlfWs9Z31pZihmIT09LTIpe2lmKHA9PW51bGwpe3A9bmV3IFAuUm4oIiIpCmU9cH1lbHNlIGU9
-cAplLmErPUMueEIuTmooYTAscSxyKQplLmErPUguTHcoaykKcT1sCmNvbnRpbnVlfX10aHJvdyBILmIo
-UC5ycigiSW52YWxpZCBiYXNlNjQgZGF0YSIsYTAscikpfWlmKHAhPW51bGwpe2U9cC5hKz1DLnhCLk5q
-KGEwLHEsYTIpCmQ9ZS5sZW5ndGgKaWYobz49MClQLnhNKGEwLG4sYTIsbyxtLGQpCmVsc2V7Yz1DLmpu
-LnpZKGQtMSw0KSsxCmlmKGM9PT0xKXRocm93IEguYihQLnJyKGEsYTAsYTIpKQpmb3IoO2M8NDspe2Ur
-PSI9IgpwLmE9ZTsrK2N9fWU9cC5hCnJldHVybiBDLnhCLmk3KGEwLGExLGEyLGUuY2hhckNvZGVBdCgw
-KT09MD9lOmUpfWI9YTItYTEKaWYobz49MClQLnhNKGEwLG4sYTIsbyxtLGIpCmVsc2V7Yz1DLmpuLnpZ
-KGIsNCkKaWYoYz09PTEpdGhyb3cgSC5iKFAucnIoYSxhMCxhMikpCmlmKGM+MSlhMD1DLnhCLmk3KGEw
-LGEyLGEyLGM9PT0yPyI9PSI6Ij0iKX1yZXR1cm4gYTB9fQpQLlU4LnByb3RvdHlwZT17fQpQLlVrLnBy
-b3RvdHlwZT17fQpQLndJLnByb3RvdHlwZT17fQpQLlppLnByb3RvdHlwZT17fQpQLlVkLnByb3RvdHlw
-ZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHM9UC5wKHRoaXMuYSkKcmV0dXJuKHRoaXMuYiE9bnVsbD8iQ29u
-dmVydGluZyBvYmplY3QgdG8gYW4gZW5jb2RhYmxlIG9iamVjdCBmYWlsZWQ6IjoiQ29udmVydGluZyBv
-YmplY3QgZGlkIG5vdCByZXR1cm4gYW4gZW5jb2RhYmxlIG9iamVjdDoiKSsiICIrc319ClAuSzgucHJv
-dG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iQ3ljbGljIGVycm9yIGluIEpTT04gc3RyaW5naWZ5
-In19ClAuYnkucHJvdG90eXBlPXsKcFc6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzCnQuZlYuYShjKQpzPVAu
-QlMoYix0aGlzLmdIZSgpLmEpCnJldHVybiBzfSwKT0I6ZnVuY3Rpb24oYSxiKXt2YXIgcwp0LmRBLmEo
-YikKcz1QLnVYKGEsdGhpcy5nWkUoKS5iLG51bGwpCnJldHVybiBzfSwKZ1pFOmZ1bmN0aW9uKCl7cmV0
-dXJuIEMublh9LApnSGU6ZnVuY3Rpb24oKXtyZXR1cm4gQy5BM319ClAub2oucHJvdG90eXBlPXt9ClAu
-TXgucHJvdG90eXBlPXt9ClAuU2gucHJvdG90eXBlPXsKdnA6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAs
-byxuLG0sbD1hLmxlbmd0aApmb3Iocz1KLnJZKGEpLHI9dGhpcy5jLHE9MCxwPTA7cDxsOysrcCl7bz1z
-LlcoYSxwKQppZihvPjkyKXtpZihvPj01NTI5Nil7bj1vJjY0NTEyCmlmKG49PT01NTI5Nil7bT1wKzEK
-bT0hKG08bCYmKEMueEIuVyhhLG0pJjY0NTEyKT09PTU2MzIwKX1lbHNlIG09ITEKaWYoIW0paWYobj09
-PTU2MzIwKXtuPXAtMQpuPSEobj49MCYmKEMueEIuTzIoYSxuKSY2NDUxMik9PT01NTI5Nil9ZWxzZSBu
-PSExCmVsc2Ugbj0hMAppZihuKXtpZihwPnEpci5hKz1DLnhCLk5qKGEscSxwKQpxPXArMQpyLmErPUgu
-THcoOTIpCnIuYSs9SC5MdygxMTcpCnIuYSs9SC5MdygxMDApCm49bz4+PjgmMTUKci5hKz1ILkx3KG48
-MTA/NDgrbjo4NytuKQpuPW8+Pj40JjE1CnIuYSs9SC5MdyhuPDEwPzQ4K246ODcrbikKbj1vJjE1CnIu
-YSs9SC5MdyhuPDEwPzQ4K246ODcrbil9fWNvbnRpbnVlfWlmKG88MzIpe2lmKHA+cSlyLmErPUMueEIu
-TmooYSxxLHApCnE9cCsxCnIuYSs9SC5Mdyg5MikKc3dpdGNoKG8pe2Nhc2UgODpyLmErPUguTHcoOTgp
-CmJyZWFrCmNhc2UgOTpyLmErPUguTHcoMTE2KQpicmVhawpjYXNlIDEwOnIuYSs9SC5MdygxMTApCmJy
-ZWFrCmNhc2UgMTI6ci5hKz1ILkx3KDEwMikKYnJlYWsKY2FzZSAxMzpyLmErPUguTHcoMTE0KQpicmVh
-awpkZWZhdWx0OnIuYSs9SC5MdygxMTcpCnIuYSs9SC5Mdyg0OCkKci5hKz1ILkx3KDQ4KQpuPW8+Pj40
-JjE1CnIuYSs9SC5MdyhuPDEwPzQ4K246ODcrbikKbj1vJjE1CnIuYSs9SC5MdyhuPDEwPzQ4K246ODcr
-bikKYnJlYWt9fWVsc2UgaWYobz09PTM0fHxvPT09OTIpe2lmKHA+cSlyLmErPUMueEIuTmooYSxxLHAp
-CnE9cCsxCnIuYSs9SC5Mdyg5MikKci5hKz1ILkx3KG8pfX1pZihxPT09MClyLmErPUguRWooYSkKZWxz
-ZSBpZihxPGwpci5hKz1zLk5qKGEscSxsKX0sCkpuOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwCmZvcihz
-PXRoaXMuYSxyPXMubGVuZ3RoLHE9MDtxPHI7KytxKXtwPXNbcV0KaWYoYT09bnVsbD9wPT1udWxsOmE9
-PT1wKXRocm93IEguYihuZXcgUC5LOChhLG51bGwpKX1DLk5tLmkocyxhKX0sCmlVOmZ1bmN0aW9uKGEp
-e3ZhciBzLHIscSxwLG89dGhpcwppZihvLnRNKGEpKXJldHVybgpvLkpuKGEpCnRyeXtzPW8uYi4kMShh
-KQppZighby50TShzKSl7cT1QLkd5KGEsbnVsbCxvLmdWSygpKQp0aHJvdyBILmIocSl9cT1vLmEKaWYo
-MD49cS5sZW5ndGgpcmV0dXJuIEguT0gocSwtMSkKcS5wb3AoKX1jYXRjaChwKXtyPUguUnUocCkKcT1Q
-Lkd5KGEscixvLmdWSygpKQp0aHJvdyBILmIocSl9fSwKdE06ZnVuY3Rpb24oYSl7dmFyIHMscixxPXRo
-aXMKaWYodHlwZW9mIGE9PSJudW1iZXIiKXtpZighaXNGaW5pdGUoYSkpcmV0dXJuITEKcS5jLmErPUMu
-Q0QudyhhKQpyZXR1cm4hMH1lbHNlIGlmKGE9PT0hMCl7cS5jLmErPSJ0cnVlIgpyZXR1cm4hMH1lbHNl
-IGlmKGE9PT0hMSl7cS5jLmErPSJmYWxzZSIKcmV0dXJuITB9ZWxzZSBpZihhPT1udWxsKXtxLmMuYSs9
-Im51bGwiCnJldHVybiEwfWVsc2UgaWYodHlwZW9mIGE9PSJzdHJpbmciKXtzPXEuYwpzLmErPSciJwpx
-LnZwKGEpCnMuYSs9JyInCnJldHVybiEwfWVsc2UgaWYodC5qLmIoYSkpe3EuSm4oYSkKcS5sSyhhKQpz
-PXEuYQppZigwPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLC0xKQpzLnBvcCgpCnJldHVybiEwfWVsc2Ug
-aWYodC5mLmIoYSkpe3EuSm4oYSkKcj1xLmp3KGEpCnM9cS5hCmlmKDA+PXMubGVuZ3RoKXJldHVybiBI
-Lk9IKHMsLTEpCnMucG9wKCkKcmV0dXJuIHJ9ZWxzZSByZXR1cm4hMX0sCmxLOmZ1bmN0aW9uKGEpe3Zh
-ciBzLHIscT10aGlzLmMKcS5hKz0iWyIKcz1KLlU2KGEpCmlmKHMuZ29yKGEpKXt0aGlzLmlVKHMucShh
-LDApKQpmb3Iocj0xO3I8cy5nQShhKTsrK3Ipe3EuYSs9IiwiCnRoaXMuaVUocy5xKGEscikpfX1xLmEr
-PSJdIn0sCmp3OmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG8sbixtPXRoaXMsbD17fQppZihhLmdsMChh
-KSl7bS5jLmErPSJ7fSIKcmV0dXJuITB9cz1hLmdBKGEpKjIKcj1QLk84KHMsbnVsbCwhMSx0LlcpCnE9
-bC5hPTAKbC5iPSEwCmEuSygwLG5ldyBQLnRpKGwscikpCmlmKCFsLmIpcmV0dXJuITEKcD1tLmMKcC5h
-Kz0ieyIKZm9yKG89JyInO3E8cztxKz0yLG89JywiJyl7cC5hKz1vCm0udnAoSC5oKHJbcV0pKQpwLmEr
-PSciOicKbj1xKzEKaWYobj49cylyZXR1cm4gSC5PSChyLG4pCm0uaVUocltuXSl9cC5hKz0ifSIKcmV0
-dXJuITB9fQpQLnRpLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHMscgppZih0eXBlb2Yg
-YSE9InN0cmluZyIpdGhpcy5hLmI9ITEKcz10aGlzLmIKcj10aGlzLmEKQy5ObS5ZKHMsci5hKyssYSkK
-Qy5ObS5ZKHMsci5hKyssYil9LAokUzoxMH0KUC50dS5wcm90b3R5cGU9ewpnVks6ZnVuY3Rpb24oKXt2
-YXIgcz10aGlzLmMuYQpyZXR1cm4gcy5jaGFyQ29kZUF0KDApPT0wP3M6c319ClAudTUucHJvdG90eXBl
-PXsKZ1pFOmZ1bmN0aW9uKCl7cmV0dXJuIEMuUWt9fQpQLkUzLnByb3RvdHlwZT17CldKOmZ1bmN0aW9u
-KGEpe3ZhciBzLHIscSxwPVAuakIoMCxudWxsLGEubGVuZ3RoKSxvPXAtMAppZihvPT09MClyZXR1cm4g
-bmV3IFVpbnQ4QXJyYXkoMCkKcz1vKjMKcj1uZXcgVWludDhBcnJheShzKQpxPW5ldyBQLlJ3KHIpCmlm
-KHEuR3goYSwwLHApIT09cCl7Si5hNihhLHAtMSkKcS5STygpfXJldHVybiBuZXcgVWludDhBcnJheShy
-LnN1YmFycmF5KDAsSC5yTSgwLHEuYixzKSkpfX0KUC5Sdy5wcm90b3R5cGU9ewpSTzpmdW5jdGlvbigp
-e3ZhciBzPXRoaXMscj1zLmMscT1zLmIscD1zLmI9cSsxLG89ci5sZW5ndGgKaWYocT49bylyZXR1cm4g
-SC5PSChyLHEpCnJbcV09MjM5CnE9cy5iPXArMQppZihwPj1vKXJldHVybiBILk9IKHIscCkKcltwXT0x
-OTEKcy5iPXErMQppZihxPj1vKXJldHVybiBILk9IKHIscSkKcltxXT0xODl9LApPNjpmdW5jdGlvbihh
-LGIpe3ZhciBzLHIscSxwLG8sbj10aGlzCmlmKChiJjY0NTEyKT09PTU2MzIwKXtzPTY1NTM2KygoYSYx
-MDIzKTw8MTApfGImMTAyMwpyPW4uYwpxPW4uYgpwPW4uYj1xKzEKbz1yLmxlbmd0aAppZihxPj1vKXJl
-dHVybiBILk9IKHIscSkKcltxXT1zPj4+MTh8MjQwCnE9bi5iPXArMQppZihwPj1vKXJldHVybiBILk9I
-KHIscCkKcltwXT1zPj4+MTImNjN8MTI4CnA9bi5iPXErMQppZihxPj1vKXJldHVybiBILk9IKHIscSkK
-cltxXT1zPj4+NiY2M3wxMjgKbi5iPXArMQppZihwPj1vKXJldHVybiBILk9IKHIscCkKcltwXT1zJjYz
-fDEyOApyZXR1cm4hMH1lbHNle24uUk8oKQpyZXR1cm4hMX19LApHeDpmdW5jdGlvbihhLGIsYyl7dmFy
-IHMscixxLHAsbyxuLG0sbD10aGlzCmlmKGIhPT1jJiYoQy54Qi5PMihhLGMtMSkmNjQ1MTIpPT09NTUy
-OTYpLS1jCmZvcihzPWwuYyxyPXMubGVuZ3RoLHE9YjtxPGM7KytxKXtwPUMueEIuVyhhLHEpCmlmKHA8
-PTEyNyl7bz1sLmIKaWYobz49cilicmVhawpsLmI9bysxCnNbb109cH1lbHNle289cCY2NDUxMgppZihv
-PT09NTUyOTYpe2lmKGwuYis0PnIpYnJlYWsKbj1xKzEKaWYobC5PNihwLEMueEIuVyhhLG4pKSlxPW59
-ZWxzZSBpZihvPT09NTYzMjApe2lmKGwuYiszPnIpYnJlYWsKbC5STygpfWVsc2UgaWYocDw9MjA0Nyl7
-bz1sLmIKbT1vKzEKaWYobT49cilicmVhawpsLmI9bQppZihvPj1yKXJldHVybiBILk9IKHMsbykKc1tv
-XT1wPj4+NnwxOTIKbC5iPW0rMQpzW21dPXAmNjN8MTI4fWVsc2V7bz1sLmIKaWYobysyPj1yKWJyZWFr
-Cm09bC5iPW8rMQppZihvPj1yKXJldHVybiBILk9IKHMsbykKc1tvXT1wPj4+MTJ8MjI0Cm89bC5iPW0r
-MQppZihtPj1yKXJldHVybiBILk9IKHMsbSkKc1ttXT1wPj4+NiY2M3wxMjgKbC5iPW8rMQppZihvPj1y
-KXJldHVybiBILk9IKHMsbykKc1tvXT1wJjYzfDEyOH19fXJldHVybiBxfX0KUC5HWS5wcm90b3R5cGU9
-ewpXSjpmdW5jdGlvbihhKXt2YXIgcyxyCnQuTC5hKGEpCnM9dGhpcy5hCnI9UC5reShzLGEsMCxudWxs
-KQppZihyIT1udWxsKXJldHVybiByCnJldHVybiBuZXcgUC5ieihzKS5OZShhLDAsbnVsbCwhMCl9fQpQ
-LmJ6LnByb3RvdHlwZT17Ck5lOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIscSxwLG8sbj10aGlzCnQu
-TC5hKGEpCnM9UC5qQihiLGMsSi5IbShhKSkKaWYoYj09PXMpcmV0dXJuIiIKcj1QLmp5KGEsYixzKQpx
-PW4uaE8ociwwLHMtYiwhMCkKcD1uLmIKaWYoKHAmMSkhPT0wKXtvPVAuajQocCkKbi5iPTAKdGhyb3cg
-SC5iKFAucnIobyxhLGIrbi5jKSl9cmV0dXJuIHF9LApoTzpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxy
-LHE9dGhpcwppZihjLWI+MTAwMCl7cz1DLmpuLkJVKGIrYywyKQpyPXEuaE8oYSxiLHMsITEpCmlmKChx
-LmImMSkhPT0wKXJldHVybiByCnJldHVybiByK3EuaE8oYSxzLGMsZCl9cmV0dXJuIHEuRWgoYSxiLGMs
-ZCl9LApFaDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyLHEscCxvLG4sbSxsLGs9dGhpcyxqPTY1NTMz
-LGk9ay5iLGg9ay5jLGc9bmV3IFAuUm4oIiIpLGY9YisxLGU9YS5sZW5ndGgKaWYoYjwwfHxiPj1lKXJl
-dHVybiBILk9IKGEsYikKcz1hW2JdCiRsYWJlbDAkMDpmb3Iocj1rLmE7ITA7KXtmb3IoOyEwO2Y9byl7
-cT1DLnhCLlcoIkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFB
+dHVybiBtLml9cz0kLnZ2W3FdCmlmKHMhPW51bGwpcmV0dXJuIHMKcj12LmludGVyY2VwdG9yc0J5VGFn
+W3FdCm49cX19aWYocj09bnVsbClyZXR1cm4gbnVsbApzPXIucHJvdG90eXBlCnA9blswXQppZihwPT09
+IiEiKXttPUguVmEocykKJC5ud1tuXT1tCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShhLHYuZGlzcGF0Y2hQ
+cm9wZXJ0eU5hbWUse3ZhbHVlOm0sZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3Vy
+YWJsZTp0cnVlfSkKcmV0dXJuIG0uaX1pZihwPT09In4iKXskLnZ2W25dPXMKcmV0dXJuIHN9aWYocD09
+PSItIil7bz1ILlZhKHMpCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShPYmplY3QuZ2V0UHJvdG90eXBlT2Yo
+YSksdi5kaXNwYXRjaFByb3BlcnR5TmFtZSx7dmFsdWU6byxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxl
+OnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpyZXR1cm4gby5pfWlmKHA9PT0iKyIpcmV0dXJuIEguTGMo
+YSxzKQppZihwPT09IioiKXRocm93IEguYihQLlNZKG4pKQppZih2LmxlYWZUYWdzW25dPT09dHJ1ZSl7
+bz1ILlZhKHMpCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShPYmplY3QuZ2V0UHJvdG90eXBlT2YoYSksdi5k
+aXNwYXRjaFByb3BlcnR5TmFtZSx7dmFsdWU6byxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUs
+Y29uZmlndXJhYmxlOnRydWV9KQpyZXR1cm4gby5pfWVsc2UgcmV0dXJuIEguTGMoYSxzKX0sCkxjOmZ1
+bmN0aW9uKGEsYil7dmFyIHM9T2JqZWN0LmdldFByb3RvdHlwZU9mKGEpCk9iamVjdC5kZWZpbmVQcm9w
+ZXJ0eShzLHYuZGlzcGF0Y2hQcm9wZXJ0eU5hbWUse3ZhbHVlOkouUXUoYixzLG51bGwsbnVsbCksZW51
+bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVlfSkKcmV0dXJuIGJ9LApW
+YTpmdW5jdGlvbihhKXtyZXR1cm4gSi5RdShhLCExLG51bGwsISFhLiRpWGopfSwKVkY6ZnVuY3Rpb24o
+YSxiLGMpe3ZhciBzPWIucHJvdG90eXBlCmlmKHYubGVhZlRhZ3NbYV09PT10cnVlKXJldHVybiBILlZh
+KHMpCmVsc2UgcmV0dXJuIEouUXUocyxjLG51bGwsbnVsbCl9LApYRDpmdW5jdGlvbigpe2lmKCEwPT09
+JC5CdilyZXR1cm4KJC5Cdj0hMApILloxKCl9LApaMTpmdW5jdGlvbigpe3ZhciBzLHIscSxwLG8sbixt
+LGwKJC5udz1PYmplY3QuY3JlYXRlKG51bGwpCiQudnY9T2JqZWN0LmNyZWF0ZShudWxsKQpILmtPKCkK
+cz12LmludGVyY2VwdG9yc0J5VGFnCnI9T2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMocykKaWYodHlw
+ZW9mIHdpbmRvdyE9InVuZGVmaW5lZCIpe3dpbmRvdwpxPWZ1bmN0aW9uKCl7fQpmb3IocD0wO3A8ci5s
+ZW5ndGg7KytwKXtvPXJbcF0Kbj0kLng3LiQxKG8pCmlmKG4hPW51bGwpe209SC5WRihvLHNbb10sbikK
+aWYobSE9bnVsbCl7T2JqZWN0LmRlZmluZVByb3BlcnR5KG4sdi5kaXNwYXRjaFByb3BlcnR5TmFtZSx7
+dmFsdWU6bSxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpx
+LnByb3RvdHlwZT1ufX19fWZvcihwPTA7cDxyLmxlbmd0aDsrK3Ape289cltwXQppZigvXltBLVphLXpf
+XS8udGVzdChvKSl7bD1zW29dCnNbIiEiK29dPWwKc1sifiIrb109bApzWyItIitvXT1sCnNbIisiK29d
+PWwKc1siKiIrb109bH19fSwKa086ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvLG4sbT1DLllxKCkKbT1I
+LnVkKEMuS1UsSC51ZChDLmZRLEgudWQoQy5pNyxILnVkKEMuaTcsSC51ZChDLnhpLEgudWQoQy5kayxI
+LnVkKEMud2IoQy5PNCksbSkpKSkpKSkKaWYodHlwZW9mIGRhcnROYXRpdmVEaXNwYXRjaEhvb2tzVHJh
+bnNmb3JtZXIhPSJ1bmRlZmluZWQiKXtzPWRhcnROYXRpdmVEaXNwYXRjaEhvb2tzVHJhbnNmb3JtZXIK
+aWYodHlwZW9mIHM9PSJmdW5jdGlvbiIpcz1bc10KaWYocy5jb25zdHJ1Y3Rvcj09QXJyYXkpZm9yKHI9
+MDtyPHMubGVuZ3RoOysrcil7cT1zW3JdCmlmKHR5cGVvZiBxPT0iZnVuY3Rpb24iKW09cShtKXx8bX19
+cD1tLmdldFRhZwpvPW0uZ2V0VW5rbm93blRhZwpuPW0ucHJvdG90eXBlRm9yVGFnCiQuTkY9bmV3IEgu
+ZEMocCkKJC5UWD1uZXcgSC53TihvKQokLng3PW5ldyBILlZYKG4pfSwKdWQ6ZnVuY3Rpb24oYSxiKXty
+ZXR1cm4gYShiKXx8Yn0sCnY0OmZ1bmN0aW9uKGEsYixjLGQsZSxmKXt2YXIgcz1iPyJtIjoiIixyPWM/
+IiI6ImkiLHE9ZD8idSI6IiIscD1lPyJzIjoiIixvPWY/ImciOiIiLG49ZnVuY3Rpb24oZyxoKXt0cnl7
+cmV0dXJuIG5ldyBSZWdFeHAoZyxoKX1jYXRjaChtKXtyZXR1cm4gbX19KGEscytyK3ErcCtvKQppZihu
+IGluc3RhbmNlb2YgUmVnRXhwKXJldHVybiBuCnRocm93IEguYihQLnJyKCJJbGxlZ2FsIFJlZ0V4cCBw
+YXR0ZXJuICgiK1N0cmluZyhuKSsiKSIsYSxudWxsKSl9LApTUTpmdW5jdGlvbihhLGIsYyl7dmFyIHMK
+aWYodHlwZW9mIGI9PSJzdHJpbmciKXJldHVybiBhLmluZGV4T2YoYixjKT49MAplbHNlIGlmKGIgaW5z
+dGFuY2VvZiBILlZSKXtzPUMueEIueW4oYSxjKQpyZXR1cm4gYi5iLnRlc3Qocyl9ZWxzZXtzPUouRkwo
+YixDLnhCLnluKGEsYykpCnJldHVybiFzLmdsMChzKX19LApBNDpmdW5jdGlvbihhKXtpZihhLmluZGV4
+T2YoIiQiLDApPj0wKXJldHVybiBhLnJlcGxhY2UoL1wkL2csIiQkJCQiKQpyZXR1cm4gYX0sCmVBOmZ1
+bmN0aW9uKGEpe2lmKC9bW1xde30oKSorPy5cXF4kfF0vLnRlc3QoYSkpcmV0dXJuIGEucmVwbGFjZSgv
+W1tcXXt9KCkqKz8uXFxeJHxdL2csIlxcJCYiKQpyZXR1cm4gYX0sCnlzOmZ1bmN0aW9uKGEsYixjKXt2
+YXIgcz1ILm5NKGEsYixjKQpyZXR1cm4gc30sCm5NOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscApp
+ZihiPT09IiIpe2lmKGE9PT0iIilyZXR1cm4gYwpzPWEubGVuZ3RoCmZvcihyPWMscT0wO3E8czsrK3Ep
+cj1yK2FbcV0rYwpyZXR1cm4gci5jaGFyQ29kZUF0KDApPT0wP3I6cn1wPWEuaW5kZXhPZihiLDApCmlm
+KHA8MClyZXR1cm4gYQppZihhLmxlbmd0aDw1MDB8fGMuaW5kZXhPZigiJCIsMCk+PTApcmV0dXJuIGEu
+c3BsaXQoYikuam9pbihjKQpyZXR1cm4gYS5yZXBsYWNlKG5ldyBSZWdFeHAoSC5lQShiKSwnZycpLEgu
+QTQoYykpfSwKUEQ6ZnVuY3Rpb24gUEQoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKV1U6ZnVuY3Rp
+b24gV1UoKXt9LApMUDpmdW5jdGlvbiBMUChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8u
+Yz1jCl8uJHRpPWR9LApYUjpmdW5jdGlvbiBYUihhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApMSTpm
+dW5jdGlvbiBMSShhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5hPWEKXy5jPWIKXy5kPWMKXy5lPWQKXy5m
+PWV9LApDajpmdW5jdGlvbiBDaihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApmOTpm
+dW5jdGlvbiBmOShhLGIsYyxkLGUsZil7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApf
+LmU9ZQpfLmY9Zn0sClcwOmZ1bmN0aW9uIFcwKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAphejpmdW5j
+dGlvbiBheihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LAp2VjpmdW5jdGlvbiB2Vihh
+KXt0aGlzLmE9YX0sCnRlOmZ1bmN0aW9uIHRlKGEpe3RoaXMuYT1hfSwKYnE6ZnVuY3Rpb24gYnEoYSxi
+KXt0aGlzLmE9YQp0aGlzLmI9Yn0sClhPOmZ1bmN0aW9uIFhPKGEpe3RoaXMuYT1hCnRoaXMuYj1udWxs
+fSwKVHA6ZnVuY3Rpb24gVHAoKXt9LApsYzpmdW5jdGlvbiBsYygpe30sCnp4OmZ1bmN0aW9uIHp4KCl7
+fSwKclQ6ZnVuY3Rpb24gclQoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9
+ZH0sCkVxOmZ1bmN0aW9uIEVxKGEpe3RoaXMuYT1hfSwKa1k6ZnVuY3Rpb24ga1koYSl7dGhpcy5hPWF9
+LAprcjpmdW5jdGlvbiBrcigpe30sCk41OmZ1bmN0aW9uIE41KGEpe3ZhciBfPXRoaXMKXy5hPTAKXy5m
+PV8uZT1fLmQ9Xy5jPV8uYj1udWxsCl8ucj0wCl8uJHRpPWF9LAp2aDpmdW5jdGlvbiB2aChhLGIpe3Zh
+ciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5kPV8uYz1udWxsfSwKaTU6ZnVuY3Rpb24gaTUoYSxiKXt0aGlz
+LmE9YQp0aGlzLiR0aT1ifSwKTjY6ZnVuY3Rpb24gTjYoYSxiLGMpe3ZhciBfPXRoaXMKXy5hPWEKXy5i
+PWIKXy5kPV8uYz1udWxsCl8uJHRpPWN9LApkQzpmdW5jdGlvbiBkQyhhKXt0aGlzLmE9YX0sCndOOmZ1
+bmN0aW9uIHdOKGEpe3RoaXMuYT1hfSwKVlg6ZnVuY3Rpb24gVlgoYSl7dGhpcy5hPWF9LApWUjpmdW5j
+dGlvbiBWUihhLGIpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5kPV8uYz1udWxsfSwKRUs6ZnVuY3Rp
+b24gRUsoYSl7dGhpcy5iPWF9LApLVzpmdW5jdGlvbiBLVyhhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIK
+dGhpcy5jPWN9LApQYjpmdW5jdGlvbiBQYihhLGIsYyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9
+YwpfLmQ9bnVsbH0sCnRROmZ1bmN0aW9uIHRRKGEsYil7dGhpcy5hPWEKdGhpcy5jPWJ9LAp1bjpmdW5j
+dGlvbiB1bihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApTZDpmdW5jdGlvbiBTZChh
+LGIsYyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9bnVsbH0sClhGOmZ1bmN0aW9uKGEp
+e3JldHVybiBhfSwKb2Q6ZnVuY3Rpb24oYSxiLGMpe2lmKGE+Pj4wIT09YXx8YT49Yyl0aHJvdyBILmIo
+SC5IWShiLGEpKX0sCnJNOmZ1bmN0aW9uKGEsYixjKXt2YXIgcwppZighKGE+Pj4wIT09YSkpcz1iPj4+
+MCE9PWJ8fGE+Ynx8Yj5jCmVsc2Ugcz0hMAppZihzKXRocm93IEguYihILmF1KGEsYixjKSkKcmV0dXJu
+IGJ9LApFVDpmdW5jdGlvbiBFVCgpe30sCkxaOmZ1bmN0aW9uIExaKCl7fSwKRGc6ZnVuY3Rpb24gRGco
+KXt9LApQZzpmdW5jdGlvbiBQZygpe30sCnhqOmZ1bmN0aW9uIHhqKCl7fSwKZEU6ZnVuY3Rpb24gZEUo
+KXt9LApaQTpmdW5jdGlvbiBaQSgpe30sCmRUOmZ1bmN0aW9uIGRUKCl7fSwKUHE6ZnVuY3Rpb24gUHEo
+KXt9LAplRTpmdW5jdGlvbiBlRSgpe30sClY2OmZ1bmN0aW9uIFY2KCl7fSwKUkc6ZnVuY3Rpb24gUkco
+KXt9LApWUDpmdW5jdGlvbiBWUCgpe30sCldCOmZ1bmN0aW9uIFdCKCl7fSwKWkc6ZnVuY3Rpb24gWkco
+KXt9LApjejpmdW5jdGlvbihhLGIpe3ZhciBzPWIuYwpyZXR1cm4gcz09bnVsbD9iLmM9SC5CKGEsYi56
+LCEwKTpzfSwKeFo6ZnVuY3Rpb24oYSxiKXt2YXIgcz1iLmMKcmV0dXJuIHM9PW51bGw/Yi5jPUguSihh
+LCJiOCIsW2Iuel0pOnN9LApRMTpmdW5jdGlvbihhKXt2YXIgcz1hLnkKaWYocz09PTZ8fHM9PT03fHxz
+PT09OClyZXR1cm4gSC5RMShhLnopCnJldHVybiBzPT09MTF8fHM9PT0xMn0sCm1EOmZ1bmN0aW9uKGEp
+e3JldHVybiBhLmN5fSwKTjA6ZnVuY3Rpb24oYSl7cmV0dXJuIEguRSh2LnR5cGVVbml2ZXJzZSxhLCEx
+KX0sClBMOmZ1bmN0aW9uKGEsYixhMCxhMSl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixl
+LGQsYz1iLnkKc3dpdGNoKGMpe2Nhc2UgNTpjYXNlIDE6Y2FzZSAyOmNhc2UgMzpjYXNlIDQ6cmV0dXJu
+IGIKY2FzZSA2OnM9Yi56CnI9SC5QTChhLHMsYTAsYTEpCmlmKHI9PT1zKXJldHVybiBiCnJldHVybiBI
+LkMoYSxyLCEwKQpjYXNlIDc6cz1iLnoKcj1ILlBMKGEscyxhMCxhMSkKaWYocj09PXMpcmV0dXJuIGIK
+cmV0dXJuIEguQihhLHIsITApCmNhc2UgODpzPWIuegpyPUguUEwoYSxzLGEwLGExKQppZihyPT09cyly
+ZXR1cm4gYgpyZXR1cm4gSC5mKGEsciwhMCkKY2FzZSA5OnE9Yi5RCnA9SC5iWihhLHEsYTAsYTEpCmlm
+KHA9PT1xKXJldHVybiBiCnJldHVybiBILkooYSxiLnoscCkKY2FzZSAxMDpvPWIuegpuPUguUEwoYSxv
+LGEwLGExKQptPWIuUQpsPUguYlooYSxtLGEwLGExKQppZihuPT09byYmbD09PW0pcmV0dXJuIGIKcmV0
+dXJuIEguYShhLG4sbCkKY2FzZSAxMTprPWIuegpqPUguUEwoYSxrLGEwLGExKQppPWIuUQpoPUgucVQo
+YSxpLGEwLGExKQppZihqPT09ayYmaD09PWkpcmV0dXJuIGIKcmV0dXJuIEguZChhLGosaCkKY2FzZSAx
+MjpnPWIuUQphMSs9Zy5sZW5ndGgKZj1ILmJaKGEsZyxhMCxhMSkKbz1iLnoKbj1ILlBMKGEsbyxhMCxh
+MSkKaWYoZj09PWcmJm49PT1vKXJldHVybiBiCnJldHVybiBILkQoYSxuLGYsITApCmNhc2UgMTM6ZT1i
+LnoKaWYoZTxhMSlyZXR1cm4gYgpkPWEwW2UtYTFdCmlmKGQ9PW51bGwpcmV0dXJuIGIKcmV0dXJuIGQK
+ZGVmYXVsdDp0aHJvdyBILmIoUC5oVigiQXR0ZW1wdGVkIHRvIHN1YnN0aXR1dGUgdW5leHBlY3RlZCBS
+VEkga2luZCAiK2MpKX19LApiWjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyLHEscCxvPWIubGVuZ3Ro
+LG49W10KZm9yKHM9ITEscj0wO3I8bzsrK3Ipe3E9YltyXQpwPUguUEwoYSxxLGMsZCkKaWYocCE9PXEp
+cz0hMApuLnB1c2gocCl9cmV0dXJuIHM/bjpifSwKdk86ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixx
+LHAsbyxuLG09Yi5sZW5ndGgsbD1bXQpmb3Iocz0hMSxyPTA7cjxtO3IrPTMpe3E9YltyXQpwPWJbcisx
+XQpvPWJbcisyXQpuPUguUEwoYSxvLGMsZCkKaWYobiE9PW8pcz0hMApsLnB1c2gocSkKbC5wdXNoKHAp
+CmwucHVzaChuKX1yZXR1cm4gcz9sOmJ9LApxVDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyPWIuYSxx
+PUguYlooYSxyLGMsZCkscD1iLmIsbz1ILmJaKGEscCxjLGQpLG49Yi5jLG09SC52TyhhLG4sYyxkKQpp
+ZihxPT09ciYmbz09PXAmJm09PT1uKXJldHVybiBiCnM9bmV3IEguRygpCnMuYT1xCnMuYj1vCnMuYz1t
+CnJldHVybiBzfSwKVk06ZnVuY3Rpb24oYSxiKXthW3YuYXJyYXlSdGldPWIKcmV0dXJuIGF9LApKUzpm
+dW5jdGlvbihhKXt2YXIgcz1hLiRTCmlmKHMhPW51bGwpe2lmKHR5cGVvZiBzPT0ibnVtYmVyIilyZXR1
+cm4gSC5CcChzKQpyZXR1cm4gYS4kUygpfXJldHVybiBudWxsfSwKVWU6ZnVuY3Rpb24oYSxiKXt2YXIg
+cwppZihILlExKGIpKWlmKGEgaW5zdGFuY2VvZiBILlRwKXtzPUguSlMoYSkKaWYocyE9bnVsbClyZXR1
+cm4gc31yZXR1cm4gSC56KGEpfSwKejpmdW5jdGlvbihhKXt2YXIgcwppZihhIGluc3RhbmNlb2YgUC5N
+aCl7cz1hLiR0aQpyZXR1cm4gcyE9bnVsbD9zOkguVlUoYSl9aWYoQXJyYXkuaXNBcnJheShhKSlyZXR1
+cm4gSC50NihhKQpyZXR1cm4gSC5WVShKLmlhKGEpKX0sCnQ2OmZ1bmN0aW9uKGEpe3ZhciBzPWFbdi5h
+cnJheVJ0aV0scj10LngKaWYocz09bnVsbClyZXR1cm4gcgppZihzLmNvbnN0cnVjdG9yIT09ci5jb25z
+dHJ1Y3RvcilyZXR1cm4gcgpyZXR1cm4gc30sCkxoOmZ1bmN0aW9uKGEpe3ZhciBzPWEuJHRpCnJldHVy
+biBzIT1udWxsP3M6SC5WVShhKX0sClZVOmZ1bmN0aW9uKGEpe3ZhciBzPWEuY29uc3RydWN0b3Iscj1z
+LiRjY2FjaGUKaWYociE9bnVsbClyZXR1cm4gcgpyZXR1cm4gSC5yOShhLHMpfSwKcjk6ZnVuY3Rpb24o
+YSxiKXt2YXIgcz1hIGluc3RhbmNlb2YgSC5UcD9hLl9fcHJvdG9fXy5fX3Byb3RvX18uY29uc3RydWN0
+b3I6YixyPUguYWkodi50eXBlVW5pdmVyc2Uscy5uYW1lKQpiLiRjY2FjaGU9cgpyZXR1cm4gcn0sCkJw
+OmZ1bmN0aW9uKGEpe3ZhciBzLHIscQpILnVQKGEpCnM9di50eXBlcwpyPXNbYV0KaWYodHlwZW9mIHI9
+PSJzdHJpbmciKXtxPUguRSh2LnR5cGVVbml2ZXJzZSxyLCExKQpzW2FdPXEKcmV0dXJuIHF9cmV0dXJu
+IHJ9LApLeDpmdW5jdGlvbihhKXt2YXIgcyxyLHEscD1hLngKaWYocCE9bnVsbClyZXR1cm4gcApzPWEu
+Y3kKcj1zLnJlcGxhY2UoL1wqL2csIiIpCmlmKHI9PT1zKXJldHVybiBhLng9bmV3IEgubFkoYSkKcT1I
+LkUodi50eXBlVW5pdmVyc2UsciwhMCkKcD1xLngKcmV0dXJuIGEueD1wPT1udWxsP3EueD1uZXcgSC5s
+WShxKTpwfSwKSko6ZnVuY3Rpb24oYSl7dmFyIHMscixxPXRoaXMscD10LksKaWYocT09PXApcmV0dXJu
+IEguUkUocSxhLEgua2UpCmlmKCFILkE4KHEpKWlmKCEocT09PXQuXykpcD1xPT09cAplbHNlIHA9ITAK
+ZWxzZSBwPSEwCmlmKHApcmV0dXJuIEguUkUocSxhLEguSXcpCnA9cS55CnM9cD09PTY/cS56OnEKaWYo
+cz09PXQuUylyPUgub2sKZWxzZSBpZihzPT09dC5nUnx8cz09PXQuZGkpcj1ILktICmVsc2UgaWYocz09
+PXQuTilyPUguTU0KZWxzZSByPXM9PT10Lnk/SC5sOm51bGwKaWYociE9bnVsbClyZXR1cm4gSC5SRShx
+LGEscikKaWYocy55PT09OSl7cD1zLnoKaWYocy5RLmV2ZXJ5KEguY2MpKXtxLnI9IiRpIitwCnJldHVy
+biBILlJFKHEsYSxILnQ0KX19ZWxzZSBpZihwPT09NylyZXR1cm4gSC5SRShxLGEsSC5BUSkKcmV0dXJu
+IEguUkUocSxhLEguWU8pfSwKUkU6ZnVuY3Rpb24oYSxiLGMpe2EuYj1jCnJldHVybiBhLmIoYil9LApB
+dTpmdW5jdGlvbihhKXt2YXIgcyxyLHE9dGhpcwppZighSC5BOChxKSlpZighKHE9PT10Ll8pKXM9cT09
+PXQuSwplbHNlIHM9ITAKZWxzZSBzPSEwCmlmKHMpcj1ILmhuCmVsc2UgaWYocT09PXQuSylyPUguVGkK
+ZWxzZSByPUgubDQKcS5hPXIKcmV0dXJuIHEuYShhKX0sClFqOmZ1bmN0aW9uKGEpe3ZhciBzLHI9YS55
+CmlmKCFILkE4KGEpKWlmKCEoYT09PXQuXykpaWYoIShhPT09dC5jRikpaWYociE9PTcpcz1yPT09OCYm
+SC5RaihhLnopfHxhPT09dC5QfHxhPT09dC5UCmVsc2Ugcz0hMAplbHNlIHM9ITAKZWxzZSBzPSEwCmVs
+c2Ugcz0hMApyZXR1cm4gc30sCllPOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMKaWYoYT09bnVsbClyZXR1
+cm4gSC5RaihzKQpyZXR1cm4gSC5XZSh2LnR5cGVVbml2ZXJzZSxILlVlKGEscyksbnVsbCxzLG51bGwp
+fSwKQVE6ZnVuY3Rpb24oYSl7aWYoYT09bnVsbClyZXR1cm4hMApyZXR1cm4gdGhpcy56LmIoYSl9LAp0
+NDpmdW5jdGlvbihhKXt2YXIgcyxyPXRoaXMKaWYoYT09bnVsbClyZXR1cm4gSC5RaihyKQpzPXIucgpp
+ZihhIGluc3RhbmNlb2YgUC5NaClyZXR1cm4hIWFbc10KcmV0dXJuISFKLmlhKGEpW3NdfSwKT3o6ZnVu
+Y3Rpb24oYSl7dmFyIHM9dGhpcwppZihhPT1udWxsKXJldHVybiBhCmVsc2UgaWYocy5iKGEpKXJldHVy
+biBhCkgubTQoYSxzKX0sCmw0OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMKaWYoYT09bnVsbClyZXR1cm4g
+YQplbHNlIGlmKHMuYihhKSlyZXR1cm4gYQpILm00KGEscyl9LAptNDpmdW5jdGlvbihhLGIpe3Rocm93
+IEguYihILlpjKEguV0soYSxILlVlKGEsYiksSC5kbShiLG51bGwpKSkpfSwKRGg6ZnVuY3Rpb24oYSxi
+LGMsZCl7dmFyIHM9bnVsbAppZihILldlKHYudHlwZVVuaXZlcnNlLGEscyxiLHMpKXJldHVybiBhCnRo
+cm93IEguYihILlpjKCJUaGUgdHlwZSBhcmd1bWVudCAnIitILkVqKEguZG0oYSxzKSkrIicgaXMgbm90
+IGEgc3VidHlwZSBvZiB0aGUgdHlwZSB2YXJpYWJsZSBib3VuZCAnIitILkVqKEguZG0oYixzKSkrIicg
+b2YgdHlwZSB2YXJpYWJsZSAnIitILkVqKGMpKyInIGluICciK0guRWooZCkrIicuIikpfSwKV0s6ZnVu
+Y3Rpb24oYSxiLGMpe3ZhciBzPVAucChhKSxyPUguZG0oYj09bnVsbD9ILnooYSk6YixudWxsKQpyZXR1
+cm4gcysiOiB0eXBlICciK0guRWoocikrIicgaXMgbm90IGEgc3VidHlwZSBvZiB0eXBlICciK0guRWoo
+YykrIicifSwKWmM6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILmlNKCJUeXBlRXJyb3I6ICIrYSl9LApx
+OmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILmlNKCJUeXBlRXJyb3I6ICIrSC5XSyhhLG51bGwsYikp
+fSwKa2U6ZnVuY3Rpb24oYSl7cmV0dXJuIGEhPW51bGx9LApUaTpmdW5jdGlvbihhKXtyZXR1cm4gYX0s
+Ckl3OmZ1bmN0aW9uKGEpe3JldHVybiEwfSwKaG46ZnVuY3Rpb24oYSl7cmV0dXJuIGF9LApsOmZ1bmN0
+aW9uKGEpe3JldHVybiEwPT09YXx8ITE9PT1hfSwKcDg6ZnVuY3Rpb24oYSl7aWYoITA9PT1hKXJldHVy
+biEwCmlmKCExPT09YSlyZXR1cm4hMQp0aHJvdyBILmIoSC5xKGEsImJvb2wiKSl9LAp5ODpmdW5jdGlv
+bihhKXtpZighMD09PWEpcmV0dXJuITAKaWYoITE9PT1hKXJldHVybiExCmlmKGE9PW51bGwpcmV0dXJu
+IGEKdGhyb3cgSC5iKEgucShhLCJib29sIikpfSwKZHA6ZnVuY3Rpb24oYSl7aWYoITA9PT1hKXJldHVy
+biEwCmlmKCExPT09YSlyZXR1cm4hMQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihILnEoYSwi
+Ym9vbD8iKSl9LApGRzpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciIpcmV0dXJuIGEKdGhy
+b3cgSC5iKEgucShhLCJkb3VibGUiKSl9LApHSDpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJl
+ciIpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsImRvdWJsZSIpKX0s
+ClFrOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gYQppZihhPT1udWxsKXJl
+dHVybiBhCnRocm93IEguYihILnEoYSwiZG91YmxlPyIpKX0sCm9rOmZ1bmN0aW9uKGEpe3JldHVybiB0
+eXBlb2YgYT09Im51bWJlciImJk1hdGguZmxvb3IoYSk9PT1hfSwKSVo6ZnVuY3Rpb24oYSl7aWYodHlw
+ZW9mIGE9PSJudW1iZXIiJiZNYXRoLmZsb29yKGEpPT09YSlyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEs
+ImludCIpKX0sCnVQOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIiYmTWF0aC5mbG9vcihh
+KT09PWEpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsImludCIpKX0s
+ClVjOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIiYmTWF0aC5mbG9vcihhKT09PWEpcmV0
+dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsImludD8iKSl9LApLSDpmdW5j
+dGlvbihhKXtyZXR1cm4gdHlwZW9mIGE9PSJudW1iZXIifSwKejU6ZnVuY3Rpb24oYSl7aWYodHlwZW9m
+IGE9PSJudW1iZXIiKXJldHVybiBhCnRocm93IEguYihILnEoYSwibnVtIikpfSwKVzE6ZnVuY3Rpb24o
+YSl7aWYodHlwZW9mIGE9PSJudW1iZXIiKXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cg
+SC5iKEgucShhLCJudW0iKSl9LApjVTpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciIpcmV0
+dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsIm51bT8iKSl9LApNTTpmdW5j
+dGlvbihhKXtyZXR1cm4gdHlwZW9mIGE9PSJzdHJpbmcifSwKQnQ6ZnVuY3Rpb24oYSl7aWYodHlwZW9m
+IGE9PSJzdHJpbmciKXJldHVybiBhCnRocm93IEguYihILnEoYSwiU3RyaW5nIikpfSwKaDpmdW5jdGlv
+bihhKXtpZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJv
+dyBILmIoSC5xKGEsIlN0cmluZyIpKX0sCms6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJzdHJpbmci
+KXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cgSC5iKEgucShhLCJTdHJpbmc/IikpfSwK
+aW86ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEKZm9yKHM9IiIscj0iIixxPTA7cTxhLmxlbmd0aDsrK3Es
+cj0iLCAiKXMrPUMueEIuaChyLEguZG0oYVtxXSxiKSkKcmV0dXJuIHN9LApiSTpmdW5jdGlvbihhNSxh
+NixhNyl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQsYyxiLGEsYTAsYTEsYTIsYTMs
+YTQ9IiwgIgppZihhNyE9bnVsbCl7cz1hNy5sZW5ndGgKaWYoYTY9PW51bGwpe2E2PUguVk0oW10sdC5z
+KQpyPW51bGx9ZWxzZSByPWE2Lmxlbmd0aApxPWE2Lmxlbmd0aApmb3IocD1zO3A+MDstLXApQy5ObS5p
+KGE2LCJUIisocStwKSkKZm9yKG89dC5XLG49dC5fLG09dC5LLGw9IjwiLGs9IiIscD0wO3A8czsrK3As
+az1hNCl7bCs9awpqPWE2Lmxlbmd0aAppPWotMS1wCmlmKGk8MClyZXR1cm4gSC5PSChhNixpKQpsPUMu
+eEIuaChsLGE2W2ldKQpoPWE3W3BdCmc9aC55CmlmKCEoZz09PTJ8fGc9PT0zfHxnPT09NHx8Zz09PTV8
+fGg9PT1vKSlpZighKGg9PT1uKSlqPWg9PT1tCmVsc2Ugaj0hMAplbHNlIGo9ITAKaWYoIWopbCs9Qy54
+Qi5oKCIgZXh0ZW5kcyAiLEguZG0oaCxhNikpfWwrPSI+In1lbHNle2w9IiIKcj1udWxsfW89YTUuegpm
+PWE1LlEKZT1mLmEKZD1lLmxlbmd0aApjPWYuYgpiPWMubGVuZ3RoCmE9Zi5jCmEwPWEubGVuZ3RoCmEx
+PUguZG0obyxhNikKZm9yKGEyPSIiLGEzPSIiLHA9MDtwPGQ7KytwLGEzPWE0KWEyKz1DLnhCLmgoYTMs
+SC5kbShlW3BdLGE2KSkKaWYoYj4wKXthMis9YTMrIlsiCmZvcihhMz0iIixwPTA7cDxiOysrcCxhMz1h
+NClhMis9Qy54Qi5oKGEzLEguZG0oY1twXSxhNikpCmEyKz0iXSJ9aWYoYTA+MCl7YTIrPWEzKyJ7Igpm
+b3IoYTM9IiIscD0wO3A8YTA7cCs9MyxhMz1hNCl7YTIrPWEzCmlmKGFbcCsxXSlhMis9InJlcXVpcmVk
+ICIKYTIrPUouYmIoSC5kbShhW3ArMl0sYTYpLCIgIikrYVtwXX1hMis9In0ifWlmKHIhPW51bGwpe2E2
+LnRvU3RyaW5nCmE2Lmxlbmd0aD1yfXJldHVybiBsKyIoIithMisiKSA9PiAiK0guRWooYTEpfSwKZG06
+ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbSxsPWEueQppZihsPT09NSlyZXR1cm4iZXJhc2Vk
+IgppZihsPT09MilyZXR1cm4iZHluYW1pYyIKaWYobD09PTMpcmV0dXJuInZvaWQiCmlmKGw9PT0xKXJl
+dHVybiJOZXZlciIKaWYobD09PTQpcmV0dXJuImFueSIKaWYobD09PTYpe3M9SC5kbShhLnosYikKcmV0
+dXJuIHN9aWYobD09PTcpe3I9YS56CnM9SC5kbShyLGIpCnE9ci55CnJldHVybiBKLmJiKHE9PT0xMXx8
+cT09PTEyP0MueEIuaCgiKCIscykrIikiOnMsIj8iKX1pZihsPT09OClyZXR1cm4iRnV0dXJlT3I8IitI
+LkVqKEguZG0oYS56LGIpKSsiPiIKaWYobD09PTkpe3A9SC5vMyhhLnopCm89YS5RCnJldHVybiBvLmxl
+bmd0aCE9PTA/cCsoIjwiK0guaW8obyxiKSsiPiIpOnB9aWYobD09PTExKXJldHVybiBILmJJKGEsYixu
+dWxsKQppZihsPT09MTIpcmV0dXJuIEguYkkoYS56LGIsYS5RKQppZihsPT09MTMpe2IudG9TdHJpbmcK
+bj1hLnoKbT1iLmxlbmd0aApuPW0tMS1uCmlmKG48MHx8bj49bSlyZXR1cm4gSC5PSChiLG4pCnJldHVy
+biBiW25dfXJldHVybiI/In0sCm8zOmZ1bmN0aW9uKGEpe3ZhciBzLHI9SC5KZyhhKQppZihyIT1udWxs
+KXJldHVybiByCnM9Im1pbmlmaWVkOiIrYQpyZXR1cm4gc30sClFvOmZ1bmN0aW9uKGEsYil7dmFyIHM9
+YS50UltiXQpmb3IoO3R5cGVvZiBzPT0ic3RyaW5nIjspcz1hLnRSW3NdCnJldHVybiBzfSwKYWk6ZnVu
+Y3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG49YS5lVCxtPW5bYl0KaWYobT09bnVsbClyZXR1cm4gSC5F
+KGEsYiwhMSkKZWxzZSBpZih0eXBlb2YgbT09Im51bWJlciIpe3M9bQpyPUgubShhLDUsIiMiKQpxPVtd
+CmZvcihwPTA7cDxzOysrcClxLnB1c2gocikKbz1ILkooYSxiLHEpCm5bYl09bwpyZXR1cm4gb31lbHNl
+IHJldHVybiBtfSwKeGI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSC5JeChhLnRSLGIpfSwKRkY6ZnVuY3Rp
+b24oYSxiKXtyZXR1cm4gSC5JeChhLmVULGIpfSwKRTpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj1hLmVD
+LHE9ci5nZXQoYikKaWYocSE9bnVsbClyZXR1cm4gcQpzPUguaShILm8oYSxudWxsLGIsYykpCnIuc2V0
+KGIscykKcmV0dXJuIHN9LApjRTpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxPWIuY2gKaWYocT09bnVs
+bClxPWIuY2g9bmV3IE1hcCgpCnM9cS5nZXQoYykKaWYocyE9bnVsbClyZXR1cm4gcwpyPUguaShILm8o
+YSxiLGMsITApKQpxLnNldChjLHIpCnJldHVybiByfSwKdjU6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIs
+cSxwPWIuY3gKaWYocD09bnVsbClwPWIuY3g9bmV3IE1hcCgpCnM9Yy5jeQpyPXAuZ2V0KHMpCmlmKHIh
+PW51bGwpcmV0dXJuIHIKcT1ILmEoYSxiLGMueT09PTEwP2MuUTpbY10pCnAuc2V0KHMscSkKcmV0dXJu
+IHF9LApCRDpmdW5jdGlvbihhLGIpe2IuYT1ILkF1CmIuYj1ILkpKCnJldHVybiBifSwKbTpmdW5jdGlv
+bihhLGIsYyl7dmFyIHMscixxPWEuZUMuZ2V0KGMpCmlmKHEhPW51bGwpcmV0dXJuIHEKcz1uZXcgSC5K
+YyhudWxsLG51bGwpCnMueT1iCnMuY3k9YwpyPUguQkQoYSxzKQphLmVDLnNldChjLHIpCnJldHVybiBy
+fSwKQzpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj1iLmN5KyIqIixxPWEuZUMuZ2V0KHIpCmlmKHEhPW51
+bGwpcmV0dXJuIHEKcz1ILlo3KGEsYixyLGMpCmEuZUMuc2V0KHIscykKcmV0dXJuIHN9LApaNzpmdW5j
+dGlvbihhLGIsYyxkKXt2YXIgcyxyLHEKaWYoZCl7cz1iLnkKaWYoIUguQTgoYikpcj1iPT09dC5QfHxi
+PT09dC5UfHxzPT09N3x8cz09PTYKZWxzZSByPSEwCmlmKHIpcmV0dXJuIGJ9cT1uZXcgSC5KYyhudWxs
+LG51bGwpCnEueT02CnEuej1iCnEuY3k9YwpyZXR1cm4gSC5CRChhLHEpfSwKQjpmdW5jdGlvbihhLGIs
+Yyl7dmFyIHMscj1iLmN5KyI/IixxPWEuZUMuZ2V0KHIpCmlmKHEhPW51bGwpcmV0dXJuIHEKcz1ILmxs
+KGEsYixyLGMpCmEuZUMuc2V0KHIscykKcmV0dXJuIHN9LApsbDpmdW5jdGlvbihhLGIsYyxkKXt2YXIg
+cyxyLHEscAppZihkKXtzPWIueQppZighSC5BOChiKSlpZighKGI9PT10LlB8fGI9PT10LlQpKWlmKHMh
+PT03KXI9cz09PTgmJkgubFIoYi56KQplbHNlIHI9ITAKZWxzZSByPSEwCmVsc2Ugcj0hMAppZihyKXJl
+dHVybiBiCmVsc2UgaWYocz09PTF8fGI9PT10LmNGKXJldHVybiB0LlAKZWxzZSBpZihzPT09Nil7cT1i
+LnoKaWYocS55PT09OCYmSC5sUihxLnopKXJldHVybiBxCmVsc2UgcmV0dXJuIEguY3ooYSxiKX19cD1u
+ZXcgSC5KYyhudWxsLG51bGwpCnAueT03CnAuej1iCnAuY3k9YwpyZXR1cm4gSC5CRChhLHApfSwKZjpm
+dW5jdGlvbihhLGIsYyl7dmFyIHMscj1iLmN5KyIvIixxPWEuZUMuZ2V0KHIpCmlmKHEhPW51bGwpcmV0
+dXJuIHEKcz1ILmVWKGEsYixyLGMpCmEuZUMuc2V0KHIscykKcmV0dXJuIHN9LAplVjpmdW5jdGlvbihh
+LGIsYyxkKXt2YXIgcyxyLHEKaWYoZCl7cz1iLnkKaWYoIUguQTgoYikpaWYoIShiPT09dC5fKSlyPWI9
+PT10LksKZWxzZSByPSEwCmVsc2Ugcj0hMAppZihyfHxiPT09dC5LKXJldHVybiBiCmVsc2UgaWYocz09
+PTEpcmV0dXJuIEguSihhLCJiOCIsW2JdKQplbHNlIGlmKGI9PT10LlB8fGI9PT10LlQpcmV0dXJuIHQu
+Ykd9cT1uZXcgSC5KYyhudWxsLG51bGwpCnEueT04CnEuej1iCnEuY3k9YwpyZXR1cm4gSC5CRChhLHEp
+fSwKSDpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT0iIitiKyJeIixwPWEuZUMuZ2V0KHEpCmlmKHAhPW51
+bGwpcmV0dXJuIHAKcz1uZXcgSC5KYyhudWxsLG51bGwpCnMueT0xMwpzLno9YgpzLmN5PXEKcj1ILkJE
+KGEscykKYS5lQy5zZXQocSxyKQpyZXR1cm4gcn0sClV4OmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPWEu
+bGVuZ3RoCmZvcihzPSIiLHI9IiIscT0wO3E8cDsrK3Escj0iLCIpcys9cithW3FdLmN5CnJldHVybiBz
+fSwKUzQ6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG09YS5sZW5ndGgKZm9yKHM9IiIscj0iIixx
+PTA7cTxtO3ErPTMscj0iLCIpe3A9YVtxXQpvPWFbcSsxXT8iISI6IjoiCm49YVtxKzJdLmN5CnMrPXIr
+cCtvK259cmV0dXJuIHN9LApKOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscD1iCmlmKGMubGVuZ3Ro
+IT09MClwKz0iPCIrSC5VeChjKSsiPiIKcz1hLmVDLmdldChwKQppZihzIT1udWxsKXJldHVybiBzCnI9
+bmV3IEguSmMobnVsbCxudWxsKQpyLnk9OQpyLno9YgpyLlE9YwppZihjLmxlbmd0aD4wKXIuYz1jWzBd
+CnIuY3k9cApxPUguQkQoYSxyKQphLmVDLnNldChwLHEpCnJldHVybiBxfSwKYTpmdW5jdGlvbihhLGIs
+Yyl7dmFyIHMscixxLHAsbyxuCmlmKGIueT09PTEwKXtzPWIuegpyPWIuUS5jb25jYXQoYyl9ZWxzZXty
+PWMKcz1ifXE9cy5jeSsoIjs8IitILlV4KHIpKyI+IikKcD1hLmVDLmdldChxKQppZihwIT1udWxsKXJl
+dHVybiBwCm89bmV3IEguSmMobnVsbCxudWxsKQpvLnk9MTAKby56PXMKby5RPXIKby5jeT1xCm49SC5C
+RChhLG8pCmEuZUMuc2V0KHEsbikKcmV0dXJuIG59LApkOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEs
+cCxvLG49Yi5jeSxtPWMuYSxsPW0ubGVuZ3RoLGs9Yy5iLGo9ay5sZW5ndGgsaT1jLmMsaD1pLmxlbmd0
+aCxnPSIoIitILlV4KG0pCmlmKGo+MCl7cz1sPjA/IiwiOiIiCnI9SC5VeChrKQpnKz1zKyJbIityKyJd
+In1pZihoPjApe3M9bD4wPyIsIjoiIgpyPUguUzQoaSkKZys9cysieyIrcisifSJ9cT1uKyhnKyIpIikK
+cD1hLmVDLmdldChxKQppZihwIT1udWxsKXJldHVybiBwCm89bmV3IEguSmMobnVsbCxudWxsKQpvLnk9
+MTEKby56PWIKby5RPWMKby5jeT1xCnI9SC5CRChhLG8pCmEuZUMuc2V0KHEscikKcmV0dXJuIHJ9LApE
+OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHI9Yi5jeSsoIjwiK0guVXgoYykrIj4iKSxxPWEuZUMuZ2V0
+KHIpCmlmKHEhPW51bGwpcmV0dXJuIHEKcz1ILmh3KGEsYixjLHIsZCkKYS5lQy5zZXQocixzKQpyZXR1
+cm4gc30sCmh3OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHMscixxLHAsbyxuLG0sbAppZihlKXtzPWMu
+bGVuZ3RoCnI9bmV3IEFycmF5KHMpCmZvcihxPTAscD0wO3A8czsrK3Ape289Y1twXQppZihvLnk9PT0x
+KXtyW3BdPW87KytxfX1pZihxPjApe249SC5QTChhLGIsciwwKQptPUguYlooYSxjLHIsMCkKcmV0dXJu
+IEguRChhLG4sbSxjIT09bSl9fWw9bmV3IEguSmMobnVsbCxudWxsKQpsLnk9MTIKbC56PWIKbC5RPWMK
+bC5jeT1kCnJldHVybiBILkJEKGEsbCl9LApvOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybnt1OmEsZTpi
+LHI6YyxzOltdLHA6MCxuOmR9fSwKaTpmdW5jdGlvbihhKXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixp
+LGgsZz1hLnIsZj1hLnMKZm9yKHM9Zy5sZW5ndGgscj0wO3I8czspe3E9Zy5jaGFyQ29kZUF0KHIpCmlm
+KHE+PTQ4JiZxPD01NylyPUguQShyKzEscSxnLGYpCmVsc2UgaWYoKCgocXwzMik+Pj4wKS05NyY2NTUz
+NSk8MjZ8fHE9PT05NXx8cT09PTM2KXI9SC50KGEscixnLGYsITEpCmVsc2UgaWYocT09PTQ2KXI9SC50
+KGEscixnLGYsITApCmVsc2V7KytyCnN3aXRjaChxKXtjYXNlIDQ0OmJyZWFrCmNhc2UgNTg6Zi5wdXNo
+KCExKQpicmVhawpjYXNlIDMzOmYucHVzaCghMCkKYnJlYWsKY2FzZSA1OTpmLnB1c2goSC5LKGEudSxh
+LmUsZi5wb3AoKSkpCmJyZWFrCmNhc2UgOTQ6Zi5wdXNoKEguSChhLnUsZi5wb3AoKSkpCmJyZWFrCmNh
+c2UgMzU6Zi5wdXNoKEgubShhLnUsNSwiIyIpKQpicmVhawpjYXNlIDY0OmYucHVzaChILm0oYS51LDIs
+IkAiKSkKYnJlYWsKY2FzZSAxMjY6Zi5wdXNoKEgubShhLnUsMywifiIpKQpicmVhawpjYXNlIDYwOmYu
+cHVzaChhLnApCmEucD1mLmxlbmd0aApicmVhawpjYXNlIDYyOnA9YS51Cm89Zi5zcGxpY2UoYS5wKQpI
+LnIoYS51LGEuZSxvKQphLnA9Zi5wb3AoKQpuPWYucG9wKCkKaWYodHlwZW9mIG49PSJzdHJpbmciKWYu
+cHVzaChILkoocCxuLG8pKQplbHNle209SC5LKHAsYS5lLG4pCnN3aXRjaChtLnkpe2Nhc2UgMTE6Zi5w
+dXNoKEguRChwLG0sbyxhLm4pKQpicmVhawpkZWZhdWx0OmYucHVzaChILmEocCxtLG8pKQpicmVha319
+YnJlYWsKY2FzZSAzODpILkkoYSxmKQpicmVhawpjYXNlIDQyOmw9YS51CmYucHVzaChILkMobCxILkso
+bCxhLmUsZi5wb3AoKSksYS5uKSkKYnJlYWsKY2FzZSA2MzpsPWEudQpmLnB1c2goSC5CKGwsSC5LKGws
+YS5lLGYucG9wKCkpLGEubikpCmJyZWFrCmNhc2UgNDc6bD1hLnUKZi5wdXNoKEguZihsLEguSyhsLGEu
+ZSxmLnBvcCgpKSxhLm4pKQpicmVhawpjYXNlIDQwOmYucHVzaChhLnApCmEucD1mLmxlbmd0aApicmVh
+awpjYXNlIDQxOnA9YS51Cms9bmV3IEguRygpCmo9cC5zRUEKaT1wLnNFQQpuPWYucG9wKCkKaWYodHlw
+ZW9mIG49PSJudW1iZXIiKXN3aXRjaChuKXtjYXNlLTE6aj1mLnBvcCgpCmJyZWFrCmNhc2UtMjppPWYu
+cG9wKCkKYnJlYWsKZGVmYXVsdDpmLnB1c2gobikKYnJlYWt9ZWxzZSBmLnB1c2gobikKbz1mLnNwbGlj
+ZShhLnApCkgucihhLnUsYS5lLG8pCmEucD1mLnBvcCgpCmsuYT1vCmsuYj1qCmsuYz1pCmYucHVzaChI
+LmQocCxILksocCxhLmUsZi5wb3AoKSksaykpCmJyZWFrCmNhc2UgOTE6Zi5wdXNoKGEucCkKYS5wPWYu
+bGVuZ3RoCmJyZWFrCmNhc2UgOTM6bz1mLnNwbGljZShhLnApCkgucihhLnUsYS5lLG8pCmEucD1mLnBv
+cCgpCmYucHVzaChvKQpmLnB1c2goLTEpCmJyZWFrCmNhc2UgMTIzOmYucHVzaChhLnApCmEucD1mLmxl
+bmd0aApicmVhawpjYXNlIDEyNTpvPWYuc3BsaWNlKGEucCkKSC55KGEudSxhLmUsbykKYS5wPWYucG9w
+KCkKZi5wdXNoKG8pCmYucHVzaCgtMikKYnJlYWsKZGVmYXVsdDp0aHJvdyJCYWQgY2hhcmFjdGVyICIr
+cX19fWg9Zi5wb3AoKQpyZXR1cm4gSC5LKGEudSxhLmUsaCl9LApBOmZ1bmN0aW9uKGEsYixjLGQpe3Zh
+ciBzLHIscT1iLTQ4CmZvcihzPWMubGVuZ3RoO2E8czsrK2Epe3I9Yy5jaGFyQ29kZUF0KGEpCmlmKCEo
+cj49NDgmJnI8PTU3KSlicmVhawpxPXEqMTArKHItNDgpfWQucHVzaChxKQpyZXR1cm4gYX0sCnQ6ZnVu
+Y3Rpb24oYSxiLGMsZCxlKXt2YXIgcyxyLHEscCxvLG4sbT1iKzEKZm9yKHM9Yy5sZW5ndGg7bTxzOysr
+bSl7cj1jLmNoYXJDb2RlQXQobSkKaWYocj09PTQ2KXtpZihlKWJyZWFrCmU9ITB9ZWxzZXtpZighKCgo
+KHJ8MzIpPj4+MCktOTcmNjU1MzUpPDI2fHxyPT09OTV8fHI9PT0zNikpcT1yPj00OCYmcjw9NTcKZWxz
+ZSBxPSEwCmlmKCFxKWJyZWFrfX1wPWMuc3Vic3RyaW5nKGIsbSkKaWYoZSl7cz1hLnUKbz1hLmUKaWYo
+by55PT09MTApbz1vLnoKbj1ILlFvKHMsby56KVtwXQppZihuPT1udWxsKUgudignTm8gIicrcCsnIiBp
+biAiJytILm1EKG8pKyciJykKZC5wdXNoKEguY0UocyxvLG4pKX1lbHNlIGQucHVzaChwKQpyZXR1cm4g
+bX0sCkk6ZnVuY3Rpb24oYSxiKXt2YXIgcz1iLnBvcCgpCmlmKDA9PT1zKXtiLnB1c2goSC5tKGEudSwx
+LCIwJiIpKQpyZXR1cm59aWYoMT09PXMpe2IucHVzaChILm0oYS51LDQsIjEmIikpCnJldHVybn10aHJv
+dyBILmIoUC5oVigiVW5leHBlY3RlZCBleHRlbmRlZCBvcGVyYXRpb24gIitILkVqKHMpKSl9LApLOmZ1
+bmN0aW9uKGEsYixjKXtpZih0eXBlb2YgYz09InN0cmluZyIpcmV0dXJuIEguSihhLGMsYS5zRUEpCmVs
+c2UgaWYodHlwZW9mIGM9PSJudW1iZXIiKXJldHVybiBILlRWKGEsYixjKQplbHNlIHJldHVybiBjfSwK
+cjpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj1jLmxlbmd0aApmb3Iocz0wO3M8cjsrK3MpY1tzXT1ILkso
+YSxiLGNbc10pfSwKeTpmdW5jdGlvbihhLGIsYyl7dmFyIHMscj1jLmxlbmd0aApmb3Iocz0yO3M8cjtz
+Kz0zKWNbc109SC5LKGEsYixjW3NdKX0sClRWOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHE9Yi55Cmlm
+KHE9PT0xMCl7aWYoYz09PTApcmV0dXJuIGIuegpzPWIuUQpyPXMubGVuZ3RoCmlmKGM8PXIpcmV0dXJu
+IHNbYy0xXQpjLT1yCmI9Yi56CnE9Yi55fWVsc2UgaWYoYz09PTApcmV0dXJuIGIKaWYocSE9PTkpdGhy
+b3cgSC5iKFAuaFYoIkluZGV4ZWQgYmFzZSBtdXN0IGJlIGFuIGludGVyZmFjZSB0eXBlIikpCnM9Yi5R
+CmlmKGM8PXMubGVuZ3RoKXJldHVybiBzW2MtMV0KdGhyb3cgSC5iKFAuaFYoIkJhZCBpbmRleCAiK2Mr
+IiBmb3IgIitiLncoMCkpKX0sCldlOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHMscixxLHAsbyxuLG0s
+bCxrLGoKaWYoYj09PWQpcmV0dXJuITAKaWYoIUguQTgoZCkpaWYoIShkPT09dC5fKSlzPWQ9PT10LksK
+ZWxzZSBzPSEwCmVsc2Ugcz0hMAppZihzKXJldHVybiEwCnI9Yi55CmlmKHI9PT00KXJldHVybiEwCmlm
+KEguQTgoYikpcmV0dXJuITEKaWYoYi55IT09MSlzPWI9PT10LlB8fGI9PT10LlQKZWxzZSBzPSEwCmlm
+KHMpcmV0dXJuITAKcT1yPT09MTMKaWYocSlpZihILldlKGEsY1tiLnpdLGMsZCxlKSlyZXR1cm4hMApw
+PWQueQppZihyPT09NilyZXR1cm4gSC5XZShhLGIueixjLGQsZSkKaWYocD09PTYpe3M9ZC56CnJldHVy
+biBILldlKGEsYixjLHMsZSl9aWYocj09PTgpe2lmKCFILldlKGEsYi56LGMsZCxlKSlyZXR1cm4hMQpy
+ZXR1cm4gSC5XZShhLEgueFooYSxiKSxjLGQsZSl9aWYocj09PTcpe3M9SC5XZShhLGIueixjLGQsZSkK
+cmV0dXJuIHN9aWYocD09PTgpe2lmKEguV2UoYSxiLGMsZC56LGUpKXJldHVybiEwCnJldHVybiBILldl
+KGEsYixjLEgueFooYSxkKSxlKX1pZihwPT09Nyl7cz1ILldlKGEsYixjLGQueixlKQpyZXR1cm4gc31p
+ZihxKXJldHVybiExCnM9ciE9PTExCmlmKCghc3x8cj09PTEyKSYmZD09PXQuWSlyZXR1cm4hMAppZihw
+PT09MTIpe2lmKGI9PT10LkQpcmV0dXJuITAKaWYociE9PTEyKXJldHVybiExCm89Yi5RCm49ZC5RCm09
+by5sZW5ndGgKaWYobSE9PW4ubGVuZ3RoKXJldHVybiExCmM9Yz09bnVsbD9vOm8uY29uY2F0KGMpCmU9
+ZT09bnVsbD9uOm4uY29uY2F0KGUpCmZvcihsPTA7bDxtOysrbCl7az1vW2xdCmo9bltsXQppZighSC5X
+ZShhLGssYyxqLGUpfHwhSC5XZShhLGosZSxrLGMpKXJldHVybiExfXJldHVybiBILmJPKGEsYi56LGMs
+ZC56LGUpfWlmKHA9PT0xMSl7aWYoYj09PXQuRClyZXR1cm4hMAppZihzKXJldHVybiExCnJldHVybiBI
+LmJPKGEsYixjLGQsZSl9aWYocj09PTkpe2lmKHAhPT05KXJldHVybiExCnJldHVybiBILnBHKGEsYixj
+LGQsZSl9cmV0dXJuITF9LApiTzpmdW5jdGlvbihhMixhMyxhNCxhNSxhNil7dmFyIHMscixxLHAsbyxu
+LG0sbCxrLGosaSxoLGcsZixlLGQsYyxiLGEsYTAsYTEKaWYoIUguV2UoYTIsYTMueixhNCxhNS56LGE2
+KSlyZXR1cm4hMQpzPWEzLlEKcj1hNS5RCnE9cy5hCnA9ci5hCm89cS5sZW5ndGgKbj1wLmxlbmd0aApp
+ZihvPm4pcmV0dXJuITEKbT1uLW8KbD1zLmIKaz1yLmIKaj1sLmxlbmd0aAppPWsubGVuZ3RoCmlmKG8r
+ajxuK2kpcmV0dXJuITEKZm9yKGg9MDtoPG87KytoKXtnPXFbaF0KaWYoIUguV2UoYTIscFtoXSxhNixn
+LGE0KSlyZXR1cm4hMX1mb3IoaD0wO2g8bTsrK2gpe2c9bFtoXQppZighSC5XZShhMixwW28raF0sYTYs
+ZyxhNCkpcmV0dXJuITF9Zm9yKGg9MDtoPGk7KytoKXtnPWxbbStoXQppZighSC5XZShhMixrW2hdLGE2
+LGcsYTQpKXJldHVybiExfWY9cy5jCmU9ci5jCmQ9Zi5sZW5ndGgKYz1lLmxlbmd0aApmb3IoYj0wLGE9
+MDthPGM7YSs9Myl7YTA9ZVthXQpmb3IoOyEwOyl7aWYoYj49ZClyZXR1cm4hMQphMT1mW2JdCmIrPTMK
+aWYoYTA8YTEpcmV0dXJuITEKaWYoYTE8YTApY29udGludWUKZz1mW2ItMV0KaWYoIUguV2UoYTIsZVth
+KzJdLGE2LGcsYTQpKXJldHVybiExCmJyZWFrfX1yZXR1cm4hMH0sCnBHOmZ1bmN0aW9uKGEsYixjLGQs
+ZSl7dmFyIHMscixxLHAsbyxuLG0sbCxrPWIueixqPWQuegppZihrPT09ail7cz1iLlEKcj1kLlEKcT1z
+Lmxlbmd0aApmb3IocD0wO3A8cTsrK3Ape289c1twXQpuPXJbcF0KaWYoIUguV2UoYSxvLGMsbixlKSly
+ZXR1cm4hMX1yZXR1cm4hMH1pZihkPT09dC5LKXJldHVybiEwCm09SC5RbyhhLGspCmlmKG09PW51bGwp
+cmV0dXJuITEKbD1tW2pdCmlmKGw9PW51bGwpcmV0dXJuITEKcT1sLmxlbmd0aApyPWQuUQpmb3IocD0w
+O3A8cTsrK3ApaWYoIUguV2UoYSxILmNFKGEsYixsW3BdKSxjLHJbcF0sZSkpcmV0dXJuITEKcmV0dXJu
+ITB9LApsUjpmdW5jdGlvbihhKXt2YXIgcyxyPWEueQppZighKGE9PT10LlB8fGE9PT10LlQpKWlmKCFI
+LkE4KGEpKWlmKHIhPT03KWlmKCEocj09PTYmJkgubFIoYS56KSkpcz1yPT09OCYmSC5sUihhLnopCmVs
+c2Ugcz0hMAplbHNlIHM9ITAKZWxzZSBzPSEwCmVsc2Ugcz0hMApyZXR1cm4gc30sCmNjOmZ1bmN0aW9u
+KGEpe3ZhciBzCmlmKCFILkE4KGEpKWlmKCEoYT09PXQuXykpcz1hPT09dC5LCmVsc2Ugcz0hMAplbHNl
+IHM9ITAKcmV0dXJuIHN9LApBODpmdW5jdGlvbihhKXt2YXIgcz1hLnkKcmV0dXJuIHM9PT0yfHxzPT09
+M3x8cz09PTR8fHM9PT01fHxhPT09dC5XfSwKSXg6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHE9T2JqZWN0
+LmtleXMoYikscD1xLmxlbmd0aApmb3Iocz0wO3M8cDsrK3Mpe3I9cVtzXQphW3JdPWJbcl19fSwKSmM6
+ZnVuY3Rpb24gSmMoYSxiKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8ueD1fLnI9Xy5jPW51bGwKXy55
+PTAKXy5jeT1fLmN4PV8uY2g9Xy5RPV8uej1udWxsfSwKRzpmdW5jdGlvbiBHKCl7dGhpcy5jPXRoaXMu
+Yj10aGlzLmE9bnVsbH0sCmxZOmZ1bmN0aW9uIGxZKGEpe3RoaXMuYT1hfSwKa1M6ZnVuY3Rpb24ga1Mo
+KXt9LAppTTpmdW5jdGlvbiBpTShhKXt0aGlzLmE9YX0sClI5OmZ1bmN0aW9uKGEpe3JldHVybiB0Lncu
+YihhKXx8dC5CLmIoYSl8fHQuZHouYihhKXx8dC5JLmIoYSl8fHQuQS5iKGEpfHx0Lmc0LmIoYSl8fHQu
+ZzIuYihhKX0sCkpnOmZ1bmN0aW9uKGEpe3JldHVybiB2Lm1hbmdsZWRHbG9iYWxOYW1lc1thXX19LEo9
+ewpRdTpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm57aTphLHA6YixlOmMseDpkfX0sCmtzOmZ1bmN0aW9u
+KGEpe3ZhciBzLHIscSxwLG89YVt2LmRpc3BhdGNoUHJvcGVydHlOYW1lXQppZihvPT1udWxsKWlmKCQu
+QnY9PW51bGwpe0guWEQoKQpvPWFbdi5kaXNwYXRjaFByb3BlcnR5TmFtZV19aWYobyE9bnVsbCl7cz1v
+LnAKaWYoITE9PT1zKXJldHVybiBvLmkKaWYoITA9PT1zKXJldHVybiBhCnI9T2JqZWN0LmdldFByb3Rv
+dHlwZU9mKGEpCmlmKHM9PT1yKXJldHVybiBvLmkKaWYoby5lPT09cil0aHJvdyBILmIoUC5TWSgiUmV0
+dXJuIGludGVyY2VwdG9yIGZvciAiK0guRWoocyhhLG8pKSkpfXE9YS5jb25zdHJ1Y3RvcgpwPXE9PW51
+bGw/bnVsbDpxW0ouUlAoKV0KaWYocCE9bnVsbClyZXR1cm4gcApwPUgudzMoYSkKaWYocCE9bnVsbCly
+ZXR1cm4gcAppZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gQy5ERwpzPU9iamVjdC5nZXRQcm90
+b3R5cGVPZihhKQppZihzPT1udWxsKXJldHVybiBDLlpRCmlmKHM9PT1PYmplY3QucHJvdG90eXBlKXJl
+dHVybiBDLlpRCmlmKHR5cGVvZiBxPT0iZnVuY3Rpb24iKXtPYmplY3QuZGVmaW5lUHJvcGVydHkocSxK
+LlJQKCkse3ZhbHVlOkMudkIsZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJs
+ZTp0cnVlfSkKcmV0dXJuIEMudkJ9cmV0dXJuIEMudkJ9LApSUDpmdW5jdGlvbigpe3ZhciBzPSQuem0K
+cmV0dXJuIHM9PW51bGw/JC56bT12LmdldElzb2xhdGVUYWcoIl8kZGFydF9qcyIpOnN9LApRaTpmdW5j
+dGlvbihhLGIpe2lmKGE8MHx8YT40Mjk0OTY3Mjk1KXRocm93IEguYihQLlRFKGEsMCw0Mjk0OTY3Mjk1
+LCJsZW5ndGgiLG51bGwpKQpyZXR1cm4gSi5weShuZXcgQXJyYXkoYSksYil9LApLaDpmdW5jdGlvbihh
+LGIpe2lmKGE8MCl0aHJvdyBILmIoUC54WSgiTGVuZ3RoIG11c3QgYmUgYSBub24tbmVnYXRpdmUgaW50
+ZWdlcjogIithKSkKcmV0dXJuIEguVk0obmV3IEFycmF5KGEpLGIuQygiamQ8MD4iKSl9LApweTpmdW5j
+dGlvbihhLGIpe3JldHVybiBKLkVwKEguVk0oYSxiLkMoImpkPDA+IikpLGIpfSwKRXA6ZnVuY3Rpb24o
+YSxiKXthLmZpeGVkJGxlbmd0aD1BcnJheQpyZXR1cm4gYX0sCnpDOmZ1bmN0aW9uKGEpe2EuZml4ZWQk
+bGVuZ3RoPUFycmF5CmEuaW1tdXRhYmxlJGxpc3Q9QXJyYXkKcmV0dXJuIGF9LApHYTpmdW5jdGlvbihh
+KXtpZihhPDI1Nilzd2l0Y2goYSl7Y2FzZSA5OmNhc2UgMTA6Y2FzZSAxMTpjYXNlIDEyOmNhc2UgMTM6
+Y2FzZSAzMjpjYXNlIDEzMzpjYXNlIDE2MDpyZXR1cm4hMApkZWZhdWx0OnJldHVybiExfXN3aXRjaChh
+KXtjYXNlIDU3NjA6Y2FzZSA4MTkyOmNhc2UgODE5MzpjYXNlIDgxOTQ6Y2FzZSA4MTk1OmNhc2UgODE5
+NjpjYXNlIDgxOTc6Y2FzZSA4MTk4OmNhc2UgODE5OTpjYXNlIDgyMDA6Y2FzZSA4MjAxOmNhc2UgODIw
+MjpjYXNlIDgyMzI6Y2FzZSA4MjMzOmNhc2UgODIzOTpjYXNlIDgyODc6Y2FzZSAxMjI4ODpjYXNlIDY1
+Mjc5OnJldHVybiEwCmRlZmF1bHQ6cmV0dXJuITF9fSwKbW06ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCmZv
+cihzPWEubGVuZ3RoO2I8czspe3I9Qy54Qi5XKGEsYikKaWYociE9PTMyJiZyIT09MTMmJiFKLkdhKHIp
+KWJyZWFrOysrYn1yZXR1cm4gYn0sCmMxOmZ1bmN0aW9uKGEsYil7dmFyIHMscgpmb3IoO2I+MDtiPXMp
+e3M9Yi0xCnI9Qy54Qi5PMihhLHMpCmlmKHIhPT0zMiYmciE9PTEzJiYhSi5HYShyKSlicmVha31yZXR1
+cm4gYn0sClRKOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gSi5xSS5wcm90
+b3R5cGUKaWYodHlwZW9mIGE9PSJzdHJpbmciKXJldHVybiBKLkRyLnByb3RvdHlwZQppZihhPT1udWxs
+KXJldHVybiBhCmlmKGEuY29uc3RydWN0b3I9PUFycmF5KXJldHVybiBKLmpkLnByb3RvdHlwZQppZih0
+eXBlb2YgYSE9Im9iamVjdCIpe2lmKHR5cGVvZiBhPT0iZnVuY3Rpb24iKXJldHVybiBKLmM1LnByb3Rv
+dHlwZQpyZXR1cm4gYX1pZihhIGluc3RhbmNlb2YgUC5NaClyZXR1cm4gYQpyZXR1cm4gSi5rcyhhKX0s
+ClU2OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gSi5Eci5wcm90b3R5cGUK
+aWYoYT09bnVsbClyZXR1cm4gYQppZihhLmNvbnN0cnVjdG9yPT1BcnJheSlyZXR1cm4gSi5qZC5wcm90
+b3R5cGUKaWYodHlwZW9mIGEhPSJvYmplY3QiKXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4g
+Si5jNS5wcm90b3R5cGUKcmV0dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAuTWgpcmV0dXJuIGEKcmV0dXJu
+IEoua3MoYSl9LApZRTpmdW5jdGlvbihhKXtpZihhPT1udWxsKXJldHVybiBhCmlmKHR5cGVvZiBhIT0i
+b2JqZWN0Iil7aWYodHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIEouYzUucHJvdG90eXBlCnJldHVy
+biBhfWlmKGEgaW5zdGFuY2VvZiBQLk1oKXJldHVybiBhCnJldHVybiBKLmtzKGEpfSwKaWE6ZnVuY3Rp
+b24oYSl7aWYodHlwZW9mIGE9PSJudW1iZXIiKXtpZihNYXRoLmZsb29yKGEpPT1hKXJldHVybiBKLmJV
+LnByb3RvdHlwZQpyZXR1cm4gSi5WQS5wcm90b3R5cGV9aWYodHlwZW9mIGE9PSJzdHJpbmciKXJldHVy
+biBKLkRyLnByb3RvdHlwZQppZihhPT1udWxsKXJldHVybiBKLndlLnByb3RvdHlwZQppZih0eXBlb2Yg
+YT09ImJvb2xlYW4iKXJldHVybiBKLnlFLnByb3RvdHlwZQppZihhLmNvbnN0cnVjdG9yPT1BcnJheSly
+ZXR1cm4gSi5qZC5wcm90b3R5cGUKaWYodHlwZW9mIGEhPSJvYmplY3QiKXtpZih0eXBlb2YgYT09ImZ1
+bmN0aW9uIilyZXR1cm4gSi5jNS5wcm90b3R5cGUKcmV0dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAuTWgp
+cmV0dXJuIGEKcmV0dXJuIEoua3MoYSl9LApyWTpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09InN0cmlu
+ZyIpcmV0dXJuIEouRHIucHJvdG90eXBlCmlmKGE9PW51bGwpcmV0dXJuIGEKaWYoIShhIGluc3RhbmNl
+b2YgUC5NaCkpcmV0dXJuIEoua2QucHJvdG90eXBlCnJldHVybiBhfSwKdmQ6ZnVuY3Rpb24oYSl7aWYo
+dHlwZW9mIGE9PSJudW1iZXIiKXJldHVybiBKLnFJLnByb3RvdHlwZQppZihhPT1udWxsKXJldHVybiBh
+CmlmKCEoYSBpbnN0YW5jZW9mIFAuTWgpKXJldHVybiBKLmtkLnByb3RvdHlwZQpyZXR1cm4gYX0sCncx
+OmZ1bmN0aW9uKGEpe2lmKGE9PW51bGwpcmV0dXJuIGEKaWYoYS5jb25zdHJ1Y3Rvcj09QXJyYXkpcmV0
+dXJuIEouamQucHJvdG90eXBlCmlmKHR5cGVvZiBhIT0ib2JqZWN0Iil7aWYodHlwZW9mIGE9PSJmdW5j
+dGlvbiIpcmV0dXJuIEouYzUucHJvdG90eXBlCnJldHVybiBhfWlmKGEgaW5zdGFuY2VvZiBQLk1oKXJl
+dHVybiBhCnJldHVybiBKLmtzKGEpfSwKQTU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi53MShhKS5lUihh
+LGIpfSwKRWg6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBKLllFKGEpLm1LKGEsYixjKX0sCkVsOmZ1bmN0
+aW9uKGEsYil7cmV0dXJuIEoudzEoYSkuZHIoYSxiKX0sCkY3OmZ1bmN0aW9uKGEpe3JldHVybiBKLlU2
+KGEpLmdvcihhKX0sCkZMOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouclkoYSkuZGQoYSxiKX0sCkdBOmZ1
+bmN0aW9uKGEsYil7cmV0dXJuIEoudzEoYSkuRShhLGIpfSwKSG06ZnVuY3Rpb24oYSl7cmV0dXJuIEou
+VTYoYSkuZ0EoYSl9LApJVDpmdW5jdGlvbihhKXtyZXR1cm4gSi53MShhKS5nbShhKX0sCkp5OmZ1bmN0
+aW9uKGEsYil7cmV0dXJuIEouaWEoYSkuZTcoYSxiKX0sCktWOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEou
+clkoYSkueW4oYSxiKX0sCkx0OmZ1bmN0aW9uKGEpe3JldHVybiBKLllFKGEpLndnKGEpfSwKTTE6ZnVu
+Y3Rpb24oYSxiLGMpe3JldHVybiBKLncxKGEpLkUyKGEsYixjKX0sCk11OmZ1bmN0aW9uKGEsYil7cmV0
+dXJuIEouWUUoYSkuc24oYSxiKX0sClF6OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouclkoYSkuVyhhLGIp
+fSwKUk06ZnVuY3Rpb24oYSxiKXtpZihhPT1udWxsKXJldHVybiBiPT1udWxsCmlmKHR5cGVvZiBhIT0i
+b2JqZWN0IilyZXR1cm4gYiE9bnVsbCYmYT09PWIKcmV0dXJuIEouaWEoYSkuRE4oYSxiKX0sClJYOmZ1
+bmN0aW9uKGEpe3JldHVybiBKLncxKGEpLmJyKGEpfSwKVDA6ZnVuY3Rpb24oYSl7cmV0dXJuIEouclko
+YSkuYlMoYSl9LApWdTpmdW5jdGlvbihhKXtyZXR1cm4gSi52ZChhKS56UShhKX0sCmE2OmZ1bmN0aW9u
+KGEsYil7cmV0dXJuIEouclkoYSkuTzIoYSxiKX0sCmJUOmZ1bmN0aW9uKGEpe3JldHVybiBKLllFKGEp
+LkQ0KGEpfSwKYmI6ZnVuY3Rpb24oYSxiKXtpZih0eXBlb2YgYT09Im51bWJlciImJnR5cGVvZiBiPT0i
+bnVtYmVyIilyZXR1cm4gYStiCnJldHVybiBKLlRKKGEpLmgoYSxiKX0sCmNIOmZ1bmN0aW9uKGEpe3Jl
+dHVybiBKLnJZKGEpLmhjKGEpfSwKZFI6ZnVuY3Rpb24oYSl7cmV0dXJuIEouWUUoYSkuZ24oYSl9LApk
+WjpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gSi5ZRShhKS5PbihhLGIsYyxkKX0sCmRnOmZ1bmN0aW9u
+KGEsYixjLGQpe3JldHVybiBKLnJZKGEpLmk3KGEsYixjLGQpfSwKZGg6ZnVuY3Rpb24oYSl7cmV0dXJu
+IEouWUUoYSkuRkYoYSl9LApkcjpmdW5jdGlvbihhLGIpe3JldHVybiBKLllFKGEpLnNhNChhLGIpfSwK
+aGY6ZnVuY3Rpb24oYSl7cmV0dXJuIEouaWEoYSkuZ2lPKGEpfSwKaWc6ZnVuY3Rpb24oYSl7cmV0dXJu
+IEouWUUoYSkuZ1FnKGEpfSwKajpmdW5jdGlvbihhKXtyZXR1cm4gSi5pYShhKS53KGEpfSwKbDU6ZnVu
+Y3Rpb24oYSxiKXtyZXR1cm4gSi5ZRShhKS5zaGYoYSxiKX0sCmxkOmZ1bmN0aW9uKGEsYixjKXtyZXR1
+cm4gSi5yWShhKS5OaihhLGIsYyl9LApwNDpmdW5jdGlvbihhLGIpe3JldHVybiBKLnJZKGEpLlRjKGEs
+Yil9LApxMDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEouclkoYSkuUWkoYSxiLGMpfSwKcUY6ZnVuY3Rp
+b24oYSl7cmV0dXJuIEouWUUoYSkuZ1ZsKGEpfSwKdEg6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBKLllF
+KGEpLnBrKGEsYixjKX0sCnU5OmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSi53MShhKS5ZNShhLGIsYyl9
+LAp1VTpmdW5jdGlvbihhKXtyZXR1cm4gSi5VNihhKS5nbDAoYSl9LAp3ZjpmdW5jdGlvbihhLGIpe3Jl
+dHVybiBKLllFKGEpLnNSTihhLGIpfSwKeDk6ZnVuY3Rpb24oYSxiKXtpZih0eXBlb2YgYj09PSJudW1i
+ZXIiKWlmKGEuY29uc3RydWN0b3I9PUFycmF5fHx0eXBlb2YgYT09InN0cmluZyJ8fEgud1YoYSxhW3Yu
+ZGlzcGF0Y2hQcm9wZXJ0eU5hbWVdKSlpZihiPj4+MD09PWImJmI8YS5sZW5ndGgpcmV0dXJuIGFbYl0K
+cmV0dXJuIEouVTYoYSkucShhLGIpfSwKemw6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5VNihhKS50Zyhh
+LGIpfSwKR3Y6ZnVuY3Rpb24gR3YoKXt9LAp5RTpmdW5jdGlvbiB5RSgpe30sCndlOmZ1bmN0aW9uIHdl
+KCl7fSwKTUY6ZnVuY3Rpb24gTUYoKXt9LAppQzpmdW5jdGlvbiBpQygpe30sCmtkOmZ1bmN0aW9uIGtk
+KCl7fSwKYzU6ZnVuY3Rpb24gYzUoKXt9LApqZDpmdW5jdGlvbiBqZChhKXt0aGlzLiR0aT1hfSwKUG86
+ZnVuY3Rpb24gUG8oYSl7dGhpcy4kdGk9YX0sCm0xOmZ1bmN0aW9uIG0xKGEsYixjKXt2YXIgXz10aGlz
+Cl8uYT1hCl8uYj1iCl8uYz0wCl8uZD1udWxsCl8uJHRpPWN9LApxSTpmdW5jdGlvbiBxSSgpe30sCmJV
+OmZ1bmN0aW9uIGJVKCl7fSwKVkE6ZnVuY3Rpb24gVkEoKXt9LApEcjpmdW5jdGlvbiBEcigpe319LFA9
+ewpPajpmdW5jdGlvbigpe3ZhciBzLHIscT17fQppZihzZWxmLnNjaGVkdWxlSW1tZWRpYXRlIT1udWxs
+KXJldHVybiBQLkVYKCkKaWYoc2VsZi5NdXRhdGlvbk9ic2VydmVyIT1udWxsJiZzZWxmLmRvY3VtZW50
+IT1udWxsKXtzPXNlbGYuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZGl2IikKcj1zZWxmLmRvY3VtZW50
+LmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpxLmE9bnVsbApuZXcgc2VsZi5NdXRhdGlvbk9ic2VydmVyKEgu
+dFIobmV3IFAudGgocSksMSkpLm9ic2VydmUocyx7Y2hpbGRMaXN0OnRydWV9KQpyZXR1cm4gbmV3IFAu
+aGEocSxzLHIpfWVsc2UgaWYoc2VsZi5zZXRJbW1lZGlhdGUhPW51bGwpcmV0dXJuIFAueXQoKQpyZXR1
+cm4gUC5xVygpfSwKWlY6ZnVuY3Rpb24oYSl7c2VsZi5zY2hlZHVsZUltbWVkaWF0ZShILnRSKG5ldyBQ
+LlZzKHQuTS5hKGEpKSwwKSl9LApvQTpmdW5jdGlvbihhKXtzZWxmLnNldEltbWVkaWF0ZShILnRSKG5l
+dyBQLkZ0KHQuTS5hKGEpKSwwKSl9LApCejpmdW5jdGlvbihhKXt0Lk0uYShhKQpQLlFOKDAsYSl9LApR
+TjpmdW5jdGlvbihhLGIpe3ZhciBzPW5ldyBQLlczKCkKcy5DWShhLGIpCnJldHVybiBzfSwKRlg6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIG5ldyBQLmloKG5ldyBQLnZzKCQuWDMsYS5DKCJ2czwwPiIpKSxhLkMoImlo
+PDA+IikpfSwKREk6ZnVuY3Rpb24oYSxiKXthLiQyKDAsbnVsbCkKYi5iPSEwCnJldHVybiBiLmF9LApq
+UTpmdW5jdGlvbihhLGIpe1AuSmUoYSxiKX0sCnlDOmZ1bmN0aW9uKGEsYil7Yi5hTSgwLGEpfSwKZjM6
+ZnVuY3Rpb24oYSxiKXtiLncwKEguUnUoYSksSC50cyhhKSl9LApKZTpmdW5jdGlvbihhLGIpe3ZhciBz
+LHIscT1uZXcgUC5XTShiKSxwPW5ldyBQLlNYKGIpCmlmKGEgaW5zdGFuY2VvZiBQLnZzKWEuUWQocSxw
+LHQueikKZWxzZXtzPXQuegppZih0LmQuYihhKSlhLlNxKHEscCxzKQplbHNle3I9bmV3IFAudnMoJC5Y
+Myx0LmMpCnIuYT00CnIuYz1hCnIuUWQocSxwLHMpfX19LApsejpmdW5jdGlvbihhKXt2YXIgcz1mdW5j
+dGlvbihiLGMpe3JldHVybiBmdW5jdGlvbihkLGUpe3doaWxlKHRydWUpdHJ5e2IoZCxlKQpicmVha31j
+YXRjaChyKXtlPXIKZD1jfX19KGEsMSkKcmV0dXJuICQuWDMuTGoobmV3IFAuR3MocyksdC5ILHQuUyx0
+LnopfSwKSUc6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLkZ5KGEsMSl9LApUaDpmdW5jdGlvbigpe3Jl
+dHVybiBDLndRfSwKWW06ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLkZ5KGEsMyl9LApsMDpmdW5jdGlv
+bihhLGIpe3JldHVybiBuZXcgUC5xNChhLGIuQygicTQ8MD4iKSl9LAprMzpmdW5jdGlvbihhLGIpe3Zh
+ciBzLHIscQpiLmE9MQp0cnl7YS5TcShuZXcgUC5wVihiKSxuZXcgUC5VNyhiKSx0LlApfWNhdGNoKHEp
+e3M9SC5SdShxKQpyPUgudHMocSkKUC5yYihuZXcgUC52cihiLHMscikpfX0sCkE5OmZ1bmN0aW9uKGEs
+Yil7dmFyIHMscixxCmZvcihzPXQuYztyPWEuYSxyPT09MjspYT1zLmEoYS5jKQppZihyPj00KXtxPWIu
+YWgoKQpiLmE9YS5hCmIuYz1hLmMKUC5IWihiLHEpfWVsc2V7cT10LkYuYShiLmMpCmIuYT0yCmIuYz1h
+CmEualEocSl9fSwKSFo6ZnVuY3Rpb24oYTAsYTEpe3ZhciBzLHIscSxwLG8sbixtLGwsayxqLGksaCxn
+LGYsZSxkLGM9bnVsbCxiPXt9LGE9Yi5hPWEwCmZvcihzPXQubixyPXQuRixxPXQuZDshMDspe3A9e30K
+bz1hLmE9PT04CmlmKGExPT1udWxsKXtpZihvKXtuPXMuYShhLmMpClAuTDIoYyxjLGEuYixuLmEsbi5i
+KX1yZXR1cm59cC5hPWExCm09YTEuYQpmb3IoYT1hMTttIT1udWxsO2E9bSxtPWwpe2EuYT1udWxsClAu
+SFooYi5hLGEpCnAuYT1tCmw9bS5hfWs9Yi5hCmo9ay5jCnAuYj1vCnAuYz1qCmk9IW8KaWYoaSl7aD1h
+LmMKaD0oaCYxKSE9PTB8fChoJjE1KT09PTh9ZWxzZSBoPSEwCmlmKGgpe2c9YS5iLmIKaWYobyl7aD1r
+LmI9PT1nCmg9IShofHxoKX1lbHNlIGg9ITEKaWYoaCl7cy5hKGopClAuTDIoYyxjLGsuYixqLmEsai5i
+KQpyZXR1cm59Zj0kLlgzCmlmKGYhPT1nKSQuWDM9ZwplbHNlIGY9YwphPWEuYwppZigoYSYxNSk9PT04
+KW5ldyBQLlJUKHAsYixvKS4kMCgpCmVsc2UgaWYoaSl7aWYoKGEmMSkhPT0wKW5ldyBQLnJxKHAsaiku
+JDAoKX1lbHNlIGlmKChhJjIpIT09MCluZXcgUC5SVyhiLHApLiQwKCkKaWYoZiE9bnVsbCkkLlgzPWYK
+YT1wLmMKaWYocS5iKGEpKXtlPXAuYS5iCmlmKGEuYT49NCl7ZD1yLmEoZS5jKQplLmM9bnVsbAphMT1l
+Lk44KGQpCmUuYT1hLmEKZS5jPWEuYwpiLmE9YQpjb250aW51ZX1lbHNlIFAuQTkoYSxlKQpyZXR1cm59
+fWU9cC5hLmIKZD1yLmEoZS5jKQplLmM9bnVsbAphMT1lLk44KGQpCmE9cC5iCms9cC5jCmlmKCFhKXtl
+LiR0aS5jLmEoaykKZS5hPTQKZS5jPWt9ZWxzZXtzLmEoaykKZS5hPTgKZS5jPWt9Yi5hPWUKYT1lfX0s
+ClZIOmZ1bmN0aW9uKGEsYil7dmFyIHMKaWYodC5hZy5iKGEpKXJldHVybiBiLkxqKGEsdC56LHQuSyx0
+LmwpCnM9dC5iSQppZihzLmIoYSkpcmV0dXJuIHMuYShhKQp0aHJvdyBILmIoUC5MMyhhLCJvbkVycm9y
+IiwiRXJyb3IgaGFuZGxlciBtdXN0IGFjY2VwdCBvbmUgT2JqZWN0IG9yIG9uZSBPYmplY3QgYW5kIGEg
+U3RhY2tUcmFjZSBhcyBhcmd1bWVudHMsIGFuZCByZXR1cm4gYSBhIHZhbGlkIHJlc3VsdCIpKX0sCnB1
+OmZ1bmN0aW9uKCl7dmFyIHMscgpmb3Iocz0kLlM2O3MhPW51bGw7cz0kLlM2KXskLm1nPW51bGwKcj1z
+LmIKJC5TNj1yCmlmKHI9PW51bGwpJC5rOD1udWxsCnMuYS4kMCgpfX0sCmVOOmZ1bmN0aW9uKCl7JC5V
+RD0hMAp0cnl7UC5wdSgpfWZpbmFsbHl7JC5tZz1udWxsCiQuVUQ9ITEKaWYoJC5TNiE9bnVsbCkkLnV0
+KCkuJDEoUC5VSSgpKX19LAplVzpmdW5jdGlvbihhKXt2YXIgcz1uZXcgUC5PTShhKSxyPSQuazgKaWYo
+cj09bnVsbCl7JC5TNj0kLms4PXMKaWYoISQuVUQpJC51dCgpLiQxKFAuVUkoKSl9ZWxzZSAkLms4PXIu
+Yj1zfSwKclI6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHA9JC5TNgppZihwPT1udWxsKXtQLmVXKGEpCiQu
+bWc9JC5rOApyZXR1cm59cz1uZXcgUC5PTShhKQpyPSQubWcKaWYocj09bnVsbCl7cy5iPXAKJC5TNj0k
+Lm1nPXN9ZWxzZXtxPXIuYgpzLmI9cQokLm1nPXIuYj1zCmlmKHE9PW51bGwpJC5rOD1zfX0sCnJiOmZ1
+bmN0aW9uKGEpe3ZhciBzPW51bGwscj0kLlgzCmlmKEMuTlU9PT1yKXtQLlRrKHMscyxDLk5VLGEpCnJl
+dHVybn1QLlRrKHMscyxyLHQuTS5hKHIudDgoYSkpKX0sClF3OmZ1bmN0aW9uKGEsYil7SC5jYihhLCJz
+dHJlYW0iLHQuSykKcmV0dXJuIG5ldyBQLnhJKGIuQygieEk8MD4iKSl9LApUbDpmdW5jdGlvbihhLGIp
+e3ZhciBzPUguY2IoYSwiZXJyb3IiLHQuSykKcmV0dXJuIG5ldyBQLkN3KHMsYj09bnVsbD9QLnYwKGEp
+OmIpfSwKdjA6ZnVuY3Rpb24oYSl7dmFyIHMKaWYodC5yLmIoYSkpe3M9YS5nSUkoKQppZihzIT1udWxs
+KXJldHVybiBzfXJldHVybiBDLnBkfSwKTDI6ZnVuY3Rpb24oYSxiLGMsZCxlKXtQLnJSKG5ldyBQLnBL
+KGQsZSkpfSwKVDg6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgcyxyPSQuWDMKaWYocj09PWMpcmV0dXJu
+IGQuJDAoKQokLlgzPWMKcz1yCnRyeXtyPWQuJDAoKQpyZXR1cm4gcn1maW5hbGx5eyQuWDM9c319LAp5
+djpmdW5jdGlvbihhLGIsYyxkLGUsZixnKXt2YXIgcyxyPSQuWDMKaWYocj09PWMpcmV0dXJuIGQuJDEo
+ZSkKJC5YMz1jCnM9cgp0cnl7cj1kLiQxKGUpCnJldHVybiByfWZpbmFsbHl7JC5YMz1zfX0sClF4OmZ1
+bmN0aW9uKGEsYixjLGQsZSxmLGcsaCxpKXt2YXIgcyxyPSQuWDMKaWYocj09PWMpcmV0dXJuIGQuJDIo
+ZSxmKQokLlgzPWMKcz1yCnRyeXtyPWQuJDIoZSxmKQpyZXR1cm4gcn1maW5hbGx5eyQuWDM9c319LApU
+azpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcwp0Lk0uYShkKQpzPUMuTlUhPT1jCmlmKHMpZD0hKCFzfHwh
+MSk/Yy50OChkKTpjLlJUKGQsdC5IKQpQLmVXKGQpfSwKdGg6ZnVuY3Rpb24gdGgoYSl7dGhpcy5hPWF9
+LApoYTpmdW5jdGlvbiBoYShhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApWczpmdW5j
+dGlvbiBWcyhhKXt0aGlzLmE9YX0sCkZ0OmZ1bmN0aW9uIEZ0KGEpe3RoaXMuYT1hfSwKVzM6ZnVuY3Rp
+b24gVzMoKXt9LAp5SDpmdW5jdGlvbiB5SChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKaWg6ZnVuY3Rp
+b24gaWgoYSxiKXt0aGlzLmE9YQp0aGlzLmI9ITEKdGhpcy4kdGk9Yn0sCldNOmZ1bmN0aW9uIFdNKGEp
+e3RoaXMuYT1hfSwKU1g6ZnVuY3Rpb24gU1goYSl7dGhpcy5hPWF9LApHczpmdW5jdGlvbiBHcyhhKXt0
+aGlzLmE9YX0sCkZ5OmZ1bmN0aW9uIEZ5KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApHVjpmdW5jdGlv
+biBHVihhLGIpe3ZhciBfPXRoaXMKXy5hPWEKXy5kPV8uYz1fLmI9bnVsbApfLiR0aT1ifSwKcTQ6ZnVu
+Y3Rpb24gcTQoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKUGY6ZnVuY3Rpb24gUGYoKXt9LApaZjpm
+dW5jdGlvbiBaZihhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApGZTpmdW5jdGlvbiBGZShhLGIsYyxk
+LGUpe3ZhciBfPXRoaXMKXy5hPW51bGwKXy5iPWEKXy5jPWIKXy5kPWMKXy5lPWQKXy4kdGk9ZX0sCnZz
+OmZ1bmN0aW9uIHZzKGEsYil7dmFyIF89dGhpcwpfLmE9MApfLmI9YQpfLmM9bnVsbApfLiR0aT1ifSwK
+ZGE6ZnVuY3Rpb24gZGEoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCm9ROmZ1bmN0aW9uIG9RKGEsYil7
+dGhpcy5hPWEKdGhpcy5iPWJ9LApwVjpmdW5jdGlvbiBwVihhKXt0aGlzLmE9YX0sClU3OmZ1bmN0aW9u
+IFU3KGEpe3RoaXMuYT1hfSwKdnI6ZnVuY3Rpb24gdnIoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRo
+aXMuYz1jfSwKcnQ6ZnVuY3Rpb24gcnQoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCktGOmZ1bmN0aW9u
+IEtGKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApaTDpmdW5jdGlvbiBaTChhLGIsYyl7dGhpcy5hPWEK
+dGhpcy5iPWIKdGhpcy5jPWN9LApSVDpmdW5jdGlvbiBSVChhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIK
+dGhpcy5jPWN9LApqWjpmdW5jdGlvbiBqWihhKXt0aGlzLmE9YX0sCnJxOmZ1bmN0aW9uIHJxKGEsYil7
+dGhpcy5hPWEKdGhpcy5iPWJ9LApSVzpmdW5jdGlvbiBSVyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwK
+T006ZnVuY3Rpb24gT00oYSl7dGhpcy5hPWEKdGhpcy5iPW51bGx9LApxaDpmdW5jdGlvbiBxaCgpe30s
+CkI1OmZ1bmN0aW9uIEI1KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp1TzpmdW5jdGlvbiB1TyhhLGIp
+e3RoaXMuYT1hCnRoaXMuYj1ifSwKTU86ZnVuY3Rpb24gTU8oKXt9LAprVDpmdW5jdGlvbiBrVCgpe30s
+CnhJOmZ1bmN0aW9uIHhJKGEpe3RoaXMuJHRpPWF9LApDdzpmdW5jdGlvbiBDdyhhLGIpe3RoaXMuYT1h
+CnRoaXMuYj1ifSwKbTA6ZnVuY3Rpb24gbTAoKXt9LApwSzpmdW5jdGlvbiBwSyhhLGIpe3RoaXMuYT1h
+CnRoaXMuYj1ifSwKSmk6ZnVuY3Rpb24gSmkoKXt9LApoajpmdW5jdGlvbiBoaihhLGIsYyl7dGhpcy5h
+PWEKdGhpcy5iPWIKdGhpcy5jPWN9LApWcDpmdW5jdGlvbiBWcChhLGIpe3RoaXMuYT1hCnRoaXMuYj1i
+fSwKT1I6ZnVuY3Rpb24gT1IoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKRUY6ZnVu
+Y3Rpb24oYSxiLGMpe3JldHVybiBiLkMoIkA8MD4iKS5LcShjKS5DKCJGbzwxLDI+IikuYShILkI3KGEs
+bmV3IEguTjUoYi5DKCJAPDA+IikuS3EoYykuQygiTjU8MSwyPiIpKSkpfSwKRmw6ZnVuY3Rpb24oYSxi
+KXtyZXR1cm4gbmV3IEguTjUoYS5DKCJAPDA+IikuS3EoYikuQygiTjU8MSwyPiIpKX0sCkxzOmZ1bmN0
+aW9uKGEpe3JldHVybiBuZXcgUC5iNihhLkMoImI2PDA+IikpfSwKVDI6ZnVuY3Rpb24oKXt2YXIgcz1P
+YmplY3QuY3JlYXRlKG51bGwpCnNbIjxub24taWRlbnRpZmllci1rZXk+Il09cwpkZWxldGUgc1siPG5v
+bi1pZGVudGlmaWVyLWtleT4iXQpyZXR1cm4gc30sCnJqOmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1uZXcg
+UC5sbShhLGIsYy5DKCJsbTwwPiIpKQpzLmM9YS5lCnJldHVybiBzfSwKRVA6ZnVuY3Rpb24oYSxiLGMp
+e3ZhciBzLHIKaWYoUC5oQihhKSl7aWYoYj09PSIoIiYmYz09PSIpIilyZXR1cm4iKC4uLikiCnJldHVy
+biBiKyIuLi4iK2N9cz1ILlZNKFtdLHQucykKQy5ObS5pKCQueGcsYSkKdHJ5e1AuVnIoYSxzKX1maW5h
+bGx5e2lmKDA+PSQueGcubGVuZ3RoKXJldHVybiBILk9IKCQueGcsLTEpCiQueGcucG9wKCl9cj1QLnZn
+KGIsdC51LmEocyksIiwgIikrYwpyZXR1cm4gci5jaGFyQ29kZUF0KDApPT0wP3I6cn0sCldFOmZ1bmN0
+aW9uKGEsYixjKXt2YXIgcyxyCmlmKFAuaEIoYSkpcmV0dXJuIGIrIi4uLiIrYwpzPW5ldyBQLlJuKGIp
+CkMuTm0uaSgkLnhnLGEpCnRyeXtyPXMKci5hPVAudmcoci5hLGEsIiwgIil9ZmluYWxseXtpZigwPj0k
+LnhnLmxlbmd0aClyZXR1cm4gSC5PSCgkLnhnLC0xKQokLnhnLnBvcCgpfXMuYSs9YwpyPXMuYQpyZXR1
+cm4gci5jaGFyQ29kZUF0KDApPT0wP3I6cn0sCmhCOmZ1bmN0aW9uKGEpe3ZhciBzLHIKZm9yKHM9JC54
+Zy5sZW5ndGgscj0wO3I8czsrK3IpaWYoYT09PSQueGdbcl0pcmV0dXJuITAKcmV0dXJuITF9LApWcjpm
+dW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixtLGw9YS5nbShhKSxrPTAsaj0wCndoaWxlKCEwKXtp
+ZighKGs8ODB8fGo8MykpYnJlYWsKaWYoIWwuRigpKXJldHVybgpzPUguRWoobC5nbCgpKQpDLk5tLmko
+YixzKQprKz1zLmxlbmd0aCsyOysran1pZighbC5GKCkpe2lmKGo8PTUpcmV0dXJuCmlmKDA+PWIubGVu
+Z3RoKXJldHVybiBILk9IKGIsLTEpCnI9Yi5wb3AoKQppZigwPj1iLmxlbmd0aClyZXR1cm4gSC5PSChi
+LC0xKQpxPWIucG9wKCl9ZWxzZXtwPWwuZ2woKTsrK2oKaWYoIWwuRigpKXtpZihqPD00KXtDLk5tLmko
+YixILkVqKHApKQpyZXR1cm59cj1ILkVqKHApCmlmKDA+PWIubGVuZ3RoKXJldHVybiBILk9IKGIsLTEp
+CnE9Yi5wb3AoKQprKz1yLmxlbmd0aCsyfWVsc2V7bz1sLmdsKCk7KytqCmZvcig7bC5GKCk7cD1vLG89
+bil7bj1sLmdsKCk7KytqCmlmKGo+MTAwKXt3aGlsZSghMCl7aWYoIShrPjc1JiZqPjMpKWJyZWFrCmlm
+KDA+PWIubGVuZ3RoKXJldHVybiBILk9IKGIsLTEpCmstPWIucG9wKCkubGVuZ3RoKzI7LS1qfUMuTm0u
+aShiLCIuLi4iKQpyZXR1cm59fXE9SC5FaihwKQpyPUguRWoobykKays9ci5sZW5ndGgrcS5sZW5ndGgr
+NH19aWYoaj5iLmxlbmd0aCsyKXtrKz01Cm09Ii4uLiJ9ZWxzZSBtPW51bGwKd2hpbGUoITApe2lmKCEo
+az44MCYmYi5sZW5ndGg+MykpYnJlYWsKaWYoMD49Yi5sZW5ndGgpcmV0dXJuIEguT0goYiwtMSkKay09
+Yi5wb3AoKS5sZW5ndGgrMgppZihtPT1udWxsKXtrKz01Cm09Ii4uLiJ9fWlmKG0hPW51bGwpQy5ObS5p
+KGIsbSkKQy5ObS5pKGIscSkKQy5ObS5pKGIscil9LAp0TTpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT1Q
+LkxzKGIpCmZvcihzPWEubGVuZ3RoLHI9MDtyPGEubGVuZ3RoO2EubGVuZ3RoPT09c3x8KDAsSC5sayko
+YSksKytyKXEuaSgwLGIuYShhW3JdKSkKcmV0dXJuIHF9LApuTzpmdW5jdGlvbihhKXt2YXIgcyxyPXt9
+CmlmKFAuaEIoYSkpcmV0dXJuInsuLi59IgpzPW5ldyBQLlJuKCIiKQp0cnl7Qy5ObS5pKCQueGcsYSkK
+cy5hKz0ieyIKci5hPSEwCmEuSygwLG5ldyBQLnJhKHIscykpCnMuYSs9In0ifWZpbmFsbHl7aWYoMD49
+JC54Zy5sZW5ndGgpcmV0dXJuIEguT0goJC54ZywtMSkKJC54Zy5wb3AoKX1yPXMuYQpyZXR1cm4gci5j
+aGFyQ29kZUF0KDApPT0wP3I6cn0sCmI2OmZ1bmN0aW9uIGI2KGEpe3ZhciBfPXRoaXMKXy5hPTAKXy5m
+PV8uZT1fLmQ9Xy5jPV8uYj1udWxsCl8ucj0wCl8uJHRpPWF9LApibjpmdW5jdGlvbiBibihhKXt0aGlz
+LmE9YQp0aGlzLmM9dGhpcy5iPW51bGx9LApsbTpmdW5jdGlvbiBsbShhLGIsYyl7dmFyIF89dGhpcwpf
+LmE9YQpfLmI9YgpfLmQ9Xy5jPW51bGwKXy4kdGk9Y30sCm1XOmZ1bmN0aW9uIG1XKCl7fSwKdXk6ZnVu
+Y3Rpb24gdXkoKXt9LApsRDpmdW5jdGlvbiBsRCgpe30sCmlsOmZ1bmN0aW9uIGlsKCl7fSwKcmE6ZnVu
+Y3Rpb24gcmEoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCllrOmZ1bmN0aW9uIFlrKCl7fSwKeVE6ZnVu
+Y3Rpb24geVEoYSl7dGhpcy5hPWF9LApLUDpmdW5jdGlvbiBLUCgpe30sClBuOmZ1bmN0aW9uIFBuKCl7
+fSwKR2o6ZnVuY3Rpb24gR2ooYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKbGY6ZnVuY3Rpb24gbGYo
+KXt9LApWajpmdW5jdGlvbiBWaigpe30sClh2OmZ1bmN0aW9uIFh2KCl7fSwKblk6ZnVuY3Rpb24gblko
+KXt9LApXWTpmdW5jdGlvbiBXWSgpe30sClJVOmZ1bmN0aW9uIFJVKCl7fSwKcFI6ZnVuY3Rpb24gcFIo
+KXt9LApCUzpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwCmlmKHR5cGVvZiBhIT0ic3RyaW5nIil0aHJv
+dyBILmIoSC50TChhKSkKcz1udWxsCnRyeXtzPUpTT04ucGFyc2UoYSl9Y2F0Y2gocSl7cj1ILlJ1KHEp
+CnA9UC5ycihTdHJpbmcociksbnVsbCxudWxsKQp0aHJvdyBILmIocCl9cD1QLlFlKHMpCnJldHVybiBw
+fSwKUWU6ZnVuY3Rpb24oYSl7dmFyIHMKaWYoYT09bnVsbClyZXR1cm4gbnVsbAppZih0eXBlb2YgYSE9
+Im9iamVjdCIpcmV0dXJuIGEKaWYoT2JqZWN0LmdldFByb3RvdHlwZU9mKGEpIT09QXJyYXkucHJvdG90
+eXBlKXJldHVybiBuZXcgUC51dyhhLE9iamVjdC5jcmVhdGUobnVsbCkpCmZvcihzPTA7czxhLmxlbmd0
+aDsrK3MpYVtzXT1QLlFlKGFbc10pCnJldHVybiBhfSwKa3k6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMs
+cgppZihiIGluc3RhbmNlb2YgVWludDhBcnJheSl7cz1iCmQ9cy5sZW5ndGgKaWYoZC1jPDE1KXJldHVy
+biBudWxsCnI9UC5DRyhhLHMsYyxkKQppZihyIT1udWxsJiZhKWlmKHIuaW5kZXhPZigiXHVmZmZkIik+
+PTApcmV0dXJuIG51bGwKcmV0dXJuIHJ9cmV0dXJuIG51bGx9LApDRzpmdW5jdGlvbihhLGIsYyxkKXt2
+YXIgcz1hPyQuSEcoKTokLnJmKCkKaWYocz09bnVsbClyZXR1cm4gbnVsbAppZigwPT09YyYmZD09PWIu
+bGVuZ3RoKXJldHVybiBQLlJiKHMsYikKcmV0dXJuIFAuUmIocyxiLnN1YmFycmF5KGMsUC5qQihjLGQs
+Yi5sZW5ndGgpKSl9LApSYjpmdW5jdGlvbihhLGIpe3ZhciBzLHIKdHJ5e3M9YS5kZWNvZGUoYikKcmV0
+dXJuIHN9Y2F0Y2gocil7SC5SdShyKX1yZXR1cm4gbnVsbH0sCnhNOmZ1bmN0aW9uKGEsYixjLGQsZSxm
+KXtpZihDLmpuLnpZKGYsNCkhPT0wKXRocm93IEguYihQLnJyKCJJbnZhbGlkIGJhc2U2NCBwYWRkaW5n
+LCBwYWRkZWQgbGVuZ3RoIG11c3QgYmUgbXVsdGlwbGUgb2YgZm91ciwgaXMgIitmLGEsYykpCmlmKGQr
+ZSE9PWYpdGhyb3cgSC5iKFAucnIoIkludmFsaWQgYmFzZTY0IHBhZGRpbmcsICc9JyBub3QgYXQgdGhl
+IGVuZCIsYSxiKSkKaWYoZT4yKXRocm93IEguYihQLnJyKCJJbnZhbGlkIGJhc2U2NCBwYWRkaW5nLCBt
+b3JlIHRoYW4gdHdvICc9JyBjaGFyYWN0ZXJzIixhLGIpKX0sCkd5OmZ1bmN0aW9uKGEsYixjKXtyZXR1
+cm4gbmV3IFAuVWQoYSxiKX0sCk5DOmZ1bmN0aW9uKGEpe3JldHVybiBhLkx0KCl9LApVZzpmdW5jdGlv
+bihhLGIpe3JldHVybiBuZXcgUC50dShhLFtdLFAuQ3koKSl9LAp1WDpmdW5jdGlvbihhLGIsYyl7dmFy
+IHMscj1uZXcgUC5SbigiIikscT1QLlVnKHIsYikKcS5pVShhKQpzPXIuYQpyZXR1cm4gcy5jaGFyQ29k
+ZUF0KDApPT0wP3M6c30sCmo0OmZ1bmN0aW9uKGEpe3N3aXRjaChhKXtjYXNlIDY1OnJldHVybiJNaXNz
+aW5nIGV4dGVuc2lvbiBieXRlIgpjYXNlIDY3OnJldHVybiJVbmV4cGVjdGVkIGV4dGVuc2lvbiBieXRl
+IgpjYXNlIDY5OnJldHVybiJJbnZhbGlkIFVURi04IGJ5dGUiCmNhc2UgNzE6cmV0dXJuIk92ZXJsb25n
+IGVuY29kaW5nIgpjYXNlIDczOnJldHVybiJPdXQgb2YgdW5pY29kZSByYW5nZSIKY2FzZSA3NTpyZXR1
+cm4iRW5jb2RlZCBzdXJyb2dhdGUiCmNhc2UgNzc6cmV0dXJuIlVuZmluaXNoZWQgVVRGLTggb2N0ZXQg
+c2VxdWVuY2UiCmRlZmF1bHQ6cmV0dXJuIiJ9fSwKank6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscSxw
+PWMtYixvPW5ldyBVaW50OEFycmF5KHApCmZvcihzPUouVTYoYSkscj0wO3I8cDsrK3Ipe3E9cy5xKGEs
+YityKQppZih0eXBlb2YgcSE9PSJudW1iZXIiKXJldHVybiBxLnpNKCkKaWYoKHEmNDI5NDk2NzA0MCk+
+Pj4wIT09MClxPTI1NQppZihyPj1wKXJldHVybiBILk9IKG8scikKb1tyXT1xfXJldHVybiBvfSwKdXc6
+ZnVuY3Rpb24gdXcoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9bnVsbH0sCmk4OmZ1bmN0aW9u
+IGk4KGEpe3RoaXMuYT1hfSwKcGc6ZnVuY3Rpb24gcGcoKXt9LApjMjpmdW5jdGlvbiBjMigpe30sCkNW
+OmZ1bmN0aW9uIENWKCl7fSwKVTg6ZnVuY3Rpb24gVTgoKXt9LApVazpmdW5jdGlvbiBVaygpe30sCndJ
+OmZ1bmN0aW9uIHdJKCl7fSwKWmk6ZnVuY3Rpb24gWmkoKXt9LApVZDpmdW5jdGlvbiBVZChhLGIpe3Ro
+aXMuYT1hCnRoaXMuYj1ifSwKSzg6ZnVuY3Rpb24gSzgoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCmJ5
+OmZ1bmN0aW9uIGJ5KCl7fSwKb2o6ZnVuY3Rpb24gb2ooYSl7dGhpcy5iPWF9LApNeDpmdW5jdGlvbiBN
+eChhKXt0aGlzLmE9YX0sClNoOmZ1bmN0aW9uIFNoKCl7fSwKdGk6ZnVuY3Rpb24gdGkoYSxiKXt0aGlz
+LmE9YQp0aGlzLmI9Yn0sCnR1OmZ1bmN0aW9uIHR1KGEsYixjKXt0aGlzLmM9YQp0aGlzLmE9Ygp0aGlz
+LmI9Y30sCnU1OmZ1bmN0aW9uIHU1KCl7fSwKRTM6ZnVuY3Rpb24gRTMoKXt9LApSdzpmdW5jdGlvbiBS
+dyhhKXt0aGlzLmI9MAp0aGlzLmM9YX0sCkdZOmZ1bmN0aW9uIEdZKGEpe3RoaXMuYT1hfSwKYno6ZnVu
+Y3Rpb24gYnooYSl7dGhpcy5hPWEKdGhpcy5iPTE2CnRoaXMuYz0wfSwKUUE6ZnVuY3Rpb24oYSxiKXt2
+YXIgcz1ILkhwKGEsYikKaWYocyE9bnVsbClyZXR1cm4gcwp0aHJvdyBILmIoUC5ycihhLG51bGwsbnVs
+bCkpfSwKb3M6ZnVuY3Rpb24oYSl7aWYoYSBpbnN0YW5jZW9mIEguVHApcmV0dXJuIGEudygwKQpyZXR1
+cm4iSW5zdGFuY2Ugb2YgJyIrSC5FaihILk0oYSkpKyInIn0sCk84OmZ1bmN0aW9uKGEsYixjLGQpe3Zh
+ciBzLHI9Yz9KLktoKGEsZCk6Si5RaShhLGQpCmlmKGEhPT0wJiZiIT1udWxsKWZvcihzPTA7czxyLmxl
+bmd0aDsrK3MpcltzXT1iCnJldHVybiByfSwKQ0g6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHI9SC5WTShb
+XSxjLkMoImpkPDA+IikpCmZvcihzPUouSVQoYSk7cy5GKCk7KUMuTm0uaShyLGMuYShzLmdsKCkpKQpp
+ZihiKXJldHVybiByCnJldHVybiBKLkVwKHIsYyl9LApZMTpmdW5jdGlvbihhLGIsYyl7dmFyIHMKaWYo
+YilyZXR1cm4gUC5ldihhLGMpCnM9Si5FcChQLmV2KGEsYyksYykKcmV0dXJuIHN9LApldjpmdW5jdGlv
+bihhLGIpe3ZhciBzLHI9SC5WTShbXSxiLkMoImpkPDA+IikpCmZvcihzPUouSVQoYSk7cy5GKCk7KUMu
+Tm0uaShyLHMuZ2woKSkKcmV0dXJuIHJ9LApBRjpmdW5jdGlvbihhLGIpe3JldHVybiBKLnpDKFAuQ0go
+YSwhMSxiKSl9LApITTpmdW5jdGlvbihhLGIsYyl7aWYodC5ibS5iKGEpKXJldHVybiBILmZ3KGEsYixQ
+LmpCKGIsYyxhLmxlbmd0aCkpCnJldHVybiBQLmJ3KGEsYixjKX0sCk9vOmZ1bmN0aW9uKGEpe3JldHVy
+biBILkx3KGEpfSwKYnc6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscSxwLG89bnVsbAppZihiPDApdGhy
+b3cgSC5iKFAuVEUoYiwwLGEubGVuZ3RoLG8sbykpCnM9Yz09bnVsbAppZighcyYmYzxiKXRocm93IEgu
+YihQLlRFKGMsYixhLmxlbmd0aCxvLG8pKQpyPW5ldyBILmE3KGEsYS5sZW5ndGgsSC56KGEpLkMoImE3
+PGxELkU+IikpCmZvcihxPTA7cTxiOysrcSlpZighci5GKCkpdGhyb3cgSC5iKFAuVEUoYiwwLHEsbyxv
+KSkKcD1bXQppZihzKWZvcig7ci5GKCk7KXAucHVzaChyLmQpCmVsc2UgZm9yKHE9YjtxPGM7KytxKXtp
+Zighci5GKCkpdGhyb3cgSC5iKFAuVEUoYyxiLHEsbyxvKSkKcC5wdXNoKHIuZCl9cmV0dXJuIEguZVQo
+cCl9LApudTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEguVlIoYSxILnY0KGEsITEsITAsITEsITEsITEp
+KX0sCnZnOmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1KLklUKGIpCmlmKCFzLkYoKSlyZXR1cm4gYQppZihj
+Lmxlbmd0aD09PTApe2RvIGErPUguRWoocy5nbCgpKQp3aGlsZShzLkYoKSl9ZWxzZXthKz1ILkVqKHMu
+Z2woKSkKZm9yKDtzLkYoKTspYT1hK2MrSC5FaihzLmdsKCkpfXJldHVybiBhfSwKbHI6ZnVuY3Rpb24o
+YSxiLGMsZCl7cmV0dXJuIG5ldyBQLm1wKGEsYixjLGQpfSwKdW86ZnVuY3Rpb24oKXt2YXIgcz1ILk0w
+KCkKaWYocyE9bnVsbClyZXR1cm4gUC5oSyhzKQp0aHJvdyBILmIoUC5MNCgiJ1VyaS5iYXNlJyBpcyBu
+b3Qgc3VwcG9ydGVkIikpfSwKZVA6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixxLHAsbyxuLG09IjAx
+MjM0NTY3ODlBQkNERUYiCmlmKGM9PT1DLnhNKXtzPSQuejQoKS5iCmlmKHR5cGVvZiBiIT0ic3RyaW5n
+IilILnYoSC50TChiKSkKcz1zLnRlc3QoYil9ZWxzZSBzPSExCmlmKHMpcmV0dXJuIGIKSC5MaChjKS5D
+KCJVay5TIikuYShiKQpyPWMuZ1pFKCkuV0ooYikKZm9yKHM9ci5sZW5ndGgscT0wLHA9IiI7cTxzOysr
+cSl7bz1yW3FdCmlmKG88MTI4KXtuPW8+Pj40CmlmKG4+PTgpcmV0dXJuIEguT0goYSxuKQpuPShhW25d
+JjE8PChvJjE1KSkhPT0wfWVsc2Ugbj0hMQppZihuKXArPUguTHcobykKZWxzZSBwPWQmJm89PT0zMj9w
+KyIrIjpwKyIlIittW28+Pj40JjE1XSttW28mMTVdfXJldHVybiBwLmNoYXJDb2RlQXQoMCk9PTA/cDpw
+fSwKR3E6ZnVuY3Rpb24oYSl7dmFyIHM9TWF0aC5hYnMoYSkscj1hPDA/Ii0iOiIiCmlmKHM+PTEwMDAp
+cmV0dXJuIiIrYQppZihzPj0xMDApcmV0dXJuIHIrIjAiK3MKaWYocz49MTApcmV0dXJuIHIrIjAwIitz
+CnJldHVybiByKyIwMDAiK3N9LApWeDpmdW5jdGlvbihhKXtpZihhPj0xMDApcmV0dXJuIiIrYQppZihh
+Pj0xMClyZXR1cm4iMCIrYQpyZXR1cm4iMDAiK2F9LApoMDpmdW5jdGlvbihhKXtpZihhPj0xMClyZXR1
+cm4iIithCnJldHVybiIwIithfSwKcDpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciJ8fEgu
+bChhKXx8bnVsbD09YSlyZXR1cm4gSi5qKGEpCmlmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gSlNP
+Ti5zdHJpbmdpZnkoYSkKcmV0dXJuIFAub3MoYSl9LApoVjpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAu
+QzYoYSl9LAp4WTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAudSghMSxudWxsLG51bGwsYSl9LApMMzpm
+dW5jdGlvbihhLGIsYyl7cmV0dXJuIG5ldyBQLnUoITAsYSxiLGMpfSwKTVI6ZnVuY3Rpb24oYSxiLGMp
+e3JldHVybiBhfSwKTzc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IFAuYkoobnVsbCxudWxsLCEwLGEs
+YiwiVmFsdWUgbm90IGluIHJhbmdlIil9LApURTpmdW5jdGlvbihhLGIsYyxkLGUpe3JldHVybiBuZXcg
+UC5iSihiLGMsITAsYSxkLCJJbnZhbGlkIHZhbHVlIil9LAp3QTpmdW5jdGlvbihhLGIsYyxkKXtpZihh
+PGJ8fGE+Yyl0aHJvdyBILmIoUC5URShhLGIsYyxkLG51bGwpKQpyZXR1cm4gYX0sCmpCOmZ1bmN0aW9u
+KGEsYixjKXtpZigwPmF8fGE+Yyl0aHJvdyBILmIoUC5URShhLDAsYywic3RhcnQiLG51bGwpKQppZihi
+IT1udWxsKXtpZihhPmJ8fGI+Yyl0aHJvdyBILmIoUC5URShiLGEsYywiZW5kIixudWxsKSkKcmV0dXJu
+IGJ9cmV0dXJuIGN9LAprMTpmdW5jdGlvbihhLGIpe2lmKGE8MCl0aHJvdyBILmIoUC5URShhLDAsbnVs
+bCxiLG51bGwpKQpyZXR1cm4gYX0sCkNmOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHM9SC51UChlPT1u
+dWxsP0ouSG0oYik6ZSkKcmV0dXJuIG5ldyBQLmVZKHMsITAsYSxjLCJJbmRleCBvdXQgb2YgcmFuZ2Ui
+KX0sCkw0OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC51YihhKX0sClNZOmZ1bmN0aW9uKGEpe3JldHVy
+biBuZXcgUC5kcyhhKX0sClBWOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5saihhKX0sCmE0OmZ1bmN0
+aW9uKGEpe3JldHVybiBuZXcgUC5VVihhKX0sCnJyOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gbmV3IFAu
+YUUoYSxiLGMpfSwKaEs6ZnVuY3Rpb24oYTUpe3ZhciBzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYs
+ZSxkLGMsYixhLGEwLGExLGEyLGEzPW51bGwsYTQ9YTUubGVuZ3RoCmlmKGE0Pj01KXtzPSgoSi5Reihh
+NSw0KV41OCkqM3xDLnhCLlcoYTUsMCleMTAwfEMueEIuVyhhNSwxKV45N3xDLnhCLlcoYTUsMileMTE2
+fEMueEIuVyhhNSwzKV45Nyk+Pj4wCmlmKHM9PT0wKXJldHVybiBQLktEKGE0PGE0P0MueEIuTmooYTUs
+MCxhNCk6YTUsNSxhMykuZ2xSKCkKZWxzZSBpZihzPT09MzIpcmV0dXJuIFAuS0QoQy54Qi5OaihhNSw1
+LGE0KSwwLGEzKS5nbFIoKX1yPVAuTzgoOCwwLCExLHQuUykKQy5ObS5ZNShyLDAsMCkKQy5ObS5ZNShy
+LDEsLTEpCkMuTm0uWTUociwyLC0xKQpDLk5tLlk1KHIsNywtMSkKQy5ObS5ZNShyLDMsMCkKQy5ObS5Z
+NShyLDQsMCkKQy5ObS5ZNShyLDUsYTQpCkMuTm0uWTUociw2LGE0KQppZihQLlVCKGE1LDAsYTQsMCxy
+KT49MTQpQy5ObS5ZNShyLDcsYTQpCnE9clsxXQppZihxPj0wKWlmKFAuVUIoYTUsMCxxLDIwLHIpPT09
+MjApcls3XT1xCnA9clsyXSsxCm89clszXQpuPXJbNF0KbT1yWzVdCmw9cls2XQppZihsPG0pbT1sCmlm
+KG48cCluPW0KZWxzZSBpZihuPD1xKW49cSsxCmlmKG88cClvPW4Kaz1yWzddPDAKaWYoaylpZihwPnEr
+Myl7aj1hMwprPSExfWVsc2V7aT1vPjAKaWYoaSYmbysxPT09bil7aj1hMwprPSExfWVsc2V7aWYoISht
+PGE0JiZtPT09bisyJiZKLnEwKGE1LCIuLiIsbikpKWg9bT5uKzImJkoucTAoYTUsIi8uLiIsbS0zKQpl
+bHNlIGg9ITAKaWYoaCl7aj1hMwprPSExfWVsc2V7aWYocT09PTQpaWYoSi5xMChhNSwiZmlsZSIsMCkp
+e2lmKHA8PTApe2lmKCFDLnhCLlFpKGE1LCIvIixuKSl7Zz0iZmlsZTovLy8iCnM9M31lbHNle2c9ImZp
+bGU6Ly8iCnM9Mn1hNT1nK0MueEIuTmooYTUsbixhNCkKcS09MAppPXMtMAptKz1pCmwrPWkKYTQ9YTUu
+bGVuZ3RoCnA9NwpvPTcKbj03fWVsc2UgaWYobj09PW0peysrbApmPW0rMQphNT1DLnhCLmk3KGE1LG4s
+bSwiLyIpOysrYTQKbT1mfWo9ImZpbGUifWVsc2UgaWYoQy54Qi5RaShhNSwiaHR0cCIsMCkpe2lmKGkm
+Jm8rMz09PW4mJkMueEIuUWkoYTUsIjgwIixvKzEpKXtsLT0zCmU9bi0zCm0tPTMKYTU9Qy54Qi5pNyhh
+NSxvLG4sIiIpCmE0LT0zCm49ZX1qPSJodHRwIn1lbHNlIGo9YTMKZWxzZSBpZihxPT09NSYmSi5xMChh
+NSwiaHR0cHMiLDApKXtpZihpJiZvKzQ9PT1uJiZKLnEwKGE1LCI0NDMiLG8rMSkpe2wtPTQKZT1uLTQK
+bS09NAphNT1KLmRnKGE1LG8sbiwiIikKYTQtPTMKbj1lfWo9Imh0dHBzIn1lbHNlIGo9YTMKaz0hMH19
+fWVsc2Ugaj1hMwppZihrKXtpPWE1Lmxlbmd0aAppZihhNDxpKXthNT1KLmxkKGE1LDAsYTQpCnEtPTAK
+cC09MApvLT0wCm4tPTAKbS09MApsLT0wfXJldHVybiBuZXcgUC5VZihhNSxxLHAsbyxuLG0sbCxqKX1p
+ZihqPT1udWxsKWlmKHE+MClqPVAuUGkoYTUsMCxxKQplbHNle2lmKHE9PT0wKXtQLlIzKGE1LDAsIklu
+dmFsaWQgZW1wdHkgc2NoZW1lIikKSC5CaSh1LmcpfWo9IiJ9aWYocD4wKXtkPXErMwpjPWQ8cD9QLnpS
+KGE1LGQscC0xKToiIgpiPVAuT2UoYTUscCxvLCExKQppPW8rMQppZihpPG4pe2E9SC5IcChKLmxkKGE1
+LGksbiksYTMpCmEwPVAud0IoYT09bnVsbD9ILnYoUC5ycigiSW52YWxpZCBwb3J0IixhNSxpKSk6YSxq
+KX1lbHNlIGEwPWEzfWVsc2V7YTA9YTMKYj1hMApjPSIifWExPVAua2EoYTUsbixtLGEzLGosYiE9bnVs
+bCkKYTI9bTxsP1AubGUoYTUsbSsxLGwsYTMpOmEzCnJldHVybiBuZXcgUC5EbihqLGMsYixhMCxhMSxh
+MixsPGE0P1AudEcoYTUsbCsxLGE0KTphMyl9LApNdDpmdW5jdGlvbihhKXtILmgoYSkKcmV0dXJuIFAu
+a3UoYSwwLGEubGVuZ3RoLEMueE0sITEpfSwKV1g6ZnVuY3Rpb24oYSl7dmFyIHM9dC5OCnJldHVybiBD
+Lk5tLk4wKEguVk0oYS5zcGxpdCgiJiIpLHQucyksUC5GbChzLHMpLG5ldyBQLm4xKEMueE0pLHQuSil9
+LApIaDpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHAsbyxuLG09IklQdjQgYWRkcmVzcyBzaG91bGQg
+Y29udGFpbiBleGFjdGx5IDQgcGFydHMiLGw9ImVhY2ggcGFydCBtdXN0IGJlIGluIHRoZSByYW5nZSAw
+Li4yNTUiLGs9bmV3IFAuY1MoYSksaj1uZXcgVWludDhBcnJheSg0KQpmb3Iocz1iLHI9cyxxPTA7czxj
+Oysrcyl7cD1DLnhCLk8yKGEscykKaWYocCE9PTQ2KXtpZigocF40OCk+OSlrLiQyKCJpbnZhbGlkIGNo
+YXJhY3RlciIscyl9ZWxzZXtpZihxPT09MylrLiQyKG0scykKbz1QLlFBKEMueEIuTmooYSxyLHMpLG51
+bGwpCmlmKG8+MjU1KWsuJDIobCxyKQpuPXErMQppZihxPj00KXJldHVybiBILk9IKGoscSkKaltxXT1v
+CnI9cysxCnE9bn19aWYocSE9PTMpay4kMihtLGMpCm89UC5RQShDLnhCLk5qKGEscixjKSxudWxsKQpp
+ZihvPjI1NSlrLiQyKGwscikKaWYocT49NClyZXR1cm4gSC5PSChqLHEpCmpbcV09bwpyZXR1cm4gan0s
+CmVnOmZ1bmN0aW9uKGEsYixhMCl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQ9bmV3
+IFAuVkMoYSksYz1uZXcgUC5KVChkLGEpCmlmKGEubGVuZ3RoPDIpZC4kMSgiYWRkcmVzcyBpcyB0b28g
+c2hvcnQiKQpzPUguVk0oW10sdC5hKQpmb3Iocj1iLHE9cixwPSExLG89ITE7cjxhMDsrK3Ipe249Qy54
+Qi5PMihhLHIpCmlmKG49PT01OCl7aWYocj09PWIpeysrcgppZihDLnhCLk8yKGEscikhPT01OClkLiQy
+KCJpbnZhbGlkIHN0YXJ0IGNvbG9uLiIscikKcT1yfWlmKHI9PT1xKXtpZihwKWQuJDIoIm9ubHkgb25l
+IHdpbGRjYXJkIGA6OmAgaXMgYWxsb3dlZCIscikKQy5ObS5pKHMsLTEpCnA9ITB9ZWxzZSBDLk5tLmko
+cyxjLiQyKHEscikpCnE9cisxfWVsc2UgaWYobj09PTQ2KW89ITB9aWYocy5sZW5ndGg9PT0wKWQuJDEo
+InRvbyBmZXcgcGFydHMiKQptPXE9PT1hMApsPUMuTm0uZ3JaKHMpCmlmKG0mJmwhPT0tMSlkLiQyKCJl
+eHBlY3RlZCBhIHBhcnQgYWZ0ZXIgbGFzdCBgOmAiLGEwKQppZighbSlpZighbylDLk5tLmkocyxjLiQy
+KHEsYTApKQplbHNle2s9UC5IaChhLHEsYTApCkMuTm0uaShzLChrWzBdPDw4fGtbMV0pPj4+MCkKQy5O
+bS5pKHMsKGtbMl08PDh8a1szXSk+Pj4wKX1pZihwKXtpZihzLmxlbmd0aD43KWQuJDEoImFuIGFkZHJl
+c3Mgd2l0aCBhIHdpbGRjYXJkIG11c3QgaGF2ZSBsZXNzIHRoYW4gNyBwYXJ0cyIpfWVsc2UgaWYocy5s
+ZW5ndGghPT04KWQuJDEoImFuIGFkZHJlc3Mgd2l0aG91dCBhIHdpbGRjYXJkIG11c3QgY29udGFpbiBl
+eGFjdGx5IDggcGFydHMiKQpqPW5ldyBVaW50OEFycmF5KDE2KQpmb3IobD1zLmxlbmd0aCxpPTktbCxy
+PTAsaD0wO3I8bDsrK3Ipe2c9c1tyXQppZihnPT09LTEpZm9yKGY9MDtmPGk7KytmKXtpZihoPDB8fGg+
+PTE2KXJldHVybiBILk9IKGosaCkKaltoXT0wCmU9aCsxCmlmKGU+PTE2KXJldHVybiBILk9IKGosZSkK
+altlXT0wCmgrPTJ9ZWxzZXtlPUMuam4ud0coZyw4KQppZihoPDB8fGg+PTE2KXJldHVybiBILk9IKGos
+aCkKaltoXT1lCmU9aCsxCmlmKGU+PTE2KXJldHVybiBILk9IKGosZSkKaltlXT1nJjI1NQpoKz0yfX1y
+ZXR1cm4gan0sCktMOmZ1bmN0aW9uKGEsYixjLGQsZSxmLGcpe3ZhciBzLHIscSxwLG8sbgpmPWY9PW51
+bGw/IiI6UC5QaShmLDAsZi5sZW5ndGgpCmc9UC56UihnLDAsZz09bnVsbD8wOmcubGVuZ3RoKQphPVAu
+T2UoYSwwLGE9PW51bGw/MDphLmxlbmd0aCwhMSkKcz1QLmxlKG51bGwsMCwwLGUpCnI9UC50RyhudWxs
+LDAsMCkKZD1QLndCKGQsZikKcT1mPT09ImZpbGUiCmlmKGE9PW51bGwpcD1nLmxlbmd0aCE9PTB8fGQh
+PW51bGx8fHEKZWxzZSBwPSExCmlmKHApYT0iIgpwPWE9PW51bGwKbz0hcApiPVAua2EoYiwwLGI9PW51
+bGw/MDpiLmxlbmd0aCxjLGYsbykKbj1mLmxlbmd0aD09PTAKaWYobiYmcCYmIUMueEIubkMoYiwiLyIp
+KWI9UC53RihiLCFufHxvKQplbHNlIGI9UC54ZShiKQpyZXR1cm4gbmV3IFAuRG4oZixnLHAmJkMueEIu
+bkMoYiwiLy8iKT8iIjphLGQsYixzLHIpfSwKd0s6ZnVuY3Rpb24oYSl7aWYoYT09PSJodHRwIilyZXR1
+cm4gODAKaWYoYT09PSJodHRwcyIpcmV0dXJuIDQ0MwpyZXR1cm4gMH0sClIzOmZ1bmN0aW9uKGEsYixj
+KXt0aHJvdyBILmIoUC5ycihjLGEsYikpfSwKWGQ6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixxLHAs
+byxuLG0sbCxrLGosaSxoPW51bGwsZz1iLmxlbmd0aAppZihnIT09MCl7cT0wCndoaWxlKCEwKXtpZigh
+KHE8Zykpe3M9IiIKcj0wCmJyZWFrfWlmKEMueEIuVyhiLHEpPT09NjQpe3M9Qy54Qi5OaihiLDAscSkK
+cj1xKzEKYnJlYWt9KytxfWlmKHI8ZyYmQy54Qi5XKGIscik9PT05MSl7Zm9yKHA9cixvPS0xO3A8Zzsr
+K3Ape249Qy54Qi5XKGIscCkKaWYobj09PTM3JiZvPDApe209Qy54Qi5RaShiLCIyNSIscCsxKT9wKzI6
+cApvPXAKcD1tfWVsc2UgaWYobj09PTkzKWJyZWFrfWlmKHA9PT1nKXRocm93IEguYihQLnJyKCJJbnZh
+bGlkIElQdjYgaG9zdCBlbnRyeS4iLGIscikpCmw9bzwwP3A6bwpQLmVnKGIscisxLGwpOysrcAppZihw
+IT09ZyYmQy54Qi5XKGIscCkhPT01OCl0aHJvdyBILmIoUC5ycigiSW52YWxpZCBlbmQgb2YgYXV0aG9y
+aXR5IixiLHApKX1lbHNlIHA9cgp3aGlsZSghMCl7aWYoIShwPGcpKXtrPWgKYnJlYWt9aWYoQy54Qi5X
+KGIscCk9PT01OCl7aj1DLnhCLnluKGIscCsxKQprPWoubGVuZ3RoIT09MD9QLlFBKGosaCk6aApicmVh
+a30rK3B9aT1DLnhCLk5qKGIscixwKX1lbHNle2s9aAppPWsKcz0iIn1yZXR1cm4gUC5LTChpLGgsSC5W
+TShjLnNwbGl0KCIvIiksdC5zKSxrLGQsYSxzKX0sCmtFOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAs
+bwpmb3Iocz1hLmxlbmd0aCxyPTA7cjxzOysrcil7cT1hW3JdCnEudG9TdHJpbmcKcD1KLlU2KHEpCm89
+cC5nQShxKQppZigwPm8pSC52KFAuVEUoMCwwLHAuZ0EocSksbnVsbCxudWxsKSkKaWYoSC5TUShxLCIv
+IiwwKSl7cz1QLkw0KCJJbGxlZ2FsIHBhdGggY2hhcmFjdGVyICIrSC5FaihxKSkKdGhyb3cgSC5iKHMp
+fX19LApITjpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxCmZvcihzPUgucUMoYSxjLG51bGwsSC50Nihh
+KS5jKSxzPW5ldyBILmE3KHMscy5nQShzKSxzLiR0aS5DKCJhNzxhTC5FPiIpKTtzLkYoKTspe3I9cy5k
+CnE9UC5udSgnWyIqLzo8Pj9cXFxcfF0nKQpyLnRvU3RyaW5nCmlmKEguU1EocixxLDApKXtzPVAuTDQo
+IklsbGVnYWwgY2hhcmFjdGVyIGluIHBhdGg6ICIrcikKdGhyb3cgSC5iKHMpfX19LApyZzpmdW5jdGlv
+bihhLGIpe3ZhciBzCmlmKCEoNjU8PWEmJmE8PTkwKSlzPTk3PD1hJiZhPD0xMjIKZWxzZSBzPSEwCmlm
+KHMpcmV0dXJuCnM9UC5MNCgiSWxsZWdhbCBkcml2ZSBsZXR0ZXIgIitQLk9vKGEpKQp0aHJvdyBILmIo
+cyl9LAp3QjpmdW5jdGlvbihhLGIpe2lmKGEhPW51bGwmJmE9PT1QLndLKGIpKXJldHVybiBudWxsCnJl
+dHVybiBhfSwKT2U6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixxLHAsbyxuCmlmKGE9PW51bGwpcmV0
+dXJuIG51bGwKaWYoYj09PWMpcmV0dXJuIiIKaWYoQy54Qi5PMihhLGIpPT09OTEpe3M9Yy0xCmlmKEMu
+eEIuTzIoYSxzKSE9PTkzKXtQLlIzKGEsYiwiTWlzc2luZyBlbmQgYF1gIHRvIG1hdGNoIGBbYCBpbiBo
+b3N0IikKSC5CaSh1LmcpfXI9YisxCnE9UC50byhhLHIscykKaWYocTxzKXtwPXErMQpvPVAuT0EoYSxD
+LnhCLlFpKGEsIjI1IixwKT9xKzM6cCxzLCIlMjUiKX1lbHNlIG89IiIKUC5lZyhhLHIscSkKcmV0dXJu
+IEMueEIuTmooYSxiLHEpLnRvTG93ZXJDYXNlKCkrbysiXSJ9Zm9yKG49YjtuPGM7KytuKWlmKEMueEIu
+TzIoYSxuKT09PTU4KXtxPUMueEIuWFUoYSwiJSIsYikKcT1xPj1iJiZxPGM/cTpjCmlmKHE8Yyl7cD1x
+KzEKbz1QLk9BKGEsQy54Qi5RaShhLCIyNSIscCk/cSszOnAsYywiJTI1Iil9ZWxzZSBvPSIiClAuZWco
+YSxiLHEpCnJldHVybiJbIitDLnhCLk5qKGEsYixxKStvKyJdIn1yZXR1cm4gUC5PTChhLGIsYyl9LAp0
+bzpmdW5jdGlvbihhLGIsYyl7dmFyIHM9Qy54Qi5YVShhLCIlIixiKQpyZXR1cm4gcz49YiYmczxjP3M6
+Y30sCk9BOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIscSxwLG8sbixtLGwsayxqLGk9ZCE9PSIiP25l
+dyBQLlJuKGQpOm51bGwKZm9yKHM9YixyPXMscT0hMDtzPGM7KXtwPUMueEIuTzIoYSxzKQppZihwPT09
+Mzcpe289UC5ydihhLHMsITApCm49bz09bnVsbAppZihuJiZxKXtzKz0zCmNvbnRpbnVlfWlmKGk9PW51
+bGwpaT1uZXcgUC5SbigiIikKbT1pLmErPUMueEIuTmooYSxyLHMpCmlmKG4pbz1DLnhCLk5qKGEscyxz
+KzMpCmVsc2UgaWYobz09PSIlIil7UC5SMyhhLHMsIlpvbmVJRCBzaG91bGQgbm90IGNvbnRhaW4gJSBh
+bnltb3JlIikKSC5CaSh1LmcpfWkuYT1tK28Kcys9MwpyPXMKcT0hMH1lbHNle2lmKHA8MTI3KXtuPXA+
+Pj40CmlmKG4+PTgpcmV0dXJuIEguT0goQy5GMyxuKQpuPShDLkYzW25dJjE8PChwJjE1KSkhPT0wfWVs
+c2Ugbj0hMQppZihuKXtpZihxJiY2NTw9cCYmOTA+PXApe2lmKGk9PW51bGwpaT1uZXcgUC5SbigiIikK
+aWYocjxzKXtpLmErPUMueEIuTmooYSxyLHMpCnI9c31xPSExfSsrc31lbHNle2lmKChwJjY0NTEyKT09
+PTU1Mjk2JiZzKzE8Yyl7bD1DLnhCLk8yKGEscysxKQppZigobCY2NDUxMik9PT01NjMyMCl7cD0ocCYx
+MDIzKTw8MTB8bCYxMDIzfDY1NTM2Cms9Mn1lbHNlIGs9MX1lbHNlIGs9MQpqPUMueEIuTmooYSxyLHMp
+CmlmKGk9PW51bGwpe2k9bmV3IFAuUm4oIiIpCm49aX1lbHNlIG49aQpuLmErPWoKbi5hKz1QLnpYKHAp
+CnMrPWsKcj1zfX19aWYoaT09bnVsbClyZXR1cm4gQy54Qi5OaihhLGIsYykKaWYocjxjKWkuYSs9Qy54
+Qi5OaihhLHIsYykKbj1pLmEKcmV0dXJuIG4uY2hhckNvZGVBdCgwKT09MD9uOm59LApPTDpmdW5jdGlv
+bihhLGIsYyl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaQpmb3Iocz1iLHI9cyxxPW51bGwscD0hMDtz
+PGM7KXtvPUMueEIuTzIoYSxzKQppZihvPT09Mzcpe249UC5ydihhLHMsITApCm09bj09bnVsbAppZiht
+JiZwKXtzKz0zCmNvbnRpbnVlfWlmKHE9PW51bGwpcT1uZXcgUC5SbigiIikKbD1DLnhCLk5qKGEscixz
+KQprPXEuYSs9IXA/bC50b0xvd2VyQ2FzZSgpOmwKaWYobSl7bj1DLnhCLk5qKGEscyxzKzMpCmo9M31l
+bHNlIGlmKG49PT0iJSIpe249IiUyNSIKaj0xfWVsc2Ugaj0zCnEuYT1rK24Kcys9agpyPXMKcD0hMH1l
+bHNle2lmKG88MTI3KXttPW8+Pj40CmlmKG0+PTgpcmV0dXJuIEguT0goQy5lYSxtKQptPShDLmVhW21d
+JjE8PChvJjE1KSkhPT0wfWVsc2UgbT0hMQppZihtKXtpZihwJiY2NTw9byYmOTA+PW8pe2lmKHE9PW51
+bGwpcT1uZXcgUC5SbigiIikKaWYocjxzKXtxLmErPUMueEIuTmooYSxyLHMpCnI9c31wPSExfSsrc31l
+bHNle2lmKG88PTkzKXttPW8+Pj40CmlmKG0+PTgpcmV0dXJuIEguT0goQy5hayxtKQptPShDLmFrW21d
+JjE8PChvJjE1KSkhPT0wfWVsc2UgbT0hMQppZihtKXtQLlIzKGEscywiSW52YWxpZCBjaGFyYWN0ZXIi
+KQpILkJpKHUuZyl9ZWxzZXtpZigobyY2NDUxMik9PT01NTI5NiYmcysxPGMpe2k9Qy54Qi5PMihhLHMr
+MSkKaWYoKGkmNjQ1MTIpPT09NTYzMjApe289KG8mMTAyMyk8PDEwfGkmMTAyM3w2NTUzNgpqPTJ9ZWxz
+ZSBqPTF9ZWxzZSBqPTEKbD1DLnhCLk5qKGEscixzKQppZighcClsPWwudG9Mb3dlckNhc2UoKQppZihx
+PT1udWxsKXtxPW5ldyBQLlJuKCIiKQptPXF9ZWxzZSBtPXEKbS5hKz1sCm0uYSs9UC56WChvKQpzKz1q
+CnI9c319fX1pZihxPT1udWxsKXJldHVybiBDLnhCLk5qKGEsYixjKQppZihyPGMpe2w9Qy54Qi5Oaihh
+LHIsYykKcS5hKz0hcD9sLnRvTG93ZXJDYXNlKCk6bH1tPXEuYQpyZXR1cm4gbS5jaGFyQ29kZUF0KDAp
+PT0wP206bX0sClBpOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscCxvPXUuZwppZihiPT09YylyZXR1
+cm4iIgppZighUC5FdChKLnJZKGEpLlcoYSxiKSkpe1AuUjMoYSxiLCJTY2hlbWUgbm90IHN0YXJ0aW5n
+IHdpdGggYWxwaGFiZXRpYyBjaGFyYWN0ZXIiKQpILkJpKG8pfWZvcihzPWIscj0hMTtzPGM7KytzKXtx
+PUMueEIuVyhhLHMpCmlmKHE8MTI4KXtwPXE+Pj40CmlmKHA+PTgpcmV0dXJuIEguT0goQy5tSyxwKQpw
+PShDLm1LW3BdJjE8PChxJjE1KSkhPT0wfWVsc2UgcD0hMQppZighcCl7UC5SMyhhLHMsIklsbGVnYWwg
+c2NoZW1lIGNoYXJhY3RlciIpCkguQmkobyl9aWYoNjU8PXEmJnE8PTkwKXI9ITB9YT1DLnhCLk5qKGEs
+YixjKQpyZXR1cm4gUC5ZYShyP2EudG9Mb3dlckNhc2UoKTphKX0sCllhOmZ1bmN0aW9uKGEpe2lmKGE9
+PT0iaHR0cCIpcmV0dXJuImh0dHAiCmlmKGE9PT0iZmlsZSIpcmV0dXJuImZpbGUiCmlmKGE9PT0iaHR0
+cHMiKXJldHVybiJodHRwcyIKaWYoYT09PSJwYWNrYWdlIilyZXR1cm4icGFja2FnZSIKcmV0dXJuIGF9
+LAp6UjpmdW5jdGlvbihhLGIsYyl7aWYoYT09bnVsbClyZXR1cm4iIgpyZXR1cm4gUC5QSShhLGIsYyxD
+LnRvLCExKX0sCmthOmZ1bmN0aW9uKGEsYixjLGQsZSxmKXt2YXIgcyxyLHE9ZT09PSJmaWxlIixwPXF8
+fGYKaWYoYT09bnVsbCl7aWYoZD09bnVsbClyZXR1cm4gcT8iLyI6IiIKcz1ILnQ2KGQpCnI9bmV3IEgu
+bEooZCxzLkMoInFVKDEpIikuYShuZXcgUC5SWigpKSxzLkMoImxKPDEscVU+IikpLmsoMCwiLyIpfWVs
+c2UgaWYoZCE9bnVsbCl0aHJvdyBILmIoUC54WSgiQm90aCBwYXRoIGFuZCBwYXRoU2VnbWVudHMgc3Bl
+Y2lmaWVkIikpCmVsc2Ugcj1QLlBJKGEsYixjLEMuV2QsITApCmlmKHIubGVuZ3RoPT09MCl7aWYocSly
+ZXR1cm4iLyJ9ZWxzZSBpZihwJiYhQy54Qi5uQyhyLCIvIikpcj0iLyIrcgpyZXR1cm4gUC5KcihyLGUs
+Zil9LApKcjpmdW5jdGlvbihhLGIsYyl7dmFyIHM9Yi5sZW5ndGg9PT0wCmlmKHMmJiFjJiYhQy54Qi5u
+QyhhLCIvIikpcmV0dXJuIFAud0YoYSwhc3x8YykKcmV0dXJuIFAueGUoYSl9LApsZTpmdW5jdGlvbihh
+LGIsYyxkKXt2YXIgcyxyPXt9CmlmKGEhPW51bGwpe2lmKGQhPW51bGwpdGhyb3cgSC5iKFAueFkoIkJv
+dGggcXVlcnkgYW5kIHF1ZXJ5UGFyYW1ldGVycyBzcGVjaWZpZWQiKSkKcmV0dXJuIFAuUEkoYSxiLGMs
+Qy5WQywhMCl9aWYoZD09bnVsbClyZXR1cm4gbnVsbApzPW5ldyBQLlJuKCIiKQpyLmE9IiIKZC5LKDAs
+bmV3IFAueTUobmV3IFAuTUUocixzKSkpCnI9cy5hCnJldHVybiByLmNoYXJDb2RlQXQoMCk9PTA/cjpy
+fSwKdEc6ZnVuY3Rpb24oYSxiLGMpe2lmKGE9PW51bGwpcmV0dXJuIG51bGwKcmV0dXJuIFAuUEkoYSxi
+LGMsQy5WQywhMCl9LApydjpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHAsbyxuPWIrMgppZihuPj1h
+Lmxlbmd0aClyZXR1cm4iJSIKcz1DLnhCLk8yKGEsYisxKQpyPUMueEIuTzIoYSxuKQpxPUgub28ocykK
+cD1ILm9vKHIpCmlmKHE8MHx8cDwwKXJldHVybiIlIgpvPXEqMTYrcAppZihvPDEyNyl7bj1DLmpuLndH
+KG8sNCkKaWYobj49OClyZXR1cm4gSC5PSChDLkYzLG4pCm49KEMuRjNbbl0mMTw8KG8mMTUpKSE9PTB9
+ZWxzZSBuPSExCmlmKG4pcmV0dXJuIEguTHcoYyYmNjU8PW8mJjkwPj1vPyhvfDMyKT4+PjA6bykKaWYo
+cz49OTd8fHI+PTk3KXJldHVybiBDLnhCLk5qKGEsYixiKzMpLnRvVXBwZXJDYXNlKCkKcmV0dXJuIG51
+bGx9LAp6WDpmdW5jdGlvbihhKXt2YXIgcyxyLHEscCxvLG4sbSxsLGs9IjAxMjM0NTY3ODlBQkNERUYi
+CmlmKGE8MTI4KXtzPW5ldyBVaW50OEFycmF5KDMpCnNbMF09MzcKc1sxXT1DLnhCLlcoayxhPj4+NCkK
+c1syXT1DLnhCLlcoayxhJjE1KX1lbHNle2lmKGE+MjA0NylpZihhPjY1NTM1KXtyPTI0MApxPTR9ZWxz
+ZXtyPTIyNApxPTN9ZWxzZXtyPTE5MgpxPTJ9cD0zKnEKcz1uZXcgVWludDhBcnJheShwKQpmb3Iobz0w
+Oy0tcSxxPj0wO3I9MTI4KXtuPUMuam4uYmYoYSw2KnEpJjYzfHIKaWYobz49cClyZXR1cm4gSC5PSChz
+LG8pCnNbb109MzcKbT1vKzEKbD1DLnhCLlcoayxuPj4+NCkKaWYobT49cClyZXR1cm4gSC5PSChzLG0p
+CnNbbV09bApsPW8rMgptPUMueEIuVyhrLG4mMTUpCmlmKGw+PXApcmV0dXJuIEguT0gocyxsKQpzW2xd
+PW0Kbys9M319cmV0dXJuIFAuSE0ocywwLG51bGwpfSwKUEk6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIg
+cz1QLlVsKGEsYixjLGQsZSkKcmV0dXJuIHM9PW51bGw/Qy54Qi5OaihhLGIsYyk6c30sClVsOmZ1bmN0
+aW9uKGEsYixjLGQsZSl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGo9bnVsbApmb3Iocz0hZSxyPWIscT1y
+LHA9ajtyPGM7KXtvPUMueEIuTzIoYSxyKQppZihvPDEyNyl7bj1vPj4+NAppZihuPj04KXJldHVybiBI
+Lk9IKGQsbikKbj0oZFtuXSYxPDwobyYxNSkpIT09MH1lbHNlIG49ITEKaWYobikrK3IKZWxzZXtpZihv
+PT09Mzcpe209UC5ydihhLHIsITEpCmlmKG09PW51bGwpe3IrPTMKY29udGludWV9aWYoIiUiPT09bSl7
+bT0iJTI1IgpsPTF9ZWxzZSBsPTN9ZWxzZXtpZihzKWlmKG88PTkzKXtuPW8+Pj40CmlmKG4+PTgpcmV0
+dXJuIEguT0goQy5hayxuKQpuPShDLmFrW25dJjE8PChvJjE1KSkhPT0wfWVsc2Ugbj0hMQplbHNlIG49
+ITEKaWYobil7UC5SMyhhLHIsIkludmFsaWQgY2hhcmFjdGVyIikKSC5CaSh1LmcpCmw9agptPWx9ZWxz
+ZXtpZigobyY2NDUxMik9PT01NTI5Nil7bj1yKzEKaWYobjxjKXtrPUMueEIuTzIoYSxuKQppZigoayY2
+NDUxMik9PT01NjMyMCl7bz0obyYxMDIzKTw8MTB8ayYxMDIzfDY1NTM2Cmw9Mn1lbHNlIGw9MX1lbHNl
+IGw9MX1lbHNlIGw9MQptPVAuelgobyl9fWlmKHA9PW51bGwpe3A9bmV3IFAuUm4oIiIpCm49cH1lbHNl
+IG49cApuLmErPUMueEIuTmooYSxxLHIpCm4uYSs9SC5FaihtKQppZih0eXBlb2YgbCE9PSJudW1iZXIi
+KXJldHVybiBILnBZKGwpCnIrPWwKcT1yfX1pZihwPT1udWxsKXJldHVybiBqCmlmKHE8YylwLmErPUMu
+eEIuTmooYSxxLGMpCnM9cC5hCnJldHVybiBzLmNoYXJDb2RlQXQoMCk9PTA/czpzfSwKeUI6ZnVuY3Rp
+b24oYSl7aWYoQy54Qi5uQyhhLCIuIikpcmV0dXJuITAKcmV0dXJuIEMueEIuT1koYSwiLy4iKSE9PS0x
+fSwKeGU6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG0KaWYoIVAueUIoYSkpcmV0dXJuIGEKcz1I
+LlZNKFtdLHQucykKZm9yKHI9YS5zcGxpdCgiLyIpLHE9ci5sZW5ndGgscD0hMSxvPTA7bzxxOysrbyl7
+bj1yW29dCmlmKEouUk0obiwiLi4iKSl7bT1zLmxlbmd0aAppZihtIT09MCl7aWYoMD49bSlyZXR1cm4g
+SC5PSChzLC0xKQpzLnBvcCgpCmlmKHMubGVuZ3RoPT09MClDLk5tLmkocywiIil9cD0hMH1lbHNlIGlm
+KCIuIj09PW4pcD0hMAplbHNle0MuTm0uaShzLG4pCnA9ITF9fWlmKHApQy5ObS5pKHMsIiIpCnJldHVy
+biBDLk5tLmsocywiLyIpfSwKd0Y6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4KaWYoIVAueUIo
+YSkpcmV0dXJuIWI/UC5DMShhKTphCnM9SC5WTShbXSx0LnMpCmZvcihyPWEuc3BsaXQoIi8iKSxxPXIu
+bGVuZ3RoLHA9ITEsbz0wO288cTsrK28pe249cltvXQppZigiLi4iPT09bilpZihzLmxlbmd0aCE9PTAm
+JkMuTm0uZ3JaKHMpIT09Ii4uIil7aWYoMD49cy5sZW5ndGgpcmV0dXJuIEguT0gocywtMSkKcy5wb3Ao
+KQpwPSEwfWVsc2V7Qy5ObS5pKHMsIi4uIikKcD0hMX1lbHNlIGlmKCIuIj09PW4pcD0hMAplbHNle0Mu
+Tm0uaShzLG4pCnA9ITF9fXI9cy5sZW5ndGgKaWYociE9PTApaWYocj09PTEpe2lmKDA+PXIpcmV0dXJu
+IEguT0gocywwKQpyPXNbMF0ubGVuZ3RoPT09MH1lbHNlIHI9ITEKZWxzZSByPSEwCmlmKHIpcmV0dXJu
+Ii4vIgppZihwfHxDLk5tLmdyWihzKT09PSIuLiIpQy5ObS5pKHMsIiIpCmlmKCFiKXtpZigwPj1zLmxl
+bmd0aClyZXR1cm4gSC5PSChzLDApCkMuTm0uWTUocywwLFAuQzEoc1swXSkpfXJldHVybiBDLk5tLmso
+cywiLyIpfSwKQzE6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHA9YS5sZW5ndGgKaWYocD49MiYmUC5FdChK
+LlF6KGEsMCkpKWZvcihzPTE7czxwOysrcyl7cj1DLnhCLlcoYSxzKQppZihyPT09NTgpcmV0dXJuIEMu
+eEIuTmooYSwwLHMpKyIlM0EiK0MueEIueW4oYSxzKzEpCmlmKHI8PTEyNyl7cT1yPj4+NAppZihxPj04
+KXJldHVybiBILk9IKEMubUsscSkKcT0oQy5tS1txXSYxPDwociYxNSkpPT09MH1lbHNlIHE9ITAKaWYo
+cSlicmVha31yZXR1cm4gYX0sCm1uOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPWEuZ0ZqKCksbz1wLmxl
+bmd0aAppZihvPjAmJkouSG0ocFswXSk9PT0yJiZKLmE2KHBbMF0sMSk9PT01OCl7aWYoMD49bylyZXR1
+cm4gSC5PSChwLDApClAucmcoSi5hNihwWzBdLDApLCExKQpQLkhOKHAsITEsMSkKcz0hMH1lbHNle1Au
+SE4ocCwhMSwwKQpzPSExfXI9YS5ndFQoKSYmIXM/IlxcIjoiIgppZihhLmdjaigpKXtxPWEuZ0pmKGEp
+CmlmKHEubGVuZ3RoIT09MClyPXIrIlxcIitxKyJcXCJ9cj1QLnZnKHIscCwiXFwiKQpvPXMmJm89PT0x
+P3IrIlxcIjpyCnJldHVybiBvLmNoYXJDb2RlQXQoMCk9PTA/bzpvfSwKSWg6ZnVuY3Rpb24oYSxiKXt2
+YXIgcyxyLHEKZm9yKHM9MCxyPTA7cjwyOysrcil7cT1DLnhCLlcoYSxiK3IpCmlmKDQ4PD1xJiZxPD01
+NylzPXMqMTYrcS00OAplbHNle3F8PTMyCmlmKDk3PD1xJiZxPD0xMDIpcz1zKjE2K3EtODcKZWxzZSB0
+aHJvdyBILmIoUC54WSgiSW52YWxpZCBVUkwgZW5jb2RpbmciKSl9fXJldHVybiBzfSwKa3U6ZnVuY3Rp
+b24oYSxiLGMsZCxlKXt2YXIgcyxyLHEscCxvPUouclkoYSksbj1iCndoaWxlKCEwKXtpZighKG48Yykp
+e3M9ITAKYnJlYWt9cj1vLlcoYSxuKQppZihyPD0xMjcpaWYociE9PTM3KXE9ZSYmcj09PTQzCmVsc2Ug
+cT0hMAplbHNlIHE9ITAKaWYocSl7cz0hMQpicmVha30rK259aWYocyl7aWYoQy54TSE9PWQpcT0hMQpl
+bHNlIHE9ITAKaWYocSlyZXR1cm4gby5OaihhLGIsYykKZWxzZSBwPW5ldyBILnFqKG8uTmooYSxiLGMp
+KX1lbHNle3A9SC5WTShbXSx0LmEpCmZvcihuPWI7bjxjOysrbil7cj1vLlcoYSxuKQppZihyPjEyNyl0
+aHJvdyBILmIoUC54WSgiSWxsZWdhbCBwZXJjZW50IGVuY29kaW5nIGluIFVSSSIpKQppZihyPT09Mzcp
+e2lmKG4rMz5hLmxlbmd0aCl0aHJvdyBILmIoUC54WSgiVHJ1bmNhdGVkIFVSSSIpKQpDLk5tLmkocCxQ
+LkloKGEsbisxKSkKbis9Mn1lbHNlIGlmKGUmJnI9PT00MylDLk5tLmkocCwzMikKZWxzZSBDLk5tLmko
+cCxyKX19dC5MLmEocCkKcmV0dXJuIEMub0UuV0oocCl9LApFdDpmdW5jdGlvbihhKXt2YXIgcz1hfDMy
+CnJldHVybiA5Nzw9cyYmczw9MTIyfSwKS0Q6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscSxwLG8sbixt
+LGwsaz0iSW52YWxpZCBNSU1FIHR5cGUiLGo9SC5WTShbYi0xXSx0LmEpCmZvcihzPWEubGVuZ3RoLHI9
+YixxPS0xLHA9bnVsbDtyPHM7KytyKXtwPUMueEIuVyhhLHIpCmlmKHA9PT00NHx8cD09PTU5KWJyZWFr
+CmlmKHA9PT00Nyl7aWYocTwwKXtxPXIKY29udGludWV9dGhyb3cgSC5iKFAucnIoayxhLHIpKX19aWYo
+cTwwJiZyPmIpdGhyb3cgSC5iKFAucnIoayxhLHIpKQpmb3IoO3AhPT00NDspe0MuTm0uaShqLHIpOysr
+cgpmb3Iobz0tMTtyPHM7KytyKXtwPUMueEIuVyhhLHIpCmlmKHA9PT02MSl7aWYobzwwKW89cn1lbHNl
+IGlmKHA9PT01OXx8cD09PTQ0KWJyZWFrfWlmKG8+PTApQy5ObS5pKGosbykKZWxzZXtuPUMuTm0uZ3Ja
+KGopCmlmKHAhPT00NHx8ciE9PW4rN3x8IUMueEIuUWkoYSwiYmFzZTY0IixuKzEpKXRocm93IEguYihQ
+LnJyKCJFeHBlY3RpbmcgJz0nIixhLHIpKQpicmVha319Qy5ObS5pKGoscikKbT1yKzEKaWYoKGoubGVu
+Z3RoJjEpPT09MSlhPUMuaDkueXIoYSxtLHMpCmVsc2V7bD1QLlVsKGEsbSxzLEMuVkMsITApCmlmKGwh
+PW51bGwpYT1DLnhCLmk3KGEsbSxzLGwpfXJldHVybiBuZXcgUC5QRShhLGosYyl9LApLTjpmdW5jdGlv
+bigpe3ZhciBzLHIscSxwLG8sbixtPSIwMTIzNDU2Nzg5QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVph
+YmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ei0uX34hJCYnKCkqKyw7PSIsbD0iLiIsaz0iOiIsaj0iLyIs
+aT0iPyIsaD0iIyIsZz1ILlZNKG5ldyBBcnJheSgyMiksdC5nTikKZm9yKHM9MDtzPDIyOysrcylnW3Nd
+PW5ldyBVaW50OEFycmF5KDk2KQpyPW5ldyBQLnlJKGcpCnE9bmV3IFAuYzYoKQpwPW5ldyBQLnFkKCkK
+bz10LmdjCm49by5hKHIuJDIoMCwyMjUpKQpxLiQzKG4sbSwxKQpxLiQzKG4sbCwxNCkKcS4kMyhuLGss
+MzQpCnEuJDMobixqLDMpCnEuJDMobixpLDE3MikKcS4kMyhuLGgsMjA1KQpuPW8uYShyLiQyKDE0LDIy
+NSkpCnEuJDMobixtLDEpCnEuJDMobixsLDE1KQpxLiQzKG4saywzNCkKcS4kMyhuLGosMjM0KQpxLiQz
+KG4saSwxNzIpCnEuJDMobixoLDIwNSkKbj1vLmEoci4kMigxNSwyMjUpKQpxLiQzKG4sbSwxKQpxLiQz
+KG4sIiUiLDIyNSkKcS4kMyhuLGssMzQpCnEuJDMobixqLDkpCnEuJDMobixpLDE3MikKcS4kMyhuLGgs
+MjA1KQpuPW8uYShyLiQyKDEsMjI1KSkKcS4kMyhuLG0sMSkKcS4kMyhuLGssMzQpCnEuJDMobixqLDEw
+KQpxLiQzKG4saSwxNzIpCnEuJDMobixoLDIwNSkKbj1vLmEoci4kMigyLDIzNSkpCnEuJDMobixtLDEz
+OSkKcS4kMyhuLGosMTMxKQpxLiQzKG4sbCwxNDYpCnEuJDMobixpLDE3MikKcS4kMyhuLGgsMjA1KQpu
+PW8uYShyLiQyKDMsMjM1KSkKcS4kMyhuLG0sMTEpCnEuJDMobixqLDY4KQpxLiQzKG4sbCwxOCkKcS4k
+MyhuLGksMTcyKQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoNCwyMjkpKQpxLiQzKG4sbSw1KQpwLiQz
+KG4sIkFaIiwyMjkpCnEuJDMobixrLDEwMikKcS4kMyhuLCJAIiw2OCkKcS4kMyhuLCJbIiwyMzIpCnEu
+JDMobixqLDEzOCkKcS4kMyhuLGksMTcyKQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoNSwyMjkpKQpx
+LiQzKG4sbSw1KQpwLiQzKG4sIkFaIiwyMjkpCnEuJDMobixrLDEwMikKcS4kMyhuLCJAIiw2OCkKcS4k
+MyhuLGosMTM4KQpxLiQzKG4saSwxNzIpCnEuJDMobixoLDIwNSkKbj1vLmEoci4kMig2LDIzMSkpCnAu
+JDMobiwiMTkiLDcpCnEuJDMobiwiQCIsNjgpCnEuJDMobixqLDEzOCkKcS4kMyhuLGksMTcyKQpxLiQz
+KG4saCwyMDUpCm49by5hKHIuJDIoNywyMzEpKQpwLiQzKG4sIjA5Iiw3KQpxLiQzKG4sIkAiLDY4KQpx
+LiQzKG4saiwxMzgpCnEuJDMobixpLDE3MikKcS4kMyhuLGgsMjA1KQpxLiQzKG8uYShyLiQyKDgsOCkp
+LCJdIiw1KQpuPW8uYShyLiQyKDksMjM1KSkKcS4kMyhuLG0sMTEpCnEuJDMobixsLDE2KQpxLiQzKG4s
+aiwyMzQpCnEuJDMobixpLDE3MikKcS4kMyhuLGgsMjA1KQpuPW8uYShyLiQyKDE2LDIzNSkpCnEuJDMo
+bixtLDExKQpxLiQzKG4sbCwxNykKcS4kMyhuLGosMjM0KQpxLiQzKG4saSwxNzIpCnEuJDMobixoLDIw
+NSkKbj1vLmEoci4kMigxNywyMzUpKQpxLiQzKG4sbSwxMSkKcS4kMyhuLGosOSkKcS4kMyhuLGksMTcy
+KQpxLiQzKG4saCwyMDUpCm49by5hKHIuJDIoMTAsMjM1KSkKcS4kMyhuLG0sMTEpCnEuJDMobixsLDE4
+KQpxLiQzKG4saiwyMzQpCnEuJDMobixpLDE3MikKcS4kMyhuLGgsMjA1KQpuPW8uYShyLiQyKDE4LDIz
+NSkpCnEuJDMobixtLDExKQpxLiQzKG4sbCwxOSkKcS4kMyhuLGosMjM0KQpxLiQzKG4saSwxNzIpCnEu
+JDMobixoLDIwNSkKbj1vLmEoci4kMigxOSwyMzUpKQpxLiQzKG4sbSwxMSkKcS4kMyhuLGosMjM0KQpx
+LiQzKG4saSwxNzIpCnEuJDMobixoLDIwNSkKbj1vLmEoci4kMigxMSwyMzUpKQpxLiQzKG4sbSwxMSkK
+cS4kMyhuLGosMTApCnEuJDMobixpLDE3MikKcS4kMyhuLGgsMjA1KQpuPW8uYShyLiQyKDEyLDIzNikp
+CnEuJDMobixtLDEyKQpxLiQzKG4saSwxMikKcS4kMyhuLGgsMjA1KQpuPW8uYShyLiQyKDEzLDIzNykp
+CnEuJDMobixtLDEzKQpxLiQzKG4saSwxMykKcC4kMyhvLmEoci4kMigyMCwyNDUpKSwiYXoiLDIxKQpy
+PW8uYShyLiQyKDIxLDI0NSkpCnAuJDMociwiYXoiLDIxKQpwLiQzKHIsIjA5IiwyMSkKcS4kMyhyLCIr
+LS4iLDIxKQpyZXR1cm4gZ30sClVCOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHMscixxLHAsbyxuPSQu
+dlooKQpmb3Iocz1KLnJZKGEpLHI9YjtyPGM7KytyKXtpZihkPDB8fGQ+PW4ubGVuZ3RoKXJldHVybiBI
+Lk9IKG4sZCkKcT1uW2RdCnA9cy5XKGEscileOTYKbz1xW3A+OTU/MzE6cF0KZD1vJjMxCkMuTm0uWTUo
+ZSxvPj4+NSxyKX1yZXR1cm4gZH0sCldGOmZ1bmN0aW9uIFdGKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9
+LAppUDpmdW5jdGlvbiBpUChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKWFM6ZnVuY3Rpb24gWFMoKXt9
+LApDNjpmdW5jdGlvbiBDNihhKXt0aGlzLmE9YX0sCkV6OmZ1bmN0aW9uIEV6KCl7fSwKRjpmdW5jdGlv
+biBGKCl7fSwKdTpmdW5jdGlvbiB1KGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMK
+Xy5kPWR9LApiSjpmdW5jdGlvbiBiSihhLGIsYyxkLGUsZil7dmFyIF89dGhpcwpfLmU9YQpfLmY9Ygpf
+LmE9YwpfLmI9ZApfLmM9ZQpfLmQ9Zn0sCmVZOmZ1bmN0aW9uIGVZKGEsYixjLGQsZSl7dmFyIF89dGhp
+cwpfLmY9YQpfLmE9YgpfLmI9YwpfLmM9ZApfLmQ9ZX0sCm1wOmZ1bmN0aW9uIG1wKGEsYixjLGQpe3Zh
+ciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWR9LAp1YjpmdW5jdGlvbiB1YihhKXt0aGlzLmE9
+YX0sCmRzOmZ1bmN0aW9uIGRzKGEpe3RoaXMuYT1hfSwKbGo6ZnVuY3Rpb24gbGooYSl7dGhpcy5hPWF9
+LApVVjpmdW5jdGlvbiBVVihhKXt0aGlzLmE9YX0sCms1OmZ1bmN0aW9uIGs1KCl7fSwKS1k6ZnVuY3Rp
+b24gS1koKXt9LApjOmZ1bmN0aW9uIGMoYSl7dGhpcy5hPWF9LApDRDpmdW5jdGlvbiBDRChhKXt0aGlz
+LmE9YX0sCmFFOmZ1bmN0aW9uIGFFKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCmNY
+OmZ1bmN0aW9uIGNYKCl7fSwKQW46ZnVuY3Rpb24gQW4oKXt9LApOMzpmdW5jdGlvbiBOMyhhLGIsYyl7
+dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy4kdGk9Y30sCmM4OmZ1bmN0aW9uIGM4KCl7fSwKTWg6ZnVuY3Rp
+b24gTWgoKXt9LApaZDpmdW5jdGlvbiBaZCgpe30sClJuOmZ1bmN0aW9uIFJuKGEpe3RoaXMuYT1hfSwK
+bjE6ZnVuY3Rpb24gbjEoYSl7dGhpcy5hPWF9LApjUzpmdW5jdGlvbiBjUyhhKXt0aGlzLmE9YX0sClZD
+OmZ1bmN0aW9uIFZDKGEpe3RoaXMuYT1hfSwKSlQ6ZnVuY3Rpb24gSlQoYSxiKXt0aGlzLmE9YQp0aGlz
+LmI9Yn0sCkRuOmZ1bmN0aW9uIERuKGEsYixjLGQsZSxmLGcpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIK
+Xy5jPWMKXy5kPWQKXy5lPWUKXy5mPWYKXy5yPWcKXy54PW51bGwKXy55PSExCl8uej1udWxsCl8uUT0h
+MQpfLmNoPW51bGwKXy5jeD0hMQpfLmN5PW51bGwKXy5kYj0hMX0sClJaOmZ1bmN0aW9uIFJaKCl7fSwK
+TUU6ZnVuY3Rpb24gTUUoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCnk1OmZ1bmN0aW9uIHk1KGEpe3Ro
+aXMuYT1hfSwKUEU6ZnVuY3Rpb24gUEUoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwK
+eUk6ZnVuY3Rpb24geUkoYSl7dGhpcy5hPWF9LApjNjpmdW5jdGlvbiBjNigpe30sCnFkOmZ1bmN0aW9u
+IHFkKCl7fSwKVWY6ZnVuY3Rpb24gVWYoYSxiLGMsZCxlLGYsZyxoKXt2YXIgXz10aGlzCl8uYT1hCl8u
+Yj1iCl8uYz1jCl8uZD1kCl8uZT1lCl8uZj1mCl8ucj1nCl8ueD1oCl8ueT1udWxsfSwKcWU6ZnVuY3Rp
+b24gcWUoYSxiLGMsZCxlLGYsZyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApfLmU9
+ZQpfLmY9ZgpfLnI9ZwpfLng9bnVsbApfLnk9ITEKXy56PW51bGwKXy5RPSExCl8uY2g9bnVsbApfLmN4
+PSExCl8uY3k9bnVsbApfLmRiPSExfSwKaUo6ZnVuY3Rpb24gaUooKXt9LApqZzpmdW5jdGlvbiBqZyhh
+LGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKVGE6ZnVuY3Rpb24gVGEoYSxiKXt0aGlzLmE9YQp0aGlzLmI9
+Yn0sCkJmOmZ1bmN0aW9uIEJmKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApBczpmdW5jdGlvbiBBcygp
+e30sCkdFOmZ1bmN0aW9uIEdFKGEpe3RoaXMuYT1hfSwKTjc6ZnVuY3Rpb24gTjcoYSxiKXt0aGlzLmE9
+YQp0aGlzLmI9Yn0sCnVROmZ1bmN0aW9uIHVRKCl7fSwKaEY6ZnVuY3Rpb24gaEYoKXt9LApSNDpmdW5j
+dGlvbihhLGIsYyxkKXt2YXIgcyxyLHEKSC55OChiKQp0LmouYShkKQppZihILm9UKGIpKXtzPVtjXQpD
+Lk5tLkZWKHMsZCkKZD1zfXI9dC56CnE9UC5DSChKLk0xKGQsUC53MCgpLHIpLCEwLHIpCnQuWS5hKGEp
+CnJldHVybiBQLndZKEguRWsoYSxxLG51bGwpKX0sCkRtOmZ1bmN0aW9uKGEsYixjKXt2YXIgcwp0cnl7
+aWYoT2JqZWN0LmlzRXh0ZW5zaWJsZShhKSYmIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHku
+Y2FsbChhLGIpKXtPYmplY3QuZGVmaW5lUHJvcGVydHkoYSxiLHt2YWx1ZTpjfSkKcmV0dXJuITB9fWNh
+dGNoKHMpe0guUnUocyl9cmV0dXJuITF9LApPbTpmdW5jdGlvbihhLGIpe2lmKE9iamVjdC5wcm90b3R5
+cGUuaGFzT3duUHJvcGVydHkuY2FsbChhLGIpKXJldHVybiBhW2JdCnJldHVybiBudWxsfSwKd1k6ZnVu
+Y3Rpb24oYSl7aWYoYT09bnVsbHx8dHlwZW9mIGE9PSJzdHJpbmcifHx0eXBlb2YgYT09Im51bWJlciJ8
+fEgubChhKSlyZXR1cm4gYQppZihhIGluc3RhbmNlb2YgUC5FNClyZXR1cm4gYS5hCmlmKEguUjkoYSkp
+cmV0dXJuIGEKaWYodC5hay5iKGEpKXJldHVybiBhCmlmKGEgaW5zdGFuY2VvZiBQLmlQKXJldHVybiBI
+Lm8yKGEpCmlmKHQuWS5iKGEpKXJldHVybiBQLmhFKGEsIiRkYXJ0X2pzRnVuY3Rpb24iLG5ldyBQLlBD
+KCkpCnJldHVybiBQLmhFKGEsIl8kZGFydF9qc09iamVjdCIsbmV3IFAubXQoJC5rSSgpKSl9LApoRTpm
+dW5jdGlvbihhLGIsYyl7dmFyIHM9UC5PbShhLGIpCmlmKHM9PW51bGwpe3M9Yy4kMShhKQpQLkRtKGEs
+YixzKX1yZXR1cm4gc30sCmRVOmZ1bmN0aW9uKGEpe3ZhciBzLHIKaWYoYT09bnVsbHx8dHlwZW9mIGE9
+PSJzdHJpbmcifHx0eXBlb2YgYT09Im51bWJlciJ8fHR5cGVvZiBhPT0iYm9vbGVhbiIpcmV0dXJuIGEK
+ZWxzZSBpZihhIGluc3RhbmNlb2YgT2JqZWN0JiZILlI5KGEpKXJldHVybiBhCmVsc2UgaWYoYSBpbnN0
+YW5jZW9mIE9iamVjdCYmdC5hay5iKGEpKXJldHVybiBhCmVsc2UgaWYoYSBpbnN0YW5jZW9mIERhdGUp
+e3M9SC51UChhLmdldFRpbWUoKSkKaWYoTWF0aC5hYnMocyk8PTg2NGUxMylyPSExCmVsc2Ugcj0hMApp
+ZihyKUgudihQLnhZKCJEYXRlVGltZSBpcyBvdXRzaWRlIHZhbGlkIHJhbmdlOiAiK3MpKQpILmNiKCEx
+LCJpc1V0YyIsdC55KQpyZXR1cm4gbmV3IFAuaVAocywhMSl9ZWxzZSBpZihhLmNvbnN0cnVjdG9yPT09
+JC5rSSgpKXJldHVybiBhLm8KZWxzZSByZXR1cm4gUC5ORChhKX0sCk5EOmZ1bmN0aW9uKGEpe2lmKHR5
+cGVvZiBhPT0iZnVuY3Rpb24iKXJldHVybiBQLmlRKGEsJC53KCksbmV3IFAuTnooKSkKaWYoYSBpbnN0
+YW5jZW9mIEFycmF5KXJldHVybiBQLmlRKGEsJC5SOCgpLG5ldyBQLlFTKCkpCnJldHVybiBQLmlRKGEs
+JC5SOCgpLG5ldyBQLm5wKCkpfSwKaVE6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPVAuT20oYSxiKQppZihz
+PT1udWxsfHwhKGEgaW5zdGFuY2VvZiBPYmplY3QpKXtzPWMuJDEoYSkKUC5EbShhLGIscyl9cmV0dXJu
+IHN9LApQQzpmdW5jdGlvbiBQQygpe30sCm10OmZ1bmN0aW9uIG10KGEpe3RoaXMuYT1hfSwKTno6ZnVu
+Y3Rpb24gTnooKXt9LApRUzpmdW5jdGlvbiBRUygpe30sCm5wOmZ1bmN0aW9uIG5wKCl7fSwKRTQ6ZnVu
+Y3Rpb24gRTQoYSl7dGhpcy5hPWF9LApyNzpmdW5jdGlvbiByNyhhKXt0aGlzLmE9YX0sClR6OmZ1bmN0
+aW9uIFR6KGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCmNvOmZ1bmN0aW9uIGNvKCl7fSwKbmQ6ZnVu
+Y3Rpb24gbmQoKXt9LApLZTpmdW5jdGlvbiBLZShhKXt0aGlzLmE9YX0sCmhpOmZ1bmN0aW9uIGhpKCl7
+fX0sVz17CngzOmZ1bmN0aW9uKCl7cmV0dXJuIHdpbmRvd30sClpyOmZ1bmN0aW9uKCl7cmV0dXJuIGRv
+Y3VtZW50fSwKSjY6ZnVuY3Rpb24oYSl7dmFyIHM9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYSIpCmlm
+KGEhPW51bGwpQy54bi5zTFUocyxhKQpyZXR1cm4gc30sClU5OmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxy
+PWRvY3VtZW50LmJvZHkKci50b1N0cmluZwpzPUMuUlkucjYocixhLGIsYykKcy50b1N0cmluZwpyPXQu
+YWMKcj1uZXcgSC5VNShuZXcgVy5lNyhzKSxyLkMoImEyKGxELkUpIikuYShuZXcgVy5DdigpKSxyLkMo
+IlU1PGxELkU+IikpCnJldHVybiB0LmguYShyLmdyOChyKSl9LApyUzpmdW5jdGlvbihhKXt2YXIgcyxy
+LHE9ImVsZW1lbnQgdGFnIHVuYXZhaWxhYmxlIgp0cnl7cz1KLllFKGEpCmlmKHR5cGVvZiBzLmducyhh
+KT09InN0cmluZyIpcT1zLmducyhhKX1jYXRjaChyKXtILlJ1KHIpfXJldHVybiBxfSwKQzA6ZnVuY3Rp
+b24oYSxiKXthPWErYiY1MzY4NzA5MTEKYT1hKygoYSY1MjQyODcpPDwxMCkmNTM2ODcwOTExCnJldHVy
+biBhXmE+Pj42fSwKckU6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHM9Vy5DMChXLkMwKFcuQzAoVy5DMCgw
+LGEpLGIpLGMpLGQpLHI9cysoKHMmNjcxMDg4NjMpPDwzKSY1MzY4NzA5MTEKcl49cj4+PjExCnJldHVy
+biByKygociYxNjM4Myk8PDE1KSY1MzY4NzA5MTF9LApUTjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT1h
+LmNsYXNzTGlzdApmb3Iocz1iLmxlbmd0aCxyPTA7cjxiLmxlbmd0aDtiLmxlbmd0aD09PXN8fCgwLEgu
+bGspKGIpLCsrcilxLmFkZChiW3JdKX0sCkpFOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHM9Vy5hRihu
+ZXcgVy52TihjKSx0LkIpCmlmKHMhPW51bGwmJiEwKUouZFooYSxiLHMsITEpCnJldHVybiBuZXcgVy54
+QyhhLGIscywhMSxlLkMoInhDPDA+IikpfSwKVHc6ZnVuY3Rpb24oYSl7dmFyIHM9Vy5KNihudWxsKSxy
+PXdpbmRvdy5sb2NhdGlvbgpzPW5ldyBXLkpRKG5ldyBXLm1rKHMscikpCnMuQ1koYSkKcmV0dXJuIHN9
+LApxRDpmdW5jdGlvbihhLGIsYyxkKXt0LmguYShhKQpILmgoYikKSC5oKGMpCnQuY3IuYShkKQpyZXR1
+cm4hMH0sClFXOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIscQp0LmguYShhKQpILmgoYikKSC5oKGMp
+CnM9dC5jci5hKGQpLmEKcj1zLmEKQy54bi5zTFUocixjKQpxPXIuaG9zdG5hbWUKcz1zLmIKaWYoIShx
+PT1zLmhvc3RuYW1lJiZyLnBvcnQ9PXMucG9ydCYmci5wcm90b2NvbD09cy5wcm90b2NvbCkpaWYocT09
+PSIiKWlmKHIucG9ydD09PSIiKXtzPXIucHJvdG9jb2wKcz1zPT09IjoifHxzPT09IiJ9ZWxzZSBzPSEx
+CmVsc2Ugcz0hMQplbHNlIHM9ITAKcmV0dXJuIHN9LApCbDpmdW5jdGlvbigpe3ZhciBzPXQuTixyPVAu
+dE0oQy5ReCxzKSxxPXQuZDAuYShuZXcgVy5JQSgpKSxwPUguVk0oWyJURU1QTEFURSJdLHQucykKcz1u
+ZXcgVy5jdChyLFAuTHMocyksUC5McyhzKSxQLkxzKHMpLG51bGwpCnMuQ1kobnVsbCxuZXcgSC5sSihD
+LlF4LHEsdC5maikscCxudWxsKQpyZXR1cm4gc30sCnFjOmZ1bmN0aW9uKGEpe3ZhciBzCmlmKGE9PW51
+bGwpcmV0dXJuIG51bGwKaWYoInBvc3RNZXNzYWdlIiBpbiBhKXtzPVcuUDEoYSkKaWYodC5hUy5iKHMp
+KXJldHVybiBzCnJldHVybiBudWxsfWVsc2UgcmV0dXJuIHQuY2guYShhKX0sClAxOmZ1bmN0aW9uKGEp
+e2lmKGE9PT13aW5kb3cpcmV0dXJuIHQuY2kuYShhKQplbHNlIHJldHVybiBuZXcgVy5kVygpfSwKYUY6
+ZnVuY3Rpb24oYSxiKXt2YXIgcz0kLlgzCmlmKHM9PT1DLk5VKXJldHVybiBhCnJldHVybiBzLlB5KGEs
+Yil9LApxRTpmdW5jdGlvbiBxRSgpe30sCkdoOmZ1bmN0aW9uIEdoKCl7fSwKZlk6ZnVuY3Rpb24gZlko
+KXt9LApuQjpmdW5jdGlvbiBuQigpe30sCkF6OmZ1bmN0aW9uIEF6KCl7fSwKUVA6ZnVuY3Rpb24gUVAo
+KXt9LApueDpmdW5jdGlvbiBueCgpe30sCm9KOmZ1bmN0aW9uIG9KKCl7fSwKaWQ6ZnVuY3Rpb24gaWQo
+KXt9LApRRjpmdW5jdGlvbiBRRigpe30sCk5oOmZ1bmN0aW9uIE5oKCl7fSwKYWU6ZnVuY3Rpb24gYWUo
+KXt9LApJQjpmdW5jdGlvbiBJQigpe30sCm43OmZ1bmN0aW9uIG43KCl7fSwKd3o6ZnVuY3Rpb24gd3oo
+YSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKY3Y6ZnVuY3Rpb24gY3YoKXt9LApDdjpmdW5jdGlvbiBD
+digpe30sCmVhOmZ1bmN0aW9uIGVhKCl7fSwKRDA6ZnVuY3Rpb24gRDAoKXt9LApoSDpmdW5jdGlvbiBo
+SCgpe30sCmg0OmZ1bmN0aW9uIGg0KCl7fSwKYnI6ZnVuY3Rpb24gYnIoKXt9LApWYjpmdW5jdGlvbiBW
+Yigpe30sCmZKOmZ1bmN0aW9uIGZKKCl7fSwKd2E6ZnVuY3Rpb24gd2EoKXt9LApTZzpmdW5jdGlvbiBT
+Zygpe30sCnc3OmZ1bmN0aW9uIHc3KCl7fSwKQWo6ZnVuY3Rpb24gQWooKXt9LAplNzpmdW5jdGlvbiBl
+NyhhKXt0aGlzLmE9YX0sCnVIOmZ1bmN0aW9uIHVIKCl7fSwKQkg6ZnVuY3Rpb24gQkgoKXt9LApTTjpm
+dW5jdGlvbiBTTigpe30sCmV3OmZ1bmN0aW9uIGV3KCl7fSwKbHA6ZnVuY3Rpb24gbHAoKXt9LApUYjpm
+dW5jdGlvbiBUYigpe30sCkl2OmZ1bmN0aW9uIEl2KCl7fSwKV1A6ZnVuY3Rpb24gV1AoKXt9LAp5WTpm
+dW5jdGlvbiB5WSgpe30sCnc2OmZ1bmN0aW9uIHc2KCl7fSwKSzU6ZnVuY3Rpb24gSzUoKXt9LApDbTpm
+dW5jdGlvbiBDbSgpe30sCkNROmZ1bmN0aW9uIENRKCl7fSwKdzQ6ZnVuY3Rpb24gdzQoKXt9LApyaDpm
+dW5jdGlvbiByaCgpe30sCmNmOmZ1bmN0aW9uIGNmKCl7fSwKaTc6ZnVuY3Rpb24gaTcoYSl7dGhpcy5h
+PWF9LApTeTpmdW5jdGlvbiBTeShhKXt0aGlzLmE9YX0sCktTOmZ1bmN0aW9uIEtTKGEsYil7dGhpcy5h
+PWEKdGhpcy5iPWJ9LApBMzpmdW5jdGlvbiBBMyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKSTQ6ZnVu
+Y3Rpb24gSTQoYSl7dGhpcy5hPWF9LApGazpmdW5jdGlvbiBGayhhLGIpe3RoaXMuYT1hCnRoaXMuJHRp
+PWJ9LApSTzpmdW5jdGlvbiBSTyhhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8u
+JHRpPWR9LApldTpmdW5jdGlvbiBldShhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1j
+Cl8uJHRpPWR9LAp4QzpmdW5jdGlvbiB4QyhhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5iPWEKXy5jPWIK
+Xy5kPWMKXy5lPWQKXy4kdGk9ZX0sCnZOOmZ1bmN0aW9uIHZOKGEpe3RoaXMuYT1hfSwKSlE6ZnVuY3Rp
+b24gSlEoYSl7dGhpcy5hPWF9LApHbTpmdW5jdGlvbiBHbSgpe30sCnZEOmZ1bmN0aW9uIHZEKGEpe3Ro
+aXMuYT1hfSwKVXY6ZnVuY3Rpb24gVXYoYSl7dGhpcy5hPWF9LApFZzpmdW5jdGlvbiBFZyhhLGIsYyl7
+dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LAptNjpmdW5jdGlvbiBtNigpe30sCkVvOmZ1bmN0aW9u
+IEVvKCl7fSwKV2s6ZnVuY3Rpb24gV2soKXt9LApjdDpmdW5jdGlvbiBjdChhLGIsYyxkLGUpe3ZhciBf
+PXRoaXMKXy5lPWEKXy5hPWIKXy5iPWMKXy5jPWQKXy5kPWV9LApJQTpmdW5jdGlvbiBJQSgpe30sCk93
+OmZ1bmN0aW9uIE93KCl7fSwKVzk6ZnVuY3Rpb24gVzkoYSxiLGMpe3ZhciBfPXRoaXMKXy5hPWEKXy5i
+PWIKXy5jPS0xCl8uZD1udWxsCl8uJHRpPWN9LApkVzpmdW5jdGlvbiBkVygpe30sCm1rOmZ1bmN0aW9u
+IG1rKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApLbzpmdW5jdGlvbiBLbyhhKXt0aGlzLmE9YQp0aGlz
+LmI9ITF9LApmbTpmdW5jdGlvbiBmbShhKXt0aGlzLmE9YX0sCkxlOmZ1bmN0aW9uIExlKCl7fSwKSzc6
+ZnVuY3Rpb24gSzcoKXt9LApyQjpmdW5jdGlvbiByQigpe30sClhXOmZ1bmN0aW9uIFhXKCl7fSwKb2E6
+ZnVuY3Rpb24gb2EoKXt9fSxNPXsKT1g6ZnVuY3Rpb24oYSl7c3dpdGNoKGEpe2Nhc2UgQy5BZDpyZXR1
+cm4iQWRkIC8qPyovIGhpbnQiCmNhc2UgQy5uZTpyZXR1cm4iQWRkIC8qISovIGhpbnQiCmNhc2UgQy53
+VjpyZXR1cm4iUmVtb3ZlIC8qPyovIGhpbnQiCmNhc2UgQy5mUjpyZXR1cm4iUmVtb3ZlIC8qISovIGhp
+bnQiCmNhc2UgQy5teTpyZXR1cm4iQ2hhbmdlIHRvIC8qPyovIGhpbnQiCmNhc2UgQy5yeDpyZXR1cm4i
+Q2hhbmdlIHRvIC8qISovIGhpbnQifXJldHVybiBudWxsfSwKSDc6ZnVuY3Rpb24gSDcoYSxiKXt0aGlz
+LmE9YQp0aGlzLmI9Yn0sCllGOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbyxuLG0sbApmb3Iocz1i
+Lmxlbmd0aCxyPTE7cjxzOysrcil7aWYoYltyXT09bnVsbHx8YltyLTFdIT1udWxsKWNvbnRpbnVlCmZv
+cig7cz49MTtzPXEpe3E9cy0xCmlmKGJbcV0hPW51bGwpYnJlYWt9cD1uZXcgUC5SbigiIikKbz1hKyIo
+IgpwLmE9bwpuPUgudDYoYikKbT1uLkMoIm5IPDE+IikKbD1uZXcgSC5uSChiLDAscyxtKQpsLkhkKGIs
+MCxzLG4uYykKbT1vK25ldyBILmxKKGwsbS5DKCJxVShhTC5FKSIpLmEobmV3IE0uTm8oKSksbS5DKCJs
+SjxhTC5FLHFVPiIpKS5rKDAsIiwgIikKcC5hPW0KcC5hPW0rKCIpOiBwYXJ0ICIrKHItMSkrIiB3YXMg
+bnVsbCwgYnV0IHBhcnQgIityKyIgd2FzIG5vdC4iKQp0aHJvdyBILmIoUC54WShwLncoMCkpKX19LAps
+STpmdW5jdGlvbiBsSShhKXt0aGlzLmE9YX0sCnE3OmZ1bmN0aW9uIHE3KCl7fSwKTm86ZnVuY3Rpb24g
+Tm8oKXt9fSxVPXsKbno6ZnVuY3Rpb24oYSl7dmFyIHM9SC51UChhLnEoMCwibm9kZUlkIikpCnJldHVy
+biBuZXcgVS5MTChDLk5tLkh0KEMucmssbmV3IFUuTUQoYSkpLHMpfSwKTEw6ZnVuY3Rpb24gTEwoYSxi
+KXt0aGlzLmE9YQp0aGlzLmI9Yn0sCk1EOmZ1bmN0aW9uIE1EKGEpe3RoaXMuYT1hfSwKamY6ZnVuY3Rp
+b24oYSl7dmFyIHMscixxLHAKaWYoYT09bnVsbClzPW51bGwKZWxzZXtzPUguVk0oW10sdC5kNykKZm9y
+KHI9Si5JVCh0LlUuYShhKSk7ci5GKCk7KXtxPXIuZ2woKQpwPUouVTYocSkKcy5wdXNoKG5ldyBVLlNl
+KEguaChwLnEocSwiZGVzY3JpcHRpb24iKSksSC5oKHAucShxLCJocmVmIikpKSl9fXJldHVybiBzfSwK
+TmQ6ZnVuY3Rpb24oYSl7dmFyIHMscgppZihhPT1udWxsKXM9bnVsbAplbHNle3M9SC5WTShbXSx0LmFB
+KQpmb3Iocj1KLklUKHQuVS5hKGEpKTtyLkYoKTspcy5wdXNoKFUuTmYoci5nbCgpKSl9cmV0dXJuIHN9
+LApOZjpmdW5jdGlvbihhKXt2YXIgcz1KLlU2KGEpLHI9SC5oKHMucShhLCJkZXNjcmlwdGlvbiIpKSxx
+PUguVk0oW10sdC5hSikKZm9yKHM9Si5JVCh0LlUuYShzLnEoYSwiZW50cmllcyIpKSk7cy5GKCk7KXEu
+cHVzaChVLlJqKHMuZ2woKSkpCnJldHVybiBuZXcgVS55RChyLHEpfSwKUmo6ZnVuY3Rpb24oYSl7dmFy
+IHMscj1KLlU2KGEpLHE9SC5oKHIucShhLCJkZXNjcmlwdGlvbiIpKSxwPUguaChyLnEoYSwiZnVuY3Rp
+b24iKSksbz1yLnEoYSwibGluayIpCmlmKG89PW51bGwpbz1udWxsCmVsc2V7cz1KLlU2KG8pCm89bmV3
+IFUuTWwoSC5oKHMucShvLCJocmVmIikpLEgudVAocy5xKG8sImxpbmUiKSksSC5oKHMucShvLCJwYXRo
+IikpKX1yPXQuZksuYShyLnEoYSwiaGludEFjdGlvbnMiKSkKcj1yPT1udWxsP251bGw6Si5NMShyLG5l
+dyBVLmFOKCksdC5hWCkKcj1yPT1udWxsP251bGw6ci5icigwKQpyZXR1cm4gbmV3IFUud2IocSxwLG8s
+cj09bnVsbD9DLmRuOnIpfSwKZDI6ZnVuY3Rpb24gZDIoYSxiLGMsZCxlLGYpe3ZhciBfPXRoaXMKXy5h
+PWEKXy5iPWIKXy5jPWMKXy5kPWQKXy5lPWUKXy5mPWZ9LApTZTpmdW5jdGlvbiBTZShhLGIpe3RoaXMu
+YT1hCnRoaXMuYj1ifSwKTWw6ZnVuY3Rpb24gTWwoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMu
+Yz1jfSwKeUQ6ZnVuY3Rpb24geUQoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCndiOmZ1bmN0aW9uIHdi
+KGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWR9LAphTjpmdW5jdGlvbiBh
+Tigpe30sCmIwOmZ1bmN0aW9uIGIwKCl7fX0sQj17CndSOmZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBCLnFw
+KCIiLCIiLCIiLEMuRHgpfSwKWWY6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG0sbCxrPUguaChh
+LnEoMCwicmVnaW9ucyIpKSxqPUguaChhLnEoMCwibmF2aWdhdGlvbkNvbnRlbnQiKSksaT1ILmgoYS5x
+KDAsInNvdXJjZUNvZGUiKSksaD1QLkZsKHQuWCx0LmRfKQpmb3Iocz10LnQuYShhLnEoMCwiZWRpdHMi
+KSkscz1zLmdQdShzKSxzPXMuZ20ocykscj10LlUscT10Lmg0O3MuRigpOyl7cD1zLmdsKCkKbz1wLmEK
+bj1ILlZNKFtdLHEpCmZvcihwPUouSVQoci5hKHAuYikpO3AuRigpOyl7bT1wLmdsKCkKbD1KLlU2KG0p
+Cm4ucHVzaChuZXcgQi5qOChILnVQKGwucShtLCJsaW5lIikpLEguaChsLnEobSwiZXhwbGFuYXRpb24i
+KSksSC51UChsLnEobSwib2Zmc2V0IikpKSl9aC5ZNSgwLG8sbil9cmV0dXJuIG5ldyBCLnFwKGssaixp
+LGgpfSwKajg6ZnVuY3Rpb24gajgoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKcXA6
+ZnVuY3Rpb24gcXAoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZH0sCmZ2
+OmZ1bmN0aW9uIGZ2KCl7fSwKT1M6ZnVuY3Rpb24oYSl7dmFyIHMKaWYoIShhPj02NSYmYTw9OTApKXM9
+YT49OTcmJmE8PTEyMgplbHNlIHM9ITAKcmV0dXJuIHN9LApZdTpmdW5jdGlvbihhLGIpe3ZhciBzPWEu
+bGVuZ3RoLHI9YisyCmlmKHM8cilyZXR1cm4hMQppZighQi5PUyhDLnhCLk8yKGEsYikpKXJldHVybiEx
+CmlmKEMueEIuTzIoYSxiKzEpIT09NTgpcmV0dXJuITEKaWYocz09PXIpcmV0dXJuITAKcmV0dXJuIEMu
+eEIuTzIoYSxyKT09PTQ3fX0sVD17bVE6ZnVuY3Rpb24gbVEoKXt9fSxMPXsKSXE6ZnVuY3Rpb24oKXtD
+LkJaLkIoZG9jdW1lbnQsIkRPTUNvbnRlbnRMb2FkZWQiLG5ldyBMLmUoKSkKQy5vbC5CKHdpbmRvdywi
+cG9wc3RhdGUiLG5ldyBMLkwoKSl9LAprejpmdW5jdGlvbihhKXt2YXIgcyxyPXQuZy5hKGEucGFyZW50
+Tm9kZSkucXVlcnlTZWxlY3RvcigiOnNjb3BlID4gdWwiKSxxPXIuc3R5bGUscD0iIitDLkNELnpRKHIu
+b2Zmc2V0SGVpZ2h0KSoyKyJweCIKcS5tYXhIZWlnaHQ9cApxPUoucUYoYSkKcD1xLiR0aQpzPXAuQygi
+figxKT8iKS5hKG5ldyBMLld4KHIsYSkpCnQuWi5hKG51bGwpClcuSkUocS5hLHEuYixzLCExLHAuYyl9
+LAp5WDpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixtPSJxdWVyeVNlbGVjdG9yQWxsIixsPWRv
+Y3VtZW50LnF1ZXJ5U2VsZWN0b3IoYSksaz10LmcKbC50b1N0cmluZwpzPXQuaApILkRoKGsscywiVCIs
+bSkKcj10LlIKcT1uZXcgVy53eihsLnF1ZXJ5U2VsZWN0b3JBbGwoIi5uYXYtbGluayIpLHIpCnEuSyhx
+LG5ldyBMLkFPKGIpKQpILkRoKGsscywiVCIsbSkKcD1uZXcgVy53eihsLnF1ZXJ5U2VsZWN0b3JBbGwo
+Ii5yZWdpb24iKSxyKQppZighcC5nbDAocCkpe289bC5xdWVyeVNlbGVjdG9yKCJ0YWJsZVtkYXRhLXBh
+dGhdIikKby50b1N0cmluZwpwLksocCxuZXcgTC5IbyhvLmdldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBX
+LlN5KG5ldyBXLmk3KG8pKS5QKCJwYXRoIikpKSl9SC5EaChrLHMsIlQiLG0pCm49bmV3IFcud3oobC5x
+dWVyeVNlbGVjdG9yQWxsKCIuYWRkLWhpbnQtbGluayIpLHIpCm4uSyhuLG5ldyBMLklDKCkpfSwKUTY6
+ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPW5ldyBYTUxIdHRwUmVxdWVzdCgpCkMuRHQuZW8ocywiR0VUIixM
+LlE0KGEsYiksITApCnMuc2V0UmVxdWVzdEhlYWRlcigiQ29udGVudC1UeXBlIiwiYXBwbGljYXRpb24v
+anNvbjsgY2hhcnNldD1VVEYtOCIpCnJldHVybiBMLkxVKHMsbnVsbCxjLkMoIjAqIikpfSwKdHk6ZnVu
+Y3Rpb24oYSxiKXt2YXIgcz1uZXcgWE1MSHR0cFJlcXVlc3QoKSxyPXQuWApDLkR0LmVvKHMsIlBPU1Qi
+LEwuUTQoYSxQLkZsKHIscikpLCEwKQpzLnNldFJlcXVlc3RIZWFkZXIoIkNvbnRlbnQtVHlwZSIsImFw
+cGxpY2F0aW9uL2pzb247IGNoYXJzZXQ9VVRGLTgiKQpyZXR1cm4gTC5MVShzLGIsdC50KX0sCkxVOmZ1
+bmN0aW9uKGEsYixjKXtyZXR1cm4gTC5UZyhhLGIsYyxjLkMoIjAqIikpfSwKVGc6ZnVuY3Rpb24oYSxi
+LGMsZCl7dmFyIHM9MCxyPVAuRlgoZCkscSxwPTIsbyxuPVtdLG0sbCxrLGosaSxoLGcsZgp2YXIgJGFz
+eW5jJExVPVAubHooZnVuY3Rpb24oZSxhMCl7aWYoZT09PTEpe289YTAKcz1wfXdoaWxlKHRydWUpc3dp
+dGNoKHMpe2Nhc2UgMDppPW5ldyBQLlpmKG5ldyBQLnZzKCQuWDMsdC5nViksdC5iQykKaD10LmViCmc9
+aC5hKG5ldyBMLmZDKGksYSkpCnQuWi5hKG51bGwpCmw9dC5lUQpXLkpFKGEsImxvYWQiLGcsITEsbCkK
+Vy5KRShhLCJlcnJvciIsaC5hKGkuZ1lKKCkpLCExLGwpCmEuc2VuZChiPT1udWxsP251bGw6Qy5DdC5P
+QihiLG51bGwpKQpwPTQKcz03CnJldHVybiBQLmpRKGkuYSwkYXN5bmMkTFUpCmNhc2UgNzpwPTIKcz02
+CmJyZWFrCmNhc2UgNDpwPTMKZj1vCkguUnUoZikKbT1ILnRzKGYpCmg9UC5UbCgiRXJyb3IgcmVhY2hp
+bmcgbWlncmF0aW9uIHByZXZpZXcgc2VydmVyLiIsbSkKdGhyb3cgSC5iKGgpCnM9NgpicmVhawpjYXNl
+IDM6cz0yCmJyZWFrCmNhc2UgNjpqPUMuQ3QucFcoMCxhLnJlc3BvbnNlVGV4dCxudWxsKQppZihhLnN0
+YXR1cz09PTIwMCl7cT1jLkMoIjAqIikuYShqKQpzPTEKYnJlYWt9ZWxzZSB0aHJvdyBILmIoaikKY2Fz
+ZSAxOnJldHVybiBQLnlDKHEscikKY2FzZSAyOnJldHVybiBQLmYzKG8scil9fSkKcmV0dXJuIFAuREko
+JGFzeW5jJExVLHIpfSwKYUs6ZnVuY3Rpb24oYSl7dmFyIHM9UC5oSyhhKS5naFkoKS5xKDAsImxpbmUi
+KQpyZXR1cm4gcz09bnVsbD9udWxsOkguSHAocyxudWxsKX0sCkc2OmZ1bmN0aW9uKGEpe3ZhciBzPVAu
+aEsoYSkuZ2hZKCkucSgwLCJvZmZzZXQiKQpyZXR1cm4gcz09bnVsbD9udWxsOkguSHAocyxudWxsKX0s
+Cmk2OmZ1bmN0aW9uKGEpe3JldHVybiBMLm5XKHQuTy5hKGEpKX0sCm5XOmZ1bmN0aW9uKGEpe3ZhciBz
+PTAscj1QLkZYKHQueikscT0xLHAsbz1bXSxuLG0sbCxrLGosaSxoCnZhciAkYXN5bmMkaTY9UC5seihm
+dW5jdGlvbihiLGMpe2lmKGI9PT0xKXtwPWMKcz1xfXdoaWxlKHRydWUpc3dpdGNoKHMpe2Nhc2UgMDpp
+PXQuZy5hKFcucWMoYS5jdXJyZW50VGFyZ2V0KSkuZ2V0QXR0cmlidXRlKCJocmVmIikKYS5wcmV2ZW50
+RGVmYXVsdCgpCnE9MwprPWRvY3VtZW50Cm49Qy5DRC56UShrLnF1ZXJ5U2VsZWN0b3IoIi5jb250ZW50
+Iikuc2Nyb2xsVG9wKQpzPTYKcmV0dXJuIFAualEoTC50eShpLG51bGwpLCRhc3luYyRpNikKY2FzZSA2
+OnM9NwpyZXR1cm4gUC5qUShMLkc3KHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSxudWxsLG51bGwsITEs
+bnVsbCksJGFzeW5jJGk2KQpjYXNlIDc6az1rLnF1ZXJ5U2VsZWN0b3IoIi5jb250ZW50IikKay50b1N0
+cmluZwprLnNjcm9sbFRvcD1KLlZ1KG4pCnE9MQpzPTUKYnJlYWsKY2FzZSAzOnE9MgpoPXAKbT1ILlJ1
+KGgpCmw9SC50cyhoKQpMLkMyKCJDb3VsZCBub3QgYWRkL3JlbW92ZSBoaW50IixtLGwpCnM9NQpicmVh
+awpjYXNlIDI6cz0xCmJyZWFrCmNhc2UgNTpyZXR1cm4gUC55QyhudWxsLHIpCmNhc2UgMTpyZXR1cm4g
+UC5mMyhwLHIpfX0pCnJldHVybiBQLkRJKCRhc3luYyRpNixyKX0sCkMyOmZ1bmN0aW9uKGEsYixjKXt2
+YXIgcyxyLHEscD0iZXhjZXB0aW9uIixvPSJzdGFja1RyYWNlIixuPXQudC5iKGIpJiZKLlJNKGIucSgw
+LCJzdWNjZXNzIiksITEpJiZiLng0KHApJiZiLng0KG8pLG09Si5pYShiKQppZihuKXtzPUguaChtLnEo
+YixwKSkKYz1tLnEoYixvKX1lbHNlIHM9bS53KGIpCm49ZG9jdW1lbnQKcj1uLnF1ZXJ5U2VsZWN0b3Io
+Ii5wb3B1cC1wYW5lIikKci5xdWVyeVNlbGVjdG9yKCJoMiIpLmlubmVyVGV4dD1hCnIucXVlcnlTZWxl
+Y3RvcigicCIpLmlubmVyVGV4dD1zCnIucXVlcnlTZWxlY3RvcigicHJlIikuaW5uZXJUZXh0PUouaihj
+KQpxPXQuZGQuYShyLnF1ZXJ5U2VsZWN0b3IoImEuYm90dG9tIikpCm09dC5YOyhxJiZDLnhuKS5zTFUo
+cSxQLlhkKCJodHRwcyIsImdpdGh1Yi5jb20iLCJkYXJ0LWxhbmcvc2RrL2lzc3Vlcy9uZXciLFAuRUYo
+WyJ0aXRsZSIsIkN1c3RvbWVyLXJlcG9ydGVkIGlzc3VlIHdpdGggTk5CRCBtaWdyYXRpb24gdG9vbDog
+IithLCJsYWJlbHMiLHUuZCwiYm9keSIsYSsiXG5cbkVycm9yOiAiK0guRWoocykrIlxuXG5QbGVhc2Ug
+ZmlsbCBpbiB0aGUgZm9sbG93aW5nOlxuXG4qKk5hbWUgb2YgcGFja2FnZSBiZWluZyBtaWdyYXRlZCAo
+aWYgcHVibGljKSoqOlxuKipXaGF0IEkgd2FzIGRvaW5nIHdoZW4gdGhpcyBpc3N1ZSBvY2N1cnJlZCoq
+OlxuKipJcyBpdCBwb3NzaWJsZSB0byB3b3JrIGFyb3VuZCB0aGlzIGlzc3VlKio6XG4qKkhhcyB0aGlz
+IGlzc3VlIGhhcHBlbmVkIGJlZm9yZSwgYW5kIGlmIHNvLCBob3cgb2Z0ZW4qKjpcbioqRGFydCBTREsg
+dmVyc2lvbioqOiAiK0guRWoobi5nZXRFbGVtZW50QnlJZCgic2RrLXZlcnNpb24iKS50ZXh0Q29udGVu
+dCkrIlxuKipBZGRpdGlvbmFsIGRldGFpbHMqKjpcblxuVGhhbmtzIGZvciBmaWxpbmchXG5cblN0YWNr
+dHJhY2U6IF9hdXRvIHBvcHVsYXRlZCBieSBtaWdyYXRpb24gcHJldmlldyB0b29sLl9cblxuYGBgXG4i
+K0guRWooYykrIlxuYGBgXG4iXSxtLG0pKS5nbkQoKSkKbT1xLnN0eWxlCm0uZGlzcGxheT0iaW5pdGlh
+bCIKbj1yLnN0eWxlCm4uZGlzcGxheT0iaW5pdGlhbCIKbj1hKyI6ICIrSC5FaihiKQp3aW5kb3cKaWYo
+dHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLmVycm9yKG4pCndpbmRvdwpu
+PUguRWooYykKaWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLmVycm9y
+KG4pfSwKdDI6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscSxwLG89dC5nLmEoVy5xYyhhLmN1cnJlbnRU
+YXJnZXQpKQphLnByZXZlbnREZWZhdWx0KCkKcz1vLmdldEF0dHJpYnV0ZSgiaHJlZiIpCnI9TC5Vcyhz
+KQpxPUwuRzYocykKcD1MLmFLKHMpCmlmKHEhPW51bGwpTC5hZihyLHEscCxiLG5ldyBMLm5UKHIscSxw
+KSkKZWxzZSBMLmFmKHIsbnVsbCxudWxsLGIsbmV3IEwuTlkocikpfSwKSzA6ZnVuY3Rpb24oYSl7dmFy
+IHMscixxLHA9ZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLnBvcHVwLXBhbmUiKQpwLnF1ZXJ5U2VsZWN0
+b3IoImgyIikuaW5uZXJUZXh0PSJGYWlsZWQgdG8gcmVydW4gZnJvbSBzb3VyY2VzIgpwLnF1ZXJ5U2Vs
+ZWN0b3IoInAiKS5pbm5lclRleHQ9IlNvdXJjZXMgY29udGFpbiBzdGF0aWMgYW5hbHlzaXMgZXJyb3Jz
+OiIKcz1wLnF1ZXJ5U2VsZWN0b3IoInByZSIpCnI9Si5FbChhLHQuYXcpCnE9SC5MaChyKQpzLmlubmVy
+VGV4dD1uZXcgSC5sSihyLHEuQygicVUqKGxELkUpIikuYShuZXcgTC51ZSgpKSxxLkMoImxKPGxELkUs
+cVUqPiIpKS5rKDAsIlxuIikKcT1wLnF1ZXJ5U2VsZWN0b3IoImEuYm90dG9tIikuc3R5bGUKcS5kaXNw
+bGF5PSJub25lIgpzPXAuc3R5bGUKcy5kaXNwbGF5PSJpbml0aWFsIn0sCnZVOmZ1bmN0aW9uKCl7dmFy
+IHM9ZG9jdW1lbnQKSC5EaCh0LmcsdC5oLCJUIiwicXVlcnlTZWxlY3RvckFsbCIpCnM9bmV3IFcud3oo
+cy5xdWVyeVNlbGVjdG9yQWxsKCIuY29kZSIpLHQuUikKcy5LKHMsbmV3IEwuZVgoKSl9LApoWDpmdW5j
+dGlvbihhLGIsYyl7cmV0dXJuIEwuWXcoYSxiLGMpfSwKWXc6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPTAs
+cj1QLkZYKHQueikscT0xLHAsbz1bXSxuLG0sbCxrLGosaSxoLGcKdmFyICRhc3luYyRoWD1QLmx6KGZ1
+bmN0aW9uKGQsZSl7aWYoZD09PTEpe3A9ZQpzPXF9d2hpbGUodHJ1ZSlzd2l0Y2gocyl7Y2FzZSAwOnE9
+MwpqPXQuWApzPTYKcmV0dXJuIFAualEoTC5RNihhLFAuRUYoWyJyZWdpb24iLCJyZWdpb24iLCJvZmZz
+ZXQiLEguRWooYildLGosaiksdC50KSwkYXN5bmMkaFgpCmNhc2UgNjpuPWUKaj1uCmk9Si5VNihqKQpt
+PW5ldyBVLmQyKFUuamYoaS5xKGosImVkaXRzIikpLEguaChpLnEoaiwiZXhwbGFuYXRpb24iKSksSC51
+UChpLnEoaiwibGluZSIpKSxILmgoaS5xKGosImRpc3BsYXlQYXRoIikpLEguaChpLnEoaiwidXJpUGF0
+aCIpKSxVLk5kKGkucShqLCJ0cmFjZXMiKSkpCkwuVDEobSkKTC5GcihhLGIsYykKTC55WCgiLmVkaXQt
+cGFuZWwgLnBhbmVsLWNvbnRlbnQiLCExKQpxPTEKcz01CmJyZWFrCmNhc2UgMzpxPTIKZz1wCmw9SC5S
+dShnKQprPUgudHMoZykKTC5DMigiQ291bGQgbm90IGxvYWQgZWRpdCBkZXRhaWxzIixsLGspCnM9NQpi
+cmVhawpjYXNlIDI6cz0xCmJyZWFrCmNhc2UgNTpyZXR1cm4gUC55QyhudWxsLHIpCmNhc2UgMTpyZXR1
+cm4gUC5mMyhwLHIpfX0pCnJldHVybiBQLkRJKCRhc3luYyRoWCxyKX0sCkc3OmZ1bmN0aW9uKGEsYixj
+LGQsZSl7cmV0dXJuIEwuTDUoYSxiLGMsZCxlKX0sCkw1OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHM9
+MCxyPVAuRlgodC5IKSxxLHA9MixvLG49W10sbSxsLGssaixpLGgsZwp2YXIgJGFzeW5jJEc3PVAubHoo
+ZnVuY3Rpb24oZixhMCl7aWYoZj09PTEpe289YTAKcz1wfXdoaWxlKHRydWUpc3dpdGNoKHMpe2Nhc2Ug
+MDppZighSi5wNChhLCIuZGFydCIpKXtMLkJFKGEsQi53UigpLGQpCkwuQlgoYSxudWxsKQppZihlIT1u
+dWxsKWUuJDAoKQpzPTEKYnJlYWt9cD00Cmk9dC5YCnM9NwpyZXR1cm4gUC5qUShMLlE2KGEsUC5FRihb
+ImlubGluZSIsInRydWUiXSxpLGkpLHQudCksJGFzeW5jJEc3KQpjYXNlIDc6bT1hMApMLkJFKGEsQi5Z
+ZihtKSxkKQpMLmZHKGIsYykKbD1MLlVzKGEpCkwuQlgobCxiKQppZihlIT1udWxsKWUuJDAoKQpwPTIK
+cz02CmJyZWFrCmNhc2UgNDpwPTMKZz1vCms9SC5SdShnKQpqPUgudHMoZykKTC5DMigiQ291bGQgbm90
+IGxvYWQgZGFydCBmaWxlICIrYSxrLGopCnM9NgpicmVhawpjYXNlIDM6cz0yCmJyZWFrCmNhc2UgNjpj
+YXNlIDE6cmV0dXJuIFAueUMocSxyKQpjYXNlIDI6cmV0dXJuIFAuZjMobyxyKX19KQpyZXR1cm4gUC5E
+SSgkYXN5bmMkRzcscil9LApHZTpmdW5jdGlvbigpe3ZhciBzPTAscj1QLkZYKHQueikscT0xLHAsbz1b
+XSxuLG0sbCxrLGosaSxoLGcKdmFyICRhc3luYyRHZT1QLmx6KGZ1bmN0aW9uKGEsYil7aWYoYT09PTEp
+e3A9YgpzPXF9d2hpbGUodHJ1ZSlzd2l0Y2gocyl7Y2FzZSAwOmg9Ii9fcHJldmlldy9uYXZpZ2F0aW9u
+VHJlZS5qc29uIgpxPTMKcz02CnJldHVybiBQLmpRKEwuUTYoaCxDLkNNLHQubSksJGFzeW5jJEdlKQpj
+YXNlIDY6bj1iCm09ZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLm5hdi10cmVlIikKSi5sNShtLCIiKQpq
+PUwubUsobikKJC5JUj1qCkwudFgobSxqLCExKQpxPTEKcz01CmJyZWFrCmNhc2UgMzpxPTIKZz1wCmw9
+SC5SdShnKQprPUgudHMoZykKTC5DMigiQ291bGQgbm90IGxvYWQgbmF2aWdhdGlvbiB0cmVlIixsLGsp
+CnM9NQpicmVhawpjYXNlIDI6cz0xCmJyZWFrCmNhc2UgNTpyZXR1cm4gUC55QyhudWxsLHIpCmNhc2Ug
+MTpyZXR1cm4gUC5mMyhwLHIpfX0pCnJldHVybiBQLkRJKCRhc3luYyRHZSxyKX0sCnFPOmZ1bmN0aW9u
+KGEpe3ZhciBzLHI9YS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxxPUMuQ0QuelEoJC5maSgpLm9mZnNl
+dEhlaWdodCkscD13aW5kb3cuaW5uZXJIZWlnaHQsbz1DLkNELnpRKCQuRFcoKS5vZmZzZXRIZWlnaHQp
+CmlmKHR5cGVvZiBwIT09Im51bWJlciIpcmV0dXJuIHAuSE4oKQpzPXIuYm90dG9tCnMudG9TdHJpbmcK
+aWYocz5wLShvKzE0KSlKLmRoKGEpCmVsc2V7cD1yLnRvcApwLnRvU3RyaW5nCmlmKHA8cSsxNClKLmRo
+KGEpfX0sCmZHOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbwppZihhIT1udWxsKXtzPWRvY3VtZW50
+CnI9cy5nZXRFbGVtZW50QnlJZCgibyIrSC5FaihhKSkKcT1zLnF1ZXJ5U2VsZWN0b3IoIi5saW5lLSIr
+SC5FaihiKSkKaWYociE9bnVsbCl7TC5xTyhyKQpKLmRSKHIpLmkoMCwidGFyZ2V0Iil9ZWxzZSBpZihx
+IT1udWxsKUwucU8ocS5wYXJlbnRFbGVtZW50KQppZihxIT1udWxsKUouZFIodC5nLmEocS5wYXJlbnRO
+b2RlKSkuaSgwLCJoaWdobGlnaHQiKX1lbHNle3M9ZG9jdW1lbnQKcD10LmcKSC5EaChwLHQuaCwiVCIs
+InF1ZXJ5U2VsZWN0b3JBbGwiKQpzPXMucXVlcnlTZWxlY3RvckFsbCgiLmxpbmUtbm8iKQpvPW5ldyBX
+Lnd6KHMsdC5SKQppZihvLmdBKG8pPT09MClyZXR1cm4KTC5xTyhwLmEoQy50NS5ndEgocykpKX19LAph
+ZjpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciBzLHIscT1MLkc2KHdpbmRvdy5sb2NhdGlvbi5ocmVmKSxw
+PUwuYUsod2luZG93LmxvY2F0aW9uLmhyZWYpCmlmKHEhPW51bGwpe3M9ZG9jdW1lbnQuZ2V0RWxlbWVu
+dEJ5SWQoIm8iK0guRWoocSkpCmlmKHMhPW51bGwpSi5kUihzKS5MKDAsInRhcmdldCIpfWlmKHAhPW51
+bGwpe3I9ZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLmxpbmUtIitILkVqKHApKQppZihyIT1udWxsKUou
+ZFIoci5wYXJlbnRFbGVtZW50KS5MKDAsImhpZ2hsaWdodCIpfWlmKGE9PXdpbmRvdy5sb2NhdGlvbi5w
+YXRobmFtZSl7TC5mRyhiLGMpCmUuJDAoKX1lbHNlIEwuRzcoYSxiLGMsZCxlKX0sClE0OmZ1bmN0aW9u
+KGEsYil7dmFyIHMscixxPVAuaEsoYSkscD10LlgKcD1QLkZsKHAscCkKZm9yKHM9cS5naFkoKSxzPXMu
+Z1B1KHMpLHM9cy5nbShzKTtzLkYoKTspe3I9cy5nbCgpCnAuWTUoMCxyLmEsci5iKX1mb3Iocz1iLmdQ
+dShiKSxzPXMuZ20ocyk7cy5GKCk7KXtyPXMuZ2woKQpwLlk1KDAsci5hLHIuYil9cC5ZNSgwLCJhdXRo
+VG9rZW4iLCQuVUUoKSkKcmV0dXJuIHEubm0oMCxwKS5nbkQoKX0sClQxOmZ1bmN0aW9uKGEpe3ZhciBz
+LHIscSxwLG8sbixtLGwsayxqPSQuaEwoKQpKLmw1KGosIiIpCmlmKGE9PW51bGwpe3M9ZG9jdW1lbnQu
+Y3JlYXRlRWxlbWVudCgicCIpCkMuTHQuc2E0KHMsIlNlZSBkZXRhaWxzIGFib3V0IGEgcHJvcG9zZWQg
+ZWRpdC4iKQpDLkx0LnNuKHMsSC5WTShbInBsYWNlaG9sZGVyIl0sdC5pKSkKai5hcHBlbmRDaGlsZChz
+KQpDLkx0LkZGKHMpCnJldHVybn1yPWEuZApxPSQublUoKQpwPXEuemYocikKbz1hLmIKbj1kb2N1bWVu
+dAptPXEuSFAocixKLlQwKG4ucXVlcnlTZWxlY3RvcigiLnJvb3QiKS50ZXh0Q29udGVudCkpCmw9YS5j
+Cms9bi5jcmVhdGVFbGVtZW50KCJwIikKai5hcHBlbmRDaGlsZChrKQprLmFwcGVuZENoaWxkKG4uY3Jl
+YXRlVGV4dE5vZGUoSC5FaihvKSsiIGF0ICIpKQpxPXQuWApxPVcuSjYoTC5RNChhLmUsUC5FRihbImxp
+bmUiLEouaihsKV0scSxxKSkpCnEuYXBwZW5kQ2hpbGQobi5jcmVhdGVUZXh0Tm9kZShILkVqKG0pKyI6
+IitILkVqKGwpKyIuIikpCmsuYXBwZW5kQ2hpbGQocSkKSi5kaChrKQpMLkNDKGEsaixwKQpMLkZ6KGEs
+ail9LApMSDpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlPSQu
+eVAoKQpKLmw1KGUsIiIpCmlmKGIuZ0EoYik9PT0wKXtzPWRvY3VtZW50CnI9cy5jcmVhdGVFbGVtZW50
+KCJwIikKZS5hcHBlbmRDaGlsZChyKQpyLmFwcGVuZENoaWxkKHMuY3JlYXRlVGV4dE5vZGUoIk5vIHBy
+b3Bvc2VkIGVkaXRzIikpfWVsc2UgZm9yKGU9Yi5nUHUoYiksZT1lLmdtKGUpLHM9dC5YLHE9dC5rLHA9
+cS5DKCJ+KDEpPyIpLG89dC5aLHE9cS5jO2UuRigpOyl7bj1lLmdsKCkKbT1kb2N1bWVudApyPW0uY3Jl
+YXRlRWxlbWVudCgicCIpCmw9JC55UCgpCmwuYXBwZW5kQ2hpbGQocikKci5hcHBlbmRDaGlsZChtLmNy
+ZWF0ZVRleHROb2RlKEguRWoobi5hKSsiOiIpKQprPW0uY3JlYXRlRWxlbWVudCgidWwiKQpsLmFwcGVu
+ZENoaWxkKGspCmZvcihuPUouSVQobi5iKTtuLkYoKTspe2w9bi5nbCgpCmo9bS5jcmVhdGVFbGVtZW50
+KCJsaSIpCmsuYXBwZW5kQ2hpbGQoaikKSi5kUihqKS5pKDAsImVkaXQiKQppPW0uY3JlYXRlRWxlbWVu
+dCgiYSIpCmouYXBwZW5kQ2hpbGQoaSkKaS5jbGFzc0xpc3QuYWRkKCJlZGl0LWxpbmsiKQpoPWwuYwpn
+PUguRWooaCkKaS5zZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhpKSkuUCgib2Zm
+c2V0IiksZykKZj1sLmEKZz1ILkVqKGYpCmkuc2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3IFcuU3kobmV3
+IFcuaTcoaSkpLlAoImxpbmUiKSxnKQppLmFwcGVuZENoaWxkKG0uY3JlYXRlVGV4dE5vZGUoImxpbmUg
+IitILkVqKGYpKSkKaS5zZXRBdHRyaWJ1dGUoImhyZWYiLEwuUTQod2luZG93LmxvY2F0aW9uLnBhdGhu
+YW1lLFAuRUYoWyJsaW5lIixILkVqKGYpLCJvZmZzZXQiLEguRWooaCldLHMscykpKQpnPXAuYShuZXcg
+TC5FRShoLGYsYSkpCm8uYShudWxsKQpXLkpFKGksImNsaWNrIixnLCExLHEpCmouYXBwZW5kQ2hpbGQo
+bS5jcmVhdGVUZXh0Tm9kZSgiOiAiK0guRWoobC5iKSkpfX1pZihjKUwuVDEobnVsbCl9LApGcjpmdW5j
+dGlvbihhLGIsYyl7dmFyIHMscixxPXdpbmRvdy5sb2NhdGlvbixwPVAuaEsoKHEmJkMuRXgpLmdEcihx
+KStILkVqKGEpKQpxPXQuWApxPVAuRmwocSxxKQppZihiIT1udWxsKXEuWTUoMCwib2Zmc2V0IixILkVq
+KGIpKQppZihjIT1udWxsKXEuWTUoMCwibGluZSIsSC5FaihjKSkKcS5ZNSgwLCJhdXRoVG9rZW4iLCQu
+VUUoKSkKcD1wLm5tKDAscSkKcT13aW5kb3cuaGlzdG9yeQpzPXQuegpyPXAuZ25EKCkKcS50b1N0cmlu
+ZwpxLnB1c2hTdGF0ZShuZXcgUC5CZihbXSxbXSkuUHYoUC5GbChzLHMpKSwiIixyKX0sCkVuOmZ1bmN0
+aW9uKGEpe3ZhciBzPUouYmIoZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLnJvb3QiKS50ZXh0Q29udGVu
+dCwiLyIpCmlmKEMueEIubkMoYSxzKSlyZXR1cm4gQy54Qi55bihhLHMubGVuZ3RoKQplbHNlIHJldHVy
+biBhfSwKT3Q6ZnVuY3Rpb24oYSl7c3dpdGNoKGEucil7Y2FzZSBDLmN3OmJyZWFrCmNhc2UgQy5XRDph
+LnI9Qy5YagpicmVhawpjYXNlIEMuWGo6YS5yPUMuV0QKYnJlYWsKY2FzZSBDLmRjOnRocm93IEguYihQ
+LlBWKCJGaWxlICIrSC5FaihhLmMpKyIgc2hvdWxkIG5vdCBoYXZlIGluZGV0ZXJtaW5hdGUgbWlncmF0
+aW9uIHN0YXR1cyIpKX19LAp4bjpmdW5jdGlvbihhLGIpe0wudGEoYSxiLmdkNigpKQppZihiLmM9PSQu
+RDkoKS5pbm5lclRleHQpTC50YSgkLmMwKCksYi5nZDYoKSl9LAp0YTpmdW5jdGlvbihhLGIpe3ZhciBz
+LHI9ImNoZWNrX2JveCIscT0idGl0bGUiLHA9Im9wdGVkLW91dCIsbz0ibWlncmF0aW5nIgpzd2l0Y2go
+Yil7Y2FzZSBDLmN3OmEuaW5uZXJUZXh0PXIKSi5kUihhKS5pKDAsImFscmVhZHktbWlncmF0ZWQiKQph
+LnNldEF0dHJpYnV0ZShxLCJBbHJlYWR5IG1pZ3JhdGVkIikKYnJlYWsKY2FzZSBDLldEOmEuaW5uZXJU
+ZXh0PXIKcz1KLllFKGEpCnMuZ24oYSkuTCgwLHApCnMuZ24oYSkuaSgwLG8pCmEuc2V0QXR0cmlidXRl
+KHEsIk1pZ3JhdGluZyB0byBudWxsIHNhZmV0eSIpCmJyZWFrCmNhc2UgQy5YajphLmlubmVyVGV4dD0i
+Y2hlY2tfYm94X291dGxpbmVfYmxhbmsiCnM9Si5ZRShhKQpzLmduKGEpLkwoMCxvKQpzLmduKGEpLmko
+MCxwKQphLnNldEF0dHJpYnV0ZShxLCJPcHRpbmcgb3V0IG9mIG51bGwgc2FmZXR5IikKYnJlYWsKZGVm
+YXVsdDphLmlubmVyVGV4dD0iaW5kZXRlcm1pbmF0ZV9jaGVja19ib3giCnM9Si5ZRShhKQpzLmduKGEp
+LkwoMCxvKQpzLmduKGEpLmkoMCxwKQphLnNldEF0dHJpYnV0ZShxLCJNaXhlZCBzdGF0dXNlcyBvZiAn
+bWlncmF0aW5nJyBhbmQgJ29wdGluZyBvdXQnIikKYnJlYWt9fSwKQlg6ZnVuY3Rpb24oYSxiKXt2YXIg
+cyxyPXt9CnIuYT1hCmE9TC5FbihhKQpyLmE9YQpKLmRyKCQuRDkoKSxhKQpzPWRvY3VtZW50CkguRGgo
+dC5nLHQuaCwiVCIsInF1ZXJ5U2VsZWN0b3JBbGwiKQpzPW5ldyBXLnd6KHMucXVlcnlTZWxlY3RvckFs
+bCgiLm5hdi1wYW5lbCAubmF2LWxpbmsiKSx0LlIpCnMuSyhzLG5ldyBMLlZTKHIpKQpKLmRSKCQuYk4o
+KSkuaSgwLCJ2aXNpYmxlIil9LApBUjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT1iLmIKaWYocSE9bnVs
+bCl7cz10LmcKcj1zLmEocy5hKGEucGFyZW50Tm9kZSkucGFyZW50Tm9kZSkKTC54bihyLnF1ZXJ5U2Vs
+ZWN0b3IoIjpzY29wZSA+IC5zdGF0dXMtaWNvbiIpLHEpCkwuQVIocixxKX19LApCRTpmdW5jdGlvbihh
+LGIsYyl7dmFyIHM9Ii5yZWdpb25zIixyPWRvY3VtZW50LHE9ci5xdWVyeVNlbGVjdG9yKHMpLHA9ci5x
+dWVyeVNlbGVjdG9yKCIuY29kZSIpCkoudEgocSxiLmEsJC5LRygpKQpKLnRIKHAsYi5iLCQuS0coKSkK
+TC5MSChhLGIuZCxjKQppZihiLmMubGVuZ3RoPDJlNSlMLnZVKCkKTC55WCgiLmNvZGUiLCEwKQpMLnlY
+KHMsITApfSwKdFg6ZnVuY3Rpb24oYSxiLGEwKXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxm
+LGU9Im1hdGVyaWFsLWljb25zIixkPWRvY3VtZW50LGM9ZC5jcmVhdGVFbGVtZW50KCJ1bCIpCmEuYXBw
+ZW5kQ2hpbGQoYykKZm9yKHM9Yi5sZW5ndGgscj10LlgscT10LloscD0wO3A8Yi5sZW5ndGg7Yi5sZW5n
+dGg9PT1zfHwoMCxILmxrKShiKSwrK3Ape289YltwXQpuPWQuY3JlYXRlRWxlbWVudCgibGkiKQpjLmFw
+cGVuZENoaWxkKG4pCmlmKG8gaW5zdGFuY2VvZiBMLnZ0KXtKLmRSKG4pLmkoMCwiZGlyIikKbi5zZXRB
+dHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhuKSkuUCgibmFtZSIpLG8uYykKbT1kLmNy
+ZWF0ZUVsZW1lbnQoInNwYW4iKQpuLmFwcGVuZENoaWxkKG0pCmw9Si5ZRShtKQpsLmduKG0pLmkoMCwi
+YXJyb3ciKQpsLnNoZihtLCImI3gyNUJDOyIpCms9ZC5jcmVhdGVFbGVtZW50KCJzcGFuIikKSi5kUihr
+KS5pKDAsZSkKay5pbm5lclRleHQ9ImZvbGRlcl9vcGVuIgpuLmFwcGVuZENoaWxkKGspCm4uYXBwZW5k
+Q2hpbGQoZC5jcmVhdGVUZXh0Tm9kZShvLmEpKQpMLnRYKG4sby5kLCExKQpMLmt6KG0pfWVsc2UgaWYo
+byBpbnN0YW5jZW9mIEwuY0Qpe2w9ZC5jcmVhdGVFbGVtZW50KCJzcGFuIikKSi5kUihsKS5pKDAsZSkK
+bC5pbm5lclRleHQ9Imluc2VydF9kcml2ZV9maWxlIgpuLmFwcGVuZENoaWxkKGwpCmo9ZC5jcmVhdGVF
+bGVtZW50KCJhIikKbi5hcHBlbmRDaGlsZChqKQpsPUouWUUoaikKbC5nbihqKS5pKDAsIm5hdi1saW5r
+IikKai5zZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhqKSkuUCgibmFtZSIpLG8u
+YykKai5zZXRBdHRyaWJ1dGUoImhyZWYiLEwuUTQoby5kLFAuRmwocixyKSkpCmouYXBwZW5kQ2hpbGQo
+ZC5jcmVhdGVUZXh0Tm9kZShvLmEpKQpsPWwuZ1ZsKGopCmk9bC4kdGkKaD1pLkMoIn4oMSk/IikuYShu
+ZXcgTC5URCgpKQpxLmEobnVsbCkKVy5KRShsLmEsbC5iLGgsITEsaS5jKQpnPW8uZQppZih0eXBlb2Yg
+ZyE9PSJudW1iZXIiKXJldHVybiBnLm9zKCkKaWYoZz4wKXtmPWQuY3JlYXRlRWxlbWVudCgic3BhbiIp
+Cm4uYXBwZW5kQ2hpbGQoZikKSi5kUihmKS5pKDAsImVkaXQtY291bnQiKQpsPSIiK2crIiAiCmlmKGc9
+PT0xKWk9InByb3Bvc2VkIGVkaXQiCmVsc2UgaT0icHJvcG9zZWQgZWRpdHMiCmYuc2V0QXR0cmlidXRl
+KCJ0aXRsZSIsbCtpKQpmLmFwcGVuZENoaWxkKGQuY3JlYXRlVGV4dE5vZGUoQy5qbi53KGcpKSl9fX19
+LAp1ejpmdW5jdGlvbihhLGIsYyl7dmFyIHM9ZG9jdW1lbnQscj1zLmNyZWF0ZUVsZW1lbnQoImJ1dHRv
+biIpLHE9dC5rLHA9cS5DKCJ+KDEpPyIpLmEobmV3IEwubTIoYSxjKSkKdC5aLmEobnVsbCkKVy5KRShy
+LCJjbGljayIscCwhMSxxLmMpCnIuYXBwZW5kQ2hpbGQocy5jcmVhdGVUZXh0Tm9kZShNLk9YKGEuYSkp
+KQpiLmFwcGVuZENoaWxkKHIpfSwKRno6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbSxsLGss
+aixpLGg9YS5hCmlmKGg9PW51bGwpcmV0dXJuCnM9ZG9jdW1lbnQKcj1zLmNyZWF0ZUVsZW1lbnQoInAi
+KQpxPWIuYXBwZW5kQ2hpbGQocikKcj1zLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpwPXQuaQpKLk11KHIs
+SC5WTShbInR5cGUtZGVzY3JpcHRpb24iXSxwKSkKci5hcHBlbmRDaGlsZChzLmNyZWF0ZVRleHROb2Rl
+KCJBY3Rpb25zIikpCnEuYXBwZW5kQ2hpbGQocikKcS5hcHBlbmRDaGlsZChzLmNyZWF0ZVRleHROb2Rl
+KCI6IikpCm89cy5jcmVhdGVFbGVtZW50KCJwIikKYi5hcHBlbmRDaGlsZChvKQpmb3Iocj1oLmxlbmd0
+aCxuPXQuUSxtPTA7bTxoLmxlbmd0aDtoLmxlbmd0aD09PXJ8fCgwLEgubGspKGgpLCsrbSl7bD1oW21d
+Cms9cy5jcmVhdGVFbGVtZW50KCJhIikKby5hcHBlbmRDaGlsZChrKQprLmFwcGVuZENoaWxkKHMuY3Jl
+YXRlVGV4dE5vZGUobC5hKSkKay5zZXRBdHRyaWJ1dGUoImhyZWYiLGwuYikKaj1uLmEoSC5WTShbImFk
+ZC1oaW50LWxpbmsiLCJiZWZvcmUtYXBwbHkiLCJidXR0b24iXSxwKSkKaT1KLmRSKGspCmkuVjEoMCkK
+aS5GVigwLGopfX0sCkNDOmZ1bmN0aW9uKGE0LGE1LGE2KXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaixp
+LGgsZyxmLGUsZCxjLGIsYSxhMCxhMSxhMixhMwpmb3Iocz1hNC5mLHI9cy5sZW5ndGgscT10LmkscD10
+LlEsbz0wO288cy5sZW5ndGg7cy5sZW5ndGg9PT1yfHwoMCxILmxrKShzKSwrK28pe249c1tvXQptPWRv
+Y3VtZW50Cmw9bS5jcmVhdGVFbGVtZW50KCJwIikKaz1wLmEoSC5WTShbInRyYWNlIl0scSkpCmo9Si5k
+UihsKQpqLlYxKDApCmouRlYoMCxrKQppPWE1LmFwcGVuZENoaWxkKGwpCmw9bS5jcmVhdGVFbGVtZW50
+KCJzcGFuIikKaz1wLmEoSC5WTShbInR5cGUtZGVzY3JpcHRpb24iXSxxKSkKaj1KLmRSKGwpCmouVjEo
+MCkKai5GVigwLGspCmwuYXBwZW5kQ2hpbGQobS5jcmVhdGVUZXh0Tm9kZShuLmEpKQppLmFwcGVuZENo
+aWxkKGwpCmkuYXBwZW5kQ2hpbGQobS5jcmVhdGVUZXh0Tm9kZSgiOiIpKQpsPW0uY3JlYXRlRWxlbWVu
+dCgidWwiKQprPXAuYShILlZNKFsidHJhY2UiXSxxKSkKaj1KLmRSKGwpCmouVjEoMCkKai5GVigwLGsp
+Cmg9aS5hcHBlbmRDaGlsZChsKQpmb3IobD1uLmIsaz1sLmxlbmd0aCxnPTA7ZzxsLmxlbmd0aDtsLmxl
+bmd0aD09PWt8fCgwLEgubGspKGwpLCsrZyl7Zj1sW2ddCmU9bS5jcmVhdGVFbGVtZW50KCJsaSIpCmgu
+YXBwZW5kQ2hpbGQoZSkKZD1tLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpjPXAuYShILlZNKFsiZnVuY3Rp
+b24iXSxxKSkKaj1KLmRSKGQpCmouVjEoMCkKai5GVigwLGMpCmM9Zi5iCkwua0QoZCxjPT1udWxsPyJ1
+bmtub3duIjpjKQplLmFwcGVuZENoaWxkKGQpCmI9Zi5jCmlmKGIhPW51bGwpe2UuYXBwZW5kQ2hpbGQo
+bS5jcmVhdGVUZXh0Tm9kZSgiICgiKSkKYT1iLmIKYTA9bS5jcmVhdGVFbGVtZW50KCJhIikKYTAuYXBw
+ZW5kQ2hpbGQobS5jcmVhdGVUZXh0Tm9kZShILkVqKGIuYykrIjoiK0guRWooYSkpKQphMC5zZXRBdHRy
+aWJ1dGUoImhyZWYiLGIuYSkKYTAuY2xhc3NMaXN0LmFkZCgibmF2LWxpbmsiKQplLmFwcGVuZENoaWxk
+KGEwKQplLmFwcGVuZENoaWxkKG0uY3JlYXRlVGV4dE5vZGUoIikiKSl9ZS5hcHBlbmRDaGlsZChtLmNy
+ZWF0ZVRleHROb2RlKCI6ICIpKQpkPWYuYQpMLmtEKGUsZD09bnVsbD8idW5rbm93biI6ZCkKZD1mLmQK
+aWYoZC5sZW5ndGghPT0wKXtjPW0uY3JlYXRlRWxlbWVudCgicCIpCmExPXAuYShILlZNKFsiZHJhd2Vy
+IiwiYmVmb3JlLWFwcGx5Il0scSkpCmo9Si5kUihjKQpqLlYxKDApCmouRlYoMCxhMSkKYTI9ZS5hcHBl
+bmRDaGlsZChjKQpmb3IoYz1kLmxlbmd0aCxhMz0wO2EzPGQubGVuZ3RoO2QubGVuZ3RoPT09Y3x8KDAs
+SC5saykoZCksKythMylMLnV6KGRbYTNdLGEyLGIpfX19fSwKVXM6ZnVuY3Rpb24oYSl7cmV0dXJuIEou
+VTYoYSkudGcoYSwiPyIpP0MueEIuTmooYSwwLEMueEIuT1koYSwiPyIpKTphfSwKa0Q6ZnVuY3Rpb24o
+YSxiKXt2YXIgcyxyLHE9SC5WTShiLnNwbGl0KCIuIiksdC5zKSxwPUMuTm0uZ3RIKHEpLG89ZG9jdW1l
+bnQKYS5hcHBlbmRDaGlsZChvLmNyZWF0ZVRleHROb2RlKHApKQpmb3IocD1ILnFDKHEsMSxudWxsLHQu
+TikscD1uZXcgSC5hNyhwLHAuZ0EocCkscC4kdGkuQygiYTc8YUwuRT4iKSkscz1KLllFKGEpO3AuRigp
+Oyl7cj1wLmQKcy5ueihhLCJiZWZvcmVlbmQiLCImIzgyMDM7LiIsbnVsbCxudWxsKQphLmFwcGVuZENo
+aWxkKG8uY3JlYXRlVGV4dE5vZGUocikpfX0sCm1IOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAKZm9y
+KHM9YS5sZW5ndGgscj0wO3I8YS5sZW5ndGg7YS5sZW5ndGg9PT1zfHwoMCxILmxrKShhKSwrK3Ipe3E9
+YVtyXQppZihxIGluc3RhbmNlb2YgTC52dCl7cD1MLm1IKHEuZCxiKQppZihwIT1udWxsKXJldHVybiBw
+fWVsc2UgaWYocS5jPT1iKXJldHVybiBxfXJldHVybiBudWxsfSwKZTpmdW5jdGlvbiBlKCl7fSwKVlc6
+ZnVuY3Rpb24gVlcoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKb1o6ZnVuY3Rpb24g
+b1ooKXt9LApqcjpmdW5jdGlvbiBqcigpe30sCnFsOmZ1bmN0aW9uIHFsKCl7fSwKSGk6ZnVuY3Rpb24g
+SGkoKXt9LApCVDpmdW5jdGlvbiBCVCgpe30sClBZOmZ1bmN0aW9uIFBZKCl7fSwKdTg6ZnVuY3Rpb24g
+dTgoKXt9LApMOmZ1bmN0aW9uIEwoKXt9LApXeDpmdW5jdGlvbiBXeChhLGIpe3RoaXMuYT1hCnRoaXMu
+Yj1ifSwKQU86ZnVuY3Rpb24gQU8oYSl7dGhpcy5hPWF9LApkTjpmdW5jdGlvbiBkTihhKXt0aGlzLmE9
+YX0sCkhvOmZ1bmN0aW9uIEhvKGEpe3RoaXMuYT1hfSwKeHo6ZnVuY3Rpb24geHooYSxiKXt0aGlzLmE9
+YQp0aGlzLmI9Yn0sCklDOmZ1bmN0aW9uIElDKCl7fSwKZkM6ZnVuY3Rpb24gZkMoYSxiKXt0aGlzLmE9
+YQp0aGlzLmI9Yn0sCm5UOmZ1bmN0aW9uIG5UKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9
+Y30sCk5ZOmZ1bmN0aW9uIE5ZKGEpe3RoaXMuYT1hfSwKdWU6ZnVuY3Rpb24gdWUoKXt9LAplWDpmdW5j
+dGlvbiBlWCgpe30sCkVFOmZ1bmN0aW9uIEVFKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9
+Y30sClFMOmZ1bmN0aW9uIFFMKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApWUzpmdW5jdGlvbiBWUyhh
+KXt0aGlzLmE9YX0sClREOmZ1bmN0aW9uIFREKCl7fSwKbTI6ZnVuY3Rpb24gbTIoYSxiKXt0aGlzLmE9
+YQp0aGlzLmI9Yn0sClhBOmZ1bmN0aW9uIFhBKCl7fSwKWnM6ZnVuY3Rpb24oYSl7dmFyIHMscixxPUou
+VTYoYSkKaWYoTC5wMihILmgocS5xKGEsInR5cGUiKSkpPT09Qy5ZMil7cz1ILmgocS5xKGEsIm5hbWUi
+KSkKcj1ILmgocS5xKGEsInBhdGgiKSkKcT1xLnEoYSwic3VidHJlZSIpCnE9bmV3IEwudnQocT09bnVs
+bD9udWxsOkwubUsocSkscyxyKQpxLkxWKCkKcmV0dXJuIHF9ZWxzZXtzPUguaChxLnEoYSwibmFtZSIp
+KQpyPUguaChxLnEoYSwicGF0aCIpKQpyZXR1cm4gbmV3IEwuY0QoSC5oKHEucShhLCJocmVmIikpLEgu
+dVAocS5xKGEsImVkaXRDb3VudCIpKSxILnk4KHEucShhLCJ3YXNFeHBsaWNpdGx5T3B0ZWRPdXQiKSks
+TC52QihILnVQKHEucShhLCJtaWdyYXRpb25TdGF0dXMiKSkpLHMscil9fSwKbUs6ZnVuY3Rpb24oYSl7
+dmFyIHMscj1ILlZNKFtdLHQuY1EpCmZvcihzPUouSVQodC5VLmEoYSkpO3MuRigpOylyLnB1c2goTC5a
+cyhzLmdsKCkpKQpyZXR1cm4gcn0sClZEOmZ1bmN0aW9uKGEpe3ZhciBzLHIscT1ILlZNKFtdLHQuRykK
+Zm9yKHM9YS5sZW5ndGgscj0wO3I8YS5sZW5ndGg7YS5sZW5ndGg9PT1zfHwoMCxILmxrKShhKSwrK3Ip
+cS5wdXNoKGFbcl0uTHQoKSkKcmV0dXJuIHF9LAp2QjpmdW5jdGlvbihhKXtpZihhPT1udWxsKXJldHVy
+biBudWxsCmlmKGE+Pj4wIT09YXx8YT49NClyZXR1cm4gSC5PSChDLmwwLGEpCnJldHVybiBDLmwwW2Fd
+fSwKcDI6ZnVuY3Rpb24oYSl7c3dpdGNoKGEpe2Nhc2UiZGlyZWN0b3J5IjpyZXR1cm4gQy5ZMgpjYXNl
+ImZpbGUiOnJldHVybiBDLnJmCmRlZmF1bHQ6dGhyb3cgSC5iKFAuUFYoIlVucmVjb2duaXplZCBuYXZp
+Z2F0aW9uIHRyZWUgbm9kZSB0eXBlOiAiK0guRWooYSkpKX19LAp2dDpmdW5jdGlvbiB2dChhLGIsYyl7
+dmFyIF89dGhpcwpfLmQ9YQpfLmE9YgpfLmI9bnVsbApfLmM9Y30sCmNEOmZ1bmN0aW9uIGNEKGEsYixj
+LGQsZSxmKXt2YXIgXz10aGlzCl8uZD1hCl8uZT1iCl8uZj1jCl8ucj1kCl8uYT1lCl8uYj1udWxsCl8u
+Yz1mfSwKRDg6ZnVuY3Rpb24gRDgoKXt9LApPOTpmdW5jdGlvbiBPOShhKXt0aGlzLmI9YX0sCkdiOmZ1
+bmN0aW9uIEdiKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApJVjpmdW5jdGlvbiBJVihhLGIsYyxkKXt2
+YXIgXz10aGlzCl8uZD1hCl8uZT1iCl8uZj1jCl8ucj1kfX0sWD17CkNMOmZ1bmN0aW9uKGEsYil7dmFy
+IHMscixxLHAsbyxuPWIueFooYSkKYi5oSyhhKQppZihuIT1udWxsKWE9Si5LVihhLG4ubGVuZ3RoKQpz
+PXQucwpyPUguVk0oW10scykKcT1ILlZNKFtdLHMpCnM9YS5sZW5ndGgKaWYocyE9PTAmJmIucjQoQy54
+Qi5XKGEsMCkpKXtpZigwPj1zKXJldHVybiBILk9IKGEsMCkKQy5ObS5pKHEsYVswXSkKcD0xfWVsc2V7
+Qy5ObS5pKHEsIiIpCnA9MH1mb3Iobz1wO288czsrK28paWYoYi5yNChDLnhCLlcoYSxvKSkpe0MuTm0u
+aShyLEMueEIuTmooYSxwLG8pKQpDLk5tLmkocSxhW29dKQpwPW8rMX1pZihwPHMpe0MuTm0uaShyLEMu
+eEIueW4oYSxwKSkKQy5ObS5pKHEsIiIpfXJldHVybiBuZXcgWC5XRChiLG4scixxKX0sCldEOmZ1bmN0
+aW9uIFdEKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5kPWMKXy5lPWR9LApJNzpmdW5j
+dGlvbihhKXtyZXR1cm4gbmV3IFguZHYoYSl9LApkdjpmdW5jdGlvbiBkdihhKXt0aGlzLmE9YX19LE89
+ewpSaDpmdW5jdGlvbigpe3ZhciBzLHI9bnVsbAppZihQLnVvKCkuZ0ZpKCkhPT0iZmlsZSIpcmV0dXJu
+ICQuRWIoKQpzPVAudW8oKQppZighQy54Qi5UYyhzLmdJaShzKSwiLyIpKXJldHVybiAkLkViKCkKaWYo
+UC5LTChyLCJhL2IiLHIscixyLHIscikudDQoKT09PSJhXFxiIilyZXR1cm4gJC5LaygpCnJldHVybiAk
+LmJEKCl9LAp6TDpmdW5jdGlvbiB6TCgpe319LEU9e09GOmZ1bmN0aW9uIE9GKGEsYixjKXt0aGlzLmQ9
+YQp0aGlzLmU9Ygp0aGlzLmY9Y319LEY9e3J1OmZ1bmN0aW9uIHJ1KGEsYixjLGQpe3ZhciBfPXRoaXMK
+Xy5kPWEKXy5lPWIKXy5mPWMKXy5yPWR9fSxEPXsKYWI6ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvPW51
+bGwKdHJ5e289UC51bygpfWNhdGNoKHMpe2lmKHQuZzguYihILlJ1KHMpKSl7cj0kLkZmCmlmKHIhPW51
+bGwpcmV0dXJuIHIKdGhyb3cgc31lbHNlIHRocm93IHN9aWYoSi5STShvLCQuSTYpKXtyPSQuRmYKci50
+b1N0cmluZwpyZXR1cm4gcn0kLkk2PW8KaWYoJC5IaygpPT0kLkViKCkpcj0kLkZmPW8uWkkoIi4iKS53
+KDApCmVsc2V7cT1vLnQ0KCkKcD1xLmxlbmd0aC0xCnI9JC5GZj1wPT09MD9xOkMueEIuTmoocSwwLHAp
+fXIudG9TdHJpbmcKcmV0dXJuIHJ9fQp2YXIgdz1bQyxILEosUCxXLE0sVSxCLFQsTCxYLE8sRSxGLERd
+Cmh1bmtIZWxwZXJzLnNldEZ1bmN0aW9uTmFtZXNJZk5lY2Vzc2FyeSh3KQp2YXIgJD17fQpILkZLLnBy
+b3RvdHlwZT17fQpKLkd2LnByb3RvdHlwZT17CkROOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGE9PT1ifSwK
+Z2lPOmZ1bmN0aW9uKGEpe3JldHVybiBILmVRKGEpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4iSW5zdGFu
+Y2Ugb2YgJyIrSC5FaihILk0oYSkpKyInIn0sCmU3OmZ1bmN0aW9uKGEsYil7dC5vLmEoYikKdGhyb3cg
+SC5iKFAubHIoYSxiLmdXYSgpLGIuZ25kKCksYi5nVm0oKSkpfX0KSi55RS5wcm90b3R5cGU9ewp3OmZ1
+bmN0aW9uKGEpe3JldHVybiBTdHJpbmcoYSl9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIGE/NTE5MDE4
+OjIxODE1OX0sCiRpYTI6MX0KSi53ZS5wcm90b3R5cGU9ewpETjpmdW5jdGlvbihhLGIpe3JldHVybiBu
+dWxsPT1ifSwKdzpmdW5jdGlvbihhKXtyZXR1cm4ibnVsbCJ9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJu
+IDB9LAplNzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlNqKGEsdC5vLmEoYikpfSwKJGljODoxfQpK
+Lk1GLnByb3RvdHlwZT17CmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gMH0sCnc6ZnVuY3Rpb24oYSl7cmV0
+dXJuIFN0cmluZyhhKX0sCiRpdm06MX0KSi5pQy5wcm90b3R5cGU9e30KSi5rZC5wcm90b3R5cGU9e30K
+Si5jNS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzPWFbJC53KCldCmlmKHM9PW51bGwpcmV0
+dXJuIHRoaXMudChhKQpyZXR1cm4iSmF2YVNjcmlwdCBmdW5jdGlvbiBmb3IgIitILkVqKEouaihzKSl9
+LAokaUVIOjF9CkouamQucHJvdG90eXBlPXsKZHI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IEgualYo
+YSxILnQ2KGEpLkMoIkA8MT4iKS5LcShiKS5DKCJqVjwxLDI+IikpfSwKaTpmdW5jdGlvbihhLGIpe0gu
+dDYoYSkuYy5hKGIpCmlmKCEhYS5maXhlZCRsZW5ndGgpSC52KFAuTDQoImFkZCIpKQphLnB1c2goYil9
+LApXNDpmdW5jdGlvbihhLGIpe3ZhciBzCmlmKCEhYS5maXhlZCRsZW5ndGgpSC52KFAuTDQoInJlbW92
+ZUF0IikpCnM9YS5sZW5ndGgKaWYoYj49cyl0aHJvdyBILmIoUC5PNyhiLG51bGwpKQpyZXR1cm4gYS5z
+cGxpY2UoYiwxKVswXX0sClVHOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyCkgudDYoYSkuQygiY1g8MT4i
+KS5hKGMpCmlmKCEhYS5maXhlZCRsZW5ndGgpSC52KFAuTDQoImluc2VydEFsbCIpKQpQLndBKGIsMCxh
+Lmxlbmd0aCwiaW5kZXgiKQppZighdC5iLmIoYykpYz1KLlJYKGMpCnM9Si5IbShjKQphLmxlbmd0aD1h
+Lmxlbmd0aCtzCnI9YitzCnRoaXMuWVcoYSxyLGEubGVuZ3RoLGEsYikKdGhpcy52ZyhhLGIscixjKX0s
+CkZWOmZ1bmN0aW9uKGEsYil7dmFyIHMKSC50NihhKS5DKCJjWDwxPiIpLmEoYikKaWYoISFhLmZpeGVk
+JGxlbmd0aClILnYoUC5MNCgiYWRkQWxsIikpCmZvcihzPUouSVQoYik7cy5GKCk7KWEucHVzaChzLmds
+KCkpfSwKRTI6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPUgudDYoYSkKcmV0dXJuIG5ldyBILmxKKGEscy5L
+cShjKS5DKCIxKDIpIikuYShiKSxzLkMoIkA8MT4iKS5LcShjKS5DKCJsSjwxLDI+IikpfSwKazpmdW5j
+dGlvbihhLGIpe3ZhciBzLHI9UC5POChhLmxlbmd0aCwiIiwhMSx0Lk4pCmZvcihzPTA7czxhLmxlbmd0
+aDsrK3MpdGhpcy5ZNShyLHMsSC5FaihhW3NdKSkKcmV0dXJuIHIuam9pbihiKX0sCmVSOmZ1bmN0aW9u
+KGEsYil7cmV0dXJuIEgucUMoYSxiLG51bGwsSC50NihhKS5jKX0sCk4wOmZ1bmN0aW9uKGEsYixjLGQp
+e3ZhciBzLHIscQpkLmEoYikKSC50NihhKS5LcShkKS5DKCIxKDEsMikiKS5hKGMpCnM9YS5sZW5ndGgK
+Zm9yKHI9YixxPTA7cTxzOysrcSl7cj1jLiQyKHIsYVtxXSkKaWYoYS5sZW5ndGghPT1zKXRocm93IEgu
+YihQLmE0KGEpKX1yZXR1cm4gcn0sCkh0OmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbwpILnQ2KGEp
+LkMoImEyKDEpIikuYShiKQpzPWEubGVuZ3RoCmZvcihyPW51bGwscT0hMSxwPTA7cDxzOysrcCl7bz1h
+W3BdCmlmKEgub1QoYi4kMShvKSkpe2lmKHEpdGhyb3cgSC5iKEguQW0oKSkKcj1vCnE9ITB9aWYocyE9
+PWEubGVuZ3RoKXRocm93IEguYihQLmE0KGEpKX1pZihxKXJldHVybiByCnRocm93IEguYihILldwKCkp
+fSwKRTpmdW5jdGlvbihhLGIpe2lmKGI8MHx8Yj49YS5sZW5ndGgpcmV0dXJuIEguT0goYSxiKQpyZXR1
+cm4gYVtiXX0sCmd0SDpmdW5jdGlvbihhKXtpZihhLmxlbmd0aD4wKXJldHVybiBhWzBdCnRocm93IEgu
+YihILldwKCkpfSwKZ3JaOmZ1bmN0aW9uKGEpe3ZhciBzPWEubGVuZ3RoCmlmKHM+MClyZXR1cm4gYVtz
+LTFdCnRocm93IEguYihILldwKCkpfSwKWVc6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgcyxyLHEscCxv
+CkgudDYoYSkuQygiY1g8MT4iKS5hKGQpCmlmKCEhYS5pbW11dGFibGUkbGlzdClILnYoUC5MNCgic2V0
+UmFuZ2UiKSkKUC5qQihiLGMsYS5sZW5ndGgpCnM9Yy1iCmlmKHM9PT0wKXJldHVybgpQLmsxKGUsInNr
+aXBDb3VudCIpCmlmKHQuai5iKGQpKXtyPWQKcT1lfWVsc2V7cj1KLkE1KGQsZSkudHQoMCwhMSkKcT0w
+fXA9Si5VNihyKQppZihxK3M+cC5nQShyKSl0aHJvdyBILmIoSC5hcigpKQppZihxPGIpZm9yKG89cy0x
+O28+PTA7LS1vKWFbYitvXT1wLnEocixxK28pCmVsc2UgZm9yKG89MDtvPHM7KytvKWFbYitvXT1wLnEo
+cixxK28pfSwKdmc6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIHRoaXMuWVcoYSxiLGMsZCwwKX0sClZy
+OmZ1bmN0aW9uKGEsYil7dmFyIHMscgpILnQ2KGEpLkMoImEyKDEpIikuYShiKQpzPWEubGVuZ3RoCmZv
+cihyPTA7cjxzOysrcil7aWYoSC5vVChiLiQxKGFbcl0pKSlyZXR1cm4hMAppZihhLmxlbmd0aCE9PXMp
+dGhyb3cgSC5iKFAuYTQoYSkpfXJldHVybiExfSwKdGc6ZnVuY3Rpb24oYSxiKXt2YXIgcwpmb3Iocz0w
+O3M8YS5sZW5ndGg7KytzKWlmKEouUk0oYVtzXSxiKSlyZXR1cm4hMApyZXR1cm4hMX0sCmdsMDpmdW5j
+dGlvbihhKXtyZXR1cm4gYS5sZW5ndGg9PT0wfSwKZ29yOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0
+aCE9PTB9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBQLldFKGEsIlsiLCJdIil9LAp0dDpmdW5jdGlvbihh
+LGIpe3ZhciBzPUguVk0oYS5zbGljZSgwKSxILnQ2KGEpKQpyZXR1cm4gc30sCmJyOmZ1bmN0aW9uKGEp
+e3JldHVybiB0aGlzLnR0KGEsITApfSwKZ206ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBKLm0xKGEsYS5s
+ZW5ndGgsSC50NihhKS5DKCJtMTwxPiIpKX0sCmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gSC5lUShhKX0s
+CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnNBOmZ1bmN0aW9uKGEsYil7aWYoISFhLmZp
+eGVkJGxlbmd0aClILnYoUC5MNCgic2V0IGxlbmd0aCIpKQppZihiPDApdGhyb3cgSC5iKFAuVEUoYiww
+LG51bGwsIm5ld0xlbmd0aCIsbnVsbCkpCmEubGVuZ3RoPWJ9LApxOmZ1bmN0aW9uKGEsYil7SC51UChi
+KQppZihiPj1hLmxlbmd0aHx8YjwwKXRocm93IEguYihILkhZKGEsYikpCnJldHVybiBhW2JdfSwKWTU6
+ZnVuY3Rpb24oYSxiLGMpe0gudDYoYSkuYy5hKGMpCmlmKCEhYS5pbW11dGFibGUkbGlzdClILnYoUC5M
+NCgiaW5kZXhlZCBzZXQiKSkKaWYoYj49YS5sZW5ndGh8fGI8MCl0aHJvdyBILmIoSC5IWShhLGIpKQph
+W2JdPWN9LAokaWJROjEsCiRpY1g6MSwKJGl6TToxfQpKLlBvLnByb3RvdHlwZT17fQpKLm0xLnByb3Rv
+dHlwZT17CmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCkY6ZnVuY3Rpb24oKXt2YXIgcyxyPXRo
+aXMscT1yLmEscD1xLmxlbmd0aAppZihyLmIhPT1wKXRocm93IEguYihILmxrKHEpKQpzPXIuYwppZihz
+Pj1wKXtyLnNNKG51bGwpCnJldHVybiExfXIuc00ocVtzXSk7KytyLmMKcmV0dXJuITB9LApzTTpmdW5j
+dGlvbihhKXt0aGlzLmQ9dGhpcy4kdGkuQygiMT8iKS5hKGEpfSwKJGlBbjoxfQpKLnFJLnByb3RvdHlw
+ZT17CnpROmZ1bmN0aW9uKGEpe2lmKGE+MCl7aWYoYSE9PTEvMClyZXR1cm4gTWF0aC5yb3VuZChhKX1l
+bHNlIGlmKGE+LTEvMClyZXR1cm4gMC1NYXRoLnJvdW5kKDAtYSkKdGhyb3cgSC5iKFAuTDQoIiIrYSsi
+LnJvdW5kKCkiKSl9LAp3OmZ1bmN0aW9uKGEpe2lmKGE9PT0wJiYxL2E8MClyZXR1cm4iLTAuMCIKZWxz
+ZSByZXR1cm4iIithfSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG89YXwwCmlmKGE9PT1vKXJl
+dHVybiBvJjUzNjg3MDkxMQpzPU1hdGguYWJzKGEpCnI9TWF0aC5sb2cocykvMC42OTMxNDcxODA1NTk5
+NDUzfDAKcT1NYXRoLnBvdygyLHIpCnA9czwxP3MvcTpxL3MKcmV0dXJuKChwKjkwMDcxOTkyNTQ3NDA5
+OTJ8MCkrKHAqMzU0MjI0MzE4MTE3NjUyMXwwKSkqNTk5MTk3K3IqMTI1OSY1MzY4NzA5MTF9LAp6WTpm
+dW5jdGlvbihhLGIpe3ZhciBzPWElYgppZihzPT09MClyZXR1cm4gMAppZihzPjApcmV0dXJuIHMKaWYo
+YjwwKXJldHVybiBzLWIKZWxzZSByZXR1cm4gcytifSwKQlU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4oYXww
+KT09PWE/YS9ifDA6dGhpcy5ESihhLGIpfSwKREo6ZnVuY3Rpb24oYSxiKXt2YXIgcz1hL2IKaWYocz49
+LTIxNDc0ODM2NDgmJnM8PTIxNDc0ODM2NDcpcmV0dXJuIHN8MAppZihzPjApe2lmKHMhPT0xLzApcmV0
+dXJuIE1hdGguZmxvb3Iocyl9ZWxzZSBpZihzPi0xLzApcmV0dXJuIE1hdGguY2VpbChzKQp0aHJvdyBI
+LmIoUC5MNCgiUmVzdWx0IG9mIHRydW5jYXRpbmcgZGl2aXNpb24gaXMgIitILkVqKHMpKyI6ICIrSC5F
+aihhKSsiIH4vICIrYikpfSwKd0c6ZnVuY3Rpb24oYSxiKXt2YXIgcwppZihhPjApcz10aGlzLnAzKGEs
+YikKZWxzZXtzPWI+MzE/MzE6YgpzPWE+PnM+Pj4wfXJldHVybiBzfSwKYmY6ZnVuY3Rpb24oYSxiKXtp
+ZihiPDApdGhyb3cgSC5iKEgudEwoYikpCnJldHVybiB0aGlzLnAzKGEsYil9LApwMzpmdW5jdGlvbihh
+LGIpe3JldHVybiBiPjMxPzA6YT4+PmJ9LAokaUNQOjEsCiRpWlo6MX0KSi5iVS5wcm90b3R5cGU9eyRp
+SWY6MX0KSi5WQS5wcm90b3R5cGU9e30KSi5Eci5wcm90b3R5cGU9ewpPMjpmdW5jdGlvbihhLGIpe2lm
+KGI8MCl0aHJvdyBILmIoSC5IWShhLGIpKQppZihiPj1hLmxlbmd0aClILnYoSC5IWShhLGIpKQpyZXR1
+cm4gYS5jaGFyQ29kZUF0KGIpfSwKVzpmdW5jdGlvbihhLGIpe2lmKGI+PWEubGVuZ3RoKXRocm93IEgu
+YihILkhZKGEsYikpCnJldHVybiBhLmNoYXJDb2RlQXQoYil9LApkZDpmdW5jdGlvbihhLGIpe3JldHVy
+biBuZXcgSC51bihiLGEsMCl9LApoOmZ1bmN0aW9uKGEsYil7aWYodHlwZW9mIGIhPSJzdHJpbmciKXRo
+cm93IEguYihQLkwzKGIsbnVsbCxudWxsKSkKcmV0dXJuIGErYn0sClRjOmZ1bmN0aW9uKGEsYil7dmFy
+IHM9Yi5sZW5ndGgscj1hLmxlbmd0aAppZihzPnIpcmV0dXJuITEKcmV0dXJuIGI9PT10aGlzLnluKGEs
+ci1zKX0sCmk3OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzPVAuakIoYixjLGEubGVuZ3RoKSxyPWEuc3Vi
+c3RyaW5nKDAsYikscT1hLnN1YnN0cmluZyhzKQpyZXR1cm4gcitkK3F9LApRaTpmdW5jdGlvbihhLGIs
+Yyl7dmFyIHMKaWYoYzwwfHxjPmEubGVuZ3RoKXRocm93IEguYihQLlRFKGMsMCxhLmxlbmd0aCxudWxs
+LG51bGwpKQpzPWMrYi5sZW5ndGgKaWYocz5hLmxlbmd0aClyZXR1cm4hMQpyZXR1cm4gYj09PWEuc3Vi
+c3RyaW5nKGMscyl9LApuQzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlFpKGEsYiwwKX0sCk5qOmZ1
+bmN0aW9uKGEsYixjKXtpZihjPT1udWxsKWM9YS5sZW5ndGgKaWYoYjwwKXRocm93IEguYihQLk83KGIs
+bnVsbCkpCmlmKGI+Yyl0aHJvdyBILmIoUC5PNyhiLG51bGwpKQppZihjPmEubGVuZ3RoKXRocm93IEgu
+YihQLk83KGMsbnVsbCkpCnJldHVybiBhLnN1YnN0cmluZyhiLGMpfSwKeW46ZnVuY3Rpb24oYSxiKXty
+ZXR1cm4gdGhpcy5OaihhLGIsbnVsbCl9LApoYzpmdW5jdGlvbihhKXtyZXR1cm4gYS50b0xvd2VyQ2Fz
+ZSgpfSwKYlM6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHA9YS50cmltKCksbz1wLmxlbmd0aAppZihvPT09
+MClyZXR1cm4gcAppZih0aGlzLlcocCwwKT09PTEzMyl7cz1KLm1tKHAsMSkKaWYocz09PW8pcmV0dXJu
+IiJ9ZWxzZSBzPTAKcj1vLTEKcT10aGlzLk8yKHAscik9PT0xMzM/Si5jMShwLHIpOm8KaWYocz09PTAm
+JnE9PT1vKXJldHVybiBwCnJldHVybiBwLnN1YnN0cmluZyhzLHEpfSwKVDpmdW5jdGlvbihhLGIpe3Zh
+ciBzLHIKaWYoMD49YilyZXR1cm4iIgppZihiPT09MXx8YS5sZW5ndGg9PT0wKXJldHVybiBhCmlmKGIh
+PT1iPj4+MCl0aHJvdyBILmIoQy5FcSkKZm9yKHM9YSxyPSIiOyEwOyl7aWYoKGImMSk9PT0xKXI9cyty
+CmI9Yj4+PjEKaWYoYj09PTApYnJlYWsKcys9c31yZXR1cm4gcn0sClhVOmZ1bmN0aW9uKGEsYixjKXt2
+YXIgcwppZihjPDB8fGM+YS5sZW5ndGgpdGhyb3cgSC5iKFAuVEUoYywwLGEubGVuZ3RoLG51bGwsbnVs
+bCkpCnM9YS5pbmRleE9mKGIsYykKcmV0dXJuIHN9LApPWTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlz
+LlhVKGEsYiwwKX0sClBrOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyCmlmKGM9PW51bGwpYz1hLmxlbmd0
+aAplbHNlIGlmKGM8MHx8Yz5hLmxlbmd0aCl0aHJvdyBILmIoUC5URShjLDAsYS5sZW5ndGgsbnVsbCxu
+dWxsKSkKcz1iLmxlbmd0aApyPWEubGVuZ3RoCmlmKGMrcz5yKWM9ci1zCnJldHVybiBhLmxhc3RJbmRl
+eE9mKGIsYyl9LApjbjpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlBrKGEsYixudWxsKX0sCklzOmZ1
+bmN0aW9uKGEsYixjKXt2YXIgcz1hLmxlbmd0aAppZihjPnMpdGhyb3cgSC5iKFAuVEUoYywwLHMsbnVs
+bCxudWxsKSkKcmV0dXJuIEguU1EoYSxiLGMpfSwKdGc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5J
+cyhhLGIsMCl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBhfSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciBzLHIs
+cQpmb3Iocz1hLmxlbmd0aCxyPTAscT0wO3E8czsrK3Epe3I9cithLmNoYXJDb2RlQXQocSkmNTM2ODcw
+OTExCnI9cisoKHImNTI0Mjg3KTw8MTApJjUzNjg3MDkxMQpyXj1yPj42fXI9cisoKHImNjcxMDg4NjMp
+PDwzKSY1MzY4NzA5MTEKcl49cj4+MTEKcmV0dXJuIHIrKChyJjE2MzgzKTw8MTUpJjUzNjg3MDkxMX0s
+CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILnVQKGIpCmlm
+KGI+PWEubGVuZ3RofHwhMSl0aHJvdyBILmIoSC5IWShhLGIpKQpyZXR1cm4gYVtiXX0sCiRpdlg6MSwK
+JGlxVToxfQpILkJSLnByb3RvdHlwZT17CmdtOmZ1bmN0aW9uKGEpe3ZhciBzPUguTGgodGhpcykKcmV0
+dXJuIG5ldyBILkU3KEouSVQodGhpcy5nT04oKSkscy5DKCJAPDE+IikuS3Eocy5RWzFdKS5DKCJFNzwx
+LDI+IikpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIEouSG0odGhpcy5nT04oKSl9LApnbDA6ZnVuY3Rp
+b24oYSl7cmV0dXJuIEoudVUodGhpcy5nT04oKSl9LApnb3I6ZnVuY3Rpb24oYSl7cmV0dXJuIEouRjco
+dGhpcy5nT04oKSl9LAplUjpmdW5jdGlvbihhLGIpe3ZhciBzPUguTGgodGhpcykKcmV0dXJuIEguR0oo
+Si5BNSh0aGlzLmdPTigpLGIpLHMuYyxzLlFbMV0pfSwKRTpmdW5jdGlvbihhLGIpe3JldHVybiBILkxo
+KHRoaXMpLlFbMV0uYShKLkdBKHRoaXMuZ09OKCksYikpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gSi5q
+KHRoaXMuZ09OKCkpfX0KSC5FNy5wcm90b3R5cGU9ewpGOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYS5G
+KCl9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLiR0aS5RWzFdLmEodGhpcy5hLmdsKCkpfSwKJGlB
+bjoxfQpILlp5LnByb3RvdHlwZT17CmdPTjpmdW5jdGlvbigpe3JldHVybiB0aGlzLmF9fQpILm9sLnBy
+b3RvdHlwZT17JGliUToxfQpILlVxLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhp
+cy4kdGkuUVsxXS5hKEoueDkodGhpcy5hLEgudVAoYikpKX0sClk1OmZ1bmN0aW9uKGEsYixjKXt2YXIg
+cz10aGlzLiR0aQpKLnU5KHRoaXMuYSxiLHMuYy5hKHMuUVsxXS5hKGMpKSl9LAokaWJROjEsCiRpek06
+MX0KSC5qVi5wcm90b3R5cGU9ewpkcjpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgSC5qVih0aGlzLmEs
+dGhpcy4kdGkuQygiQDwxPiIpLktxKGIpLkMoImpWPDEsMj4iKSl9LApnT046ZnVuY3Rpb24oKXtyZXR1
+cm4gdGhpcy5hfX0KSC5uLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5hCnJldHVy
+biBzIT1udWxsPyJMYXRlSW5pdGlhbGl6YXRpb25FcnJvcjogIitzOiJMYXRlSW5pdGlhbGl6YXRpb25F
+cnJvciJ9fQpILnIzLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHM9IlJlYWNoYWJpbGl0eUVy
+cm9yOiAiK3RoaXMuYQpyZXR1cm4gc319CkgucWoucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0
+dXJuIHRoaXMuYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEMueEIuTzIodGhpcy5hLEgu
+dVAoYikpfX0KSC5HTS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJOdWxsIGlzIG5vdCBh
+IHZhbGlkIHZhbHVlIGZvciB0aGUgcGFyYW1ldGVyICciK3RoaXMuYSsiJyBvZiB0eXBlICciK0guS3go
+dGhpcy4kdGkuYykudygwKSsiJyJ9fQpILmJRLnByb3RvdHlwZT17fQpILmFMLnByb3RvdHlwZT17Cmdt
+OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMKcmV0dXJuIG5ldyBILmE3KHMscy5nQShzKSxILkxoKHMpLkMo
+ImE3PGFMLkU+IikpfSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmdBKHRoaXMpPT09MH0sCms6
+ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscD10aGlzLG89cC5nQShwKQppZihiLmxlbmd0aCE9PTApe2lm
+KG89PT0wKXJldHVybiIiCnM9SC5FaihwLkUoMCwwKSkKaWYobyE9PXAuZ0EocCkpdGhyb3cgSC5iKFAu
+YTQocCkpCmZvcihyPXMscT0xO3E8bzsrK3Epe3I9citiK0guRWoocC5FKDAscSkpCmlmKG8hPT1wLmdB
+KHApKXRocm93IEguYihQLmE0KHApKX1yZXR1cm4gci5jaGFyQ29kZUF0KDApPT0wP3I6cn1lbHNle2Zv
+cihxPTAscj0iIjtxPG87KytxKXtyKz1ILkVqKHAuRSgwLHEpKQppZihvIT09cC5nQShwKSl0aHJvdyBI
+LmIoUC5hNChwKSl9cmV0dXJuIHIuY2hhckNvZGVBdCgwKT09MD9yOnJ9fSwKZXY6ZnVuY3Rpb24oYSxi
+KXtyZXR1cm4gdGhpcy5HRygwLEguTGgodGhpcykuQygiYTIoYUwuRSkiKS5hKGIpKX0sCkUyOmZ1bmN0
+aW9uKGEsYixjKXt2YXIgcz1ILkxoKHRoaXMpCnJldHVybiBuZXcgSC5sSih0aGlzLHMuS3EoYykuQygi
+MShhTC5FKSIpLmEoYikscy5DKCJAPGFMLkU+IikuS3EoYykuQygibEo8MSwyPiIpKX0sCmVSOmZ1bmN0
+aW9uKGEsYil7cmV0dXJuIEgucUModGhpcyxiLG51bGwsSC5MaCh0aGlzKS5DKCJhTC5FIikpfSwKdHQ6
+ZnVuY3Rpb24oYSxiKXtyZXR1cm4gUC5ZMSh0aGlzLCEwLEguTGgodGhpcykuQygiYUwuRSIpKX0sCmJy
+OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLnR0KGEsITApfX0KSC5uSC5wcm90b3R5cGU9ewpIZDpmdW5j
+dGlvbihhLGIsYyxkKXt2YXIgcyxyPXRoaXMuYgpQLmsxKHIsInN0YXJ0IikKcz10aGlzLmMKaWYocyE9
+bnVsbCl7UC5rMShzLCJlbmQiKQppZihyPnMpdGhyb3cgSC5iKFAuVEUociwwLHMsInN0YXJ0IixudWxs
+KSl9fSwKZ1VEOmZ1bmN0aW9uKCl7dmFyIHM9Si5IbSh0aGlzLmEpLHI9dGhpcy5jCmlmKHI9PW51bGx8
+fHI+cylyZXR1cm4gcwpyZXR1cm4gcn0sCmdBczpmdW5jdGlvbigpe3ZhciBzPUouSG0odGhpcy5hKSxy
+PXRoaXMuYgppZihyPnMpcmV0dXJuIHMKcmV0dXJuIHJ9LApnQTpmdW5jdGlvbihhKXt2YXIgcyxyPUou
+SG0odGhpcy5hKSxxPXRoaXMuYgppZihxPj1yKXJldHVybiAwCnM9dGhpcy5jCmlmKHM9PW51bGx8fHM+
+PXIpcmV0dXJuIHItcQppZih0eXBlb2YgcyE9PSJudW1iZXIiKXJldHVybiBzLkhOKCkKcmV0dXJuIHMt
+cX0sCkU6ZnVuY3Rpb24oYSxiKXt2YXIgcz10aGlzLHI9cy5nQXMoKStiCmlmKGI8MHx8cj49cy5nVUQo
+KSl0aHJvdyBILmIoUC5DZihiLHMsImluZGV4IixudWxsLG51bGwpKQpyZXR1cm4gSi5HQShzLmEscil9
+LAplUjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT10aGlzClAuazEoYiwiY291bnQiKQpzPXEuYitiCnI9
+cS5jCmlmKHIhPW51bGwmJnM+PXIpcmV0dXJuIG5ldyBILk1CKHEuJHRpLkMoIk1CPDE+IikpCnJldHVy
+biBILnFDKHEuYSxzLHIscS4kdGkuYyl9LAp0dDpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwPXRoaXMs
+bz1wLmIsbj1wLmEsbT1KLlU2KG4pLGw9bS5nQShuKSxrPXAuYwppZihrIT1udWxsJiZrPGwpbD1rCmlm
+KHR5cGVvZiBsIT09Im51bWJlciIpcmV0dXJuIGwuSE4oKQpzPWwtbwppZihzPD0wKXtuPUouUWkoMCxw
+LiR0aS5jKQpyZXR1cm4gbn1yPVAuTzgocyxtLkUobixvKSwhMSxwLiR0aS5jKQpmb3IocT0xO3E8czsr
+K3Epe0MuTm0uWTUocixxLG0uRShuLG8rcSkpCmlmKG0uZ0Eobik8bCl0aHJvdyBILmIoUC5hNChwKSl9
+cmV0dXJuIHJ9fQpILmE3LnByb3RvdHlwZT17CmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCkY6
+ZnVuY3Rpb24oKXt2YXIgcyxyPXRoaXMscT1yLmEscD1KLlU2KHEpLG89cC5nQShxKQppZihyLmIhPT1v
+KXRocm93IEguYihQLmE0KHEpKQpzPXIuYwppZihzPj1vKXtyLnNJKG51bGwpCnJldHVybiExfXIuc0ko
+cC5FKHEscykpOysrci5jCnJldHVybiEwfSwKc0k6ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLkMo
+IjE/IikuYShhKX0sCiRpQW46MX0KSC5pMS5wcm90b3R5cGU9ewpnbTpmdW5jdGlvbihhKXt2YXIgcz1I
+LkxoKHRoaXMpCnJldHVybiBuZXcgSC5NSChKLklUKHRoaXMuYSksdGhpcy5iLHMuQygiQDwxPiIpLktx
+KHMuUVsxXSkuQygiTUg8MSwyPiIpKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiBKLkhtKHRoaXMuYSl9
+LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIEoudVUodGhpcy5hKX0sCkU6ZnVuY3Rpb24oYSxiKXtyZXR1
+cm4gdGhpcy5iLiQxKEouR0EodGhpcy5hLGIpKX19CkgueHkucHJvdG90eXBlPXskaWJROjF9CkguTUgu
+cHJvdG90eXBlPXsKRjpmdW5jdGlvbigpe3ZhciBzPXRoaXMscj1zLmIKaWYoci5GKCkpe3Muc0kocy5j
+LiQxKHIuZ2woKSkpCnJldHVybiEwfXMuc0kobnVsbCkKcmV0dXJuITF9LApnbDpmdW5jdGlvbigpe3Jl
+dHVybiB0aGlzLmF9LApzSTpmdW5jdGlvbihhKXt0aGlzLmE9dGhpcy4kdGkuQygiMj8iKS5hKGEpfX0K
+SC5sSi5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gSi5IbSh0aGlzLmEpfSwKRTpmdW5j
+dGlvbihhLGIpe3JldHVybiB0aGlzLmIuJDEoSi5HQSh0aGlzLmEsYikpfX0KSC5VNS5wcm90b3R5cGU9
+ewpnbTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEguU08oSi5JVCh0aGlzLmEpLHRoaXMuYix0aGlzLiR0
+aS5DKCJTTzwxPiIpKX19CkguU08ucHJvdG90eXBlPXsKRjpmdW5jdGlvbigpe3ZhciBzLHIKZm9yKHM9
+dGhpcy5hLHI9dGhpcy5iO3MuRigpOylpZihILm9UKHIuJDEocy5nbCgpKSkpcmV0dXJuITAKcmV0dXJu
+ITF9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmEuZ2woKX19CkguQU0ucHJvdG90eXBlPXsKZVI6
+ZnVuY3Rpb24oYSxiKXtQLk1SKGIsImNvdW50Iix0LlMpClAuazEoYiwiY291bnQiKQpyZXR1cm4gbmV3
+IEguQU0odGhpcy5hLHRoaXMuYitiLEguTGgodGhpcykuQygiQU08MT4iKSl9LApnbTpmdW5jdGlvbihh
+KXtyZXR1cm4gbmV3IEguVTEoSi5JVCh0aGlzLmEpLHRoaXMuYixILkxoKHRoaXMpLkMoIlUxPDE+Iikp
+fX0KSC5kNS5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXt2YXIgcz1KLkhtKHRoaXMuYSktdGhpcy5i
+CmlmKHM+PTApcmV0dXJuIHMKcmV0dXJuIDB9LAplUjpmdW5jdGlvbihhLGIpe1AuTVIoYiwiY291bnQi
+LHQuUykKUC5rMShiLCJjb3VudCIpCnJldHVybiBuZXcgSC5kNSh0aGlzLmEsdGhpcy5iK2IsdGhpcy4k
+dGkpfSwKJGliUToxfQpILlUxLnByb3RvdHlwZT17CkY6ZnVuY3Rpb24oKXt2YXIgcyxyCmZvcihzPXRo
+aXMuYSxyPTA7cjx0aGlzLmI7KytyKXMuRigpCnRoaXMuYj0wCnJldHVybiBzLkYoKX0sCmdsOmZ1bmN0
+aW9uKCl7cmV0dXJuIHRoaXMuYS5nbCgpfX0KSC5NQi5wcm90b3R5cGU9ewpnbTpmdW5jdGlvbihhKXty
+ZXR1cm4gQy5Hd30sCmdsMDpmdW5jdGlvbihhKXtyZXR1cm4hMH0sCmdBOmZ1bmN0aW9uKGEpe3JldHVy
+biAwfSwKRTpmdW5jdGlvbihhLGIpe3Rocm93IEguYihQLlRFKGIsMCwwLCJpbmRleCIsbnVsbCkpfSwK
+ZVI6ZnVuY3Rpb24oYSxiKXtQLmsxKGIsImNvdW50IikKcmV0dXJuIHRoaXN9fQpILkZ1LnByb3RvdHlw
+ZT17CkY6ZnVuY3Rpb24oKXtyZXR1cm4hMX0sCmdsOmZ1bmN0aW9uKCl7dGhyb3cgSC5iKEguV3AoKSl9
+LAokaUFuOjF9CkgudTYucHJvdG90eXBlPXsKZ206ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILkpCKEou
+SVQodGhpcy5hKSx0aGlzLiR0aS5DKCJKQjwxPiIpKX19CkguSkIucHJvdG90eXBlPXsKRjpmdW5jdGlv
+bigpe3ZhciBzLHIKZm9yKHM9dGhpcy5hLHI9dGhpcy4kdGkuYztzLkYoKTspaWYoci5iKHMuZ2woKSkp
+cmV0dXJuITAKcmV0dXJuITF9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLiR0aS5jLmEodGhpcy5h
+LmdsKCkpfSwKJGlBbjoxfQpILlNVLnByb3RvdHlwZT17fQpILlJlLnByb3RvdHlwZT17Clk1OmZ1bmN0
+aW9uKGEsYixjKXtILkxoKHRoaXMpLkMoIlJlLkUiKS5hKGMpCnRocm93IEguYihQLkw0KCJDYW5ub3Qg
+bW9kaWZ5IGFuIHVubW9kaWZpYWJsZSBsaXN0IikpfX0KSC53Mi5wcm90b3R5cGU9e30KSC53di5wcm90
+b3R5cGU9ewpnaU86ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5faGFzaENvZGUKaWYocyE9bnVsbClyZXR1
+cm4gcwpzPTY2NDU5NypKLmhmKHRoaXMuYSkmNTM2ODcwOTExCnRoaXMuX2hhc2hDb2RlPXMKcmV0dXJu
+IHN9LAp3OmZ1bmN0aW9uKGEpe3JldHVybidTeW1ib2woIicrSC5Faih0aGlzLmEpKyciKSd9LApETjpm
+dW5jdGlvbihhLGIpe2lmKGI9PW51bGwpcmV0dXJuITEKcmV0dXJuIGIgaW5zdGFuY2VvZiBILnd2JiZ0
+aGlzLmE9PWIuYX0sCiRpR0Q6MX0KSC5RQy5wcm90b3R5cGU9e30KSC5QRC5wcm90b3R5cGU9e30KSC5X
+VS5wcm90b3R5cGU9ewpnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ0EodGhpcyk9PT0wfSwKdzpm
+dW5jdGlvbihhKXtyZXR1cm4gUC5uTyh0aGlzKX0sClk1OmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1ILkxo
+KHRoaXMpCnMuYy5hKGIpCnMuUVsxXS5hKGMpCkguZGMoKQpILkJpKHUuZyl9LApnUHU6ZnVuY3Rpb24o
+YSl7cmV0dXJuIHRoaXMucTQoYSxILkxoKHRoaXMpLkMoIk4zPDEsMj4iKSl9LApxNDpmdW5jdGlvbihh
+LGIpe3ZhciBzPXRoaXMKcmV0dXJuIFAubDAoZnVuY3Rpb24oKXt2YXIgcj1hCnZhciBxPTAscD0xLG8s
+bixtLGwsawpyZXR1cm4gZnVuY3Rpb24gJGFzeW5jJGdQdShjLGQpe2lmKGM9PT0xKXtvPWQKcT1wfXdo
+aWxlKHRydWUpc3dpdGNoKHEpe2Nhc2UgMDpuPXMuZ3ZjKCksbj1uLmdtKG4pLG09SC5MaChzKSxtPW0u
+QygiQDwxPiIpLktxKG0uUVsxXSkuQygiTjM8MSwyPiIpCmNhc2UgMjppZighbi5GKCkpe3E9MwpicmVh
+a31sPW4uZ2woKQprPXMucSgwLGwpCmsudG9TdHJpbmcKcT00CnJldHVybiBuZXcgUC5OMyhsLGssbSkK
+Y2FzZSA0OnE9MgpicmVhawpjYXNlIDM6cmV0dXJuIFAuVGgoKQpjYXNlIDE6cmV0dXJuIFAuWW0obyl9
+fX0sYil9LAokaVowOjF9CkguTFAucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
+YX0sCng0OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhIT0ic3RyaW5nIilyZXR1cm4hMQppZigiX19wcm90
+b19fIj09PWEpcmV0dXJuITEKcmV0dXJuIHRoaXMuYi5oYXNPd25Qcm9wZXJ0eShhKX0sCnE6ZnVuY3Rp
+b24oYSxiKXtpZighdGhpcy54NChiKSlyZXR1cm4gbnVsbApyZXR1cm4gdGhpcy5xUChiKX0sCnFQOmZ1
+bmN0aW9uKGEpe3JldHVybiB0aGlzLmJbSC5oKGEpXX0sCks6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEs
+cCxvPUguTGgodGhpcykKby5DKCJ+KDEsMikiKS5hKGIpCnM9dGhpcy5jCmZvcihyPXMubGVuZ3RoLG89
+by5RWzFdLHE9MDtxPHI7KytxKXtwPXNbcV0KYi4kMihwLG8uYSh0aGlzLnFQKHApKSl9fSwKZ3ZjOmZ1
+bmN0aW9uKCl7cmV0dXJuIG5ldyBILlhSKHRoaXMsSC5MaCh0aGlzKS5DKCJYUjwxPiIpKX19CkguWFIu
+cHJvdG90eXBlPXsKZ206ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5hLmMKcmV0dXJuIG5ldyBKLm0xKHMs
+cy5sZW5ndGgsSC50NihzKS5DKCJtMTwxPiIpKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEu
+Yy5sZW5ndGh9fQpILkxJLnByb3RvdHlwZT17CmdXYTpmdW5jdGlvbigpe3ZhciBzPXRoaXMuYQpyZXR1
+cm4gc30sCmduZDpmdW5jdGlvbigpe3ZhciBzLHIscSxwLG89dGhpcwppZihvLmM9PT0xKXJldHVybiBD
+LmhVCnM9by5kCnI9cy5sZW5ndGgtby5lLmxlbmd0aC1vLmYKaWYocj09PTApcmV0dXJuIEMuaFUKcT1b
+XQpmb3IocD0wO3A8cjsrK3Ape2lmKHA+PXMubGVuZ3RoKXJldHVybiBILk9IKHMscCkKcS5wdXNoKHNb
+cF0pfXJldHVybiBKLnpDKHEpfSwKZ1ZtOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbyxuLG0sbCxrPXRo
+aXMKaWYoay5jIT09MClyZXR1cm4gQy5XTwpzPWsuZQpyPXMubGVuZ3RoCnE9ay5kCnA9cS5sZW5ndGgt
+ci1rLmYKaWYocj09PTApcmV0dXJuIEMuV08Kbz1uZXcgSC5ONSh0LmVvKQpmb3Iobj0wO248cjsrK24p
+e2lmKG4+PXMubGVuZ3RoKXJldHVybiBILk9IKHMsbikKbT1zW25dCmw9cCtuCmlmKGw8MHx8bD49cS5s
+ZW5ndGgpcmV0dXJuIEguT0gocSxsKQpvLlk1KDAsbmV3IEgud3YobSkscVtsXSl9cmV0dXJuIG5ldyBI
+LlBEKG8sdC5nRil9LAokaXZROjF9CkguQ2oucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIg
+cwpILmgoYSkKcz10aGlzLmEKcy5iPXMuYisiJCIrSC5FaihhKQpDLk5tLmkodGhpcy5iLGEpCkMuTm0u
+aSh0aGlzLmMsYik7KytzLmF9LAokUzoxMn0KSC5mOS5wcm90b3R5cGU9ewpxUzpmdW5jdGlvbihhKXt2
+YXIgcyxyLHE9dGhpcyxwPW5ldyBSZWdFeHAocS5hKS5leGVjKGEpCmlmKHA9PW51bGwpcmV0dXJuIG51
+bGwKcz1PYmplY3QuY3JlYXRlKG51bGwpCnI9cS5iCmlmKHIhPT0tMSlzLmFyZ3VtZW50cz1wW3IrMV0K
+cj1xLmMKaWYociE9PS0xKXMuYXJndW1lbnRzRXhwcj1wW3IrMV0Kcj1xLmQKaWYociE9PS0xKXMuZXhw
+cj1wW3IrMV0Kcj1xLmUKaWYociE9PS0xKXMubWV0aG9kPXBbcisxXQpyPXEuZgppZihyIT09LTEpcy5y
+ZWNlaXZlcj1wW3IrMV0KcmV0dXJuIHN9fQpILlcwLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFy
+IHM9dGhpcy5iCmlmKHM9PW51bGwpcmV0dXJuIk5vU3VjaE1ldGhvZEVycm9yOiAiK0guRWoodGhpcy5h
+KQpyZXR1cm4iTm9TdWNoTWV0aG9kRXJyb3I6IG1ldGhvZCBub3QgZm91bmQ6ICciK3MrIicgb24gbnVs
+bCJ9fQpILmF6LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHMscj10aGlzLHE9Ik5vU3VjaE1l
+dGhvZEVycm9yOiBtZXRob2Qgbm90IGZvdW5kOiAnIixwPXIuYgppZihwPT1udWxsKXJldHVybiJOb1N1
+Y2hNZXRob2RFcnJvcjogIitILkVqKHIuYSkKcz1yLmMKaWYocz09bnVsbClyZXR1cm4gcStwKyInICgi
+K0guRWooci5hKSsiKSIKcmV0dXJuIHErcCsiJyBvbiAnIitzKyInICgiK0guRWooci5hKSsiKSJ9fQpI
+LnZWLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5hCnJldHVybiBzLmxlbmd0aD09
+PTA/IkVycm9yIjoiRXJyb3I6ICIrc319CkgudGUucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1
+cm4iVGhyb3cgb2YgbnVsbCAoJyIrKHRoaXMuYT09PW51bGw/Im51bGwiOiJ1bmRlZmluZWQiKSsiJyBm
+cm9tIEphdmFTY3JpcHQpIn0sCiRpUno6MX0KSC5icS5wcm90b3R5cGU9e30KSC5YTy5wcm90b3R5cGU9
+ewp3OmZ1bmN0aW9uKGEpe3ZhciBzLHI9dGhpcy5iCmlmKHIhPW51bGwpcmV0dXJuIHIKcj10aGlzLmEK
+cz1yIT09bnVsbCYmdHlwZW9mIHI9PT0ib2JqZWN0Ij9yLnN0YWNrOm51bGwKcmV0dXJuIHRoaXMuYj1z
+PT1udWxsPyIiOnN9LAokaUd6OjF9CkguVHAucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgcz10
+aGlzLmNvbnN0cnVjdG9yLHI9cz09bnVsbD9udWxsOnMubmFtZQpyZXR1cm4iQ2xvc3VyZSAnIitILk5R
+KHI9PW51bGw/InVua25vd24iOnIpKyInIn0sCiRpRUg6MSwKZ0t1OmZ1bmN0aW9uKCl7cmV0dXJuIHRo
+aXN9LAokQzoiJDEiLAokUjoxLAokRDpudWxsfQpILmxjLnByb3RvdHlwZT17fQpILnp4LnByb3RvdHlw
+ZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy4kc3RhdGljX25hbWUKaWYocz09bnVsbClyZXR1cm4i
+Q2xvc3VyZSBvZiB1bmtub3duIHN0YXRpYyBtZXRob2QiCnJldHVybiJDbG9zdXJlICciK0guTlEocykr
+IicifX0KSC5yVC5wcm90b3R5cGU9ewpETjpmdW5jdGlvbihhLGIpe3ZhciBzPXRoaXMKaWYoYj09bnVs
+bClyZXR1cm4hMQppZihzPT09YilyZXR1cm4hMAppZighKGIgaW5zdGFuY2VvZiBILnJUKSlyZXR1cm4h
+MQpyZXR1cm4gcy5hPT09Yi5hJiZzLmI9PT1iLmImJnMuYz09PWIuY30sCmdpTzpmdW5jdGlvbihhKXt2
+YXIgcyxyPXRoaXMuYwppZihyPT1udWxsKXM9SC5lUSh0aGlzLmEpCmVsc2Ugcz10eXBlb2YgciE9PSJv
+YmplY3QiP0ouaGYocik6SC5lUShyKQpyPUguZVEodGhpcy5iKQppZih0eXBlb2YgcyE9PSJudW1iZXIi
+KXJldHVybiBzLlkoKQpyZXR1cm4oc15yKT4+PjB9LAp3OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuYwpp
+ZihzPT1udWxsKXM9dGhpcy5hCnJldHVybiJDbG9zdXJlICciK0guRWoodGhpcy5kKSsiJyBvZiAiKygi
+SW5zdGFuY2Ugb2YgJyIrSC5FaihILk0ocykpKyInIil9fQpILkVxLnByb3RvdHlwZT17Cnc6ZnVuY3Rp
+b24oYSl7cmV0dXJuIlJ1bnRpbWVFcnJvcjogIit0aGlzLmF9fQpILmtZLnByb3RvdHlwZT17Cnc6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIkFzc2VydGlvbiBmYWlsZWQ6ICIrUC5wKHRoaXMuYSl9fQpILmtyLnByb3Rv
+dHlwZT17fQpILk41LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9LApnbDA6
+ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYT09PTB9LApndmM6ZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEgu
+aTUodGhpcyxILkxoKHRoaXMpLkMoImk1PDE+IikpfSwKeDQ6ZnVuY3Rpb24oYSl7dmFyIHMscgppZih0
+eXBlb2YgYT09InN0cmluZyIpe3M9dGhpcy5iCmlmKHM9PW51bGwpcmV0dXJuITEKcmV0dXJuIHRoaXMu
+WHUocyxhKX1lbHNle3I9dGhpcy5DWChhKQpyZXR1cm4gcn19LApDWDpmdW5jdGlvbihhKXt2YXIgcz10
+aGlzLmQKaWYocz09bnVsbClyZXR1cm4hMQpyZXR1cm4gdGhpcy5GaCh0aGlzLkJ0KHMsSi5oZihhKSYw
+eDNmZmZmZmYpLGEpPj0wfSwKcTpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG89dGhpcyxuPW51bGwK
+aWYodHlwZW9mIGI9PSJzdHJpbmciKXtzPW8uYgppZihzPT1udWxsKXJldHVybiBuCnI9by5qMihzLGIp
+CnE9cj09bnVsbD9uOnIuYgpyZXR1cm4gcX1lbHNlIGlmKHR5cGVvZiBiPT0ibnVtYmVyIiYmKGImMHgz
+ZmZmZmZmKT09PWIpe3A9by5jCmlmKHA9PW51bGwpcmV0dXJuIG4Kcj1vLmoyKHAsYikKcT1yPT1udWxs
+P246ci5iCnJldHVybiBxfWVsc2UgcmV0dXJuIG8uYWEoYil9LAphYTpmdW5jdGlvbihhKXt2YXIgcyxy
+LHE9dGhpcy5kCmlmKHE9PW51bGwpcmV0dXJuIG51bGwKcz10aGlzLkJ0KHEsSi5oZihhKSYweDNmZmZm
+ZmYpCnI9dGhpcy5GaChzLGEpCmlmKHI8MClyZXR1cm4gbnVsbApyZXR1cm4gc1tyXS5ifSwKWTU6ZnVu
+Y3Rpb24oYSxiLGMpe3ZhciBzLHIscSxwLG8sbixtPXRoaXMsbD1ILkxoKG0pCmwuYy5hKGIpCmwuUVsx
+XS5hKGMpCmlmKHR5cGVvZiBiPT0ic3RyaW5nIil7cz1tLmIKbS5FSChzPT1udWxsP20uYj1tLnpLKCk6
+cyxiLGMpfWVsc2UgaWYodHlwZW9mIGI9PSJudW1iZXIiJiYoYiYweDNmZmZmZmYpPT09Yil7cj1tLmMK
+bS5FSChyPT1udWxsP20uYz1tLnpLKCk6cixiLGMpfWVsc2V7cT1tLmQKaWYocT09bnVsbClxPW0uZD1t
+LnpLKCkKcD1KLmhmKGIpJjB4M2ZmZmZmZgpvPW0uQnQocSxwKQppZihvPT1udWxsKW0uRUkocSxwLFtt
+LkhuKGIsYyldKQplbHNle249bS5GaChvLGIpCmlmKG4+PTApb1tuXS5iPWMKZWxzZSBvLnB1c2gobS5I
+bihiLGMpKX19fSwKSzpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT10aGlzCkguTGgocSkuQygifigxLDIp
+IikuYShiKQpzPXEuZQpyPXEucgpmb3IoO3MhPW51bGw7KXtiLiQyKHMuYSxzLmIpCmlmKHIhPT1xLnIp
+dGhyb3cgSC5iKFAuYTQocSkpCnM9cy5jfX0sCkVIOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyPXRoaXMs
+cT1ILkxoKHIpCnEuYy5hKGIpCnEuUVsxXS5hKGMpCnM9ci5qMihhLGIpCmlmKHM9PW51bGwpci5FSShh
+LGIsci5IbihiLGMpKQplbHNlIHMuYj1jfSwKa3M6ZnVuY3Rpb24oKXt0aGlzLnI9dGhpcy5yKzEmNjcx
+MDg4NjN9LApIbjpmdW5jdGlvbihhLGIpe3ZhciBzPXRoaXMscj1ILkxoKHMpLHE9bmV3IEgudmgoci5j
+LmEoYSksci5RWzFdLmEoYikpCmlmKHMuZT09bnVsbClzLmU9cy5mPXEKZWxzZXtyPXMuZgpyLnRvU3Ry
+aW5nCnEuZD1yCnMuZj1yLmM9cX0rK3MuYQpzLmtzKCkKcmV0dXJuIHF9LApGaDpmdW5jdGlvbihhLGIp
+e3ZhciBzLHIKaWYoYT09bnVsbClyZXR1cm4tMQpzPWEubGVuZ3RoCmZvcihyPTA7cjxzOysrcilpZihK
+LlJNKGFbcl0uYSxiKSlyZXR1cm4gcgpyZXR1cm4tMX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFAubk8o
+dGhpcyl9LApqMjpmdW5jdGlvbihhLGIpe3JldHVybiBhW2JdfSwKQnQ6ZnVuY3Rpb24oYSxiKXtyZXR1
+cm4gYVtiXX0sCkVJOmZ1bmN0aW9uKGEsYixjKXthW2JdPWN9LApybjpmdW5jdGlvbihhLGIpe2RlbGV0
+ZSBhW2JdfSwKWHU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5qMihhLGIpIT1udWxsfSwKeks6ZnVu
+Y3Rpb24oKXt2YXIgcz0iPG5vbi1pZGVudGlmaWVyLWtleT4iLHI9T2JqZWN0LmNyZWF0ZShudWxsKQp0
+aGlzLkVJKHIscyxyKQp0aGlzLnJuKHIscykKcmV0dXJuIHJ9LAokaUZvOjF9CkgudmgucHJvdG90eXBl
+PXt9CkguaTUucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5hfSwKZ2wwOmZ1
+bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuYT09PTB9LApnbTpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmEs
+cj1uZXcgSC5ONihzLHMucix0aGlzLiR0aS5DKCJONjwxPiIpKQpyLmM9cy5lCnJldHVybiByfSwKdGc6
+ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5hLng0KGIpfX0KSC5ONi5wcm90b3R5cGU9ewpnbDpmdW5j
+dGlvbigpe3JldHVybiB0aGlzLmR9LApGOmZ1bmN0aW9uKCl7dmFyIHMscj10aGlzLHE9ci5hCmlmKHIu
+YiE9PXEucil0aHJvdyBILmIoUC5hNChxKSkKcz1yLmMKaWYocz09bnVsbCl7ci5zcVkobnVsbCkKcmV0
+dXJuITF9ZWxzZXtyLnNxWShzLmEpCnIuYz1zLmMKcmV0dXJuITB9fSwKc3FZOmZ1bmN0aW9uKGEpe3Ro
+aXMuZD10aGlzLiR0aS5DKCIxPyIpLmEoYSl9LAokaUFuOjF9CkguZEMucHJvdG90eXBlPXsKJDE6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIHRoaXMuYShhKX0sCiRTOjR9Ckgud04ucHJvdG90eXBlPXsKJDI6ZnVuY3Rp
+b24oYSxiKXtyZXR1cm4gdGhpcy5hKGEsYil9LAokUzo0Nn0KSC5WWC5wcm90b3R5cGU9ewokMTpmdW5j
+dGlvbihhKXtyZXR1cm4gdGhpcy5hKEguaChhKSl9LAokUzo0MX0KSC5WUi5wcm90b3R5cGU9ewp3OmZ1
+bmN0aW9uKGEpe3JldHVybiJSZWdFeHAvIit0aGlzLmErIi8iK3RoaXMuYi5mbGFnc30sCmdIYzpmdW5j
+dGlvbigpe3ZhciBzPXRoaXMscj1zLmMKaWYociE9bnVsbClyZXR1cm4gcgpyPXMuYgpyZXR1cm4gcy5j
+PUgudjQocy5hLHIubXVsdGlsaW5lLCFyLmlnbm9yZUNhc2Usci51bmljb2RlLHIuZG90QWxsLCEwKX0s
+CmRkOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILktXKHRoaXMsYiwwKX0sClVaOmZ1bmN0aW9uKGEs
+Yil7dmFyIHMscj10aGlzLmdIYygpCnIubGFzdEluZGV4PWIKcz1yLmV4ZWMoYSkKaWYocz09bnVsbCly
+ZXR1cm4gbnVsbApyZXR1cm4gbmV3IEguRUsocyl9LAokaXZYOjEsCiRpd0w6MX0KSC5FSy5wcm90b3R5
+cGU9ewpxOmZ1bmN0aW9uKGEsYil7dmFyIHMKSC51UChiKQpzPXRoaXMuYgppZihiPj1zLmxlbmd0aCly
+ZXR1cm4gSC5PSChzLGIpCnJldHVybiBzW2JdfSwKJGlPZDoxLAokaWliOjF9CkguS1cucHJvdG90eXBl
+PXsKZ206ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILlBiKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX19Ckgu
+UGIucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKRjpmdW5jdGlvbigpe3Zh
+ciBzLHIscSxwLG8sbixtPXRoaXMsbD1tLmIKaWYobD09bnVsbClyZXR1cm4hMQpzPW0uYwpyPWwubGVu
+Z3RoCmlmKHM8PXIpe3E9bS5hCnA9cS5VWihsLHMpCmlmKHAhPW51bGwpe20uZD1wCnM9cC5iCm89cy5p
+bmRleApuPW8rc1swXS5sZW5ndGgKaWYobz09PW4pe2lmKHEuYi51bmljb2RlKXtzPW0uYwpxPXMrMQpp
+ZihxPHIpe3M9Qy54Qi5PMihsLHMpCmlmKHM+PTU1Mjk2JiZzPD01NjMxOSl7cz1DLnhCLk8yKGwscSkK
+cz1zPj01NjMyMCYmczw9NTczNDN9ZWxzZSBzPSExfWVsc2Ugcz0hMX1lbHNlIHM9ITEKbj0ocz9uKzE6
+bikrMX1tLmM9bgpyZXR1cm4hMH19bS5iPW0uZD1udWxsCnJldHVybiExfSwKJGlBbjoxfQpILnRRLnBy
+b3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILnVQKGIpCmlmKGIhPT0wKUgudihQLk83KGIsbnVsbCkp
+CnJldHVybiB0aGlzLmN9LAokaU9kOjF9CkgudW4ucHJvdG90eXBlPXsKZ206ZnVuY3Rpb24oYSl7cmV0
+dXJuIG5ldyBILlNkKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX19CkguU2QucHJvdG90eXBlPXsKRjpmdW5j
+dGlvbigpe3ZhciBzLHIscT10aGlzLHA9cS5jLG89cS5iLG49by5sZW5ndGgsbT1xLmEsbD1tLmxlbmd0
+aAppZihwK24+bCl7cS5kPW51bGwKcmV0dXJuITF9cz1tLmluZGV4T2YobyxwKQppZihzPDApe3EuYz1s
+KzEKcS5kPW51bGwKcmV0dXJuITF9cj1zK24KcS5kPW5ldyBILnRRKHMsbykKcS5jPXI9PT1xLmM/cisx
+OnIKcmV0dXJuITB9LApnbDpmdW5jdGlvbigpe3ZhciBzPXRoaXMuZApzLnRvU3RyaW5nCnJldHVybiBz
+fSwKJGlBbjoxfQpILkVULnByb3RvdHlwZT17JGlFVDoxLCRpQVM6MX0KSC5MWi5wcm90b3R5cGU9ewpn
+QTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LAokaVhqOjF9CkguRGcucHJvdG90eXBlPXsKcTpm
+dW5jdGlvbihhLGIpe0gudVAoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfSwKWTU6ZnVu
+Y3Rpb24oYSxiLGMpe0guR0goYykKSC5vZChiLGEsYS5sZW5ndGgpCmFbYl09Y30sCiRpYlE6MSwKJGlj
+WDoxLAokaXpNOjF9CkguUGcucHJvdG90eXBlPXsKWTU6ZnVuY3Rpb24oYSxiLGMpe0gudVAoYykKSC5v
+ZChiLGEsYS5sZW5ndGgpCmFbYl09Y30sCiRpYlE6MSwKJGljWDoxLAokaXpNOjF9CkgueGoucHJvdG90
+eXBlPXsKcTpmdW5jdGlvbihhLGIpe0gudVAoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2Jd
+fX0KSC5kRS5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7SC51UChiKQpILm9kKGIsYSxhLmxlbmd0
+aCkKcmV0dXJuIGFbYl19fQpILlpBLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILnVQKGIpCkgu
+b2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguZFQucHJvdG90eXBlPXsKcTpmdW5jdGlvbihh
+LGIpe0gudVAoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfX0KSC5QcS5wcm90b3R5cGU9
+ewpxOmZ1bmN0aW9uKGEsYil7SC51UChiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpI
+LmVFLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24o
+YSxiKXtILnVQKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguVjYucHJvdG90eXBl
+PXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0gudVAoYikK
+SC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfSwKJGlWNjoxLAokaW42OjF9CkguUkcucHJvdG90
+eXBlPXt9CkguVlAucHJvdG90eXBlPXt9CkguV0IucHJvdG90eXBlPXt9CkguWkcucHJvdG90eXBlPXt9
+CkguSmMucHJvdG90eXBlPXsKQzpmdW5jdGlvbihhKXtyZXR1cm4gSC5jRSh2LnR5cGVVbml2ZXJzZSx0
+aGlzLGEpfSwKS3E6ZnVuY3Rpb24oYSl7cmV0dXJuIEgudjUodi50eXBlVW5pdmVyc2UsdGhpcyxhKX19
+CkguRy5wcm90b3R5cGU9e30KSC5sWS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiBILmRt
+KHRoaXMuYSxudWxsKX19Ckgua1MucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5h
+fX0KSC5pTS5wcm90b3R5cGU9e30KUC50aC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgcz10
+aGlzLmEscj1zLmEKcy5hPW51bGwKci4kMCgpfSwKJFM6OX0KUC5oYS5wcm90b3R5cGU9ewokMTpmdW5j
+dGlvbihhKXt2YXIgcyxyCnRoaXMuYS5hPXQuTS5hKGEpCnM9dGhpcy5iCnI9dGhpcy5jCnMuZmlyc3RD
+aGlsZD9zLnJlbW92ZUNoaWxkKHIpOnMuYXBwZW5kQ2hpbGQocil9LAokUzozNH0KUC5Wcy5wcm90b3R5
+cGU9ewokMDpmdW5jdGlvbigpe3RoaXMuYS4kMCgpfSwKJEM6IiQwIiwKJFI6MCwKJFM6Mn0KUC5GdC5w
+cm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3RoaXMuYS4kMCgpfSwKJEM6IiQwIiwKJFI6MCwKJFM6Mn0K
+UC5XMy5wcm90b3R5cGU9ewpDWTpmdW5jdGlvbihhLGIpe2lmKHNlbGYuc2V0VGltZW91dCE9bnVsbClz
+ZWxmLnNldFRpbWVvdXQoSC50UihuZXcgUC55SCh0aGlzLGIpLDApLGEpCmVsc2UgdGhyb3cgSC5iKFAu
+TDQoImBzZXRUaW1lb3V0KClgIG5vdCBmb3VuZC4iKSl9fQpQLnlILnByb3RvdHlwZT17CiQwOmZ1bmN0
+aW9uKCl7dGhpcy5iLiQwKCl9LAokQzoiJDAiLAokUjowLAokUzowfQpQLmloLnByb3RvdHlwZT17CmFN
+OmZ1bmN0aW9uKGEsYil7dmFyIHMscj10aGlzLHE9ci4kdGkKcS5DKCIxLz8iKS5hKGIpCmlmKCFyLmIp
+ci5hLlhmKGIpCmVsc2V7cz1yLmEKaWYocS5DKCJiODwxPiIpLmIoYikpcy5jVShiKQplbHNlIHMuWDIo
+cS5jLmEoYikpfX0sCncwOmZ1bmN0aW9uKGEsYil7dmFyIHMKaWYoYj09bnVsbCliPVAudjAoYSkKcz10
+aGlzLmEKaWYodGhpcy5iKXMuWkwoYSxiKQplbHNlIHMuTmsoYSxiKX19ClAuV00ucHJvdG90eXBlPXsK
+JDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS4kMigwLGEpfSwKJFM6NTJ9ClAuU1gucHJvdG90eXBl
+PXsKJDI6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuJDIoMSxuZXcgSC5icShhLHQubC5hKGIpKSl9LAokQzoi
+JDIiLAokUjoyLAokUzoyNH0KUC5Hcy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3RoaXMuYShI
+LnVQKGEpLGIpfSwKJFM6MjZ9ClAuRnkucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iSXRl
+cmF0aW9uTWFya2VyKCIrdGhpcy5iKyIsICIrSC5Faih0aGlzLmEpKyIpIn19ClAuR1YucHJvdG90eXBl
+PXsKZ2w6ZnVuY3Rpb24oKXt2YXIgcz10aGlzLmMKaWYocz09bnVsbClyZXR1cm4gdGhpcy4kdGkuYy5h
+KHRoaXMuYikKcmV0dXJuIHMuZ2woKX0sCkY6ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvLG4sbT10aGlz
+CmZvcihzPW0uJHRpLkMoIkFuPDE+Iik7ITA7KXtyPW0uYwppZihyIT1udWxsKWlmKHIuRigpKXJldHVy
+biEwCmVsc2UgbS5zWDkobnVsbCkKcT1mdW5jdGlvbihhLGIsYyl7dmFyIGwsaz1iCndoaWxlKHRydWUp
+dHJ5e3JldHVybiBhKGssbCl9Y2F0Y2goail7bD1qCms9Y319KG0uYSwwLDEpCmlmKHEgaW5zdGFuY2Vv
+ZiBQLkZ5KXtwPXEuYgppZihwPT09Mil7bz1tLmQKaWYobz09bnVsbHx8by5sZW5ndGg9PT0wKXttLnNF
+QyhudWxsKQpyZXR1cm4hMX1pZigwPj1vLmxlbmd0aClyZXR1cm4gSC5PSChvLC0xKQptLmE9by5wb3Ao
+KQpjb250aW51ZX1lbHNle3I9cS5hCmlmKHA9PT0zKXRocm93IHIKZWxzZXtuPXMuYShKLklUKHIpKQpp
+ZihuIGluc3RhbmNlb2YgUC5HVil7cj1tLmQKaWYocj09bnVsbClyPW0uZD1bXQpDLk5tLmkocixtLmEp
+Cm0uYT1uLmEKY29udGludWV9ZWxzZXttLnNYOShuKQpjb250aW51ZX19fX1lbHNle20uc0VDKHEpCnJl
+dHVybiEwfX1yZXR1cm4hMX0sCnNFQzpmdW5jdGlvbihhKXt0aGlzLmI9dGhpcy4kdGkuQygiMT8iKS5h
+KGEpfSwKc1g5OmZ1bmN0aW9uKGEpe3RoaXMuYz10aGlzLiR0aS5DKCJBbjwxPj8iKS5hKGEpfSwKJGlB
+bjoxfQpQLnE0LnByb3RvdHlwZT17CmdtOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5HVih0aGlzLmEo
+KSx0aGlzLiR0aS5DKCJHVjwxPiIpKX19ClAuUGYucHJvdG90eXBlPXsKdzA6ZnVuY3Rpb24oYSxiKXt2
+YXIgcwpILmNiKGEsImVycm9yIix0LkspCnM9dGhpcy5hCmlmKHMuYSE9PTApdGhyb3cgSC5iKFAuUFYo
+IkZ1dHVyZSBhbHJlYWR5IGNvbXBsZXRlZCIpKQppZihiPT1udWxsKWI9UC52MChhKQpzLk5rKGEsYil9
+LApwbTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy53MChhLG51bGwpfX0KUC5aZi5wcm90b3R5cGU9ewph
+TTpmdW5jdGlvbihhLGIpe3ZhciBzLHI9dGhpcy4kdGkKci5DKCIxLz8iKS5hKGIpCnM9dGhpcy5hCmlm
+KHMuYSE9PTApdGhyb3cgSC5iKFAuUFYoIkZ1dHVyZSBhbHJlYWR5IGNvbXBsZXRlZCIpKQpzLlhmKHIu
+QygiMS8iKS5hKGIpKX19ClAuRmUucHJvdG90eXBlPXsKSFI6ZnVuY3Rpb24oYSl7aWYoKHRoaXMuYyYx
+NSkhPT02KXJldHVybiEwCnJldHVybiB0aGlzLmIuYi5idih0LmFsLmEodGhpcy5kKSxhLmEsdC55LHQu
+Syl9LApLdzpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmUscj10LnoscT10LksscD10aGlzLiR0aS5DKCIy
+LyIpLG89dGhpcy5iLmIKaWYodC5hZy5iKHMpKXJldHVybiBwLmEoby5ycChzLGEuYSxhLmIscixxLHQu
+bCkpCmVsc2UgcmV0dXJuIHAuYShvLmJ2KHQuYkkuYShzKSxhLmEscixxKSl9fQpQLnZzLnByb3RvdHlw
+ZT17ClNxOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEscD10aGlzLiR0aQpwLktxKGMpLkMoIjEvKDIp
+IikuYShhKQpzPSQuWDMKaWYocyE9PUMuTlUpe2MuQygiQDwwLz4iKS5LcShwLmMpLkMoIjEoMikiKS5h
+KGEpCmlmKGIhPW51bGwpYj1QLlZIKGIscyl9cj1uZXcgUC52cyhzLGMuQygidnM8MD4iKSkKcT1iPT1u
+dWxsPzE6Mwp0aGlzLnhmKG5ldyBQLkZlKHIscSxhLGIscC5DKCJAPDE+IikuS3EoYykuQygiRmU8MSwy
+PiIpKSkKcmV0dXJuIHJ9LApXNzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlNxKGEsbnVsbCxiKX0s
+ClFkOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyPXRoaXMuJHRpCnIuS3EoYykuQygiMS8oMikiKS5hKGEp
+CnM9bmV3IFAudnMoJC5YMyxjLkMoInZzPDA+IikpCnRoaXMueGYobmV3IFAuRmUocywxOSxhLGIsci5D
+KCJAPDE+IikuS3EoYykuQygiRmU8MSwyPiIpKSkKcmV0dXJuIHN9LAp4ZjpmdW5jdGlvbihhKXt2YXIg
+cyxyPXRoaXMscT1yLmEKaWYocTw9MSl7YS5hPXQuRi5hKHIuYykKci5jPWF9ZWxzZXtpZihxPT09Mil7
+cz10LmMuYShyLmMpCnE9cy5hCmlmKHE8NCl7cy54ZihhKQpyZXR1cm59ci5hPXEKci5jPXMuY31QLlRr
+KG51bGwsbnVsbCxyLmIsdC5NLmEobmV3IFAuZGEocixhKSkpfX0sCmpROmZ1bmN0aW9uKGEpe3ZhciBz
+LHIscSxwLG8sbixtPXRoaXMsbD17fQpsLmE9YQppZihhPT1udWxsKXJldHVybgpzPW0uYQppZihzPD0x
+KXtyPXQuRi5hKG0uYykKbS5jPWEKaWYociE9bnVsbCl7cT1hLmEKZm9yKHA9YTtxIT1udWxsO3A9cSxx
+PW8pbz1xLmEKcC5hPXJ9fWVsc2V7aWYocz09PTIpe249dC5jLmEobS5jKQpzPW4uYQppZihzPDQpe24u
+alEoYSkKcmV0dXJufW0uYT1zCm0uYz1uLmN9bC5hPW0uTjgoYSkKUC5UayhudWxsLG51bGwsbS5iLHQu
+TS5hKG5ldyBQLm9RKGwsbSkpKX19LAphaDpmdW5jdGlvbigpe3ZhciBzPXQuRi5hKHRoaXMuYykKdGhp
+cy5jPW51bGwKcmV0dXJuIHRoaXMuTjgocyl9LApOODpmdW5jdGlvbihhKXt2YXIgcyxyLHEKZm9yKHM9
+YSxyPW51bGw7cyE9bnVsbDtyPXMscz1xKXtxPXMuYQpzLmE9cn1yZXR1cm4gcn0sCkhIOmZ1bmN0aW9u
+KGEpe3ZhciBzLHI9dGhpcyxxPXIuJHRpCnEuQygiMS8iKS5hKGEpCmlmKHEuQygiYjg8MT4iKS5iKGEp
+KWlmKHEuYihhKSlQLkE5KGEscikKZWxzZSBQLmszKGEscikKZWxzZXtzPXIuYWgoKQpxLmMuYShhKQpy
+LmE9NApyLmM9YQpQLkhaKHIscyl9fSwKWDI6ZnVuY3Rpb24oYSl7dmFyIHMscj10aGlzCnIuJHRpLmMu
+YShhKQpzPXIuYWgoKQpyLmE9NApyLmM9YQpQLkhaKHIscyl9LApaTDpmdW5jdGlvbihhLGIpe3ZhciBz
+LHIscT10aGlzCnQubC5hKGIpCnM9cS5haCgpCnI9UC5UbChhLGIpCnEuYT04CnEuYz1yClAuSFoocSxz
+KX0sClhmOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuJHRpCnMuQygiMS8iKS5hKGEpCmlmKHMuQygiYjg8
+MT4iKS5iKGEpKXt0aGlzLmNVKGEpCnJldHVybn10aGlzLndVKHMuYy5hKGEpKX0sCndVOmZ1bmN0aW9u
+KGEpe3ZhciBzPXRoaXMKcy4kdGkuYy5hKGEpCnMuYT0xClAuVGsobnVsbCxudWxsLHMuYix0Lk0uYShu
+ZXcgUC5ydChzLGEpKSl9LApjVTpmdW5jdGlvbihhKXt2YXIgcz10aGlzLHI9cy4kdGkKci5DKCJiODwx
+PiIpLmEoYSkKaWYoci5iKGEpKXtpZihhLmE9PT04KXtzLmE9MQpQLlRrKG51bGwsbnVsbCxzLmIsdC5N
+LmEobmV3IFAuS0YocyxhKSkpfWVsc2UgUC5BOShhLHMpCnJldHVybn1QLmszKGEscyl9LApOazpmdW5j
+dGlvbihhLGIpe3RoaXMuYT0xClAuVGsobnVsbCxudWxsLHRoaXMuYix0Lk0uYShuZXcgUC5aTCh0aGlz
+LGEsYikpKX0sCiRpYjg6MX0KUC5kYS5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe1AuSFoodGhpcy5h
+LHRoaXMuYil9LAokUzowfQpQLm9RLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7UC5IWih0aGlzLmIs
+dGhpcy5hLmEpfSwKJFM6MH0KUC5wVi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgcz10aGlz
+LmEKcy5hPTAKcy5ISChhKX0sCiRTOjl9ClAuVTcucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0
+aGlzLmEuWkwoYSx0LmwuYShiKSl9LAokQzoiJDIiLAokUjoyLAokUzoyOX0KUC52ci5wcm90b3R5cGU9
+ewokMDpmdW5jdGlvbigpe3RoaXMuYS5aTCh0aGlzLmIsdGhpcy5jKX0sCiRTOjB9ClAucnQucHJvdG90
+eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuWDIodGhpcy5iKX0sCiRTOjB9ClAuS0YucHJvdG90eXBl
+PXsKJDA6ZnVuY3Rpb24oKXtQLkE5KHRoaXMuYix0aGlzLmEpfSwKJFM6MH0KUC5aTC5wcm90b3R5cGU9
+ewokMDpmdW5jdGlvbigpe3RoaXMuYS5aTCh0aGlzLmIsdGhpcy5jKX0sCiRTOjB9ClAuUlQucHJvdG90
+eXBlPXsKJDA6ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvLG4sbT10aGlzLGw9bnVsbAp0cnl7cT1tLmEu
+YQpsPXEuYi5iLnp6KHQuZk8uYShxLmQpLHQueil9Y2F0Y2gocCl7cz1ILlJ1KHApCnI9SC50cyhwKQpp
+ZihtLmMpe3E9dC5uLmEobS5iLmEuYykuYQpvPXMKbz1xPT1udWxsP289PW51bGw6cT09PW8KcT1vfWVs
+c2UgcT0hMQpvPW0uYQppZihxKW8uYz10Lm4uYShtLmIuYS5jKQplbHNlIG8uYz1QLlRsKHMscikKby5i
+PSEwCnJldHVybn1pZihsIGluc3RhbmNlb2YgUC52cyYmbC5hPj00KXtpZihsLmE9PT04KXtxPW0uYQpx
+LmM9dC5uLmEobC5jKQpxLmI9ITB9cmV0dXJufWlmKHQuZC5iKGwpKXtuPW0uYi5hCnE9bS5hCnEuYz1s
+Llc3KG5ldyBQLmpaKG4pLHQueikKcS5iPSExfX0sCiRTOjB9ClAualoucHJvdG90eXBlPXsKJDE6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIHRoaXMuYX0sCiRTOjMyfQpQLnJxLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9u
+KCl7dmFyIHMscixxLHAsbyxuLG0sbAp0cnl7cT10aGlzLmEKcD1xLmEKbz1wLiR0aQpuPW8uYwptPW4u
+YSh0aGlzLmIpCnEuYz1wLmIuYi5idihvLkMoIjIvKDEpIikuYShwLmQpLG0sby5DKCIyLyIpLG4pfWNh
+dGNoKGwpe3M9SC5SdShsKQpyPUgudHMobCkKcT10aGlzLmEKcS5jPVAuVGwocyxyKQpxLmI9ITB9fSwK
+JFM6MH0KUC5SVy5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3ZhciBzLHIscSxwLG8sbixtLGwsaz10
+aGlzCnRyeXtzPXQubi5hKGsuYS5hLmMpCnA9ay5iCmlmKEgub1QocC5hLkhSKHMpKSYmcC5hLmUhPW51
+bGwpe3AuYz1wLmEuS3cocykKcC5iPSExfX1jYXRjaChvKXtyPUguUnUobykKcT1ILnRzKG8pCnA9dC5u
+LmEoay5hLmEuYykKbj1wLmEKbT1yCmw9ay5iCmlmKG49PW51bGw/bT09bnVsbDpuPT09bSlsLmM9cApl
+bHNlIGwuYz1QLlRsKHIscSkKbC5iPSEwfX0sCiRTOjB9ClAuT00ucHJvdG90eXBlPXt9ClAucWgucHJv
+dG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7dmFyIHMscixxPXRoaXMscD17fSxvPW5ldyBQLnZzKCQuWDMs
+dC5mSikKcC5hPTAKcz1ILkxoKHEpCnI9cy5DKCJ+KDEpPyIpLmEobmV3IFAuQjUocCxxKSkKdC5aLmEo
+bmV3IFAudU8ocCxvKSkKVy5KRShxLmEscS5iLHIsITEscy5jKQpyZXR1cm4gb319ClAuQjUucHJvdG90
+eXBlPXsKJDE6ZnVuY3Rpb24oYSl7SC5MaCh0aGlzLmIpLmMuYShhKTsrK3RoaXMuYS5hfSwKJFM6ZnVu
+Y3Rpb24oKXtyZXR1cm4gSC5MaCh0aGlzLmIpLkMoIn4oMSkiKX19ClAudU8ucHJvdG90eXBlPXsKJDA6
+ZnVuY3Rpb24oKXt0aGlzLmIuSEgodGhpcy5hLmEpfSwKJFM6MH0KUC5NTy5wcm90b3R5cGU9e30KUC5r
+VC5wcm90b3R5cGU9e30KUC54SS5wcm90b3R5cGU9e30KUC5Ddy5wcm90b3R5cGU9ewp3OmZ1bmN0aW9u
+KGEpe3JldHVybiBILkVqKHRoaXMuYSl9LAokaVhTOjEsCmdJSTpmdW5jdGlvbigpe3JldHVybiB0aGlz
+LmJ9fQpQLm0wLnByb3RvdHlwZT17JGlRbToxfQpQLnBLLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7
+dmFyIHM9SC5iKHRoaXMuYSkKcy5zdGFjaz1KLmoodGhpcy5iKQp0aHJvdyBzfSwKJFM6MH0KUC5KaS5w
+cm90b3R5cGU9ewpiSDpmdW5jdGlvbihhKXt2YXIgcyxyLHEscD1udWxsCnQuTS5hKGEpCnRyeXtpZihD
+Lk5VPT09JC5YMyl7YS4kMCgpCnJldHVybn1QLlQ4KHAscCx0aGlzLGEsdC5IKX1jYXRjaChxKXtzPUgu
+UnUocSkKcj1ILnRzKHEpClAuTDIocCxwLHRoaXMscyx0LmwuYShyKSl9fSwKRGw6ZnVuY3Rpb24oYSxi
+LGMpe3ZhciBzLHIscSxwPW51bGwKYy5DKCJ+KDApIikuYShhKQpjLmEoYikKdHJ5e2lmKEMuTlU9PT0k
+LlgzKXthLiQxKGIpCnJldHVybn1QLnl2KHAscCx0aGlzLGEsYix0LkgsYyl9Y2F0Y2gocSl7cz1ILlJ1
+KHEpCnI9SC50cyhxKQpQLkwyKHAscCx0aGlzLHMsdC5sLmEocikpfX0sClJUOmZ1bmN0aW9uKGEsYil7
+cmV0dXJuIG5ldyBQLmhqKHRoaXMsYi5DKCIwKCkiKS5hKGEpLGIpfSwKdDg6ZnVuY3Rpb24oYSl7cmV0
+dXJuIG5ldyBQLlZwKHRoaXMsdC5NLmEoYSkpfSwKUHk6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IFAu
+T1IodGhpcyxiLkMoIn4oMCkiKS5hKGEpLGIpfSwKcTpmdW5jdGlvbihhLGIpe3JldHVybiBudWxsfSwK
+eno6ZnVuY3Rpb24oYSxiKXtiLkMoIjAoKSIpLmEoYSkKaWYoJC5YMz09PUMuTlUpcmV0dXJuIGEuJDAo
+KQpyZXR1cm4gUC5UOChudWxsLG51bGwsdGhpcyxhLGIpfSwKYnY6ZnVuY3Rpb24oYSxiLGMsZCl7Yy5D
+KCJAPDA+IikuS3EoZCkuQygiMSgyKSIpLmEoYSkKZC5hKGIpCmlmKCQuWDM9PT1DLk5VKXJldHVybiBh
+LiQxKGIpCnJldHVybiBQLnl2KG51bGwsbnVsbCx0aGlzLGEsYixjLGQpfSwKcnA6ZnVuY3Rpb24oYSxi
+LGMsZCxlLGYpe2QuQygiQDwwPiIpLktxKGUpLktxKGYpLkMoIjEoMiwzKSIpLmEoYSkKZS5hKGIpCmYu
+YShjKQppZigkLlgzPT09Qy5OVSlyZXR1cm4gYS4kMihiLGMpCnJldHVybiBQLlF4KG51bGwsbnVsbCx0
+aGlzLGEsYixjLGQsZSxmKX0sCkxqOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBiLkMoIkA8MD4iKS5L
+cShjKS5LcShkKS5DKCIxKDIsMykiKS5hKGEpfX0KUC5oai5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigp
+e3JldHVybiB0aGlzLmEuenoodGhpcy5iLHRoaXMuYyl9LAokUzpmdW5jdGlvbigpe3JldHVybiB0aGlz
+LmMuQygiMCgpIil9fQpQLlZwLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYS5i
+SCh0aGlzLmIpfSwKJFM6MH0KUC5PUi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgcz10aGlz
+LmMKcmV0dXJuIHRoaXMuYS5EbCh0aGlzLmIscy5hKGEpLHMpfSwKJFM6ZnVuY3Rpb24oKXtyZXR1cm4g
+dGhpcy5jLkMoIn4oMCkiKX19ClAuYjYucHJvdG90eXBlPXsKZ206ZnVuY3Rpb24oYSl7dmFyIHM9dGhp
+cyxyPW5ldyBQLmxtKHMscy5yLEguTGgocykuQygibG08MT4iKSkKci5jPXMuZQpyZXR1cm4gcn0sCmdB
+OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYT09
+PTB9LApnb3I6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYSE9PTB9LAp0ZzpmdW5jdGlvbihhLGIpe3Zh
+ciBzLHIKaWYodHlwZW9mIGI9PSJzdHJpbmciJiZiIT09Il9fcHJvdG9fXyIpe3M9dGhpcy5iCmlmKHM9
+PW51bGwpcmV0dXJuITEKcmV0dXJuIHQuZS5hKHNbYl0pIT1udWxsfWVsc2V7cj10aGlzLlBSKGIpCnJl
+dHVybiByfX0sClBSOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuZAppZihzPT1udWxsKXJldHVybiExCnJl
+dHVybiB0aGlzLlIoc1t0aGlzLk4oYSldLGEpPj0wfSwKaTpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT10
+aGlzCkguTGgocSkuYy5hKGIpCmlmKHR5cGVvZiBiPT0ic3RyaW5nIiYmYiE9PSJfX3Byb3RvX18iKXtz
+PXEuYgpyZXR1cm4gcS5TKHM9PW51bGw/cS5iPVAuVDIoKTpzLGIpfWVsc2UgaWYodHlwZW9mIGI9PSJu
+dW1iZXIiJiYoYiYxMDczNzQxODIzKT09PWIpe3I9cS5jCnJldHVybiBxLlMocj09bnVsbD9xLmM9UC5U
+MigpOnIsYil9ZWxzZSByZXR1cm4gcS5HKGIpfSwKRzpmdW5jdGlvbihhKXt2YXIgcyxyLHEscD10aGlz
+CkguTGgocCkuYy5hKGEpCnM9cC5kCmlmKHM9PW51bGwpcz1wLmQ9UC5UMigpCnI9cC5OKGEpCnE9c1ty
+XQppZihxPT1udWxsKXNbcl09W3AuSChhKV0KZWxzZXtpZihwLlIocSxhKT49MClyZXR1cm4hMQpxLnB1
+c2gocC5IKGEpKX1yZXR1cm4hMH0sCkw6ZnVuY3Rpb24oYSxiKXt2YXIgcz10aGlzCmlmKHR5cGVvZiBi
+PT0ic3RyaW5nIiYmYiE9PSJfX3Byb3RvX18iKXJldHVybiBzLkg0KHMuYixiKQplbHNlIGlmKHR5cGVv
+ZiBiPT0ibnVtYmVyIiYmKGImMTA3Mzc0MTgyMyk9PT1iKXJldHVybiBzLkg0KHMuYyxiKQplbHNlIHJl
+dHVybiBzLnFnKGIpfSwKcWc6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbz10aGlzLG49by5kCmlmKG49
+PW51bGwpcmV0dXJuITEKcz1vLk4oYSkKcj1uW3NdCnE9by5SKHIsYSkKaWYocTwwKXJldHVybiExCnA9
+ci5zcGxpY2UocSwxKVswXQppZigwPT09ci5sZW5ndGgpZGVsZXRlIG5bc10Kby5HUyhwKQpyZXR1cm4h
+MH0sClM6ZnVuY3Rpb24oYSxiKXtILkxoKHRoaXMpLmMuYShiKQppZih0LmUuYShhW2JdKSE9bnVsbCly
+ZXR1cm4hMQphW2JdPXRoaXMuSChiKQpyZXR1cm4hMH0sCkg0OmZ1bmN0aW9uKGEsYil7dmFyIHMKaWYo
+YT09bnVsbClyZXR1cm4hMQpzPXQuZS5hKGFbYl0pCmlmKHM9PW51bGwpcmV0dXJuITEKdGhpcy5HUyhz
+KQpkZWxldGUgYVtiXQpyZXR1cm4hMH0sCkdZOmZ1bmN0aW9uKCl7dGhpcy5yPXRoaXMucisxJjEwNzM3
+NDE4MjN9LApIOmZ1bmN0aW9uKGEpe3ZhciBzLHI9dGhpcyxxPW5ldyBQLmJuKEguTGgocikuYy5hKGEp
+KQppZihyLmU9PW51bGwpci5lPXIuZj1xCmVsc2V7cz1yLmYKcy50b1N0cmluZwpxLmM9cwpyLmY9cy5i
+PXF9KytyLmEKci5HWSgpCnJldHVybiBxfSwKR1M6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcyxyPWEuYyxx
+PWEuYgppZihyPT1udWxsKXMuZT1xCmVsc2Ugci5iPXEKaWYocT09bnVsbClzLmY9cgplbHNlIHEuYz1y
+Oy0tcy5hCnMuR1koKX0sCk46ZnVuY3Rpb24oYSl7cmV0dXJuIEouaGYoYSkmMTA3Mzc0MTgyM30sClI6
+ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCmlmKGE9PW51bGwpcmV0dXJuLTEKcz1hLmxlbmd0aApmb3Iocj0w
+O3I8czsrK3IpaWYoSi5STShhW3JdLmEsYikpcmV0dXJuIHIKcmV0dXJuLTF9fQpQLmJuLnByb3RvdHlw
+ZT17fQpQLmxtLnByb3RvdHlwZT17CmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCkY6ZnVuY3Rp
+b24oKXt2YXIgcz10aGlzLHI9cy5jLHE9cy5hCmlmKHMuYiE9PXEucil0aHJvdyBILmIoUC5hNChxKSkK
+ZWxzZSBpZihyPT1udWxsKXtzLnNqKG51bGwpCnJldHVybiExfWVsc2V7cy5zaihzLiR0aS5DKCIxPyIp
+LmEoci5hKSkKcy5jPXIuYgpyZXR1cm4hMH19LApzajpmdW5jdGlvbihhKXt0aGlzLmQ9dGhpcy4kdGku
+QygiMT8iKS5hKGEpfSwKJGlBbjoxfQpQLm1XLnByb3RvdHlwZT17fQpQLnV5LnByb3RvdHlwZT17JGli
+UToxLCRpY1g6MSwkaXpNOjF9ClAubEQucHJvdG90eXBlPXsKZ206ZnVuY3Rpb24oYSl7cmV0dXJuIG5l
+dyBILmE3KGEsdGhpcy5nQShhKSxILnooYSkuQygiYTc8bEQuRT4iKSl9LApFOmZ1bmN0aW9uKGEsYil7
+cmV0dXJuIHRoaXMucShhLGIpfSwKSzpmdW5jdGlvbihhLGIpe3ZhciBzLHIKSC56KGEpLkMoIn4obEQu
+RSkiKS5hKGIpCnM9dGhpcy5nQShhKQpmb3Iocj0wO3I8czsrK3Ipe2IuJDEodGhpcy5xKGEscikpCmlm
+KHMhPT10aGlzLmdBKGEpKXRocm93IEguYihQLmE0KGEpKX19LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJu
+IHRoaXMuZ0EoYSk9PT0wfSwKZ29yOmZ1bmN0aW9uKGEpe3JldHVybiF0aGlzLmdsMChhKX0sCkUyOmZ1
+bmN0aW9uKGEsYixjKXt2YXIgcz1ILnooYSkKcmV0dXJuIG5ldyBILmxKKGEscy5LcShjKS5DKCIxKGxE
+LkUpIikuYShiKSxzLkMoIkA8bEQuRT4iKS5LcShjKS5DKCJsSjwxLDI+IikpfSwKZVI6ZnVuY3Rpb24o
+YSxiKXtyZXR1cm4gSC5xQyhhLGIsbnVsbCxILnooYSkuQygibEQuRSIpKX0sCmRyOmZ1bmN0aW9uKGEs
+Yil7cmV0dXJuIG5ldyBILmpWKGEsSC56KGEpLkMoIkA8bEQuRT4iKS5LcShiKS5DKCJqVjwxLDI+Iikp
+fSwKZHU6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMKSC56KGEpLkMoImxELkU/IikuYShkKQpQLmpCKGIs
+Yyx0aGlzLmdBKGEpKQpmb3Iocz1iO3M8YzsrK3MpdGhpcy5ZNShhLHMsZCl9LAp3OmZ1bmN0aW9uKGEp
+e3JldHVybiBQLldFKGEsIlsiLCJdIil9fQpQLmlsLnByb3RvdHlwZT17fQpQLnJhLnByb3RvdHlwZT17
+CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHMscj10aGlzLmEKaWYoIXIuYSl0aGlzLmIuYSs9IiwgIgpyLmE9
+ITEKcj10aGlzLmIKcz1yLmErPUguRWooYSkKci5hPXMrIjogIgpyLmErPUguRWooYil9LAokUzoxMH0K
+UC5Zay5wcm90b3R5cGU9ewpLOmZ1bmN0aW9uKGEsYil7dmFyIHMscgpILkxoKHRoaXMpLkMoIn4oWWsu
+SyxZay5WKSIpLmEoYikKZm9yKHM9Si5JVCh0aGlzLmd2YygpKTtzLkYoKTspe3I9cy5nbCgpCmIuJDIo
+cix0aGlzLnEoMCxyKSl9fSwKZ1B1OmZ1bmN0aW9uKGEpe3JldHVybiBKLk0xKHRoaXMuZ3ZjKCksbmV3
+IFAueVEodGhpcyksSC5MaCh0aGlzKS5DKCJOMzxZay5LLFlrLlY+IikpfSwKeDQ6ZnVuY3Rpb24oYSl7
+cmV0dXJuIEouemwodGhpcy5ndmMoKSxhKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiBKLkhtKHRoaXMu
+Z3ZjKCkpfSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiBKLnVVKHRoaXMuZ3ZjKCkpfSwKdzpmdW5jdGlv
+bihhKXtyZXR1cm4gUC5uTyh0aGlzKX0sCiRpWjA6MX0KUC55US5wcm90b3R5cGU9ewokMTpmdW5jdGlv
+bihhKXt2YXIgcz10aGlzLmEscj1ILkxoKHMpCnIuQygiWWsuSyIpLmEoYSkKcmV0dXJuIG5ldyBQLk4z
+KGEscy5xKDAsYSksci5DKCJAPFlrLks+IikuS3Eoci5DKCJZay5WIikpLkMoIk4zPDEsMj4iKSl9LAok
+UzpmdW5jdGlvbigpe3JldHVybiBILkxoKHRoaXMuYSkuQygiTjM8WWsuSyxZay5WPihZay5LKSIpfX0K
+UC5LUC5wcm90b3R5cGU9ewpZNTpmdW5jdGlvbihhLGIsYyl7dmFyIHM9SC5MaCh0aGlzKQpzLmMuYShi
+KQpzLlFbMV0uYShjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IG1vZGlmeSB1bm1vZGlmaWFibGUgbWFw
+IikpfX0KUC5Qbi5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYS5xKDAsYil9
+LApZNTpmdW5jdGlvbihhLGIsYyl7dmFyIHM9SC5MaCh0aGlzKQp0aGlzLmEuWTUoMCxzLmMuYShiKSxz
+LlFbMV0uYShjKSl9LAp4NDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLng0KGEpfSwKSzpmdW5jdGlv
+bihhLGIpe3RoaXMuYS5LKDAsSC5MaCh0aGlzKS5DKCJ+KDEsMikiKS5hKGIpKX0sCmdsMDpmdW5jdGlv
+bihhKXt2YXIgcz10aGlzLmEKcmV0dXJuIHMuZ2wwKHMpfSwKZ0E6ZnVuY3Rpb24oYSl7dmFyIHM9dGhp
+cy5hCnJldHVybiBzLmdBKHMpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gSi5qKHRoaXMuYSl9LApnUHU6
+ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5hCnJldHVybiBzLmdQdShzKX0sCiRpWjA6MX0KUC5Hai5wcm90
+b3R5cGU9e30KUC5sZi5wcm90b3R5cGU9ewpnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ0EodGhp
+cyk9PT0wfSwKZ29yOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmdBKHRoaXMpIT09MH0sCkZWOmZ1bmN0
+aW9uKGEsYil7dmFyIHMKZm9yKHM9Si5JVChILkxoKHRoaXMpLkMoImNYPGxmLkU+IikuYShiKSk7cy5G
+KCk7KXRoaXMuaSgwLHMuZ2woKSl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBQLldFKHRoaXMsInsiLCJ9
+Iil9LAprOmZ1bmN0aW9uKGEsYil7dmFyIHMscj10aGlzLmdtKHRoaXMpCmlmKCFyLkYoKSlyZXR1cm4i
+IgppZihiPT09IiIpe3M9IiIKZG8gcys9SC5FaihyLmQpCndoaWxlKHIuRigpKX1lbHNle3M9SC5Faihy
+LmQpCmZvcig7ci5GKCk7KXM9cytiK0guRWooci5kKX1yZXR1cm4gcy5jaGFyQ29kZUF0KDApPT0wP3M6
+c30sCmVSOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEguYksodGhpcyxiLEguTGgodGhpcykuQygibGYuRSIp
+KX0sCkU6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscD0iaW5kZXgiCkguY2IoYixwLHQuUykKUC5rMShi
+LHApCmZvcihzPXRoaXMuZ20odGhpcykscj0wO3MuRigpOyl7cT1zLmQKaWYoYj09PXIpcmV0dXJuIHE7
+KytyfXRocm93IEguYihQLkNmKGIsdGhpcyxwLG51bGwscikpfX0KUC5Wai5wcm90b3R5cGU9eyRpYlE6
+MSwkaWNYOjEsJGl4dToxfQpQLlh2LnByb3RvdHlwZT17JGliUToxLCRpY1g6MSwkaXh1OjF9ClAublku
+cHJvdG90eXBlPXt9ClAuV1kucHJvdG90eXBlPXt9ClAuUlUucHJvdG90eXBlPXt9ClAucFIucHJvdG90
+eXBlPXt9ClAudXcucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe3ZhciBzLHI9dGhpcy5iCmlmKHI9
+PW51bGwpcmV0dXJuIHRoaXMuYy5xKDAsYikKZWxzZSBpZih0eXBlb2YgYiE9InN0cmluZyIpcmV0dXJu
+IG51bGwKZWxzZXtzPXJbYl0KcmV0dXJuIHR5cGVvZiBzPT0idW5kZWZpbmVkIj90aGlzLmZiKGIpOnN9
+fSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYj09bnVsbD90aGlzLmMuYTp0aGlzLkNmKCkubGVu
+Z3RofSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmdBKHRoaXMpPT09MH0sCmd2YzpmdW5jdGlv
+bigpe2lmKHRoaXMuYj09bnVsbCl7dmFyIHM9dGhpcy5jCnJldHVybiBuZXcgSC5pNShzLEguTGgocyku
+QygiaTU8MT4iKSl9cmV0dXJuIG5ldyBQLmk4KHRoaXMpfSwKWTU6ZnVuY3Rpb24oYSxiLGMpe3ZhciBz
+LHIscT10aGlzCmlmKHEuYj09bnVsbClxLmMuWTUoMCxiLGMpCmVsc2UgaWYocS54NChiKSl7cz1xLmIK
+c1tiXT1jCnI9cS5hCmlmKHI9PW51bGw/cyE9bnVsbDpyIT09cylyW2JdPW51bGx9ZWxzZSBxLlhLKCku
+WTUoMCxiLGMpfSwKeDQ6ZnVuY3Rpb24oYSl7aWYodGhpcy5iPT1udWxsKXJldHVybiB0aGlzLmMueDQo
+YSkKcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLmEsYSl9LApL
+OmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbz10aGlzCnQuY0EuYShiKQppZihvLmI9PW51bGwpcmV0
+dXJuIG8uYy5LKDAsYikKcz1vLkNmKCkKZm9yKHI9MDtyPHMubGVuZ3RoOysrcil7cT1zW3JdCnA9by5i
+W3FdCmlmKHR5cGVvZiBwPT0idW5kZWZpbmVkIil7cD1QLlFlKG8uYVtxXSkKby5iW3FdPXB9Yi4kMihx
+LHApCmlmKHMhPT1vLmMpdGhyb3cgSC5iKFAuYTQobykpfX0sCkNmOmZ1bmN0aW9uKCl7dmFyIHM9dC5i
+TS5hKHRoaXMuYykKaWYocz09bnVsbClzPXRoaXMuYz1ILlZNKE9iamVjdC5rZXlzKHRoaXMuYSksdC5z
+KQpyZXR1cm4gc30sClhLOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbyxuPXRoaXMKaWYobi5iPT1udWxs
+KXJldHVybiBuLmMKcz1QLkZsKHQuTix0LnopCnI9bi5DZigpCmZvcihxPTA7cD1yLmxlbmd0aCxxPHA7
+KytxKXtvPXJbcV0Kcy5ZNSgwLG8sbi5xKDAsbykpfWlmKHA9PT0wKUMuTm0uaShyLCIiKQplbHNlIEMu
+Tm0uc0EociwwKQpuLmE9bi5iPW51bGwKcmV0dXJuIG4uYz1zfSwKZmI6ZnVuY3Rpb24oYSl7dmFyIHMK
+aWYoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLmEsYSkpcmV0dXJuIG51
+bGwKcz1QLlFlKHRoaXMuYVthXSkKcmV0dXJuIHRoaXMuYlthXT1zfX0KUC5pOC5wcm90b3R5cGU9ewpn
+QTpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmEKcmV0dXJuIHMuZ0Eocyl9LApFOmZ1bmN0aW9uKGEsYil7
+dmFyIHM9dGhpcy5hCmlmKHMuYj09bnVsbClzPXMuZ3ZjKCkuRSgwLGIpCmVsc2V7cz1zLkNmKCkKaWYo
+YjwwfHxiPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLGIpCnM9c1tiXX1yZXR1cm4gc30sCmdtOmZ1bmN0
+aW9uKGEpe3ZhciBzPXRoaXMuYQppZihzLmI9PW51bGwpe3M9cy5ndmMoKQpzPXMuZ20ocyl9ZWxzZXtz
+PXMuQ2YoKQpzPW5ldyBKLm0xKHMscy5sZW5ndGgsSC50NihzKS5DKCJtMTwxPiIpKX1yZXR1cm4gc30s
+CnRnOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYS54NChiKX19ClAucGcucHJvdG90eXBlPXsKJDA6
+ZnVuY3Rpb24oKXt2YXIgcyxyCnRyeXtzPW5ldyBUZXh0RGVjb2RlcigidXRmLTgiLHtmYXRhbDp0cnVl
+fSkKcmV0dXJuIHN9Y2F0Y2gocil7SC5SdShyKX1yZXR1cm4gbnVsbH0sCiRTOjExfQpQLmMyLnByb3Rv
+dHlwZT17CiQwOmZ1bmN0aW9uKCl7dmFyIHMscgp0cnl7cz1uZXcgVGV4dERlY29kZXIoInV0Zi04Iix7
+ZmF0YWw6ZmFsc2V9KQpyZXR1cm4gc31jYXRjaChyKXtILlJ1KHIpfXJldHVybiBudWxsfSwKJFM6MTF9
+ClAuQ1YucHJvdG90eXBlPXsKeXI6ZnVuY3Rpb24oYTAsYTEsYTIpe3ZhciBzLHIscSxwLG8sbixtLGws
+ayxqLGksaCxnLGYsZSxkLGMsYixhPSJJbnZhbGlkIGJhc2U2NCBlbmNvZGluZyBsZW5ndGggIgphMj1Q
+LmpCKGExLGEyLGEwLmxlbmd0aCkKcz0kLlY3KCkKZm9yKHI9YTEscT1yLHA9bnVsbCxvPS0xLG49LTEs
+bT0wO3I8YTI7cj1sKXtsPXIrMQprPUMueEIuVyhhMCxyKQppZihrPT09Mzcpe2o9bCsyCmlmKGo8PWEy
+KXtpPUgub28oQy54Qi5XKGEwLGwpKQpoPUgub28oQy54Qi5XKGEwLGwrMSkpCmc9aSoxNitoLShoJjI1
+NikKaWYoZz09PTM3KWc9LTEKbD1qfWVsc2UgZz0tMX1lbHNlIGc9awppZigwPD1nJiZnPD0xMjcpe2lm
+KGc8MHx8Zz49cy5sZW5ndGgpcmV0dXJuIEguT0gocyxnKQpmPXNbZ10KaWYoZj49MCl7Zz1DLnhCLk8y
+KCJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1
+Njc4OSsvIixmKQppZihnPT09ayljb250aW51ZQprPWd9ZWxzZXtpZihmPT09LTEpe2lmKG88MCl7ZT1w
+PT1udWxsP251bGw6cC5hLmxlbmd0aAppZihlPT1udWxsKWU9MApvPWUrKHItcSkKbj1yfSsrbQppZihr
+PT09NjEpY29udGludWV9az1nfWlmKGYhPT0tMil7aWYocD09bnVsbCl7cD1uZXcgUC5SbigiIikKZT1w
+fWVsc2UgZT1wCmUuYSs9Qy54Qi5OaihhMCxxLHIpCmUuYSs9SC5MdyhrKQpxPWwKY29udGludWV9fXRo
+cm93IEguYihQLnJyKCJJbnZhbGlkIGJhc2U2NCBkYXRhIixhMCxyKSl9aWYocCE9bnVsbCl7ZT1wLmEr
+PUMueEIuTmooYTAscSxhMikKZD1lLmxlbmd0aAppZihvPj0wKVAueE0oYTAsbixhMixvLG0sZCkKZWxz
+ZXtjPUMuam4uelkoZC0xLDQpKzEKaWYoYz09PTEpdGhyb3cgSC5iKFAucnIoYSxhMCxhMikpCmZvcig7
+Yzw0Oyl7ZSs9Ij0iCnAuYT1lOysrY319ZT1wLmEKcmV0dXJuIEMueEIuaTcoYTAsYTEsYTIsZS5jaGFy
+Q29kZUF0KDApPT0wP2U6ZSl9Yj1hMi1hMQppZihvPj0wKVAueE0oYTAsbixhMixvLG0sYikKZWxzZXtj
+PUMuam4uelkoYiw0KQppZihjPT09MSl0aHJvdyBILmIoUC5ycihhLGEwLGEyKSkKaWYoYz4xKWEwPUMu
+eEIuaTcoYTAsYTIsYTIsYz09PTI/Ij09IjoiPSIpfXJldHVybiBhMH19ClAuVTgucHJvdG90eXBlPXt9
+ClAuVWsucHJvdG90eXBlPXt9ClAud0kucHJvdG90eXBlPXt9ClAuWmkucHJvdG90eXBlPXt9ClAuVWQu
+cHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgcz1QLnAodGhpcy5hKQpyZXR1cm4odGhpcy5iIT1u
+dWxsPyJDb252ZXJ0aW5nIG9iamVjdCB0byBhbiBlbmNvZGFibGUgb2JqZWN0IGZhaWxlZDoiOiJDb252
+ZXJ0aW5nIG9iamVjdCBkaWQgbm90IHJldHVybiBhbiBlbmNvZGFibGUgb2JqZWN0OiIpKyIgIitzfX0K
+UC5LOC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJDeWNsaWMgZXJyb3IgaW4gSlNPTiBz
+dHJpbmdpZnkifX0KUC5ieS5wcm90b3R5cGU9ewpwVzpmdW5jdGlvbihhLGIsYyl7dmFyIHMKdC5mVi5h
+KGMpCnM9UC5CUyhiLHRoaXMuZ0hlKCkuYSkKcmV0dXJuIHN9LApPQjpmdW5jdGlvbihhLGIpe3ZhciBz
+CnQuZEEuYShiKQpzPVAudVgoYSx0aGlzLmdaRSgpLmIsbnVsbCkKcmV0dXJuIHN9LApnWkU6ZnVuY3Rp
+b24oKXtyZXR1cm4gQy5uWH0sCmdIZTpmdW5jdGlvbigpe3JldHVybiBDLkEzfX0KUC5vai5wcm90b3R5
+cGU9e30KUC5NeC5wcm90b3R5cGU9e30KUC5TaC5wcm90b3R5cGU9ewp2cDpmdW5jdGlvbihhKXt2YXIg
+cyxyLHEscCxvLG4sbSxsPWEubGVuZ3RoCmZvcihzPUouclkoYSkscj10aGlzLmMscT0wLHA9MDtwPGw7
+KytwKXtvPXMuVyhhLHApCmlmKG8+OTIpe2lmKG8+PTU1Mjk2KXtuPW8mNjQ1MTIKaWYobj09PTU1Mjk2
+KXttPXArMQptPSEobTxsJiYoQy54Qi5XKGEsbSkmNjQ1MTIpPT09NTYzMjApfWVsc2UgbT0hMQppZigh
+bSlpZihuPT09NTYzMjApe249cC0xCm49IShuPj0wJiYoQy54Qi5PMihhLG4pJjY0NTEyKT09PTU1Mjk2
+KX1lbHNlIG49ITEKZWxzZSBuPSEwCmlmKG4pe2lmKHA+cSlyLmErPUMueEIuTmooYSxxLHApCnE9cCsx
+CnIuYSs9SC5Mdyg5MikKci5hKz1ILkx3KDExNykKci5hKz1ILkx3KDEwMCkKbj1vPj4+OCYxNQpyLmEr
+PUguTHcobjwxMD80OCtuOjg3K24pCm49bz4+PjQmMTUKci5hKz1ILkx3KG48MTA/NDgrbjo4NytuKQpu
+PW8mMTUKci5hKz1ILkx3KG48MTA/NDgrbjo4NytuKX19Y29udGludWV9aWYobzwzMil7aWYocD5xKXIu
+YSs9Qy54Qi5OaihhLHEscCkKcT1wKzEKci5hKz1ILkx3KDkyKQpzd2l0Y2gobyl7Y2FzZSA4OnIuYSs9
+SC5Mdyg5OCkKYnJlYWsKY2FzZSA5OnIuYSs9SC5MdygxMTYpCmJyZWFrCmNhc2UgMTA6ci5hKz1ILkx3
+KDExMCkKYnJlYWsKY2FzZSAxMjpyLmErPUguTHcoMTAyKQpicmVhawpjYXNlIDEzOnIuYSs9SC5Mdygx
+MTQpCmJyZWFrCmRlZmF1bHQ6ci5hKz1ILkx3KDExNykKci5hKz1ILkx3KDQ4KQpyLmErPUguTHcoNDgp
+Cm49bz4+PjQmMTUKci5hKz1ILkx3KG48MTA/NDgrbjo4NytuKQpuPW8mMTUKci5hKz1ILkx3KG48MTA/
+NDgrbjo4NytuKQpicmVha319ZWxzZSBpZihvPT09MzR8fG89PT05Mil7aWYocD5xKXIuYSs9Qy54Qi5O
+aihhLHEscCkKcT1wKzEKci5hKz1ILkx3KDkyKQpyLmErPUguTHcobyl9fWlmKHE9PT0wKXIuYSs9SC5F
+aihhKQplbHNlIGlmKHE8bClyLmErPXMuTmooYSxxLGwpfSwKSm46ZnVuY3Rpb24oYSl7dmFyIHMscixx
+LHAKZm9yKHM9dGhpcy5hLHI9cy5sZW5ndGgscT0wO3E8cjsrK3Epe3A9c1txXQppZihhPT1udWxsP3A9
+PW51bGw6YT09PXApdGhyb3cgSC5iKG5ldyBQLks4KGEsbnVsbCkpfUMuTm0uaShzLGEpfSwKaVU6ZnVu
+Y3Rpb24oYSl7dmFyIHMscixxLHAsbz10aGlzCmlmKG8udE0oYSkpcmV0dXJuCm8uSm4oYSkKdHJ5e3M9
+by5iLiQxKGEpCmlmKCFvLnRNKHMpKXtxPVAuR3koYSxudWxsLG8uZ1ZLKCkpCnRocm93IEguYihxKX1x
+PW8uYQppZigwPj1xLmxlbmd0aClyZXR1cm4gSC5PSChxLC0xKQpxLnBvcCgpfWNhdGNoKHApe3I9SC5S
+dShwKQpxPVAuR3koYSxyLG8uZ1ZLKCkpCnRocm93IEguYihxKX19LAp0TTpmdW5jdGlvbihhKXt2YXIg
+cyxyLHE9dGhpcwppZih0eXBlb2YgYT09Im51bWJlciIpe2lmKCFpc0Zpbml0ZShhKSlyZXR1cm4hMQpx
+LmMuYSs9Qy5DRC53KGEpCnJldHVybiEwfWVsc2UgaWYoYT09PSEwKXtxLmMuYSs9InRydWUiCnJldHVy
+biEwfWVsc2UgaWYoYT09PSExKXtxLmMuYSs9ImZhbHNlIgpyZXR1cm4hMH1lbHNlIGlmKGE9PW51bGwp
+e3EuYy5hKz0ibnVsbCIKcmV0dXJuITB9ZWxzZSBpZih0eXBlb2YgYT09InN0cmluZyIpe3M9cS5jCnMu
+YSs9JyInCnEudnAoYSkKcy5hKz0nIicKcmV0dXJuITB9ZWxzZSBpZih0LmouYihhKSl7cS5KbihhKQpx
+LmxLKGEpCnM9cS5hCmlmKDA+PXMubGVuZ3RoKXJldHVybiBILk9IKHMsLTEpCnMucG9wKCkKcmV0dXJu
+ITB9ZWxzZSBpZih0LmYuYihhKSl7cS5KbihhKQpyPXEuancoYSkKcz1xLmEKaWYoMD49cy5sZW5ndGgp
+cmV0dXJuIEguT0gocywtMSkKcy5wb3AoKQpyZXR1cm4gcn1lbHNlIHJldHVybiExfSwKbEs6ZnVuY3Rp
+b24oYSl7dmFyIHMscixxPXRoaXMuYwpxLmErPSJbIgpzPUouVTYoYSkKaWYocy5nb3IoYSkpe3RoaXMu
+aVUocy5xKGEsMCkpCmZvcihyPTE7cjxzLmdBKGEpOysrcil7cS5hKz0iLCIKdGhpcy5pVShzLnEoYSxy
+KSl9fXEuYSs9Il0ifSwKanc6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG09dGhpcyxsPXt9Cmlm
+KGEuZ2wwKGEpKXttLmMuYSs9Int9IgpyZXR1cm4hMH1zPWEuZ0EoYSkqMgpyPVAuTzgocyxudWxsLCEx
+LHQuVykKcT1sLmE9MApsLmI9ITAKYS5LKDAsbmV3IFAudGkobCxyKSkKaWYoIWwuYilyZXR1cm4hMQpw
+PW0uYwpwLmErPSJ7Igpmb3Iobz0nIic7cTxzO3ErPTIsbz0nLCInKXtwLmErPW8KbS52cChILmgocltx
+XSkpCnAuYSs9JyI6JwpuPXErMQppZihuPj1zKXJldHVybiBILk9IKHIsbikKbS5pVShyW25dKX1wLmEr
+PSJ9IgpyZXR1cm4hMH19ClAudGkucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCmlm
+KHR5cGVvZiBhIT0ic3RyaW5nIil0aGlzLmEuYj0hMQpzPXRoaXMuYgpyPXRoaXMuYQpDLk5tLlk1KHMs
+ci5hKyssYSkKQy5ObS5ZNShzLHIuYSsrLGIpfSwKJFM6MTB9ClAudHUucHJvdG90eXBlPXsKZ1ZLOmZ1
+bmN0aW9uKCl7dmFyIHM9dGhpcy5jLmEKcmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9fQpQLnU1
+LnByb3RvdHlwZT17CmdaRTpmdW5jdGlvbigpe3JldHVybiBDLlFrfX0KUC5FMy5wcm90b3R5cGU9ewpX
+SjpmdW5jdGlvbihhKXt2YXIgcyxyLHEscD1QLmpCKDAsbnVsbCxhLmxlbmd0aCksbz1wLTAKaWYobz09
+PTApcmV0dXJuIG5ldyBVaW50OEFycmF5KDApCnM9byozCnI9bmV3IFVpbnQ4QXJyYXkocykKcT1uZXcg
+UC5SdyhyKQppZihxLkd4KGEsMCxwKSE9PXApe0ouYTYoYSxwLTEpCnEuUk8oKX1yZXR1cm4gbmV3IFVp
+bnQ4QXJyYXkoci5zdWJhcnJheSgwLEguck0oMCxxLmIscykpKX19ClAuUncucHJvdG90eXBlPXsKUk86
+ZnVuY3Rpb24oKXt2YXIgcz10aGlzLHI9cy5jLHE9cy5iLHA9cy5iPXErMSxvPXIubGVuZ3RoCmlmKHE+
+PW8pcmV0dXJuIEguT0gocixxKQpyW3FdPTIzOQpxPXMuYj1wKzEKaWYocD49bylyZXR1cm4gSC5PSChy
+LHApCnJbcF09MTkxCnMuYj1xKzEKaWYocT49bylyZXR1cm4gSC5PSChyLHEpCnJbcV09MTg5fSwKTzY6
+ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG49dGhpcwppZigoYiY2NDUxMik9PT01NjMyMCl7cz02
+NTUzNisoKGEmMTAyMyk8PDEwKXxiJjEwMjMKcj1uLmMKcT1uLmIKcD1uLmI9cSsxCm89ci5sZW5ndGgK
+aWYocT49bylyZXR1cm4gSC5PSChyLHEpCnJbcV09cz4+PjE4fDI0MApxPW4uYj1wKzEKaWYocD49byly
+ZXR1cm4gSC5PSChyLHApCnJbcF09cz4+PjEyJjYzfDEyOApwPW4uYj1xKzEKaWYocT49bylyZXR1cm4g
+SC5PSChyLHEpCnJbcV09cz4+PjYmNjN8MTI4Cm4uYj1wKzEKaWYocD49bylyZXR1cm4gSC5PSChyLHAp
+CnJbcF09cyY2M3wxMjgKcmV0dXJuITB9ZWxzZXtuLlJPKCkKcmV0dXJuITF9fSwKR3g6ZnVuY3Rpb24o
+YSxiLGMpe3ZhciBzLHIscSxwLG8sbixtLGw9dGhpcwppZihiIT09YyYmKEMueEIuTzIoYSxjLTEpJjY0
+NTEyKT09PTU1Mjk2KS0tYwpmb3Iocz1sLmMscj1zLmxlbmd0aCxxPWI7cTxjOysrcSl7cD1DLnhCLlco
+YSxxKQppZihwPD0xMjcpe289bC5iCmlmKG8+PXIpYnJlYWsKbC5iPW8rMQpzW29dPXB9ZWxzZXtvPXAm
+NjQ1MTIKaWYobz09PTU1Mjk2KXtpZihsLmIrND5yKWJyZWFrCm49cSsxCmlmKGwuTzYocCxDLnhCLlco
+YSxuKSkpcT1ufWVsc2UgaWYobz09PTU2MzIwKXtpZihsLmIrMz5yKWJyZWFrCmwuUk8oKX1lbHNlIGlm
+KHA8PTIwNDcpe289bC5iCm09bysxCmlmKG0+PXIpYnJlYWsKbC5iPW0KaWYobz49cilyZXR1cm4gSC5P
+SChzLG8pCnNbb109cD4+PjZ8MTkyCmwuYj1tKzEKc1ttXT1wJjYzfDEyOH1lbHNle289bC5iCmlmKG8r
+Mj49cilicmVhawptPWwuYj1vKzEKaWYobz49cilyZXR1cm4gSC5PSChzLG8pCnNbb109cD4+PjEyfDIy
+NApvPWwuYj1tKzEKaWYobT49cilyZXR1cm4gSC5PSChzLG0pCnNbbV09cD4+PjYmNjN8MTI4CmwuYj1v
+KzEKaWYobz49cilyZXR1cm4gSC5PSChzLG8pCnNbb109cCY2M3wxMjh9fX1yZXR1cm4gcX19ClAuR1ku
+cHJvdG90eXBlPXsKV0o6ZnVuY3Rpb24oYSl7dmFyIHMscgp0LkwuYShhKQpzPXRoaXMuYQpyPVAua3ko
+cyxhLDAsbnVsbCkKaWYociE9bnVsbClyZXR1cm4gcgpyZXR1cm4gbmV3IFAuYnoocykuTmUoYSwwLG51
+bGwsITApfX0KUC5iei5wcm90b3R5cGU9ewpOZTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyLHEscCxv
+LG49dGhpcwp0LkwuYShhKQpzPVAuakIoYixjLEouSG0oYSkpCmlmKGI9PT1zKXJldHVybiIiCnI9UC5q
+eShhLGIscykKcT1uLmhPKHIsMCxzLWIsITApCnA9bi5iCmlmKChwJjEpIT09MCl7bz1QLmo0KHApCm4u
+Yj0wCnRocm93IEguYihQLnJyKG8sYSxiK24uYykpfXJldHVybiBxfSwKaE86ZnVuY3Rpb24oYSxiLGMs
+ZCl7dmFyIHMscixxPXRoaXMKaWYoYy1iPjEwMDApe3M9Qy5qbi5CVShiK2MsMikKcj1xLmhPKGEsYixz
+LCExKQppZigocS5iJjEpIT09MClyZXR1cm4gcgpyZXR1cm4gcitxLmhPKGEscyxjLGQpfXJldHVybiBx
+LkVoKGEsYixjLGQpfSwKRWg6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixxLHAsbyxuLG0sbCxrPXRo
+aXMsaj02NTUzMyxpPWsuYixoPWsuYyxnPW5ldyBQLlJuKCIiKSxmPWIrMSxlPWEubGVuZ3RoCmlmKGI8
+MHx8Yj49ZSlyZXR1cm4gSC5PSChhLGIpCnM9YVtiXQokbGFiZWwwJDA6Zm9yKHI9ay5hOyEwOyl7Zm9y
+KDshMDtmPW8pe3E9Qy54Qi5XKCJBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFB
QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFB
-QUFBQUFBQUFBQUFBQUFBQUFBRkZGRkZGRkZGRkZGRkZGRkdHR0dHR0dHR0dHR0dHR0dISEhISEhISEhI
-SEhISEhISEhISEhISEhISEhJSEhISkVFQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCS0NDQ0ND
-Q0NDQ0NDQ0RDTE9OTk5NRUVFRUVFRUVFRUUiLHMpJjMxCmg9aTw9MzI/cyY2MTY5ND4+PnE6KHMmNjN8
-aDw8Nik+Pj4wCmk9Qy54Qi5XKCIgXHgwMDA6WEVDQ0NDQ046bERiIFx4MDAwOlhFQ0NDQ0NOdmxEYiBc
-eDAwMDpYRUNDQ0NDTjpsRGIgQUFBQUFceDAwXHgwMFx4MDBceDAwXHgwMEFBQUFBMDAwMDBBQUFBQTo6
-Ojo6QUFBQUFHRzAwMEFBQUFBMDBLS0tBQUFBQUc6Ojo6QUFBQUE6SUlJSUFBQUFBMDAwXHg4MDBBQUFB
-QVx4MDBceDAwXHgwMFx4MDAgQUFBQUEiLGkrcSkKaWYoaT09PTApe2cuYSs9SC5MdyhoKQppZihmPT09
-YylicmVhayAkbGFiZWwwJDAKYnJlYWt9ZWxzZSBpZigoaSYxKSE9PTApe2lmKHIpc3dpdGNoKGkpe2Nh
-c2UgNjk6Y2FzZSA2NzpnLmErPUguTHcoaikKYnJlYWsKY2FzZSA2NTpnLmErPUguTHcoaik7LS1mCmJy
-ZWFrCmRlZmF1bHQ6cD1nLmErPUguTHcoaikKZy5hPXArSC5MdyhqKQpicmVha31lbHNle2suYj1pCmsu
-Yz1mLTEKcmV0dXJuIiJ9aT0wfWlmKGY9PT1jKWJyZWFrICRsYWJlbDAkMApvPWYrMQppZihmPDB8fGY+
-PWUpcmV0dXJuIEguT0goYSxmKQpzPWFbZl19bz1mKzEKaWYoZjwwfHxmPj1lKXJldHVybiBILk9IKGEs
-ZikKcz1hW2ZdCmlmKHM8MTI4KXt3aGlsZSghMCl7aWYoIShvPGMpKXtuPWMKYnJlYWt9bT1vKzEKaWYo
-bzwwfHxvPj1lKXJldHVybiBILk9IKGEsbykKcz1hW29dCmlmKHM+PTEyOCl7bj1tLTEKbz1tCmJyZWFr
-fW89bX1pZihuLWY8MjApZm9yKGw9ZjtsPG47KytsKXtpZihsPj1lKXJldHVybiBILk9IKGEsbCkKZy5h
-Kz1ILkx3KGFbbF0pfWVsc2UgZy5hKz1QLkhNKGEsZixuKQppZihuPT09YylicmVhayAkbGFiZWwwJDAK
-Zj1vfWVsc2UgZj1vfWlmKGQmJmk+MzIpaWYocilnLmErPUguTHcoaikKZWxzZXtrLmI9NzcKay5jPWMK
-cmV0dXJuIiJ9ay5iPWkKay5jPWgKZT1nLmEKcmV0dXJuIGUuY2hhckNvZGVBdCgwKT09MD9lOmV9fQpQ
-LldGLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxCnQuZm8uYShhKQpzPXRoaXMu
-YgpyPXRoaXMuYQpzLmErPXIuYQpxPXMuYSs9SC5FaihhLmEpCnMuYT1xKyI6ICIKcy5hKz1QLnAoYikK
-ci5hPSIsICJ9LAokUzo0Mn0KUC5pUC5wcm90b3R5cGU9ewpETjpmdW5jdGlvbihhLGIpe2lmKGI9PW51
-bGwpcmV0dXJuITEKcmV0dXJuIGIgaW5zdGFuY2VvZiBQLmlQJiZ0aGlzLmE9PT1iLmEmJiEwfSwKZ2lP
-OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuYQpyZXR1cm4oc15DLmpuLndHKHMsMzApKSYxMDczNzQxODIz
-fSwKdzpmdW5jdGlvbihhKXt2YXIgcz10aGlzLHI9UC5HcShILnRKKHMpKSxxPVAuaDAoSC5OUyhzKSks
-cD1QLmgwKEguakEocykpLG89UC5oMChILklYKHMpKSxuPVAuaDAoSC5jaChzKSksbT1QLmgwKEguSmQo
-cykpLGw9UC5WeChILm8xKHMpKSxrPXIrIi0iK3ErIi0iK3ArIiAiK28rIjoiK24rIjoiK20rIi4iK2wK
-cmV0dXJuIGt9fQpQLlhTLnByb3RvdHlwZT17CmdJSTpmdW5jdGlvbigpe3JldHVybiBILnRzKHRoaXMu
-JHRocm93bkpzRXJyb3IpfX0KUC5DNi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMu
-YQppZihzIT1udWxsKXJldHVybiJBc3NlcnRpb24gZmFpbGVkOiAiK1AucChzKQpyZXR1cm4iQXNzZXJ0
-aW9uIGZhaWxlZCJ9fQpQLkV6LnByb3RvdHlwZT17fQpQLkYucHJvdG90eXBlPXsKdzpmdW5jdGlvbihh
-KXtyZXR1cm4iVGhyb3cgb2YgbnVsbC4ifX0KUC51LnByb3RvdHlwZT17CmdaOmZ1bmN0aW9uKCl7cmV0
-dXJuIkludmFsaWQgYXJndW1lbnQiKyghdGhpcy5hPyIocykiOiIiKX0sCmd1OmZ1bmN0aW9uKCl7cmV0
-dXJuIiJ9LAp3OmZ1bmN0aW9uKGEpe3ZhciBzLHIscT10aGlzLHA9cS5jLG89cD09bnVsbD8iIjoiICgi
-K3ArIikiLG49cS5kLG09bj09bnVsbD8iIjoiOiAiK0guRWoobiksbD1xLmdaKCkrbyttCmlmKCFxLmEp
-cmV0dXJuIGwKcz1xLmd1KCkKcj1QLnAocS5iKQpyZXR1cm4gbCtzKyI6ICIrcn19ClAuYkoucHJvdG90
-eXBlPXsKZ1o6ZnVuY3Rpb24oKXtyZXR1cm4iUmFuZ2VFcnJvciJ9LApndTpmdW5jdGlvbigpe3ZhciBz
-LHI9dGhpcy5lLHE9dGhpcy5mCmlmKHI9PW51bGwpcz1xIT1udWxsPyI6IE5vdCBsZXNzIHRoYW4gb3Ig
-ZXF1YWwgdG8gIitILkVqKHEpOiIiCmVsc2UgaWYocT09bnVsbClzPSI6IE5vdCBncmVhdGVyIHRoYW4g
-b3IgZXF1YWwgdG8gIitILkVqKHIpCmVsc2UgaWYocT5yKXM9IjogTm90IGluIGluY2x1c2l2ZSByYW5n
-ZSAiK0guRWoocikrIi4uIitILkVqKHEpCmVsc2Ugcz1xPHI/IjogVmFsaWQgdmFsdWUgcmFuZ2UgaXMg
-ZW1wdHkiOiI6IE9ubHkgdmFsaWQgdmFsdWUgaXMgIitILkVqKHIpCnJldHVybiBzfX0KUC5lWS5wcm90
-b3R5cGU9ewpnWjpmdW5jdGlvbigpe3JldHVybiJSYW5nZUVycm9yIn0sCmd1OmZ1bmN0aW9uKCl7dmFy
-IHMscj1ILnVQKHRoaXMuYikKaWYodHlwZW9mIHIhPT0ibnVtYmVyIilyZXR1cm4gci5KKCkKaWYocjww
-KXJldHVybiI6IGluZGV4IG11c3Qgbm90IGJlIG5lZ2F0aXZlIgpzPXRoaXMuZgppZihzPT09MClyZXR1
-cm4iOiBubyBpbmRpY2VzIGFyZSB2YWxpZCIKcmV0dXJuIjogaW5kZXggc2hvdWxkIGJlIGxlc3MgdGhh
-biAiK0guRWoocyl9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5mfX0KUC5tcC5wcm90b3R5cGU9
-ewp3OmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG8sbixtLGwsaz10aGlzLGo9e30saT1uZXcgUC5Sbigi
-IikKai5hPSIiCnM9ay5jCmZvcihyPXMubGVuZ3RoLHE9MCxwPSIiLG89IiI7cTxyOysrcSxvPSIsICIp
-e249c1txXQppLmE9cCtvCnA9aS5hKz1QLnAobikKai5hPSIsICJ9ay5kLksoMCxuZXcgUC5XRihqLGkp
-KQptPVAucChrLmEpCmw9aS53KDApCnI9Ik5vU3VjaE1ldGhvZEVycm9yOiBtZXRob2Qgbm90IGZvdW5k
-OiAnIitILkVqKGsuYi5hKSsiJ1xuUmVjZWl2ZXI6ICIrbSsiXG5Bcmd1bWVudHM6IFsiK2wrIl0iCnJl
-dHVybiByfX0KUC51Yi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJVbnN1cHBvcnRlZCBv
-cGVyYXRpb246ICIrdGhpcy5hfX0KUC5kcy5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzPXRo
-aXMuYQpyZXR1cm4gcyE9bnVsbD8iVW5pbXBsZW1lbnRlZEVycm9yOiAiK3M6IlVuaW1wbGVtZW50ZWRF
-cnJvciJ9fQpQLmxqLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIkJhZCBzdGF0ZTogIit0
-aGlzLmF9fQpQLlVWLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5hCmlmKHM9PW51
-bGwpcmV0dXJuIkNvbmN1cnJlbnQgbW9kaWZpY2F0aW9uIGR1cmluZyBpdGVyYXRpb24uIgpyZXR1cm4i
-Q29uY3VycmVudCBtb2RpZmljYXRpb24gZHVyaW5nIGl0ZXJhdGlvbjogIitQLnAocykrIi4ifX0KUC5r
-NS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJPdXQgb2YgTWVtb3J5In0sCmdJSTpmdW5j
-dGlvbigpe3JldHVybiBudWxsfSwKJGlYUzoxfQpQLktZLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7
-cmV0dXJuIlN0YWNrIE92ZXJmbG93In0sCmdJSTpmdW5jdGlvbigpe3JldHVybiBudWxsfSwKJGlYUzox
-fQpQLmMucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmEKcmV0dXJuIHM9PW51bGw/
-IlJlYWRpbmcgc3RhdGljIHZhcmlhYmxlIGR1cmluZyBpdHMgaW5pdGlhbGl6YXRpb24iOiJSZWFkaW5n
-IHN0YXRpYyB2YXJpYWJsZSAnIitzKyInIGR1cmluZyBpdHMgaW5pdGlhbGl6YXRpb24ifX0KUC5DRC5w
-cm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJFeGNlcHRpb246ICIrdGhpcy5hfSwKJGlSejox
-fQpQLmFFLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaSxo
-LGc9dGhpcy5hLGY9ZyE9bnVsbCYmIiIhPT1nPyJGb3JtYXRFeGNlcHRpb246ICIrSC5FaihnKToiRm9y
-bWF0RXhjZXB0aW9uIixlPXRoaXMuYyxkPXRoaXMuYgppZih0eXBlb2YgZD09InN0cmluZyIpe2lmKGUh
-PW51bGwpcz1lPDB8fGU+ZC5sZW5ndGgKZWxzZSBzPSExCmlmKHMpZT1udWxsCmlmKGU9PW51bGwpe2lm
-KGQubGVuZ3RoPjc4KWQ9Qy54Qi5OaihkLDAsNzUpKyIuLi4iCnJldHVybiBmKyJcbiIrZH1mb3Iocj0x
-LHE9MCxwPSExLG89MDtvPGU7KytvKXtuPUMueEIuVyhkLG8pCmlmKG49PT0xMCl7aWYocSE9PW98fCFw
-KSsrcgpxPW8rMQpwPSExfWVsc2UgaWYobj09PTEzKXsrK3IKcT1vKzEKcD0hMH19Zj1yPjE/ZisoIiAo
-YXQgbGluZSAiK3IrIiwgY2hhcmFjdGVyICIrKGUtcSsxKSsiKVxuIik6ZisoIiAoYXQgY2hhcmFjdGVy
-ICIrKGUrMSkrIilcbiIpCm09ZC5sZW5ndGgKZm9yKG89ZTtvPG07KytvKXtuPUMueEIuTzIoZCxvKQpp
-ZihuPT09MTB8fG49PT0xMyl7bT1vCmJyZWFrfX1pZihtLXE+NzgpaWYoZS1xPDc1KXtsPXErNzUKaz1x
-Cmo9IiIKaT0iLi4uIn1lbHNle2lmKG0tZTw3NSl7az1tLTc1Cmw9bQppPSIifWVsc2V7az1lLTM2Cmw9
-ZSszNgppPSIuLi4ifWo9Ii4uLiJ9ZWxzZXtsPW0Kaz1xCmo9IiIKaT0iIn1oPUMueEIuTmooZCxrLGwp
-CnJldHVybiBmK2oraCtpKyJcbiIrQy54Qi5JeCgiICIsZS1rK2oubGVuZ3RoKSsiXlxuIn1lbHNlIHJl
-dHVybiBlIT1udWxsP2YrKCIgKGF0IG9mZnNldCAiK0guRWooZSkrIikiKTpmfSwKJGlSejoxfQpQLmNY
-LnByb3RvdHlwZT17CmRyOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEguR0oodGhpcyxILkxoKHRoaXMpLkMo
-ImNYLkUiKSxiKX0sCkUyOmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1ILkxoKHRoaXMpCnJldHVybiBILksx
-KHRoaXMscy5LcShjKS5DKCIxKGNYLkUpIikuYShiKSxzLkMoImNYLkUiKSxjKX0sCmV2OmZ1bmN0aW9u
-KGEsYil7dmFyIHM9SC5MaCh0aGlzKQpyZXR1cm4gbmV3IEguVTUodGhpcyxzLkMoImEyKGNYLkUpIiku
-YShiKSxzLkMoIlU1PGNYLkU+IikpfSwKdHQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gUC5ZMSh0aGlzLGIs
-SC5MaCh0aGlzKS5DKCJjWC5FIikpfSwKYnI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMudHQoYSwhMCl9
-LApnQTpmdW5jdGlvbihhKXt2YXIgcyxyPXRoaXMuZ20odGhpcykKZm9yKHM9MDtyLkYoKTspKytzCnJl
-dHVybiBzfSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiF0aGlzLmdtKHRoaXMpLkYoKX0sCmdvcjpmdW5j
-dGlvbihhKXtyZXR1cm4hdGhpcy5nbDAodGhpcyl9LAplUjpmdW5jdGlvbihhLGIpe3JldHVybiBILmJL
-KHRoaXMsYixILkxoKHRoaXMpLkMoImNYLkUiKSl9LApncjg6ZnVuY3Rpb24oYSl7dmFyIHMscj10aGlz
-LmdtKHRoaXMpCmlmKCFyLkYoKSl0aHJvdyBILmIoSC5XcCgpKQpzPXIuZ2woKQppZihyLkYoKSl0aHJv
-dyBILmIoSC5BbSgpKQpyZXR1cm4gc30sCkU6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEKUC5rMShiLCJp
-bmRleCIpCmZvcihzPXRoaXMuZ20odGhpcykscj0wO3MuRigpOyl7cT1zLmdsKCkKaWYoYj09PXIpcmV0
-dXJuIHE7KytyfXRocm93IEguYihQLkNmKGIsdGhpcywiaW5kZXgiLG51bGwscikpfSwKdzpmdW5jdGlv
-bihhKXtyZXR1cm4gUC5FUCh0aGlzLCIoIiwiKSIpfX0KUC5Bbi5wcm90b3R5cGU9e30KUC5OMy5wcm90
-b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJNYXBFbnRyeSgiK0guRWooSi5qKHRoaXMuYSkpKyI6
-ICIrSC5FaihKLmoodGhpcy5iKSkrIikifX0KUC5jOC5wcm90b3R5cGU9ewpnaU86ZnVuY3Rpb24oYSl7
-cmV0dXJuIFAuTWgucHJvdG90eXBlLmdpTy5jYWxsKEMuak4sdGhpcyl9LAp3OmZ1bmN0aW9uKGEpe3Jl
-dHVybiJudWxsIn19ClAuTWgucHJvdG90eXBlPXtjb25zdHJ1Y3RvcjpQLk1oLCRpTWg6MSwKRE46ZnVu
-Y3Rpb24oYSxiKXtyZXR1cm4gdGhpcz09PWJ9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIEguZVEodGhp
-cyl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiJJbnN0YW5jZSBvZiAnIitILkVqKEguTSh0aGlzKSkrIici
-fSwKZTc6ZnVuY3Rpb24oYSxiKXt0Lm8uYShiKQp0aHJvdyBILmIoUC5scih0aGlzLGIuZ1dhKCksYi5n
-bmQoKSxiLmdWbSgpKSl9LAp0b1N0cmluZzpmdW5jdGlvbigpe3JldHVybiB0aGlzLncodGhpcyl9fQpQ
-LlpkLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIiJ9LAokaUd6OjF9ClAuUm4ucHJvdG90
-eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5sZW5ndGh9LAp3OmZ1bmN0aW9uKGEpe3Zh
-ciBzPXRoaXMuYQpyZXR1cm4gcy5jaGFyQ29kZUF0KDApPT0wP3M6c30sCiRpQkw6MX0KUC5uMS5wcm90
-b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwCnQuSi5hKGEpCkguaChiKQpzPUouclko
-YikuT1koYiwiPSIpCmlmKHM9PT0tMSl7aWYoYiE9PSIiKWEuWSgwLFAua3UoYiwwLGIubGVuZ3RoLHRo
-aXMuYSwhMCksIiIpfWVsc2UgaWYocyE9PTApe3I9Qy54Qi5OaihiLDAscykKcT1DLnhCLkcoYixzKzEp
-CnA9dGhpcy5hCmEuWSgwLFAua3UociwwLHIubGVuZ3RoLHAsITApLFAua3UocSwwLHEubGVuZ3RoLHAs
-ITApKX1yZXR1cm4gYX0sCiRTOjQ0fQpQLmNTLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhy
-b3cgSC5iKFAucnIoIklsbGVnYWwgSVB2NCBhZGRyZXNzLCAiK2EsdGhpcy5hLGIpKX0sCiRTOjIxfQpQ
-LlZDLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhyb3cgSC5iKFAucnIoIklsbGVnYWwgSVB2
-NiBhZGRyZXNzLCAiK2EsdGhpcy5hLGIpKX0sCiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLiQyKGEs
-bnVsbCl9LAokUzo0OX0KUC5KVC5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciBzCmlmKGIt
-YT40KXRoaXMuYS4kMigiYW4gSVB2NiBwYXJ0IGNhbiBvbmx5IGNvbnRhaW4gYSBtYXhpbXVtIG9mIDQg
-aGV4IGRpZ2l0cyIsYSkKcz1QLlFBKEMueEIuTmoodGhpcy5iLGEsYiksMTYpCmlmKHM8MHx8cz42NTUz
-NSl0aGlzLmEuJDIoImVhY2ggcGFydCBtdXN0IGJlIGluIHRoZSByYW5nZSBvZiBgMHgwLi4weEZGRkZg
-IixhKQpyZXR1cm4gc30sCiRTOjUxfQpQLkRuLnByb3RvdHlwZT17CmduRDpmdW5jdGlvbigpe3ZhciBz
-LHIscSxwLG89dGhpcwppZighby55KXtzPW8uYQpyPXMubGVuZ3RoIT09MD9zKyI6IjoiIgpxPW8uYwpw
-PXE9PW51bGwKaWYoIXB8fHM9PT0iZmlsZSIpe3M9cisiLy8iCnI9by5iCmlmKHIubGVuZ3RoIT09MClz
-PXMrcisiQCIKaWYoIXApcys9cQpyPW8uZAppZihyIT1udWxsKXM9cysiOiIrSC5FaihyKX1lbHNlIHM9
-cgpzKz1vLmUKcj1vLmYKaWYociE9bnVsbClzPXMrIj8iK3IKcj1vLnIKaWYociE9bnVsbClzPXMrIiMi
-K3IKaWYoby55KXRocm93IEguYihILkdRKCJfdGV4dCIpKQpvLng9cy5jaGFyQ29kZUF0KDApPT0wP3M6
-cwpvLnk9ITB9cmV0dXJuIG8ueH0sCmdGajpmdW5jdGlvbigpe3ZhciBzLHIscT10aGlzCmlmKCFxLlEp
-e3M9cS5lCmlmKHMubGVuZ3RoIT09MCYmQy54Qi5XKHMsMCk9PT00NylzPUMueEIuRyhzLDEpCnI9cy5s
-ZW5ndGg9PT0wP0MueEQ6UC5BRihuZXcgSC5sSihILlZNKHMuc3BsaXQoIi8iKSx0LnMpLHQuZE8uYShQ
-LlBIKCkpLHQuZG8pLHQuTikKaWYocS5RKXRocm93IEguYihILkdRKCJwYXRoU2VnbWVudHMiKSkKcS5z
-S3AocikKcS5RPSEwfXJldHVybiBxLnp9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHMscj10aGlzCmlmKCFy
-LmN4KXtzPUouaGYoci5nbkQoKSkKaWYoci5jeCl0aHJvdyBILmIoSC5HUSgiaGFzaENvZGUiKSkKci5j
-aD1zCnIuY3g9ITB9cmV0dXJuIHIuY2h9LApnaFk6ZnVuY3Rpb24oKXt2YXIgcyxyPXRoaXMKaWYoIXIu
-ZGIpe3M9UC5XWChyLmd0UCgpKQppZihyLmRiKXRocm93IEguYihILkdRKCJxdWVyeVBhcmFtZXRlcnMi
-KSkKci5zTk0obmV3IFAuR2oocyx0LmR3KSkKci5kYj0hMH1yZXR1cm4gci5jeX0sCmdrdTpmdW5jdGlv
-bigpe3JldHVybiB0aGlzLmJ9LApnSmY6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5jCmlmKHM9PW51bGwp
-cmV0dXJuIiIKaWYoQy54Qi5uKHMsIlsiKSlyZXR1cm4gQy54Qi5OaihzLDEscy5sZW5ndGgtMSkKcmV0
-dXJuIHN9LApndHA6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5kCnJldHVybiBzPT1udWxsP1Aud0sodGhp
-cy5hKTpzfSwKZ3RQOmZ1bmN0aW9uKCl7dmFyIHM9dGhpcy5mCnJldHVybiBzPT1udWxsPyIiOnN9LApn
-S2E6ZnVuY3Rpb24oKXt2YXIgcz10aGlzLnIKcmV0dXJuIHM9PW51bGw/IiI6c30sCm5tOmZ1bmN0aW9u
-KGEsYil7dmFyIHMscixxLHAsbyxuLG0sbCxrLGo9dGhpcwp0LmM5LmEoYikKcz1qLmEKcj1zPT09ImZp
-bGUiCnE9ai5iCnA9ai5kCm89ai5jCmlmKCEobyE9bnVsbCkpbz1xLmxlbmd0aCE9PTB8fHAhPW51bGx8
-fHI/IiI6bnVsbApuPWouZQppZighciltPW8hPW51bGwmJm4ubGVuZ3RoIT09MAplbHNlIG09ITAKaWYo
-bSYmIUMueEIubihuLCIvIikpbj0iLyIrbgpsPW4Kaz1QLmxlKG51bGwsMCwwLGIpCnJldHVybiBuZXcg
-UC5EbihzLHEsbyxwLGwsayxqLnIpfSwKSmg6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4KZm9y
-KHM9MCxyPTA7Qy54Qi5RaShiLCIuLi8iLHIpOyl7cis9MzsrK3N9cT1DLnhCLmNuKGEsIi8iKQp3aGls
-ZSghMCl7aWYoIShxPjAmJnM+MCkpYnJlYWsKcD1DLnhCLlBrKGEsIi8iLHEtMSkKaWYocDwwKWJyZWFr
-Cm89cS1wCm49byE9PTIKaWYoIW58fG89PT0zKWlmKEMueEIuTzIoYSxwKzEpPT09NDYpbj0hbnx8Qy54
-Qi5PMihhLHArMik9PT00NgplbHNlIG49ITEKZWxzZSBuPSExCmlmKG4pYnJlYWs7LS1zCnE9cH1yZXR1
-cm4gQy54Qi5pNyhhLHErMSxudWxsLEMueEIuRyhiLHItMypzKSl9LApaSTpmdW5jdGlvbihhKXtyZXR1
-cm4gdGhpcy5tUyhQLmhLKGEpKX0sCm1TOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG8sbixtLGwsayxq
-PXRoaXMsaT1udWxsCmlmKGEuZ0ZpKCkubGVuZ3RoIT09MCl7cz1hLmdGaSgpCmlmKGEuZ2NqKCkpe3I9
-YS5na3UoKQpxPWEuZ0pmKGEpCnA9YS5neEEoKT9hLmd0cChhKTppfWVsc2V7cD1pCnE9cApyPSIifW89
-UC54ZShhLmdJaShhKSkKbj1hLmdRRCgpP2EuZ3RQKCk6aX1lbHNle3M9ai5hCmlmKGEuZ2NqKCkpe3I9
-YS5na3UoKQpxPWEuZ0pmKGEpCnA9UC53QihhLmd4QSgpP2EuZ3RwKGEpOmkscykKbz1QLnhlKGEuZ0lp
-KGEpKQpuPWEuZ1FEKCk/YS5ndFAoKTppfWVsc2V7cj1qLmIKcT1qLmMKcD1qLmQKaWYoYS5nSWkoYSk9
-PT0iIil7bz1qLmUKbj1hLmdRRCgpP2EuZ3RQKCk6ai5mfWVsc2V7aWYoYS5ndFQoKSlvPVAueGUoYS5n
-SWkoYSkpCmVsc2V7bT1qLmUKaWYobS5sZW5ndGg9PT0wKWlmKHE9PW51bGwpbz1zLmxlbmd0aD09PTA/
-YS5nSWkoYSk6UC54ZShhLmdJaShhKSkKZWxzZSBvPVAueGUoIi8iK2EuZ0lpKGEpKQplbHNle2w9ai5K
-aChtLGEuZ0lpKGEpKQprPXMubGVuZ3RoPT09MAppZigha3x8cSE9bnVsbHx8Qy54Qi5uKG0sIi8iKSlv
-PVAueGUobCkKZWxzZSBvPVAud0YobCwha3x8cSE9bnVsbCl9fW49YS5nUUQoKT9hLmd0UCgpOml9fX1y
-ZXR1cm4gbmV3IFAuRG4ocyxyLHEscCxvLG4sYS5nWjgoKT9hLmdLYSgpOmkpfSwKZ2NqOmZ1bmN0aW9u
-KCl7cmV0dXJuIHRoaXMuYyE9bnVsbH0sCmd4QTpmdW5jdGlvbigpe3JldHVybiB0aGlzLmQhPW51bGx9
-LApnUUQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5mIT1udWxsfSwKZ1o4OmZ1bmN0aW9uKCl7cmV0dXJu
-IHRoaXMuciE9bnVsbH0sCmd0VDpmdW5jdGlvbigpe3JldHVybiBDLnhCLm4odGhpcy5lLCIvIil9LAp0
-NDpmdW5jdGlvbigpe3ZhciBzLHI9dGhpcyxxPXIuYQppZihxIT09IiImJnEhPT0iZmlsZSIpdGhyb3cg
-SC5iKFAuTDQoIkNhbm5vdCBleHRyYWN0IGEgZmlsZSBwYXRoIGZyb20gYSAiK3ErIiBVUkkiKSkKaWYo
-ci5ndFAoKSE9PSIiKXRocm93IEguYihQLkw0KHUuaSkpCmlmKHIuZ0thKCkhPT0iIil0aHJvdyBILmIo
-UC5MNCh1LmwpKQpxPSQud1EoKQppZihILm9UKHEpKXE9UC5tbihyKQplbHNle2lmKHIuYyE9bnVsbCYm
-ci5nSmYocikhPT0iIilILnYoUC5MNCh1LmopKQpzPXIuZ0ZqKCkKUC5rRShzLCExKQpxPVAudmcoQy54
-Qi5uKHIuZSwiLyIpPyIvIjoiIixzLCIvIikKcT1xLmNoYXJDb2RlQXQoMCk9PTA/cTpxfXJldHVybiBx
-fSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nbkQoKX0sCkROOmZ1bmN0aW9uKGEsYil7dmFyIHM9
-dGhpcwppZihiPT1udWxsKXJldHVybiExCmlmKHM9PT1iKXJldHVybiEwCnJldHVybiB0LmRELmIoYikm
-JnMuYT09PWIuZ0ZpKCkmJnMuYyE9bnVsbD09PWIuZ2NqKCkmJnMuYj09PWIuZ2t1KCkmJnMuZ0pmKHMp
-PT09Yi5nSmYoYikmJnMuZ3RwKHMpPT09Yi5ndHAoYikmJnMuZT09PWIuZ0lpKGIpJiZzLmYhPW51bGw9
-PT1iLmdRRCgpJiZzLmd0UCgpPT09Yi5ndFAoKSYmcy5yIT1udWxsPT09Yi5nWjgoKSYmcy5nS2EoKT09
-PWIuZ0thKCl9LApzS3A6ZnVuY3Rpb24oYSl7dGhpcy56PXQuYmsuYShhKX0sCnNOTTpmdW5jdGlvbihh
-KXt0aGlzLmN5PXQuY1ouYShhKX0sCiRpaUQ6MSwKZ0ZpOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYX0s
-CmdJaTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5lfX0KUC5SWi5wcm90b3R5cGU9ewokMTpmdW5jdGlv
-bihhKXtyZXR1cm4gUC5lUChDLlpKLEguaChhKSxDLnhNLCExKX0sCiRTOjV9ClAuTUUucHJvdG90eXBl
-PXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgcz10aGlzLmIscj10aGlzLmEKcy5hKz1yLmEKci5hPSImIgpy
-PXMuYSs9SC5FaihQLmVQKEMuRjMsYSxDLnhNLCEwKSkKaWYoYiE9bnVsbCYmYi5sZW5ndGghPT0wKXtz
-LmE9cisiPSIKcy5hKz1ILkVqKFAuZVAoQy5GMyxiLEMueE0sITApKX19LAokUzoyMn0KUC55NS5wcm90
-b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciBzLHIKSC5oKGEpCmlmKGI9PW51bGx8fHR5cGVvZiBi
-PT0ic3RyaW5nIil0aGlzLmEuJDIoYSxILmsoYikpCmVsc2UgZm9yKHM9Si5JVCh0LnUuYShiKSkscj10
-aGlzLmE7cy5GKCk7KXIuJDIoYSxILmgocy5nbCgpKSl9LAokUzoxMn0KUC5QRS5wcm90b3R5cGU9ewpn
-bFI6ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvPXRoaXMsbj1udWxsLG09by5jCmlmKG09PW51bGwpe209
-by5iCmlmKDA+PW0ubGVuZ3RoKXJldHVybiBILk9IKG0sMCkKcz1vLmEKbT1tWzBdKzEKcj1DLnhCLlhV
-KHMsIj8iLG0pCnE9cy5sZW5ndGgKaWYocj49MCl7cD1QLlBJKHMscisxLHEsQy5WQywhMSkKcT1yfWVs
-c2UgcD1uCm09by5jPW5ldyBQLnFlKCJkYXRhIiwiIixuLG4sUC5QSShzLG0scSxDLldkLCExKSxwLG4p
-fXJldHVybiBtfSwKdzpmdW5jdGlvbihhKXt2YXIgcyxyPXRoaXMuYgppZigwPj1yLmxlbmd0aClyZXR1
-cm4gSC5PSChyLDApCnM9dGhpcy5hCnJldHVybiByWzBdPT09LTE/ImRhdGE6IitzOnN9fQpQLnlJLnBy
-b3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHM9dGhpcy5hCmlmKGE+PXMubGVuZ3RoKXJldHVy
-biBILk9IKHMsYSkKcz1zW2FdCkMuTkEuZHUocywwLDk2LGIpCnJldHVybiBzfSwKJFM6MjN9ClAuYzYu
-cHJvdG90eXBlPXsKJDM6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzLHIscQpmb3Iocz1iLmxlbmd0aCxyPTA7
-cjxzOysrcil7cT1DLnhCLlcoYixyKV45NgppZihxPj05NilyZXR1cm4gSC5PSChhLHEpCmFbcV09Y319
-LAokUzoxM30KUC5xZC5wcm90b3R5cGU9ewokMzpmdW5jdGlvbihhLGIsYyl7dmFyIHMscixxCmZvcihz
-PUMueEIuVyhiLDApLHI9Qy54Qi5XKGIsMSk7czw9cjsrK3Mpe3E9KHNeOTYpPj4+MAppZihxPj05Nily
-ZXR1cm4gSC5PSChhLHEpCmFbcV09Y319LAokUzoxM30KUC5VZi5wcm90b3R5cGU9ewpnY2o6ZnVuY3Rp
-b24oKXtyZXR1cm4gdGhpcy5jPjB9LApneEE6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jPjAmJnRoaXMu
-ZCsxPHRoaXMuZX0sCmdRRDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmY8dGhpcy5yfSwKZ1o4OmZ1bmN0
-aW9uKCl7cmV0dXJuIHRoaXMucjx0aGlzLmEubGVuZ3RofSwKZ053OmZ1bmN0aW9uKCl7cmV0dXJuIHRo
-aXMuYj09PTQmJkMueEIubih0aGlzLmEsImZpbGUiKX0sCmdXWjpmdW5jdGlvbigpe3JldHVybiB0aGlz
-LmI9PT00JiZDLnhCLm4odGhpcy5hLCJodHRwIil9LApnUmU6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5i
-PT09NSYmQy54Qi5uKHRoaXMuYSwiaHR0cHMiKX0sCmd0VDpmdW5jdGlvbigpe3JldHVybiBDLnhCLlFp
-KHRoaXMuYSwiLyIsdGhpcy5lKX0sCmdGaTpmdW5jdGlvbigpe3ZhciBzPXRoaXMueApyZXR1cm4gcz09
-bnVsbD90aGlzLng9dGhpcy5VMigpOnN9LApVMjpmdW5jdGlvbigpe3ZhciBzPXRoaXMscj1zLmIKaWYo
-cjw9MClyZXR1cm4iIgppZihzLmdXWigpKXJldHVybiJodHRwIgppZihzLmdSZSgpKXJldHVybiJodHRw
-cyIKaWYocy5nTncoKSlyZXR1cm4iZmlsZSIKaWYocj09PTcmJkMueEIubihzLmEsInBhY2thZ2UiKSly
-ZXR1cm4icGFja2FnZSIKcmV0dXJuIEMueEIuTmoocy5hLDAscil9LApna3U6ZnVuY3Rpb24oKXt2YXIg
-cz10aGlzLmMscj10aGlzLmIrMwpyZXR1cm4gcz5yP0MueEIuTmoodGhpcy5hLHIscy0xKToiIn0sCmdK
-ZjpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmMKcmV0dXJuIHM+MD9DLnhCLk5qKHRoaXMuYSxzLHRoaXMu
-ZCk6IiJ9LApndHA6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcwppZihzLmd4QSgpKXJldHVybiBQLlFBKEMu
-eEIuTmoocy5hLHMuZCsxLHMuZSksbnVsbCkKaWYocy5nV1ooKSlyZXR1cm4gODAKaWYocy5nUmUoKSly
-ZXR1cm4gNDQzCnJldHVybiAwfSwKZ0lpOmZ1bmN0aW9uKGEpe3JldHVybiBDLnhCLk5qKHRoaXMuYSx0
-aGlzLmUsdGhpcy5mKX0sCmd0UDpmdW5jdGlvbigpe3ZhciBzPXRoaXMuZixyPXRoaXMucgpyZXR1cm4g
-czxyP0MueEIuTmoodGhpcy5hLHMrMSxyKToiIn0sCmdLYTpmdW5jdGlvbigpe3ZhciBzPXRoaXMucixy
-PXRoaXMuYQpyZXR1cm4gczxyLmxlbmd0aD9DLnhCLkcocixzKzEpOiIifSwKZ0ZqOmZ1bmN0aW9uKCl7
-dmFyIHMscixxPXRoaXMuZSxwPXRoaXMuZixvPXRoaXMuYQppZihDLnhCLlFpKG8sIi8iLHEpKSsrcQpp
-ZihxPT09cClyZXR1cm4gQy54RApzPUguVk0oW10sdC5zKQpmb3Iocj1xO3I8cDsrK3IpaWYoQy54Qi5P
-MihvLHIpPT09NDcpe0MuTm0uaShzLEMueEIuTmoobyxxLHIpKQpxPXIrMX1DLk5tLmkocyxDLnhCLk5q
-KG8scSxwKSkKcmV0dXJuIFAuQUYocyx0Lk4pfSwKZ2hZOmZ1bmN0aW9uKCl7aWYodGhpcy5mPj10aGlz
-LnIpcmV0dXJuIEMuQ00KcmV0dXJuIG5ldyBQLkdqKFAuV1godGhpcy5ndFAoKSksdC5kdyl9LAprWDpm
-dW5jdGlvbihhKXt2YXIgcz10aGlzLmQrMQpyZXR1cm4gcythLmxlbmd0aD09PXRoaXMuZSYmQy54Qi5R
-aSh0aGlzLmEsYSxzKX0sCk45OmZ1bmN0aW9uKCl7dmFyIHM9dGhpcyxyPXMucixxPXMuYQppZihyPj1x
-Lmxlbmd0aClyZXR1cm4gcwpyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihxLDAscikscy5iLHMuYyxzLmQs
-cy5lLHMuZixyLHMueCl9LApubTpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixtLGwsayxqLGk9
-dGhpcyxoPW51bGwKdC5jOS5hKGIpCnM9aS5nRmkoKQpyPXM9PT0iZmlsZSIKcT1pLmMKcD1xPjA/Qy54
-Qi5OaihpLmEsaS5iKzMscSk6IiIKbz1pLmd4QSgpP2kuZ3RwKGkpOmgKcT1pLmMKaWYocT4wKW49Qy54
-Qi5OaihpLmEscSxpLmQpCmVsc2Ugbj1wLmxlbmd0aCE9PTB8fG8hPW51bGx8fHI/IiI6aApxPWkuYQpt
-PUMueEIuTmoocSxpLmUsaS5mKQppZighcilsPW4hPW51bGwmJm0ubGVuZ3RoIT09MAplbHNlIGw9ITAK
-aWYobCYmIUMueEIubihtLCIvIikpbT0iLyIrbQprPVAubGUoaCwwLDAsYikKbD1pLnIKaj1sPHEubGVu
-Z3RoP0MueEIuRyhxLGwrMSk6aApyZXR1cm4gbmV3IFAuRG4ocyxwLG4sbyxtLGssail9LApaSTpmdW5j
-dGlvbihhKXtyZXR1cm4gdGhpcy5tUyhQLmhLKGEpKX0sCm1TOmZ1bmN0aW9uKGEpe2lmKGEgaW5zdGFu
-Y2VvZiBQLlVmKXJldHVybiB0aGlzLnUxKHRoaXMsYSkKcmV0dXJuIHRoaXMudnMoKS5tUyhhKX0sCnUx
-OmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGc9Yi5iCmlmKGc+MClyZXR1
-cm4gYgpzPWIuYwppZihzPjApe3I9YS5iCmlmKHI8PTApcmV0dXJuIGIKaWYoYS5nTncoKSlxPWIuZSE9
-PWIuZgplbHNlIGlmKGEuZ1daKCkpcT0hYi5rWCgiODAiKQplbHNlIHE9IWEuZ1JlKCl8fCFiLmtYKCI0
-NDMiKQppZihxKXtwPXIrMQpyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihhLmEsMCxwKStDLnhCLkcoYi5h
-LGcrMSkscixzK3AsYi5kK3AsYi5lK3AsYi5mK3AsYi5yK3AsYS54KX1lbHNlIHJldHVybiB0aGlzLnZz
-KCkubVMoYil9bz1iLmUKZz1iLmYKaWYobz09PWcpe3M9Yi5yCmlmKGc8cyl7cj1hLmYKcD1yLWcKcmV0
-dXJuIG5ldyBQLlVmKEMueEIuTmooYS5hLDAscikrQy54Qi5HKGIuYSxnKSxhLmIsYS5jLGEuZCxhLmUs
-ZytwLHMrcCxhLngpfWc9Yi5hCmlmKHM8Zy5sZW5ndGgpe3I9YS5yCnJldHVybiBuZXcgUC5VZihDLnhC
-Lk5qKGEuYSwwLHIpK0MueEIuRyhnLHMpLGEuYixhLmMsYS5kLGEuZSxhLmYscysoci1zKSxhLngpfXJl
-dHVybiBhLk45KCl9cz1iLmEKaWYoQy54Qi5RaShzLCIvIixvKSl7cj1hLmUKcD1yLW8KcmV0dXJuIG5l
-dyBQLlVmKEMueEIuTmooYS5hLDAscikrQy54Qi5HKHMsbyksYS5iLGEuYyxhLmQscixnK3AsYi5yK3As
-YS54KX1uPWEuZQptPWEuZgppZihuPT09bSYmYS5jPjApe2Zvcig7Qy54Qi5RaShzLCIuLi8iLG8pOylv
-Kz0zCnA9bi1vKzEKcmV0dXJuIG5ldyBQLlVmKEMueEIuTmooYS5hLDAsbikrIi8iK0MueEIuRyhzLG8p
-LGEuYixhLmMsYS5kLG4sZytwLGIucitwLGEueCl9bD1hLmEKZm9yKGs9bjtDLnhCLlFpKGwsIi4uLyIs
-ayk7KWsrPTMKaj0wCndoaWxlKCEwKXtpPW8rMwppZighKGk8PWcmJkMueEIuUWkocywiLi4vIixvKSkp
-YnJlYWs7KytqCm89aX1mb3IoaD0iIjttPms7KXstLW0KaWYoQy54Qi5PMihsLG0pPT09NDcpe2lmKGo9
-PT0wKXtoPSIvIgpicmVha30tLWoKaD0iLyJ9fWlmKG09PT1rJiZhLmI8PTAmJiFDLnhCLlFpKGwsIi8i
-LG4pKXtvLT1qKjMKaD0iIn1wPW0tbytoLmxlbmd0aApyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihsLDAs
-bSkraCtDLnhCLkcocyxvKSxhLmIsYS5jLGEuZCxuLGcrcCxiLnIrcCxhLngpfSwKdDQ6ZnVuY3Rpb24o
-KXt2YXIgcyxyLHEscD10aGlzCmlmKHAuYj49MCYmIXAuZ053KCkpdGhyb3cgSC5iKFAuTDQoIkNhbm5v
-dCBleHRyYWN0IGEgZmlsZSBwYXRoIGZyb20gYSAiK3AuZ0ZpKCkrIiBVUkkiKSkKcz1wLmYKcj1wLmEK
-aWYoczxyLmxlbmd0aCl7aWYoczxwLnIpdGhyb3cgSC5iKFAuTDQodS5pKSkKdGhyb3cgSC5iKFAuTDQo
-dS5sKSl9cT0kLndRKCkKaWYoSC5vVChxKSlzPVAubW4ocCkKZWxzZXtpZihwLmM8cC5kKUgudihQLkw0
-KHUuaikpCnM9Qy54Qi5OaihyLHAuZSxzKX1yZXR1cm4gc30sCmdpTzpmdW5jdGlvbihhKXt2YXIgcz10
-aGlzLnkKcmV0dXJuIHM9PW51bGw/dGhpcy55PUMueEIuZ2lPKHRoaXMuYSk6c30sCkROOmZ1bmN0aW9u
-KGEsYil7aWYoYj09bnVsbClyZXR1cm4hMQppZih0aGlzPT09YilyZXR1cm4hMApyZXR1cm4gdC5kRC5i
-KGIpJiZ0aGlzLmE9PT1iLncoMCl9LAp2czpmdW5jdGlvbigpe3ZhciBzPXRoaXMscj1udWxsLHE9cy5n
-RmkoKSxwPXMuZ2t1KCksbz1zLmM+MD9zLmdKZihzKTpyLG49cy5neEEoKT9zLmd0cChzKTpyLG09cy5h
-LGw9cy5mLGs9Qy54Qi5OaihtLHMuZSxsKSxqPXMucgpsPWw8aj9zLmd0UCgpOnIKcmV0dXJuIG5ldyBQ
-LkRuKHEscCxvLG4sayxsLGo8bS5sZW5ndGg/cy5nS2EoKTpyKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJu
-IHRoaXMuYX0sCiRpaUQ6MX0KUC5xZS5wcm90b3R5cGU9e30KVy5xRS5wcm90b3R5cGU9e30KVy5HaC5w
-cm90b3R5cGU9ewpzTFU6ZnVuY3Rpb24oYSxiKXthLmhyZWY9Yn0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJu
-IFN0cmluZyhhKX0sCiRpR2g6MX0KVy5mWS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiBT
-dHJpbmcoYSl9fQpXLm5CLnByb3RvdHlwZT17JGluQjoxfQpXLkF6LnByb3RvdHlwZT17JGlBejoxfQpX
-LlFQLnByb3RvdHlwZT17JGlRUDoxfQpXLm54LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVy
-biBhLmxlbmd0aH19Clcub0oucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3Ro
-fX0KVy5pZC5wcm90b3R5cGU9e30KVy5RRi5wcm90b3R5cGU9e30KVy5OaC5wcm90b3R5cGU9ewp3OmZ1
-bmN0aW9uKGEpe3JldHVybiBTdHJpbmcoYSl9fQpXLmFlLnByb3RvdHlwZT17CkRjOmZ1bmN0aW9uKGEs
-Yil7cmV0dXJuIGEuY3JlYXRlSFRNTERvY3VtZW50KGIpfX0KVy5JQi5wcm90b3R5cGU9ewp3OmZ1bmN0
-aW9uKGEpe3ZhciBzLHI9YS5sZWZ0CnIudG9TdHJpbmcKcj0iUmVjdGFuZ2xlICgiK0guRWoocikrIiwg
-IgpzPWEudG9wCnMudG9TdHJpbmcKcz1yK0guRWoocykrIikgIgpyPWEud2lkdGgKci50b1N0cmluZwpy
-PXMrSC5FaihyKSsiIHggIgpzPWEuaGVpZ2h0CnMudG9TdHJpbmcKcmV0dXJuIHIrSC5FaihzKX0sCkRO
-OmZ1bmN0aW9uKGEsYil7dmFyIHMscgppZihiPT1udWxsKXJldHVybiExCmlmKHQucS5iKGIpKXtzPWEu
-bGVmdApzLnRvU3RyaW5nCnI9Yi5sZWZ0CnIudG9TdHJpbmcKaWYocz09PXIpe3M9YS50b3AKcy50b1N0
-cmluZwpyPWIudG9wCnIudG9TdHJpbmcKaWYocz09PXIpe3M9YS53aWR0aApzLnRvU3RyaW5nCnI9Yi53
-aWR0aApyLnRvU3RyaW5nCmlmKHM9PT1yKXtzPWEuaGVpZ2h0CnMudG9TdHJpbmcKcj1iLmhlaWdodApy
-LnRvU3RyaW5nCnI9cz09PXIKcz1yfWVsc2Ugcz0hMX1lbHNlIHM9ITF9ZWxzZSBzPSExfWVsc2Ugcz0h
-MQpyZXR1cm4gc30sCmdpTzpmdW5jdGlvbihhKXt2YXIgcyxyLHEscD1hLmxlZnQKcC50b1N0cmluZwpw
-PUMuQ0QuZ2lPKHApCnM9YS50b3AKcy50b1N0cmluZwpzPUMuQ0QuZ2lPKHMpCnI9YS53aWR0aApyLnRv
-U3RyaW5nCnI9Qy5DRC5naU8ocikKcT1hLmhlaWdodApxLnRvU3RyaW5nCnJldHVybiBXLnJFKHAscyxy
-LEMuQ0QuZ2lPKHEpKX0sCiRpdG46MX0KVy5uNy5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1
-cm4gYS5sZW5ndGh9fQpXLnd6LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEu
-bGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe3ZhciBzCkgudVAoYikKcz10aGlzLmEKaWYoYjwwfHxiPj1z
-Lmxlbmd0aClyZXR1cm4gSC5PSChzLGIpCnJldHVybiB0aGlzLiR0aS5jLmEoc1tiXSl9LApZOmZ1bmN0
-aW9uKGEsYixjKXt0aGlzLiR0aS5jLmEoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBtb2RpZnkgbGlz
-dCIpKX19ClcuY3YucHJvdG90eXBlPXsKZ1FnOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5pNyhhKX0s
-CmdEOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5JNChhKX0sCnNEOmZ1bmN0aW9uKGEsYil7dmFyIHMK
-dC5RLmEoYikKcz10aGlzLmdEKGEpCnMuVjEoMCkKcy5GVigwLGIpfSwKdzpmdW5jdGlvbihhKXtyZXR1
-cm4gYS5sb2NhbE5hbWV9LApGRjpmdW5jdGlvbihhKXt2YXIgcz0hIWEuc2Nyb2xsSW50b1ZpZXdJZk5l
-ZWRlZAppZihzKWEuc2Nyb2xsSW50b1ZpZXdJZk5lZWRlZCgpCmVsc2UgYS5zY3JvbGxJbnRvVmlldygp
-fSwKbno6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgcyxyPXRoaXMucjYoYSxjLGQsZSkKc3dpdGNoKGIu
-dG9Mb3dlckNhc2UoKSl7Y2FzZSJiZWZvcmViZWdpbiI6cz1hLnBhcmVudE5vZGUKcy50b1N0cmluZwpK
-LkVoKHMscixhKQpicmVhawpjYXNlImFmdGVyYmVnaW4iOnM9YS5jaGlsZE5vZGVzCnRoaXMubUsoYSxy
-LHMubGVuZ3RoPjA/c1swXTpudWxsKQpicmVhawpjYXNlImJlZm9yZWVuZCI6YS5hcHBlbmRDaGlsZChy
-KQpicmVhawpjYXNlImFmdGVyZW5kIjpzPWEucGFyZW50Tm9kZQpzLnRvU3RyaW5nCkouRWgocyxyLGEu
-bmV4dFNpYmxpbmcpCmJyZWFrCmRlZmF1bHQ6SC52KFAueFkoIkludmFsaWQgcG9zaXRpb24gIitiKSl9
-fSwKcjY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixxLHAKaWYoYz09bnVsbCl7aWYoZD09bnVsbCl7
-cz0kLmx0CmlmKHM9PW51bGwpe3M9SC5WTShbXSx0LnYpCnI9bmV3IFcudkQocykKQy5ObS5pKHMsVy5U
-dyhudWxsKSkKQy5ObS5pKHMsVy5CbCgpKQokLmx0PXIKZD1yfWVsc2UgZD1zfXM9JC5FVQppZihzPT1u
-dWxsKXtzPW5ldyBXLktvKGQpCiQuRVU9cwpjPXN9ZWxzZXtzLmE9ZApjPXN9fWVsc2UgaWYoZCE9bnVs
-bCl0aHJvdyBILmIoUC54WSgidmFsaWRhdG9yIGNhbiBvbmx5IGJlIHBhc3NlZCBpZiB0cmVlU2FuaXRp
-emVyIGlzIG51bGwiKSkKaWYoJC54bz09bnVsbCl7cz1kb2N1bWVudApyPXMuaW1wbGVtZW50YXRpb24K
-ci50b1N0cmluZwpyPUMubUguRGMociwiIikKJC54bz1yCiQuQk89ci5jcmVhdGVSYW5nZSgpCnI9JC54
-by5jcmVhdGVFbGVtZW50KCJiYXNlIikKdC5jUi5hKHIpCnM9cy5iYXNlVVJJCnMudG9TdHJpbmcKci5o
-cmVmPXMKJC54by5oZWFkLmFwcGVuZENoaWxkKHIpfXM9JC54bwppZihzLmJvZHk9PW51bGwpe3I9cy5j
-cmVhdGVFbGVtZW50KCJib2R5IikKQy5CWi5zWEcocyx0LnAuYShyKSl9cz0kLnhvCmlmKHQucC5iKGEp
-KXtzPXMuYm9keQpzLnRvU3RyaW5nCnE9c31lbHNle3MudG9TdHJpbmcKcT1zLmNyZWF0ZUVsZW1lbnQo
-YS50YWdOYW1lKQokLnhvLmJvZHkuYXBwZW5kQ2hpbGQocSl9aWYoImNyZWF0ZUNvbnRleHR1YWxGcmFn
-bWVudCIgaW4gd2luZG93LlJhbmdlLnByb3RvdHlwZSYmIUMuTm0udGcoQy5TcSxhLnRhZ05hbWUpKXsk
-LkJPLnNlbGVjdE5vZGVDb250ZW50cyhxKQpzPSQuQk8Kcy50b1N0cmluZwpwPXMuY3JlYXRlQ29udGV4
-dHVhbEZyYWdtZW50KGI9PW51bGw/Im51bGwiOmIpfWVsc2V7Si53ZihxLGIpCnA9JC54by5jcmVhdGVE
-b2N1bWVudEZyYWdtZW50KCkKZm9yKDtzPXEuZmlyc3RDaGlsZCxzIT1udWxsOylwLmFwcGVuZENoaWxk
-KHMpfWlmKHEhPT0kLnhvLmJvZHkpSi5MdChxKQpjLlBuKHApCmRvY3VtZW50LmFkb3B0Tm9kZShwKQpy
-ZXR1cm4gcH0sCkFIOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gdGhpcy5yNihhLGIsYyxudWxsKX0sCnNo
-ZjpmdW5jdGlvbihhLGIpe3RoaXMuWUMoYSxiKX0sCnBrOmZ1bmN0aW9uKGEsYixjKXt0aGlzLnNhNChh
-LG51bGwpCmEuYXBwZW5kQ2hpbGQodGhpcy5yNihhLGIsbnVsbCxjKSl9LApZQzpmdW5jdGlvbihhLGIp
-e3JldHVybiB0aGlzLnBrKGEsYixudWxsKX0sCnNSTjpmdW5jdGlvbihhLGIpe2EuaW5uZXJIVE1MPWJ9
-LApnbnM6ZnVuY3Rpb24oYSl7cmV0dXJuIGEudGFnTmFtZX0sCmdWbDpmdW5jdGlvbihhKXtyZXR1cm4g
-bmV3IFcuZXUoYSwiY2xpY2siLCExLHQuayl9LAokaWN2OjF9ClcuQ3YucHJvdG90eXBlPXsKJDE6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIHQuaC5iKHQuQS5hKGEpKX0sCiRTOjI1fQpXLmVhLnByb3RvdHlwZT17JGll
-YToxfQpXLkQwLnByb3RvdHlwZT17Ck9uOmZ1bmN0aW9uKGEsYixjLGQpe3QuYncuYShjKQppZihjIT1u
-dWxsKXRoaXMudihhLGIsYyxkKX0sCkI6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiB0aGlzLk9uKGEsYixj
-LG51bGwpfSwKdjpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gYS5hZGRFdmVudExpc3RlbmVyKGIsSC50
-Uih0LmJ3LmEoYyksMSksZCl9LAokaUQwOjF9ClcuaEgucHJvdG90eXBlPXskaWhIOjF9ClcuaDQucHJv
-dG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofX0KVy5ici5wcm90b3R5cGU9ewpn
-QTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpXLlZiLnByb3RvdHlwZT17CnNYRzpmdW5jdGlv
-bihhLGIpe2EuYm9keT1ifX0KVy5mSi5wcm90b3R5cGU9ewplbzpmdW5jdGlvbihhLGIsYyxkKXtyZXR1
-cm4gYS5vcGVuKGIsYywhMCl9LAokaWZKOjF9Clcud2EucHJvdG90eXBlPXt9ClcuU2cucHJvdG90eXBl
-PXskaVNnOjF9ClcudTgucHJvdG90eXBlPXsKZ0RyOmZ1bmN0aW9uKGEpe2lmKCJvcmlnaW4iIGluIGEp
-cmV0dXJuIGEub3JpZ2luCnJldHVybiBILkVqKGEucHJvdG9jb2wpKyIvLyIrSC5FaihhLmhvc3QpfSwK
-dzpmdW5jdGlvbihhKXtyZXR1cm4gU3RyaW5nKGEpfSwKJGl1ODoxfQpXLkFqLnByb3RvdHlwZT17JGlB
-ajoxfQpXLmU3LnByb3RvdHlwZT17CmdyODpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmEscj1zLmNoaWxk
-Tm9kZXMubGVuZ3RoCmlmKHI9PT0wKXRocm93IEguYihQLlBWKCJObyBlbGVtZW50cyIpKQppZihyPjEp
-dGhyb3cgSC5iKFAuUFYoIk1vcmUgdGhhbiBvbmUgZWxlbWVudCIpKQpzPXMuZmlyc3RDaGlsZApzLnRv
-U3RyaW5nCnJldHVybiBzfSwKRlY6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvCnQuZWguYShiKQpp
-ZihiIGluc3RhbmNlb2YgVy5lNyl7cz1iLmEKcj10aGlzLmEKaWYocyE9PXIpZm9yKHE9cy5jaGlsZE5v
-ZGVzLmxlbmd0aCxwPTA7cDxxOysrcCl7bz1zLmZpcnN0Q2hpbGQKby50b1N0cmluZwpyLmFwcGVuZENo
-aWxkKG8pfXJldHVybn1mb3Iocz1iLmdtKGIpLHI9dGhpcy5hO3MuRigpOylyLmFwcGVuZENoaWxkKHMu
-Z2woKSl9LApZOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyCnQuQS5hKGMpCnM9dGhpcy5hCnI9cy5jaGls
-ZE5vZGVzCmlmKGI8MHx8Yj49ci5sZW5ndGgpcmV0dXJuIEguT0gocixiKQpzLnJlcGxhY2VDaGlsZChj
-LHJbYl0pfSwKZ206ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5hLmNoaWxkTm9kZXMKcmV0dXJuIG5ldyBX
-Llc5KHMscy5sZW5ndGgsSC56KHMpLkMoIlc5PEdtLkU+IikpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJu
-IHRoaXMuYS5jaGlsZE5vZGVzLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXt2YXIgcwpILnVQKGIpCnM9
-dGhpcy5hLmNoaWxkTm9kZXMKaWYoYjwwfHxiPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLGIpCnJldHVy
-biBzW2JdfX0KVy51SC5wcm90b3R5cGU9ewp3ZzpmdW5jdGlvbihhKXt2YXIgcz1hLnBhcmVudE5vZGUK
-aWYocyE9bnVsbClzLnJlbW92ZUNoaWxkKGEpfSwKRDQ6ZnVuY3Rpb24oYSl7dmFyIHMKZm9yKDtzPWEu
-Zmlyc3RDaGlsZCxzIT1udWxsOylhLnJlbW92ZUNoaWxkKHMpfSwKdzpmdW5jdGlvbihhKXt2YXIgcz1h
-Lm5vZGVWYWx1ZQpyZXR1cm4gcz09bnVsbD90aGlzLlUoYSk6c30sCnNhNDpmdW5jdGlvbihhLGIpe2Eu
-dGV4dENvbnRlbnQ9Yn0sCm1LOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gYS5pbnNlcnRCZWZvcmUoYixj
-KX0sCiRpdUg6MX0KVy5CSC5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9
-LApxOmZ1bmN0aW9uKGEsYil7SC51UChiKQppZihiPj4+MCE9PWJ8fGI+PWEubGVuZ3RoKXRocm93IEgu
-YihQLkNmKGIsYSxudWxsLG51bGwsbnVsbCkpCnJldHVybiBhW2JdfSwKWTpmdW5jdGlvbihhLGIsYyl7
-dC5BLmEoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBhc3NpZ24gZWxlbWVudCBvZiBpbW11dGFibGUg
-TGlzdC4iKSl9LApndEg6ZnVuY3Rpb24oYSl7aWYoYS5sZW5ndGg+MClyZXR1cm4gYVswXQp0aHJvdyBI
-LmIoUC5QVigiTm8gZWxlbWVudHMiKSl9LApFOmZ1bmN0aW9uKGEsYil7aWYoYjwwfHxiPj1hLmxlbmd0
-aClyZXR1cm4gSC5PSChhLGIpCnJldHVybiBhW2JdfSwKJGliUToxLAokaVhqOjEsCiRpY1g6MSwKJGl6
-TToxfQpXLlNOLnByb3RvdHlwZT17fQpXLmV3LnByb3RvdHlwZT17JGlldzoxfQpXLmxwLnByb3RvdHlw
-ZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH19ClcuVGIucHJvdG90eXBlPXsKcjY6ZnVu
-Y3Rpb24oYSxiLGMsZCl7dmFyIHMscgppZigiY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50IiBpbiB3aW5k
-b3cuUmFuZ2UucHJvdG90eXBlKXJldHVybiB0aGlzLkRXKGEsYixjLGQpCnM9Vy5VOSgiPHRhYmxlPiIr
-SC5FaihiKSsiPC90YWJsZT4iLGMsZCkKcj1kb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkK
-ci50b1N0cmluZwpzLnRvU3RyaW5nCm5ldyBXLmU3KHIpLkZWKDAsbmV3IFcuZTcocykpCnJldHVybiBy
-fX0KVy5Jdi5wcm90b3R5cGU9ewpyNjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyLHEscAppZigiY3Jl
-YXRlQ29udGV4dHVhbEZyYWdtZW50IiBpbiB3aW5kb3cuUmFuZ2UucHJvdG90eXBlKXJldHVybiB0aGlz
-LkRXKGEsYixjLGQpCnM9ZG9jdW1lbnQKcj1zLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKQpzPUMuSWUu
-cjYocy5jcmVhdGVFbGVtZW50KCJ0YWJsZSIpLGIsYyxkKQpzLnRvU3RyaW5nCnM9bmV3IFcuZTcocykK
-cT1zLmdyOChzKQpxLnRvU3RyaW5nCnM9bmV3IFcuZTcocSkKcD1zLmdyOChzKQpyLnRvU3RyaW5nCnAu
-dG9TdHJpbmcKbmV3IFcuZTcocikuRlYoMCxuZXcgVy5lNyhwKSkKcmV0dXJuIHJ9fQpXLldQLnByb3Rv
-dHlwZT17CnI2OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIscQppZigiY3JlYXRlQ29udGV4dHVhbEZy
-YWdtZW50IiBpbiB3aW5kb3cuUmFuZ2UucHJvdG90eXBlKXJldHVybiB0aGlzLkRXKGEsYixjLGQpCnM9
-ZG9jdW1lbnQKcj1zLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKQpzPUMuSWUucjYocy5jcmVhdGVFbGVt
-ZW50KCJ0YWJsZSIpLGIsYyxkKQpzLnRvU3RyaW5nCnM9bmV3IFcuZTcocykKcT1zLmdyOChzKQpyLnRv
-U3RyaW5nCnEudG9TdHJpbmcKbmV3IFcuZTcocikuRlYoMCxuZXcgVy5lNyhxKSkKcmV0dXJuIHJ9fQpX
-LnlZLnByb3RvdHlwZT17CnBrOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyCnRoaXMuc2E0KGEsbnVsbCkK
-cz1hLmNvbnRlbnQKcy50b1N0cmluZwpKLmJUKHMpCnI9dGhpcy5yNihhLGIsbnVsbCxjKQphLmNvbnRl
-bnQuYXBwZW5kQ2hpbGQocil9LApZQzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLnBrKGEsYixudWxs
-KX0sCiRpeVk6MX0KVy53Ni5wcm90b3R5cGU9e30KVy5LNS5wcm90b3R5cGU9ewpQbzpmdW5jdGlvbihh
-LGIsYyl7dmFyIHM9Vy5QMShhLm9wZW4oYixjKSkKcmV0dXJuIHN9LApnbVc6ZnVuY3Rpb24oYSl7cmV0
-dXJuIGEubG9jYXRpb259LAp1czpmdW5jdGlvbihhLGIpe3JldHVybiBhLmNvbmZpcm0oYil9LAokaUs1
-OjEsCiRpdjY6MX0KVy5DbS5wcm90b3R5cGU9eyRpQ206MX0KVy5DUS5wcm90b3R5cGU9eyRpQ1E6MX0K
-Vy53NC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzLHI9YS5sZWZ0CnIudG9TdHJpbmcKcj0i
-UmVjdGFuZ2xlICgiK0guRWoocikrIiwgIgpzPWEudG9wCnMudG9TdHJpbmcKcz1yK0guRWoocykrIikg
-IgpyPWEud2lkdGgKci50b1N0cmluZwpyPXMrSC5FaihyKSsiIHggIgpzPWEuaGVpZ2h0CnMudG9TdHJp
-bmcKcmV0dXJuIHIrSC5FaihzKX0sCkROOmZ1bmN0aW9uKGEsYil7dmFyIHMscgppZihiPT1udWxsKXJl
-dHVybiExCmlmKHQucS5iKGIpKXtzPWEubGVmdApzLnRvU3RyaW5nCnI9Yi5sZWZ0CnIudG9TdHJpbmcK
-aWYocz09PXIpe3M9YS50b3AKcy50b1N0cmluZwpyPWIudG9wCnIudG9TdHJpbmcKaWYocz09PXIpe3M9
-YS53aWR0aApzLnRvU3RyaW5nCnI9Yi53aWR0aApyLnRvU3RyaW5nCmlmKHM9PT1yKXtzPWEuaGVpZ2h0
-CnMudG9TdHJpbmcKcj1iLmhlaWdodApyLnRvU3RyaW5nCnI9cz09PXIKcz1yfWVsc2Ugcz0hMX1lbHNl
-IHM9ITF9ZWxzZSBzPSExfWVsc2Ugcz0hMQpyZXR1cm4gc30sCmdpTzpmdW5jdGlvbihhKXt2YXIgcyxy
-LHEscD1hLmxlZnQKcC50b1N0cmluZwpwPUMuQ0QuZ2lPKHApCnM9YS50b3AKcy50b1N0cmluZwpzPUMu
-Q0QuZ2lPKHMpCnI9YS53aWR0aApyLnRvU3RyaW5nCnI9Qy5DRC5naU8ocikKcT1hLmhlaWdodApxLnRv
-U3RyaW5nCnJldHVybiBXLnJFKHAscyxyLEMuQ0QuZ2lPKHEpKX19ClcucmgucHJvdG90eXBlPXsKZ0E6
-ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0gudVAoYikKaWYoYj4+
-PjAhPT1ifHxiPj1hLmxlbmd0aCl0aHJvdyBILmIoUC5DZihiLGEsbnVsbCxudWxsLG51bGwpKQpyZXR1
-cm4gYVtiXX0sClk6ZnVuY3Rpb24oYSxiLGMpe3QuQS5hKGMpCnRocm93IEguYihQLkw0KCJDYW5ub3Qg
-YXNzaWduIGVsZW1lbnQgb2YgaW1tdXRhYmxlIExpc3QuIikpfSwKRTpmdW5jdGlvbihhLGIpe2lmKGI8
-MHx8Yj49YS5sZW5ndGgpcmV0dXJuIEguT0goYSxiKQpyZXR1cm4gYVtiXX0sCiRpYlE6MSwKJGlYajox
-LAokaWNYOjEsCiRpek06MX0KVy5jZi5wcm90b3R5cGU9ewpLOmZ1bmN0aW9uKGEsYil7dmFyIHMscixx
-LHAsbwp0LmVBLmEoYikKZm9yKHM9dGhpcy5nVigpLHI9cy5sZW5ndGgscT10aGlzLmEscD0wO3A8cy5s
-ZW5ndGg7cy5sZW5ndGg9PT1yfHwoMCxILmxrKShzKSwrK3Ape289c1twXQpiLiQyKG8scS5nZXRBdHRy
-aWJ1dGUobykpfX0sCmdWOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbyxuLG09dGhpcy5hLmF0dHJpYnV0
-ZXMKbS50b1N0cmluZwpzPUguVk0oW10sdC5zKQpmb3Iocj1tLmxlbmd0aCxxPXQuaDkscD0wO3A8cjsr
-K3Ape2lmKHA+PW0ubGVuZ3RoKXJldHVybiBILk9IKG0scCkKbz1xLmEobVtwXSkKaWYoby5uYW1lc3Bh
-Y2VVUkk9PW51bGwpe249by5uYW1lCm4udG9TdHJpbmcKQy5ObS5pKHMsbil9fXJldHVybiBzfSwKZ2ww
-OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmdWKCkubGVuZ3RoPT09MH19ClcuaTcucHJvdG90eXBlPXsK
-eDQ6ZnVuY3Rpb24oYSl7dmFyIHM9SC5vVCh0aGlzLmEuaGFzQXR0cmlidXRlKGEpKQpyZXR1cm4gc30s
-CnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5hLmdldEF0dHJpYnV0ZShILmgoYikpfSwKWTpmdW5j
-dGlvbihhLGIsYyl7dGhpcy5hLnNldEF0dHJpYnV0ZShiLGMpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJu
-IHRoaXMuZ1YoKS5sZW5ndGh9fQpXLlN5LnByb3RvdHlwZT17Cng0OmZ1bmN0aW9uKGEpe3ZhciBzPUgu
-b1QodGhpcy5hLmEuaGFzQXR0cmlidXRlKCJkYXRhLSIrdGhpcy5PKGEpKSkKcmV0dXJuIHN9LApxOmZ1
-bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYS5hLmdldEF0dHJpYnV0ZSgiZGF0YS0iK3RoaXMuTyhILmgo
-YikpKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3RoaXMuYS5hLnNldEF0dHJpYnV0ZSgiZGF0YS0iK3RoaXMu
-TyhiKSxjKX0sCks6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuSygwLG5ldyBXLktTKHRoaXMsdC5lQS5hKGIp
-KSl9LApnVjpmdW5jdGlvbigpe3ZhciBzPUguVk0oW10sdC5zKQp0aGlzLmEuSygwLG5ldyBXLkEzKHRo
-aXMscykpCnJldHVybiBzfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ1YoKS5sZW5ndGh9LApn
-bDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ1YoKS5sZW5ndGg9PT0wfSwKazpmdW5jdGlvbihhKXt2
-YXIgcyxyLHE9SC5WTShhLnNwbGl0KCItIiksdC5zKQpmb3Iocz0xO3M8cS5sZW5ndGg7KytzKXtyPXFb
-c10KaWYoci5sZW5ndGg+MClDLk5tLlkocSxzLHJbMF0udG9VcHBlckNhc2UoKStKLktWKHIsMSkpfXJl
-dHVybiBDLk5tLkgocSwiIil9LApPOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG8KZm9yKHM9YS5sZW5n
-dGgscj0wLHE9IiI7cjxzOysrcil7cD1hW3JdCm89cC50b0xvd2VyQ2FzZSgpCnE9KHAhPT1vJiZyPjA/
-cSsiLSI6cSkrb31yZXR1cm4gcS5jaGFyQ29kZUF0KDApPT0wP3E6cX19ClcuS1MucHJvdG90eXBlPXsK
-JDI6ZnVuY3Rpb24oYSxiKXtpZihKLnJZKGEpLm4oYSwiZGF0YS0iKSl0aGlzLmIuJDIodGhpcy5hLmso
-Qy54Qi5HKGEsNSkpLGIpfSwKJFM6MTR9ClcuQTMucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtp
-ZihKLnJZKGEpLm4oYSwiZGF0YS0iKSlDLk5tLmkodGhpcy5iLHRoaXMuYS5rKEMueEIuRyhhLDUpKSl9
-LAokUzoxNH0KVy5JNC5wcm90b3R5cGU9ewpQOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbz1QLkxzKHQu
-TikKZm9yKHM9dGhpcy5hLmNsYXNzTmFtZS5zcGxpdCgiICIpLHI9cy5sZW5ndGgscT0wO3E8cjsrK3Ep
-e3A9Si5UMChzW3FdKQppZihwLmxlbmd0aCE9PTApby5pKDAscCl9cmV0dXJuIG99LApYOmZ1bmN0aW9u
-KGEpe3RoaXMuYS5jbGFzc05hbWU9dC5DLmEoYSkuSCgwLCIgIil9LApnQTpmdW5jdGlvbihhKXtyZXR1
-cm4gdGhpcy5hLmNsYXNzTGlzdC5sZW5ndGh9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5j
-bGFzc0xpc3QubGVuZ3RoPT09MH0sCmdvcjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmNsYXNzTGlz
-dC5sZW5ndGghPT0wfSwKVjE6ZnVuY3Rpb24oYSl7dGhpcy5hLmNsYXNzTmFtZT0iIn0sCnRnOmZ1bmN0
-aW9uKGEsYil7dmFyIHM9dGhpcy5hLmNsYXNzTGlzdC5jb250YWlucyhiKQpyZXR1cm4gc30sCmk6ZnVu
-Y3Rpb24oYSxiKXt2YXIgcyxyCkguaChiKQpzPXRoaXMuYS5jbGFzc0xpc3QKcj1zLmNvbnRhaW5zKGIp
-CnMuYWRkKGIpCnJldHVybiFyfSwKUjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscQppZih0eXBlb2YgYj09
-InN0cmluZyIpe3M9dGhpcy5hLmNsYXNzTGlzdApyPXMuY29udGFpbnMoYikKcy5yZW1vdmUoYikKcT1y
-fWVsc2UgcT0hMQpyZXR1cm4gcX0sCkZWOmZ1bmN0aW9uKGEsYil7Vy5UTih0aGlzLmEsdC5RLmEoYikp
-fX0KVy5Gay5wcm90b3R5cGU9e30KVy5STy5wcm90b3R5cGU9e30KVy5ldS5wcm90b3R5cGU9e30KVy54
-Qy5wcm90b3R5cGU9e30KVy52Ti5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5h
-LiQxKHQuQi5hKGEpKX0sCiRTOjI3fQpXLkpRLnByb3RvdHlwZT17CkNZOmZ1bmN0aW9uKGEpe3ZhciBz
-CmlmKCQub3IuYT09PTApe2ZvcihzPTA7czwyNjI7KytzKSQub3IuWSgwLEMuY21bc10sVy5wUygpKQpm
-b3Iocz0wO3M8MTI7KytzKSQub3IuWSgwLEMuQklbc10sVy5WNCgpKX19LAppMDpmdW5jdGlvbihhKXty
-ZXR1cm4gJC5BTigpLnRnKDAsVy5yUyhhKSl9LApFYjpmdW5jdGlvbihhLGIsYyl7dmFyIHM9JC5vci5x
-KDAsSC5FaihXLnJTKGEpKSsiOjoiK2IpCmlmKHM9PW51bGwpcz0kLm9yLnEoMCwiKjo6IitiKQppZihz
-PT1udWxsKXJldHVybiExCnJldHVybiBILnk4KHMuJDQoYSxiLGMsdGhpcykpfSwKJGlrRjoxfQpXLkdt
-LnByb3RvdHlwZT17CmdtOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5XOShhLHRoaXMuZ0EoYSksSC56
-KGEpLkMoIlc5PEdtLkU+IikpfX0KVy52RC5wcm90b3R5cGU9ewppMDpmdW5jdGlvbihhKXtyZXR1cm4g
-Qy5ObS5Wcih0aGlzLmEsbmV3IFcuVXYoYSkpfSwKRWI6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBDLk5t
-LlZyKHRoaXMuYSxuZXcgVy5FZyhhLGIsYykpfSwKJGlrRjoxfQpXLlV2LnByb3RvdHlwZT17CiQxOmZ1
-bmN0aW9uKGEpe3JldHVybiB0LmY2LmEoYSkuaTAodGhpcy5hKX0sCiRTOjE1fQpXLkVnLnByb3RvdHlw
-ZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0LmY2LmEoYSkuRWIodGhpcy5hLHRoaXMuYix0aGlzLmMp
-fSwKJFM6MTV9ClcubTYucHJvdG90eXBlPXsKQ1k6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixxCnRo
-aXMuYS5GVigwLGMpCnM9Yi5ldigwLG5ldyBXLkVvKCkpCnI9Yi5ldigwLG5ldyBXLldrKCkpCnRoaXMu
-Yi5GVigwLHMpCnE9dGhpcy5jCnEuRlYoMCxDLnhEKQpxLkZWKDAscil9LAppMDpmdW5jdGlvbihhKXty
-ZXR1cm4gdGhpcy5hLnRnKDAsVy5yUyhhKSl9LApFYjpmdW5jdGlvbihhLGIsYyl7dmFyIHM9dGhpcyxy
-PVcuclMoYSkscT1zLmMKaWYocS50ZygwLEguRWoocikrIjo6IitiKSlyZXR1cm4gcy5kLkR0KGMpCmVs
-c2UgaWYocS50ZygwLCIqOjoiK2IpKXJldHVybiBzLmQuRHQoYykKZWxzZXtxPXMuYgppZihxLnRnKDAs
-SC5FaihyKSsiOjoiK2IpKXJldHVybiEwCmVsc2UgaWYocS50ZygwLCIqOjoiK2IpKXJldHVybiEwCmVs
-c2UgaWYocS50ZygwLEguRWoocikrIjo6KiIpKXJldHVybiEwCmVsc2UgaWYocS50ZygwLCIqOjoqIikp
-cmV0dXJuITB9cmV0dXJuITF9LAokaWtGOjF9ClcuRW8ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7
-cmV0dXJuIUMuTm0udGcoQy5CSSxILmgoYSkpfSwKJFM6Nn0KVy5Xay5wcm90b3R5cGU9ewokMTpmdW5j
-dGlvbihhKXtyZXR1cm4gQy5ObS50ZyhDLkJJLEguaChhKSl9LAokUzo2fQpXLmN0LnByb3RvdHlwZT17
-CkViOmZ1bmN0aW9uKGEsYixjKXtpZih0aGlzLmpGKGEsYixjKSlyZXR1cm4hMAppZihiPT09InRlbXBs
-YXRlIiYmYz09PSIiKXJldHVybiEwCmlmKGEuZ2V0QXR0cmlidXRlKCJ0ZW1wbGF0ZSIpPT09IiIpcmV0
-dXJuIHRoaXMuZS50ZygwLGIpCnJldHVybiExfX0KVy5JQS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihh
-KXtyZXR1cm4iVEVNUExBVEU6OiIrSC5FaihILmgoYSkpfSwKJFM6NX0KVy5Pdy5wcm90b3R5cGU9ewpp
-MDpmdW5jdGlvbihhKXt2YXIgcwppZih0LmV3LmIoYSkpcmV0dXJuITEKcz10Lmc3LmIoYSkKaWYocyYm
-Vy5yUyhhKT09PSJmb3JlaWduT2JqZWN0IilyZXR1cm4hMQppZihzKXJldHVybiEwCnJldHVybiExfSwK
-RWI6ZnVuY3Rpb24oYSxiLGMpe2lmKGI9PT0iaXMifHxDLnhCLm4oYiwib24iKSlyZXR1cm4hMQpyZXR1
-cm4gdGhpcy5pMChhKX0sCiRpa0Y6MX0KVy5XOS5wcm90b3R5cGU9ewpGOmZ1bmN0aW9uKCl7dmFyIHM9
-dGhpcyxyPXMuYysxLHE9cy5iCmlmKHI8cSl7cy5zcChKLng5KHMuYSxyKSkKcy5jPXIKcmV0dXJuITB9
-cy5zcChudWxsKQpzLmM9cQpyZXR1cm4hMX0sCmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCnNw
-OmZ1bmN0aW9uKGEpe3RoaXMuZD10aGlzLiR0aS5DKCIxPyIpLmEoYSl9LAokaUFuOjF9ClcuZFcucHJv
-dG90eXBlPXskaUQwOjEsJGl2NjoxfQpXLm1rLnByb3RvdHlwZT17JGl5MDoxfQpXLktvLnByb3RvdHlw
-ZT17ClBuOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMscj1uZXcgVy5mbShzKQpzLmI9ITEKci4kMihhLG51
-bGwpCmZvcig7cy5iOyl7cy5iPSExCnIuJDIoYSxudWxsKX19LApFUDpmdW5jdGlvbihhLGIpe3ZhciBz
-PXRoaXMuYj0hMAppZihiIT1udWxsP2IhPT1hLnBhcmVudE5vZGU6cylKLkx0KGEpCmVsc2UgYi5yZW1v
-dmVDaGlsZChhKX0sCkk0OmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbyxuPSEwLG09bnVsbCxsPW51
-bGwKdHJ5e209Si5pZyhhKQpsPW0uYS5nZXRBdHRyaWJ1dGUoImlzIikKdC5oLmEoYSkKcz1mdW5jdGlv
-bihjKXtpZighKGMuYXR0cmlidXRlcyBpbnN0YW5jZW9mIE5hbWVkTm9kZU1hcCkpcmV0dXJuIHRydWUK
-aWYoYy5pZD09J2xhc3RDaGlsZCd8fGMubmFtZT09J2xhc3RDaGlsZCd8fGMuaWQ9PSdwcmV2aW91c1Np
-YmxpbmcnfHxjLm5hbWU9PSdwcmV2aW91c1NpYmxpbmcnfHxjLmlkPT0nY2hpbGRyZW4nfHxjLm5hbWU9
-PSdjaGlsZHJlbicpcmV0dXJuIHRydWUKdmFyIGs9Yy5jaGlsZE5vZGVzCmlmKGMubGFzdENoaWxkJiZj
-Lmxhc3RDaGlsZCE9PWtbay5sZW5ndGgtMV0pcmV0dXJuIHRydWUKaWYoYy5jaGlsZHJlbilpZighKGMu
-Y2hpbGRyZW4gaW5zdGFuY2VvZiBIVE1MQ29sbGVjdGlvbnx8Yy5jaGlsZHJlbiBpbnN0YW5jZW9mIE5v
-ZGVMaXN0KSlyZXR1cm4gdHJ1ZQp2YXIgaj0wCmlmKGMuY2hpbGRyZW4paj1jLmNoaWxkcmVuLmxlbmd0
-aApmb3IodmFyIGk9MDtpPGo7aSsrKXt2YXIgaD1jLmNoaWxkcmVuW2ldCmlmKGguaWQ9PSdhdHRyaWJ1
-dGVzJ3x8aC5uYW1lPT0nYXR0cmlidXRlcyd8fGguaWQ9PSdsYXN0Q2hpbGQnfHxoLm5hbWU9PSdsYXN0
-Q2hpbGQnfHxoLmlkPT0ncHJldmlvdXNTaWJsaW5nJ3x8aC5uYW1lPT0ncHJldmlvdXNTaWJsaW5nJ3x8
-aC5pZD09J2NoaWxkcmVuJ3x8aC5uYW1lPT0nY2hpbGRyZW4nKXJldHVybiB0cnVlfXJldHVybiBmYWxz
-ZX0oYSkKbj1ILm9UKHMpPyEwOiEoYS5hdHRyaWJ1dGVzIGluc3RhbmNlb2YgTmFtZWROb2RlTWFwKX1j
-YXRjaChwKXtILlJ1KHApfXI9ImVsZW1lbnQgdW5wcmludGFibGUiCnRyeXtyPUouaihhKX1jYXRjaChw
-KXtILlJ1KHApfXRyeXtxPVcuclMoYSkKdGhpcy5rUih0LmguYShhKSxiLG4scixxLHQuZi5hKG0pLEgu
-ayhsKSl9Y2F0Y2gocCl7aWYoSC5SdShwKSBpbnN0YW5jZW9mIFAudSl0aHJvdyBwCmVsc2V7dGhpcy5F
-UChhLGIpCndpbmRvdwpvPSJSZW1vdmluZyBjb3JydXB0ZWQgZWxlbWVudCAiK0guRWoocikKaWYodHlw
-ZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLndhcm4obyl9fX0sCmtSOmZ1bmN0
-aW9uKGEsYixjLGQsZSxmLGcpe3ZhciBzLHIscSxwLG8sbixtPXRoaXMKaWYoYyl7bS5FUChhLGIpCndp
-bmRvdwpzPSJSZW1vdmluZyBlbGVtZW50IGR1ZSB0byBjb3JydXB0ZWQgYXR0cmlidXRlcyBvbiA8Iitk
-KyI+IgppZih0eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUud2FybihzKQpy
-ZXR1cm59aWYoIW0uYS5pMChhKSl7bS5FUChhLGIpCndpbmRvdwpzPSJSZW1vdmluZyBkaXNhbGxvd2Vk
-IGVsZW1lbnQgPCIrSC5FaihlKSsiPiBmcm9tICIrSC5FaihiKQppZih0eXBlb2YgY29uc29sZSE9InVu
-ZGVmaW5lZCIpd2luZG93LmNvbnNvbGUud2FybihzKQpyZXR1cm59aWYoZyE9bnVsbClpZighbS5hLkVi
-KGEsImlzIixnKSl7bS5FUChhLGIpCndpbmRvdwpzPSJSZW1vdmluZyBkaXNhbGxvd2VkIHR5cGUgZXh0
-ZW5zaW9uIDwiK0guRWooZSkrJyBpcz0iJytnKyciPicKaWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmlu
-ZWQiKXdpbmRvdy5jb25zb2xlLndhcm4ocykKcmV0dXJufXM9Zi5nVigpCnI9SC5WTShzLnNsaWNlKDAp
-LEgudDYocykpCmZvcihxPWYuZ1YoKS5sZW5ndGgtMSxzPWYuYTtxPj0wOy0tcSl7aWYocT49ci5sZW5n
-dGgpcmV0dXJuIEguT0gocixxKQpwPXJbcV0Kbz1tLmEKbj1KLmNIKHApCkguaChwKQppZighby5FYihh
-LG4scy5nZXRBdHRyaWJ1dGUocCkpKXt3aW5kb3cKbz0iUmVtb3ZpbmcgZGlzYWxsb3dlZCBhdHRyaWJ1
-dGUgPCIrSC5FaihlKSsiICIrcCsnPSInK0guRWoocy5nZXRBdHRyaWJ1dGUocCkpKyciPicKaWYodHlw
-ZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLndhcm4obykKcy5yZW1vdmVBdHRy
-aWJ1dGUocCl9fWlmKHQuYVcuYihhKSl7cz1hLmNvbnRlbnQKcy50b1N0cmluZwptLlBuKHMpfX0sCiRp
-b246MX0KVy5mbS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixtPXRo
-aXMuYQpzd2l0Y2goYS5ub2RlVHlwZSl7Y2FzZSAxOm0uSTQoYSxiKQpicmVhawpjYXNlIDg6Y2FzZSAx
-MTpjYXNlIDM6Y2FzZSA0OmJyZWFrCmRlZmF1bHQ6bS5FUChhLGIpfXM9YS5sYXN0Q2hpbGQKZm9yKHE9
-dC5BO251bGwhPXM7KXtyPW51bGwKdHJ5e3I9cy5wcmV2aW91c1NpYmxpbmcKaWYociE9bnVsbCl7cD1y
-Lm5leHRTaWJsaW5nCm89cwpvPXA9PW51bGw/byE9bnVsbDpwIT09bwpwPW99ZWxzZSBwPSExCmlmKHAp
-e3A9UC5QVigiQ29ycnVwdCBIVE1MIikKdGhyb3cgSC5iKHApfX1jYXRjaChuKXtILlJ1KG4pCnA9cS5h
-KHMpCm0uYj0hMApvPXAucGFyZW50Tm9kZQpvPWE9PW51bGw/byE9bnVsbDphIT09bwppZihvKXtvPXAu
-cGFyZW50Tm9kZQppZihvIT1udWxsKW8ucmVtb3ZlQ2hpbGQocCl9ZWxzZSBhLnJlbW92ZUNoaWxkKHAp
-CnM9bnVsbApyPWEubGFzdENoaWxkfWlmKHMhPW51bGwpdGhpcy4kMihzLGEpCnM9cn19LAokUzozMH0K
-Vy5MZS5wcm90b3R5cGU9e30KVy5LNy5wcm90b3R5cGU9e30KVy5yQi5wcm90b3R5cGU9e30KVy5YVy5w
-cm90b3R5cGU9e30KVy5vYS5wcm90b3R5cGU9e30KUC5pSi5wcm90b3R5cGU9ewpWSDpmdW5jdGlvbihh
-KXt2YXIgcyxyPXRoaXMuYSxxPXIubGVuZ3RoCmZvcihzPTA7czxxOysrcylpZihyW3NdPT09YSlyZXR1
-cm4gcwpDLk5tLmkocixhKQpDLk5tLmkodGhpcy5iLG51bGwpCnJldHVybiBxfSwKUHY6ZnVuY3Rpb24o
-YSl7dmFyIHMscixxLHA9dGhpcyxvPXt9CmlmKGE9PW51bGwpcmV0dXJuIGEKaWYoSC5sKGEpKXJldHVy
-biBhCmlmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gYQppZih0eXBlb2YgYT09InN0cmluZyIpcmV0
-dXJuIGEKaWYoYSBpbnN0YW5jZW9mIFAuaVApcmV0dXJuIG5ldyBEYXRlKGEuYSkKaWYodC5mdi5iKGEp
-KXRocm93IEguYihQLlNZKCJzdHJ1Y3R1cmVkIGNsb25lIG9mIFJlZ0V4cCIpKQppZih0LmM4LmIoYSkp
-cmV0dXJuIGEKaWYodC53LmIoYSkpcmV0dXJuIGEKaWYodC5JLmIoYSkpcmV0dXJuIGEKcz10LmRFLmIo
-YSl8fCExCmlmKHMpcmV0dXJuIGEKaWYodC5mLmIoYSkpe3I9cC5WSChhKQpzPXAuYgppZihyPj1zLmxl
-bmd0aClyZXR1cm4gSC5PSChzLHIpCnE9by5hPXNbcl0KaWYocSE9bnVsbClyZXR1cm4gcQpxPXt9Cm8u
-YT1xCkMuTm0uWShzLHIscSkKYS5LKDAsbmV3IFAuamcobyxwKSkKcmV0dXJuIG8uYX1pZih0LmouYihh
-KSl7cj1wLlZIKGEpCm89cC5iCmlmKHI+PW8ubGVuZ3RoKXJldHVybiBILk9IKG8scikKcT1vW3JdCmlm
-KHEhPW51bGwpcmV0dXJuIHEKcmV0dXJuIHAuZWsoYSxyKX1pZih0LmVILmIoYSkpe3I9cC5WSChhKQpz
-PXAuYgppZihyPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLHIpCnE9by5iPXNbcl0KaWYocSE9bnVsbCly
-ZXR1cm4gcQpxPXt9Cm8uYj1xCkMuTm0uWShzLHIscSkKcC5pbShhLG5ldyBQLlRhKG8scCkpCnJldHVy
+QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUZGRkZGRkZGRkZGRkZGRkZHR0dHR0dHR0dHR0dHR0dH
+SEhISEhISEhISEhISEhISEhISEhISEhISEhISUhISEpFRUJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJC
+QkJCQktDQ0NDQ0NDQ0NDQ0NEQ0xPTk5OTUVFRUVFRUVFRUVFIixzKSYzMQpoPWk8PTMyP3MmNjE2OTQ+
+Pj5xOihzJjYzfGg8PDYpPj4+MAppPUMueEIuVygiIFx4MDAwOlhFQ0NDQ0NOOmxEYiBceDAwMDpYRUND
+Q0NDTnZsRGIgXHgwMDA6WEVDQ0NDQ046bERiIEFBQUFBXHgwMFx4MDBceDAwXHgwMFx4MDBBQUFBQTAw
+MDAwQUFBQUE6Ojo6OkFBQUFBR0cwMDBBQUFBQTAwS0tLQUFBQUFHOjo6OkFBQUFBOklJSUlBQUFBQTAw
+MFx4ODAwQUFBQUFceDAwXHgwMFx4MDBceDAwIEFBQUFBIixpK3EpCmlmKGk9PT0wKXtnLmErPUguTHco
+aCkKaWYoZj09PWMpYnJlYWsgJGxhYmVsMCQwCmJyZWFrfWVsc2UgaWYoKGkmMSkhPT0wKXtpZihyKXN3
+aXRjaChpKXtjYXNlIDY5OmNhc2UgNjc6Zy5hKz1ILkx3KGopCmJyZWFrCmNhc2UgNjU6Zy5hKz1ILkx3
+KGopOy0tZgpicmVhawpkZWZhdWx0OnA9Zy5hKz1ILkx3KGopCmcuYT1wK0guTHcoaikKYnJlYWt9ZWxz
+ZXtrLmI9aQprLmM9Zi0xCnJldHVybiIifWk9MH1pZihmPT09YylicmVhayAkbGFiZWwwJDAKbz1mKzEK
+aWYoZjwwfHxmPj1lKXJldHVybiBILk9IKGEsZikKcz1hW2ZdfW89ZisxCmlmKGY8MHx8Zj49ZSlyZXR1
+cm4gSC5PSChhLGYpCnM9YVtmXQppZihzPDEyOCl7d2hpbGUoITApe2lmKCEobzxjKSl7bj1jCmJyZWFr
+fW09bysxCmlmKG88MHx8bz49ZSlyZXR1cm4gSC5PSChhLG8pCnM9YVtvXQppZihzPj0xMjgpe249bS0x
+Cm89bQpicmVha31vPW19aWYobi1mPDIwKWZvcihsPWY7bDxuOysrbCl7aWYobD49ZSlyZXR1cm4gSC5P
+SChhLGwpCmcuYSs9SC5MdyhhW2xdKX1lbHNlIGcuYSs9UC5ITShhLGYsbikKaWYobj09PWMpYnJlYWsg
+JGxhYmVsMCQwCmY9b31lbHNlIGY9b31pZihkJiZpPjMyKWlmKHIpZy5hKz1ILkx3KGopCmVsc2V7ay5i
+PTc3CmsuYz1jCnJldHVybiIifWsuYj1pCmsuYz1oCmU9Zy5hCnJldHVybiBlLmNoYXJDb2RlQXQoMCk9
+PTA/ZTplfX0KUC5XRi5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscQp0LmZvLmEo
+YSkKcz10aGlzLmIKcj10aGlzLmEKcy5hKz1yLmEKcT1zLmErPUguRWooYS5hKQpzLmE9cSsiOiAiCnMu
+YSs9UC5wKGIpCnIuYT0iLCAifSwKJFM6NDJ9ClAuaVAucHJvdG90eXBlPXsKRE46ZnVuY3Rpb24oYSxi
+KXtpZihiPT1udWxsKXJldHVybiExCnJldHVybiBiIGluc3RhbmNlb2YgUC5pUCYmdGhpcy5hPT09Yi5h
+JiYhMH0sCmdpTzpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmEKcmV0dXJuKHNeQy5qbi53RyhzLDMwKSkm
+MTA3Mzc0MTgyM30sCnc6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcyxyPVAuR3EoSC50SihzKSkscT1QLmgw
+KEguTlMocykpLHA9UC5oMChILmpBKHMpKSxvPVAuaDAoSC5JWChzKSksbj1QLmgwKEguY2gocykpLG09
+UC5oMChILkpkKHMpKSxsPVAuVngoSC5vMShzKSksaz1yKyItIitxKyItIitwKyIgIitvKyI6IituKyI6
+IittKyIuIitsCnJldHVybiBrfX0KUC5YUy5wcm90b3R5cGU9ewpnSUk6ZnVuY3Rpb24oKXtyZXR1cm4g
+SC50cyh0aGlzLiR0aHJvd25Kc0Vycm9yKX19ClAuQzYucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2
+YXIgcz10aGlzLmEKaWYocyE9bnVsbClyZXR1cm4iQXNzZXJ0aW9uIGZhaWxlZDogIitQLnAocykKcmV0
+dXJuIkFzc2VydGlvbiBmYWlsZWQifX0KUC5Fei5wcm90b3R5cGU9e30KUC5GLnByb3RvdHlwZT17Cnc6
+ZnVuY3Rpb24oYSl7cmV0dXJuIlRocm93IG9mIG51bGwuIn19ClAudS5wcm90b3R5cGU9ewpnWjpmdW5j
+dGlvbigpe3JldHVybiJJbnZhbGlkIGFyZ3VtZW50IisoIXRoaXMuYT8iKHMpIjoiIil9LApndTpmdW5j
+dGlvbigpe3JldHVybiIifSwKdzpmdW5jdGlvbihhKXt2YXIgcyxyLHE9dGhpcyxwPXEuYyxvPXA9PW51
+bGw/IiI6IiAoIitwKyIpIixuPXEuZCxtPW49PW51bGw/IiI6IjogIitILkVqKG4pLGw9cS5nWigpK28r
+bQppZighcS5hKXJldHVybiBsCnM9cS5ndSgpCnI9UC5wKHEuYikKcmV0dXJuIGwrcysiOiAiK3J9fQpQ
+LmJKLnByb3RvdHlwZT17CmdaOmZ1bmN0aW9uKCl7cmV0dXJuIlJhbmdlRXJyb3IifSwKZ3U6ZnVuY3Rp
+b24oKXt2YXIgcyxyPXRoaXMuZSxxPXRoaXMuZgppZihyPT1udWxsKXM9cSE9bnVsbD8iOiBOb3QgbGVz
+cyB0aGFuIG9yIGVxdWFsIHRvICIrSC5FaihxKToiIgplbHNlIGlmKHE9PW51bGwpcz0iOiBOb3QgZ3Jl
+YXRlciB0aGFuIG9yIGVxdWFsIHRvICIrSC5FaihyKQplbHNlIGlmKHE+cilzPSI6IE5vdCBpbiBpbmNs
+dXNpdmUgcmFuZ2UgIitILkVqKHIpKyIuLiIrSC5FaihxKQplbHNlIHM9cTxyPyI6IFZhbGlkIHZhbHVl
+IHJhbmdlIGlzIGVtcHR5IjoiOiBPbmx5IHZhbGlkIHZhbHVlIGlzICIrSC5FaihyKQpyZXR1cm4gc319
+ClAuZVkucHJvdG90eXBlPXsKZ1o6ZnVuY3Rpb24oKXtyZXR1cm4iUmFuZ2VFcnJvciJ9LApndTpmdW5j
+dGlvbigpe3ZhciBzLHI9SC51UCh0aGlzLmIpCmlmKHR5cGVvZiByIT09Im51bWJlciIpcmV0dXJuIHIu
+SigpCmlmKHI8MClyZXR1cm4iOiBpbmRleCBtdXN0IG5vdCBiZSBuZWdhdGl2ZSIKcz10aGlzLmYKaWYo
+cz09PTApcmV0dXJuIjogbm8gaW5kaWNlcyBhcmUgdmFsaWQiCnJldHVybiI6IGluZGV4IHNob3VsZCBi
+ZSBsZXNzIHRoYW4gIitILkVqKHMpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZn19ClAubXAu
+cHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgcyxyLHEscCxvLG4sbSxsLGs9dGhpcyxqPXt9LGk9
+bmV3IFAuUm4oIiIpCmouYT0iIgpzPWsuYwpmb3Iocj1zLmxlbmd0aCxxPTAscD0iIixvPSIiO3E8cjsr
+K3Esbz0iLCAiKXtuPXNbcV0KaS5hPXArbwpwPWkuYSs9UC5wKG4pCmouYT0iLCAifWsuZC5LKDAsbmV3
+IFAuV0YoaixpKSkKbT1QLnAoay5hKQpsPWkudygwKQpyPSJOb1N1Y2hNZXRob2RFcnJvcjogbWV0aG9k
+IG5vdCBmb3VuZDogJyIrSC5FaihrLmIuYSkrIidcblJlY2VpdmVyOiAiK20rIlxuQXJndW1lbnRzOiBb
+IitsKyJdIgpyZXR1cm4gcn19ClAudWIucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iVW5z
+dXBwb3J0ZWQgb3BlcmF0aW9uOiAiK3RoaXMuYX19ClAuZHMucHJvdG90eXBlPXsKdzpmdW5jdGlvbihh
+KXt2YXIgcz10aGlzLmEKcmV0dXJuIHMhPW51bGw/IlVuaW1wbGVtZW50ZWRFcnJvcjogIitzOiJVbmlt
+cGxlbWVudGVkRXJyb3IifX0KUC5sai5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJCYWQg
+c3RhdGU6ICIrdGhpcy5hfX0KUC5VVi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMu
+YQppZihzPT1udWxsKXJldHVybiJDb25jdXJyZW50IG1vZGlmaWNhdGlvbiBkdXJpbmcgaXRlcmF0aW9u
+LiIKcmV0dXJuIkNvbmN1cnJlbnQgbW9kaWZpY2F0aW9uIGR1cmluZyBpdGVyYXRpb246ICIrUC5wKHMp
+KyIuIn19ClAuazUucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iT3V0IG9mIE1lbW9yeSJ9
+LApnSUk6ZnVuY3Rpb24oKXtyZXR1cm4gbnVsbH0sCiRpWFM6MX0KUC5LWS5wcm90b3R5cGU9ewp3OmZ1
+bmN0aW9uKGEpe3JldHVybiJTdGFjayBPdmVyZmxvdyJ9LApnSUk6ZnVuY3Rpb24oKXtyZXR1cm4gbnVs
+bH0sCiRpWFM6MX0KUC5jLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5hCnJldHVy
+biBzPT1udWxsPyJSZWFkaW5nIHN0YXRpYyB2YXJpYWJsZSBkdXJpbmcgaXRzIGluaXRpYWxpemF0aW9u
+IjoiUmVhZGluZyBzdGF0aWMgdmFyaWFibGUgJyIrcysiJyBkdXJpbmcgaXRzIGluaXRpYWxpemF0aW9u
+In19ClAuQ0QucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iRXhjZXB0aW9uOiAiK3RoaXMu
+YX0sCiRpUno6MX0KUC5hRS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG8sbixt
+LGwsayxqLGksaCxnPXRoaXMuYSxmPWchPW51bGwmJiIiIT09Zz8iRm9ybWF0RXhjZXB0aW9uOiAiK0gu
+RWooZyk6IkZvcm1hdEV4Y2VwdGlvbiIsZT10aGlzLmMsZD10aGlzLmIKaWYodHlwZW9mIGQ9PSJzdHJp
+bmciKXtpZihlIT1udWxsKXM9ZTwwfHxlPmQubGVuZ3RoCmVsc2Ugcz0hMQppZihzKWU9bnVsbAppZihl
+PT1udWxsKXtpZihkLmxlbmd0aD43OClkPUMueEIuTmooZCwwLDc1KSsiLi4uIgpyZXR1cm4gZisiXG4i
+K2R9Zm9yKHI9MSxxPTAscD0hMSxvPTA7bzxlOysrbyl7bj1DLnhCLlcoZCxvKQppZihuPT09MTApe2lm
+KHEhPT1vfHwhcCkrK3IKcT1vKzEKcD0hMX1lbHNlIGlmKG49PT0xMyl7KytyCnE9bysxCnA9ITB9fWY9
+cj4xP2YrKCIgKGF0IGxpbmUgIityKyIsIGNoYXJhY3RlciAiKyhlLXErMSkrIilcbiIpOmYrKCIgKGF0
+IGNoYXJhY3RlciAiKyhlKzEpKyIpXG4iKQptPWQubGVuZ3RoCmZvcihvPWU7bzxtOysrbyl7bj1DLnhC
+Lk8yKGQsbykKaWYobj09PTEwfHxuPT09MTMpe209bwpicmVha319aWYobS1xPjc4KWlmKGUtcTw3NSl7
+bD1xKzc1Cms9cQpqPSIiCmk9Ii4uLiJ9ZWxzZXtpZihtLWU8NzUpe2s9bS03NQpsPW0KaT0iIn1lbHNl
+e2s9ZS0zNgpsPWUrMzYKaT0iLi4uIn1qPSIuLi4ifWVsc2V7bD1tCms9cQpqPSIiCmk9IiJ9aD1DLnhC
+Lk5qKGQsayxsKQpyZXR1cm4gZitqK2graSsiXG4iK0MueEIuVCgiICIsZS1rK2oubGVuZ3RoKSsiXlxu
+In1lbHNlIHJldHVybiBlIT1udWxsP2YrKCIgKGF0IG9mZnNldCAiK0guRWooZSkrIikiKTpmfSwKJGlS
+ejoxfQpQLmNYLnByb3RvdHlwZT17CmRyOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEguR0oodGhpcyxILkxo
+KHRoaXMpLkMoImNYLkUiKSxiKX0sCkUyOmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1ILkxoKHRoaXMpCnJl
+dHVybiBILksxKHRoaXMscy5LcShjKS5DKCIxKGNYLkUpIikuYShiKSxzLkMoImNYLkUiKSxjKX0sCmV2
+OmZ1bmN0aW9uKGEsYil7dmFyIHM9SC5MaCh0aGlzKQpyZXR1cm4gbmV3IEguVTUodGhpcyxzLkMoImEy
+KGNYLkUpIikuYShiKSxzLkMoIlU1PGNYLkU+IikpfSwKdHQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gUC5Z
+MSh0aGlzLGIsSC5MaCh0aGlzKS5DKCJjWC5FIikpfSwKYnI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
+dHQoYSwhMCl9LApnQTpmdW5jdGlvbihhKXt2YXIgcyxyPXRoaXMuZ20odGhpcykKZm9yKHM9MDtyLkYo
+KTspKytzCnJldHVybiBzfSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiF0aGlzLmdtKHRoaXMpLkYoKX0s
+CmdvcjpmdW5jdGlvbihhKXtyZXR1cm4hdGhpcy5nbDAodGhpcyl9LAplUjpmdW5jdGlvbihhLGIpe3Jl
+dHVybiBILmJLKHRoaXMsYixILkxoKHRoaXMpLkMoImNYLkUiKSl9LApncjg6ZnVuY3Rpb24oYSl7dmFy
+IHMscj10aGlzLmdtKHRoaXMpCmlmKCFyLkYoKSl0aHJvdyBILmIoSC5XcCgpKQpzPXIuZ2woKQppZihy
+LkYoKSl0aHJvdyBILmIoSC5BbSgpKQpyZXR1cm4gc30sCkU6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEK
+UC5rMShiLCJpbmRleCIpCmZvcihzPXRoaXMuZ20odGhpcykscj0wO3MuRigpOyl7cT1zLmdsKCkKaWYo
+Yj09PXIpcmV0dXJuIHE7KytyfXRocm93IEguYihQLkNmKGIsdGhpcywiaW5kZXgiLG51bGwscikpfSwK
+dzpmdW5jdGlvbihhKXtyZXR1cm4gUC5FUCh0aGlzLCIoIiwiKSIpfX0KUC5Bbi5wcm90b3R5cGU9e30K
+UC5OMy5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJNYXBFbnRyeSgiK0guRWooSi5qKHRo
+aXMuYSkpKyI6ICIrSC5FaihKLmoodGhpcy5iKSkrIikifX0KUC5jOC5wcm90b3R5cGU9ewpnaU86ZnVu
+Y3Rpb24oYSl7cmV0dXJuIFAuTWgucHJvdG90eXBlLmdpTy5jYWxsKEMuak4sdGhpcyl9LAp3OmZ1bmN0
+aW9uKGEpe3JldHVybiJudWxsIn19ClAuTWgucHJvdG90eXBlPXtjb25zdHJ1Y3RvcjpQLk1oLCRpTWg6
+MSwKRE46ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcz09PWJ9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJu
+IEguZVEodGhpcyl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiJJbnN0YW5jZSBvZiAnIitILkVqKEguTSh0
+aGlzKSkrIicifSwKZTc6ZnVuY3Rpb24oYSxiKXt0Lm8uYShiKQp0aHJvdyBILmIoUC5scih0aGlzLGIu
+Z1dhKCksYi5nbmQoKSxiLmdWbSgpKSl9LAp0b1N0cmluZzpmdW5jdGlvbigpe3JldHVybiB0aGlzLnco
+dGhpcyl9fQpQLlpkLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIiJ9LAokaUd6OjF9ClAu
+Um4ucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5sZW5ndGh9LAp3OmZ1bmN0
+aW9uKGEpe3ZhciBzPXRoaXMuYQpyZXR1cm4gcy5jaGFyQ29kZUF0KDApPT0wP3M6c30sCiRpQkw6MX0K
+UC5uMS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwCnQuSi5hKGEpCkguaChi
+KQpzPUouclkoYikuT1koYiwiPSIpCmlmKHM9PT0tMSl7aWYoYiE9PSIiKWEuWTUoMCxQLmt1KGIsMCxi
+Lmxlbmd0aCx0aGlzLmEsITApLCIiKX1lbHNlIGlmKHMhPT0wKXtyPUMueEIuTmooYiwwLHMpCnE9Qy54
+Qi55bihiLHMrMSkKcD10aGlzLmEKYS5ZNSgwLFAua3UociwwLHIubGVuZ3RoLHAsITApLFAua3UocSww
+LHEubGVuZ3RoLHAsITApKX1yZXR1cm4gYX0sCiRTOjQ0fQpQLmNTLnByb3RvdHlwZT17CiQyOmZ1bmN0
+aW9uKGEsYil7dGhyb3cgSC5iKFAucnIoIklsbGVnYWwgSVB2NCBhZGRyZXNzLCAiK2EsdGhpcy5hLGIp
+KX0sCiRTOjIxfQpQLlZDLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhyb3cgSC5iKFAucnIo
+IklsbGVnYWwgSVB2NiBhZGRyZXNzLCAiK2EsdGhpcy5hLGIpKX0sCiQxOmZ1bmN0aW9uKGEpe3JldHVy
+biB0aGlzLiQyKGEsbnVsbCl9LAokUzo0OX0KUC5KVC5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIp
+e3ZhciBzCmlmKGItYT40KXRoaXMuYS4kMigiYW4gSVB2NiBwYXJ0IGNhbiBvbmx5IGNvbnRhaW4gYSBt
+YXhpbXVtIG9mIDQgaGV4IGRpZ2l0cyIsYSkKcz1QLlFBKEMueEIuTmoodGhpcy5iLGEsYiksMTYpCmlm
+KHM8MHx8cz42NTUzNSl0aGlzLmEuJDIoImVhY2ggcGFydCBtdXN0IGJlIGluIHRoZSByYW5nZSBvZiBg
+MHgwLi4weEZGRkZgIixhKQpyZXR1cm4gc30sCiRTOjUxfQpQLkRuLnByb3RvdHlwZT17CmduRDpmdW5j
+dGlvbigpe3ZhciBzLHIscSxwLG89dGhpcwppZighby55KXtzPW8uYQpyPXMubGVuZ3RoIT09MD9zKyI6
+IjoiIgpxPW8uYwpwPXE9PW51bGwKaWYoIXB8fHM9PT0iZmlsZSIpe3M9cisiLy8iCnI9by5iCmlmKHIu
+bGVuZ3RoIT09MClzPXMrcisiQCIKaWYoIXApcys9cQpyPW8uZAppZihyIT1udWxsKXM9cysiOiIrSC5F
+aihyKX1lbHNlIHM9cgpzKz1vLmUKcj1vLmYKaWYociE9bnVsbClzPXMrIj8iK3IKcj1vLnIKaWYociE9
+bnVsbClzPXMrIiMiK3IKaWYoby55KXRocm93IEguYihILkdRKCJfdGV4dCIpKQpvLng9cy5jaGFyQ29k
+ZUF0KDApPT0wP3M6cwpvLnk9ITB9cmV0dXJuIG8ueH0sCmdGajpmdW5jdGlvbigpe3ZhciBzLHIscT10
+aGlzCmlmKCFxLlEpe3M9cS5lCmlmKHMubGVuZ3RoIT09MCYmQy54Qi5XKHMsMCk9PT00NylzPUMueEIu
+eW4ocywxKQpyPXMubGVuZ3RoPT09MD9DLnhEOlAuQUYobmV3IEgubEooSC5WTShzLnNwbGl0KCIvIiks
+dC5zKSx0LmRPLmEoUC5QSCgpKSx0LmRvKSx0Lk4pCmlmKHEuUSl0aHJvdyBILmIoSC5HUSgicGF0aFNl
+Z21lbnRzIikpCnEuc0twKHIpCnEuUT0hMH1yZXR1cm4gcS56fSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciBz
+LHI9dGhpcwppZighci5jeCl7cz1KLmhmKHIuZ25EKCkpCmlmKHIuY3gpdGhyb3cgSC5iKEguR1EoImhh
+c2hDb2RlIikpCnIuY2g9cwpyLmN4PSEwfXJldHVybiByLmNofSwKZ2hZOmZ1bmN0aW9uKCl7dmFyIHMs
+cj10aGlzCmlmKCFyLmRiKXtzPVAuV1goci5ndFAoKSkKaWYoci5kYil0aHJvdyBILmIoSC5HUSgicXVl
+cnlQYXJhbWV0ZXJzIikpCnIuc05NKG5ldyBQLkdqKHMsdC5kdykpCnIuZGI9ITB9cmV0dXJuIHIuY3l9
+LApna3U6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5ifSwKZ0pmOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMu
+YwppZihzPT1udWxsKXJldHVybiIiCmlmKEMueEIubkMocywiWyIpKXJldHVybiBDLnhCLk5qKHMsMSxz
+Lmxlbmd0aC0xKQpyZXR1cm4gc30sCmd0cDpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmQKcmV0dXJuIHM9
+PW51bGw/UC53Syh0aGlzLmEpOnN9LApndFA6ZnVuY3Rpb24oKXt2YXIgcz10aGlzLmYKcmV0dXJuIHM9
+PW51bGw/IiI6c30sCmdLYTpmdW5jdGlvbigpe3ZhciBzPXRoaXMucgpyZXR1cm4gcz09bnVsbD8iIjpz
+fSwKbm06ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbSxsLGssaj10aGlzCnQuYzkuYShiKQpz
+PWouYQpyPXM9PT0iZmlsZSIKcT1qLmIKcD1qLmQKbz1qLmMKaWYoIShvIT1udWxsKSlvPXEubGVuZ3Ro
+IT09MHx8cCE9bnVsbHx8cj8iIjpudWxsCm49ai5lCmlmKCFyKW09byE9bnVsbCYmbi5sZW5ndGghPT0w
+CmVsc2UgbT0hMAppZihtJiYhQy54Qi5uQyhuLCIvIikpbj0iLyIrbgpsPW4Kaz1QLmxlKG51bGwsMCww
+LGIpCnJldHVybiBuZXcgUC5EbihzLHEsbyxwLGwsayxqLnIpfSwKSmg6ZnVuY3Rpb24oYSxiKXt2YXIg
+cyxyLHEscCxvLG4KZm9yKHM9MCxyPTA7Qy54Qi5RaShiLCIuLi8iLHIpOyl7cis9MzsrK3N9cT1DLnhC
+LmNuKGEsIi8iKQp3aGlsZSghMCl7aWYoIShxPjAmJnM+MCkpYnJlYWsKcD1DLnhCLlBrKGEsIi8iLHEt
+MSkKaWYocDwwKWJyZWFrCm89cS1wCm49byE9PTIKaWYoIW58fG89PT0zKWlmKEMueEIuTzIoYSxwKzEp
+PT09NDYpbj0hbnx8Qy54Qi5PMihhLHArMik9PT00NgplbHNlIG49ITEKZWxzZSBuPSExCmlmKG4pYnJl
+YWs7LS1zCnE9cH1yZXR1cm4gQy54Qi5pNyhhLHErMSxudWxsLEMueEIueW4oYixyLTMqcykpfSwKWkk6
+ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMubVMoUC5oSyhhKSl9LAptUzpmdW5jdGlvbihhKXt2YXIgcyxy
+LHEscCxvLG4sbSxsLGssaj10aGlzLGk9bnVsbAppZihhLmdGaSgpLmxlbmd0aCE9PTApe3M9YS5nRmko
+KQppZihhLmdjaigpKXtyPWEuZ2t1KCkKcT1hLmdKZihhKQpwPWEuZ3hBKCk/YS5ndHAoYSk6aX1lbHNl
+e3A9aQpxPXAKcj0iIn1vPVAueGUoYS5nSWkoYSkpCm49YS5nUUQoKT9hLmd0UCgpOml9ZWxzZXtzPWou
+YQppZihhLmdjaigpKXtyPWEuZ2t1KCkKcT1hLmdKZihhKQpwPVAud0IoYS5neEEoKT9hLmd0cChhKTpp
+LHMpCm89UC54ZShhLmdJaShhKSkKbj1hLmdRRCgpP2EuZ3RQKCk6aX1lbHNle3I9ai5iCnE9ai5jCnA9
+ai5kCmlmKGEuZ0lpKGEpPT09IiIpe289ai5lCm49YS5nUUQoKT9hLmd0UCgpOmouZn1lbHNle2lmKGEu
+Z3RUKCkpbz1QLnhlKGEuZ0lpKGEpKQplbHNle209ai5lCmlmKG0ubGVuZ3RoPT09MClpZihxPT1udWxs
+KW89cy5sZW5ndGg9PT0wP2EuZ0lpKGEpOlAueGUoYS5nSWkoYSkpCmVsc2Ugbz1QLnhlKCIvIithLmdJ
+aShhKSkKZWxzZXtsPWouSmgobSxhLmdJaShhKSkKaz1zLmxlbmd0aD09PTAKaWYoIWt8fHEhPW51bGx8
+fEMueEIubkMobSwiLyIpKW89UC54ZShsKQplbHNlIG89UC53RihsLCFrfHxxIT1udWxsKX19bj1hLmdR
+RCgpP2EuZ3RQKCk6aX19fXJldHVybiBuZXcgUC5EbihzLHIscSxwLG8sbixhLmdaOCgpP2EuZ0thKCk6
+aSl9LApnY2o6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jIT1udWxsfSwKZ3hBOmZ1bmN0aW9uKCl7cmV0
+dXJuIHRoaXMuZCE9bnVsbH0sCmdRRDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmYhPW51bGx9LApnWjg6
+ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5yIT1udWxsfSwKZ3RUOmZ1bmN0aW9uKCl7cmV0dXJuIEMueEIu
+bkModGhpcy5lLCIvIil9LAp0NDpmdW5jdGlvbigpe3ZhciBzLHI9dGhpcyxxPXIuYQppZihxIT09IiIm
+JnEhPT0iZmlsZSIpdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBleHRyYWN0IGEgZmlsZSBwYXRoIGZyb20g
+YSAiK3ErIiBVUkkiKSkKaWYoci5ndFAoKSE9PSIiKXRocm93IEguYihQLkw0KHUuaSkpCmlmKHIuZ0th
+KCkhPT0iIil0aHJvdyBILmIoUC5MNCh1LmwpKQpxPSQud1EoKQppZihILm9UKHEpKXE9UC5tbihyKQpl
+bHNle2lmKHIuYyE9bnVsbCYmci5nSmYocikhPT0iIilILnYoUC5MNCh1LmopKQpzPXIuZ0ZqKCkKUC5r
+RShzLCExKQpxPVAudmcoQy54Qi5uQyhyLmUsIi8iKT8iLyI6IiIscywiLyIpCnE9cS5jaGFyQ29kZUF0
+KDApPT0wP3E6cX1yZXR1cm4gcX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ25EKCl9LApETjpm
+dW5jdGlvbihhLGIpe3ZhciBzPXRoaXMKaWYoYj09bnVsbClyZXR1cm4hMQppZihzPT09YilyZXR1cm4h
+MApyZXR1cm4gdC5kRC5iKGIpJiZzLmE9PT1iLmdGaSgpJiZzLmMhPW51bGw9PT1iLmdjaigpJiZzLmI9
+PT1iLmdrdSgpJiZzLmdKZihzKT09PWIuZ0pmKGIpJiZzLmd0cChzKT09PWIuZ3RwKGIpJiZzLmU9PT1i
+LmdJaShiKSYmcy5mIT1udWxsPT09Yi5nUUQoKSYmcy5ndFAoKT09PWIuZ3RQKCkmJnMuciE9bnVsbD09
+PWIuZ1o4KCkmJnMuZ0thKCk9PT1iLmdLYSgpfSwKc0twOmZ1bmN0aW9uKGEpe3RoaXMuej10LmJrLmEo
+YSl9LApzTk06ZnVuY3Rpb24oYSl7dGhpcy5jeT10LmNaLmEoYSl9LAokaWlEOjEsCmdGaTpmdW5jdGlv
+bigpe3JldHVybiB0aGlzLmF9LApnSWk6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZX19ClAuUloucHJv
+dG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIFAuZVAoQy5aSixILmgoYSksQy54TSwhMSl9LAok
+Uzo1fQpQLk1FLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHM9dGhpcy5iLHI9dGhpcy5h
+CnMuYSs9ci5hCnIuYT0iJiIKcj1zLmErPUguRWooUC5lUChDLkYzLGEsQy54TSwhMCkpCmlmKGIhPW51
+bGwmJmIubGVuZ3RoIT09MCl7cy5hPXIrIj0iCnMuYSs9SC5FaihQLmVQKEMuRjMsYixDLnhNLCEwKSl9
+fSwKJFM6MjJ9ClAueTUucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCkguaChhKQpp
+ZihiPT1udWxsfHx0eXBlb2YgYj09InN0cmluZyIpdGhpcy5hLiQyKGEsSC5rKGIpKQplbHNlIGZvcihz
+PUouSVQodC51LmEoYikpLHI9dGhpcy5hO3MuRigpOylyLiQyKGEsSC5oKHMuZ2woKSkpfSwKJFM6MTJ9
+ClAuUEUucHJvdG90eXBlPXsKZ2xSOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbz10aGlzLG49bnVsbCxt
+PW8uYwppZihtPT1udWxsKXttPW8uYgppZigwPj1tLmxlbmd0aClyZXR1cm4gSC5PSChtLDApCnM9by5h
+Cm09bVswXSsxCnI9Qy54Qi5YVShzLCI/IixtKQpxPXMubGVuZ3RoCmlmKHI+PTApe3A9UC5QSShzLHIr
+MSxxLEMuVkMsITEpCnE9cn1lbHNlIHA9bgptPW8uYz1uZXcgUC5xZSgiZGF0YSIsIiIsbixuLFAuUEko
+cyxtLHEsQy5XZCwhMSkscCxuKX1yZXR1cm4gbX0sCnc6ZnVuY3Rpb24oYSl7dmFyIHMscj10aGlzLmIK
+aWYoMD49ci5sZW5ndGgpcmV0dXJuIEguT0gociwwKQpzPXRoaXMuYQpyZXR1cm4gclswXT09PS0xPyJk
+YXRhOiIrczpzfX0KUC55SS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciBzPXRoaXMuYQpp
+ZihhPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLGEpCnM9c1thXQpDLk5BLmR1KHMsMCw5NixiKQpyZXR1
+cm4gc30sCiRTOjIzfQpQLmM2LnByb3RvdHlwZT17CiQzOmZ1bmN0aW9uKGEsYixjKXt2YXIgcyxyLHEK
+Zm9yKHM9Yi5sZW5ndGgscj0wO3I8czsrK3Ipe3E9Qy54Qi5XKGIscileOTYKaWYocT49OTYpcmV0dXJu
+IEguT0goYSxxKQphW3FdPWN9fSwKJFM6MTN9ClAucWQucHJvdG90eXBlPXsKJDM6ZnVuY3Rpb24oYSxi
+LGMpe3ZhciBzLHIscQpmb3Iocz1DLnhCLlcoYiwwKSxyPUMueEIuVyhiLDEpO3M8PXI7KytzKXtxPShz
+Xjk2KT4+PjAKaWYocT49OTYpcmV0dXJuIEguT0goYSxxKQphW3FdPWN9fSwKJFM6MTN9ClAuVWYucHJv
+dG90eXBlPXsKZ2NqOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYz4wfSwKZ3hBOmZ1bmN0aW9uKCl7cmV0
+dXJuIHRoaXMuYz4wJiZ0aGlzLmQrMTx0aGlzLmV9LApnUUQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5m
+PHRoaXMucn0sCmdaODpmdW5jdGlvbigpe3JldHVybiB0aGlzLnI8dGhpcy5hLmxlbmd0aH0sCmdOdzpm
+dW5jdGlvbigpe3JldHVybiB0aGlzLmI9PT00JiZDLnhCLm5DKHRoaXMuYSwiZmlsZSIpfSwKZ1daOmZ1
+bmN0aW9uKCl7cmV0dXJuIHRoaXMuYj09PTQmJkMueEIubkModGhpcy5hLCJodHRwIil9LApnUmU6ZnVu
+Y3Rpb24oKXtyZXR1cm4gdGhpcy5iPT09NSYmQy54Qi5uQyh0aGlzLmEsImh0dHBzIil9LApndFQ6ZnVu
+Y3Rpb24oKXtyZXR1cm4gQy54Qi5RaSh0aGlzLmEsIi8iLHRoaXMuZSl9LApnRmk6ZnVuY3Rpb24oKXt2
+YXIgcz10aGlzLngKcmV0dXJuIHM9PW51bGw/dGhpcy54PXRoaXMuVTIoKTpzfSwKVTI6ZnVuY3Rpb24o
+KXt2YXIgcz10aGlzLHI9cy5iCmlmKHI8PTApcmV0dXJuIiIKaWYocy5nV1ooKSlyZXR1cm4iaHR0cCIK
+aWYocy5nUmUoKSlyZXR1cm4iaHR0cHMiCmlmKHMuZ053KCkpcmV0dXJuImZpbGUiCmlmKHI9PT03JiZD
+LnhCLm5DKHMuYSwicGFja2FnZSIpKXJldHVybiJwYWNrYWdlIgpyZXR1cm4gQy54Qi5OaihzLmEsMCxy
+KX0sCmdrdTpmdW5jdGlvbigpe3ZhciBzPXRoaXMuYyxyPXRoaXMuYiszCnJldHVybiBzPnI/Qy54Qi5O
+aih0aGlzLmEscixzLTEpOiIifSwKZ0pmOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuYwpyZXR1cm4gcz4w
+P0MueEIuTmoodGhpcy5hLHMsdGhpcy5kKToiIn0sCmd0cDpmdW5jdGlvbihhKXt2YXIgcz10aGlzCmlm
+KHMuZ3hBKCkpcmV0dXJuIFAuUUEoQy54Qi5OaihzLmEscy5kKzEscy5lKSxudWxsKQppZihzLmdXWigp
+KXJldHVybiA4MAppZihzLmdSZSgpKXJldHVybiA0NDMKcmV0dXJuIDB9LApnSWk6ZnVuY3Rpb24oYSl7
+cmV0dXJuIEMueEIuTmoodGhpcy5hLHRoaXMuZSx0aGlzLmYpfSwKZ3RQOmZ1bmN0aW9uKCl7dmFyIHM9
+dGhpcy5mLHI9dGhpcy5yCnJldHVybiBzPHI/Qy54Qi5Oaih0aGlzLmEscysxLHIpOiIifSwKZ0thOmZ1
+bmN0aW9uKCl7dmFyIHM9dGhpcy5yLHI9dGhpcy5hCnJldHVybiBzPHIubGVuZ3RoP0MueEIueW4ocixz
+KzEpOiIifSwKZ0ZqOmZ1bmN0aW9uKCl7dmFyIHMscixxPXRoaXMuZSxwPXRoaXMuZixvPXRoaXMuYQpp
+ZihDLnhCLlFpKG8sIi8iLHEpKSsrcQppZihxPT09cClyZXR1cm4gQy54RApzPUguVk0oW10sdC5zKQpm
+b3Iocj1xO3I8cDsrK3IpaWYoQy54Qi5PMihvLHIpPT09NDcpe0MuTm0uaShzLEMueEIuTmoobyxxLHIp
+KQpxPXIrMX1DLk5tLmkocyxDLnhCLk5qKG8scSxwKSkKcmV0dXJuIFAuQUYocyx0Lk4pfSwKZ2hZOmZ1
+bmN0aW9uKCl7aWYodGhpcy5mPj10aGlzLnIpcmV0dXJuIEMuQ00KcmV0dXJuIG5ldyBQLkdqKFAuV1go
+dGhpcy5ndFAoKSksdC5kdyl9LAprWDpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmQrMQpyZXR1cm4gcyth
+Lmxlbmd0aD09PXRoaXMuZSYmQy54Qi5RaSh0aGlzLmEsYSxzKX0sCk45OmZ1bmN0aW9uKCl7dmFyIHM9
+dGhpcyxyPXMucixxPXMuYQppZihyPj1xLmxlbmd0aClyZXR1cm4gcwpyZXR1cm4gbmV3IFAuVWYoQy54
+Qi5OaihxLDAscikscy5iLHMuYyxzLmQscy5lLHMuZixyLHMueCl9LApubTpmdW5jdGlvbihhLGIpe3Zh
+ciBzLHIscSxwLG8sbixtLGwsayxqLGk9dGhpcyxoPW51bGwKdC5jOS5hKGIpCnM9aS5nRmkoKQpyPXM9
+PT0iZmlsZSIKcT1pLmMKcD1xPjA/Qy54Qi5OaihpLmEsaS5iKzMscSk6IiIKbz1pLmd4QSgpP2kuZ3Rw
+KGkpOmgKcT1pLmMKaWYocT4wKW49Qy54Qi5OaihpLmEscSxpLmQpCmVsc2Ugbj1wLmxlbmd0aCE9PTB8
+fG8hPW51bGx8fHI/IiI6aApxPWkuYQptPUMueEIuTmoocSxpLmUsaS5mKQppZighcilsPW4hPW51bGwm
+Jm0ubGVuZ3RoIT09MAplbHNlIGw9ITAKaWYobCYmIUMueEIubkMobSwiLyIpKW09Ii8iK20Kaz1QLmxl
+KGgsMCwwLGIpCmw9aS5yCmo9bDxxLmxlbmd0aD9DLnhCLnluKHEsbCsxKTpoCnJldHVybiBuZXcgUC5E
+bihzLHAsbixvLG0sayxqKX0sClpJOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLm1TKFAuaEsoYSkpfSwK
+bVM6ZnVuY3Rpb24oYSl7aWYoYSBpbnN0YW5jZW9mIFAuVWYpcmV0dXJuIHRoaXMudTEodGhpcyxhKQpy
+ZXR1cm4gdGhpcy52cygpLm1TKGEpfSwKdTE6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbSxs
+LGssaixpLGgsZz1iLmIKaWYoZz4wKXJldHVybiBiCnM9Yi5jCmlmKHM+MCl7cj1hLmIKaWYocjw9MCly
+ZXR1cm4gYgppZihhLmdOdygpKXE9Yi5lIT09Yi5mCmVsc2UgaWYoYS5nV1ooKSlxPSFiLmtYKCI4MCIp
+CmVsc2UgcT0hYS5nUmUoKXx8IWIua1goIjQ0MyIpCmlmKHEpe3A9cisxCnJldHVybiBuZXcgUC5VZihD
+LnhCLk5qKGEuYSwwLHApK0MueEIueW4oYi5hLGcrMSkscixzK3AsYi5kK3AsYi5lK3AsYi5mK3AsYi5y
+K3AsYS54KX1lbHNlIHJldHVybiB0aGlzLnZzKCkubVMoYil9bz1iLmUKZz1iLmYKaWYobz09PWcpe3M9
+Yi5yCmlmKGc8cyl7cj1hLmYKcD1yLWcKcmV0dXJuIG5ldyBQLlVmKEMueEIuTmooYS5hLDAscikrQy54
+Qi55bihiLmEsZyksYS5iLGEuYyxhLmQsYS5lLGcrcCxzK3AsYS54KX1nPWIuYQppZihzPGcubGVuZ3Ro
+KXtyPWEucgpyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihhLmEsMCxyKStDLnhCLnluKGcscyksYS5iLGEu
+YyxhLmQsYS5lLGEuZixzKyhyLXMpLGEueCl9cmV0dXJuIGEuTjkoKX1zPWIuYQppZihDLnhCLlFpKHMs
+Ii8iLG8pKXtyPWEuZQpwPXItbwpyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihhLmEsMCxyKStDLnhCLnlu
+KHMsbyksYS5iLGEuYyxhLmQscixnK3AsYi5yK3AsYS54KX1uPWEuZQptPWEuZgppZihuPT09bSYmYS5j
+PjApe2Zvcig7Qy54Qi5RaShzLCIuLi8iLG8pOylvKz0zCnA9bi1vKzEKcmV0dXJuIG5ldyBQLlVmKEMu
+eEIuTmooYS5hLDAsbikrIi8iK0MueEIueW4ocyxvKSxhLmIsYS5jLGEuZCxuLGcrcCxiLnIrcCxhLngp
+fWw9YS5hCmZvcihrPW47Qy54Qi5RaShsLCIuLi8iLGspOylrKz0zCmo9MAp3aGlsZSghMCl7aT1vKzMK
+aWYoIShpPD1nJiZDLnhCLlFpKHMsIi4uLyIsbykpKWJyZWFrOysragpvPWl9Zm9yKGg9IiI7bT5rOyl7
+LS1tCmlmKEMueEIuTzIobCxtKT09PTQ3KXtpZihqPT09MCl7aD0iLyIKYnJlYWt9LS1qCmg9Ii8ifX1p
+ZihtPT09ayYmYS5iPD0wJiYhQy54Qi5RaShsLCIvIixuKSl7by09aiozCmg9IiJ9cD1tLW8raC5sZW5n
+dGgKcmV0dXJuIG5ldyBQLlVmKEMueEIuTmoobCwwLG0pK2grQy54Qi55bihzLG8pLGEuYixhLmMsYS5k
+LG4sZytwLGIucitwLGEueCl9LAp0NDpmdW5jdGlvbigpe3ZhciBzLHIscSxwPXRoaXMKaWYocC5iPj0w
+JiYhcC5nTncoKSl0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBh
+ICIrcC5nRmkoKSsiIFVSSSIpKQpzPXAuZgpyPXAuYQppZihzPHIubGVuZ3RoKXtpZihzPHAucil0aHJv
+dyBILmIoUC5MNCh1LmkpKQp0aHJvdyBILmIoUC5MNCh1LmwpKX1xPSQud1EoKQppZihILm9UKHEpKXM9
+UC5tbihwKQplbHNle2lmKHAuYzxwLmQpSC52KFAuTDQodS5qKSkKcz1DLnhCLk5qKHIscC5lLHMpfXJl
+dHVybiBzfSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMueQpyZXR1cm4gcz09bnVsbD90aGlzLnk9
+Qy54Qi5naU8odGhpcy5hKTpzfSwKRE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxsKXJldHVybiExCmlm
+KHRoaXM9PT1iKXJldHVybiEwCnJldHVybiB0LmRELmIoYikmJnRoaXMuYT09PWIudygwKX0sCnZzOmZ1
+bmN0aW9uKCl7dmFyIHM9dGhpcyxyPW51bGwscT1zLmdGaSgpLHA9cy5na3UoKSxvPXMuYz4wP3MuZ0pm
+KHMpOnIsbj1zLmd4QSgpP3MuZ3RwKHMpOnIsbT1zLmEsbD1zLmYsaz1DLnhCLk5qKG0scy5lLGwpLGo9
+cy5yCmw9bDxqP3MuZ3RQKCk6cgpyZXR1cm4gbmV3IFAuRG4ocSxwLG8sbixrLGwsajxtLmxlbmd0aD9z
+LmdLYSgpOnIpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfSwKJGlpRDoxfQpQLnFlLnByb3Rv
+dHlwZT17fQpXLnFFLnByb3RvdHlwZT17fQpXLkdoLnByb3RvdHlwZT17CnNMVTpmdW5jdGlvbihhLGIp
+e2EuaHJlZj1ifSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gU3RyaW5nKGEpfSwKJGlHaDoxfQpXLmZZLnBy
+b3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmluZyhhKX19ClcubkIucHJvdG90eXBlPXsk
+aW5COjF9ClcuQXoucHJvdG90eXBlPXskaUF6OjF9ClcuUVAucHJvdG90eXBlPXskaVFQOjF9Clcubngu
+cHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofX0KVy5vSi5wcm90b3R5cGU9
+ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpXLmlkLnByb3RvdHlwZT17fQpXLlFGLnBy
+b3RvdHlwZT17fQpXLk5oLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmluZyhhKX19
+ClcuYWUucHJvdG90eXBlPXsKRGM6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYS5jcmVhdGVIVE1MRG9jdW1l
+bnQoYil9fQpXLklCLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHMscj1hLmxlZnQKci50b1N0
+cmluZwpyPSJSZWN0YW5nbGUgKCIrSC5FaihyKSsiLCAiCnM9YS50b3AKcy50b1N0cmluZwpzPXIrSC5F
+aihzKSsiKSAiCnI9YS53aWR0aApyLnRvU3RyaW5nCnI9cytILkVqKHIpKyIgeCAiCnM9YS5oZWlnaHQK
+cy50b1N0cmluZwpyZXR1cm4gcitILkVqKHMpfSwKRE46ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCmlmKGI9
+PW51bGwpcmV0dXJuITEKaWYodC5xLmIoYikpe3M9YS5sZWZ0CnMudG9TdHJpbmcKcj1iLmxlZnQKci50
+b1N0cmluZwppZihzPT09cil7cz1hLnRvcApzLnRvU3RyaW5nCnI9Yi50b3AKci50b1N0cmluZwppZihz
+PT09cil7cz1hLndpZHRoCnMudG9TdHJpbmcKcj1iLndpZHRoCnIudG9TdHJpbmcKaWYocz09PXIpe3M9
+YS5oZWlnaHQKcy50b1N0cmluZwpyPWIuaGVpZ2h0CnIudG9TdHJpbmcKcj1zPT09cgpzPXJ9ZWxzZSBz
+PSExfWVsc2Ugcz0hMX1lbHNlIHM9ITF9ZWxzZSBzPSExCnJldHVybiBzfSwKZ2lPOmZ1bmN0aW9uKGEp
+e3ZhciBzLHIscSxwPWEubGVmdApwLnRvU3RyaW5nCnA9Qy5DRC5naU8ocCkKcz1hLnRvcApzLnRvU3Ry
+aW5nCnM9Qy5DRC5naU8ocykKcj1hLndpZHRoCnIudG9TdHJpbmcKcj1DLkNELmdpTyhyKQpxPWEuaGVp
+Z2h0CnEudG9TdHJpbmcKcmV0dXJuIFcuckUocCxzLHIsQy5DRC5naU8ocSkpfSwKJGl0bjoxfQpXLm43
+LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH19Clcud3oucHJvdG90eXBl
+PXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7dmFy
+IHMKSC51UChiKQpzPXRoaXMuYQppZihiPDB8fGI+PXMubGVuZ3RoKXJldHVybiBILk9IKHMsYikKcmV0
+dXJuIHRoaXMuJHRpLmMuYShzW2JdKX0sClk1OmZ1bmN0aW9uKGEsYixjKXt0aGlzLiR0aS5jLmEoYykK
+dGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBtb2RpZnkgbGlzdCIpKX19ClcuY3YucHJvdG90eXBlPXsKZ1Fn
+OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5pNyhhKX0sCmduOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcg
+Vy5JNChhKX0sCnNuOmZ1bmN0aW9uKGEsYil7dmFyIHMKdC5RLmEoYikKcz10aGlzLmduKGEpCnMuVjEo
+MCkKcy5GVigwLGIpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gYS5sb2NhbE5hbWV9LApGRjpmdW5jdGlv
+bihhKXt2YXIgcz0hIWEuc2Nyb2xsSW50b1ZpZXdJZk5lZWRlZAppZihzKWEuc2Nyb2xsSW50b1ZpZXdJ
+Zk5lZWRlZCgpCmVsc2UgYS5zY3JvbGxJbnRvVmlldygpfSwKbno6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2
+YXIgcyxyPXRoaXMucjYoYSxjLGQsZSkKc3dpdGNoKGIudG9Mb3dlckNhc2UoKSl7Y2FzZSJiZWZvcmVi
+ZWdpbiI6cz1hLnBhcmVudE5vZGUKcy50b1N0cmluZwpKLkVoKHMscixhKQpicmVhawpjYXNlImFmdGVy
+YmVnaW4iOnM9YS5jaGlsZE5vZGVzCnRoaXMubUsoYSxyLHMubGVuZ3RoPjA/c1swXTpudWxsKQpicmVh
+awpjYXNlImJlZm9yZWVuZCI6YS5hcHBlbmRDaGlsZChyKQpicmVhawpjYXNlImFmdGVyZW5kIjpzPWEu
+cGFyZW50Tm9kZQpzLnRvU3RyaW5nCkouRWgocyxyLGEubmV4dFNpYmxpbmcpCmJyZWFrCmRlZmF1bHQ6
+SC52KFAueFkoIkludmFsaWQgcG9zaXRpb24gIitiKSl9fSwKcjY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFy
+IHMscixxLHAKaWYoYz09bnVsbCl7aWYoZD09bnVsbCl7cz0kLmx0CmlmKHM9PW51bGwpe3M9SC5WTShb
+XSx0LnYpCnI9bmV3IFcudkQocykKQy5ObS5pKHMsVy5UdyhudWxsKSkKQy5ObS5pKHMsVy5CbCgpKQok
+Lmx0PXIKZD1yfWVsc2UgZD1zfXM9JC5FVQppZihzPT1udWxsKXtzPW5ldyBXLktvKGQpCiQuRVU9cwpj
+PXN9ZWxzZXtzLmE9ZApjPXN9fWVsc2UgaWYoZCE9bnVsbCl0aHJvdyBILmIoUC54WSgidmFsaWRhdG9y
+IGNhbiBvbmx5IGJlIHBhc3NlZCBpZiB0cmVlU2FuaXRpemVyIGlzIG51bGwiKSkKaWYoJC54bz09bnVs
+bCl7cz1kb2N1bWVudApyPXMuaW1wbGVtZW50YXRpb24Kci50b1N0cmluZwpyPUMubUguRGMociwiIikK
+JC54bz1yCiQuQk89ci5jcmVhdGVSYW5nZSgpCnI9JC54by5jcmVhdGVFbGVtZW50KCJiYXNlIikKdC5j
+Ui5hKHIpCnM9cy5iYXNlVVJJCnMudG9TdHJpbmcKci5ocmVmPXMKJC54by5oZWFkLmFwcGVuZENoaWxk
+KHIpfXM9JC54bwppZihzLmJvZHk9PW51bGwpe3I9cy5jcmVhdGVFbGVtZW50KCJib2R5IikKQy5CWi5z
+WEcocyx0LnAuYShyKSl9cz0kLnhvCmlmKHQucC5iKGEpKXtzPXMuYm9keQpzLnRvU3RyaW5nCnE9c31l
+bHNle3MudG9TdHJpbmcKcT1zLmNyZWF0ZUVsZW1lbnQoYS50YWdOYW1lKQokLnhvLmJvZHkuYXBwZW5k
+Q2hpbGQocSl9aWYoImNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudCIgaW4gd2luZG93LlJhbmdlLnByb3Rv
+dHlwZSYmIUMuTm0udGcoQy5TcSxhLnRhZ05hbWUpKXskLkJPLnNlbGVjdE5vZGVDb250ZW50cyhxKQpz
+PSQuQk8Kcy50b1N0cmluZwpwPXMuY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50KGI9PW51bGw/Im51bGwi
+OmIpfWVsc2V7Si53ZihxLGIpCnA9JC54by5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkKZm9yKDtzPXEu
+Zmlyc3RDaGlsZCxzIT1udWxsOylwLmFwcGVuZENoaWxkKHMpfWlmKHEhPT0kLnhvLmJvZHkpSi5MdChx
+KQpjLlBuKHApCmRvY3VtZW50LmFkb3B0Tm9kZShwKQpyZXR1cm4gcH0sCkFIOmZ1bmN0aW9uKGEsYixj
+KXtyZXR1cm4gdGhpcy5yNihhLGIsYyxudWxsKX0sCnNoZjpmdW5jdGlvbihhLGIpe3RoaXMuWUMoYSxi
+KX0sCnBrOmZ1bmN0aW9uKGEsYixjKXt0aGlzLnNhNChhLG51bGwpCmEuYXBwZW5kQ2hpbGQodGhpcy5y
+NihhLGIsbnVsbCxjKSl9LApZQzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLnBrKGEsYixudWxsKX0s
+CnNSTjpmdW5jdGlvbihhLGIpe2EuaW5uZXJIVE1MPWJ9LApnbnM6ZnVuY3Rpb24oYSl7cmV0dXJuIGEu
+dGFnTmFtZX0sCmdWbDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuZXUoYSwiY2xpY2siLCExLHQuayl9
+LAokaWN2OjF9ClcuQ3YucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHQuaC5iKHQuQS5h
+KGEpKX0sCiRTOjI1fQpXLmVhLnByb3RvdHlwZT17JGllYToxfQpXLkQwLnByb3RvdHlwZT17Ck9uOmZ1
+bmN0aW9uKGEsYixjLGQpe3QuYncuYShjKQppZihjIT1udWxsKXRoaXMudihhLGIsYyxkKX0sCkI6ZnVu
+Y3Rpb24oYSxiLGMpe3JldHVybiB0aGlzLk9uKGEsYixjLG51bGwpfSwKdjpmdW5jdGlvbihhLGIsYyxk
+KXtyZXR1cm4gYS5hZGRFdmVudExpc3RlbmVyKGIsSC50Uih0LmJ3LmEoYyksMSksZCl9LAokaUQwOjF9
+ClcuaEgucHJvdG90eXBlPXskaWhIOjF9ClcuaDQucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0
+dXJuIGEubGVuZ3RofX0KVy5ici5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5n
+dGh9fQpXLlZiLnByb3RvdHlwZT17CnNYRzpmdW5jdGlvbihhLGIpe2EuYm9keT1ifX0KVy5mSi5wcm90
+b3R5cGU9ewplbzpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gYS5vcGVuKGIsYywhMCl9LAokaWZKOjF9
+Clcud2EucHJvdG90eXBlPXt9ClcuU2cucHJvdG90eXBlPXskaVNnOjF9ClcudzcucHJvdG90eXBlPXsK
+Z0RyOmZ1bmN0aW9uKGEpe2lmKCJvcmlnaW4iIGluIGEpcmV0dXJuIGEub3JpZ2luCnJldHVybiBILkVq
+KGEucHJvdG9jb2wpKyIvLyIrSC5FaihhLmhvc3QpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gU3RyaW5n
+KGEpfSwKJGl3NzoxfQpXLkFqLnByb3RvdHlwZT17JGlBajoxfQpXLmU3LnByb3RvdHlwZT17CmdyODpm
+dW5jdGlvbihhKXt2YXIgcz10aGlzLmEscj1zLmNoaWxkTm9kZXMubGVuZ3RoCmlmKHI9PT0wKXRocm93
+IEguYihQLlBWKCJObyBlbGVtZW50cyIpKQppZihyPjEpdGhyb3cgSC5iKFAuUFYoIk1vcmUgdGhhbiBv
+bmUgZWxlbWVudCIpKQpzPXMuZmlyc3RDaGlsZApzLnRvU3RyaW5nCnJldHVybiBzfSwKRlY6ZnVuY3Rp
+b24oYSxiKXt2YXIgcyxyLHEscCxvCnQuZWguYShiKQppZihiIGluc3RhbmNlb2YgVy5lNyl7cz1iLmEK
+cj10aGlzLmEKaWYocyE9PXIpZm9yKHE9cy5jaGlsZE5vZGVzLmxlbmd0aCxwPTA7cDxxOysrcCl7bz1z
+LmZpcnN0Q2hpbGQKby50b1N0cmluZwpyLmFwcGVuZENoaWxkKG8pfXJldHVybn1mb3Iocz1iLmdtKGIp
+LHI9dGhpcy5hO3MuRigpOylyLmFwcGVuZENoaWxkKHMuZ2woKSl9LApZNTpmdW5jdGlvbihhLGIsYyl7
+dmFyIHMscgp0LkEuYShjKQpzPXRoaXMuYQpyPXMuY2hpbGROb2RlcwppZihiPDB8fGI+PXIubGVuZ3Ro
+KXJldHVybiBILk9IKHIsYikKcy5yZXBsYWNlQ2hpbGQoYyxyW2JdKX0sCmdtOmZ1bmN0aW9uKGEpe3Zh
+ciBzPXRoaXMuYS5jaGlsZE5vZGVzCnJldHVybiBuZXcgVy5XOShzLHMubGVuZ3RoLEgueihzKS5DKCJX
+OTxHbS5FPiIpKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuY2hpbGROb2Rlcy5sZW5ndGh9
+LApxOmZ1bmN0aW9uKGEsYil7dmFyIHMKSC51UChiKQpzPXRoaXMuYS5jaGlsZE5vZGVzCmlmKGI8MHx8
+Yj49cy5sZW5ndGgpcmV0dXJuIEguT0gocyxiKQpyZXR1cm4gc1tiXX19ClcudUgucHJvdG90eXBlPXsK
+d2c6ZnVuY3Rpb24oYSl7dmFyIHM9YS5wYXJlbnROb2RlCmlmKHMhPW51bGwpcy5yZW1vdmVDaGlsZChh
+KX0sCkQ0OmZ1bmN0aW9uKGEpe3ZhciBzCmZvcig7cz1hLmZpcnN0Q2hpbGQscyE9bnVsbDspYS5yZW1v
+dmVDaGlsZChzKX0sCnc6ZnVuY3Rpb24oYSl7dmFyIHM9YS5ub2RlVmFsdWUKcmV0dXJuIHM9PW51bGw/
+dGhpcy5VKGEpOnN9LApzYTQ6ZnVuY3Rpb24oYSxiKXthLnRleHRDb250ZW50PWJ9LAptSzpmdW5jdGlv
+bihhLGIsYyl7cmV0dXJuIGEuaW5zZXJ0QmVmb3JlKGIsYyl9LAokaXVIOjF9ClcuQkgucHJvdG90eXBl
+PXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0gudVAoYikK
+aWYoYj4+PjAhPT1ifHxiPj1hLmxlbmd0aCl0aHJvdyBILmIoUC5DZihiLGEsbnVsbCxudWxsLG51bGwp
+KQpyZXR1cm4gYVtiXX0sClk1OmZ1bmN0aW9uKGEsYixjKXt0LkEuYShjKQp0aHJvdyBILmIoUC5MNCgi
+Q2Fubm90IGFzc2lnbiBlbGVtZW50IG9mIGltbXV0YWJsZSBMaXN0LiIpKX0sCmd0SDpmdW5jdGlvbihh
+KXtpZihhLmxlbmd0aD4wKXJldHVybiBhWzBdCnRocm93IEguYihQLlBWKCJObyBlbGVtZW50cyIpKX0s
+CkU6ZnVuY3Rpb24oYSxiKXtpZihiPDB8fGI+PWEubGVuZ3RoKXJldHVybiBILk9IKGEsYikKcmV0dXJu
+IGFbYl19LAokaWJROjEsCiRpWGo6MSwKJGljWDoxLAokaXpNOjF9ClcuU04ucHJvdG90eXBlPXt9Clcu
+ZXcucHJvdG90eXBlPXskaWV3OjF9ClcubHAucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJu
+IGEubGVuZ3RofX0KVy5UYi5wcm90b3R5cGU9ewpyNjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyCmlm
+KCJjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQiIGluIHdpbmRvdy5SYW5nZS5wcm90b3R5cGUpcmV0dXJu
+IHRoaXMuRFcoYSxiLGMsZCkKcz1XLlU5KCI8dGFibGU+IitILkVqKGIpKyI8L3RhYmxlPiIsYyxkKQpy
+PWRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKQpyLnRvU3RyaW5nCnMudG9TdHJpbmcKbmV3
+IFcuZTcocikuRlYoMCxuZXcgVy5lNyhzKSkKcmV0dXJuIHJ9fQpXLkl2LnByb3RvdHlwZT17CnI2OmZ1
+bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIscSxwCmlmKCJjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQiIGlu
+IHdpbmRvdy5SYW5nZS5wcm90b3R5cGUpcmV0dXJuIHRoaXMuRFcoYSxiLGMsZCkKcz1kb2N1bWVudApy
+PXMuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpCnM9Qy5JZS5yNihzLmNyZWF0ZUVsZW1lbnQoInRhYmxl
+IiksYixjLGQpCnMudG9TdHJpbmcKcz1uZXcgVy5lNyhzKQpxPXMuZ3I4KHMpCnEudG9TdHJpbmcKcz1u
+ZXcgVy5lNyhxKQpwPXMuZ3I4KHMpCnIudG9TdHJpbmcKcC50b1N0cmluZwpuZXcgVy5lNyhyKS5GVigw
+LG5ldyBXLmU3KHApKQpyZXR1cm4gcn19ClcuV1AucHJvdG90eXBlPXsKcjY6ZnVuY3Rpb24oYSxiLGMs
+ZCl7dmFyIHMscixxCmlmKCJjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQiIGluIHdpbmRvdy5SYW5nZS5w
+cm90b3R5cGUpcmV0dXJuIHRoaXMuRFcoYSxiLGMsZCkKcz1kb2N1bWVudApyPXMuY3JlYXRlRG9jdW1l
+bnRGcmFnbWVudCgpCnM9Qy5JZS5yNihzLmNyZWF0ZUVsZW1lbnQoInRhYmxlIiksYixjLGQpCnMudG9T
+dHJpbmcKcz1uZXcgVy5lNyhzKQpxPXMuZ3I4KHMpCnIudG9TdHJpbmcKcS50b1N0cmluZwpuZXcgVy5l
+NyhyKS5GVigwLG5ldyBXLmU3KHEpKQpyZXR1cm4gcn19ClcueVkucHJvdG90eXBlPXsKcGs6ZnVuY3Rp
+b24oYSxiLGMpe3ZhciBzLHIKdGhpcy5zYTQoYSxudWxsKQpzPWEuY29udGVudApzLnRvU3RyaW5nCkou
+YlQocykKcj10aGlzLnI2KGEsYixudWxsLGMpCmEuY29udGVudC5hcHBlbmRDaGlsZChyKX0sCllDOmZ1
+bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMucGsoYSxiLG51bGwpfSwKJGl5WToxfQpXLnc2LnByb3RvdHlw
+ZT17fQpXLks1LnByb3RvdHlwZT17ClBvOmZ1bmN0aW9uKGEsYixjKXt2YXIgcz1XLlAxKGEub3Blbihi
+LGMpKQpyZXR1cm4gc30sCmdtVzpmdW5jdGlvbihhKXtyZXR1cm4gYS5sb2NhdGlvbn0sCnVzOmZ1bmN0
+aW9uKGEsYil7cmV0dXJuIGEuY29uZmlybShiKX0sCiRpSzU6MSwKJGl2NjoxfQpXLkNtLnByb3RvdHlw
+ZT17JGlDbToxfQpXLkNRLnByb3RvdHlwZT17JGlDUToxfQpXLnc0LnByb3RvdHlwZT17Cnc6ZnVuY3Rp
+b24oYSl7dmFyIHMscj1hLmxlZnQKci50b1N0cmluZwpyPSJSZWN0YW5nbGUgKCIrSC5FaihyKSsiLCAi
+CnM9YS50b3AKcy50b1N0cmluZwpzPXIrSC5FaihzKSsiKSAiCnI9YS53aWR0aApyLnRvU3RyaW5nCnI9
+cytILkVqKHIpKyIgeCAiCnM9YS5oZWlnaHQKcy50b1N0cmluZwpyZXR1cm4gcitILkVqKHMpfSwKRE46
+ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCmlmKGI9PW51bGwpcmV0dXJuITEKaWYodC5xLmIoYikpe3M9YS5s
+ZWZ0CnMudG9TdHJpbmcKcj1iLmxlZnQKci50b1N0cmluZwppZihzPT09cil7cz1hLnRvcApzLnRvU3Ry
+aW5nCnI9Yi50b3AKci50b1N0cmluZwppZihzPT09cil7cz1hLndpZHRoCnMudG9TdHJpbmcKcj1iLndp
+ZHRoCnIudG9TdHJpbmcKaWYocz09PXIpe3M9YS5oZWlnaHQKcy50b1N0cmluZwpyPWIuaGVpZ2h0CnIu
+dG9TdHJpbmcKcj1zPT09cgpzPXJ9ZWxzZSBzPSExfWVsc2Ugcz0hMX1lbHNlIHM9ITF9ZWxzZSBzPSEx
+CnJldHVybiBzfSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwPWEubGVmdApwLnRvU3RyaW5nCnA9
+Qy5DRC5naU8ocCkKcz1hLnRvcApzLnRvU3RyaW5nCnM9Qy5DRC5naU8ocykKcj1hLndpZHRoCnIudG9T
+dHJpbmcKcj1DLkNELmdpTyhyKQpxPWEuaGVpZ2h0CnEudG9TdHJpbmcKcmV0dXJuIFcuckUocCxzLHIs
+Qy5DRC5naU8ocSkpfX0KVy5yaC5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5n
+dGh9LApxOmZ1bmN0aW9uKGEsYil7SC51UChiKQppZihiPj4+MCE9PWJ8fGI+PWEubGVuZ3RoKXRocm93
+IEguYihQLkNmKGIsYSxudWxsLG51bGwsbnVsbCkpCnJldHVybiBhW2JdfSwKWTU6ZnVuY3Rpb24oYSxi
+LGMpe3QuQS5hKGMpCnRocm93IEguYihQLkw0KCJDYW5ub3QgYXNzaWduIGVsZW1lbnQgb2YgaW1tdXRh
+YmxlIExpc3QuIikpfSwKRTpmdW5jdGlvbihhLGIpe2lmKGI8MHx8Yj49YS5sZW5ndGgpcmV0dXJuIEgu
+T0goYSxiKQpyZXR1cm4gYVtiXX0sCiRpYlE6MSwKJGlYajoxLAokaWNYOjEsCiRpek06MX0KVy5jZi5w
+cm90b3R5cGU9ewpLOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbwp0LmVBLmEoYikKZm9yKHM9dGhp
+cy5ndmMoKSxyPXMubGVuZ3RoLHE9dGhpcy5hLHA9MDtwPHMubGVuZ3RoO3MubGVuZ3RoPT09cnx8KDAs
+SC5saykocyksKytwKXtvPXNbcF0KYi4kMihvLHEuZ2V0QXR0cmlidXRlKG8pKX19LApndmM6ZnVuY3Rp
+b24oKXt2YXIgcyxyLHEscCxvLG4sbT10aGlzLmEuYXR0cmlidXRlcwptLnRvU3RyaW5nCnM9SC5WTShb
+XSx0LnMpCmZvcihyPW0ubGVuZ3RoLHE9dC5oOSxwPTA7cDxyOysrcCl7aWYocD49bS5sZW5ndGgpcmV0
+dXJuIEguT0gobSxwKQpvPXEuYShtW3BdKQppZihvLm5hbWVzcGFjZVVSST09bnVsbCl7bj1vLm5hbWUK
+bi50b1N0cmluZwpDLk5tLmkocyxuKX19cmV0dXJuIHN9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRo
+aXMuZ3ZjKCkubGVuZ3RoPT09MH19ClcuaTcucHJvdG90eXBlPXsKeDQ6ZnVuY3Rpb24oYSl7dmFyIHM9
+SC5vVCh0aGlzLmEuaGFzQXR0cmlidXRlKGEpKQpyZXR1cm4gc30sCnE6ZnVuY3Rpb24oYSxiKXtyZXR1
+cm4gdGhpcy5hLmdldEF0dHJpYnV0ZShILmgoYikpfSwKWTU6ZnVuY3Rpb24oYSxiLGMpe3RoaXMuYS5z
+ZXRBdHRyaWJ1dGUoYixjKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmd2YygpLmxlbmd0aH19
+ClcuU3kucHJvdG90eXBlPXsKeDQ6ZnVuY3Rpb24oYSl7dmFyIHM9SC5vVCh0aGlzLmEuYS5oYXNBdHRy
+aWJ1dGUoImRhdGEtIit0aGlzLlAoYSkpKQpyZXR1cm4gc30sCnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4g
+dGhpcy5hLmEuZ2V0QXR0cmlidXRlKCJkYXRhLSIrdGhpcy5QKEguaChiKSkpfSwKWTU6ZnVuY3Rpb24o
+YSxiLGMpe3RoaXMuYS5hLnNldEF0dHJpYnV0ZSgiZGF0YS0iK3RoaXMuUChiKSxjKX0sCks6ZnVuY3Rp
+b24oYSxiKXt0aGlzLmEuSygwLG5ldyBXLktTKHRoaXMsdC5lQS5hKGIpKSl9LApndmM6ZnVuY3Rpb24o
+KXt2YXIgcz1ILlZNKFtdLHQucykKdGhpcy5hLksoMCxuZXcgVy5BMyh0aGlzLHMpKQpyZXR1cm4gc30s
+CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmd2YygpLmxlbmd0aH0sCmdsMDpmdW5jdGlvbihhKXty
+ZXR1cm4gdGhpcy5ndmMoKS5sZW5ndGg9PT0wfSwKeHE6ZnVuY3Rpb24oYSl7dmFyIHMscixxPUguVk0o
+YS5zcGxpdCgiLSIpLHQucykKZm9yKHM9MTtzPHEubGVuZ3RoOysrcyl7cj1xW3NdCmlmKHIubGVuZ3Ro
+PjApQy5ObS5ZNShxLHMsclswXS50b1VwcGVyQ2FzZSgpK0ouS1YociwxKSl9cmV0dXJuIEMuTm0uayhx
+LCIiKX0sClA6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbwpmb3Iocz1hLmxlbmd0aCxyPTAscT0iIjty
+PHM7KytyKXtwPWFbcl0Kbz1wLnRvTG93ZXJDYXNlKCkKcT0ocCE9PW8mJnI+MD9xKyItIjpxKStvfXJl
+dHVybiBxLmNoYXJDb2RlQXQoMCk9PTA/cTpxfX0KVy5LUy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihh
+LGIpe2lmKEouclkoYSkubkMoYSwiZGF0YS0iKSl0aGlzLmIuJDIodGhpcy5hLnhxKEMueEIueW4oYSw1
+KSksYil9LAokUzoxNH0KVy5BMy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe2lmKEouclkoYSku
+bkMoYSwiZGF0YS0iKSlDLk5tLmkodGhpcy5iLHRoaXMuYS54cShDLnhCLnluKGEsNSkpKX0sCiRTOjE0
+fQpXLkk0LnByb3RvdHlwZT17CkQ6ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvPVAuTHModC5OKQpmb3Io
+cz10aGlzLmEuY2xhc3NOYW1lLnNwbGl0KCIgIikscj1zLmxlbmd0aCxxPTA7cTxyOysrcSl7cD1KLlQw
+KHNbcV0pCmlmKHAubGVuZ3RoIT09MClvLmkoMCxwKX1yZXR1cm4gb30sClg6ZnVuY3Rpb24oYSl7dGhp
+cy5hLmNsYXNzTmFtZT10LkMuYShhKS5rKDAsIiAiKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlz
+LmEuY2xhc3NMaXN0Lmxlbmd0aH0sCmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmNsYXNzTGlz
+dC5sZW5ndGg9PT0wfSwKZ29yOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuY2xhc3NMaXN0Lmxlbmd0
+aCE9PTB9LApWMTpmdW5jdGlvbihhKXt0aGlzLmEuY2xhc3NOYW1lPSIifSwKdGc6ZnVuY3Rpb24oYSxi
+KXt2YXIgcz10aGlzLmEuY2xhc3NMaXN0LmNvbnRhaW5zKGIpCnJldHVybiBzfSwKaTpmdW5jdGlvbihh
+LGIpe3ZhciBzLHIKSC5oKGIpCnM9dGhpcy5hLmNsYXNzTGlzdApyPXMuY29udGFpbnMoYikKcy5hZGQo
+YikKcmV0dXJuIXJ9LApMOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxCmlmKHR5cGVvZiBiPT0ic3RyaW5n
+Iil7cz10aGlzLmEuY2xhc3NMaXN0CnI9cy5jb250YWlucyhiKQpzLnJlbW92ZShiKQpxPXJ9ZWxzZSBx
+PSExCnJldHVybiBxfSwKRlY6ZnVuY3Rpb24oYSxiKXtXLlROKHRoaXMuYSx0LlEuYShiKSl9fQpXLkZr
+LnByb3RvdHlwZT17fQpXLlJPLnByb3RvdHlwZT17fQpXLmV1LnByb3RvdHlwZT17fQpXLnhDLnByb3Rv
+dHlwZT17fQpXLnZOLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuJDEodC5C
+LmEoYSkpfSwKJFM6Mjd9ClcuSlEucHJvdG90eXBlPXsKQ1k6ZnVuY3Rpb24oYSl7dmFyIHMKaWYoJC5v
+ci5hPT09MCl7Zm9yKHM9MDtzPDI2MjsrK3MpJC5vci5ZNSgwLEMuY21bc10sVy5wUygpKQpmb3Iocz0w
+O3M8MTI7KytzKSQub3IuWTUoMCxDLkJJW3NdLFcuVjQoKSl9fSwKaTA6ZnVuY3Rpb24oYSl7cmV0dXJu
+ICQuQU4oKS50ZygwLFcuclMoYSkpfSwKRWI6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPSQub3IucSgwLEgu
+RWooVy5yUyhhKSkrIjo6IitiKQppZihzPT1udWxsKXM9JC5vci5xKDAsIio6OiIrYikKaWYocz09bnVs
+bClyZXR1cm4hMQpyZXR1cm4gSC55OChzLiQ0KGEsYixjLHRoaXMpKX0sCiRpa0Y6MX0KVy5HbS5wcm90
+b3R5cGU9ewpnbTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuVzkoYSx0aGlzLmdBKGEpLEgueihhKS5D
+KCJXOTxHbS5FPiIpKX19ClcudkQucHJvdG90eXBlPXsKaTA6ZnVuY3Rpb24oYSl7cmV0dXJuIEMuTm0u
+VnIodGhpcy5hLG5ldyBXLlV2KGEpKX0sCkViOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gQy5ObS5Wcih0
+aGlzLmEsbmV3IFcuRWcoYSxiLGMpKX0sCiRpa0Y6MX0KVy5Vdi5wcm90b3R5cGU9ewokMTpmdW5jdGlv
+bihhKXtyZXR1cm4gdC5mNi5hKGEpLmkwKHRoaXMuYSl9LAokUzoxNX0KVy5FZy5wcm90b3R5cGU9ewok
+MTpmdW5jdGlvbihhKXtyZXR1cm4gdC5mNi5hKGEpLkViKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX0sCiRT
+OjE1fQpXLm02LnByb3RvdHlwZT17CkNZOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBzLHIscQp0aGlzLmEu
+RlYoMCxjKQpzPWIuZXYoMCxuZXcgVy5FbygpKQpyPWIuZXYoMCxuZXcgVy5XaygpKQp0aGlzLmIuRlYo
+MCxzKQpxPXRoaXMuYwpxLkZWKDAsQy54RCkKcS5GVigwLHIpfSwKaTA6ZnVuY3Rpb24oYSl7cmV0dXJu
+IHRoaXMuYS50ZygwLFcuclMoYSkpfSwKRWI6ZnVuY3Rpb24oYSxiLGMpe3ZhciBzPXRoaXMscj1XLnJT
+KGEpLHE9cy5jCmlmKHEudGcoMCxILkVqKHIpKyI6OiIrYikpcmV0dXJuIHMuZC5EdChjKQplbHNlIGlm
+KHEudGcoMCwiKjo6IitiKSlyZXR1cm4gcy5kLkR0KGMpCmVsc2V7cT1zLmIKaWYocS50ZygwLEguRWoo
+cikrIjo6IitiKSlyZXR1cm4hMAplbHNlIGlmKHEudGcoMCwiKjo6IitiKSlyZXR1cm4hMAplbHNlIGlm
+KHEudGcoMCxILkVqKHIpKyI6OioiKSlyZXR1cm4hMAplbHNlIGlmKHEudGcoMCwiKjo6KiIpKXJldHVy
+biEwfXJldHVybiExfSwKJGlrRjoxfQpXLkVvLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVy
+biFDLk5tLnRnKEMuQkksSC5oKGEpKX0sCiRTOjZ9ClcuV2sucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24o
+YSl7cmV0dXJuIEMuTm0udGcoQy5CSSxILmgoYSkpfSwKJFM6Nn0KVy5jdC5wcm90b3R5cGU9ewpFYjpm
+dW5jdGlvbihhLGIsYyl7aWYodGhpcy5qRihhLGIsYykpcmV0dXJuITAKaWYoYj09PSJ0ZW1wbGF0ZSIm
+JmM9PT0iIilyZXR1cm4hMAppZihhLmdldEF0dHJpYnV0ZSgidGVtcGxhdGUiKT09PSIiKXJldHVybiB0
+aGlzLmUudGcoMCxiKQpyZXR1cm4hMX19ClcuSUEucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0
+dXJuIlRFTVBMQVRFOjoiK0guRWooSC5oKGEpKX0sCiRTOjV9ClcuT3cucHJvdG90eXBlPXsKaTA6ZnVu
+Y3Rpb24oYSl7dmFyIHMKaWYodC5ldy5iKGEpKXJldHVybiExCnM9dC5nNy5iKGEpCmlmKHMmJlcuclMo
+YSk9PT0iZm9yZWlnbk9iamVjdCIpcmV0dXJuITEKaWYocylyZXR1cm4hMApyZXR1cm4hMX0sCkViOmZ1
+bmN0aW9uKGEsYixjKXtpZihiPT09ImlzInx8Qy54Qi5uQyhiLCJvbiIpKXJldHVybiExCnJldHVybiB0
+aGlzLmkwKGEpfSwKJGlrRjoxfQpXLlc5LnByb3RvdHlwZT17CkY6ZnVuY3Rpb24oKXt2YXIgcz10aGlz
+LHI9cy5jKzEscT1zLmIKaWYocjxxKXtzLnNwKEoueDkocy5hLHIpKQpzLmM9cgpyZXR1cm4hMH1zLnNw
+KG51bGwpCnMuYz1xCnJldHVybiExfSwKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKc3A6ZnVu
+Y3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLkMoIjE/IikuYShhKX0sCiRpQW46MX0KVy5kVy5wcm90b3R5
+cGU9eyRpRDA6MSwkaXY2OjF9ClcubWsucHJvdG90eXBlPXskaXkwOjF9ClcuS28ucHJvdG90eXBlPXsK
+UG46ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcyxyPW5ldyBXLmZtKHMpCnMuYj0hMQpyLiQyKGEsbnVsbCkK
+Zm9yKDtzLmI7KXtzLmI9ITEKci4kMihhLG51bGwpfX0sCkVQOmZ1bmN0aW9uKGEsYil7dmFyIHM9dGhp
+cy5iPSEwCmlmKGIhPW51bGw/YiE9PWEucGFyZW50Tm9kZTpzKUouTHQoYSkKZWxzZSBiLnJlbW92ZUNo
+aWxkKGEpfSwKSTQ6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG49ITAsbT1udWxsLGw9bnVsbAp0
+cnl7bT1KLmlnKGEpCmw9bS5hLmdldEF0dHJpYnV0ZSgiaXMiKQp0LmguYShhKQpzPWZ1bmN0aW9uKGMp
+e2lmKCEoYy5hdHRyaWJ1dGVzIGluc3RhbmNlb2YgTmFtZWROb2RlTWFwKSlyZXR1cm4gdHJ1ZQppZihj
+LmlkPT0nbGFzdENoaWxkJ3x8Yy5uYW1lPT0nbGFzdENoaWxkJ3x8Yy5pZD09J3ByZXZpb3VzU2libGlu
+Zyd8fGMubmFtZT09J3ByZXZpb3VzU2libGluZyd8fGMuaWQ9PSdjaGlsZHJlbid8fGMubmFtZT09J2No
+aWxkcmVuJylyZXR1cm4gdHJ1ZQp2YXIgaz1jLmNoaWxkTm9kZXMKaWYoYy5sYXN0Q2hpbGQmJmMubGFz
+dENoaWxkIT09a1trLmxlbmd0aC0xXSlyZXR1cm4gdHJ1ZQppZihjLmNoaWxkcmVuKWlmKCEoYy5jaGls
+ZHJlbiBpbnN0YW5jZW9mIEhUTUxDb2xsZWN0aW9ufHxjLmNoaWxkcmVuIGluc3RhbmNlb2YgTm9kZUxp
+c3QpKXJldHVybiB0cnVlCnZhciBqPTAKaWYoYy5jaGlsZHJlbilqPWMuY2hpbGRyZW4ubGVuZ3RoCmZv
+cih2YXIgaT0wO2k8ajtpKyspe3ZhciBoPWMuY2hpbGRyZW5baV0KaWYoaC5pZD09J2F0dHJpYnV0ZXMn
+fHxoLm5hbWU9PSdhdHRyaWJ1dGVzJ3x8aC5pZD09J2xhc3RDaGlsZCd8fGgubmFtZT09J2xhc3RDaGls
+ZCd8fGguaWQ9PSdwcmV2aW91c1NpYmxpbmcnfHxoLm5hbWU9PSdwcmV2aW91c1NpYmxpbmcnfHxoLmlk
+PT0nY2hpbGRyZW4nfHxoLm5hbWU9PSdjaGlsZHJlbicpcmV0dXJuIHRydWV9cmV0dXJuIGZhbHNlfShh
+KQpuPUgub1Qocyk/ITA6IShhLmF0dHJpYnV0ZXMgaW5zdGFuY2VvZiBOYW1lZE5vZGVNYXApfWNhdGNo
+KHApe0guUnUocCl9cj0iZWxlbWVudCB1bnByaW50YWJsZSIKdHJ5e3I9Si5qKGEpfWNhdGNoKHApe0gu
+UnUocCl9dHJ5e3E9Vy5yUyhhKQp0aGlzLmtSKHQuaC5hKGEpLGIsbixyLHEsdC5mLmEobSksSC5rKGwp
+KX1jYXRjaChwKXtpZihILlJ1KHApIGluc3RhbmNlb2YgUC51KXRocm93IHAKZWxzZXt0aGlzLkVQKGEs
+YikKd2luZG93Cm89IlJlbW92aW5nIGNvcnJ1cHRlZCBlbGVtZW50ICIrSC5FaihyKQppZih0eXBlb2Yg
+Y29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUud2FybihvKX19fSwKa1I6ZnVuY3Rpb24o
+YSxiLGMsZCxlLGYsZyl7dmFyIHMscixxLHAsbyxuLG09dGhpcwppZihjKXttLkVQKGEsYikKd2luZG93
+CnM9IlJlbW92aW5nIGVsZW1lbnQgZHVlIHRvIGNvcnJ1cHRlZCBhdHRyaWJ1dGVzIG9uIDwiK2QrIj4i
+CmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS53YXJuKHMpCnJldHVy
+bn1pZighbS5hLmkwKGEpKXttLkVQKGEsYikKd2luZG93CnM9IlJlbW92aW5nIGRpc2FsbG93ZWQgZWxl
+bWVudCA8IitILkVqKGUpKyI+IGZyb20gIitILkVqKGIpCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZp
+bmVkIil3aW5kb3cuY29uc29sZS53YXJuKHMpCnJldHVybn1pZihnIT1udWxsKWlmKCFtLmEuRWIoYSwi
+aXMiLGcpKXttLkVQKGEsYikKd2luZG93CnM9IlJlbW92aW5nIGRpc2FsbG93ZWQgdHlwZSBleHRlbnNp
+b24gPCIrSC5FaihlKSsnIGlzPSInK2crJyI+JwppZih0eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIp
+d2luZG93LmNvbnNvbGUud2FybihzKQpyZXR1cm59cz1mLmd2YygpCnI9SC5WTShzLnNsaWNlKDApLEgu
+dDYocykpCmZvcihxPWYuZ3ZjKCkubGVuZ3RoLTEscz1mLmE7cT49MDstLXEpe2lmKHE+PXIubGVuZ3Ro
+KXJldHVybiBILk9IKHIscSkKcD1yW3FdCm89bS5hCm49Si5jSChwKQpILmgocCkKaWYoIW8uRWIoYSxu
+LHMuZ2V0QXR0cmlidXRlKHApKSl7d2luZG93Cm89IlJlbW92aW5nIGRpc2FsbG93ZWQgYXR0cmlidXRl
+IDwiK0guRWooZSkrIiAiK3ArJz0iJytILkVqKHMuZ2V0QXR0cmlidXRlKHApKSsnIj4nCmlmKHR5cGVv
+ZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS53YXJuKG8pCnMucmVtb3ZlQXR0cmli
+dXRlKHApfX1pZih0LmFXLmIoYSkpe3M9YS5jb250ZW50CnMudG9TdHJpbmcKbS5QbihzKX19LAokaW9u
+OjF9ClcuZm0ucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyLHEscCxvLG4sbT10aGlz
+LmEKc3dpdGNoKGEubm9kZVR5cGUpe2Nhc2UgMTptLkk0KGEsYikKYnJlYWsKY2FzZSA4OmNhc2UgMTE6
+Y2FzZSAzOmNhc2UgNDpicmVhawpkZWZhdWx0Om0uRVAoYSxiKX1zPWEubGFzdENoaWxkCmZvcihxPXQu
+QTtudWxsIT1zOyl7cj1udWxsCnRyeXtyPXMucHJldmlvdXNTaWJsaW5nCmlmKHIhPW51bGwpe3A9ci5u
+ZXh0U2libGluZwpvPXMKbz1wPT1udWxsP28hPW51bGw6cCE9PW8KcD1vfWVsc2UgcD0hMQppZihwKXtw
+PVAuUFYoIkNvcnJ1cHQgSFRNTCIpCnRocm93IEguYihwKX19Y2F0Y2gobil7SC5SdShuKQpwPXEuYShz
+KQptLmI9ITAKbz1wLnBhcmVudE5vZGUKbz1hPT1udWxsP28hPW51bGw6YSE9PW8KaWYobyl7bz1wLnBh
+cmVudE5vZGUKaWYobyE9bnVsbClvLnJlbW92ZUNoaWxkKHApfWVsc2UgYS5yZW1vdmVDaGlsZChwKQpz
+PW51bGwKcj1hLmxhc3RDaGlsZH1pZihzIT1udWxsKXRoaXMuJDIocyxhKQpzPXJ9fSwKJFM6MzB9Clcu
+TGUucHJvdG90eXBlPXt9ClcuSzcucHJvdG90eXBlPXt9ClcuckIucHJvdG90eXBlPXt9ClcuWFcucHJv
+dG90eXBlPXt9Clcub2EucHJvdG90eXBlPXt9ClAuaUoucHJvdG90eXBlPXsKVkg6ZnVuY3Rpb24oYSl7
+dmFyIHMscj10aGlzLmEscT1yLmxlbmd0aApmb3Iocz0wO3M8cTsrK3MpaWYocltzXT09PWEpcmV0dXJu
+IHMKQy5ObS5pKHIsYSkKQy5ObS5pKHRoaXMuYixudWxsKQpyZXR1cm4gcX0sClB2OmZ1bmN0aW9uKGEp
+e3ZhciBzLHIscSxwPXRoaXMsbz17fQppZihhPT1udWxsKXJldHVybiBhCmlmKEgubChhKSlyZXR1cm4g
+YQppZih0eXBlb2YgYT09Im51bWJlciIpcmV0dXJuIGEKaWYodHlwZW9mIGE9PSJzdHJpbmciKXJldHVy
+biBhCmlmKGEgaW5zdGFuY2VvZiBQLmlQKXJldHVybiBuZXcgRGF0ZShhLmEpCmlmKHQuZnYuYihhKSl0
+aHJvdyBILmIoUC5TWSgic3RydWN0dXJlZCBjbG9uZSBvZiBSZWdFeHAiKSkKaWYodC5jOC5iKGEpKXJl
+dHVybiBhCmlmKHQudy5iKGEpKXJldHVybiBhCmlmKHQuSS5iKGEpKXJldHVybiBhCnM9dC5kRS5iKGEp
+fHwhMQppZihzKXJldHVybiBhCmlmKHQuZi5iKGEpKXtyPXAuVkgoYSkKcz1wLmIKaWYocj49cy5sZW5n
+dGgpcmV0dXJuIEguT0gocyxyKQpxPW8uYT1zW3JdCmlmKHEhPW51bGwpcmV0dXJuIHEKcT17fQpvLmE9
+cQpDLk5tLlk1KHMscixxKQphLksoMCxuZXcgUC5qZyhvLHApKQpyZXR1cm4gby5hfWlmKHQuai5iKGEp
+KXtyPXAuVkgoYSkKbz1wLmIKaWYocj49by5sZW5ndGgpcmV0dXJuIEguT0gobyxyKQpxPW9bcl0KaWYo
+cSE9bnVsbClyZXR1cm4gcQpyZXR1cm4gcC5layhhLHIpfWlmKHQuZUguYihhKSl7cj1wLlZIKGEpCnM9
+cC5iCmlmKHI+PXMubGVuZ3RoKXJldHVybiBILk9IKHMscikKcT1vLmI9c1tyXQppZihxIT1udWxsKXJl
+dHVybiBxCnE9e30Kby5iPXEKQy5ObS5ZNShzLHIscSkKcC5pbShhLG5ldyBQLlRhKG8scCkpCnJldHVy
biBvLmJ9dGhyb3cgSC5iKFAuU1koInN0cnVjdHVyZWQgY2xvbmUgb2Ygb3RoZXIgdHlwZSIpKX0sCmVr
OmZ1bmN0aW9uKGEsYil7dmFyIHMscj1KLlU2KGEpLHE9ci5nQShhKSxwPW5ldyBBcnJheShxKQpDLk5t
-LlkodGhpcy5iLGIscCkKZm9yKHM9MDtzPHE7KytzKUMuTm0uWShwLHMsdGhpcy5QdihyLnEoYSxzKSkp
-CnJldHVybiBwfX0KUC5qZy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3RoaXMuYS5hW2FdPXRo
-aXMuYi5QdihiKX0sCiRTOjMxfQpQLlRhLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhpcy5h
-LmJbYV09dGhpcy5iLlB2KGIpfSwKJFM6MTZ9ClAuQmYucHJvdG90eXBlPXsKaW06ZnVuY3Rpb24oYSxi
-KXt2YXIgcyxyLHEscAp0LmI4LmEoYikKZm9yKHM9T2JqZWN0LmtleXMoYSkscj1zLmxlbmd0aCxxPTA7
-cTxyOysrcSl7cD1zW3FdCmIuJDIocCxhW3BdKX19fQpQLkFzLnByb3RvdHlwZT17ClQ6ZnVuY3Rpb24o
-YSl7dmFyIHMKSC5oKGEpCnM9JC5oRygpLmIKaWYodHlwZW9mIGEhPSJzdHJpbmciKUgudihILnRMKGEp
-KQppZihzLnRlc3QoYSkpcmV0dXJuIGEKdGhyb3cgSC5iKFAuTDMoYSwidmFsdWUiLCJOb3QgYSB2YWxp
-ZCBjbGFzcyB0b2tlbiIpKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuUCgpLkgoMCwiICIpfSwK
-Z206ZnVuY3Rpb24oYSl7dmFyIHM9dGhpcy5QKCkKcmV0dXJuIFAucmoocyxzLnIsSC5MaChzKS5jKX0s
-CmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5QKCkuYT09PTB9LApnb3I6ZnVuY3Rpb24oYSl7cmV0
-dXJuIHRoaXMuUCgpLmEhPT0wfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuUCgpLmF9LAp0Zzpm
-dW5jdGlvbihhLGIpe3RoaXMuVChiKQpyZXR1cm4gdGhpcy5QKCkudGcoMCxiKX0sCmk6ZnVuY3Rpb24o
-YSxiKXt2YXIgcwpILmgoYikKdGhpcy5UKGIpCnM9dGhpcy5PUyhuZXcgUC5HRShiKSkKcmV0dXJuIEgu
-eTgocz09bnVsbD8hMTpzKX0sClI6ZnVuY3Rpb24oYSxiKXt2YXIgcyxyCmlmKHR5cGVvZiBiIT0ic3Ry
-aW5nIilyZXR1cm4hMQp0aGlzLlQoYikKcz10aGlzLlAoKQpyPXMuUigwLGIpCnRoaXMuWChzKQpyZXR1
-cm4gcn0sCkZWOmZ1bmN0aW9uKGEsYil7dGhpcy5PUyhuZXcgUC5ONyh0aGlzLHQuUS5hKGIpKSl9LApl
-UjpmdW5jdGlvbihhLGIpe3ZhciBzPXRoaXMuUCgpCnJldHVybiBILmJLKHMsYixILkxoKHMpLkMoImxm
-LkUiKSl9LApFOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuUCgpLkUoMCxiKX0sClYxOmZ1bmN0aW9u
-KGEpe3RoaXMuT1MobmV3IFAudVEoKSl9LApPUzpmdW5jdGlvbihhKXt2YXIgcyxyCnQuYlUuYShhKQpz
-PXRoaXMuUCgpCnI9YS4kMShzKQp0aGlzLlgocykKcmV0dXJuIHJ9fQpQLkdFLnByb3RvdHlwZT17CiQx
-OmZ1bmN0aW9uKGEpe3JldHVybiB0LkMuYShhKS5pKDAsdGhpcy5hKX0sCiRTOjMzfQpQLk43LnByb3Rv
-dHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuYixyPUgudDYocykKcmV0dXJuIHQuQy5hKGEp
-LkZWKDAsbmV3IEgubEoocyxyLkMoInFVKDEpIikuYSh0aGlzLmEuZ3VNKCkpLHIuQygibEo8MSxxVT4i
-KSkpfSwKJFM6MTd9ClAudVEucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dC5DLmEoYSkKaWYoYS5h
-PjApe2EuYj1hLmM9YS5kPWEuZT1hLmY9bnVsbAphLmE9MAphLlMoKX1yZXR1cm4gbnVsbH0sCiRTOjE3
-fQpQLmhGLnByb3RvdHlwZT17JGloRjoxfQpQLlBDLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3Zh
-ciBzCnQuWS5hKGEpCnM9ZnVuY3Rpb24oYixjLGQpe3JldHVybiBmdW5jdGlvbigpe3JldHVybiBiKGMs
-ZCx0aGlzLEFycmF5LnByb3RvdHlwZS5zbGljZS5hcHBseShhcmd1bWVudHMpKX19KFAuUjQsYSwhMSkK
-UC5EbShzLCQudygpLGEpCnJldHVybiBzfSwKJFM6NH0KUC5tdC5wcm90b3R5cGU9ewokMTpmdW5jdGlv
-bihhKXtyZXR1cm4gbmV3IHRoaXMuYShhKX0sCiRTOjR9ClAuTnoucHJvdG90eXBlPXsKJDE6ZnVuY3Rp
-b24oYSl7cmV0dXJuIG5ldyBQLnI3KGEpfSwKJFM6MzV9ClAuUVMucHJvdG90eXBlPXsKJDE6ZnVuY3Rp
-b24oYSl7cmV0dXJuIG5ldyBQLlR6KGEsdC5hbSl9LAokUzo1NH0KUC5ucC5wcm90b3R5cGU9ewokMTpm
-dW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuRTQoYSl9LAokUzozN30KUC5FNC5wcm90b3R5cGU9ewpxOmZ1
-bmN0aW9uKGEsYil7aWYodHlwZW9mIGIhPSJzdHJpbmciJiZ0eXBlb2YgYiE9Im51bWJlciIpdGhyb3cg
-SC5iKFAueFkoInByb3BlcnR5IGlzIG5vdCBhIFN0cmluZyBvciBudW0iKSkKcmV0dXJuIFAuZFUodGhp
-cy5hW2JdKX0sClk6ZnVuY3Rpb24oYSxiLGMpe2lmKHR5cGVvZiBiIT0ic3RyaW5nIiYmdHlwZW9mIGIh
+Llk1KHRoaXMuYixiLHApCmZvcihzPTA7czxxOysrcylDLk5tLlk1KHAscyx0aGlzLlB2KHIucShhLHMp
+KSkKcmV0dXJuIHB9fQpQLmpnLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhpcy5hLmFbYV09
+dGhpcy5iLlB2KGIpfSwKJFM6MzF9ClAuVGEucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0aGlz
+LmEuYlthXT10aGlzLmIuUHYoYil9LAokUzoxNn0KUC5CZi5wcm90b3R5cGU9ewppbTpmdW5jdGlvbihh
+LGIpe3ZhciBzLHIscSxwCnQuYjguYShiKQpmb3Iocz1PYmplY3Qua2V5cyhhKSxyPXMubGVuZ3RoLHE9
+MDtxPHI7KytxKXtwPXNbcV0KYi4kMihwLGFbcF0pfX19ClAuQXMucHJvdG90eXBlPXsKVjpmdW5jdGlv
+bihhKXt2YXIgcwpILmgoYSkKcz0kLmhHKCkuYgppZih0eXBlb2YgYSE9InN0cmluZyIpSC52KEgudEwo
+YSkpCmlmKHMudGVzdChhKSlyZXR1cm4gYQp0aHJvdyBILmIoUC5MMyhhLCJ2YWx1ZSIsIk5vdCBhIHZh
+bGlkIGNsYXNzIHRva2VuIikpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5EKCkuaygwLCIgIil9
+LApnbTpmdW5jdGlvbihhKXt2YXIgcz10aGlzLkQoKQpyZXR1cm4gUC5yaihzLHMucixILkxoKHMpLmMp
+fSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLkQoKS5hPT09MH0sCmdvcjpmdW5jdGlvbihhKXty
+ZXR1cm4gdGhpcy5EKCkuYSE9PTB9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5EKCkuYX0sCnRn
+OmZ1bmN0aW9uKGEsYil7dGhpcy5WKGIpCnJldHVybiB0aGlzLkQoKS50ZygwLGIpfSwKaTpmdW5jdGlv
+bihhLGIpe3ZhciBzCkguaChiKQp0aGlzLlYoYikKcz10aGlzLk8obmV3IFAuR0UoYikpCnJldHVybiBI
+Lnk4KHM9PW51bGw/ITE6cyl9LApMOmZ1bmN0aW9uKGEsYil7dmFyIHMscgppZih0eXBlb2YgYiE9InN0
+cmluZyIpcmV0dXJuITEKdGhpcy5WKGIpCnM9dGhpcy5EKCkKcj1zLkwoMCxiKQp0aGlzLlgocykKcmV0
+dXJuIHJ9LApGVjpmdW5jdGlvbihhLGIpe3RoaXMuTyhuZXcgUC5ONyh0aGlzLHQuUS5hKGIpKSl9LApl
+UjpmdW5jdGlvbihhLGIpe3ZhciBzPXRoaXMuRCgpCnJldHVybiBILmJLKHMsYixILkxoKHMpLkMoImxm
+LkUiKSl9LApFOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuRCgpLkUoMCxiKX0sClYxOmZ1bmN0aW9u
+KGEpe3RoaXMuTyhuZXcgUC51USgpKX0sCk86ZnVuY3Rpb24oYSl7dmFyIHMscgp0LmJVLmEoYSkKcz10
+aGlzLkQoKQpyPWEuJDEocykKdGhpcy5YKHMpCnJldHVybiByfX0KUC5HRS5wcm90b3R5cGU9ewokMTpm
+dW5jdGlvbihhKXtyZXR1cm4gdC5DLmEoYSkuaSgwLHRoaXMuYSl9LAokUzozM30KUC5ONy5wcm90b3R5
+cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmIscj1ILnQ2KHMpCnJldHVybiB0LkMuYShhKS5G
+VigwLG5ldyBILmxKKHMsci5DKCJxVSgxKSIpLmEodGhpcy5hLmd1TSgpKSxyLkMoImxKPDEscVU+Iikp
+KX0sCiRTOjE3fQpQLnVRLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3QuQy5hKGEpCmlmKGEuYT4w
+KXthLmI9YS5jPWEuZD1hLmU9YS5mPW51bGwKYS5hPTAKYS5HWSgpfXJldHVybiBudWxsfSwKJFM6MTd9
+ClAuaEYucHJvdG90eXBlPXskaWhGOjF9ClAuUEMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFy
+IHMKdC5ZLmEoYSkKcz1mdW5jdGlvbihiLGMsZCl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGIoYyxk
+LHRoaXMsQXJyYXkucHJvdG90eXBlLnNsaWNlLmFwcGx5KGFyZ3VtZW50cykpfX0oUC5SNCxhLCExKQpQ
+LkRtKHMsJC53KCksYSkKcmV0dXJuIHN9LAokUzo0fQpQLm10LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9u
+KGEpe3JldHVybiBuZXcgdGhpcy5hKGEpfSwKJFM6NH0KUC5Oei5wcm90b3R5cGU9ewokMTpmdW5jdGlv
+bihhKXtyZXR1cm4gbmV3IFAucjcoYSl9LAokUzozNX0KUC5RUy5wcm90b3R5cGU9ewokMTpmdW5jdGlv
+bihhKXtyZXR1cm4gbmV3IFAuVHooYSx0LmFtKX0sCiRTOjU0fQpQLm5wLnByb3RvdHlwZT17CiQxOmZ1
+bmN0aW9uKGEpe3JldHVybiBuZXcgUC5FNChhKX0sCiRTOjM3fQpQLkU0LnByb3RvdHlwZT17CnE6ZnVu
+Y3Rpb24oYSxiKXtpZih0eXBlb2YgYiE9InN0cmluZyImJnR5cGVvZiBiIT0ibnVtYmVyIil0aHJvdyBI
+LmIoUC54WSgicHJvcGVydHkgaXMgbm90IGEgU3RyaW5nIG9yIG51bSIpKQpyZXR1cm4gUC5kVSh0aGlz
+LmFbYl0pfSwKWTU6ZnVuY3Rpb24oYSxiLGMpe2lmKHR5cGVvZiBiIT0ic3RyaW5nIiYmdHlwZW9mIGIh
PSJudW1iZXIiKXRocm93IEguYihQLnhZKCJwcm9wZXJ0eSBpcyBub3QgYSBTdHJpbmcgb3IgbnVtIikp
CnRoaXMuYVtiXT1QLndZKGMpfSwKRE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxsKXJldHVybiExCnJl
dHVybiBiIGluc3RhbmNlb2YgUC5FNCYmdGhpcy5hPT09Yi5hfSwKdzpmdW5jdGlvbihhKXt2YXIgcyxy
@@ -10757,975 +10793,990 @@
Y3Rpb24oYSl7cmV0dXJuIDB9fQpQLnI3LnByb3RvdHlwZT17fQpQLlR6LnByb3RvdHlwZT17CmNQOmZ1
bmN0aW9uKGEpe3ZhciBzPXRoaXMscj1hPDB8fGE+PXMuZ0EocykKaWYocil0aHJvdyBILmIoUC5URShh
LDAscy5nQShzKSxudWxsLG51bGwpKX0sCnE6ZnVuY3Rpb24oYSxiKXtpZihILm9rKGIpKXRoaXMuY1Ao
-YikKcmV0dXJuIHRoaXMuJHRpLmMuYSh0aGlzLlVyKDAsYikpfSwKWTpmdW5jdGlvbihhLGIsYyl7dGhp
-cy5jUChiKQp0aGlzLmU0KDAsYixjKX0sCmdBOmZ1bmN0aW9uKGEpe3ZhciBzPXRoaXMuYS5sZW5ndGgK
-aWYodHlwZW9mIHM9PT0ibnVtYmVyIiYmcz4+PjA9PT1zKXJldHVybiBzCnRocm93IEguYihQLlBWKCJC
-YWQgSnNBcnJheSBsZW5ndGgiKSl9LAokaWJROjEsCiRpY1g6MSwKJGl6TToxfQpQLmNvLnByb3RvdHlw
-ZT17fQpQLm5kLnByb3RvdHlwZT17JGluZDoxfQpQLktlLnByb3RvdHlwZT17ClA6ZnVuY3Rpb24oKXt2
-YXIgcyxyLHEscCxvPXRoaXMuYS5nZXRBdHRyaWJ1dGUoImNsYXNzIiksbj1QLkxzKHQuTikKaWYobz09
-bnVsbClyZXR1cm4gbgpmb3Iocz1vLnNwbGl0KCIgIikscj1zLmxlbmd0aCxxPTA7cTxyOysrcSl7cD1K
-LlQwKHNbcV0pCmlmKHAubGVuZ3RoIT09MCluLmkoMCxwKX1yZXR1cm4gbn0sClg6ZnVuY3Rpb24oYSl7
-dGhpcy5hLnNldEF0dHJpYnV0ZSgiY2xhc3MiLGEuSCgwLCIgIikpfX0KUC5oaS5wcm90b3R5cGU9ewpn
-RDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuS2UoYSl9LApzaGY6ZnVuY3Rpb24oYSxiKXt0aGlzLllD
-KGEsYil9LApyNjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgcyxyLHEscCxvLG4KaWYoZD09bnVsbCl7cz1I
-LlZNKFtdLHQudikKZD1uZXcgVy52RChzKQpDLk5tLmkocyxXLlR3KG51bGwpKQpDLk5tLmkocyxXLkJs
-KCkpCkMuTm0uaShzLG5ldyBXLk93KCkpfWM9bmV3IFcuS28oZCkKcj0nPHN2ZyB2ZXJzaW9uPSIxLjEi
-PicrSC5FaihiKSsiPC9zdmc+IgpzPWRvY3VtZW50CnE9cy5ib2R5CnEudG9TdHJpbmcKcD1DLlJZLkFI
-KHEscixjKQpvPXMuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpCnAudG9TdHJpbmcKcz1uZXcgVy5lNyhw
-KQpuPXMuZ3I4KHMpCmZvcig7cz1uLmZpcnN0Q2hpbGQscyE9bnVsbDspby5hcHBlbmRDaGlsZChzKQpy
-ZXR1cm4gb30sCm56OmZ1bmN0aW9uKGEsYixjLGQsZSl7dGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBpbnZv
-a2UgaW5zZXJ0QWRqYWNlbnRIdG1sIG9uIFNWRy4iKSl9LApnVmw6ZnVuY3Rpb24oYSl7cmV0dXJuIG5l
-dyBXLmV1KGEsImNsaWNrIiwhMSx0LmspfSwKJGloaToxfQpNLkg3LnByb3RvdHlwZT17Cnc6ZnVuY3Rp
-b24oYSl7cmV0dXJuIHRoaXMuYn19ClUuTEwucHJvdG90eXBlPXsKTHQ6ZnVuY3Rpb24oKXtyZXR1cm4g
-UC5FRihbIm5vZGVJZCIsdGhpcy5iLCJraW5kIix0aGlzLmEuYV0sdC5YLHQuXyl9fQpVLk1ELnByb3Rv
-dHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0LmZFLmEoYSkuYT09PXRoaXMuYS5xKDAsImtpbmQi
-KX0sCiRTOjM4fQpVLmQyLnByb3RvdHlwZT17Ckx0OmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbz10aGlz
-LG49dC5YLG09dC5fLGw9UC5GbChuLG0pLGs9by5hCmlmKGshPW51bGwpe3M9SC5WTShbXSx0LkcpCmZv
-cihyPWsubGVuZ3RoLHE9MDtxPGsubGVuZ3RoO2subGVuZ3RoPT09cnx8KDAsSC5saykoayksKytxKXtw
-PWtbcV0Kcy5wdXNoKFAuRUYoWyJkZXNjcmlwdGlvbiIscC5hLCJocmVmIixwLmJdLG4sbSkpfWwuWSgw
-LCJlZGl0cyIscyl9bC5ZKDAsImV4cGxhbmF0aW9uIixvLmIpCmwuWSgwLCJsaW5lIixvLmMpCmwuWSgw
-LCJkaXNwbGF5UGF0aCIsby5kKQpsLlkoMCwidXJpUGF0aCIsby5lKQpuPW8uZgppZihuIT1udWxsKXtt
-PUguVk0oW10sdC5HKQpmb3Ioaz1uLmxlbmd0aCxxPTA7cTxuLmxlbmd0aDtuLmxlbmd0aD09PWt8fCgw
-LEgubGspKG4pLCsrcSltLnB1c2gobltxXS5MdCgpKQpsLlkoMCwidHJhY2VzIixtKX1yZXR1cm4gbH19
-ClUuU2UucHJvdG90eXBlPXsKTHQ6ZnVuY3Rpb24oKXtyZXR1cm4gUC5FRihbImRlc2NyaXB0aW9uIix0
-aGlzLmEsImhyZWYiLHRoaXMuYl0sdC5YLHQuXyl9fQpVLk1sLnByb3RvdHlwZT17Ckx0OmZ1bmN0aW9u
-KCl7cmV0dXJuIFAuRUYoWyJocmVmIix0aGlzLmEsImxpbmUiLHRoaXMuYiwicGF0aCIsdGhpcy5jXSx0
-LlgsdC5fKX19ClUueUQucHJvdG90eXBlPXsKTHQ6ZnVuY3Rpb24oKXt2YXIgcyxyLHEscD1ILlZNKFtd
-LHQuRykKZm9yKHM9dGhpcy5iLHI9cy5sZW5ndGgscT0wO3E8cy5sZW5ndGg7cy5sZW5ndGg9PT1yfHwo
-MCxILmxrKShzKSwrK3EpcC5wdXNoKHNbcV0uTHQoKSkKcmV0dXJuIFAuRUYoWyJkZXNjcmlwdGlvbiIs
-dGhpcy5hLCJlbnRyaWVzIixwXSx0LlgsdC5fKX19ClUud2IucHJvdG90eXBlPXsKTHQ6ZnVuY3Rpb24o
-KXt2YXIgcyxyLHEscD10aGlzLG89UC5GbCh0LlgsdC5fKQpvLlkoMCwiZGVzY3JpcHRpb24iLHAuYSkK
-cz1wLmIKaWYocyE9bnVsbClvLlkoMCwiZnVuY3Rpb24iLHMpCnM9cC5jCmlmKHMhPW51bGwpby5ZKDAs
-ImxpbmsiLHMuTHQoKSkKcz1wLmQKaWYocy5sZW5ndGghPT0wKXtyPUgudDYocykKcT1yLkMoImxKPDEs
-WjA8cVUqLE1oKj4qPiIpCm8uWSgwLCJoaW50QWN0aW9ucyIsUC5ZMShuZXcgSC5sSihzLHIuQygiWjA8
-cVUqLE1oKj4qKDEpIikuYShuZXcgVS5iMCgpKSxxKSwhMCxxLkMoImFMLkUiKSkpfXJldHVybiBvfX0K
-VS5hTi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gVS5ueih0LnQuYShhKSl9LAokUzoz
-OX0KVS5iMC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdC5hWC5hKGEpLkx0KCl9LAok
-Uzo0MH0KQi5qOC5wcm90b3R5cGU9ewpMdDpmdW5jdGlvbigpe3JldHVybiBQLkVGKFsibGluZSIsdGhp
-cy5hLCJleHBsYW5hdGlvbiIsdGhpcy5iLCJvZmZzZXQiLHRoaXMuY10sdC5YLHQuXyl9fQpCLnFwLnBy
-b3RvdHlwZT17Ckx0OmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbyxuLG0sbD10aGlzLGs9dC5YLGo9UC5G
-bChrLHQuZHApCmZvcihzPWwuZCxzPXMuZ1B1KHMpLHM9cy5nbShzKSxyPXQuXyxxPXQuRztzLkYoKTsp
-e3A9cy5nbCgpCm89cC5hCm49SC5WTShbXSxxKQpmb3IocD1KLklUKHAuYik7cC5GKCk7KXttPXAuZ2wo
-KQpuLnB1c2goUC5FRihbImxpbmUiLG0uYSwiZXhwbGFuYXRpb24iLG0uYiwib2Zmc2V0IixtLmNdLGss
-cikpfWouWSgwLG8sbil9cmV0dXJuIFAuRUYoWyJyZWdpb25zIixsLmEsIm5hdmlnYXRpb25Db250ZW50
-IixsLmIsInNvdXJjZUNvZGUiLGwuYywiZWRpdHMiLGpdLGsscil9fQpULm1RLnByb3RvdHlwZT17fQpM
-LmUucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG0KdC5hTC5hKGEpCnM9
-d2luZG93LmxvY2F0aW9uLnBhdGhuYW1lCnI9TC5HNih3aW5kb3cubG9jYXRpb24uaHJlZikKcT1MLmFL
-KHdpbmRvdy5sb2NhdGlvbi5ocmVmKQpMLkdlKCkKaWYocyE9PSIvIiYmcyE9PUouVDAoZG9jdW1lbnQu
-cXVlcnlTZWxlY3RvcigiLnJvb3QiKS50ZXh0Q29udGVudCkpTC5HNyhzLHIscSwhMCxuZXcgTC5WVyhz
-LHIscSkpCnA9ZG9jdW1lbnQKbz1KLnFGKHAucXVlcnlTZWxlY3RvcigiLmFwcGx5LW1pZ3JhdGlvbiIp
-KQpuPW8uJHRpCm09bi5DKCJ+KDEpPyIpLmEobmV3IEwub1ooKSkKdC5aLmEobnVsbCkKVy5KRShvLmEs
-by5iLG0sITEsbi5jKQpuPUoucUYocC5xdWVyeVNlbGVjdG9yKCIucmVydW4tbWlncmF0aW9uIikpCm09
-bi4kdGkKVy5KRShuLmEsbi5iLG0uQygifigxKT8iKS5hKG5ldyBMLkhpKCkpLCExLG0uYykKbT1KLnFG
-KHAucXVlcnlTZWxlY3RvcigiLnJlcG9ydC1wcm9ibGVtIikpCm49bS4kdGkKVy5KRShtLmEsbS5iLG4u
-QygifigxKT8iKS5hKG5ldyBMLkJUKCkpLCExLG4uYykKcD1KLnFGKHAucXVlcnlTZWxlY3RvcigiLnBv
-cHVwLXBhbmUgLmNsb3NlIikpCm49cC4kdGkKVy5KRShwLmEscC5iLG4uQygifigxKT8iKS5hKG5ldyBM
-LlBZKCkpLCExLG4uYyl9LAokUzoxOH0KTC5WVy5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe0wuRnIo
-dGhpcy5hLHRoaXMuYix0aGlzLmMpfSwKJFM6MX0KTC5vWi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihh
-KXt2YXIgcyxyLHEscAp0Lk8uYShhKQppZihILm9UKEMub2wudXMod2luZG93LCJUaGlzIHdpbGwgYXBw
-bHkgdGhlIGNoYW5nZXMgeW91J3ZlIHByZXZpZXdlZCB0byB5b3VyIHdvcmtpbmcgZGlyZWN0b3J5LiBJ
-dCBpcyByZWNvbW1lbmRlZCB5b3UgY29tbWl0IGFueSBjaGFuZ2VzIHlvdSBtYWRlIGJlZm9yZSBkb2lu
-ZyB0aGlzLiIpKSl7cz1MLnR5KCIvYXBwbHktbWlncmF0aW9uIixudWxsKS5XNyhuZXcgTC5qcigpLHQu
-UCkKcj1uZXcgTC5xbCgpCnQuYjcuYShudWxsKQpxPXMuJHRpCnA9JC5YMwppZihwIT09Qy5OVSlyPVAu
-VkgocixwKQpzLnhmKG5ldyBQLkZlKG5ldyBQLnZzKHAscSksMixudWxsLHIscS5DKCJAPDE+IikuS3Eo
-cS5jKS5DKCJGZTwxLDI+IikpKX19LAokUzoyfQpMLmpyLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEp
-e3ZhciBzCnQudC5hKGEpCnM9ZG9jdW1lbnQuYm9keQpzLmNsYXNzTGlzdC5yZW1vdmUoInByb3Bvc2Vk
-IikKcy5jbGFzc0xpc3QuYWRkKCJhcHBsaWVkIil9LAokUzo0M30KTC5xbC5wcm90b3R5cGU9ewokMjpm
-dW5jdGlvbihhLGIpe0wuQzIoIkNvdWxkIG5vdCBhcHBseSBtaWdyYXRpb24iLGEsYil9LAokQzoiJDIi
-LAokUjoyLAokUzoxNn0KTC5IaS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy54
-bih0Lk8uYShhKSl9LAp4bjpmdW5jdGlvbihhKXt2YXIgcz0wLHI9UC5GWCh0LlApLHE9MSxwLG89W10s
-bixtLGwsayxqCnZhciAkYXN5bmMkJDE9UC5seihmdW5jdGlvbihiLGMpe2lmKGI9PT0xKXtwPWMKcz1x
-fXdoaWxlKHRydWUpc3dpdGNoKHMpe2Nhc2UgMDpxPTMKZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRk
-KCJyZXJ1bm5pbmciKQpzPTYKcmV0dXJuIFAualEoTC50eSgiL3JlcnVuLW1pZ3JhdGlvbiIsbnVsbCks
-JGFzeW5jJCQxKQpjYXNlIDY6bj1jCmlmKEgub1QoSC55OChKLng5KG4sInN1Y2Nlc3MiKSkpKXdpbmRv
-dy5sb2NhdGlvbi5yZWxvYWQoKQplbHNlIEwuSzAodC5tLmEoSi54OShuLCJlcnJvcnMiKSkpCm8ucHVz
-aCg1KQpzPTQKYnJlYWsKY2FzZSAzOnE9MgpqPXAKbT1ILlJ1KGopCmw9SC50cyhqKQpMLkMyKCJGYWls
-ZWQgdG8gcmVydW4gbWlncmF0aW9uIixtLGwpCm8ucHVzaCg1KQpzPTQKYnJlYWsKY2FzZSAyOm89WzFd
-CmNhc2UgNDpxPTEKZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKCJyZXJ1bm5pbmciKQpzPW8u
-cG9wKCkKYnJlYWsKY2FzZSA1OnJldHVybiBQLnlDKG51bGwscikKY2FzZSAxOnJldHVybiBQLmYzKHAs
-cil9fSkKcmV0dXJuIFAuREkoJGFzeW5jJCQxLHIpfSwKJFM6MTl9CkwuQlQucHJvdG90eXBlPXsKJDE6
-ZnVuY3Rpb24oYSl7dmFyIHMKdC5PLmEoYSkKcz10LlgKQy5vbC5Qbyh3aW5kb3csUC5YZCgiaHR0cHMi
-LCJnaXRodWIuY29tIiwiZGFydC1sYW5nL3Nkay9pc3N1ZXMvbmV3IixQLkVGKFsidGl0bGUiLCJDdXN0
-b21lci1yZXBvcnRlZCBpc3N1ZSB3aXRoIE5OQkQgbWlncmF0aW9uIHRvb2wiLCJsYWJlbHMiLHUuZCwi
-Ym9keSIsIiMjIyMgU3RlcHMgdG8gcmVwcm9kdWNlXG5cbiMjIyMgV2hhdCBkaWQgeW91IGV4cGVjdCB0
-byBoYXBwZW4/XG5cbiMjIyMgV2hhdCBhY3R1YWxseSBoYXBwZW5lZD9cblxuX1NjcmVlbnNob3RzIGFy
-ZSBhcHByZWNpYXRlZF9cblxuKipEYXJ0IFNESyB2ZXJzaW9uKio6ICIrSC5Faihkb2N1bWVudC5nZXRF
-bGVtZW50QnlJZCgic2RrLXZlcnNpb24iKS50ZXh0Q29udGVudCkrIlxuXG5UaGFua3MgZm9yIGZpbGlu
-ZyFcbiJdLHMscykpLmduRCgpLCJyZXBvcnQtcHJvYmxlbSIpfSwKJFM6Mn0KTC5QWS5wcm90b3R5cGU9
-ewokMTpmdW5jdGlvbihhKXt2YXIgcwp0Lk8uYShhKQpzPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5w
-b3B1cC1wYW5lIikuc3R5bGUKcy5kaXNwbGF5PSJub25lIgpyZXR1cm4ibm9uZSJ9LAokUzo0NX0KTC5M
-LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzLHIscQp0LmFMLmEoYSkKcz13aW5kb3cubG9j
-YXRpb24ucGF0aG5hbWUKcj1MLkc2KHdpbmRvdy5sb2NhdGlvbi5ocmVmKQpxPUwuYUsod2luZG93Lmxv
-Y2F0aW9uLmhyZWYpCmlmKHMubGVuZ3RoPjEpTC5HNyhzLHIscSwhMSxudWxsKQplbHNle0wuQkUocyxC
-LndSKCksITApCkwuQlgoIiZuYnNwOyIsbnVsbCl9fSwKJFM6MTh9CkwuV3gucHJvdG90eXBlPXsKJDE6
-ZnVuY3Rpb24oYSl7dmFyIHMscixxLHA9ImNvbGxhcHNlZCIKdC5PLmEoYSkKcz10aGlzLmEKcj1KLllF
-KHMpCnE9dGhpcy5iCmlmKCFyLmdEKHMpLnRnKDAscCkpe3IuZ0QocykuaSgwLHApCkouZFIocSkuaSgw
-LHApfWVsc2V7ci5nRChzKS5SKDAscCkKSi5kUihxKS5SKDAscCl9fSwKJFM6Mn0KTC5BTy5wcm90b3R5
-cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgcz1KLnFGKHQuZy5hKGEpKSxyPXMuJHRpLHE9ci5DKCJ+KDEp
-PyIpLmEobmV3IEwuZE4odGhpcy5hKSkKdC5aLmEobnVsbCkKVy5KRShzLmEscy5iLHEsITEsci5jKX0s
-CiRTOjN9CkwuZE4ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHMKdC5PLmEoYSkKcz1kb2N1
-bWVudC5xdWVyeVNlbGVjdG9yKCJ0YWJsZVtkYXRhLXBhdGhdIikKcy50b1N0cmluZwpMLnQyKGEsdGhp
-cy5hLHMuZ2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3IFcuU3kobmV3IFcuaTcocykpLk8oInBhdGgiKSkp
-fSwKJFM6Mn0KTC5Iby5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgcyxyLHEKdC5nLmEoYSkK
-cz1KLnFGKGEpCnI9cy4kdGkKcT1yLkMoIn4oMSk/IikuYShuZXcgTC54eihhLHRoaXMuYSkpCnQuWi5h
-KG51bGwpClcuSkUocy5hLHMuYixxLCExLHIuYyl9LAokUzozfQpMLnh6LnByb3RvdHlwZT17CiQxOmZ1
-bmN0aW9uKGEpe3ZhciBzCnQuTy5hKGEpCnM9dGhpcy5hCkwuaFgodGhpcy5iLFAuUUEocy5nZXRBdHRy
-aWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhzKSkuTygib2Zmc2V0IikpLG51bGwpLFAuUUEo
-cy5nZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhzKSkuTygibGluZSIpKSxudWxs
-KSl9LAokUzoyfQpMLklDLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzPUoucUYodC5nLmEo
-YSkpLHI9cy4kdGkKci5DKCJ+KDEpPyIpLmEoTC5pUygpKQp0LlouYShudWxsKQpXLkpFKHMuYSxzLmIs
-TC5pUygpLCExLHIuYyl9LAokUzozfQpMLmZDLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3QuZVEu
-YShhKQp0aGlzLmEuYU0oMCx0aGlzLmIpfSwKJFM6NDd9CkwublQucHJvdG90eXBlPXsKJDA6ZnVuY3Rp
-b24oKXtMLkZyKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX0sCiRTOjF9CkwuTlkucHJvdG90eXBlPXsKJDA6
-ZnVuY3Rpb24oKXtMLkZyKHRoaXMuYSxudWxsLG51bGwpfSwKJFM6MX0KTC51ZS5wcm90b3R5cGU9ewok
-MTpmdW5jdGlvbihhKXt0LmF3LmEoYSkKcmV0dXJuIEguRWooYS5xKDAsInNldmVyaXR5IikpKyIgLSAi
-K0guRWooYS5xKDAsIm1lc3NhZ2UiKSkrIiBhdCAiK0guRWooYS5xKDAsImxvY2F0aW9uIikpKyIgLSAo
-IitILkVqKGEucSgwLCJjb2RlIikpKyIpIn0sCiRTOjQ4fQpMLmVYLnByb3RvdHlwZT17CiQxOmZ1bmN0
-aW9uKGEpe3QuZy5hKGEpCiQuekIoKS50b1N0cmluZwp0LmRILmEoJC5vdygpLnEoMCwiaGxqcyIpKS5W
-NygiaGlnaGxpZ2h0QmxvY2siLFthXSl9LAokUzozfQpMLkVFLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9u
-KGEpe3ZhciBzLHIKdC5PLmEoYSkucHJldmVudERlZmF1bHQoKQpzPXRoaXMuYQpyPXRoaXMuYgpMLmFm
-KHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSxzLHIsITAsbmV3IEwuUUwocyxyKSkKTC5oWCh0aGlzLmMs
-cyxyKX0sCiRTOjJ9CkwuUUwucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtMLkZyKHdpbmRvdy5sb2Nh
-dGlvbi5wYXRobmFtZSx0aGlzLmEsdGhpcy5iKX0sCiRTOjF9CkwuVlMucHJvdG90eXBlPXsKJDE6ZnVu
-Y3Rpb24oYSl7dmFyIHMscj0ic2VsZWN0ZWQtZmlsZSIKdC5nLmEoYSkKYS50b1N0cmluZwpzPUouWUUo
-YSkKaWYoYS5nZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhhKSkuTygibmFtZSIp
-KT09PXRoaXMuYS5hKXMuZ0QoYSkuaSgwLHIpCmVsc2Ugcy5nRChhKS5SKDAscil9LAokUzozfQpMLlRE
-LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBMLnQyKHQuTy5hKGEpLCEwLG51bGwpfSwK
-JFM6MjB9CkwubTIucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuUkkodC5PLmEo
-YSkpfSwKUkk6ZnVuY3Rpb24oYSl7dmFyIHM9MCxyPVAuRlgodC5QKSxxPTEscCxvPVtdLG49dGhpcyxt
-LGwsayxqLGksaCxnLGYKdmFyICRhc3luYyQkMT1QLmx6KGZ1bmN0aW9uKGIsYyl7aWYoYj09PTEpe3A9
-YwpzPXF9d2hpbGUodHJ1ZSlzd2l0Y2gocyl7Y2FzZSAwOnE9MwppPWRvY3VtZW50Cm09Qy5DRC56UShp
-LnF1ZXJ5U2VsZWN0b3IoIi5jb250ZW50Iikuc2Nyb2xsVG9wKQpoPXQuWApzPTYKcmV0dXJuIFAualEo
-TC50eShMLlE0KCIvYXBwbHktaGludCIsUC5GbChoLGgpKSxuLmEuTHQoKSksJGFzeW5jJCQxKQpjYXNl
-IDY6aD1uLmIKbD1MLlVzKGguYSkKcz03CnJldHVybiBQLmpRKEwuRzcobCxudWxsLGguYiwhMSxudWxs
-KSwkYXN5bmMkJDEpCmNhc2UgNzppLmJvZHkuY2xhc3NMaXN0LmFkZCgibmVlZHMtcmVydW4iKQppPWku
-cXVlcnlTZWxlY3RvcigiLmNvbnRlbnQiKQppLnRvU3RyaW5nCmkuc2Nyb2xsVG9wPUouVnUobSkKcT0x
-CnM9NQpicmVhawpjYXNlIDM6cT0yCmY9cAprPUguUnUoZikKaj1ILnRzKGYpCkwuQzIoIkNvdWxkIG5v
-dCBhcHBseSBoaW50IixrLGopCnM9NQpicmVhawpjYXNlIDI6cz0xCmJyZWFrCmNhc2UgNTpyZXR1cm4g
-UC55QyhudWxsLHIpCmNhc2UgMTpyZXR1cm4gUC5mMyhwLHIpfX0pCnJldHVybiBQLkRJKCRhc3luYyQk
-MSxyKX0sCiRTOjE5fQpMLlhBLnByb3RvdHlwZT17CkViOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4hMH0s
-CmkwOmZ1bmN0aW9uKGEpe3JldHVybiEwfSwKJGlrRjoxfQpMLnZ0LnByb3RvdHlwZT17CkxWOmZ1bmN0
-aW9uKCl7dmFyIHMscixxPXRoaXMuZAppZihxIT1udWxsKWZvcihzPXEubGVuZ3RoLHI9MDtyPHM7Kyty
-KXFbcl0uYj10aGlzfSwKTHQ6ZnVuY3Rpb24oKXt2YXIgcyxyPVAuRmwodC5YLHQuXykKci5ZKDAsInR5
-cGUiLCJkaXJlY3RvcnkiKQpyLlkoMCwibmFtZSIsdGhpcy5hKQpyLlkoMCwic3VidHJlZSIsTC5WRCh0
-aGlzLmQpKQpzPXRoaXMuYwppZihzIT1udWxsKXIuWSgwLCJwYXRoIixzKQpyZXR1cm4gcn19CkwuY0Qu
-cHJvdG90eXBlPXsKTHQ6ZnVuY3Rpb24oKXt2YXIgcyxyPXRoaXMscT1QLkZsKHQuWCx0Ll8pCnEuWSgw
-LCJ0eXBlIiwiZmlsZSIpCnEuWSgwLCJuYW1lIixyLmEpCnM9ci5jCmlmKHMhPW51bGwpcS5ZKDAsInBh
-dGgiLHMpCnM9ci5kCmlmKHMhPW51bGwpcS5ZKDAsImhyZWYiLHMpCnM9ci5lCmlmKHMhPW51bGwpcS5Z
-KDAsImVkaXRDb3VudCIscykKcz1yLmYKaWYocyE9bnVsbClxLlkoMCwid2FzRXhwbGljaXRseU9wdGVk
-T3V0IixzKQpzPXIucgppZihzIT1udWxsKXEuWSgwLCJtaWdyYXRpb25TdGF0dXMiLHMuYSkKcmV0dXJu
-IHF9fQpMLkQ4LnByb3RvdHlwZT17fQpMLk85LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJu
-IHRoaXMuYn19CkwuR2IucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5ifX0KTS5s
-SS5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigpe3ZhciBzPUQuYWIoKQpyZXR1cm4gc30sCldPOmZ1bmN0
-aW9uKGEsYil7dmFyIHMscixxPXQuZDQKTS5ZRigiYWJzb2x1dGUiLEguVk0oW2IsbnVsbCxudWxsLG51
-bGwsbnVsbCxudWxsLG51bGxdLHEpKQpzPXRoaXMuYQpzPXMuWXIoYik+MCYmIXMuaEsoYikKaWYocyly
-ZXR1cm4gYgpyPUguVk0oW3RoaXMuZ2woKSxiLG51bGwsbnVsbCxudWxsLG51bGwsbnVsbCxudWxsXSxx
-KQpNLllGKCJqb2luIixyKQpyZXR1cm4gdGhpcy5JUChuZXcgSC51NihyLHQuZUopKX0sCnpmOmZ1bmN0
-aW9uKGEpe3ZhciBzLHIscT1YLkNMKGEsdGhpcy5hKQpxLklWKCkKcz1xLmQKcj1zLmxlbmd0aAppZihy
-PT09MCl7cz1xLmIKcmV0dXJuIHM9PW51bGw/Ii4iOnN9aWYocj09PTEpe3M9cS5iCnJldHVybiBzPT1u
-dWxsPyIuIjpzfWlmKDA+PXIpcmV0dXJuIEguT0gocywtMSkKcy5wb3AoKQpzPXEuZQppZigwPj1zLmxl
-bmd0aClyZXR1cm4gSC5PSChzLC0xKQpzLnBvcCgpCnEuSVYoKQpyZXR1cm4gcS53KDApfSwKSVA6ZnVu
-Y3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG0sbCxrLGoKdC5RLmEoYSkKZm9yKHM9YS4kdGkscj1zLkMo
-ImEyKGNYLkUpIikuYShuZXcgTS5xNygpKSxxPWEuZ20oYSkscz1uZXcgSC5TTyhxLHIscy5DKCJTTzxj
-WC5FPiIpKSxyPXRoaXMuYSxwPSExLG89ITEsbj0iIjtzLkYoKTspe209cS5nbCgpCmlmKHIuaEsobSkm
-Jm8pe2w9WC5DTChtLHIpCms9bi5jaGFyQ29kZUF0KDApPT0wP246bgpuPUMueEIuTmooaywwLHIuU3Ao
-aywhMCkpCmwuYj1uCmlmKHIuZHMobikpQy5ObS5ZKGwuZSwwLHIuZ21JKCkpCm49bC53KDApfWVsc2Ug
-aWYoci5ZcihtKT4wKXtvPSFyLmhLKG0pCm49SC5FaihtKX1lbHNle2o9bS5sZW5ndGgKaWYoaiE9PTAp
-e2lmKDA+PWopcmV0dXJuIEguT0gobSwwKQpqPXIuVWQobVswXSl9ZWxzZSBqPSExCmlmKCFqKWlmKHAp
-bis9ci5nbUkoKQpuKz1tfXA9ci5kcyhtKX1yZXR1cm4gbi5jaGFyQ29kZUF0KDApPT0wP246bn0sCm81
-OmZ1bmN0aW9uKGEpe3ZhciBzCmlmKCF0aGlzLnkzKGEpKXJldHVybiBhCnM9WC5DTChhLHRoaXMuYSkK
-cy5yUigpCnJldHVybiBzLncoMCl9LAp5MzpmdW5jdGlvbihhKXt2YXIgcyxyLHEscCxvLG4sbSxsLGss
-agphLnRvU3RyaW5nCnM9dGhpcy5hCnI9cy5ZcihhKQppZihyIT09MCl7aWYocz09PSQuS2soKSlmb3Io
-cT0wO3E8cjsrK3EpaWYoQy54Qi5XKGEscSk9PT00NylyZXR1cm4hMApwPXIKbz00N31lbHNle3A9MApv
-PW51bGx9Zm9yKG49bmV3IEgucWooYSkuYSxtPW4ubGVuZ3RoLHE9cCxsPW51bGw7cTxtOysrcSxsPW8s
-bz1rKXtrPUMueEIuTzIobixxKQppZihzLnI0KGspKXtpZihzPT09JC5LaygpJiZrPT09NDcpcmV0dXJu
-ITAKaWYobyE9bnVsbCYmcy5yNChvKSlyZXR1cm4hMAppZihvPT09NDYpaj1sPT1udWxsfHxsPT09NDZ8
-fHMucjQobCkKZWxzZSBqPSExCmlmKGopcmV0dXJuITB9fWlmKG89PW51bGwpcmV0dXJuITAKaWYocy5y
-NChvKSlyZXR1cm4hMAppZihvPT09NDYpcz1sPT1udWxsfHxzLnI0KGwpfHxsPT09NDYKZWxzZSBzPSEx
-CmlmKHMpcmV0dXJuITAKcmV0dXJuITF9LApIUDpmdW5jdGlvbihhLGIpe3ZhciBzLHIscSxwLG8sbixt
-LGw9dGhpcyxrPSdVbmFibGUgdG8gZmluZCBhIHBhdGggdG8gIicKYj1sLldPKDAsYikKcz1sLmEKaWYo
-cy5ZcihiKTw9MCYmcy5ZcihhKT4wKXJldHVybiBsLm81KGEpCmlmKHMuWXIoYSk8PTB8fHMuaEsoYSkp
-YT1sLldPKDAsYSkKaWYocy5ZcihhKTw9MCYmcy5ZcihiKT4wKXRocm93IEguYihYLkk3KGsrSC5Faihh
-KSsnIiBmcm9tICInK0guRWooYikrJyIuJykpCnI9WC5DTChiLHMpCnIuclIoKQpxPVguQ0woYSxzKQpx
-LnJSKCkKcD1yLmQKbz1wLmxlbmd0aAppZihvIT09MCl7aWYoMD49bylyZXR1cm4gSC5PSChwLDApCnA9
-Si5STShwWzBdLCIuIil9ZWxzZSBwPSExCmlmKHApcmV0dXJuIHEudygwKQpwPXIuYgpvPXEuYgppZihw
-IT1vKXA9cD09bnVsbHx8bz09bnVsbHx8IXMuTmMocCxvKQplbHNlIHA9ITEKaWYocClyZXR1cm4gcS53
-KDApCndoaWxlKCEwKXtwPXIuZApvPXAubGVuZ3RoCmlmKG8hPT0wKXtuPXEuZAptPW4ubGVuZ3RoCmlm
-KG0hPT0wKXtpZigwPj1vKXJldHVybiBILk9IKHAsMCkKcD1wWzBdCmlmKDA+PW0pcmV0dXJuIEguT0go
-biwwKQpuPXMuTmMocCxuWzBdKQpwPW59ZWxzZSBwPSExfWVsc2UgcD0hMQppZighcClicmVhawpDLk5t
-Llc0KHIuZCwwKQpDLk5tLlc0KHIuZSwxKQpDLk5tLlc0KHEuZCwwKQpDLk5tLlc0KHEuZSwxKX1wPXIu
-ZApvPXAubGVuZ3RoCmlmKG8hPT0wKXtpZigwPj1vKXJldHVybiBILk9IKHAsMCkKcD1KLlJNKHBbMF0s
-Ii4uIil9ZWxzZSBwPSExCmlmKHApdGhyb3cgSC5iKFguSTcoaytILkVqKGEpKyciIGZyb20gIicrSC5F
-aihiKSsnIi4nKSkKcD10Lk4KQy5ObS5VRyhxLmQsMCxQLk84KHIuZC5sZW5ndGgsIi4uIiwhMSxwKSkK
-Qy5ObS5ZKHEuZSwwLCIiKQpDLk5tLlVHKHEuZSwxLFAuTzgoci5kLmxlbmd0aCxzLmdtSSgpLCExLHAp
-KQpzPXEuZApwPXMubGVuZ3RoCmlmKHA9PT0wKXJldHVybiIuIgppZihwPjEmJkouUk0oQy5ObS5ncloo
-cyksIi4iKSl7cz1xLmQKaWYoMD49cy5sZW5ndGgpcmV0dXJuIEguT0gocywtMSkKcy5wb3AoKQpzPXEu
-ZQppZigwPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLC0xKQpzLnBvcCgpCmlmKDA+PXMubGVuZ3RoKXJl
-dHVybiBILk9IKHMsLTEpCnMucG9wKCkKQy5ObS5pKHMsIiIpfXEuYj0iIgpxLklWKCkKcmV0dXJuIHEu
-dygwKX19Ck0ucTcucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIEguaChhKSE9PSIifSwK
-JFM6Nn0KTS5Oby5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtILmsoYSkKcmV0dXJuIGE9PW51bGw/
-Im51bGwiOiciJythKyciJ30sCiRTOjUwfQpCLmZ2LnByb3RvdHlwZT17CnhaOmZ1bmN0aW9uKGEpe3Zh
-ciBzLHI9dGhpcy5ZcihhKQppZihyPjApcmV0dXJuIEoubGQoYSwwLHIpCmlmKHRoaXMuaEsoYSkpe2lm
-KDA+PWEubGVuZ3RoKXJldHVybiBILk9IKGEsMCkKcz1hWzBdfWVsc2Ugcz1udWxsCnJldHVybiBzfSwK
-TmM6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYT09Yn19ClguV0QucHJvdG90eXBlPXsKSVY6ZnVuY3Rpb24o
-KXt2YXIgcyxyLHE9dGhpcwp3aGlsZSghMCl7cz1xLmQKaWYoIShzLmxlbmd0aCE9PTAmJkouUk0oQy5O
-bS5ncloocyksIiIpKSlicmVhawpzPXEuZAppZigwPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLC0xKQpz
-LnBvcCgpCnM9cS5lCmlmKDA+PXMubGVuZ3RoKXJldHVybiBILk9IKHMsLTEpCnMucG9wKCl9cz1xLmUK
-cj1zLmxlbmd0aAppZihyIT09MClDLk5tLlkocyxyLTEsIiIpfSwKclI6ZnVuY3Rpb24oKXt2YXIgcyxy
-LHEscCxvLG4sbT10aGlzLGw9SC5WTShbXSx0LnMpCmZvcihzPW0uZCxyPXMubGVuZ3RoLHE9MCxwPTA7
-cDxzLmxlbmd0aDtzLmxlbmd0aD09PXJ8fCgwLEgubGspKHMpLCsrcCl7bz1zW3BdCm49Si5pYShvKQpp
-ZighKG4uRE4obywiLiIpfHxuLkROKG8sIiIpKSlpZihuLkROKG8sIi4uIikpe249bC5sZW5ndGgKaWYo
-biE9PTApe2lmKDA+PW4pcmV0dXJuIEguT0gobCwtMSkKbC5wb3AoKX1lbHNlICsrcX1lbHNlIEMuTm0u
-aShsLG8pfWlmKG0uYj09bnVsbClDLk5tLlVHKGwsMCxQLk84KHEsIi4uIiwhMSx0Lk4pKQppZihsLmxl
-bmd0aD09PTAmJm0uYj09bnVsbClDLk5tLmkobCwiLiIpCm0uc25KKGwpCnM9bS5hCm0uc1BoKFAuTzgo
-bC5sZW5ndGgrMSxzLmdtSSgpLCEwLHQuTikpCnI9bS5iCmlmKHI9PW51bGx8fGwubGVuZ3RoPT09MHx8
-IXMuZHMocikpQy5ObS5ZKG0uZSwwLCIiKQpyPW0uYgppZihyIT1udWxsJiZzPT09JC5LaygpKXtyLnRv
-U3RyaW5nCm0uYj1ILnlzKHIsIi8iLCJcXCIpfW0uSVYoKX0sCnc6ZnVuY3Rpb24oYSl7dmFyIHMscixx
-PXRoaXMscD1xLmIKcD1wIT1udWxsP3A6IiIKZm9yKHM9MDtzPHEuZC5sZW5ndGg7KytzKXtyPXEuZQpp
-ZihzPj1yLmxlbmd0aClyZXR1cm4gSC5PSChyLHMpCnI9cCtILkVqKHJbc10pCnA9cS5kCmlmKHM+PXAu
-bGVuZ3RoKXJldHVybiBILk9IKHAscykKcD1yK0guRWoocFtzXSl9cCs9SC5FaihDLk5tLmdyWihxLmUp
-KQpyZXR1cm4gcC5jaGFyQ29kZUF0KDApPT0wP3A6cH0sCnNuSjpmdW5jdGlvbihhKXt0aGlzLmQ9dC5F
-LmEoYSl9LApzUGg6ZnVuY3Rpb24oYSl7dGhpcy5lPXQuRS5hKGEpfX0KWC5kdi5wcm90b3R5cGU9ewp3
-OmZ1bmN0aW9uKGEpe3JldHVybiJQYXRoRXhjZXB0aW9uOiAiK3RoaXMuYX0sCiRpUno6MX0KTy56TC5w
-cm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmdvYyh0aGlzKX19CkUuT0YucHJvdG90
-eXBlPXsKVWQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEMueEIudGcoYSwiLyIpfSwKcjQ6ZnVuY3Rpb24oYSl7
-cmV0dXJuIGE9PT00N30sCmRzOmZ1bmN0aW9uKGEpe3ZhciBzPWEubGVuZ3RoCnJldHVybiBzIT09MCYm
-Qy54Qi5PMihhLHMtMSkhPT00N30sClNwOmZ1bmN0aW9uKGEsYil7aWYoYS5sZW5ndGghPT0wJiZDLnhC
-LlcoYSwwKT09PTQ3KXJldHVybiAxCnJldHVybiAwfSwKWXI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
-U3AoYSwhMSl9LApoSzpmdW5jdGlvbihhKXtyZXR1cm4hMX0sCmdvYzpmdW5jdGlvbigpe3JldHVybiJw
-b3NpeCJ9LApnbUk6ZnVuY3Rpb24oKXtyZXR1cm4iLyJ9fQpGLnJ1LnByb3RvdHlwZT17ClVkOmZ1bmN0
-aW9uKGEpe3JldHVybiBDLnhCLnRnKGEsIi8iKX0sCnI0OmZ1bmN0aW9uKGEpe3JldHVybiBhPT09NDd9
-LApkczpmdW5jdGlvbihhKXt2YXIgcz1hLmxlbmd0aAppZihzPT09MClyZXR1cm4hMQppZihDLnhCLk8y
-KGEscy0xKSE9PTQ3KXJldHVybiEwCnJldHVybiBDLnhCLlRjKGEsIjovLyIpJiZ0aGlzLllyKGEpPT09
-c30sClNwOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbz1hLmxlbmd0aAppZihvPT09MClyZXR1cm4g
-MAppZihDLnhCLlcoYSwwKT09PTQ3KXJldHVybiAxCmZvcihzPTA7czxvOysrcyl7cj1DLnhCLlcoYSxz
-KQppZihyPT09NDcpcmV0dXJuIDAKaWYocj09PTU4KXtpZihzPT09MClyZXR1cm4gMApxPUMueEIuWFUo
-YSwiLyIsQy54Qi5RaShhLCIvLyIscysxKT9zKzM6cykKaWYocTw9MClyZXR1cm4gbwppZighYnx8bzxx
-KzMpcmV0dXJuIHEKaWYoIUMueEIubihhLCJmaWxlOi8vIikpcmV0dXJuIHEKaWYoIUIuWXUoYSxxKzEp
-KXJldHVybiBxCnA9cSszCnJldHVybiBvPT09cD9wOnErNH19cmV0dXJuIDB9LApZcjpmdW5jdGlvbihh
-KXtyZXR1cm4gdGhpcy5TcChhLCExKX0sCmhLOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aCE9PTAm
-JkMueEIuVyhhLDApPT09NDd9LApnb2M6ZnVuY3Rpb24oKXtyZXR1cm4idXJsIn0sCmdtSTpmdW5jdGlv
-bigpe3JldHVybiIvIn19CkwuSVYucHJvdG90eXBlPXsKVWQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEMueEIu
-dGcoYSwiLyIpfSwKcjQ6ZnVuY3Rpb24oYSl7cmV0dXJuIGE9PT00N3x8YT09PTkyfSwKZHM6ZnVuY3Rp
-b24oYSl7dmFyIHM9YS5sZW5ndGgKaWYocz09PTApcmV0dXJuITEKcz1DLnhCLk8yKGEscy0xKQpyZXR1
-cm4hKHM9PT00N3x8cz09PTkyKX0sClNwOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxPWEubGVuZ3RoCmlm
-KHE9PT0wKXJldHVybiAwCnM9Qy54Qi5XKGEsMCkKaWYocz09PTQ3KXJldHVybiAxCmlmKHM9PT05Mil7
-aWYocTwyfHxDLnhCLlcoYSwxKSE9PTkyKXJldHVybiAxCnI9Qy54Qi5YVShhLCJcXCIsMikKaWYocj4w
-KXtyPUMueEIuWFUoYSwiXFwiLHIrMSkKaWYocj4wKXJldHVybiByfXJldHVybiBxfWlmKHE8MylyZXR1
-cm4gMAppZighQi5PUyhzKSlyZXR1cm4gMAppZihDLnhCLlcoYSwxKSE9PTU4KXJldHVybiAwCnE9Qy54
-Qi5XKGEsMikKaWYoIShxPT09NDd8fHE9PT05MikpcmV0dXJuIDAKcmV0dXJuIDN9LApZcjpmdW5jdGlv
-bihhKXtyZXR1cm4gdGhpcy5TcChhLCExKX0sCmhLOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLllyKGEp
-PT09MX0sCk90OmZ1bmN0aW9uKGEsYil7dmFyIHMKaWYoYT09PWIpcmV0dXJuITAKaWYoYT09PTQ3KXJl
-dHVybiBiPT09OTIKaWYoYT09PTkyKXJldHVybiBiPT09NDcKaWYoKGFeYikhPT0zMilyZXR1cm4hMQpz
-PWF8MzIKcmV0dXJuIHM+PTk3JiZzPD0xMjJ9LApOYzpmdW5jdGlvbihhLGIpe3ZhciBzLHIscQppZihh
-PT1iKXJldHVybiEwCnM9YS5sZW5ndGgKaWYocyE9PWIubGVuZ3RoKXJldHVybiExCmZvcihyPUouclko
-YikscT0wO3E8czsrK3EpaWYoIXRoaXMuT3QoQy54Qi5XKGEscSksci5XKGIscSkpKXJldHVybiExCnJl
-dHVybiEwfSwKZ29jOmZ1bmN0aW9uKCl7cmV0dXJuIndpbmRvd3MifSwKZ21JOmZ1bmN0aW9uKCl7cmV0
-dXJuIlxcIn19OyhmdW5jdGlvbiBhbGlhc2VzKCl7dmFyIHM9Si5Hdi5wcm90b3R5cGUKcy5VPXMudwpz
-LlNqPXMuZTcKcz1KLk1GLnByb3RvdHlwZQpzLnQ9cy53CnM9UC5jWC5wcm90b3R5cGUKcy5HRz1zLmV2
-CnM9UC5NaC5wcm90b3R5cGUKcy54Yj1zLncKcz1XLmN2LnByb3RvdHlwZQpzLkRXPXMucjYKcz1XLm02
-LnByb3RvdHlwZQpzLmpGPXMuRWIKcz1QLkU0LnByb3RvdHlwZQpzLlVyPXMucQpzLmU0PXMuWX0pKCk7
-KGZ1bmN0aW9uIGluc3RhbGxUZWFyT2Zmcygpe3ZhciBzPWh1bmtIZWxwZXJzLl9zdGF0aWNfMSxyPWh1
-bmtIZWxwZXJzLl9zdGF0aWNfMCxxPWh1bmtIZWxwZXJzLmluc3RhbGxJbnN0YW5jZVRlYXJPZmYscD1o
-dW5rSGVscGVycy5pbnN0YWxsU3RhdGljVGVhck9mZixvPWh1bmtIZWxwZXJzLl9pbnN0YW5jZV8xdQpz
-KFAsIkVYIiwiWlYiLDcpCnMoUCwieXQiLCJvQSIsNykKcyhQLCJxVyIsIkJ6Iiw3KQpyKFAsIlVJIiwi
-ZU4iLDApCnEoUC5QZi5wcm90b3R5cGUsImdZSiIsMCwxLG51bGwsWyIkMiIsIiQxIl0sWyJ3MCIsInBt
-Il0sMjgsMCkKcyhQLCJDeSIsIk5DIiw0KQpzKFAsIlBIIiwiTXQiLDUpCnAoVywicFMiLDQsbnVsbCxb
-IiQ0Il0sWyJxRCJdLDgsMCkKcChXLCJWNCIsNCxudWxsLFsiJDQiXSxbIlFXIl0sOCwwKQpvKFAuQXMu
-cHJvdG90eXBlLCJndU0iLCJUIiw1KQpzKFAsImlHIiwid1kiLDUzKQpzKFAsIncwIiwiZFUiLDM2KQpz
-KEwsImlTIiwiaTYiLDIwKX0pKCk7KGZ1bmN0aW9uIGluaGVyaXRhbmNlKCl7dmFyIHM9aHVua0hlbHBl
-cnMubWl4aW4scj1odW5rSGVscGVycy5pbmhlcml0LHE9aHVua0hlbHBlcnMuaW5oZXJpdE1hbnkKcihQ
-Lk1oLG51bGwpCnEoUC5NaCxbSC5GSyxKLkd2LEoubTEsUC5jWCxILkU3LFAuWFMsUC5uWSxILmE3LFAu
-QW4sSC5GdSxILkpCLEguU1UsSC5SZSxILnd2LFAuUG4sSC5XVSxILkxJLEguVHAsSC5mOSxILnRlLEgu
-YnEsSC5YTyxILmtyLFAuWWssSC52aCxILk42LEguVlIsSC5FSyxILlBiLEgudFEsSC5TZCxILkpjLEgu
-RyxILmxZLFAuVzMsUC5paCxQLkZ5LFAuR1YsUC5QZixQLkZlLFAudnMsUC5PTSxQLnFoLFAuTU8sUC5r
-VCxQLnhJLFAuQ3csUC5tMCxQLnBSLFAuYm4sUC5sbSxQLmxELFAuS1AsUC5sZixQLldZLFAuVWssUC5T
-aCxQLlJ3LFAuYnosUC5pUCxQLms1LFAuS1ksUC5DRCxQLmFFLFAuTjMsUC5jOCxQLlpkLFAuUm4sUC5E
-bixQLlBFLFAuVWYsVy5pZCxXLkZrLFcuSlEsVy5HbSxXLnZELFcubTYsVy5PdyxXLlc5LFcuZFcsVy5t
-ayxXLktvLFAuaUosUC5FNCxNLkg3LFUuTEwsVS5kMixVLlNlLFUuTWwsVS55RCxVLndiLEIuajgsQi5x
-cCxULm1RLEwuWEEsTC5EOCxMLk85LEwuR2IsTS5sSSxPLnpMLFguV0QsWC5kdl0pCnEoSi5HdixbSi55
-RSxKLndlLEouTUYsSi5qZCxKLnFJLEouRHIsSC5FVCxXLkQwLFcuQXosVy5MZSxXLk5oLFcuYWUsVy5J
-QixXLm43LFcuZWEsVy5icixXLlNnLFcudTgsVy5LNyxXLlhXLFAuaEZdKQpxKEouTUYsW0ouaUMsSi5r
-ZCxKLmM1XSkKcihKLlBvLEouamQpCnEoSi5xSSxbSi5iVSxKLlZBXSkKcShQLmNYLFtILkJSLEguYlEs
-SC5pMSxILlU1LEguQU0sSC51NixILlhSLFAubVcsSC51bl0pCnEoSC5CUixbSC5aeSxILlFDXSkKcihI
-Lm9sLEguWnkpCnIoSC5VcSxILlFDKQpyKEgualYsSC5VcSkKcShQLlhTLFtILm4sSC5yMyxILkdNLFAu
-RXosSC5heixILnZWLEguRXEsUC5DNixILmtTLFAuVWQsUC5GLFAudSxQLm1wLFAudWIsUC5kcyxQLmxq
-LFAuVVYsUC5jXSkKcihQLnV5LFAublkpCnEoUC51eSxbSC53MixXLnd6LFcuZTddKQpyKEgucWosSC53
-MikKcShILmJRLFtILmFMLEguTUIsSC5pNV0pCnEoSC5hTCxbSC5uSCxILmxKLFAuaThdKQpyKEgueHks
-SC5pMSkKcShQLkFuLFtILk1ILEguU08sSC5VMV0pCnIoSC5kNSxILkFNKQpyKFAuUlUsUC5QbikKcihQ
-LkdqLFAuUlUpCnIoSC5QRCxQLkdqKQpyKEguTFAsSC5XVSkKcShILlRwLFtILkNqLEgubGMsSC5kQyxI
-LndOLEguVlgsUC50aCxQLmhhLFAuVnMsUC5GdCxQLnlILFAuV00sUC5TWCxQLkdzLFAuZGEsUC5vUSxQ
-LnBWLFAuVTcsUC52cixQLnJ0LFAuS0YsUC5aTCxQLlJULFAualosUC5ycSxQLlJXLFAuQjUsUC51TyxQ
-LnBLLFAuaGosUC5WcCxQLk9SLFAucmEsUC55USxQLnBnLFAuYzIsUC50aSxQLldGLFAubjEsUC5jUyxQ
-LlZDLFAuSlQsUC5SWixQLk1FLFAueTUsUC55SSxQLmM2LFAucWQsVy5DdixXLktTLFcuQTMsVy52TixX
-LlV2LFcuRWcsVy5FbyxXLldrLFcuSUEsVy5mbSxQLmpnLFAuVGEsUC5HRSxQLk43LFAudVEsUC5QQyxQ
-Lm10LFAuTnosUC5RUyxQLm5wLFUuTUQsVS5hTixVLmIwLEwuZSxMLlZXLEwub1osTC5qcixMLnFsLEwu
-SGksTC5CVCxMLlBZLEwuTCxMLld4LEwuQU8sTC5kTixMLkhvLEwueHosTC5JQyxMLmZDLEwublQsTC5O
-WSxMLnVlLEwuZVgsTC5FRSxMLlFMLEwuVlMsTC5URCxMLm0yLE0ucTcsTS5Ob10pCnIoSC5XMCxQLkV6
-KQpxKEgubGMsW0guengsSC5yVF0pCnIoSC5rWSxQLkM2KQpyKFAuaWwsUC5ZaykKcShQLmlsLFtILk41
-LFAudXcsVy5jZixXLlN5XSkKcShQLm1XLFtILktXLFAucTRdKQpyKEguTFosSC5FVCkKcShILkxaLFtI
-LlJHLEguV0JdKQpyKEguVlAsSC5SRykKcihILkRnLEguVlApCnIoSC5aRyxILldCKQpyKEguUGcsSC5a
-RykKcShILlBnLFtILnhqLEguZEUsSC5aQSxILmRULEguUHEsSC5lRSxILlY2XSkKcihILmlNLEgua1Mp
-CnIoUC5aZixQLlBmKQpyKFAuSmksUC5tMCkKcihQLlh2LFAucFIpCnIoUC5iNixQLlh2KQpyKFAuVmos
-UC5XWSkKcShQLlVrLFtQLkNWLFAuWmksUC5ieV0pCnIoUC53SSxQLmtUKQpxKFAud0ksW1AuVTgsUC5v
-aixQLk14LFAuRTMsUC5HWV0pCnIoUC5LOCxQLlVkKQpyKFAudHUsUC5TaCkKcihQLnU1LFAuWmkpCnEo
-UC51LFtQLmJKLFAuZVldKQpyKFAucWUsUC5EbikKcShXLkQwLFtXLnVILFcud2EsVy5LNSxXLkNtXSkK
-cShXLnVILFtXLmN2LFcubngsVy5RRixXLkNRXSkKcShXLmN2LFtXLnFFLFAuaGldKQpxKFcucUUsW1cu
-R2gsVy5mWSxXLm5CLFcuUVAsVy5oNCxXLlNOLFcubHAsVy5UYixXLkl2LFcuV1AsVy55WV0pCnIoVy5v
-SixXLkxlKQpyKFcuaEgsVy5BeikKcihXLlZiLFcuUUYpCnIoVy5mSixXLndhKQpxKFcuZWEsW1cudzYs
-Vy5ld10pCnIoVy5BaixXLnc2KQpyKFcuckIsVy5LNykKcihXLkJILFcuckIpCnIoVy53NCxXLklCKQpy
-KFcub2EsVy5YVykKcihXLnJoLFcub2EpCnIoVy5pNyxXLmNmKQpyKFAuQXMsUC5WaikKcShQLkFzLFtX
-Lkk0LFAuS2VdKQpyKFcuUk8sUC5xaCkKcihXLmV1LFcuUk8pCnIoVy54QyxQLk1PKQpyKFcuY3QsVy5t
-NikKcihQLkJmLFAuaUopCnEoUC5FNCxbUC5yNyxQLmNvXSkKcihQLlR6LFAuY28pCnIoUC5uZCxQLmhp
-KQpxKEwuRDgsW0wudnQsTC5jRF0pCnIoQi5mdixPLnpMKQpxKEIuZnYsW0UuT0YsRi5ydSxMLklWXSkK
-cyhILncyLEguUmUpCnMoSC5RQyxQLmxEKQpzKEguUkcsUC5sRCkKcyhILlZQLEguU1UpCnMoSC5XQixQ
-LmxEKQpzKEguWkcsSC5TVSkKcyhQLm5ZLFAubEQpCnMoUC5XWSxQLmxmKQpzKFAuUlUsUC5LUCkKcyhQ
-LnBSLFAubGYpCnMoVy5MZSxXLmlkKQpzKFcuSzcsUC5sRCkKcyhXLnJCLFcuR20pCnMoVy5YVyxQLmxE
-KQpzKFcub2EsVy5HbSkKcyhQLmNvLFAubEQpfSkoKQp2YXIgdj17dHlwZVVuaXZlcnNlOntlQzpuZXcg
-TWFwKCksdFI6e30sZVQ6e30sdFBWOnt9LHNFQTpbXX0sbWFuZ2xlZEdsb2JhbE5hbWVzOntJZjoiaW50
-IixDUDoiZG91YmxlIixaWjoibnVtIixxVToiU3RyaW5nIixhMjoiYm9vbCIsYzg6Ik51bGwiLHpNOiJM
-aXN0In0sbWFuZ2xlZE5hbWVzOnt9LGdldFR5cGVGcm9tTmFtZTpnZXRHbG9iYWxGcm9tTmFtZSxtZXRh
-ZGF0YTpbXSx0eXBlczpbIn4oKSIsImM4KCkiLCJjOChBaiopIiwiYzgoY3YqKSIsIkAoQCkiLCJxVShx
-VSkiLCJhMihxVSkiLCJ+KH4oKSkiLCJhMihjdixxVSxxVSxKUSkiLCJjOChAKSIsIn4oTWg/LE1oPyki
-LCJAKCkiLCJ+KHFVLEApIiwifihuNixxVSxJZikiLCJ+KHFVLHFVKSIsImEyKGtGKSIsImM4KEAsQCki
-LCJ+KHh1PHFVPikiLCJjOChlYSopIiwiYjg8Yzg+KihBaiopIiwifihBaiopIiwifihxVSxJZikiLCJ+
-KHFVLHFVPykiLCJuNihALEApIiwiYzgoQCxHeikiLCJhMih1SCkiLCJ+KElmLEApIiwifihlYSkiLCJ+
-KE1oW0d6P10pIiwiYzgoTWgsR3opIiwifih1SCx1SD8pIiwifihALEApIiwidnM8QD4oQCkiLCJhMih4
-dTxxVT4pIiwiYzgofigpKSIsInI3KEApIiwiTWg/KEApIiwiRTQoQCkiLCJhMiooSDcqKSIsIkxMKihA
-KSIsIlowPHFVKixNaCo+KihMTCopIiwiQChxVSkiLCJ+KEdELEApIiwiYzgoWjA8cVUqLE1oKj4qKSIs
-IlowPHFVLHFVPihaMDxxVSxxVT4scVUpIiwicVUqKEFqKikiLCJAKEAscVUpIiwiYzgoZXcqKSIsInFV
-KihaMDxALEA+KikiLCJ+KHFVW0BdKSIsInFVKHFVPykiLCJJZihJZixJZikiLCJ+KEApIiwiTWg/KE1o
-PykiLCJUejxAPihAKSJdLGludGVyY2VwdG9yc0J5VGFnOm51bGwsbGVhZlRhZ3M6bnVsbCxhcnJheVJ0
-aTp0eXBlb2YgU3ltYm9sPT0iZnVuY3Rpb24iJiZ0eXBlb2YgU3ltYm9sKCk9PSJzeW1ib2wiP1N5bWJv
-bCgiJHRpIik6IiR0aSJ9CkgueGIodi50eXBlVW5pdmVyc2UsSlNPTi5wYXJzZSgneyJjNSI6Ik1GIiwi
-aUMiOiJNRiIsImtkIjoiTUYiLCJyeCI6ImVhIiwiZTUiOiJlYSIsIlkwIjoiaGkiLCJ0cCI6ImhpIiwi
-RzgiOiJldyIsIk1yIjoicUUiLCJlTCI6InFFIiwiSTAiOiJ1SCIsImhzIjoidUgiLCJYZyI6IlFGIiwi
-bnIiOiJBaiIsInk0IjoidzYiLCJhUCI6IkNtIiwieGMiOiJueCIsImtKIjoibngiLCJ6VSI6IkRnIiwi
-ZGYiOiJFVCIsInlFIjp7ImEyIjpbXX0sIndlIjp7ImM4IjpbXX0sIk1GIjp7InZtIjpbXSwiRUgiOltd
-fSwiamQiOnsiek0iOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sIlBvIjp7ImpkIjpbIjEiXSwi
-ek0iOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sIm0xIjp7IkFuIjpbIjEiXX0sInFJIjp7IkNQ
-IjpbXSwiWloiOltdfSwiYlUiOnsiQ1AiOltdLCJJZiI6W10sIlpaIjpbXX0sIlZBIjp7IkNQIjpbXSwi
-WloiOltdfSwiRHIiOnsicVUiOltdLCJ2WCI6W119LCJCUiI6eyJjWCI6WyIyIl19LCJFNyI6eyJBbiI6
-WyIyIl19LCJaeSI6eyJCUiI6WyIxIiwiMiJdLCJjWCI6WyIyIl0sImNYLkUiOiIyIn0sIm9sIjp7Ilp5
-IjpbIjEiLCIyIl0sIkJSIjpbIjEiLCIyIl0sImJRIjpbIjIiXSwiY1giOlsiMiJdLCJjWC5FIjoiMiJ9
-LCJVcSI6eyJsRCI6WyIyIl0sInpNIjpbIjIiXSwiQlIiOlsiMSIsIjIiXSwiYlEiOlsiMiJdLCJjWCI6
-WyIyIl19LCJqViI6eyJVcSI6WyIxIiwiMiJdLCJsRCI6WyIyIl0sInpNIjpbIjIiXSwiQlIiOlsiMSIs
-IjIiXSwiYlEiOlsiMiJdLCJjWCI6WyIyIl0sImxELkUiOiIyIiwiY1guRSI6IjIifSwibiI6eyJYUyI6
-W119LCJyMyI6eyJYUyI6W119LCJxaiI6eyJsRCI6WyJJZiJdLCJSZSI6WyJJZiJdLCJ6TSI6WyJJZiJd
-LCJiUSI6WyJJZiJdLCJjWCI6WyJJZiJdLCJsRC5FIjoiSWYiLCJSZS5FIjoiSWYifSwiR00iOnsiWFMi
-OltdfSwiYlEiOnsiY1giOlsiMSJdfSwiYUwiOnsiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJuSCI6eyJh
-TCI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJdLCJhTC5FIjoiMSIsImNYLkUiOiIxIn0sImE3Ijp7
-IkFuIjpbIjEiXX0sImkxIjp7ImNYIjpbIjIiXSwiY1guRSI6IjIifSwieHkiOnsiaTEiOlsiMSIsIjIi
-XSwiYlEiOlsiMiJdLCJjWCI6WyIyIl0sImNYLkUiOiIyIn0sIk1IIjp7IkFuIjpbIjIiXX0sImxKIjp7
-ImFMIjpbIjIiXSwiYlEiOlsiMiJdLCJjWCI6WyIyIl0sImFMLkUiOiIyIiwiY1guRSI6IjIifSwiVTUi
-OnsiY1giOlsiMSJdLCJjWC5FIjoiMSJ9LCJTTyI6eyJBbiI6WyIxIl19LCJBTSI6eyJjWCI6WyIxIl0s
-ImNYLkUiOiIxIn0sImQ1Ijp7IkFNIjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl0sImNYLkUiOiIx
-In0sIlUxIjp7IkFuIjpbIjEiXX0sIk1CIjp7ImJRIjpbIjEiXSwiY1giOlsiMSJdLCJjWC5FIjoiMSJ9
-LCJGdSI6eyJBbiI6WyIxIl19LCJ1NiI6eyJjWCI6WyIxIl0sImNYLkUiOiIxIn0sIkpCIjp7IkFuIjpb
-IjEiXX0sIncyIjp7ImxEIjpbIjEiXSwiUmUiOlsiMSJdLCJ6TSI6WyIxIl0sImJRIjpbIjEiXSwiY1gi
-OlsiMSJdfSwid3YiOnsiR0QiOltdfSwiUEQiOnsiR2oiOlsiMSIsIjIiXSwiUlUiOlsiMSIsIjIiXSwi
-UG4iOlsiMSIsIjIiXSwiS1AiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIiXX0sIldVIjp7IlowIjpbIjEi
-LCIyIl19LCJMUCI6eyJXVSI6WyIxIiwiMiJdLCJaMCI6WyIxIiwiMiJdfSwiWFIiOnsiY1giOlsiMSJd
-LCJjWC5FIjoiMSJ9LCJMSSI6eyJ2USI6W119LCJXMCI6eyJYUyI6W119LCJheiI6eyJYUyI6W119LCJ2
-ViI6eyJYUyI6W119LCJ0ZSI6eyJSeiI6W119LCJYTyI6eyJHeiI6W119LCJUcCI6eyJFSCI6W119LCJs
-YyI6eyJFSCI6W119LCJ6eCI6eyJFSCI6W119LCJyVCI6eyJFSCI6W119LCJFcSI6eyJYUyI6W119LCJr
-WSI6eyJYUyI6W119LCJONSI6eyJZayI6WyIxIiwiMiJdLCJGbyI6WyIxIiwiMiJdLCJaMCI6WyIxIiwi
-MiJdLCJZay5LIjoiMSIsIllrLlYiOiIyIn0sImk1Ijp7ImJRIjpbIjEiXSwiY1giOlsiMSJdLCJjWC5F
-IjoiMSJ9LCJONiI6eyJBbiI6WyIxIl19LCJWUiI6eyJ3TCI6W10sInZYIjpbXX0sIkVLIjp7ImliIjpb
-XSwiT2QiOltdfSwiS1ciOnsiY1giOlsiaWIiXSwiY1guRSI6ImliIn0sIlBiIjp7IkFuIjpbImliIl19
-LCJ0USI6eyJPZCI6W119LCJ1biI6eyJjWCI6WyJPZCJdLCJjWC5FIjoiT2QifSwiU2QiOnsiQW4iOlsi
-T2QiXX0sIkVUIjp7IkFTIjpbXX0sIkxaIjp7IlhqIjpbIjEiXSwiRVQiOltdLCJBUyI6W119LCJEZyI6
-eyJsRCI6WyJDUCJdLCJYaiI6WyJDUCJdLCJ6TSI6WyJDUCJdLCJFVCI6W10sImJRIjpbIkNQIl0sIkFT
-IjpbXSwiY1giOlsiQ1AiXSwiU1UiOlsiQ1AiXSwibEQuRSI6IkNQIn0sIlBnIjp7ImxEIjpbIklmIl0s
-IlhqIjpbIklmIl0sInpNIjpbIklmIl0sIkVUIjpbXSwiYlEiOlsiSWYiXSwiQVMiOltdLCJjWCI6WyJJ
-ZiJdLCJTVSI6WyJJZiJdfSwieGoiOnsibEQiOlsiSWYiXSwiWGoiOlsiSWYiXSwiek0iOlsiSWYiXSwi
-RVQiOltdLCJiUSI6WyJJZiJdLCJBUyI6W10sImNYIjpbIklmIl0sIlNVIjpbIklmIl0sImxELkUiOiJJ
-ZiJ9LCJkRSI6eyJsRCI6WyJJZiJdLCJYaiI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJFVCI6W10sImJRIjpb
-IklmIl0sIkFTIjpbXSwiY1giOlsiSWYiXSwiU1UiOlsiSWYiXSwibEQuRSI6IklmIn0sIlpBIjp7ImxE
-IjpbIklmIl0sIlhqIjpbIklmIl0sInpNIjpbIklmIl0sIkVUIjpbXSwiYlEiOlsiSWYiXSwiQVMiOltd
-LCJjWCI6WyJJZiJdLCJTVSI6WyJJZiJdLCJsRC5FIjoiSWYifSwiZFQiOnsibEQiOlsiSWYiXSwiWGoi
-OlsiSWYiXSwiek0iOlsiSWYiXSwiRVQiOltdLCJiUSI6WyJJZiJdLCJBUyI6W10sImNYIjpbIklmIl0s
-IlNVIjpbIklmIl0sImxELkUiOiJJZiJ9LCJQcSI6eyJsRCI6WyJJZiJdLCJYaiI6WyJJZiJdLCJ6TSI6
-WyJJZiJdLCJFVCI6W10sImJRIjpbIklmIl0sIkFTIjpbXSwiY1giOlsiSWYiXSwiU1UiOlsiSWYiXSwi
-bEQuRSI6IklmIn0sImVFIjp7ImxEIjpbIklmIl0sIlhqIjpbIklmIl0sInpNIjpbIklmIl0sIkVUIjpb
-XSwiYlEiOlsiSWYiXSwiQVMiOltdLCJjWCI6WyJJZiJdLCJTVSI6WyJJZiJdLCJsRC5FIjoiSWYifSwi
-VjYiOnsibEQiOlsiSWYiXSwibjYiOltdLCJYaiI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJFVCI6W10sImJR
-IjpbIklmIl0sIkFTIjpbXSwiY1giOlsiSWYiXSwiU1UiOlsiSWYiXSwibEQuRSI6IklmIn0sImtTIjp7
-IlhTIjpbXX0sImlNIjp7IlhTIjpbXX0sIkdWIjp7IkFuIjpbIjEiXX0sInE0Ijp7ImNYIjpbIjEiXSwi
-Y1guRSI6IjEifSwiWmYiOnsiUGYiOlsiMSJdfSwidnMiOnsiYjgiOlsiMSJdfSwiQ3ciOnsiWFMiOltd
-fSwibTAiOnsiUW0iOltdfSwiSmkiOnsibTAiOltdLCJRbSI6W119LCJiNiI6eyJsZiI6WyIxIl0sInh1
-IjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl0sImxmLkUiOiIxIn0sImxtIjp7IkFuIjpbIjEiXX0s
-Im1XIjp7ImNYIjpbIjEiXX0sInV5Ijp7ImxEIjpbIjEiXSwiek0iOlsiMSJdLCJiUSI6WyIxIl0sImNY
-IjpbIjEiXX0sImlsIjp7IllrIjpbIjEiLCIyIl0sIlowIjpbIjEiLCIyIl19LCJZayI6eyJaMCI6WyIx
-IiwiMiJdfSwiUG4iOnsiWjAiOlsiMSIsIjIiXX0sIkdqIjp7IlJVIjpbIjEiLCIyIl0sIlBuIjpbIjEi
-LCIyIl0sIktQIjpbIjEiLCIyIl0sIlowIjpbIjEiLCIyIl19LCJWaiI6eyJsZiI6WyIxIl0sInh1Ijpb
-IjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJYdiI6eyJsZiI6WyIxIl0sInh1IjpbIjEiXSwiYlEi
-OlsiMSJdLCJjWCI6WyIxIl19LCJ1dyI6eyJZayI6WyJxVSIsIkAiXSwiWjAiOlsicVUiLCJAIl0sIllr
-LksiOiJxVSIsIllrLlYiOiJAIn0sImk4Ijp7ImFMIjpbInFVIl0sImJRIjpbInFVIl0sImNYIjpbInFV
-Il0sImFMLkUiOiJxVSIsImNYLkUiOiJxVSJ9LCJDViI6eyJVayI6WyJ6TTxJZj4iLCJxVSJdLCJVay5T
-Ijoiek08SWY+In0sIlU4Ijp7IndJIjpbInpNPElmPiIsInFVIl19LCJaaSI6eyJVayI6WyJxVSIsInpN
-PElmPiJdfSwiVWQiOnsiWFMiOltdfSwiSzgiOnsiWFMiOltdfSwiYnkiOnsiVWsiOlsiTWg/IiwicVUi
-XSwiVWsuUyI6Ik1oPyJ9LCJvaiI6eyJ3SSI6WyJNaD8iLCJxVSJdfSwiTXgiOnsid0kiOlsicVUiLCJN
-aD8iXX0sInU1Ijp7IlVrIjpbInFVIiwiek08SWY+Il0sIlVrLlMiOiJxVSJ9LCJFMyI6eyJ3SSI6WyJx
-VSIsInpNPElmPiJdfSwiR1kiOnsid0kiOlsiek08SWY+IiwicVUiXX0sIkNQIjp7IlpaIjpbXX0sIklm
-Ijp7IlpaIjpbXX0sInpNIjp7ImJRIjpbIjEiXSwiY1giOlsiMSJdfSwiaWIiOnsiT2QiOltdfSwieHUi
-OnsiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJxVSI6eyJ2WCI6W119LCJDNiI6eyJYUyI6W119LCJFeiI6
-eyJYUyI6W119LCJGIjp7IlhTIjpbXX0sInUiOnsiWFMiOltdfSwiYkoiOnsiWFMiOltdfSwiZVkiOnsi
-WFMiOltdfSwibXAiOnsiWFMiOltdfSwidWIiOnsiWFMiOltdfSwiZHMiOnsiWFMiOltdfSwibGoiOnsi
-WFMiOltdfSwiVVYiOnsiWFMiOltdfSwiazUiOnsiWFMiOltdfSwiS1kiOnsiWFMiOltdfSwiYyI6eyJY
-UyI6W119LCJDRCI6eyJSeiI6W119LCJhRSI6eyJSeiI6W119LCJaZCI6eyJHeiI6W119LCJSbiI6eyJC
-TCI6W119LCJEbiI6eyJpRCI6W119LCJVZiI6eyJpRCI6W119LCJxZSI6eyJpRCI6W119LCJxRSI6eyJj
-diI6W10sInVIIjpbXSwiRDAiOltdfSwiR2giOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sImZZIjp7
-ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJuQiI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiUVAi
-OnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIm54Ijp7InVIIjpbXSwiRDAiOltdfSwiUUYiOnsidUgi
-OltdLCJEMCI6W119LCJJQiI6eyJ0biI6WyJaWiJdfSwid3oiOnsibEQiOlsiMSJdLCJ6TSI6WyIxIl0s
-ImJRIjpbIjEiXSwiY1giOlsiMSJdLCJsRC5FIjoiMSJ9LCJjdiI6eyJ1SCI6W10sIkQwIjpbXX0sImhI
-Ijp7IkF6IjpbXX0sImg0Ijp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJWYiI6eyJ1SCI6W10sIkQw
-IjpbXX0sImZKIjp7IkQwIjpbXX0sIndhIjp7IkQwIjpbXX0sIkFqIjp7ImVhIjpbXX0sImU3Ijp7ImxE
-IjpbInVIIl0sInpNIjpbInVIIl0sImJRIjpbInVIIl0sImNYIjpbInVIIl0sImxELkUiOiJ1SCJ9LCJ1
-SCI6eyJEMCI6W119LCJCSCI6eyJsRCI6WyJ1SCJdLCJHbSI6WyJ1SCJdLCJ6TSI6WyJ1SCJdLCJYaiI6
-WyJ1SCJdLCJiUSI6WyJ1SCJdLCJjWCI6WyJ1SCJdLCJsRC5FIjoidUgiLCJHbS5FIjoidUgifSwiU04i
-OnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sImV3Ijp7ImVhIjpbXX0sImxwIjp7ImN2IjpbXSwidUgi
-OltdLCJEMCI6W119LCJUYiI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiSXYiOnsiY3YiOltdLCJ1
-SCI6W10sIkQwIjpbXX0sIldQIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJ5WSI6eyJjdiI6W10s
-InVIIjpbXSwiRDAiOltdfSwidzYiOnsiZWEiOltdfSwiSzUiOnsidjYiOltdLCJEMCI6W119LCJDbSI6
-eyJEMCI6W119LCJDUSI6eyJ1SCI6W10sIkQwIjpbXX0sInc0Ijp7InRuIjpbIlpaIl19LCJyaCI6eyJs
-RCI6WyJ1SCJdLCJHbSI6WyJ1SCJdLCJ6TSI6WyJ1SCJdLCJYaiI6WyJ1SCJdLCJiUSI6WyJ1SCJdLCJj
-WCI6WyJ1SCJdLCJsRC5FIjoidUgiLCJHbS5FIjoidUgifSwiY2YiOnsiWWsiOlsicVUiLCJxVSJdLCJa
-MCI6WyJxVSIsInFVIl19LCJpNyI6eyJZayI6WyJxVSIsInFVIl0sIlowIjpbInFVIiwicVUiXSwiWWsu
-SyI6InFVIiwiWWsuViI6InFVIn0sIlN5Ijp7IllrIjpbInFVIiwicVUiXSwiWjAiOlsicVUiLCJxVSJd
-LCJZay5LIjoicVUiLCJZay5WIjoicVUifSwiSTQiOnsibGYiOlsicVUiXSwieHUiOlsicVUiXSwiYlEi
-OlsicVUiXSwiY1giOlsicVUiXSwibGYuRSI6InFVIn0sIlJPIjp7InFoIjpbIjEiXX0sImV1Ijp7IlJP
-IjpbIjEiXSwicWgiOlsiMSJdfSwieEMiOnsiTU8iOlsiMSJdfSwiSlEiOnsia0YiOltdfSwidkQiOnsi
-a0YiOltdfSwibTYiOnsia0YiOltdfSwiY3QiOnsia0YiOltdfSwiT3ciOnsia0YiOltdfSwiVzkiOnsi
-QW4iOlsiMSJdfSwiZFciOnsidjYiOltdLCJEMCI6W119LCJtayI6eyJ5MCI6W119LCJLbyI6eyJvbiI6
-W119LCJBcyI6eyJsZiI6WyJxVSJdLCJ4dSI6WyJxVSJdLCJiUSI6WyJxVSJdLCJjWCI6WyJxVSJdfSwi
-cjciOnsiRTQiOltdfSwiVHoiOnsibEQiOlsiMSJdLCJ6TSI6WyIxIl0sImJRIjpbIjEiXSwiRTQiOltd
-LCJjWCI6WyIxIl0sImxELkUiOiIxIn0sIm5kIjp7ImhpIjpbXSwiY3YiOltdLCJ1SCI6W10sIkQwIjpb
-XX0sIktlIjp7ImxmIjpbInFVIl0sInh1IjpbInFVIl0sImJRIjpbInFVIl0sImNYIjpbInFVIl0sImxm
-LkUiOiJxVSJ9LCJoaSI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiWEEiOnsia0YiOltdfSwidnQi
-OnsiRDgiOltdfSwiY0QiOnsiRDgiOltdfSwiZHYiOnsiUnoiOltdfSwiT0YiOnsiZnYiOltdfSwicnUi
-OnsiZnYiOltdfSwiSVYiOnsiZnYiOltdfSwibjYiOnsiek0iOlsiSWYiXSwiYlEiOlsiSWYiXSwiY1gi
-OlsiSWYiXSwiQVMiOltdfX0nKSkKSC5GRih2LnR5cGVVbml2ZXJzZSxKU09OLnBhcnNlKCd7IncyIjox
-LCJRQyI6MiwiTFoiOjEsImtUIjoyLCJtVyI6MSwidXkiOjEsImlsIjoyLCJWaiI6MSwiWHYiOjEsIm5Z
-IjoxLCJXWSI6MSwicFIiOjEsImNvIjoxfScpKQp2YXIgdT17bDoiQ2Fubm90IGV4dHJhY3QgYSBmaWxl
-IHBhdGggZnJvbSBhIFVSSSB3aXRoIGEgZnJhZ21lbnQgY29tcG9uZW50IixpOiJDYW5ub3QgZXh0cmFj
-dCBhIGZpbGUgcGF0aCBmcm9tIGEgVVJJIHdpdGggYSBxdWVyeSBjb21wb25lbnQiLGo6IkNhbm5vdCBl
-eHRyYWN0IGEgbm9uLVdpbmRvd3MgZmlsZSBwYXRoIGZyb20gYSBmaWxlIFVSSSB3aXRoIGFuIGF1dGhv
-cml0eSIsZzoiYG51bGxgIGVuY291bnRlcmVkIGFzIHRoZSByZXN1bHQgZnJvbSBleHByZXNzaW9uIHdp
-dGggdHlwZSBgTmV2ZXJgLiIsZDoiYXJlYS1hbmFseXplcixhbmFseXplci1ubmJkLW1pZ3JhdGlvbix0
-eXBlLWJ1ZyJ9CnZhciB0PShmdW5jdGlvbiBydGlpKCl7dmFyIHM9SC5OMApyZXR1cm57bjpzKCJDdyIp
-LGNSOnMoIm5CIiksdzpzKCJBeiIpLHA6cygiUVAiKSxnRjpzKCJQRDxHRCxAPiIpLGI6cygiYlE8QD4i
-KSxoOnMoImN2IikscjpzKCJYUyIpLEI6cygiZWEiKSxhUzpzKCJEMCIpLGc4OnMoIlJ6IiksYzg6cygi
-aEgiKSxZOnMoIkVIIiksZDpzKCJiODxAPiIpLEk6cygiU2ciKSxvOnMoInZRIiksZWg6cygiY1g8dUg+
-IiksUTpzKCJjWDxxVT4iKSx1OnMoImNYPEA+IiksdjpzKCJqZDxrRj4iKSxzOnMoImpkPHFVPiIpLGdO
-OnMoImpkPG42PiIpLHg6cygiamQ8QD4iKSxhOnMoImpkPElmPiIpLGQ3OnMoImpkPFNlKj4iKSxoNDpz
-KCJqZDxqOCo+IiksRzpzKCJqZDxaMDxxVSosTWgqPio+IiksY1E6cygiamQ8RDgqPiIpLGk6cygiamQ8
-cVUqPiIpLGFBOnMoImpkPHlEKj4iKSxhSjpzKCJqZDx3Yio+IiksVjpzKCJqZDxJZio+IiksZDQ6cygi
-amQ8cVU/PiIpLFQ6cygid2UiKSxlSDpzKCJ2bSIpLEQ6cygiYzUiKSxhVTpzKCJYajxAPiIpLGFtOnMo
-IlR6PEA+IiksZW86cygiTjU8R0QsQD4iKSxkejpzKCJoRiIpLEU6cygiek08cVU+IiksajpzKCJ6TTxA
-PiIpLEw6cygiek08SWY+IiksSjpzKCJaMDxxVSxxVT4iKSxmOnMoIlowPEAsQD4iKSxkbzpzKCJsSjxx
-VSxAPiIpLGZqOnMoImxKPHFVKixxVT4iKSxkRTpzKCJFVCIpLGJtOnMoIlY2IiksQTpzKCJ1SCIpLGY2
-OnMoImtGIiksUDpzKCJjOCIpLEs6cygiTWgiKSxxOnMoInRuPFpaPiIpLGZ2OnMoIndMIiksZXc6cygi
-bmQiKSxDOnMoInh1PHFVPiIpLGw6cygiR3oiKSxOOnMoInFVIiksZDA6cygicVUocVUqKSIpLGc3OnMo
-ImhpIiksZm86cygiR0QiKSxhVzpzKCJ5WSIpLGFrOnMoIkFTIiksZ2M6cygibjYiKSxiSjpzKCJrZCIp
-LGR3OnMoIkdqPHFVLHFVPiIpLGREOnMoImlEIiksZUo6cygidTY8cVU+IiksZzQ6cygiSzUiKSxjaTpz
-KCJ2NiIpLGcyOnMoIkNtIiksYkM6cygiWmY8ZkoqPiIpLGg5OnMoIkNRIiksYWM6cygiZTciKSxrOnMo
-ImV1PEFqKj4iKSxSOnMoInd6PGN2Kj4iKSxjOnMoInZzPEA+IiksZko6cygidnM8SWY+IiksZ1Y6cygi
-dnM8ZkoqPiIpLGNyOnMoIkpRIikseTpzKCJhMiIpLGFsOnMoImEyKE1oKSIpLGdSOnMoIkNQIiksejpz
-KCJAIiksZk86cygiQCgpIiksYkk6cygiQChNaCkiKSxhZzpzKCJAKE1oLEd6KSIpLGJVOnMoIkAoeHU8
-cVU+KSIpLGRPOnMoIkAocVUpIiksYjg6cygiQChALEApIiksUzpzKCJJZiIpLGRkOnMoIkdoKiIpLGc6
-cygiY3YqIiksYUw6cygiZWEqIiksYVg6cygiTEwqIiksZkU6cygiSDcqIiksVTpzKCJjWDxAPioiKSxk
-SDpzKCJFNCoiKSxmSzpzKCJ6TTxAPioiKSxkXzpzKCJ6TTxqOCo+KiIpLGRwOnMoInpNPFowPHFVKixN
-aCo+Kj4qIiksbTpzKCJ6TTxNaCo+KiIpLGF3OnMoIlowPEAsQD4qIiksdDpzKCJaMDxxVSosTWgqPioi
-KSxPOnMoIkFqKiIpLGNGOnMoIjAmKiIpLF86cygiTWgqIiksZVE6cygiZXcqIiksWDpzKCJxVSoiKSxj
-aDpzKCJEMD8iKSxiRzpzKCJiODxjOD4/IiksYms6cygiek08cVU+PyIpLGJNOnMoInpNPEA+PyIpLGNa
-OnMoIlowPHFVLHFVPj8iKSxjOTpzKCJaMDxxVSxAPj8iKSxXOnMoIk1oPyIpLEY6cygiRmU8QCxAPj8i
-KSxlOnMoImJuPyIpLGI3OnMoImEyKE1oKT8iKSxidzpzKCJAKGVhKT8iKSxmVjpzKCJNaD8oTWg/LE1o
-Pyk/IiksZEE6cygiTWg/KEApPyIpLFo6cygifigpPyIpLGViOnMoIn4oZXcqKT8iKSxkaTpzKCJaWiIp
-LEg6cygifiIpLE06cygifigpIiksZUE6cygifihxVSxxVSkiKSxjQTpzKCJ+KHFVLEApIil9fSkoKTso
-ZnVuY3Rpb24gY29uc3RhbnRzKCl7dmFyIHM9aHVua0hlbHBlcnMubWFrZUNvbnN0TGlzdApDLnhuPVcu
-R2gucHJvdG90eXBlCkMuUlk9Vy5RUC5wcm90b3R5cGUKQy5tSD1XLmFlLnByb3RvdHlwZQpDLkJaPVcu
-VmIucHJvdG90eXBlCkMuRHQ9Vy5mSi5wcm90b3R5cGUKQy5Paz1KLkd2LnByb3RvdHlwZQpDLk5tPUou
-amQucHJvdG90eXBlCkMuam49Si5iVS5wcm90b3R5cGUKQy5qTj1KLndlLnByb3RvdHlwZQpDLkNEPUou
-cUkucHJvdG90eXBlCkMueEI9Si5Eci5wcm90b3R5cGUKQy5ERz1KLmM1LnByb3RvdHlwZQpDLkV4PVcu
-dTgucHJvdG90eXBlCkMuTkE9SC5WNi5wcm90b3R5cGUKQy50NT1XLkJILnByb3RvdHlwZQpDLkx0PVcu
-U04ucHJvdG90eXBlCkMuWlE9Si5pQy5wcm90b3R5cGUKQy5JZT1XLlRiLnByb3RvdHlwZQpDLnZCPUou
-a2QucHJvdG90eXBlCkMub2w9Vy5LNS5wcm90b3R5cGUKQy55OD1uZXcgUC5VOCgpCkMuaDk9bmV3IFAu
-Q1YoKQpDLkd3PW5ldyBILkZ1KEguTjAoIkZ1PGM4PiIpKQpDLk80PWZ1bmN0aW9uIGdldFRhZ0ZhbGxi
-YWNrKG8pIHsKICB2YXIgcyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKTsKICByZXR1
-cm4gcy5zdWJzdHJpbmcoOCwgcy5sZW5ndGggLSAxKTsKfQpDLllxPWZ1bmN0aW9uKCkgewogIHZhciB0
-b1N0cmluZ0Z1bmN0aW9uID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZzsKICBmdW5jdGlvbiBnZXRU
-YWcobykgewogICAgdmFyIHMgPSB0b1N0cmluZ0Z1bmN0aW9uLmNhbGwobyk7CiAgICByZXR1cm4gcy5z
-dWJzdHJpbmcoOCwgcy5sZW5ndGggLSAxKTsKICB9CiAgZnVuY3Rpb24gZ2V0VW5rbm93blRhZyhvYmpl
-Y3QsIHRhZykgewogICAgaWYgKC9eSFRNTFtBLVpdLipFbGVtZW50JC8udGVzdCh0YWcpKSB7CiAgICAg
-IHZhciBuYW1lID0gdG9TdHJpbmdGdW5jdGlvbi5jYWxsKG9iamVjdCk7CiAgICAgIGlmIChuYW1lID09
-ICJbb2JqZWN0IE9iamVjdF0iKSByZXR1cm4gbnVsbDsKICAgICAgcmV0dXJuICJIVE1MRWxlbWVudCI7
-CiAgICB9CiAgfQogIGZ1bmN0aW9uIGdldFVua25vd25UYWdHZW5lcmljQnJvd3NlcihvYmplY3QsIHRh
-ZykgewogICAgaWYgKHNlbGYuSFRNTEVsZW1lbnQgJiYgb2JqZWN0IGluc3RhbmNlb2YgSFRNTEVsZW1l
-bnQpIHJldHVybiAiSFRNTEVsZW1lbnQiOwogICAgcmV0dXJuIGdldFVua25vd25UYWcob2JqZWN0LCB0
-YWcpOwogIH0KICBmdW5jdGlvbiBwcm90b3R5cGVGb3JUYWcodGFnKSB7CiAgICBpZiAodHlwZW9mIHdp
-bmRvdyA9PSAidW5kZWZpbmVkIikgcmV0dXJuIG51bGw7CiAgICBpZiAodHlwZW9mIHdpbmRvd1t0YWdd
-ID09ICJ1bmRlZmluZWQiKSByZXR1cm4gbnVsbDsKICAgIHZhciBjb25zdHJ1Y3RvciA9IHdpbmRvd1t0
-YWddOwogICAgaWYgKHR5cGVvZiBjb25zdHJ1Y3RvciAhPSAiZnVuY3Rpb24iKSByZXR1cm4gbnVsbDsK
-ICAgIHJldHVybiBjb25zdHJ1Y3Rvci5wcm90b3R5cGU7CiAgfQogIGZ1bmN0aW9uIGRpc2NyaW1pbmF0
-b3IodGFnKSB7IHJldHVybiBudWxsOyB9CiAgdmFyIGlzQnJvd3NlciA9IHR5cGVvZiBuYXZpZ2F0b3Ig
-PT0gIm9iamVjdCI7CiAgcmV0dXJuIHsKICAgIGdldFRhZzogZ2V0VGFnLAogICAgZ2V0VW5rbm93blRh
-ZzogaXNCcm93c2VyID8gZ2V0VW5rbm93blRhZ0dlbmVyaWNCcm93c2VyIDogZ2V0VW5rbm93blRhZywK
-ICAgIHByb3RvdHlwZUZvclRhZzogcHJvdG90eXBlRm9yVGFnLAogICAgZGlzY3JpbWluYXRvcjogZGlz
-Y3JpbWluYXRvciB9Owp9CkMud2I9ZnVuY3Rpb24oZ2V0VGFnRmFsbGJhY2spIHsKICByZXR1cm4gZnVu
-Y3Rpb24oaG9va3MpIHsKICAgIGlmICh0eXBlb2YgbmF2aWdhdG9yICE9ICJvYmplY3QiKSByZXR1cm4g
-aG9va3M7CiAgICB2YXIgdWEgPSBuYXZpZ2F0b3IudXNlckFnZW50OwogICAgaWYgKHVhLmluZGV4T2Yo
-IkR1bXBSZW5kZXJUcmVlIikgPj0gMCkgcmV0dXJuIGhvb2tzOwogICAgaWYgKHVhLmluZGV4T2YoIkNo
-cm9tZSIpID49IDApIHsKICAgICAgZnVuY3Rpb24gY29uZmlybShwKSB7CiAgICAgICAgcmV0dXJuIHR5
-cGVvZiB3aW5kb3cgPT0gIm9iamVjdCIgJiYgd2luZG93W3BdICYmIHdpbmRvd1twXS5uYW1lID09IHA7
-CiAgICAgIH0KICAgICAgaWYgKGNvbmZpcm0oIldpbmRvdyIpICYmIGNvbmZpcm0oIkhUTUxFbGVtZW50
-IikpIHJldHVybiBob29rczsKICAgIH0KICAgIGhvb2tzLmdldFRhZyA9IGdldFRhZ0ZhbGxiYWNrOwog
-IH07Cn0KQy5LVT1mdW5jdGlvbihob29rcykgewogIGlmICh0eXBlb2YgZGFydEV4cGVyaW1lbnRhbEZp
-eHVwR2V0VGFnICE9ICJmdW5jdGlvbiIpIHJldHVybiBob29rczsKICBob29rcy5nZXRUYWcgPSBkYXJ0
-RXhwZXJpbWVudGFsRml4dXBHZXRUYWcoaG9va3MuZ2V0VGFnKTsKfQpDLmZRPWZ1bmN0aW9uKGhvb2tz
-KSB7CiAgdmFyIGdldFRhZyA9IGhvb2tzLmdldFRhZzsKICB2YXIgcHJvdG90eXBlRm9yVGFnID0gaG9v
-a3MucHJvdG90eXBlRm9yVGFnOwogIGZ1bmN0aW9uIGdldFRhZ0ZpeGVkKG8pIHsKICAgIHZhciB0YWcg
-PSBnZXRUYWcobyk7CiAgICBpZiAodGFnID09ICJEb2N1bWVudCIpIHsKICAgICAgaWYgKCEhby54bWxW
-ZXJzaW9uKSByZXR1cm4gIiFEb2N1bWVudCI7CiAgICAgIHJldHVybiAiIUhUTUxEb2N1bWVudCI7CiAg
-ICB9CiAgICByZXR1cm4gdGFnOwogIH0KICBmdW5jdGlvbiBwcm90b3R5cGVGb3JUYWdGaXhlZCh0YWcp
-IHsKICAgIGlmICh0YWcgPT0gIkRvY3VtZW50IikgcmV0dXJuIG51bGw7CiAgICByZXR1cm4gcHJvdG90
-eXBlRm9yVGFnKHRhZyk7CiAgfQogIGhvb2tzLmdldFRhZyA9IGdldFRhZ0ZpeGVkOwogIGhvb2tzLnBy
-b3RvdHlwZUZvclRhZyA9IHByb3RvdHlwZUZvclRhZ0ZpeGVkOwp9CkMuZGs9ZnVuY3Rpb24oaG9va3Mp
-IHsKICB2YXIgdXNlckFnZW50ID0gdHlwZW9mIG5hdmlnYXRvciA9PSAib2JqZWN0IiA/IG5hdmlnYXRv
-ci51c2VyQWdlbnQgOiAiIjsKICBpZiAodXNlckFnZW50LmluZGV4T2YoIkZpcmVmb3giKSA9PSAtMSkg
-cmV0dXJuIGhvb2tzOwogIHZhciBnZXRUYWcgPSBob29rcy5nZXRUYWc7CiAgdmFyIHF1aWNrTWFwID0g
-ewogICAgIkJlZm9yZVVubG9hZEV2ZW50IjogIkV2ZW50IiwKICAgICJEYXRhVHJhbnNmZXIiOiAiQ2xp
-cGJvYXJkIiwKICAgICJHZW9HZW9sb2NhdGlvbiI6ICJHZW9sb2NhdGlvbiIsCiAgICAiTG9jYXRpb24i
-OiAiIUxvY2F0aW9uIiwKICAgICJXb3JrZXJNZXNzYWdlRXZlbnQiOiAiTWVzc2FnZUV2ZW50IiwKICAg
-ICJYTUxEb2N1bWVudCI6ICIhRG9jdW1lbnQifTsKICBmdW5jdGlvbiBnZXRUYWdGaXJlZm94KG8pIHsK
-ICAgIHZhciB0YWcgPSBnZXRUYWcobyk7CiAgICByZXR1cm4gcXVpY2tNYXBbdGFnXSB8fCB0YWc7CiAg
-fQogIGhvb2tzLmdldFRhZyA9IGdldFRhZ0ZpcmVmb3g7Cn0KQy54aT1mdW5jdGlvbihob29rcykgewog
-IHZhciB1c2VyQWdlbnQgPSB0eXBlb2YgbmF2aWdhdG9yID09ICJvYmplY3QiID8gbmF2aWdhdG9yLnVz
-ZXJBZ2VudCA6ICIiOwogIGlmICh1c2VyQWdlbnQuaW5kZXhPZigiVHJpZGVudC8iKSA9PSAtMSkgcmV0
-dXJuIGhvb2tzOwogIHZhciBnZXRUYWcgPSBob29rcy5nZXRUYWc7CiAgdmFyIHF1aWNrTWFwID0gewog
-ICAgIkJlZm9yZVVubG9hZEV2ZW50IjogIkV2ZW50IiwKICAgICJEYXRhVHJhbnNmZXIiOiAiQ2xpcGJv
-YXJkIiwKICAgICJIVE1MRERFbGVtZW50IjogIkhUTUxFbGVtZW50IiwKICAgICJIVE1MRFRFbGVtZW50
-IjogIkhUTUxFbGVtZW50IiwKICAgICJIVE1MUGhyYXNlRWxlbWVudCI6ICJIVE1MRWxlbWVudCIsCiAg
-ICAiUG9zaXRpb24iOiAiR2VvcG9zaXRpb24iCiAgfTsKICBmdW5jdGlvbiBnZXRUYWdJRShvKSB7CiAg
-ICB2YXIgdGFnID0gZ2V0VGFnKG8pOwogICAgdmFyIG5ld1RhZyA9IHF1aWNrTWFwW3RhZ107CiAgICBp
-ZiAobmV3VGFnKSByZXR1cm4gbmV3VGFnOwogICAgaWYgKHRhZyA9PSAiT2JqZWN0IikgewogICAgICBp
-ZiAod2luZG93LkRhdGFWaWV3ICYmIChvIGluc3RhbmNlb2Ygd2luZG93LkRhdGFWaWV3KSkgcmV0dXJu
-ICJEYXRhVmlldyI7CiAgICB9CiAgICByZXR1cm4gdGFnOwogIH0KICBmdW5jdGlvbiBwcm90b3R5cGVG
-b3JUYWdJRSh0YWcpIHsKICAgIHZhciBjb25zdHJ1Y3RvciA9IHdpbmRvd1t0YWddOwogICAgaWYgKGNv
-bnN0cnVjdG9yID09IG51bGwpIHJldHVybiBudWxsOwogICAgcmV0dXJuIGNvbnN0cnVjdG9yLnByb3Rv
-dHlwZTsKICB9CiAgaG9va3MuZ2V0VGFnID0gZ2V0VGFnSUU7CiAgaG9va3MucHJvdG90eXBlRm9yVGFn
-ID0gcHJvdG90eXBlRm9yVGFnSUU7Cn0KQy5pNz1mdW5jdGlvbihob29rcykgeyByZXR1cm4gaG9va3M7
-IH0KCkMuQ3Q9bmV3IFAuYnkoKQpDLkVxPW5ldyBQLms1KCkKQy54TT1uZXcgUC51NSgpCkMuUWs9bmV3
-IFAuRTMoKQpDLk52PW5ldyBILmtyKCkKQy5OVT1uZXcgUC5KaSgpCkMucGQ9bmV3IFAuWmQoKQpDLkFk
-PW5ldyBNLkg3KDAsIkhpbnRBY3Rpb25LaW5kLmFkZE51bGxhYmxlSGludCIpCkMubmU9bmV3IE0uSDco
-MSwiSGludEFjdGlvbktpbmQuYWRkTm9uTnVsbGFibGVIaW50IikKQy5teT1uZXcgTS5INygyLCJIaW50
-QWN0aW9uS2luZC5jaGFuZ2VUb051bGxhYmxlSGludCIpCkMucng9bmV3IE0uSDcoMywiSGludEFjdGlv
-bktpbmQuY2hhbmdlVG9Ob25OdWxsYWJsZUhpbnQiKQpDLndWPW5ldyBNLkg3KDQsIkhpbnRBY3Rpb25L
-aW5kLnJlbW92ZU51bGxhYmxlSGludCIpCkMuZlI9bmV3IE0uSDcoNSwiSGludEFjdGlvbktpbmQucmVt
-b3ZlTm9uTnVsbGFibGVIaW50IikKQy5BMz1uZXcgUC5NeChudWxsKQpDLm5YPW5ldyBQLm9qKG51bGwp
-CkMuY3c9bmV3IEwuR2IoMCwiVW5pdE1pZ3JhdGlvblN0YXR1cy5hbHJlYWR5TWlncmF0ZWQiKQpDLmRj
-PW5ldyBMLkdiKDEsIlVuaXRNaWdyYXRpb25TdGF0dXMuaW5kZXRlcm1pbmF0ZSIpCkMuV0Q9bmV3IEwu
-R2IoMiwiVW5pdE1pZ3JhdGlvblN0YXR1cy5taWdyYXRpbmciKQpDLlhqPW5ldyBMLkdiKDMsIlVuaXRN
-aWdyYXRpb25TdGF0dXMub3B0aW5nT3V0IikKQy5sMD1ILlZNKHMoW0MuY3csQy5kYyxDLldELEMuWGpd
-KSxILk4wKCJqZDxHYio+IikpCkMuYWs9SC5WTShzKFswLDAsMzI3NzYsMzM3OTIsMSwxMDI0MCwwLDBd
-KSx0LlYpCkMuY209SC5WTShzKFsiKjo6Y2xhc3MiLCIqOjpkaXIiLCIqOjpkcmFnZ2FibGUiLCIqOjpo
-aWRkZW4iLCIqOjppZCIsIio6OmluZXJ0IiwiKjo6aXRlbXByb3AiLCIqOjppdGVtcmVmIiwiKjo6aXRl
-bXNjb3BlIiwiKjo6bGFuZyIsIio6OnNwZWxsY2hlY2siLCIqOjp0aXRsZSIsIio6OnRyYW5zbGF0ZSIs
-IkE6OmFjY2Vzc2tleSIsIkE6OmNvb3JkcyIsIkE6OmhyZWZsYW5nIiwiQTo6bmFtZSIsIkE6OnNoYXBl
-IiwiQTo6dGFiaW5kZXgiLCJBOjp0YXJnZXQiLCJBOjp0eXBlIiwiQVJFQTo6YWNjZXNza2V5IiwiQVJF
-QTo6YWx0IiwiQVJFQTo6Y29vcmRzIiwiQVJFQTo6bm9ocmVmIiwiQVJFQTo6c2hhcGUiLCJBUkVBOjp0
-YWJpbmRleCIsIkFSRUE6OnRhcmdldCIsIkFVRElPOjpjb250cm9scyIsIkFVRElPOjpsb29wIiwiQVVE
-SU86Om1lZGlhZ3JvdXAiLCJBVURJTzo6bXV0ZWQiLCJBVURJTzo6cHJlbG9hZCIsIkJETzo6ZGlyIiwi
-Qk9EWTo6YWxpbmsiLCJCT0RZOjpiZ2NvbG9yIiwiQk9EWTo6bGluayIsIkJPRFk6OnRleHQiLCJCT0RZ
-Ojp2bGluayIsIkJSOjpjbGVhciIsIkJVVFRPTjo6YWNjZXNza2V5IiwiQlVUVE9OOjpkaXNhYmxlZCIs
-IkJVVFRPTjo6bmFtZSIsIkJVVFRPTjo6dGFiaW5kZXgiLCJCVVRUT046OnR5cGUiLCJCVVRUT046OnZh
-bHVlIiwiQ0FOVkFTOjpoZWlnaHQiLCJDQU5WQVM6OndpZHRoIiwiQ0FQVElPTjo6YWxpZ24iLCJDT0w6
-OmFsaWduIiwiQ09MOjpjaGFyIiwiQ09MOjpjaGFyb2ZmIiwiQ09MOjpzcGFuIiwiQ09MOjp2YWxpZ24i
-LCJDT0w6OndpZHRoIiwiQ09MR1JPVVA6OmFsaWduIiwiQ09MR1JPVVA6OmNoYXIiLCJDT0xHUk9VUDo6
-Y2hhcm9mZiIsIkNPTEdST1VQOjpzcGFuIiwiQ09MR1JPVVA6OnZhbGlnbiIsIkNPTEdST1VQOjp3aWR0
-aCIsIkNPTU1BTkQ6OmNoZWNrZWQiLCJDT01NQU5EOjpjb21tYW5kIiwiQ09NTUFORDo6ZGlzYWJsZWQi
-LCJDT01NQU5EOjpsYWJlbCIsIkNPTU1BTkQ6OnJhZGlvZ3JvdXAiLCJDT01NQU5EOjp0eXBlIiwiREFU
-QTo6dmFsdWUiLCJERUw6OmRhdGV0aW1lIiwiREVUQUlMUzo6b3BlbiIsIkRJUjo6Y29tcGFjdCIsIkRJ
-Vjo6YWxpZ24iLCJETDo6Y29tcGFjdCIsIkZJRUxEU0VUOjpkaXNhYmxlZCIsIkZPTlQ6OmNvbG9yIiwi
-Rk9OVDo6ZmFjZSIsIkZPTlQ6OnNpemUiLCJGT1JNOjphY2NlcHQiLCJGT1JNOjphdXRvY29tcGxldGUi
-LCJGT1JNOjplbmN0eXBlIiwiRk9STTo6bWV0aG9kIiwiRk9STTo6bmFtZSIsIkZPUk06Om5vdmFsaWRh
-dGUiLCJGT1JNOjp0YXJnZXQiLCJGUkFNRTo6bmFtZSIsIkgxOjphbGlnbiIsIkgyOjphbGlnbiIsIkgz
-OjphbGlnbiIsIkg0OjphbGlnbiIsIkg1OjphbGlnbiIsIkg2OjphbGlnbiIsIkhSOjphbGlnbiIsIkhS
-Ojpub3NoYWRlIiwiSFI6OnNpemUiLCJIUjo6d2lkdGgiLCJIVE1MOjp2ZXJzaW9uIiwiSUZSQU1FOjph
-bGlnbiIsIklGUkFNRTo6ZnJhbWVib3JkZXIiLCJJRlJBTUU6OmhlaWdodCIsIklGUkFNRTo6bWFyZ2lu
-aGVpZ2h0IiwiSUZSQU1FOjptYXJnaW53aWR0aCIsIklGUkFNRTo6d2lkdGgiLCJJTUc6OmFsaWduIiwi
-SU1HOjphbHQiLCJJTUc6OmJvcmRlciIsIklNRzo6aGVpZ2h0IiwiSU1HOjpoc3BhY2UiLCJJTUc6Omlz
-bWFwIiwiSU1HOjpuYW1lIiwiSU1HOjp1c2VtYXAiLCJJTUc6OnZzcGFjZSIsIklNRzo6d2lkdGgiLCJJ
-TlBVVDo6YWNjZXB0IiwiSU5QVVQ6OmFjY2Vzc2tleSIsIklOUFVUOjphbGlnbiIsIklOUFVUOjphbHQi
-LCJJTlBVVDo6YXV0b2NvbXBsZXRlIiwiSU5QVVQ6OmF1dG9mb2N1cyIsIklOUFVUOjpjaGVja2VkIiwi
-SU5QVVQ6OmRpc2FibGVkIiwiSU5QVVQ6OmlucHV0bW9kZSIsIklOUFVUOjppc21hcCIsIklOUFVUOjps
-aXN0IiwiSU5QVVQ6Om1heCIsIklOUFVUOjptYXhsZW5ndGgiLCJJTlBVVDo6bWluIiwiSU5QVVQ6Om11
-bHRpcGxlIiwiSU5QVVQ6Om5hbWUiLCJJTlBVVDo6cGxhY2Vob2xkZXIiLCJJTlBVVDo6cmVhZG9ubHki
-LCJJTlBVVDo6cmVxdWlyZWQiLCJJTlBVVDo6c2l6ZSIsIklOUFVUOjpzdGVwIiwiSU5QVVQ6OnRhYmlu
-ZGV4IiwiSU5QVVQ6OnR5cGUiLCJJTlBVVDo6dXNlbWFwIiwiSU5QVVQ6OnZhbHVlIiwiSU5TOjpkYXRl
-dGltZSIsIktFWUdFTjo6ZGlzYWJsZWQiLCJLRVlHRU46OmtleXR5cGUiLCJLRVlHRU46Om5hbWUiLCJM
-QUJFTDo6YWNjZXNza2V5IiwiTEFCRUw6OmZvciIsIkxFR0VORDo6YWNjZXNza2V5IiwiTEVHRU5EOjph
-bGlnbiIsIkxJOjp0eXBlIiwiTEk6OnZhbHVlIiwiTElOSzo6c2l6ZXMiLCJNQVA6Om5hbWUiLCJNRU5V
-Ojpjb21wYWN0IiwiTUVOVTo6bGFiZWwiLCJNRU5VOjp0eXBlIiwiTUVURVI6OmhpZ2giLCJNRVRFUjo6
-bG93IiwiTUVURVI6Om1heCIsIk1FVEVSOjptaW4iLCJNRVRFUjo6dmFsdWUiLCJPQkpFQ1Q6OnR5cGVt
-dXN0bWF0Y2giLCJPTDo6Y29tcGFjdCIsIk9MOjpyZXZlcnNlZCIsIk9MOjpzdGFydCIsIk9MOjp0eXBl
-IiwiT1BUR1JPVVA6OmRpc2FibGVkIiwiT1BUR1JPVVA6OmxhYmVsIiwiT1BUSU9OOjpkaXNhYmxlZCIs
-Ik9QVElPTjo6bGFiZWwiLCJPUFRJT046OnNlbGVjdGVkIiwiT1BUSU9OOjp2YWx1ZSIsIk9VVFBVVDo6
-Zm9yIiwiT1VUUFVUOjpuYW1lIiwiUDo6YWxpZ24iLCJQUkU6OndpZHRoIiwiUFJPR1JFU1M6Om1heCIs
-IlBST0dSRVNTOjptaW4iLCJQUk9HUkVTUzo6dmFsdWUiLCJTRUxFQ1Q6OmF1dG9jb21wbGV0ZSIsIlNF
-TEVDVDo6ZGlzYWJsZWQiLCJTRUxFQ1Q6Om11bHRpcGxlIiwiU0VMRUNUOjpuYW1lIiwiU0VMRUNUOjpy
-ZXF1aXJlZCIsIlNFTEVDVDo6c2l6ZSIsIlNFTEVDVDo6dGFiaW5kZXgiLCJTT1VSQ0U6OnR5cGUiLCJU
-QUJMRTo6YWxpZ24iLCJUQUJMRTo6Ymdjb2xvciIsIlRBQkxFOjpib3JkZXIiLCJUQUJMRTo6Y2VsbHBh
-ZGRpbmciLCJUQUJMRTo6Y2VsbHNwYWNpbmciLCJUQUJMRTo6ZnJhbWUiLCJUQUJMRTo6cnVsZXMiLCJU
-QUJMRTo6c3VtbWFyeSIsIlRBQkxFOjp3aWR0aCIsIlRCT0RZOjphbGlnbiIsIlRCT0RZOjpjaGFyIiwi
-VEJPRFk6OmNoYXJvZmYiLCJUQk9EWTo6dmFsaWduIiwiVEQ6OmFiYnIiLCJURDo6YWxpZ24iLCJURDo6
-YXhpcyIsIlREOjpiZ2NvbG9yIiwiVEQ6OmNoYXIiLCJURDo6Y2hhcm9mZiIsIlREOjpjb2xzcGFuIiwi
-VEQ6OmhlYWRlcnMiLCJURDo6aGVpZ2h0IiwiVEQ6Om5vd3JhcCIsIlREOjpyb3dzcGFuIiwiVEQ6OnNj
-b3BlIiwiVEQ6OnZhbGlnbiIsIlREOjp3aWR0aCIsIlRFWFRBUkVBOjphY2Nlc3NrZXkiLCJURVhUQVJF
-QTo6YXV0b2NvbXBsZXRlIiwiVEVYVEFSRUE6OmNvbHMiLCJURVhUQVJFQTo6ZGlzYWJsZWQiLCJURVhU
-QVJFQTo6aW5wdXRtb2RlIiwiVEVYVEFSRUE6Om5hbWUiLCJURVhUQVJFQTo6cGxhY2Vob2xkZXIiLCJU
-RVhUQVJFQTo6cmVhZG9ubHkiLCJURVhUQVJFQTo6cmVxdWlyZWQiLCJURVhUQVJFQTo6cm93cyIsIlRF
-WFRBUkVBOjp0YWJpbmRleCIsIlRFWFRBUkVBOjp3cmFwIiwiVEZPT1Q6OmFsaWduIiwiVEZPT1Q6OmNo
-YXIiLCJURk9PVDo6Y2hhcm9mZiIsIlRGT09UOjp2YWxpZ24iLCJUSDo6YWJiciIsIlRIOjphbGlnbiIs
-IlRIOjpheGlzIiwiVEg6OmJnY29sb3IiLCJUSDo6Y2hhciIsIlRIOjpjaGFyb2ZmIiwiVEg6OmNvbHNw
-YW4iLCJUSDo6aGVhZGVycyIsIlRIOjpoZWlnaHQiLCJUSDo6bm93cmFwIiwiVEg6OnJvd3NwYW4iLCJU
-SDo6c2NvcGUiLCJUSDo6dmFsaWduIiwiVEg6OndpZHRoIiwiVEhFQUQ6OmFsaWduIiwiVEhFQUQ6OmNo
-YXIiLCJUSEVBRDo6Y2hhcm9mZiIsIlRIRUFEOjp2YWxpZ24iLCJUUjo6YWxpZ24iLCJUUjo6Ymdjb2xv
-ciIsIlRSOjpjaGFyIiwiVFI6OmNoYXJvZmYiLCJUUjo6dmFsaWduIiwiVFJBQ0s6OmRlZmF1bHQiLCJU
-UkFDSzo6a2luZCIsIlRSQUNLOjpsYWJlbCIsIlRSQUNLOjpzcmNsYW5nIiwiVUw6OmNvbXBhY3QiLCJV
-TDo6dHlwZSIsIlZJREVPOjpjb250cm9scyIsIlZJREVPOjpoZWlnaHQiLCJWSURFTzo6bG9vcCIsIlZJ
-REVPOjptZWRpYWdyb3VwIiwiVklERU86Om11dGVkIiwiVklERU86OnByZWxvYWQiLCJWSURFTzo6d2lk
-dGgiXSksdC5pKQpDLlZDPUguVk0ocyhbMCwwLDY1NDkwLDQ1MDU1LDY1NTM1LDM0ODE1LDY1NTM0LDE4
-NDMxXSksdC5WKQpDLm1LPUguVk0ocyhbMCwwLDI2NjI0LDEwMjMsNjU1MzQsMjA0Nyw2NTUzNCwyMDQ3
-XSksdC5WKQpDLlNxPUguVk0ocyhbIkhFQUQiLCJBUkVBIiwiQkFTRSIsIkJBU0VGT05UIiwiQlIiLCJD
-T0wiLCJDT0xHUk9VUCIsIkVNQkVEIiwiRlJBTUUiLCJGUkFNRVNFVCIsIkhSIiwiSU1BR0UiLCJJTUci
-LCJJTlBVVCIsIklTSU5ERVgiLCJMSU5LIiwiTUVUQSIsIlBBUkFNIiwiU09VUkNFIiwiU1RZTEUiLCJU
-SVRMRSIsIldCUiJdKSx0LmkpCkMuaFU9SC5WTShzKFtdKSx0LngpCkMuZG49SC5WTShzKFtdKSxILk4w
-KCJqZDxMTCo+IikpCkMueEQ9SC5WTShzKFtdKSx0LmkpCkMudG89SC5WTShzKFswLDAsMzI3MjIsMTIy
-ODcsNjU1MzQsMzQ4MTUsNjU1MzQsMTg0MzFdKSx0LlYpCkMucms9SC5WTShzKFtDLkFkLEMubmUsQy5t
-eSxDLnJ4LEMud1YsQy5mUl0pLEguTjAoImpkPEg3Kj4iKSkKQy5GMz1ILlZNKHMoWzAsMCwyNDU3Niwx
-MDIzLDY1NTM0LDM0ODE1LDY1NTM0LDE4NDMxXSksdC5WKQpDLmVhPUguVk0ocyhbMCwwLDMyNzU0LDEx
-MjYzLDY1NTM0LDM0ODE1LDY1NTM0LDE4NDMxXSksdC5WKQpDLlpKPUguVk0ocyhbMCwwLDMyNzIyLDEy
-Mjg3LDY1NTM1LDM0ODE1LDY1NTM0LDE4NDMxXSksdC5WKQpDLldkPUguVk0ocyhbMCwwLDY1NDkwLDEy
-Mjg3LDY1NTM1LDM0ODE1LDY1NTM0LDE4NDMxXSksdC5WKQpDLlF4PUguVk0ocyhbImJpbmQiLCJpZiIs
-InJlZiIsInJlcGVhdCIsInN5bnRheCJdKSx0LmkpCkMuQkk9SC5WTShzKFsiQTo6aHJlZiIsIkFSRUE6
-OmhyZWYiLCJCTE9DS1FVT1RFOjpjaXRlIiwiQk9EWTo6YmFja2dyb3VuZCIsIkNPTU1BTkQ6Omljb24i
-LCJERUw6OmNpdGUiLCJGT1JNOjphY3Rpb24iLCJJTUc6OnNyYyIsIklOUFVUOjpzcmMiLCJJTlM6OmNp
-dGUiLCJROjpjaXRlIiwiVklERU86OnBvc3RlciJdKSx0LmkpCkMuRHg9bmV3IEguTFAoMCx7fSxDLnhE
-LEguTjAoIkxQPHFVKix6TTxqOCo+Kj4iKSkKQy5DTT1uZXcgSC5MUCgwLHt9LEMueEQsSC5OMCgiTFA8
-cVUqLHFVKj4iKSkKQy5pSD1ILlZNKHMoW10pLEguTjAoImpkPEdEKj4iKSkKQy5XTz1uZXcgSC5MUCgw
-LHt9LEMuaUgsSC5OMCgiTFA8R0QqLEA+IikpCkMuWTI9bmV3IEwuTzkoIk5hdmlnYXRpb25UcmVlTm9k
-ZVR5cGUuZGlyZWN0b3J5IikKQy5yZj1uZXcgTC5POSgiTmF2aWdhdGlvblRyZWVOb2RlVHlwZS5maWxl
-IikKQy5UZT1uZXcgSC53digiY2FsbCIpCkMub0U9bmV3IFAuR1koITEpCkMud1E9bmV3IFAuRnkobnVs
-bCwyKX0pKCk7KGZ1bmN0aW9uIHN0YXRpY0ZpZWxkcygpeyQuem09bnVsbAokLnlqPTAKJC5tSj1udWxs
-CiQuUDQ9bnVsbAokLk5GPW51bGwKJC5UWD1udWxsCiQueDc9bnVsbAokLm53PW51bGwKJC52dj1udWxs
-CiQuQnY9bnVsbAokLlM2PW51bGwKJC5rOD1udWxsCiQubWc9bnVsbAokLlVEPSExCiQuWDM9Qy5OVQok
-LnhnPUguVk0oW10sSC5OMCgiamQ8TWg+IikpCiQueG89bnVsbAokLkJPPW51bGwKJC5sdD1udWxsCiQu
-RVU9bnVsbAokLm9yPVAuRmwodC5OLHQuWSkKJC5JNj1udWxsCiQuRmY9bnVsbH0pKCk7KGZ1bmN0aW9u
-IGxhenlJbml0aWFsaXplcnMoKXt2YXIgcz1odW5rSGVscGVycy5sYXp5RmluYWwscj1odW5rSGVscGVy
-cy5sYXp5T2xkCnMoJCwiZmEiLCJ3IixmdW5jdGlvbigpe3JldHVybiBILllnKCJfJGRhcnRfZGFydENs
-b3N1cmUiKX0pCnMoJCwiVTIiLCJTbiIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILlM3KHsKdG9TdHJp
-bmc6ZnVuY3Rpb24oKXtyZXR1cm4iJHJlY2VpdmVyJCJ9fSkpfSkKcygkLCJ4cSIsImxxIixmdW5jdGlv
-bigpe3JldHVybiBILmNNKEguUzcoeyRtZXRob2QkOm51bGwsCnRvU3RyaW5nOmZ1bmN0aW9uKCl7cmV0
-dXJuIiRyZWNlaXZlciQifX0pKX0pCnMoJCwiUjEiLCJOOSIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShI
-LlM3KG51bGwpKX0pCnMoJCwiZk4iLCJpSSIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShmdW5jdGlvbigp
-e3ZhciAkYXJndW1lbnRzRXhwciQ9JyRhcmd1bWVudHMkJwp0cnl7bnVsbC4kbWV0aG9kJCgkYXJndW1l
-bnRzRXhwciQpfWNhdGNoKHEpe3JldHVybiBxLm1lc3NhZ2V9fSgpKX0pCnMoJCwicWkiLCJVTiIsZnVu
-Y3Rpb24oKXtyZXR1cm4gSC5jTShILlM3KHZvaWQgMCkpfSkKcygkLCJyWiIsIlpoIixmdW5jdGlvbigp
-e3JldHVybiBILmNNKGZ1bmN0aW9uKCl7dmFyICRhcmd1bWVudHNFeHByJD0nJGFyZ3VtZW50cyQnCnRy
-eXsodm9pZCAwKS4kbWV0aG9kJCgkYXJndW1lbnRzRXhwciQpfWNhdGNoKHEpe3JldHVybiBxLm1lc3Nh
-Z2V9fSgpKX0pCnMoJCwia3EiLCJyTiIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILk1qKG51bGwpKX0p
-CnMoJCwidHQiLCJjMyIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShmdW5jdGlvbigpe3RyeXtudWxsLiRt
-ZXRob2QkfWNhdGNoKHEpe3JldHVybiBxLm1lc3NhZ2V9fSgpKX0pCnMoJCwiZHQiLCJISyIsZnVuY3Rp
-b24oKXtyZXR1cm4gSC5jTShILk1qKHZvaWQgMCkpfSkKcygkLCJBNyIsInIxIixmdW5jdGlvbigpe3Jl
-dHVybiBILmNNKGZ1bmN0aW9uKCl7dHJ5eyh2b2lkIDApLiRtZXRob2QkfWNhdGNoKHEpe3JldHVybiBx
-Lm1lc3NhZ2V9fSgpKX0pCnMoJCwiV2MiLCJ1dCIsZnVuY3Rpb24oKXtyZXR1cm4gUC5PaigpfSkKcygk
-LCJraCIsInJmIixmdW5jdGlvbigpe3JldHVybiBuZXcgUC5wZygpLiQwKCl9KQpzKCQsImRIIiwiSEci
-LGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBQLmMyKCkuJDAoKX0pCnMoJCwiYnQiLCJWNyIsZnVuY3Rpb24o
-KXtyZXR1cm4gbmV3IEludDhBcnJheShILlhGKEguVk0oWy0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0y
-LC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0y
-LC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0xLC0yLC0yLC0yLC0yLC0yLDYyLC0yLDYyLC0yLDYzLDUy
-LDUzLDU0LDU1LDU2LDU3LDU4LDU5LDYwLDYxLC0yLC0yLC0yLC0xLC0yLC0yLC0yLDAsMSwyLDMsNCw1
-LDYsNyw4LDksMTAsMTEsMTIsMTMsMTQsMTUsMTYsMTcsMTgsMTksMjAsMjEsMjIsMjMsMjQsMjUsLTIs
-LTIsLTIsLTIsNjMsLTIsMjYsMjcsMjgsMjksMzAsMzEsMzIsMzMsMzQsMzUsMzYsMzcsMzgsMzksNDAs
-NDEsNDIsNDMsNDQsNDUsNDYsNDcsNDgsNDksNTAsNTEsLTIsLTIsLTIsLTIsLTJdLHQuYSkpKX0pCnMo
-JCwiTTUiLCJ3USIsZnVuY3Rpb24oKXtyZXR1cm4gdHlwZW9mIHByb2Nlc3MhPSJ1bmRlZmluZWQiJiZP
-YmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwocHJvY2Vzcyk9PSJbb2JqZWN0IHByb2Nlc3NdIiYm
-cHJvY2Vzcy5wbGF0Zm9ybT09IndpbjMyIn0pCnMoJCwibWYiLCJ6NCIsZnVuY3Rpb24oKXtyZXR1cm4g
-UC5udSgiXltcXC1cXC4wLTlBLVpfYS16fl0qJCIpfSkKcygkLCJPUSIsInZaIixmdW5jdGlvbigpe3Jl
-dHVybiBQLktOKCl9KQpzKCQsIlNDIiwiQU4iLGZ1bmN0aW9uKCl7cmV0dXJuIFAudE0oWyJBIiwiQUJC
-UiIsIkFDUk9OWU0iLCJBRERSRVNTIiwiQVJFQSIsIkFSVElDTEUiLCJBU0lERSIsIkFVRElPIiwiQiIs
-IkJESSIsIkJETyIsIkJJRyIsIkJMT0NLUVVPVEUiLCJCUiIsIkJVVFRPTiIsIkNBTlZBUyIsIkNBUFRJ
-T04iLCJDRU5URVIiLCJDSVRFIiwiQ09ERSIsIkNPTCIsIkNPTEdST1VQIiwiQ09NTUFORCIsIkRBVEEi
-LCJEQVRBTElTVCIsIkREIiwiREVMIiwiREVUQUlMUyIsIkRGTiIsIkRJUiIsIkRJViIsIkRMIiwiRFQi
-LCJFTSIsIkZJRUxEU0VUIiwiRklHQ0FQVElPTiIsIkZJR1VSRSIsIkZPTlQiLCJGT09URVIiLCJGT1JN
-IiwiSDEiLCJIMiIsIkgzIiwiSDQiLCJINSIsIkg2IiwiSEVBREVSIiwiSEdST1VQIiwiSFIiLCJJIiwi
-SUZSQU1FIiwiSU1HIiwiSU5QVVQiLCJJTlMiLCJLQkQiLCJMQUJFTCIsIkxFR0VORCIsIkxJIiwiTUFQ
-IiwiTUFSSyIsIk1FTlUiLCJNRVRFUiIsIk5BViIsIk5PQlIiLCJPTCIsIk9QVEdST1VQIiwiT1BUSU9O
-IiwiT1VUUFVUIiwiUCIsIlBSRSIsIlBST0dSRVNTIiwiUSIsIlMiLCJTQU1QIiwiU0VDVElPTiIsIlNF
-TEVDVCIsIlNNQUxMIiwiU09VUkNFIiwiU1BBTiIsIlNUUklLRSIsIlNUUk9ORyIsIlNVQiIsIlNVTU1B
-UlkiLCJTVVAiLCJUQUJMRSIsIlRCT0RZIiwiVEQiLCJURVhUQVJFQSIsIlRGT09UIiwiVEgiLCJUSEVB
-RCIsIlRJTUUiLCJUUiIsIlRSQUNLIiwiVFQiLCJVIiwiVUwiLCJWQVIiLCJWSURFTyIsIldCUiJdLHQu
-Til9KQpzKCQsIlg0IiwiaEciLGZ1bmN0aW9uKCl7cmV0dXJuIFAubnUoIl5cXFMrJCIpfSkKcygkLCJ3
-TyIsIm93IixmdW5jdGlvbigpe3JldHVybiBQLk5EKHNlbGYpfSkKcygkLCJrdCIsIlI4IixmdW5jdGlv
-bigpe3JldHVybiBILllnKCJfJGRhcnRfZGFydE9iamVjdCIpfSkKcygkLCJmSyIsImtJIixmdW5jdGlv
-bigpe3JldHVybiBmdW5jdGlvbiBEYXJ0T2JqZWN0KGEpe3RoaXMubz1hfX0pCnIoJCwicXQiLCJ6QiIs
-ZnVuY3Rpb24oKXtyZXR1cm4gbmV3IFQubVEoKX0pCnIoJCwiT2wiLCJVRSIsZnVuY3Rpb24oKXtyZXR1
-cm4gUC5oSyhDLm9sLmdtVyhXLngzKCkpLmhyZWYpLmdoWSgpLnEoMCwiYXV0aFRva2VuIil9KQpyKCQs
-ImhUIiwieVAiLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCIuZWRpdC1saXN0
-IC5wYW5lbC1jb250ZW50Iil9KQpyKCQsIlc2IiwiaEwiLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5x
-dWVyeVNlbGVjdG9yKCIuZWRpdC1wYW5lbCAucGFuZWwtY29udGVudCIpfSkKcigkLCJUUiIsIkRXIixm
-dW5jdGlvbigpe3JldHVybiBXLlpyKCkucXVlcnlTZWxlY3RvcigiZm9vdGVyIil9KQpyKCQsIkVZIiwi
-ZmkiLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCJoZWFkZXIiKX0pCnIoJCwi
-YXYiLCJEOSIsZnVuY3Rpb24oKXtyZXR1cm4gVy5acigpLnF1ZXJ5U2VsZWN0b3IoIiN1bml0LW5hbWUi
-KX0pCnIoJCwiZmUiLCJLRyIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEwuWEEoKX0pCnMoJCwiZW8iLCJu
-VSIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IE0ubEkoJC5IaygpKX0pCnMoJCwieXIiLCJiRCIsZnVuY3Rp
-b24oKXtyZXR1cm4gbmV3IEUuT0YoUC5udSgiLyIpLFAubnUoIlteL10kIiksUC5udSgiXi8iKSl9KQpz
-KCQsIk1rIiwiS2siLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBMLklWKFAubnUoIlsvXFxcXF0iKSxQLm51
-KCJbXi9cXFxcXSQiKSxQLm51KCJeKFxcXFxcXFxcW15cXFxcXStcXFxcW15cXFxcL10rfFthLXpBLVpd
-OlsvXFxcXF0pIiksUC5udSgiXlsvXFxcXF0oPyFbL1xcXFxdKSIpKX0pCnMoJCwiYWsiLCJFYiIsZnVu
-Y3Rpb24oKXtyZXR1cm4gbmV3IEYucnUoUC5udSgiLyIpLFAubnUoIiheW2EtekEtWl1bLSsuYS16QS1a
-XFxkXSo6Ly98W14vXSkkIiksUC5udSgiW2EtekEtWl1bLSsuYS16QS1aXFxkXSo6Ly9bXi9dKiIpLFAu
-bnUoIl4vIikpfSkKcygkLCJscyIsIkhrIixmdW5jdGlvbigpe3JldHVybiBPLlJoKCl9KX0pKCk7KGZ1
-bmN0aW9uIG5hdGl2ZVN1cHBvcnQoKXshZnVuY3Rpb24oKXt2YXIgcz1mdW5jdGlvbihhKXt2YXIgbT17
-fQptW2FdPTEKcmV0dXJuIE9iamVjdC5rZXlzKGh1bmtIZWxwZXJzLmNvbnZlcnRUb0Zhc3RPYmplY3Qo
-bSkpWzBdfQp2LmdldElzb2xhdGVUYWc9ZnVuY3Rpb24oYSl7cmV0dXJuIHMoIl9fX2RhcnRfIithK3Yu
-aXNvbGF0ZVRhZyl9CnZhciByPSJfX19kYXJ0X2lzb2xhdGVfdGFnc18iCnZhciBxPU9iamVjdFtyXXx8
-KE9iamVjdFtyXT1PYmplY3QuY3JlYXRlKG51bGwpKQp2YXIgcD0iX1p4WXhYIgpmb3IodmFyIG89MDs7
-bysrKXt2YXIgbj1zKHArIl8iK28rIl8iKQppZighKG4gaW4gcSkpe3Fbbl09MQp2Lmlzb2xhdGVUYWc9
-bgpicmVha319di5kaXNwYXRjaFByb3BlcnR5TmFtZT12LmdldElzb2xhdGVUYWcoImRpc3BhdGNoX3Jl
-Y29yZCIpfSgpCmh1bmtIZWxwZXJzLnNldE9yVXBkYXRlSW50ZXJjZXB0b3JzQnlUYWcoe0RPTUVycm9y
-OkouR3YsTWVkaWFFcnJvcjpKLkd2LE5hdmlnYXRvcjpKLkd2LE5hdmlnYXRvckNvbmN1cnJlbnRIYXJk
-d2FyZTpKLkd2LE5hdmlnYXRvclVzZXJNZWRpYUVycm9yOkouR3YsT3ZlcmNvbnN0cmFpbmVkRXJyb3I6
-Si5HdixQb3NpdGlvbkVycm9yOkouR3YsUmFuZ2U6Si5HdixTUUxFcnJvcjpKLkd2LERhdGFWaWV3Okgu
-RVQsQXJyYXlCdWZmZXJWaWV3OkguRVQsRmxvYXQzMkFycmF5OkguRGcsRmxvYXQ2NEFycmF5OkguRGcs
-SW50MTZBcnJheTpILnhqLEludDMyQXJyYXk6SC5kRSxJbnQ4QXJyYXk6SC5aQSxVaW50MTZBcnJheTpI
-LmRULFVpbnQzMkFycmF5OkguUHEsVWludDhDbGFtcGVkQXJyYXk6SC5lRSxDYW52YXNQaXhlbEFycmF5
-OkguZUUsVWludDhBcnJheTpILlY2LEhUTUxBdWRpb0VsZW1lbnQ6Vy5xRSxIVE1MQlJFbGVtZW50Olcu
-cUUsSFRNTEJ1dHRvbkVsZW1lbnQ6Vy5xRSxIVE1MQ2FudmFzRWxlbWVudDpXLnFFLEhUTUxDb250ZW50
-RWxlbWVudDpXLnFFLEhUTUxETGlzdEVsZW1lbnQ6Vy5xRSxIVE1MRGF0YUVsZW1lbnQ6Vy5xRSxIVE1M
-RGF0YUxpc3RFbGVtZW50OlcucUUsSFRNTERldGFpbHNFbGVtZW50OlcucUUsSFRNTERpYWxvZ0VsZW1l
-bnQ6Vy5xRSxIVE1MRGl2RWxlbWVudDpXLnFFLEhUTUxFbWJlZEVsZW1lbnQ6Vy5xRSxIVE1MRmllbGRT
-ZXRFbGVtZW50OlcucUUsSFRNTEhSRWxlbWVudDpXLnFFLEhUTUxIZWFkRWxlbWVudDpXLnFFLEhUTUxI
-ZWFkaW5nRWxlbWVudDpXLnFFLEhUTUxIdG1sRWxlbWVudDpXLnFFLEhUTUxJRnJhbWVFbGVtZW50Olcu
-cUUsSFRNTEltYWdlRWxlbWVudDpXLnFFLEhUTUxJbnB1dEVsZW1lbnQ6Vy5xRSxIVE1MTElFbGVtZW50
-OlcucUUsSFRNTExhYmVsRWxlbWVudDpXLnFFLEhUTUxMZWdlbmRFbGVtZW50OlcucUUsSFRNTExpbmtF
-bGVtZW50OlcucUUsSFRNTE1hcEVsZW1lbnQ6Vy5xRSxIVE1MTWVkaWFFbGVtZW50OlcucUUsSFRNTE1l
-bnVFbGVtZW50OlcucUUsSFRNTE1ldGFFbGVtZW50OlcucUUsSFRNTE1ldGVyRWxlbWVudDpXLnFFLEhU
-TUxNb2RFbGVtZW50OlcucUUsSFRNTE9MaXN0RWxlbWVudDpXLnFFLEhUTUxPYmplY3RFbGVtZW50Olcu
-cUUsSFRNTE9wdEdyb3VwRWxlbWVudDpXLnFFLEhUTUxPcHRpb25FbGVtZW50OlcucUUsSFRNTE91dHB1
-dEVsZW1lbnQ6Vy5xRSxIVE1MUGFyYW1FbGVtZW50OlcucUUsSFRNTFBpY3R1cmVFbGVtZW50OlcucUUs
-SFRNTFByZUVsZW1lbnQ6Vy5xRSxIVE1MUHJvZ3Jlc3NFbGVtZW50OlcucUUsSFRNTFF1b3RlRWxlbWVu
-dDpXLnFFLEhUTUxTY3JpcHRFbGVtZW50OlcucUUsSFRNTFNoYWRvd0VsZW1lbnQ6Vy5xRSxIVE1MU2xv
-dEVsZW1lbnQ6Vy5xRSxIVE1MU291cmNlRWxlbWVudDpXLnFFLEhUTUxTcGFuRWxlbWVudDpXLnFFLEhU
-TUxTdHlsZUVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVDYXB0aW9uRWxlbWVudDpXLnFFLEhUTUxUYWJsZUNl
-bGxFbGVtZW50OlcucUUsSFRNTFRhYmxlRGF0YUNlbGxFbGVtZW50OlcucUUsSFRNTFRhYmxlSGVhZGVy
-Q2VsbEVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVDb2xFbGVtZW50OlcucUUsSFRNTFRleHRBcmVhRWxlbWVu
-dDpXLnFFLEhUTUxUaW1lRWxlbWVudDpXLnFFLEhUTUxUaXRsZUVsZW1lbnQ6Vy5xRSxIVE1MVHJhY2tF
-bGVtZW50OlcucUUsSFRNTFVMaXN0RWxlbWVudDpXLnFFLEhUTUxVbmtub3duRWxlbWVudDpXLnFFLEhU
-TUxWaWRlb0VsZW1lbnQ6Vy5xRSxIVE1MRGlyZWN0b3J5RWxlbWVudDpXLnFFLEhUTUxGb250RWxlbWVu
-dDpXLnFFLEhUTUxGcmFtZUVsZW1lbnQ6Vy5xRSxIVE1MRnJhbWVTZXRFbGVtZW50OlcucUUsSFRNTE1h
-cnF1ZWVFbGVtZW50OlcucUUsSFRNTEVsZW1lbnQ6Vy5xRSxIVE1MQW5jaG9yRWxlbWVudDpXLkdoLEhU
-TUxBcmVhRWxlbWVudDpXLmZZLEhUTUxCYXNlRWxlbWVudDpXLm5CLEJsb2I6Vy5BeixIVE1MQm9keUVs
-ZW1lbnQ6Vy5RUCxDREFUQVNlY3Rpb246Vy5ueCxDaGFyYWN0ZXJEYXRhOlcubngsQ29tbWVudDpXLm54
-LFByb2Nlc3NpbmdJbnN0cnVjdGlvbjpXLm54LFRleHQ6Vy5ueCxDU1NTdHlsZURlY2xhcmF0aW9uOlcu
-b0osTVNTdHlsZUNTU1Byb3BlcnRpZXM6Vy5vSixDU1MyUHJvcGVydGllczpXLm9KLFhNTERvY3VtZW50
-OlcuUUYsRG9jdW1lbnQ6Vy5RRixET01FeGNlcHRpb246Vy5OaCxET01JbXBsZW1lbnRhdGlvbjpXLmFl
-LERPTVJlY3RSZWFkT25seTpXLklCLERPTVRva2VuTGlzdDpXLm43LEVsZW1lbnQ6Vy5jdixBYm9ydFBh
-eW1lbnRFdmVudDpXLmVhLEFuaW1hdGlvbkV2ZW50OlcuZWEsQW5pbWF0aW9uUGxheWJhY2tFdmVudDpX
-LmVhLEFwcGxpY2F0aW9uQ2FjaGVFcnJvckV2ZW50OlcuZWEsQmFja2dyb3VuZEZldGNoQ2xpY2tFdmVu
-dDpXLmVhLEJhY2tncm91bmRGZXRjaEV2ZW50OlcuZWEsQmFja2dyb3VuZEZldGNoRmFpbEV2ZW50Olcu
-ZWEsQmFja2dyb3VuZEZldGNoZWRFdmVudDpXLmVhLEJlZm9yZUluc3RhbGxQcm9tcHRFdmVudDpXLmVh
-LEJlZm9yZVVubG9hZEV2ZW50OlcuZWEsQmxvYkV2ZW50OlcuZWEsQ2FuTWFrZVBheW1lbnRFdmVudDpX
-LmVhLENsaXBib2FyZEV2ZW50OlcuZWEsQ2xvc2VFdmVudDpXLmVhLEN1c3RvbUV2ZW50OlcuZWEsRGV2
-aWNlTW90aW9uRXZlbnQ6Vy5lYSxEZXZpY2VPcmllbnRhdGlvbkV2ZW50OlcuZWEsRXJyb3JFdmVudDpX
-LmVhLEV4dGVuZGFibGVFdmVudDpXLmVhLEV4dGVuZGFibGVNZXNzYWdlRXZlbnQ6Vy5lYSxGZXRjaEV2
-ZW50OlcuZWEsRm9udEZhY2VTZXRMb2FkRXZlbnQ6Vy5lYSxGb3JlaWduRmV0Y2hFdmVudDpXLmVhLEdh
-bWVwYWRFdmVudDpXLmVhLEhhc2hDaGFuZ2VFdmVudDpXLmVhLEluc3RhbGxFdmVudDpXLmVhLE1lZGlh
-RW5jcnlwdGVkRXZlbnQ6Vy5lYSxNZWRpYUtleU1lc3NhZ2VFdmVudDpXLmVhLE1lZGlhUXVlcnlMaXN0
-RXZlbnQ6Vy5lYSxNZWRpYVN0cmVhbUV2ZW50OlcuZWEsTWVkaWFTdHJlYW1UcmFja0V2ZW50OlcuZWEs
-TWVzc2FnZUV2ZW50OlcuZWEsTUlESUNvbm5lY3Rpb25FdmVudDpXLmVhLE1JRElNZXNzYWdlRXZlbnQ6
-Vy5lYSxNdXRhdGlvbkV2ZW50OlcuZWEsTm90aWZpY2F0aW9uRXZlbnQ6Vy5lYSxQYWdlVHJhbnNpdGlv
-bkV2ZW50OlcuZWEsUGF5bWVudFJlcXVlc3RFdmVudDpXLmVhLFBheW1lbnRSZXF1ZXN0VXBkYXRlRXZl
-bnQ6Vy5lYSxQb3BTdGF0ZUV2ZW50OlcuZWEsUHJlc2VudGF0aW9uQ29ubmVjdGlvbkF2YWlsYWJsZUV2
-ZW50OlcuZWEsUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlRXZlbnQ6Vy5lYSxQcm9taXNlUmVqZWN0
-aW9uRXZlbnQ6Vy5lYSxQdXNoRXZlbnQ6Vy5lYSxSVENEYXRhQ2hhbm5lbEV2ZW50OlcuZWEsUlRDRFRN
-RlRvbmVDaGFuZ2VFdmVudDpXLmVhLFJUQ1BlZXJDb25uZWN0aW9uSWNlRXZlbnQ6Vy5lYSxSVENUcmFj
-a0V2ZW50OlcuZWEsU2VjdXJpdHlQb2xpY3lWaW9sYXRpb25FdmVudDpXLmVhLFNlbnNvckVycm9yRXZl
-bnQ6Vy5lYSxTcGVlY2hSZWNvZ25pdGlvbkVycm9yOlcuZWEsU3BlZWNoUmVjb2duaXRpb25FdmVudDpX
-LmVhLFNwZWVjaFN5bnRoZXNpc0V2ZW50OlcuZWEsU3RvcmFnZUV2ZW50OlcuZWEsU3luY0V2ZW50Olcu
-ZWEsVHJhY2tFdmVudDpXLmVhLFRyYW5zaXRpb25FdmVudDpXLmVhLFdlYktpdFRyYW5zaXRpb25FdmVu
-dDpXLmVhLFZSRGV2aWNlRXZlbnQ6Vy5lYSxWUkRpc3BsYXlFdmVudDpXLmVhLFZSU2Vzc2lvbkV2ZW50
-OlcuZWEsTW9qb0ludGVyZmFjZVJlcXVlc3RFdmVudDpXLmVhLFVTQkNvbm5lY3Rpb25FdmVudDpXLmVh
-LElEQlZlcnNpb25DaGFuZ2VFdmVudDpXLmVhLEF1ZGlvUHJvY2Vzc2luZ0V2ZW50OlcuZWEsT2ZmbGlu
-ZUF1ZGlvQ29tcGxldGlvbkV2ZW50OlcuZWEsV2ViR0xDb250ZXh0RXZlbnQ6Vy5lYSxFdmVudDpXLmVh
-LElucHV0RXZlbnQ6Vy5lYSxTdWJtaXRFdmVudDpXLmVhLEV2ZW50VGFyZ2V0OlcuRDAsRmlsZTpXLmhI
-LEhUTUxGb3JtRWxlbWVudDpXLmg0LEhpc3Rvcnk6Vy5icixIVE1MRG9jdW1lbnQ6Vy5WYixYTUxIdHRw
-UmVxdWVzdDpXLmZKLFhNTEh0dHBSZXF1ZXN0RXZlbnRUYXJnZXQ6Vy53YSxJbWFnZURhdGE6Vy5TZyxM
-b2NhdGlvbjpXLnU4LE1vdXNlRXZlbnQ6Vy5BaixEcmFnRXZlbnQ6Vy5BaixQb2ludGVyRXZlbnQ6Vy5B
-aixXaGVlbEV2ZW50OlcuQWosRG9jdW1lbnRGcmFnbWVudDpXLnVILFNoYWRvd1Jvb3Q6Vy51SCxEb2N1
-bWVudFR5cGU6Vy51SCxOb2RlOlcudUgsTm9kZUxpc3Q6Vy5CSCxSYWRpb05vZGVMaXN0OlcuQkgsSFRN
-TFBhcmFncmFwaEVsZW1lbnQ6Vy5TTixQcm9ncmVzc0V2ZW50OlcuZXcsUmVzb3VyY2VQcm9ncmVzc0V2
-ZW50OlcuZXcsSFRNTFNlbGVjdEVsZW1lbnQ6Vy5scCxIVE1MVGFibGVFbGVtZW50OlcuVGIsSFRNTFRh
-YmxlUm93RWxlbWVudDpXLkl2LEhUTUxUYWJsZVNlY3Rpb25FbGVtZW50OlcuV1AsSFRNTFRlbXBsYXRl
-RWxlbWVudDpXLnlZLENvbXBvc2l0aW9uRXZlbnQ6Vy53NixGb2N1c0V2ZW50OlcudzYsS2V5Ym9hcmRF
-dmVudDpXLnc2LFRleHRFdmVudDpXLnc2LFRvdWNoRXZlbnQ6Vy53NixVSUV2ZW50OlcudzYsV2luZG93
-OlcuSzUsRE9NV2luZG93OlcuSzUsRGVkaWNhdGVkV29ya2VyR2xvYmFsU2NvcGU6Vy5DbSxTZXJ2aWNl
-V29ya2VyR2xvYmFsU2NvcGU6Vy5DbSxTaGFyZWRXb3JrZXJHbG9iYWxTY29wZTpXLkNtLFdvcmtlckds
-b2JhbFNjb3BlOlcuQ20sQXR0cjpXLkNRLENsaWVudFJlY3Q6Vy53NCxET01SZWN0OlcudzQsTmFtZWRO
-b2RlTWFwOlcucmgsTW96TmFtZWRBdHRyTWFwOlcucmgsSURCS2V5UmFuZ2U6UC5oRixTVkdTY3JpcHRF
-bGVtZW50OlAubmQsU1ZHQUVsZW1lbnQ6UC5oaSxTVkdBbmltYXRlRWxlbWVudDpQLmhpLFNWR0FuaW1h
-dGVNb3Rpb25FbGVtZW50OlAuaGksU1ZHQW5pbWF0ZVRyYW5zZm9ybUVsZW1lbnQ6UC5oaSxTVkdBbmlt
-YXRpb25FbGVtZW50OlAuaGksU1ZHQ2lyY2xlRWxlbWVudDpQLmhpLFNWR0NsaXBQYXRoRWxlbWVudDpQ
-LmhpLFNWR0RlZnNFbGVtZW50OlAuaGksU1ZHRGVzY0VsZW1lbnQ6UC5oaSxTVkdEaXNjYXJkRWxlbWVu
-dDpQLmhpLFNWR0VsbGlwc2VFbGVtZW50OlAuaGksU1ZHRkVCbGVuZEVsZW1lbnQ6UC5oaSxTVkdGRUNv
-bG9yTWF0cml4RWxlbWVudDpQLmhpLFNWR0ZFQ29tcG9uZW50VHJhbnNmZXJFbGVtZW50OlAuaGksU1ZH
-RkVDb21wb3NpdGVFbGVtZW50OlAuaGksU1ZHRkVDb252b2x2ZU1hdHJpeEVsZW1lbnQ6UC5oaSxTVkdG
-RURpZmZ1c2VMaWdodGluZ0VsZW1lbnQ6UC5oaSxTVkdGRURpc3BsYWNlbWVudE1hcEVsZW1lbnQ6UC5o
-aSxTVkdGRURpc3RhbnRMaWdodEVsZW1lbnQ6UC5oaSxTVkdGRUZsb29kRWxlbWVudDpQLmhpLFNWR0ZF
-RnVuY0FFbGVtZW50OlAuaGksU1ZHRkVGdW5jQkVsZW1lbnQ6UC5oaSxTVkdGRUZ1bmNHRWxlbWVudDpQ
-LmhpLFNWR0ZFRnVuY1JFbGVtZW50OlAuaGksU1ZHRkVHYXVzc2lhbkJsdXJFbGVtZW50OlAuaGksU1ZH
-RkVJbWFnZUVsZW1lbnQ6UC5oaSxTVkdGRU1lcmdlRWxlbWVudDpQLmhpLFNWR0ZFTWVyZ2VOb2RlRWxl
-bWVudDpQLmhpLFNWR0ZFTW9ycGhvbG9neUVsZW1lbnQ6UC5oaSxTVkdGRU9mZnNldEVsZW1lbnQ6UC5o
-aSxTVkdGRVBvaW50TGlnaHRFbGVtZW50OlAuaGksU1ZHRkVTcGVjdWxhckxpZ2h0aW5nRWxlbWVudDpQ
-LmhpLFNWR0ZFU3BvdExpZ2h0RWxlbWVudDpQLmhpLFNWR0ZFVGlsZUVsZW1lbnQ6UC5oaSxTVkdGRVR1
-cmJ1bGVuY2VFbGVtZW50OlAuaGksU1ZHRmlsdGVyRWxlbWVudDpQLmhpLFNWR0ZvcmVpZ25PYmplY3RF
-bGVtZW50OlAuaGksU1ZHR0VsZW1lbnQ6UC5oaSxTVkdHZW9tZXRyeUVsZW1lbnQ6UC5oaSxTVkdHcmFw
-aGljc0VsZW1lbnQ6UC5oaSxTVkdJbWFnZUVsZW1lbnQ6UC5oaSxTVkdMaW5lRWxlbWVudDpQLmhpLFNW
-R0xpbmVhckdyYWRpZW50RWxlbWVudDpQLmhpLFNWR01hcmtlckVsZW1lbnQ6UC5oaSxTVkdNYXNrRWxl
-bWVudDpQLmhpLFNWR01ldGFkYXRhRWxlbWVudDpQLmhpLFNWR1BhdGhFbGVtZW50OlAuaGksU1ZHUGF0
-dGVybkVsZW1lbnQ6UC5oaSxTVkdQb2x5Z29uRWxlbWVudDpQLmhpLFNWR1BvbHlsaW5lRWxlbWVudDpQ
-LmhpLFNWR1JhZGlhbEdyYWRpZW50RWxlbWVudDpQLmhpLFNWR1JlY3RFbGVtZW50OlAuaGksU1ZHU2V0
-RWxlbWVudDpQLmhpLFNWR1N0b3BFbGVtZW50OlAuaGksU1ZHU3R5bGVFbGVtZW50OlAuaGksU1ZHU1ZH
-RWxlbWVudDpQLmhpLFNWR1N3aXRjaEVsZW1lbnQ6UC5oaSxTVkdTeW1ib2xFbGVtZW50OlAuaGksU1ZH
-VFNwYW5FbGVtZW50OlAuaGksU1ZHVGV4dENvbnRlbnRFbGVtZW50OlAuaGksU1ZHVGV4dEVsZW1lbnQ6
-UC5oaSxTVkdUZXh0UGF0aEVsZW1lbnQ6UC5oaSxTVkdUZXh0UG9zaXRpb25pbmdFbGVtZW50OlAuaGks
-U1ZHVGl0bGVFbGVtZW50OlAuaGksU1ZHVXNlRWxlbWVudDpQLmhpLFNWR1ZpZXdFbGVtZW50OlAuaGks
-U1ZHR3JhZGllbnRFbGVtZW50OlAuaGksU1ZHQ29tcG9uZW50VHJhbnNmZXJGdW5jdGlvbkVsZW1lbnQ6
-UC5oaSxTVkdGRURyb3BTaGFkb3dFbGVtZW50OlAuaGksU1ZHTVBhdGhFbGVtZW50OlAuaGksU1ZHRWxl
-bWVudDpQLmhpfSkKaHVua0hlbHBlcnMuc2V0T3JVcGRhdGVMZWFmVGFncyh7RE9NRXJyb3I6dHJ1ZSxN
-ZWRpYUVycm9yOnRydWUsTmF2aWdhdG9yOnRydWUsTmF2aWdhdG9yQ29uY3VycmVudEhhcmR3YXJlOnRy
-dWUsTmF2aWdhdG9yVXNlck1lZGlhRXJyb3I6dHJ1ZSxPdmVyY29uc3RyYWluZWRFcnJvcjp0cnVlLFBv
-c2l0aW9uRXJyb3I6dHJ1ZSxSYW5nZTp0cnVlLFNRTEVycm9yOnRydWUsRGF0YVZpZXc6dHJ1ZSxBcnJh
-eUJ1ZmZlclZpZXc6ZmFsc2UsRmxvYXQzMkFycmF5OnRydWUsRmxvYXQ2NEFycmF5OnRydWUsSW50MTZB
-cnJheTp0cnVlLEludDMyQXJyYXk6dHJ1ZSxJbnQ4QXJyYXk6dHJ1ZSxVaW50MTZBcnJheTp0cnVlLFVp
-bnQzMkFycmF5OnRydWUsVWludDhDbGFtcGVkQXJyYXk6dHJ1ZSxDYW52YXNQaXhlbEFycmF5OnRydWUs
-VWludDhBcnJheTpmYWxzZSxIVE1MQXVkaW9FbGVtZW50OnRydWUsSFRNTEJSRWxlbWVudDp0cnVlLEhU
-TUxCdXR0b25FbGVtZW50OnRydWUsSFRNTENhbnZhc0VsZW1lbnQ6dHJ1ZSxIVE1MQ29udGVudEVsZW1l
-bnQ6dHJ1ZSxIVE1MRExpc3RFbGVtZW50OnRydWUsSFRNTERhdGFFbGVtZW50OnRydWUsSFRNTERhdGFM
-aXN0RWxlbWVudDp0cnVlLEhUTUxEZXRhaWxzRWxlbWVudDp0cnVlLEhUTUxEaWFsb2dFbGVtZW50OnRy
-dWUsSFRNTERpdkVsZW1lbnQ6dHJ1ZSxIVE1MRW1iZWRFbGVtZW50OnRydWUsSFRNTEZpZWxkU2V0RWxl
-bWVudDp0cnVlLEhUTUxIUkVsZW1lbnQ6dHJ1ZSxIVE1MSGVhZEVsZW1lbnQ6dHJ1ZSxIVE1MSGVhZGlu
-Z0VsZW1lbnQ6dHJ1ZSxIVE1MSHRtbEVsZW1lbnQ6dHJ1ZSxIVE1MSUZyYW1lRWxlbWVudDp0cnVlLEhU
-TUxJbWFnZUVsZW1lbnQ6dHJ1ZSxIVE1MSW5wdXRFbGVtZW50OnRydWUsSFRNTExJRWxlbWVudDp0cnVl
-LEhUTUxMYWJlbEVsZW1lbnQ6dHJ1ZSxIVE1MTGVnZW5kRWxlbWVudDp0cnVlLEhUTUxMaW5rRWxlbWVu
-dDp0cnVlLEhUTUxNYXBFbGVtZW50OnRydWUsSFRNTE1lZGlhRWxlbWVudDp0cnVlLEhUTUxNZW51RWxl
-bWVudDp0cnVlLEhUTUxNZXRhRWxlbWVudDp0cnVlLEhUTUxNZXRlckVsZW1lbnQ6dHJ1ZSxIVE1MTW9k
-RWxlbWVudDp0cnVlLEhUTUxPTGlzdEVsZW1lbnQ6dHJ1ZSxIVE1MT2JqZWN0RWxlbWVudDp0cnVlLEhU
-TUxPcHRHcm91cEVsZW1lbnQ6dHJ1ZSxIVE1MT3B0aW9uRWxlbWVudDp0cnVlLEhUTUxPdXRwdXRFbGVt
-ZW50OnRydWUsSFRNTFBhcmFtRWxlbWVudDp0cnVlLEhUTUxQaWN0dXJlRWxlbWVudDp0cnVlLEhUTUxQ
-cmVFbGVtZW50OnRydWUsSFRNTFByb2dyZXNzRWxlbWVudDp0cnVlLEhUTUxRdW90ZUVsZW1lbnQ6dHJ1
-ZSxIVE1MU2NyaXB0RWxlbWVudDp0cnVlLEhUTUxTaGFkb3dFbGVtZW50OnRydWUsSFRNTFNsb3RFbGVt
-ZW50OnRydWUsSFRNTFNvdXJjZUVsZW1lbnQ6dHJ1ZSxIVE1MU3BhbkVsZW1lbnQ6dHJ1ZSxIVE1MU3R5
-bGVFbGVtZW50OnRydWUsSFRNTFRhYmxlQ2FwdGlvbkVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVDZWxsRWxl
-bWVudDp0cnVlLEhUTUxUYWJsZURhdGFDZWxsRWxlbWVudDp0cnVlLEhUTUxUYWJsZUhlYWRlckNlbGxF
-bGVtZW50OnRydWUsSFRNTFRhYmxlQ29sRWxlbWVudDp0cnVlLEhUTUxUZXh0QXJlYUVsZW1lbnQ6dHJ1
-ZSxIVE1MVGltZUVsZW1lbnQ6dHJ1ZSxIVE1MVGl0bGVFbGVtZW50OnRydWUsSFRNTFRyYWNrRWxlbWVu
-dDp0cnVlLEhUTUxVTGlzdEVsZW1lbnQ6dHJ1ZSxIVE1MVW5rbm93bkVsZW1lbnQ6dHJ1ZSxIVE1MVmlk
-ZW9FbGVtZW50OnRydWUsSFRNTERpcmVjdG9yeUVsZW1lbnQ6dHJ1ZSxIVE1MRm9udEVsZW1lbnQ6dHJ1
-ZSxIVE1MRnJhbWVFbGVtZW50OnRydWUsSFRNTEZyYW1lU2V0RWxlbWVudDp0cnVlLEhUTUxNYXJxdWVl
-RWxlbWVudDp0cnVlLEhUTUxFbGVtZW50OmZhbHNlLEhUTUxBbmNob3JFbGVtZW50OnRydWUsSFRNTEFy
-ZWFFbGVtZW50OnRydWUsSFRNTEJhc2VFbGVtZW50OnRydWUsQmxvYjpmYWxzZSxIVE1MQm9keUVsZW1l
-bnQ6dHJ1ZSxDREFUQVNlY3Rpb246dHJ1ZSxDaGFyYWN0ZXJEYXRhOnRydWUsQ29tbWVudDp0cnVlLFBy
-b2Nlc3NpbmdJbnN0cnVjdGlvbjp0cnVlLFRleHQ6dHJ1ZSxDU1NTdHlsZURlY2xhcmF0aW9uOnRydWUs
-TVNTdHlsZUNTU1Byb3BlcnRpZXM6dHJ1ZSxDU1MyUHJvcGVydGllczp0cnVlLFhNTERvY3VtZW50OnRy
-dWUsRG9jdW1lbnQ6ZmFsc2UsRE9NRXhjZXB0aW9uOnRydWUsRE9NSW1wbGVtZW50YXRpb246dHJ1ZSxE
-T01SZWN0UmVhZE9ubHk6ZmFsc2UsRE9NVG9rZW5MaXN0OnRydWUsRWxlbWVudDpmYWxzZSxBYm9ydFBh
-eW1lbnRFdmVudDp0cnVlLEFuaW1hdGlvbkV2ZW50OnRydWUsQW5pbWF0aW9uUGxheWJhY2tFdmVudDp0
-cnVlLEFwcGxpY2F0aW9uQ2FjaGVFcnJvckV2ZW50OnRydWUsQmFja2dyb3VuZEZldGNoQ2xpY2tFdmVu
-dDp0cnVlLEJhY2tncm91bmRGZXRjaEV2ZW50OnRydWUsQmFja2dyb3VuZEZldGNoRmFpbEV2ZW50OnRy
-dWUsQmFja2dyb3VuZEZldGNoZWRFdmVudDp0cnVlLEJlZm9yZUluc3RhbGxQcm9tcHRFdmVudDp0cnVl
-LEJlZm9yZVVubG9hZEV2ZW50OnRydWUsQmxvYkV2ZW50OnRydWUsQ2FuTWFrZVBheW1lbnRFdmVudDp0
-cnVlLENsaXBib2FyZEV2ZW50OnRydWUsQ2xvc2VFdmVudDp0cnVlLEN1c3RvbUV2ZW50OnRydWUsRGV2
-aWNlTW90aW9uRXZlbnQ6dHJ1ZSxEZXZpY2VPcmllbnRhdGlvbkV2ZW50OnRydWUsRXJyb3JFdmVudDp0
-cnVlLEV4dGVuZGFibGVFdmVudDp0cnVlLEV4dGVuZGFibGVNZXNzYWdlRXZlbnQ6dHJ1ZSxGZXRjaEV2
-ZW50OnRydWUsRm9udEZhY2VTZXRMb2FkRXZlbnQ6dHJ1ZSxGb3JlaWduRmV0Y2hFdmVudDp0cnVlLEdh
-bWVwYWRFdmVudDp0cnVlLEhhc2hDaGFuZ2VFdmVudDp0cnVlLEluc3RhbGxFdmVudDp0cnVlLE1lZGlh
-RW5jcnlwdGVkRXZlbnQ6dHJ1ZSxNZWRpYUtleU1lc3NhZ2VFdmVudDp0cnVlLE1lZGlhUXVlcnlMaXN0
-RXZlbnQ6dHJ1ZSxNZWRpYVN0cmVhbUV2ZW50OnRydWUsTWVkaWFTdHJlYW1UcmFja0V2ZW50OnRydWUs
-TWVzc2FnZUV2ZW50OnRydWUsTUlESUNvbm5lY3Rpb25FdmVudDp0cnVlLE1JRElNZXNzYWdlRXZlbnQ6
-dHJ1ZSxNdXRhdGlvbkV2ZW50OnRydWUsTm90aWZpY2F0aW9uRXZlbnQ6dHJ1ZSxQYWdlVHJhbnNpdGlv
-bkV2ZW50OnRydWUsUGF5bWVudFJlcXVlc3RFdmVudDp0cnVlLFBheW1lbnRSZXF1ZXN0VXBkYXRlRXZl
-bnQ6dHJ1ZSxQb3BTdGF0ZUV2ZW50OnRydWUsUHJlc2VudGF0aW9uQ29ubmVjdGlvbkF2YWlsYWJsZUV2
-ZW50OnRydWUsUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlRXZlbnQ6dHJ1ZSxQcm9taXNlUmVqZWN0
-aW9uRXZlbnQ6dHJ1ZSxQdXNoRXZlbnQ6dHJ1ZSxSVENEYXRhQ2hhbm5lbEV2ZW50OnRydWUsUlRDRFRN
-RlRvbmVDaGFuZ2VFdmVudDp0cnVlLFJUQ1BlZXJDb25uZWN0aW9uSWNlRXZlbnQ6dHJ1ZSxSVENUcmFj
-a0V2ZW50OnRydWUsU2VjdXJpdHlQb2xpY3lWaW9sYXRpb25FdmVudDp0cnVlLFNlbnNvckVycm9yRXZl
-bnQ6dHJ1ZSxTcGVlY2hSZWNvZ25pdGlvbkVycm9yOnRydWUsU3BlZWNoUmVjb2duaXRpb25FdmVudDp0
-cnVlLFNwZWVjaFN5bnRoZXNpc0V2ZW50OnRydWUsU3RvcmFnZUV2ZW50OnRydWUsU3luY0V2ZW50OnRy
-dWUsVHJhY2tFdmVudDp0cnVlLFRyYW5zaXRpb25FdmVudDp0cnVlLFdlYktpdFRyYW5zaXRpb25FdmVu
-dDp0cnVlLFZSRGV2aWNlRXZlbnQ6dHJ1ZSxWUkRpc3BsYXlFdmVudDp0cnVlLFZSU2Vzc2lvbkV2ZW50
-OnRydWUsTW9qb0ludGVyZmFjZVJlcXVlc3RFdmVudDp0cnVlLFVTQkNvbm5lY3Rpb25FdmVudDp0cnVl
-LElEQlZlcnNpb25DaGFuZ2VFdmVudDp0cnVlLEF1ZGlvUHJvY2Vzc2luZ0V2ZW50OnRydWUsT2ZmbGlu
-ZUF1ZGlvQ29tcGxldGlvbkV2ZW50OnRydWUsV2ViR0xDb250ZXh0RXZlbnQ6dHJ1ZSxFdmVudDpmYWxz
-ZSxJbnB1dEV2ZW50OmZhbHNlLFN1Ym1pdEV2ZW50OmZhbHNlLEV2ZW50VGFyZ2V0OmZhbHNlLEZpbGU6
-dHJ1ZSxIVE1MRm9ybUVsZW1lbnQ6dHJ1ZSxIaXN0b3J5OnRydWUsSFRNTERvY3VtZW50OnRydWUsWE1M
-SHR0cFJlcXVlc3Q6dHJ1ZSxYTUxIdHRwUmVxdWVzdEV2ZW50VGFyZ2V0OmZhbHNlLEltYWdlRGF0YTp0
-cnVlLExvY2F0aW9uOnRydWUsTW91c2VFdmVudDp0cnVlLERyYWdFdmVudDp0cnVlLFBvaW50ZXJFdmVu
-dDp0cnVlLFdoZWVsRXZlbnQ6dHJ1ZSxEb2N1bWVudEZyYWdtZW50OnRydWUsU2hhZG93Um9vdDp0cnVl
-LERvY3VtZW50VHlwZTp0cnVlLE5vZGU6ZmFsc2UsTm9kZUxpc3Q6dHJ1ZSxSYWRpb05vZGVMaXN0OnRy
-dWUsSFRNTFBhcmFncmFwaEVsZW1lbnQ6dHJ1ZSxQcm9ncmVzc0V2ZW50OnRydWUsUmVzb3VyY2VQcm9n
-cmVzc0V2ZW50OnRydWUsSFRNTFNlbGVjdEVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVFbGVtZW50OnRydWUs
-SFRNTFRhYmxlUm93RWxlbWVudDp0cnVlLEhUTUxUYWJsZVNlY3Rpb25FbGVtZW50OnRydWUsSFRNTFRl
-bXBsYXRlRWxlbWVudDp0cnVlLENvbXBvc2l0aW9uRXZlbnQ6dHJ1ZSxGb2N1c0V2ZW50OnRydWUsS2V5
-Ym9hcmRFdmVudDp0cnVlLFRleHRFdmVudDp0cnVlLFRvdWNoRXZlbnQ6dHJ1ZSxVSUV2ZW50OmZhbHNl
-LFdpbmRvdzp0cnVlLERPTVdpbmRvdzp0cnVlLERlZGljYXRlZFdvcmtlckdsb2JhbFNjb3BlOnRydWUs
-U2VydmljZVdvcmtlckdsb2JhbFNjb3BlOnRydWUsU2hhcmVkV29ya2VyR2xvYmFsU2NvcGU6dHJ1ZSxX
-b3JrZXJHbG9iYWxTY29wZTp0cnVlLEF0dHI6dHJ1ZSxDbGllbnRSZWN0OnRydWUsRE9NUmVjdDp0cnVl
-LE5hbWVkTm9kZU1hcDp0cnVlLE1vek5hbWVkQXR0ck1hcDp0cnVlLElEQktleVJhbmdlOnRydWUsU1ZH
-U2NyaXB0RWxlbWVudDp0cnVlLFNWR0FFbGVtZW50OnRydWUsU1ZHQW5pbWF0ZUVsZW1lbnQ6dHJ1ZSxT
-VkdBbmltYXRlTW90aW9uRWxlbWVudDp0cnVlLFNWR0FuaW1hdGVUcmFuc2Zvcm1FbGVtZW50OnRydWUs
-U1ZHQW5pbWF0aW9uRWxlbWVudDp0cnVlLFNWR0NpcmNsZUVsZW1lbnQ6dHJ1ZSxTVkdDbGlwUGF0aEVs
-ZW1lbnQ6dHJ1ZSxTVkdEZWZzRWxlbWVudDp0cnVlLFNWR0Rlc2NFbGVtZW50OnRydWUsU1ZHRGlzY2Fy
-ZEVsZW1lbnQ6dHJ1ZSxTVkdFbGxpcHNlRWxlbWVudDp0cnVlLFNWR0ZFQmxlbmRFbGVtZW50OnRydWUs
-U1ZHRkVDb2xvck1hdHJpeEVsZW1lbnQ6dHJ1ZSxTVkdGRUNvbXBvbmVudFRyYW5zZmVyRWxlbWVudDp0
-cnVlLFNWR0ZFQ29tcG9zaXRlRWxlbWVudDp0cnVlLFNWR0ZFQ29udm9sdmVNYXRyaXhFbGVtZW50OnRy
-dWUsU1ZHRkVEaWZmdXNlTGlnaHRpbmdFbGVtZW50OnRydWUsU1ZHRkVEaXNwbGFjZW1lbnRNYXBFbGVt
-ZW50OnRydWUsU1ZHRkVEaXN0YW50TGlnaHRFbGVtZW50OnRydWUsU1ZHRkVGbG9vZEVsZW1lbnQ6dHJ1
-ZSxTVkdGRUZ1bmNBRWxlbWVudDp0cnVlLFNWR0ZFRnVuY0JFbGVtZW50OnRydWUsU1ZHRkVGdW5jR0Vs
-ZW1lbnQ6dHJ1ZSxTVkdGRUZ1bmNSRWxlbWVudDp0cnVlLFNWR0ZFR2F1c3NpYW5CbHVyRWxlbWVudDp0
-cnVlLFNWR0ZFSW1hZ2VFbGVtZW50OnRydWUsU1ZHRkVNZXJnZUVsZW1lbnQ6dHJ1ZSxTVkdGRU1lcmdl
-Tm9kZUVsZW1lbnQ6dHJ1ZSxTVkdGRU1vcnBob2xvZ3lFbGVtZW50OnRydWUsU1ZHRkVPZmZzZXRFbGVt
-ZW50OnRydWUsU1ZHRkVQb2ludExpZ2h0RWxlbWVudDp0cnVlLFNWR0ZFU3BlY3VsYXJMaWdodGluZ0Vs
-ZW1lbnQ6dHJ1ZSxTVkdGRVNwb3RMaWdodEVsZW1lbnQ6dHJ1ZSxTVkdGRVRpbGVFbGVtZW50OnRydWUs
-U1ZHRkVUdXJidWxlbmNlRWxlbWVudDp0cnVlLFNWR0ZpbHRlckVsZW1lbnQ6dHJ1ZSxTVkdGb3JlaWdu
-T2JqZWN0RWxlbWVudDp0cnVlLFNWR0dFbGVtZW50OnRydWUsU1ZHR2VvbWV0cnlFbGVtZW50OnRydWUs
-U1ZHR3JhcGhpY3NFbGVtZW50OnRydWUsU1ZHSW1hZ2VFbGVtZW50OnRydWUsU1ZHTGluZUVsZW1lbnQ6
-dHJ1ZSxTVkdMaW5lYXJHcmFkaWVudEVsZW1lbnQ6dHJ1ZSxTVkdNYXJrZXJFbGVtZW50OnRydWUsU1ZH
-TWFza0VsZW1lbnQ6dHJ1ZSxTVkdNZXRhZGF0YUVsZW1lbnQ6dHJ1ZSxTVkdQYXRoRWxlbWVudDp0cnVl
-LFNWR1BhdHRlcm5FbGVtZW50OnRydWUsU1ZHUG9seWdvbkVsZW1lbnQ6dHJ1ZSxTVkdQb2x5bGluZUVs
-ZW1lbnQ6dHJ1ZSxTVkdSYWRpYWxHcmFkaWVudEVsZW1lbnQ6dHJ1ZSxTVkdSZWN0RWxlbWVudDp0cnVl
-LFNWR1NldEVsZW1lbnQ6dHJ1ZSxTVkdTdG9wRWxlbWVudDp0cnVlLFNWR1N0eWxlRWxlbWVudDp0cnVl
-LFNWR1NWR0VsZW1lbnQ6dHJ1ZSxTVkdTd2l0Y2hFbGVtZW50OnRydWUsU1ZHU3ltYm9sRWxlbWVudDp0
-cnVlLFNWR1RTcGFuRWxlbWVudDp0cnVlLFNWR1RleHRDb250ZW50RWxlbWVudDp0cnVlLFNWR1RleHRF
-bGVtZW50OnRydWUsU1ZHVGV4dFBhdGhFbGVtZW50OnRydWUsU1ZHVGV4dFBvc2l0aW9uaW5nRWxlbWVu
-dDp0cnVlLFNWR1RpdGxlRWxlbWVudDp0cnVlLFNWR1VzZUVsZW1lbnQ6dHJ1ZSxTVkdWaWV3RWxlbWVu
-dDp0cnVlLFNWR0dyYWRpZW50RWxlbWVudDp0cnVlLFNWR0NvbXBvbmVudFRyYW5zZmVyRnVuY3Rpb25F
-bGVtZW50OnRydWUsU1ZHRkVEcm9wU2hhZG93RWxlbWVudDp0cnVlLFNWR01QYXRoRWxlbWVudDp0cnVl
-LFNWR0VsZW1lbnQ6ZmFsc2V9KQpILkxaLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZp
-ZXciCkguUkcuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5WUC4kbmF0aXZl
-U3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILkRnLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJB
-cnJheUJ1ZmZlclZpZXciCkguV0IuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIK
-SC5aRy4kbmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILlBnLiRuYXRpdmVTdXBl
-cmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXcifSkoKQpjb252ZXJ0QWxsVG9GYXN0T2JqZWN0KHcpCmNv
-bnZlcnRUb0Zhc3RPYmplY3QoJCk7KGZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBkb2N1bWVudD09PSJ1bmRl
-ZmluZWQiKXthKG51bGwpCnJldHVybn1pZih0eXBlb2YgZG9jdW1lbnQuY3VycmVudFNjcmlwdCE9J3Vu
-ZGVmaW5lZCcpe2EoZG9jdW1lbnQuY3VycmVudFNjcmlwdCkKcmV0dXJufXZhciBzPWRvY3VtZW50LnNj
-cmlwdHMKZnVuY3Rpb24gb25Mb2FkKGIpe2Zvcih2YXIgcT0wO3E8cy5sZW5ndGg7KytxKXNbcV0ucmVt
-b3ZlRXZlbnRMaXN0ZW5lcigibG9hZCIsb25Mb2FkLGZhbHNlKQphKGIudGFyZ2V0KX1mb3IodmFyIHI9
-MDtyPHMubGVuZ3RoOysrcilzW3JdLmFkZEV2ZW50TGlzdGVuZXIoImxvYWQiLG9uTG9hZCxmYWxzZSl9
-KShmdW5jdGlvbihhKXt2LmN1cnJlbnRTY3JpcHQ9YQppZih0eXBlb2YgZGFydE1haW5SdW5uZXI9PT0i
-ZnVuY3Rpb24iKWRhcnRNYWluUnVubmVyKEwuSXEsW10pCmVsc2UgTC5JcShbXSl9KX0pKCkKLy8jIHNv
-dXJjZU1hcHBpbmdVUkw9bWlncmF0aW9uLmpzLm1hcAo=
+YikKcmV0dXJuIHRoaXMuJHRpLmMuYSh0aGlzLlVyKDAsYikpfSwKWTU6ZnVuY3Rpb24oYSxiLGMpe3Ro
+aXMuY1AoYikKdGhpcy5lNCgwLGIsYyl9LApnQTpmdW5jdGlvbihhKXt2YXIgcz10aGlzLmEubGVuZ3Ro
+CmlmKHR5cGVvZiBzPT09Im51bWJlciImJnM+Pj4wPT09cylyZXR1cm4gcwp0aHJvdyBILmIoUC5QVigi
+QmFkIEpzQXJyYXkgbGVuZ3RoIikpfSwKJGliUToxLAokaWNYOjEsCiRpek06MX0KUC5jby5wcm90b3R5
+cGU9e30KUC5uZC5wcm90b3R5cGU9eyRpbmQ6MX0KUC5LZS5wcm90b3R5cGU9ewpEOmZ1bmN0aW9uKCl7
+dmFyIHMscixxLHAsbz10aGlzLmEuZ2V0QXR0cmlidXRlKCJjbGFzcyIpLG49UC5Mcyh0Lk4pCmlmKG89
+PW51bGwpcmV0dXJuIG4KZm9yKHM9by5zcGxpdCgiICIpLHI9cy5sZW5ndGgscT0wO3E8cjsrK3Epe3A9
+Si5UMChzW3FdKQppZihwLmxlbmd0aCE9PTApbi5pKDAscCl9cmV0dXJuIG59LApYOmZ1bmN0aW9uKGEp
+e3RoaXMuYS5zZXRBdHRyaWJ1dGUoImNsYXNzIixhLmsoMCwiICIpKX19ClAuaGkucHJvdG90eXBlPXsK
+Z246ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLktlKGEpfSwKc2hmOmZ1bmN0aW9uKGEsYil7dGhpcy5Z
+QyhhLGIpfSwKcjY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHMscixxLHAsbyxuCmlmKGQ9PW51bGwpe3M9
+SC5WTShbXSx0LnYpCmQ9bmV3IFcudkQocykKQy5ObS5pKHMsVy5UdyhudWxsKSkKQy5ObS5pKHMsVy5C
+bCgpKQpDLk5tLmkocyxuZXcgVy5PdygpKX1jPW5ldyBXLktvKGQpCnI9JzxzdmcgdmVyc2lvbj0iMS4x
+Ij4nK0guRWooYikrIjwvc3ZnPiIKcz1kb2N1bWVudApxPXMuYm9keQpxLnRvU3RyaW5nCnA9Qy5SWS5B
+SChxLHIsYykKbz1zLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKQpwLnRvU3RyaW5nCnM9bmV3IFcuZTco
+cCkKbj1zLmdyOChzKQpmb3IoO3M9bi5maXJzdENoaWxkLHMhPW51bGw7KW8uYXBwZW5kQ2hpbGQocykK
+cmV0dXJuIG99LApuejpmdW5jdGlvbihhLGIsYyxkLGUpe3Rocm93IEguYihQLkw0KCJDYW5ub3QgaW52
+b2tlIGluc2VydEFkamFjZW50SHRtbCBvbiBTVkcuIikpfSwKZ1ZsOmZ1bmN0aW9uKGEpe3JldHVybiBu
+ZXcgVy5ldShhLCJjbGljayIsITEsdC5rKX0sCiRpaGk6MX0KTS5INy5wcm90b3R5cGU9ewp3OmZ1bmN0
+aW9uKGEpe3JldHVybiB0aGlzLmJ9fQpVLkxMLnByb3RvdHlwZT17Ckx0OmZ1bmN0aW9uKCl7cmV0dXJu
+IFAuRUYoWyJub2RlSWQiLHRoaXMuYiwia2luZCIsdGhpcy5hLmFdLHQuWCx0Ll8pfX0KVS5NRC5wcm90
+b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdC5mRS5hKGEpLmE9PT10aGlzLmEucSgwLCJraW5k
+Iil9LAokUzozOH0KVS5kMi5wcm90b3R5cGU9ewpMdDpmdW5jdGlvbigpe3ZhciBzLHIscSxwLG89dGhp
+cyxuPXQuWCxtPXQuXyxsPVAuRmwobixtKSxrPW8uYQppZihrIT1udWxsKXtzPUguVk0oW10sdC5HKQpm
+b3Iocj1rLmxlbmd0aCxxPTA7cTxrLmxlbmd0aDtrLmxlbmd0aD09PXJ8fCgwLEgubGspKGspLCsrcSl7
+cD1rW3FdCnMucHVzaChQLkVGKFsiZGVzY3JpcHRpb24iLHAuYSwiaHJlZiIscC5iXSxuLG0pKX1sLlk1
+KDAsImVkaXRzIixzKX1sLlk1KDAsImV4cGxhbmF0aW9uIixvLmIpCmwuWTUoMCwibGluZSIsby5jKQps
+Llk1KDAsImRpc3BsYXlQYXRoIixvLmQpCmwuWTUoMCwidXJpUGF0aCIsby5lKQpuPW8uZgppZihuIT1u
+dWxsKXttPUguVk0oW10sdC5HKQpmb3Ioaz1uLmxlbmd0aCxxPTA7cTxuLmxlbmd0aDtuLmxlbmd0aD09
+PWt8fCgwLEgubGspKG4pLCsrcSltLnB1c2gobltxXS5MdCgpKQpsLlk1KDAsInRyYWNlcyIsbSl9cmV0
+dXJuIGx9fQpVLlNlLnByb3RvdHlwZT17Ckx0OmZ1bmN0aW9uKCl7cmV0dXJuIFAuRUYoWyJkZXNjcmlw
+dGlvbiIsdGhpcy5hLCJocmVmIix0aGlzLmJdLHQuWCx0Ll8pfX0KVS5NbC5wcm90b3R5cGU9ewpMdDpm
+dW5jdGlvbigpe3JldHVybiBQLkVGKFsiaHJlZiIsdGhpcy5hLCJsaW5lIix0aGlzLmIsInBhdGgiLHRo
+aXMuY10sdC5YLHQuXyl9fQpVLnlELnByb3RvdHlwZT17Ckx0OmZ1bmN0aW9uKCl7dmFyIHMscixxLHA9
+SC5WTShbXSx0LkcpCmZvcihzPXRoaXMuYixyPXMubGVuZ3RoLHE9MDtxPHMubGVuZ3RoO3MubGVuZ3Ro
+PT09cnx8KDAsSC5saykocyksKytxKXAucHVzaChzW3FdLkx0KCkpCnJldHVybiBQLkVGKFsiZGVzY3Jp
+cHRpb24iLHRoaXMuYSwiZW50cmllcyIscF0sdC5YLHQuXyl9fQpVLndiLnByb3RvdHlwZT17Ckx0OmZ1
+bmN0aW9uKCl7dmFyIHMscixxLHA9dGhpcyxvPVAuRmwodC5YLHQuXykKby5ZNSgwLCJkZXNjcmlwdGlv
+biIscC5hKQpzPXAuYgppZihzIT1udWxsKW8uWTUoMCwiZnVuY3Rpb24iLHMpCnM9cC5jCmlmKHMhPW51
+bGwpby5ZNSgwLCJsaW5rIixzLkx0KCkpCnM9cC5kCmlmKHMubGVuZ3RoIT09MCl7cj1ILnQ2KHMpCnE9
+ci5DKCJsSjwxLFowPHFVKixNaCo+Kj4iKQpvLlk1KDAsImhpbnRBY3Rpb25zIixQLlkxKG5ldyBILmxK
+KHMsci5DKCJaMDxxVSosTWgqPiooMSkiKS5hKG5ldyBVLmIwKCkpLHEpLCEwLHEuQygiYUwuRSIpKSl9
+cmV0dXJuIG99fQpVLmFOLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBVLm56KHQudC5h
+KGEpKX0sCiRTOjM5fQpVLmIwLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0LmFYLmEo
+YSkuTHQoKX0sCiRTOjQwfQpCLmo4LnByb3RvdHlwZT17Ckx0OmZ1bmN0aW9uKCl7cmV0dXJuIFAuRUYo
+WyJsaW5lIix0aGlzLmEsImV4cGxhbmF0aW9uIix0aGlzLmIsIm9mZnNldCIsdGhpcy5jXSx0LlgsdC5f
+KX19CkIucXAucHJvdG90eXBlPXsKTHQ6ZnVuY3Rpb24oKXt2YXIgcyxyLHEscCxvLG4sbSxsPXRoaXMs
+az10Llgsaj1QLkZsKGssdC5kcCkKZm9yKHM9bC5kLHM9cy5nUHUocykscz1zLmdtKHMpLHI9dC5fLHE9
+dC5HO3MuRigpOyl7cD1zLmdsKCkKbz1wLmEKbj1ILlZNKFtdLHEpCmZvcihwPUouSVQocC5iKTtwLkYo
+KTspe209cC5nbCgpCm4ucHVzaChQLkVGKFsibGluZSIsbS5hLCJleHBsYW5hdGlvbiIsbS5iLCJvZmZz
+ZXQiLG0uY10sayxyKSl9ai5ZNSgwLG8sbil9cmV0dXJuIFAuRUYoWyJyZWdpb25zIixsLmEsIm5hdmln
+YXRpb25Db250ZW50IixsLmIsInNvdXJjZUNvZGUiLGwuYywiZWRpdHMiLGpdLGsscil9fQpULm1RLnBy
+b3RvdHlwZT17fQpMLmUucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHMscixxLHAsbyxuLG0K
+dC5hTC5hKGEpCnM9d2luZG93LmxvY2F0aW9uLnBhdGhuYW1lCnI9TC5HNih3aW5kb3cubG9jYXRpb24u
+aHJlZikKcT1MLmFLKHdpbmRvdy5sb2NhdGlvbi5ocmVmKQpMLkdlKCkKaWYocyE9PSIvIiYmcyE9PUou
+VDAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLnJvb3QiKS50ZXh0Q29udGVudCkpTC5HNyhzLHIscSwh
+MCxuZXcgTC5WVyhzLHIscSkpCnA9ZG9jdW1lbnQKbz1KLnFGKHAucXVlcnlTZWxlY3RvcigiLmFwcGx5
+LW1pZ3JhdGlvbiIpKQpuPW8uJHRpCm09bi5DKCJ+KDEpPyIpLmEobmV3IEwub1ooKSkKdC5aLmEobnVs
+bCkKVy5KRShvLmEsby5iLG0sITEsbi5jKQpuPUoucUYocC5xdWVyeVNlbGVjdG9yKCIucmVydW4tbWln
+cmF0aW9uIikpCm09bi4kdGkKVy5KRShuLmEsbi5iLG0uQygifigxKT8iKS5hKG5ldyBMLkhpKCkpLCEx
+LG0uYykKbT1KLnFGKHAucXVlcnlTZWxlY3RvcigiLnJlcG9ydC1wcm9ibGVtIikpCm49bS4kdGkKVy5K
+RShtLmEsbS5iLG4uQygifigxKT8iKS5hKG5ldyBMLkJUKCkpLCExLG4uYykKcD1KLnFGKHAucXVlcnlT
+ZWxlY3RvcigiLnBvcHVwLXBhbmUgLmNsb3NlIikpCm49cC4kdGkKVy5KRShwLmEscC5iLG4uQygifigx
+KT8iKS5hKG5ldyBMLlBZKCkpLCExLG4uYykKbj1KLnFGKCQuYzAoKSkKcD1uLiR0aQpXLkpFKG4uYSxu
+LmIscC5DKCJ+KDEpPyIpLmEobmV3IEwudTgoKSksITEscC5jKX0sCiRTOjE4fQpMLlZXLnByb3RvdHlw
+ZT17CiQwOmZ1bmN0aW9uKCl7TC5Gcih0aGlzLmEsdGhpcy5iLHRoaXMuYyl9LAokUzoyfQpMLm9aLnBy
+b3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwCnQuTy5hKGEpCmlmKEgub1QoQy5vbC51
+cyh3aW5kb3csIlRoaXMgd2lsbCBhcHBseSB0aGUgY2hhbmdlcyB5b3UndmUgcHJldmlld2VkIHRvIHlv
+dXIgd29ya2luZyBkaXJlY3RvcnkuIEl0IGlzIHJlY29tbWVuZGVkIHlvdSBjb21taXQgYW55IGNoYW5n
+ZXMgeW91IG1hZGUgYmVmb3JlIGRvaW5nIHRoaXMuIikpKXtzPUwudHkoIi9hcHBseS1taWdyYXRpb24i
+LG51bGwpLlc3KG5ldyBMLmpyKCksdC5QKQpyPW5ldyBMLnFsKCkKdC5iNy5hKG51bGwpCnE9cy4kdGkK
+cD0kLlgzCmlmKHAhPT1DLk5VKXI9UC5WSChyLHApCnMueGYobmV3IFAuRmUobmV3IFAudnMocCxxKSwy
+LG51bGwscixxLkMoIkA8MT4iKS5LcShxLmMpLkMoIkZlPDEsMj4iKSkpfX0sCiRTOjF9CkwuanIucHJv
+dG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHMKdC50LmEoYSkKcz1kb2N1bWVudC5ib2R5CnMuY2xh
+c3NMaXN0LnJlbW92ZSgicHJvcG9zZWQiKQpzLmNsYXNzTGlzdC5hZGQoImFwcGxpZWQiKX0sCiRTOjQz
+fQpMLnFsLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7TC5DMigiQ291bGQgbm90IGFwcGx5IG1p
+Z3JhdGlvbiIsYSxiKX0sCiRDOiIkMiIsCiRSOjIsCiRTOjE2fQpMLkhpLnByb3RvdHlwZT17CiQxOmZ1
+bmN0aW9uKGEpe3JldHVybiB0aGlzLnhuKHQuTy5hKGEpKX0sCnhuOmZ1bmN0aW9uKGEpe3ZhciBzPTAs
+cj1QLkZYKHQuUCkscT0xLHAsbz1bXSxuLG0sbCxrLGoKdmFyICRhc3luYyQkMT1QLmx6KGZ1bmN0aW9u
+KGIsYyl7aWYoYj09PTEpe3A9YwpzPXF9d2hpbGUodHJ1ZSlzd2l0Y2gocyl7Y2FzZSAwOnE9Mwpkb2N1
+bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoInJlcnVubmluZyIpCnM9NgpyZXR1cm4gUC5qUShMLnR5KCIv
+cmVydW4tbWlncmF0aW9uIixudWxsKSwkYXN5bmMkJDEpCmNhc2UgNjpuPWMKaWYoSC5vVChILnk4KEou
+eDkobiwic3VjY2VzcyIpKSkpd2luZG93LmxvY2F0aW9uLnJlbG9hZCgpCmVsc2UgTC5LMCh0Lm0uYShK
+Lng5KG4sImVycm9ycyIpKSkKby5wdXNoKDUpCnM9NApicmVhawpjYXNlIDM6cT0yCmo9cAptPUguUnUo
+aikKbD1ILnRzKGopCkwuQzIoIkZhaWxlZCB0byByZXJ1biBtaWdyYXRpb24iLG0sbCkKby5wdXNoKDUp
+CnM9NApicmVhawpjYXNlIDI6bz1bMV0KY2FzZSA0OnE9MQpkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5y
+ZW1vdmUoInJlcnVubmluZyIpCnM9by5wb3AoKQpicmVhawpjYXNlIDU6cmV0dXJuIFAueUMobnVsbCxy
+KQpjYXNlIDE6cmV0dXJuIFAuZjMocCxyKX19KQpyZXR1cm4gUC5ESSgkYXN5bmMkJDEscil9LAokUzox
+OX0KTC5CVC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgcwp0Lk8uYShhKQpzPXQuWApDLm9s
+LlBvKHdpbmRvdyxQLlhkKCJodHRwcyIsImdpdGh1Yi5jb20iLCJkYXJ0LWxhbmcvc2RrL2lzc3Vlcy9u
+ZXciLFAuRUYoWyJ0aXRsZSIsIkN1c3RvbWVyLXJlcG9ydGVkIGlzc3VlIHdpdGggTk5CRCBtaWdyYXRp
+b24gdG9vbCIsImxhYmVscyIsdS5kLCJib2R5IiwiIyMjIyBTdGVwcyB0byByZXByb2R1Y2VcblxuIyMj
+IyBXaGF0IGRpZCB5b3UgZXhwZWN0IHRvIGhhcHBlbj9cblxuIyMjIyBXaGF0IGFjdHVhbGx5IGhhcHBl
+bmVkP1xuXG5fU2NyZWVuc2hvdHMgYXJlIGFwcHJlY2lhdGVkX1xuXG4qKkRhcnQgU0RLIHZlcnNpb24q
+KjogIitILkVqKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJzZGstdmVyc2lvbiIpLnRleHRDb250ZW50
+KSsiXG5cblRoYW5rcyBmb3IgZmlsaW5nIVxuIl0scyxzKSkuZ25EKCksInJlcG9ydC1wcm9ibGVtIil9
+LAokUzoxfQpMLlBZLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzCnQuTy5hKGEpCnM9ZG9j
+dW1lbnQucXVlcnlTZWxlY3RvcigiLnBvcHVwLXBhbmUiKS5zdHlsZQpzLmRpc3BsYXk9Im5vbmUiCnJl
+dHVybiJub25lIn0sCiRTOjQ1fQpMLnU4LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzLHIs
+cSxwCnQuTy5hKGEpCnM9JC5EOSgpLmlubmVyVGV4dApyPXQuZy5hKGRvY3VtZW50LnF1ZXJ5U2VsZWN0
+b3IoJy5uYXYtcGFuZWwgW2RhdGEtbmFtZSo9IicrSC5FaihzKSsnIl0nKS5wYXJlbnROb2RlKQpxPXIu
+cXVlcnlTZWxlY3RvcigiLnN0YXR1cy1pY29uIikKcD1MLm1IKCQuSVIscykKaWYocCBpbnN0YW5jZW9m
+IEwuY0Qpe0wuT3QocCkKTC54bihxLHApCkwuQVIocixwKX19LAokUzoxfQpMLkwucHJvdG90eXBlPXsK
+JDE6ZnVuY3Rpb24oYSl7dmFyIHMscixxCnQuYUwuYShhKQpzPXdpbmRvdy5sb2NhdGlvbi5wYXRobmFt
+ZQpyPUwuRzYod2luZG93LmxvY2F0aW9uLmhyZWYpCnE9TC5hSyh3aW5kb3cubG9jYXRpb24uaHJlZikK
+aWYocy5sZW5ndGg+MSlMLkc3KHMscixxLCExLG51bGwpCmVsc2V7TC5CRShzLEIud1IoKSwhMCkKTC5C
+WCgiJm5ic3A7IixudWxsKX19LAokUzoxOH0KTC5XeC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2
+YXIgcyxyLHEscD0iY29sbGFwc2VkIgp0Lk8uYShhKQpzPXRoaXMuYQpyPUouWUUocykKcT10aGlzLmIK
+aWYoIXIuZ24ocykudGcoMCxwKSl7ci5nbihzKS5pKDAscCkKSi5kUihxKS5pKDAscCl9ZWxzZXtyLmdu
+KHMpLkwoMCxwKQpKLmRSKHEpLkwoMCxwKX19LAokUzoxfQpMLkFPLnByb3RvdHlwZT17CiQxOmZ1bmN0
+aW9uKGEpe3ZhciBzPUoucUYodC5nLmEoYSkpLHI9cy4kdGkscT1yLkMoIn4oMSk/IikuYShuZXcgTC5k
+Tih0aGlzLmEpKQp0LlouYShudWxsKQpXLkpFKHMuYSxzLmIscSwhMSxyLmMpfSwKJFM6M30KTC5kTi5w
+cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgcwp0Lk8uYShhKQpzPWRvY3VtZW50LnF1ZXJ5U2Vs
+ZWN0b3IoInRhYmxlW2RhdGEtcGF0aF0iKQpzLnRvU3RyaW5nCkwudDIoYSx0aGlzLmEscy5nZXRBdHRy
+aWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhzKSkuUCgicGF0aCIpKSl9LAokUzoxfQpMLkhv
+LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciBzLHIscQp0LmcuYShhKQpzPUoucUYoYSkKcj1z
+LiR0aQpxPXIuQygifigxKT8iKS5hKG5ldyBMLnh6KGEsdGhpcy5hKSkKdC5aLmEobnVsbCkKVy5KRShz
+LmEscy5iLHEsITEsci5jKX0sCiRTOjN9CkwueHoucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFy
+IHMKdC5PLmEoYSkKcz10aGlzLmEKTC5oWCh0aGlzLmIsUC5RQShzLmdldEF0dHJpYnV0ZSgiZGF0YS0i
+K25ldyBXLlN5KG5ldyBXLmk3KHMpKS5QKCJvZmZzZXQiKSksbnVsbCksUC5RQShzLmdldEF0dHJpYnV0
+ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KHMpKS5QKCJsaW5lIikpLG51bGwpKX0sCiRTOjF9Ckwu
+SUMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHM9Si5xRih0LmcuYShhKSkscj1zLiR0aQpy
+LkMoIn4oMSk/IikuYShMLmlTKCkpCnQuWi5hKG51bGwpClcuSkUocy5hLHMuYixMLmlTKCksITEsci5j
+KX0sCiRTOjN9CkwuZkMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dC5lUS5hKGEpCnRoaXMuYS5h
+TSgwLHRoaXMuYil9LAokUzo0N30KTC5uVC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe0wuRnIodGhp
+cy5hLHRoaXMuYix0aGlzLmMpfSwKJFM6Mn0KTC5OWS5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe0wu
+RnIodGhpcy5hLG51bGwsbnVsbCl9LAokUzoyfQpMLnVlLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEp
+e3QuYXcuYShhKQpyZXR1cm4gSC5FaihhLnEoMCwic2V2ZXJpdHkiKSkrIiAtICIrSC5FaihhLnEoMCwi
+bWVzc2FnZSIpKSsiIGF0ICIrSC5FaihhLnEoMCwibG9jYXRpb24iKSkrIiAtICgiK0guRWooYS5xKDAs
+ImNvZGUiKSkrIikifSwKJFM6NDh9CkwuZVgucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dC5nLmEo
+YSkKJC56QigpLnRvU3RyaW5nCnQuZEguYSgkLm93KCkucSgwLCJobGpzIikpLlY3KCJoaWdobGlnaHRC
+bG9jayIsW2FdKX0sCiRTOjN9CkwuRUUucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHMscgp0
+Lk8uYShhKS5wcmV2ZW50RGVmYXVsdCgpCnM9dGhpcy5hCnI9dGhpcy5iCkwuYWYod2luZG93LmxvY2F0
+aW9uLnBhdGhuYW1lLHMsciwhMCxuZXcgTC5RTChzLHIpKQpMLmhYKHRoaXMuYyxzLHIpfSwKJFM6MX0K
+TC5RTC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe0wuRnIod2luZG93LmxvY2F0aW9uLnBhdGhuYW1l
+LHRoaXMuYSx0aGlzLmIpfSwKJFM6Mn0KTC5WUy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIg
+cyxyPSJzZWxlY3RlZC1maWxlIgp0LmcuYShhKQphLnRvU3RyaW5nCnM9Si5ZRShhKQppZihhLmdldEF0
+dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KGEpKS5QKCJuYW1lIikpPT09dGhpcy5hLmEp
+cy5nbihhKS5pKDAscikKZWxzZSBzLmduKGEpLkwoMCxyKX0sCiRTOjN9CkwuVEQucHJvdG90eXBlPXsK
+JDE6ZnVuY3Rpb24oYSl7cmV0dXJuIEwudDIodC5PLmEoYSksITAsbnVsbCl9LAokUzoyMH0KTC5tMi5w
+cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5SSSh0Lk8uYShhKSl9LApSSTpmdW5j
+dGlvbihhKXt2YXIgcz0wLHI9UC5GWCh0LlApLHE9MSxwLG89W10sbj10aGlzLG0sbCxrLGosaSxoLGcs
+Zgp2YXIgJGFzeW5jJCQxPVAubHooZnVuY3Rpb24oYixjKXtpZihiPT09MSl7cD1jCnM9cX13aGlsZSh0
+cnVlKXN3aXRjaChzKXtjYXNlIDA6cT0zCmk9ZG9jdW1lbnQKbT1DLkNELnpRKGkucXVlcnlTZWxlY3Rv
+cigiLmNvbnRlbnQiKS5zY3JvbGxUb3ApCmg9dC5YCnM9NgpyZXR1cm4gUC5qUShMLnR5KEwuUTQoIi9h
+cHBseS1oaW50IixQLkZsKGgsaCkpLG4uYS5MdCgpKSwkYXN5bmMkJDEpCmNhc2UgNjpoPW4uYgpsPUwu
+VXMoaC5hKQpzPTcKcmV0dXJuIFAualEoTC5HNyhsLG51bGwsaC5iLCExLG51bGwpLCRhc3luYyQkMSkK
+Y2FzZSA3OmkuYm9keS5jbGFzc0xpc3QuYWRkKCJuZWVkcy1yZXJ1biIpCmk9aS5xdWVyeVNlbGVjdG9y
+KCIuY29udGVudCIpCmkudG9TdHJpbmcKaS5zY3JvbGxUb3A9Si5WdShtKQpxPTEKcz01CmJyZWFrCmNh
+c2UgMzpxPTIKZj1wCms9SC5SdShmKQpqPUgudHMoZikKTC5DMigiQ291bGQgbm90IGFwcGx5IGhpbnQi
+LGssaikKcz01CmJyZWFrCmNhc2UgMjpzPTEKYnJlYWsKY2FzZSA1OnJldHVybiBQLnlDKG51bGwscikK
+Y2FzZSAxOnJldHVybiBQLmYzKHAscil9fSkKcmV0dXJuIFAuREkoJGFzeW5jJCQxLHIpfSwKJFM6MTl9
+CkwuWEEucHJvdG90eXBlPXsKRWI6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiEwfSwKaTA6ZnVuY3Rpb24o
+YSl7cmV0dXJuITB9LAokaWtGOjF9CkwudnQucHJvdG90eXBlPXsKZ2Q2OmZ1bmN0aW9uKCl7dmFyIHMs
+cixxLHAsbyxuLG0sbD10aGlzLmQKaWYobC5sZW5ndGg9PT0wKXJldHVybiBDLmN3CnM9Qy5ObS5ndEgo
+bCkuZ2Q2KCkKZm9yKHI9bC5sZW5ndGgscT0hMCxwPSEwLG89MDtvPGwubGVuZ3RoO2wubGVuZ3RoPT09
+cnx8KDAsSC5saykobCksKytvKXtuPWxbb10uZ2Q2KCkKaWYobiE9cylzPW51bGwKbT1uIT09Qy5jdwpp
+ZihtJiZuIT09Qy5XRClxPSExCmlmKG0mJm4hPT1DLlhqKXA9ITF9aWYocyE9bnVsbClyZXR1cm4gcwpp
+ZihxKXJldHVybiBDLldECmlmKHApcmV0dXJuIEMuWGoKcmV0dXJuIEMuZGN9LApMVjpmdW5jdGlvbigp
+e3ZhciBzLHIscT10aGlzLmQKaWYocSE9bnVsbClmb3Iocz1xLmxlbmd0aCxyPTA7cjxzOysrcilxW3Jd
+LmI9dGhpc30sCkx0OmZ1bmN0aW9uKCl7dmFyIHMscj1QLkZsKHQuWCx0Ll8pCnIuWTUoMCwidHlwZSIs
+ImRpcmVjdG9yeSIpCnIuWTUoMCwibmFtZSIsdGhpcy5hKQpyLlk1KDAsInN1YnRyZWUiLEwuVkQodGhp
+cy5kKSkKcz10aGlzLmMKaWYocyE9bnVsbClyLlk1KDAsInBhdGgiLHMpCnJldHVybiByfX0KTC5jRC5w
+cm90b3R5cGU9ewpMdDpmdW5jdGlvbigpe3ZhciBzLHI9dGhpcyxxPVAuRmwodC5YLHQuXykKcS5ZNSgw
+LCJ0eXBlIiwiZmlsZSIpCnEuWTUoMCwibmFtZSIsci5hKQpzPXIuYwppZihzIT1udWxsKXEuWTUoMCwi
+cGF0aCIscykKcz1yLmQKaWYocyE9bnVsbClxLlk1KDAsImhyZWYiLHMpCnM9ci5lCmlmKHMhPW51bGwp
+cS5ZNSgwLCJlZGl0Q291bnQiLHMpCnM9ci5mCmlmKHMhPW51bGwpcS5ZNSgwLCJ3YXNFeHBsaWNpdGx5
+T3B0ZWRPdXQiLHMpCnM9ci5yCmlmKHMhPW51bGwpcS5ZNSgwLCJtaWdyYXRpb25TdGF0dXMiLHMuYSkK
+cmV0dXJuIHF9LApnZDY6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5yfX0KTC5EOC5wcm90b3R5cGU9e30K
+TC5POS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmJ9fQpMLkdiLnByb3RvdHlw
+ZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYn19Ck0ubEkucHJvdG90eXBlPXsKZ2w6ZnVuY3Rp
+b24oKXt2YXIgcz1ELmFiKCkKcmV0dXJuIHN9LApXTzpmdW5jdGlvbihhLGIpe3ZhciBzLHIscT10LmQ0
+Ck0uWUYoImFic29sdXRlIixILlZNKFtiLG51bGwsbnVsbCxudWxsLG51bGwsbnVsbCxudWxsXSxxKSkK
+cz10aGlzLmEKcz1zLllyKGIpPjAmJiFzLmhLKGIpCmlmKHMpcmV0dXJuIGIKcj1ILlZNKFt0aGlzLmds
+KCksYixudWxsLG51bGwsbnVsbCxudWxsLG51bGwsbnVsbF0scSkKTS5ZRigiam9pbiIscikKcmV0dXJu
+IHRoaXMuSVAobmV3IEgudTYocix0LmVKKSl9LAp6ZjpmdW5jdGlvbihhKXt2YXIgcyxyLHE9WC5DTChh
+LHRoaXMuYSkKcS5JeCgpCnM9cS5kCnI9cy5sZW5ndGgKaWYocj09PTApe3M9cS5iCnJldHVybiBzPT1u
+dWxsPyIuIjpzfWlmKHI9PT0xKXtzPXEuYgpyZXR1cm4gcz09bnVsbD8iLiI6c31pZigwPj1yKXJldHVy
+biBILk9IKHMsLTEpCnMucG9wKCkKcz1xLmUKaWYoMD49cy5sZW5ndGgpcmV0dXJuIEguT0gocywtMSkK
+cy5wb3AoKQpxLkl4KCkKcmV0dXJuIHEudygwKX0sCklQOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG8s
+bixtLGwsayxqCnQuUS5hKGEpCmZvcihzPWEuJHRpLHI9cy5DKCJhMihjWC5FKSIpLmEobmV3IE0ucTco
+KSkscT1hLmdtKGEpLHM9bmV3IEguU08ocSxyLHMuQygiU088Y1guRT4iKSkscj10aGlzLmEscD0hMSxv
+PSExLG49IiI7cy5GKCk7KXttPXEuZ2woKQppZihyLmhLKG0pJiZvKXtsPVguQ0wobSxyKQprPW4uY2hh
+ckNvZGVBdCgwKT09MD9uOm4Kbj1DLnhCLk5qKGssMCxyLlNwKGssITApKQpsLmI9bgppZihyLmRzKG4p
+KUMuTm0uWTUobC5lLDAsci5nbUkoKSkKbj1sLncoMCl9ZWxzZSBpZihyLllyKG0pPjApe289IXIuaEso
+bSkKbj1ILkVqKG0pfWVsc2V7aj1tLmxlbmd0aAppZihqIT09MCl7aWYoMD49ailyZXR1cm4gSC5PSCht
+LDApCmo9ci5VZChtWzBdKX1lbHNlIGo9ITEKaWYoIWopaWYocCluKz1yLmdtSSgpCm4rPW19cD1yLmRz
+KG0pfXJldHVybiBuLmNoYXJDb2RlQXQoMCk9PTA/bjpufSwKbzU6ZnVuY3Rpb24oYSl7dmFyIHMKaWYo
+IXRoaXMueTMoYSkpcmV0dXJuIGEKcz1YLkNMKGEsdGhpcy5hKQpzLnJSKCkKcmV0dXJuIHMudygwKX0s
+CnkzOmZ1bmN0aW9uKGEpe3ZhciBzLHIscSxwLG8sbixtLGwsayxqCmEudG9TdHJpbmcKcz10aGlzLmEK
+cj1zLllyKGEpCmlmKHIhPT0wKXtpZihzPT09JC5LaygpKWZvcihxPTA7cTxyOysrcSlpZihDLnhCLlco
+YSxxKT09PTQ3KXJldHVybiEwCnA9cgpvPTQ3fWVsc2V7cD0wCm89bnVsbH1mb3Iobj1uZXcgSC5xaihh
+KS5hLG09bi5sZW5ndGgscT1wLGw9bnVsbDtxPG07KytxLGw9byxvPWspe2s9Qy54Qi5PMihuLHEpCmlm
+KHMucjQoaykpe2lmKHM9PT0kLktrKCkmJms9PT00NylyZXR1cm4hMAppZihvIT1udWxsJiZzLnI0KG8p
+KXJldHVybiEwCmlmKG89PT00NilqPWw9PW51bGx8fGw9PT00Nnx8cy5yNChsKQplbHNlIGo9ITEKaWYo
+ailyZXR1cm4hMH19aWYobz09bnVsbClyZXR1cm4hMAppZihzLnI0KG8pKXJldHVybiEwCmlmKG89PT00
+NilzPWw9PW51bGx8fHMucjQobCl8fGw9PT00NgplbHNlIHM9ITEKaWYocylyZXR1cm4hMApyZXR1cm4h
+MX0sCkhQOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxLHAsbyxuLG0sbD10aGlzLGs9J1VuYWJsZSB0byBm
+aW5kIGEgcGF0aCB0byAiJwpiPWwuV08oMCxiKQpzPWwuYQppZihzLllyKGIpPD0wJiZzLllyKGEpPjAp
+cmV0dXJuIGwubzUoYSkKaWYocy5ZcihhKTw9MHx8cy5oSyhhKSlhPWwuV08oMCxhKQppZihzLllyKGEp
+PD0wJiZzLllyKGIpPjApdGhyb3cgSC5iKFguSTcoaytILkVqKGEpKyciIGZyb20gIicrSC5FaihiKSsn
+Ii4nKSkKcj1YLkNMKGIscykKci5yUigpCnE9WC5DTChhLHMpCnEuclIoKQpwPXIuZApvPXAubGVuZ3Ro
+CmlmKG8hPT0wKXtpZigwPj1vKXJldHVybiBILk9IKHAsMCkKcD1KLlJNKHBbMF0sIi4iKX1lbHNlIHA9
+ITEKaWYocClyZXR1cm4gcS53KDApCnA9ci5iCm89cS5iCmlmKHAhPW8pcD1wPT1udWxsfHxvPT1udWxs
+fHwhcy5OYyhwLG8pCmVsc2UgcD0hMQppZihwKXJldHVybiBxLncoMCkKd2hpbGUoITApe3A9ci5kCm89
+cC5sZW5ndGgKaWYobyE9PTApe249cS5kCm09bi5sZW5ndGgKaWYobSE9PTApe2lmKDA+PW8pcmV0dXJu
+IEguT0gocCwwKQpwPXBbMF0KaWYoMD49bSlyZXR1cm4gSC5PSChuLDApCm49cy5OYyhwLG5bMF0pCnA9
+bn1lbHNlIHA9ITF9ZWxzZSBwPSExCmlmKCFwKWJyZWFrCkMuTm0uVzQoci5kLDApCkMuTm0uVzQoci5l
+LDEpCkMuTm0uVzQocS5kLDApCkMuTm0uVzQocS5lLDEpfXA9ci5kCm89cC5sZW5ndGgKaWYobyE9PTAp
+e2lmKDA+PW8pcmV0dXJuIEguT0gocCwwKQpwPUouUk0ocFswXSwiLi4iKX1lbHNlIHA9ITEKaWYocCl0
+aHJvdyBILmIoWC5JNyhrK0guRWooYSkrJyIgZnJvbSAiJytILkVqKGIpKyciLicpKQpwPXQuTgpDLk5t
+LlVHKHEuZCwwLFAuTzgoci5kLmxlbmd0aCwiLi4iLCExLHApKQpDLk5tLlk1KHEuZSwwLCIiKQpDLk5t
+LlVHKHEuZSwxLFAuTzgoci5kLmxlbmd0aCxzLmdtSSgpLCExLHApKQpzPXEuZApwPXMubGVuZ3RoCmlm
+KHA9PT0wKXJldHVybiIuIgppZihwPjEmJkouUk0oQy5ObS5ncloocyksIi4iKSl7cz1xLmQKaWYoMD49
+cy5sZW5ndGgpcmV0dXJuIEguT0gocywtMSkKcy5wb3AoKQpzPXEuZQppZigwPj1zLmxlbmd0aClyZXR1
+cm4gSC5PSChzLC0xKQpzLnBvcCgpCmlmKDA+PXMubGVuZ3RoKXJldHVybiBILk9IKHMsLTEpCnMucG9w
+KCkKQy5ObS5pKHMsIiIpfXEuYj0iIgpxLkl4KCkKcmV0dXJuIHEudygwKX19Ck0ucTcucHJvdG90eXBl
+PXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIEguaChhKSE9PSIifSwKJFM6Nn0KTS5Oby5wcm90b3R5cGU9
+ewokMTpmdW5jdGlvbihhKXtILmsoYSkKcmV0dXJuIGE9PW51bGw/Im51bGwiOiciJythKyciJ30sCiRT
+OjUwfQpCLmZ2LnByb3RvdHlwZT17CnhaOmZ1bmN0aW9uKGEpe3ZhciBzLHI9dGhpcy5ZcihhKQppZihy
+PjApcmV0dXJuIEoubGQoYSwwLHIpCmlmKHRoaXMuaEsoYSkpe2lmKDA+PWEubGVuZ3RoKXJldHVybiBI
+Lk9IKGEsMCkKcz1hWzBdfWVsc2Ugcz1udWxsCnJldHVybiBzfSwKTmM6ZnVuY3Rpb24oYSxiKXtyZXR1
+cm4gYT09Yn19ClguV0QucHJvdG90eXBlPXsKSXg6ZnVuY3Rpb24oKXt2YXIgcyxyLHE9dGhpcwp3aGls
+ZSghMCl7cz1xLmQKaWYoIShzLmxlbmd0aCE9PTAmJkouUk0oQy5ObS5ncloocyksIiIpKSlicmVhawpz
+PXEuZAppZigwPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLC0xKQpzLnBvcCgpCnM9cS5lCmlmKDA+PXMu
+bGVuZ3RoKXJldHVybiBILk9IKHMsLTEpCnMucG9wKCl9cz1xLmUKcj1zLmxlbmd0aAppZihyIT09MClD
+Lk5tLlk1KHMsci0xLCIiKX0sCnJSOmZ1bmN0aW9uKCl7dmFyIHMscixxLHAsbyxuLG09dGhpcyxsPUgu
+Vk0oW10sdC5zKQpmb3Iocz1tLmQscj1zLmxlbmd0aCxxPTAscD0wO3A8cy5sZW5ndGg7cy5sZW5ndGg9
+PT1yfHwoMCxILmxrKShzKSwrK3Ape289c1twXQpuPUouaWEobykKaWYoIShuLkROKG8sIi4iKXx8bi5E
+TihvLCIiKSkpaWYobi5ETihvLCIuLiIpKXtuPWwubGVuZ3RoCmlmKG4hPT0wKXtpZigwPj1uKXJldHVy
+biBILk9IKGwsLTEpCmwucG9wKCl9ZWxzZSArK3F9ZWxzZSBDLk5tLmkobCxvKX1pZihtLmI9PW51bGwp
+Qy5ObS5VRyhsLDAsUC5POChxLCIuLiIsITEsdC5OKSkKaWYobC5sZW5ndGg9PT0wJiZtLmI9PW51bGwp
+Qy5ObS5pKGwsIi4iKQptLnNuSihsKQpzPW0uYQptLnNQaChQLk84KGwubGVuZ3RoKzEscy5nbUkoKSwh
+MCx0Lk4pKQpyPW0uYgppZihyPT1udWxsfHxsLmxlbmd0aD09PTB8fCFzLmRzKHIpKUMuTm0uWTUobS5l
+LDAsIiIpCnI9bS5iCmlmKHIhPW51bGwmJnM9PT0kLktrKCkpe3IudG9TdHJpbmcKbS5iPUgueXMociwi
+LyIsIlxcIil9bS5JeCgpfSwKdzpmdW5jdGlvbihhKXt2YXIgcyxyLHE9dGhpcyxwPXEuYgpwPXAhPW51
+bGw/cDoiIgpmb3Iocz0wO3M8cS5kLmxlbmd0aDsrK3Mpe3I9cS5lCmlmKHM+PXIubGVuZ3RoKXJldHVy
+biBILk9IKHIscykKcj1wK0guRWoocltzXSkKcD1xLmQKaWYocz49cC5sZW5ndGgpcmV0dXJuIEguT0go
+cCxzKQpwPXIrSC5FaihwW3NdKX1wKz1ILkVqKEMuTm0uZ3JaKHEuZSkpCnJldHVybiBwLmNoYXJDb2Rl
+QXQoMCk9PTA/cDpwfSwKc25KOmZ1bmN0aW9uKGEpe3RoaXMuZD10LkUuYShhKX0sCnNQaDpmdW5jdGlv
+bihhKXt0aGlzLmU9dC5FLmEoYSl9fQpYLmR2LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJu
+IlBhdGhFeGNlcHRpb246ICIrdGhpcy5hfSwKJGlSejoxfQpPLnpMLnByb3RvdHlwZT17Cnc6ZnVuY3Rp
+b24oYSl7cmV0dXJuIHRoaXMuZ29jKHRoaXMpfX0KRS5PRi5wcm90b3R5cGU9ewpVZDpmdW5jdGlvbihh
+KXtyZXR1cm4gQy54Qi50ZyhhLCIvIil9LApyNDpmdW5jdGlvbihhKXtyZXR1cm4gYT09PTQ3fSwKZHM6
+ZnVuY3Rpb24oYSl7dmFyIHM9YS5sZW5ndGgKcmV0dXJuIHMhPT0wJiZDLnhCLk8yKGEscy0xKSE9PTQ3
+fSwKU3A6ZnVuY3Rpb24oYSxiKXtpZihhLmxlbmd0aCE9PTAmJkMueEIuVyhhLDApPT09NDcpcmV0dXJu
+IDEKcmV0dXJuIDB9LApZcjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5TcChhLCExKX0sCmhLOmZ1bmN0
+aW9uKGEpe3JldHVybiExfSwKZ29jOmZ1bmN0aW9uKCl7cmV0dXJuInBvc2l4In0sCmdtSTpmdW5jdGlv
+bigpe3JldHVybiIvIn19CkYucnUucHJvdG90eXBlPXsKVWQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEMueEIu
+dGcoYSwiLyIpfSwKcjQ6ZnVuY3Rpb24oYSl7cmV0dXJuIGE9PT00N30sCmRzOmZ1bmN0aW9uKGEpe3Zh
+ciBzPWEubGVuZ3RoCmlmKHM9PT0wKXJldHVybiExCmlmKEMueEIuTzIoYSxzLTEpIT09NDcpcmV0dXJu
+ITAKcmV0dXJuIEMueEIuVGMoYSwiOi8vIikmJnRoaXMuWXIoYSk9PT1zfSwKU3A6ZnVuY3Rpb24oYSxi
+KXt2YXIgcyxyLHEscCxvPWEubGVuZ3RoCmlmKG89PT0wKXJldHVybiAwCmlmKEMueEIuVyhhLDApPT09
+NDcpcmV0dXJuIDEKZm9yKHM9MDtzPG87KytzKXtyPUMueEIuVyhhLHMpCmlmKHI9PT00NylyZXR1cm4g
+MAppZihyPT09NTgpe2lmKHM9PT0wKXJldHVybiAwCnE9Qy54Qi5YVShhLCIvIixDLnhCLlFpKGEsIi8v
+IixzKzEpP3MrMzpzKQppZihxPD0wKXJldHVybiBvCmlmKCFifHxvPHErMylyZXR1cm4gcQppZighQy54
+Qi5uQyhhLCJmaWxlOi8vIikpcmV0dXJuIHEKaWYoIUIuWXUoYSxxKzEpKXJldHVybiBxCnA9cSszCnJl
+dHVybiBvPT09cD9wOnErNH19cmV0dXJuIDB9LApZcjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5TcChh
+LCExKX0sCmhLOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aCE9PTAmJkMueEIuVyhhLDApPT09NDd9
+LApnb2M6ZnVuY3Rpb24oKXtyZXR1cm4idXJsIn0sCmdtSTpmdW5jdGlvbigpe3JldHVybiIvIn19Ckwu
+SVYucHJvdG90eXBlPXsKVWQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEMueEIudGcoYSwiLyIpfSwKcjQ6ZnVu
+Y3Rpb24oYSl7cmV0dXJuIGE9PT00N3x8YT09PTkyfSwKZHM6ZnVuY3Rpb24oYSl7dmFyIHM9YS5sZW5n
+dGgKaWYocz09PTApcmV0dXJuITEKcz1DLnhCLk8yKGEscy0xKQpyZXR1cm4hKHM9PT00N3x8cz09PTky
+KX0sClNwOmZ1bmN0aW9uKGEsYil7dmFyIHMscixxPWEubGVuZ3RoCmlmKHE9PT0wKXJldHVybiAwCnM9
+Qy54Qi5XKGEsMCkKaWYocz09PTQ3KXJldHVybiAxCmlmKHM9PT05Mil7aWYocTwyfHxDLnhCLlcoYSwx
+KSE9PTkyKXJldHVybiAxCnI9Qy54Qi5YVShhLCJcXCIsMikKaWYocj4wKXtyPUMueEIuWFUoYSwiXFwi
+LHIrMSkKaWYocj4wKXJldHVybiByfXJldHVybiBxfWlmKHE8MylyZXR1cm4gMAppZighQi5PUyhzKSly
+ZXR1cm4gMAppZihDLnhCLlcoYSwxKSE9PTU4KXJldHVybiAwCnE9Qy54Qi5XKGEsMikKaWYoIShxPT09
+NDd8fHE9PT05MikpcmV0dXJuIDAKcmV0dXJuIDN9LApZcjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5T
+cChhLCExKX0sCmhLOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLllyKGEpPT09MX0sCk90OmZ1bmN0aW9u
+KGEsYil7dmFyIHMKaWYoYT09PWIpcmV0dXJuITAKaWYoYT09PTQ3KXJldHVybiBiPT09OTIKaWYoYT09
+PTkyKXJldHVybiBiPT09NDcKaWYoKGFeYikhPT0zMilyZXR1cm4hMQpzPWF8MzIKcmV0dXJuIHM+PTk3
+JiZzPD0xMjJ9LApOYzpmdW5jdGlvbihhLGIpe3ZhciBzLHIscQppZihhPT1iKXJldHVybiEwCnM9YS5s
+ZW5ndGgKaWYocyE9PWIubGVuZ3RoKXJldHVybiExCmZvcihyPUouclkoYikscT0wO3E8czsrK3EpaWYo
+IXRoaXMuT3QoQy54Qi5XKGEscSksci5XKGIscSkpKXJldHVybiExCnJldHVybiEwfSwKZ29jOmZ1bmN0
+aW9uKCl7cmV0dXJuIndpbmRvd3MifSwKZ21JOmZ1bmN0aW9uKCl7cmV0dXJuIlxcIn19OyhmdW5jdGlv
+biBhbGlhc2VzKCl7dmFyIHM9Si5Hdi5wcm90b3R5cGUKcy5VPXMudwpzLlNqPXMuZTcKcz1KLk1GLnBy
+b3RvdHlwZQpzLnQ9cy53CnM9UC5jWC5wcm90b3R5cGUKcy5HRz1zLmV2CnM9UC5NaC5wcm90b3R5cGUK
+cy54Yj1zLncKcz1XLmN2LnByb3RvdHlwZQpzLkRXPXMucjYKcz1XLm02LnByb3RvdHlwZQpzLmpGPXMu
+RWIKcz1QLkU0LnByb3RvdHlwZQpzLlVyPXMucQpzLmU0PXMuWTV9KSgpOyhmdW5jdGlvbiBpbnN0YWxs
+VGVhck9mZnMoKXt2YXIgcz1odW5rSGVscGVycy5fc3RhdGljXzEscj1odW5rSGVscGVycy5fc3RhdGlj
+XzAscT1odW5rSGVscGVycy5pbnN0YWxsSW5zdGFuY2VUZWFyT2ZmLHA9aHVua0hlbHBlcnMuaW5zdGFs
+bFN0YXRpY1RlYXJPZmYsbz1odW5rSGVscGVycy5faW5zdGFuY2VfMXUKcyhQLCJFWCIsIlpWIiw3KQpz
+KFAsInl0Iiwib0EiLDcpCnMoUCwicVciLCJCeiIsNykKcihQLCJVSSIsImVOIiwwKQpxKFAuUGYucHJv
+dG90eXBlLCJnWUoiLDAsMSxudWxsLFsiJDIiLCIkMSJdLFsidzAiLCJwbSJdLDI4LDApCnMoUCwiQ3ki
+LCJOQyIsNCkKcyhQLCJQSCIsIk10Iiw1KQpwKFcsInBTIiw0LG51bGwsWyIkNCJdLFsicUQiXSw4LDAp
+CnAoVywiVjQiLDQsbnVsbCxbIiQ0Il0sWyJRVyJdLDgsMCkKbyhQLkFzLnByb3RvdHlwZSwiZ3VNIiwi
+ViIsNSkKcyhQLCJpRyIsIndZIiw1MykKcyhQLCJ3MCIsImRVIiwzNikKcyhMLCJpUyIsImk2IiwyMCl9
+KSgpOyhmdW5jdGlvbiBpbmhlcml0YW5jZSgpe3ZhciBzPWh1bmtIZWxwZXJzLm1peGluLHI9aHVua0hl
+bHBlcnMuaW5oZXJpdCxxPWh1bmtIZWxwZXJzLmluaGVyaXRNYW55CnIoUC5NaCxudWxsKQpxKFAuTWgs
+W0guRkssSi5HdixKLm0xLFAuY1gsSC5FNyxQLlhTLFAublksSC5hNyxQLkFuLEguRnUsSC5KQixILlNV
+LEguUmUsSC53dixQLlBuLEguV1UsSC5MSSxILlRwLEguZjksSC50ZSxILmJxLEguWE8sSC5rcixQLllr
+LEgudmgsSC5ONixILlZSLEguRUssSC5QYixILnRRLEguU2QsSC5KYyxILkcsSC5sWSxQLlczLFAuaWgs
+UC5GeSxQLkdWLFAuUGYsUC5GZSxQLnZzLFAuT00sUC5xaCxQLk1PLFAua1QsUC54SSxQLkN3LFAubTAs
+UC5wUixQLmJuLFAubG0sUC5sRCxQLktQLFAubGYsUC5XWSxQLlVrLFAuU2gsUC5SdyxQLmJ6LFAuaVAs
+UC5rNSxQLktZLFAuQ0QsUC5hRSxQLk4zLFAuYzgsUC5aZCxQLlJuLFAuRG4sUC5QRSxQLlVmLFcuaWQs
+Vy5GayxXLkpRLFcuR20sVy52RCxXLm02LFcuT3csVy5XOSxXLmRXLFcubWssVy5LbyxQLmlKLFAuRTQs
+TS5INyxVLkxMLFUuZDIsVS5TZSxVLk1sLFUueUQsVS53YixCLmo4LEIucXAsVC5tUSxMLlhBLEwuRDgs
+TC5POSxMLkdiLE0ubEksTy56TCxYLldELFguZHZdKQpxKEouR3YsW0oueUUsSi53ZSxKLk1GLEouamQs
+Si5xSSxKLkRyLEguRVQsVy5EMCxXLkF6LFcuTGUsVy5OaCxXLmFlLFcuSUIsVy5uNyxXLmVhLFcuYnIs
+Vy5TZyxXLnc3LFcuSzcsVy5YVyxQLmhGXSkKcShKLk1GLFtKLmlDLEoua2QsSi5jNV0pCnIoSi5QbyxK
+LmpkKQpxKEoucUksW0ouYlUsSi5WQV0pCnEoUC5jWCxbSC5CUixILmJRLEguaTEsSC5VNSxILkFNLEgu
+dTYsSC5YUixQLm1XLEgudW5dKQpxKEguQlIsW0guWnksSC5RQ10pCnIoSC5vbCxILlp5KQpyKEguVXEs
+SC5RQykKcihILmpWLEguVXEpCnEoUC5YUyxbSC5uLEgucjMsSC5HTSxQLkV6LEguYXosSC52VixILkVx
+LFAuQzYsSC5rUyxQLlVkLFAuRixQLnUsUC5tcCxQLnViLFAuZHMsUC5saixQLlVWLFAuY10pCnIoUC51
+eSxQLm5ZKQpxKFAudXksW0gudzIsVy53eixXLmU3XSkKcihILnFqLEgudzIpCnEoSC5iUSxbSC5hTCxI
+Lk1CLEguaTVdKQpxKEguYUwsW0gubkgsSC5sSixQLmk4XSkKcihILnh5LEguaTEpCnEoUC5BbixbSC5N
+SCxILlNPLEguVTFdKQpyKEguZDUsSC5BTSkKcihQLlJVLFAuUG4pCnIoUC5HaixQLlJVKQpyKEguUEQs
+UC5HaikKcihILkxQLEguV1UpCnEoSC5UcCxbSC5DaixILmxjLEguZEMsSC53TixILlZYLFAudGgsUC5o
+YSxQLlZzLFAuRnQsUC55SCxQLldNLFAuU1gsUC5HcyxQLmRhLFAub1EsUC5wVixQLlU3LFAudnIsUC5y
+dCxQLktGLFAuWkwsUC5SVCxQLmpaLFAucnEsUC5SVyxQLkI1LFAudU8sUC5wSyxQLmhqLFAuVnAsUC5P
+UixQLnJhLFAueVEsUC5wZyxQLmMyLFAudGksUC5XRixQLm4xLFAuY1MsUC5WQyxQLkpULFAuUlosUC5N
+RSxQLnk1LFAueUksUC5jNixQLnFkLFcuQ3YsVy5LUyxXLkEzLFcudk4sVy5VdixXLkVnLFcuRW8sVy5X
+ayxXLklBLFcuZm0sUC5qZyxQLlRhLFAuR0UsUC5ONyxQLnVRLFAuUEMsUC5tdCxQLk56LFAuUVMsUC5u
+cCxVLk1ELFUuYU4sVS5iMCxMLmUsTC5WVyxMLm9aLEwuanIsTC5xbCxMLkhpLEwuQlQsTC5QWSxMLnU4
+LEwuTCxMLld4LEwuQU8sTC5kTixMLkhvLEwueHosTC5JQyxMLmZDLEwublQsTC5OWSxMLnVlLEwuZVgs
+TC5FRSxMLlFMLEwuVlMsTC5URCxMLm0yLE0ucTcsTS5Ob10pCnIoSC5XMCxQLkV6KQpxKEgubGMsW0gu
+engsSC5yVF0pCnIoSC5rWSxQLkM2KQpyKFAuaWwsUC5ZaykKcShQLmlsLFtILk41LFAudXcsVy5jZixX
+LlN5XSkKcShQLm1XLFtILktXLFAucTRdKQpyKEguTFosSC5FVCkKcShILkxaLFtILlJHLEguV0JdKQpy
+KEguVlAsSC5SRykKcihILkRnLEguVlApCnIoSC5aRyxILldCKQpyKEguUGcsSC5aRykKcShILlBnLFtI
+LnhqLEguZEUsSC5aQSxILmRULEguUHEsSC5lRSxILlY2XSkKcihILmlNLEgua1MpCnIoUC5aZixQLlBm
+KQpyKFAuSmksUC5tMCkKcihQLlh2LFAucFIpCnIoUC5iNixQLlh2KQpyKFAuVmosUC5XWSkKcShQLlVr
+LFtQLkNWLFAuWmksUC5ieV0pCnIoUC53SSxQLmtUKQpxKFAud0ksW1AuVTgsUC5vaixQLk14LFAuRTMs
+UC5HWV0pCnIoUC5LOCxQLlVkKQpyKFAudHUsUC5TaCkKcihQLnU1LFAuWmkpCnEoUC51LFtQLmJKLFAu
+ZVldKQpyKFAucWUsUC5EbikKcShXLkQwLFtXLnVILFcud2EsVy5LNSxXLkNtXSkKcShXLnVILFtXLmN2
+LFcubngsVy5RRixXLkNRXSkKcShXLmN2LFtXLnFFLFAuaGldKQpxKFcucUUsW1cuR2gsVy5mWSxXLm5C
+LFcuUVAsVy5oNCxXLlNOLFcubHAsVy5UYixXLkl2LFcuV1AsVy55WV0pCnIoVy5vSixXLkxlKQpyKFcu
+aEgsVy5BeikKcihXLlZiLFcuUUYpCnIoVy5mSixXLndhKQpxKFcuZWEsW1cudzYsVy5ld10pCnIoVy5B
+aixXLnc2KQpyKFcuckIsVy5LNykKcihXLkJILFcuckIpCnIoVy53NCxXLklCKQpyKFcub2EsVy5YVykK
+cihXLnJoLFcub2EpCnIoVy5pNyxXLmNmKQpyKFAuQXMsUC5WaikKcShQLkFzLFtXLkk0LFAuS2VdKQpy
+KFcuUk8sUC5xaCkKcihXLmV1LFcuUk8pCnIoVy54QyxQLk1PKQpyKFcuY3QsVy5tNikKcihQLkJmLFAu
+aUopCnEoUC5FNCxbUC5yNyxQLmNvXSkKcihQLlR6LFAuY28pCnIoUC5uZCxQLmhpKQpxKEwuRDgsW0wu
+dnQsTC5jRF0pCnIoQi5mdixPLnpMKQpxKEIuZnYsW0UuT0YsRi5ydSxMLklWXSkKcyhILncyLEguUmUp
+CnMoSC5RQyxQLmxEKQpzKEguUkcsUC5sRCkKcyhILlZQLEguU1UpCnMoSC5XQixQLmxEKQpzKEguWkcs
+SC5TVSkKcyhQLm5ZLFAubEQpCnMoUC5XWSxQLmxmKQpzKFAuUlUsUC5LUCkKcyhQLnBSLFAubGYpCnMo
+Vy5MZSxXLmlkKQpzKFcuSzcsUC5sRCkKcyhXLnJCLFcuR20pCnMoVy5YVyxQLmxEKQpzKFcub2EsVy5H
+bSkKcyhQLmNvLFAubEQpfSkoKQp2YXIgdj17dHlwZVVuaXZlcnNlOntlQzpuZXcgTWFwKCksdFI6e30s
+ZVQ6e30sdFBWOnt9LHNFQTpbXX0sbWFuZ2xlZEdsb2JhbE5hbWVzOntJZjoiaW50IixDUDoiZG91Ymxl
+IixaWjoibnVtIixxVToiU3RyaW5nIixhMjoiYm9vbCIsYzg6Ik51bGwiLHpNOiJMaXN0In0sbWFuZ2xl
+ZE5hbWVzOnt9LGdldFR5cGVGcm9tTmFtZTpnZXRHbG9iYWxGcm9tTmFtZSxtZXRhZGF0YTpbXSx0eXBl
+czpbIn4oKSIsImM4KEFqKikiLCJjOCgpIiwiYzgoY3YqKSIsIkAoQCkiLCJxVShxVSkiLCJhMihxVSki
+LCJ+KH4oKSkiLCJhMihjdixxVSxxVSxKUSkiLCJjOChAKSIsIn4oTWg/LE1oPykiLCJAKCkiLCJ+KHFV
+LEApIiwifihuNixxVSxJZikiLCJ+KHFVLHFVKSIsImEyKGtGKSIsImM4KEAsQCkiLCJ+KHh1PHFVPiki
+LCJjOChlYSopIiwiYjg8Yzg+KihBaiopIiwifihBaiopIiwifihxVSxJZikiLCJ+KHFVLHFVPykiLCJu
+NihALEApIiwiYzgoQCxHeikiLCJhMih1SCkiLCJ+KElmLEApIiwifihlYSkiLCJ+KE1oW0d6P10pIiwi
+YzgoTWgsR3opIiwifih1SCx1SD8pIiwifihALEApIiwidnM8QD4oQCkiLCJhMih4dTxxVT4pIiwiYzgo
+figpKSIsInI3KEApIiwiTWg/KEApIiwiRTQoQCkiLCJhMiooSDcqKSIsIkxMKihAKSIsIlowPHFVKixN
+aCo+KihMTCopIiwiQChxVSkiLCJ+KEdELEApIiwiYzgoWjA8cVUqLE1oKj4qKSIsIlowPHFVLHFVPiha
+MDxxVSxxVT4scVUpIiwicVUqKEFqKikiLCJAKEAscVUpIiwiYzgoZXcqKSIsInFVKihaMDxALEA+Kiki
+LCJ+KHFVW0BdKSIsInFVKHFVPykiLCJJZihJZixJZikiLCJ+KEApIiwiTWg/KE1oPykiLCJUejxAPihA
+KSJdLGludGVyY2VwdG9yc0J5VGFnOm51bGwsbGVhZlRhZ3M6bnVsbCxhcnJheVJ0aTp0eXBlb2YgU3lt
+Ym9sPT0iZnVuY3Rpb24iJiZ0eXBlb2YgU3ltYm9sKCk9PSJzeW1ib2wiP1N5bWJvbCgiJHRpIik6IiR0
+aSJ9CkgueGIodi50eXBlVW5pdmVyc2UsSlNPTi5wYXJzZSgneyJjNSI6Ik1GIiwiaUMiOiJNRiIsImtk
+IjoiTUYiLCJyeCI6ImVhIiwiZTUiOiJlYSIsIlkwIjoiaGkiLCJ0cCI6ImhpIiwiRzgiOiJldyIsIk1y
+IjoicUUiLCJlTCI6InFFIiwiSTAiOiJ1SCIsImhzIjoidUgiLCJYZyI6IlFGIiwibnIiOiJBaiIsInk0
+IjoidzYiLCJhUCI6IkNtIiwieGMiOiJueCIsImtKIjoibngiLCJ6VSI6IkRnIiwiZGYiOiJFVCIsInlF
+Ijp7ImEyIjpbXX0sIndlIjp7ImM4IjpbXX0sIk1GIjp7InZtIjpbXSwiRUgiOltdfSwiamQiOnsiek0i
+OlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sIlBvIjp7ImpkIjpbIjEiXSwiek0iOlsiMSJdLCJi
+USI6WyIxIl0sImNYIjpbIjEiXX0sIm0xIjp7IkFuIjpbIjEiXX0sInFJIjp7IkNQIjpbXSwiWloiOltd
+fSwiYlUiOnsiQ1AiOltdLCJJZiI6W10sIlpaIjpbXX0sIlZBIjp7IkNQIjpbXSwiWloiOltdfSwiRHIi
+OnsicVUiOltdLCJ2WCI6W119LCJCUiI6eyJjWCI6WyIyIl19LCJFNyI6eyJBbiI6WyIyIl19LCJaeSI6
+eyJCUiI6WyIxIiwiMiJdLCJjWCI6WyIyIl0sImNYLkUiOiIyIn0sIm9sIjp7Ilp5IjpbIjEiLCIyIl0s
+IkJSIjpbIjEiLCIyIl0sImJRIjpbIjIiXSwiY1giOlsiMiJdLCJjWC5FIjoiMiJ9LCJVcSI6eyJsRCI6
+WyIyIl0sInpNIjpbIjIiXSwiQlIiOlsiMSIsIjIiXSwiYlEiOlsiMiJdLCJjWCI6WyIyIl19LCJqViI6
+eyJVcSI6WyIxIiwiMiJdLCJsRCI6WyIyIl0sInpNIjpbIjIiXSwiQlIiOlsiMSIsIjIiXSwiYlEiOlsi
+MiJdLCJjWCI6WyIyIl0sImxELkUiOiIyIiwiY1guRSI6IjIifSwibiI6eyJYUyI6W119LCJyMyI6eyJY
+UyI6W119LCJxaiI6eyJsRCI6WyJJZiJdLCJSZSI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJiUSI6WyJJZiJd
+LCJjWCI6WyJJZiJdLCJsRC5FIjoiSWYiLCJSZS5FIjoiSWYifSwiR00iOnsiWFMiOltdfSwiYlEiOnsi
+Y1giOlsiMSJdfSwiYUwiOnsiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJuSCI6eyJhTCI6WyIxIl0sImJR
+IjpbIjEiXSwiY1giOlsiMSJdLCJhTC5FIjoiMSIsImNYLkUiOiIxIn0sImE3Ijp7IkFuIjpbIjEiXX0s
+ImkxIjp7ImNYIjpbIjIiXSwiY1guRSI6IjIifSwieHkiOnsiaTEiOlsiMSIsIjIiXSwiYlEiOlsiMiJd
+LCJjWCI6WyIyIl0sImNYLkUiOiIyIn0sIk1IIjp7IkFuIjpbIjIiXX0sImxKIjp7ImFMIjpbIjIiXSwi
+YlEiOlsiMiJdLCJjWCI6WyIyIl0sImFMLkUiOiIyIiwiY1guRSI6IjIifSwiVTUiOnsiY1giOlsiMSJd
+LCJjWC5FIjoiMSJ9LCJTTyI6eyJBbiI6WyIxIl19LCJBTSI6eyJjWCI6WyIxIl0sImNYLkUiOiIxIn0s
+ImQ1Ijp7IkFNIjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl0sImNYLkUiOiIxIn0sIlUxIjp7IkFu
+IjpbIjEiXX0sIk1CIjp7ImJRIjpbIjEiXSwiY1giOlsiMSJdLCJjWC5FIjoiMSJ9LCJGdSI6eyJBbiI6
+WyIxIl19LCJ1NiI6eyJjWCI6WyIxIl0sImNYLkUiOiIxIn0sIkpCIjp7IkFuIjpbIjEiXX0sIncyIjp7
+ImxEIjpbIjEiXSwiUmUiOlsiMSJdLCJ6TSI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJdfSwid3Yi
+OnsiR0QiOltdfSwiUEQiOnsiR2oiOlsiMSIsIjIiXSwiUlUiOlsiMSIsIjIiXSwiUG4iOlsiMSIsIjIi
+XSwiS1AiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIiXX0sIldVIjp7IlowIjpbIjEiLCIyIl19LCJMUCI6
+eyJXVSI6WyIxIiwiMiJdLCJaMCI6WyIxIiwiMiJdfSwiWFIiOnsiY1giOlsiMSJdLCJjWC5FIjoiMSJ9
+LCJMSSI6eyJ2USI6W119LCJXMCI6eyJYUyI6W119LCJheiI6eyJYUyI6W119LCJ2ViI6eyJYUyI6W119
+LCJ0ZSI6eyJSeiI6W119LCJYTyI6eyJHeiI6W119LCJUcCI6eyJFSCI6W119LCJsYyI6eyJFSCI6W119
+LCJ6eCI6eyJFSCI6W119LCJyVCI6eyJFSCI6W119LCJFcSI6eyJYUyI6W119LCJrWSI6eyJYUyI6W119
+LCJONSI6eyJZayI6WyIxIiwiMiJdLCJGbyI6WyIxIiwiMiJdLCJaMCI6WyIxIiwiMiJdLCJZay5LIjoi
+MSIsIllrLlYiOiIyIn0sImk1Ijp7ImJRIjpbIjEiXSwiY1giOlsiMSJdLCJjWC5FIjoiMSJ9LCJONiI6
+eyJBbiI6WyIxIl19LCJWUiI6eyJ3TCI6W10sInZYIjpbXX0sIkVLIjp7ImliIjpbXSwiT2QiOltdfSwi
+S1ciOnsiY1giOlsiaWIiXSwiY1guRSI6ImliIn0sIlBiIjp7IkFuIjpbImliIl19LCJ0USI6eyJPZCI6
+W119LCJ1biI6eyJjWCI6WyJPZCJdLCJjWC5FIjoiT2QifSwiU2QiOnsiQW4iOlsiT2QiXX0sIkVUIjp7
+IkFTIjpbXX0sIkxaIjp7IlhqIjpbIjEiXSwiRVQiOltdLCJBUyI6W119LCJEZyI6eyJsRCI6WyJDUCJd
+LCJYaiI6WyJDUCJdLCJ6TSI6WyJDUCJdLCJFVCI6W10sImJRIjpbIkNQIl0sIkFTIjpbXSwiY1giOlsi
+Q1AiXSwiU1UiOlsiQ1AiXSwibEQuRSI6IkNQIn0sIlBnIjp7ImxEIjpbIklmIl0sIlhqIjpbIklmIl0s
+InpNIjpbIklmIl0sIkVUIjpbXSwiYlEiOlsiSWYiXSwiQVMiOltdLCJjWCI6WyJJZiJdLCJTVSI6WyJJ
+ZiJdfSwieGoiOnsibEQiOlsiSWYiXSwiWGoiOlsiSWYiXSwiek0iOlsiSWYiXSwiRVQiOltdLCJiUSI6
+WyJJZiJdLCJBUyI6W10sImNYIjpbIklmIl0sIlNVIjpbIklmIl0sImxELkUiOiJJZiJ9LCJkRSI6eyJs
+RCI6WyJJZiJdLCJYaiI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJFVCI6W10sImJRIjpbIklmIl0sIkFTIjpb
+XSwiY1giOlsiSWYiXSwiU1UiOlsiSWYiXSwibEQuRSI6IklmIn0sIlpBIjp7ImxEIjpbIklmIl0sIlhq
+IjpbIklmIl0sInpNIjpbIklmIl0sIkVUIjpbXSwiYlEiOlsiSWYiXSwiQVMiOltdLCJjWCI6WyJJZiJd
+LCJTVSI6WyJJZiJdLCJsRC5FIjoiSWYifSwiZFQiOnsibEQiOlsiSWYiXSwiWGoiOlsiSWYiXSwiek0i
+OlsiSWYiXSwiRVQiOltdLCJiUSI6WyJJZiJdLCJBUyI6W10sImNYIjpbIklmIl0sIlNVIjpbIklmIl0s
+ImxELkUiOiJJZiJ9LCJQcSI6eyJsRCI6WyJJZiJdLCJYaiI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJFVCI6
+W10sImJRIjpbIklmIl0sIkFTIjpbXSwiY1giOlsiSWYiXSwiU1UiOlsiSWYiXSwibEQuRSI6IklmIn0s
+ImVFIjp7ImxEIjpbIklmIl0sIlhqIjpbIklmIl0sInpNIjpbIklmIl0sIkVUIjpbXSwiYlEiOlsiSWYi
+XSwiQVMiOltdLCJjWCI6WyJJZiJdLCJTVSI6WyJJZiJdLCJsRC5FIjoiSWYifSwiVjYiOnsibEQiOlsi
+SWYiXSwibjYiOltdLCJYaiI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJFVCI6W10sImJRIjpbIklmIl0sIkFT
+IjpbXSwiY1giOlsiSWYiXSwiU1UiOlsiSWYiXSwibEQuRSI6IklmIn0sImtTIjp7IlhTIjpbXX0sImlN
+Ijp7IlhTIjpbXX0sIkdWIjp7IkFuIjpbIjEiXX0sInE0Ijp7ImNYIjpbIjEiXSwiY1guRSI6IjEifSwi
+WmYiOnsiUGYiOlsiMSJdfSwidnMiOnsiYjgiOlsiMSJdfSwiQ3ciOnsiWFMiOltdfSwibTAiOnsiUW0i
+OltdfSwiSmkiOnsibTAiOltdLCJRbSI6W119LCJiNiI6eyJsZiI6WyIxIl0sInh1IjpbIjEiXSwiYlEi
+OlsiMSJdLCJjWCI6WyIxIl0sImxmLkUiOiIxIn0sImxtIjp7IkFuIjpbIjEiXX0sIm1XIjp7ImNYIjpb
+IjEiXX0sInV5Ijp7ImxEIjpbIjEiXSwiek0iOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sImls
+Ijp7IllrIjpbIjEiLCIyIl0sIlowIjpbIjEiLCIyIl19LCJZayI6eyJaMCI6WyIxIiwiMiJdfSwiUG4i
+OnsiWjAiOlsiMSIsIjIiXX0sIkdqIjp7IlJVIjpbIjEiLCIyIl0sIlBuIjpbIjEiLCIyIl0sIktQIjpb
+IjEiLCIyIl0sIlowIjpbIjEiLCIyIl19LCJWaiI6eyJsZiI6WyIxIl0sInh1IjpbIjEiXSwiYlEiOlsi
+MSJdLCJjWCI6WyIxIl19LCJYdiI6eyJsZiI6WyIxIl0sInh1IjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6
+WyIxIl19LCJ1dyI6eyJZayI6WyJxVSIsIkAiXSwiWjAiOlsicVUiLCJAIl0sIllrLksiOiJxVSIsIllr
+LlYiOiJAIn0sImk4Ijp7ImFMIjpbInFVIl0sImJRIjpbInFVIl0sImNYIjpbInFVIl0sImFMLkUiOiJx
+VSIsImNYLkUiOiJxVSJ9LCJDViI6eyJVayI6WyJ6TTxJZj4iLCJxVSJdLCJVay5TIjoiek08SWY+In0s
+IlU4Ijp7IndJIjpbInpNPElmPiIsInFVIl19LCJaaSI6eyJVayI6WyJxVSIsInpNPElmPiJdfSwiVWQi
+OnsiWFMiOltdfSwiSzgiOnsiWFMiOltdfSwiYnkiOnsiVWsiOlsiTWg/IiwicVUiXSwiVWsuUyI6Ik1o
+PyJ9LCJvaiI6eyJ3SSI6WyJNaD8iLCJxVSJdfSwiTXgiOnsid0kiOlsicVUiLCJNaD8iXX0sInU1Ijp7
+IlVrIjpbInFVIiwiek08SWY+Il0sIlVrLlMiOiJxVSJ9LCJFMyI6eyJ3SSI6WyJxVSIsInpNPElmPiJd
+fSwiR1kiOnsid0kiOlsiek08SWY+IiwicVUiXX0sIkNQIjp7IlpaIjpbXX0sIklmIjp7IlpaIjpbXX0s
+InpNIjp7ImJRIjpbIjEiXSwiY1giOlsiMSJdfSwiaWIiOnsiT2QiOltdfSwieHUiOnsiYlEiOlsiMSJd
+LCJjWCI6WyIxIl19LCJxVSI6eyJ2WCI6W119LCJDNiI6eyJYUyI6W119LCJFeiI6eyJYUyI6W119LCJG
+Ijp7IlhTIjpbXX0sInUiOnsiWFMiOltdfSwiYkoiOnsiWFMiOltdfSwiZVkiOnsiWFMiOltdfSwibXAi
+OnsiWFMiOltdfSwidWIiOnsiWFMiOltdfSwiZHMiOnsiWFMiOltdfSwibGoiOnsiWFMiOltdfSwiVVYi
+OnsiWFMiOltdfSwiazUiOnsiWFMiOltdfSwiS1kiOnsiWFMiOltdfSwiYyI6eyJYUyI6W119LCJDRCI6
+eyJSeiI6W119LCJhRSI6eyJSeiI6W119LCJaZCI6eyJHeiI6W119LCJSbiI6eyJCTCI6W119LCJEbiI6
+eyJpRCI6W119LCJVZiI6eyJpRCI6W119LCJxZSI6eyJpRCI6W119LCJxRSI6eyJjdiI6W10sInVIIjpb
+XSwiRDAiOltdfSwiR2giOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sImZZIjp7ImN2IjpbXSwidUgi
+OltdLCJEMCI6W119LCJuQiI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiUVAiOnsiY3YiOltdLCJ1
+SCI6W10sIkQwIjpbXX0sIm54Ijp7InVIIjpbXSwiRDAiOltdfSwiUUYiOnsidUgiOltdLCJEMCI6W119
+LCJJQiI6eyJ0biI6WyJaWiJdfSwid3oiOnsibEQiOlsiMSJdLCJ6TSI6WyIxIl0sImJRIjpbIjEiXSwi
+Y1giOlsiMSJdLCJsRC5FIjoiMSJ9LCJjdiI6eyJ1SCI6W10sIkQwIjpbXX0sImhIIjp7IkF6IjpbXX0s
+Img0Ijp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJWYiI6eyJ1SCI6W10sIkQwIjpbXX0sImZKIjp7
+IkQwIjpbXX0sIndhIjp7IkQwIjpbXX0sIkFqIjp7ImVhIjpbXX0sImU3Ijp7ImxEIjpbInVIIl0sInpN
+IjpbInVIIl0sImJRIjpbInVIIl0sImNYIjpbInVIIl0sImxELkUiOiJ1SCJ9LCJ1SCI6eyJEMCI6W119
+LCJCSCI6eyJsRCI6WyJ1SCJdLCJHbSI6WyJ1SCJdLCJ6TSI6WyJ1SCJdLCJYaiI6WyJ1SCJdLCJiUSI6
+WyJ1SCJdLCJjWCI6WyJ1SCJdLCJsRC5FIjoidUgiLCJHbS5FIjoidUgifSwiU04iOnsiY3YiOltdLCJ1
+SCI6W10sIkQwIjpbXX0sImV3Ijp7ImVhIjpbXX0sImxwIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119
+LCJUYiI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiSXYiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpb
+XX0sIldQIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJ5WSI6eyJjdiI6W10sInVIIjpbXSwiRDAi
+OltdfSwidzYiOnsiZWEiOltdfSwiSzUiOnsidjYiOltdLCJEMCI6W119LCJDbSI6eyJEMCI6W119LCJD
+USI6eyJ1SCI6W10sIkQwIjpbXX0sInc0Ijp7InRuIjpbIlpaIl19LCJyaCI6eyJsRCI6WyJ1SCJdLCJH
+bSI6WyJ1SCJdLCJ6TSI6WyJ1SCJdLCJYaiI6WyJ1SCJdLCJiUSI6WyJ1SCJdLCJjWCI6WyJ1SCJdLCJs
+RC5FIjoidUgiLCJHbS5FIjoidUgifSwiY2YiOnsiWWsiOlsicVUiLCJxVSJdLCJaMCI6WyJxVSIsInFV
+Il19LCJpNyI6eyJZayI6WyJxVSIsInFVIl0sIlowIjpbInFVIiwicVUiXSwiWWsuSyI6InFVIiwiWWsu
+ViI6InFVIn0sIlN5Ijp7IllrIjpbInFVIiwicVUiXSwiWjAiOlsicVUiLCJxVSJdLCJZay5LIjoicVUi
+LCJZay5WIjoicVUifSwiSTQiOnsibGYiOlsicVUiXSwieHUiOlsicVUiXSwiYlEiOlsicVUiXSwiY1gi
+OlsicVUiXSwibGYuRSI6InFVIn0sIlJPIjp7InFoIjpbIjEiXX0sImV1Ijp7IlJPIjpbIjEiXSwicWgi
+OlsiMSJdfSwieEMiOnsiTU8iOlsiMSJdfSwiSlEiOnsia0YiOltdfSwidkQiOnsia0YiOltdfSwibTYi
+Onsia0YiOltdfSwiY3QiOnsia0YiOltdfSwiT3ciOnsia0YiOltdfSwiVzkiOnsiQW4iOlsiMSJdfSwi
+ZFciOnsidjYiOltdLCJEMCI6W119LCJtayI6eyJ5MCI6W119LCJLbyI6eyJvbiI6W119LCJBcyI6eyJs
+ZiI6WyJxVSJdLCJ4dSI6WyJxVSJdLCJiUSI6WyJxVSJdLCJjWCI6WyJxVSJdfSwicjciOnsiRTQiOltd
+fSwiVHoiOnsibEQiOlsiMSJdLCJ6TSI6WyIxIl0sImJRIjpbIjEiXSwiRTQiOltdLCJjWCI6WyIxIl0s
+ImxELkUiOiIxIn0sIm5kIjp7ImhpIjpbXSwiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIktlIjp7Imxm
+IjpbInFVIl0sInh1IjpbInFVIl0sImJRIjpbInFVIl0sImNYIjpbInFVIl0sImxmLkUiOiJxVSJ9LCJo
+aSI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiWEEiOnsia0YiOltdfSwidnQiOnsiRDgiOltdfSwi
+Y0QiOnsiRDgiOltdfSwiZHYiOnsiUnoiOltdfSwiT0YiOnsiZnYiOltdfSwicnUiOnsiZnYiOltdfSwi
+SVYiOnsiZnYiOltdfSwibjYiOnsiek0iOlsiSWYiXSwiYlEiOlsiSWYiXSwiY1giOlsiSWYiXSwiQVMi
+OltdfX0nKSkKSC5GRih2LnR5cGVVbml2ZXJzZSxKU09OLnBhcnNlKCd7IncyIjoxLCJRQyI6MiwiTFoi
+OjEsImtUIjoyLCJtVyI6MSwidXkiOjEsImlsIjoyLCJWaiI6MSwiWHYiOjEsIm5ZIjoxLCJXWSI6MSwi
+cFIiOjEsImNvIjoxfScpKQp2YXIgdT17bDoiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBh
+IFVSSSB3aXRoIGEgZnJhZ21lbnQgY29tcG9uZW50IixpOiJDYW5ub3QgZXh0cmFjdCBhIGZpbGUgcGF0
+aCBmcm9tIGEgVVJJIHdpdGggYSBxdWVyeSBjb21wb25lbnQiLGo6IkNhbm5vdCBleHRyYWN0IGEgbm9u
+LVdpbmRvd3MgZmlsZSBwYXRoIGZyb20gYSBmaWxlIFVSSSB3aXRoIGFuIGF1dGhvcml0eSIsZzoiYG51
+bGxgIGVuY291bnRlcmVkIGFzIHRoZSByZXN1bHQgZnJvbSBleHByZXNzaW9uIHdpdGggdHlwZSBgTmV2
+ZXJgLiIsZDoiYXJlYS1hbmFseXplcixhbmFseXplci1ubmJkLW1pZ3JhdGlvbix0eXBlLWJ1ZyJ9CnZh
+ciB0PShmdW5jdGlvbiBydGlpKCl7dmFyIHM9SC5OMApyZXR1cm57bjpzKCJDdyIpLGNSOnMoIm5CIiks
+dzpzKCJBeiIpLHA6cygiUVAiKSxnRjpzKCJQRDxHRCxAPiIpLGI6cygiYlE8QD4iKSxoOnMoImN2Iiks
+cjpzKCJYUyIpLEI6cygiZWEiKSxhUzpzKCJEMCIpLGc4OnMoIlJ6IiksYzg6cygiaEgiKSxZOnMoIkVI
+IiksZDpzKCJiODxAPiIpLEk6cygiU2ciKSxvOnMoInZRIiksZWg6cygiY1g8dUg+IiksUTpzKCJjWDxx
+VT4iKSx1OnMoImNYPEA+IiksdjpzKCJqZDxrRj4iKSxzOnMoImpkPHFVPiIpLGdOOnMoImpkPG42PiIp
+LHg6cygiamQ8QD4iKSxhOnMoImpkPElmPiIpLGQ3OnMoImpkPFNlKj4iKSxoNDpzKCJqZDxqOCo+Iiks
+RzpzKCJqZDxaMDxxVSosTWgqPio+IiksY1E6cygiamQ8RDgqPiIpLGk6cygiamQ8cVUqPiIpLGFBOnMo
+ImpkPHlEKj4iKSxhSjpzKCJqZDx3Yio+IiksVjpzKCJqZDxJZio+IiksZDQ6cygiamQ8cVU/PiIpLFQ6
+cygid2UiKSxlSDpzKCJ2bSIpLEQ6cygiYzUiKSxhVTpzKCJYajxAPiIpLGFtOnMoIlR6PEA+IiksZW86
+cygiTjU8R0QsQD4iKSxkejpzKCJoRiIpLEU6cygiek08cVU+IiksajpzKCJ6TTxAPiIpLEw6cygiek08
+SWY+IiksSjpzKCJaMDxxVSxxVT4iKSxmOnMoIlowPEAsQD4iKSxkbzpzKCJsSjxxVSxAPiIpLGZqOnMo
+ImxKPHFVKixxVT4iKSxkRTpzKCJFVCIpLGJtOnMoIlY2IiksQTpzKCJ1SCIpLGY2OnMoImtGIiksUDpz
+KCJjOCIpLEs6cygiTWgiKSxxOnMoInRuPFpaPiIpLGZ2OnMoIndMIiksZXc6cygibmQiKSxDOnMoInh1
+PHFVPiIpLGw6cygiR3oiKSxOOnMoInFVIiksZDA6cygicVUocVUqKSIpLGc3OnMoImhpIiksZm86cygi
+R0QiKSxhVzpzKCJ5WSIpLGFrOnMoIkFTIiksZ2M6cygibjYiKSxiSjpzKCJrZCIpLGR3OnMoIkdqPHFV
+LHFVPiIpLGREOnMoImlEIiksZUo6cygidTY8cVU+IiksZzQ6cygiSzUiKSxjaTpzKCJ2NiIpLGcyOnMo
+IkNtIiksYkM6cygiWmY8ZkoqPiIpLGg5OnMoIkNRIiksYWM6cygiZTciKSxrOnMoImV1PEFqKj4iKSxS
+OnMoInd6PGN2Kj4iKSxjOnMoInZzPEA+IiksZko6cygidnM8SWY+IiksZ1Y6cygidnM8ZkoqPiIpLGNy
+OnMoIkpRIikseTpzKCJhMiIpLGFsOnMoImEyKE1oKSIpLGdSOnMoIkNQIiksejpzKCJAIiksZk86cygi
+QCgpIiksYkk6cygiQChNaCkiKSxhZzpzKCJAKE1oLEd6KSIpLGJVOnMoIkAoeHU8cVU+KSIpLGRPOnMo
+IkAocVUpIiksYjg6cygiQChALEApIiksUzpzKCJJZiIpLGRkOnMoIkdoKiIpLGc6cygiY3YqIiksYUw6
+cygiZWEqIiksYVg6cygiTEwqIiksZkU6cygiSDcqIiksVTpzKCJjWDxAPioiKSxkSDpzKCJFNCoiKSxm
+SzpzKCJ6TTxAPioiKSxkXzpzKCJ6TTxqOCo+KiIpLGRwOnMoInpNPFowPHFVKixNaCo+Kj4qIiksbTpz
+KCJ6TTxNaCo+KiIpLGF3OnMoIlowPEAsQD4qIiksdDpzKCJaMDxxVSosTWgqPioiKSxPOnMoIkFqKiIp
+LGNGOnMoIjAmKiIpLF86cygiTWgqIiksZVE6cygiZXcqIiksWDpzKCJxVSoiKSxjaDpzKCJEMD8iKSxi
+RzpzKCJiODxjOD4/IiksYms6cygiek08cVU+PyIpLGJNOnMoInpNPEA+PyIpLGNaOnMoIlowPHFVLHFV
+Pj8iKSxjOTpzKCJaMDxxVSxAPj8iKSxXOnMoIk1oPyIpLEY6cygiRmU8QCxAPj8iKSxlOnMoImJuPyIp
+LGI3OnMoImEyKE1oKT8iKSxidzpzKCJAKGVhKT8iKSxmVjpzKCJNaD8oTWg/LE1oPyk/IiksZEE6cygi
+TWg/KEApPyIpLFo6cygifigpPyIpLGViOnMoIn4oZXcqKT8iKSxkaTpzKCJaWiIpLEg6cygifiIpLE06
+cygifigpIiksZUE6cygifihxVSxxVSkiKSxjQTpzKCJ+KHFVLEApIil9fSkoKTsoZnVuY3Rpb24gY29u
+c3RhbnRzKCl7dmFyIHM9aHVua0hlbHBlcnMubWFrZUNvbnN0TGlzdApDLnhuPVcuR2gucHJvdG90eXBl
+CkMuUlk9Vy5RUC5wcm90b3R5cGUKQy5tSD1XLmFlLnByb3RvdHlwZQpDLkJaPVcuVmIucHJvdG90eXBl
+CkMuRHQ9Vy5mSi5wcm90b3R5cGUKQy5Paz1KLkd2LnByb3RvdHlwZQpDLk5tPUouamQucHJvdG90eXBl
+CkMuam49Si5iVS5wcm90b3R5cGUKQy5qTj1KLndlLnByb3RvdHlwZQpDLkNEPUoucUkucHJvdG90eXBl
+CkMueEI9Si5Eci5wcm90b3R5cGUKQy5ERz1KLmM1LnByb3RvdHlwZQpDLkV4PVcudzcucHJvdG90eXBl
+CkMuTkE9SC5WNi5wcm90b3R5cGUKQy50NT1XLkJILnByb3RvdHlwZQpDLkx0PVcuU04ucHJvdG90eXBl
+CkMuWlE9Si5pQy5wcm90b3R5cGUKQy5JZT1XLlRiLnByb3RvdHlwZQpDLnZCPUoua2QucHJvdG90eXBl
+CkMub2w9Vy5LNS5wcm90b3R5cGUKQy55OD1uZXcgUC5VOCgpCkMuaDk9bmV3IFAuQ1YoKQpDLkd3PW5l
+dyBILkZ1KEguTjAoIkZ1PGM4PiIpKQpDLk80PWZ1bmN0aW9uIGdldFRhZ0ZhbGxiYWNrKG8pIHsKICB2
+YXIgcyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKTsKICByZXR1cm4gcy5zdWJzdHJp
+bmcoOCwgcy5sZW5ndGggLSAxKTsKfQpDLllxPWZ1bmN0aW9uKCkgewogIHZhciB0b1N0cmluZ0Z1bmN0
+aW9uID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZzsKICBmdW5jdGlvbiBnZXRUYWcobykgewogICAg
+dmFyIHMgPSB0b1N0cmluZ0Z1bmN0aW9uLmNhbGwobyk7CiAgICByZXR1cm4gcy5zdWJzdHJpbmcoOCwg
+cy5sZW5ndGggLSAxKTsKICB9CiAgZnVuY3Rpb24gZ2V0VW5rbm93blRhZyhvYmplY3QsIHRhZykgewog
+ICAgaWYgKC9eSFRNTFtBLVpdLipFbGVtZW50JC8udGVzdCh0YWcpKSB7CiAgICAgIHZhciBuYW1lID0g
+dG9TdHJpbmdGdW5jdGlvbi5jYWxsKG9iamVjdCk7CiAgICAgIGlmIChuYW1lID09ICJbb2JqZWN0IE9i
+amVjdF0iKSByZXR1cm4gbnVsbDsKICAgICAgcmV0dXJuICJIVE1MRWxlbWVudCI7CiAgICB9CiAgfQog
+IGZ1bmN0aW9uIGdldFVua25vd25UYWdHZW5lcmljQnJvd3NlcihvYmplY3QsIHRhZykgewogICAgaWYg
+KHNlbGYuSFRNTEVsZW1lbnQgJiYgb2JqZWN0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHJldHVybiAi
+SFRNTEVsZW1lbnQiOwogICAgcmV0dXJuIGdldFVua25vd25UYWcob2JqZWN0LCB0YWcpOwogIH0KICBm
+dW5jdGlvbiBwcm90b3R5cGVGb3JUYWcodGFnKSB7CiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PSAidW5k
+ZWZpbmVkIikgcmV0dXJuIG51bGw7CiAgICBpZiAodHlwZW9mIHdpbmRvd1t0YWddID09ICJ1bmRlZmlu
+ZWQiKSByZXR1cm4gbnVsbDsKICAgIHZhciBjb25zdHJ1Y3RvciA9IHdpbmRvd1t0YWddOwogICAgaWYg
+KHR5cGVvZiBjb25zdHJ1Y3RvciAhPSAiZnVuY3Rpb24iKSByZXR1cm4gbnVsbDsKICAgIHJldHVybiBj
+b25zdHJ1Y3Rvci5wcm90b3R5cGU7CiAgfQogIGZ1bmN0aW9uIGRpc2NyaW1pbmF0b3IodGFnKSB7IHJl
+dHVybiBudWxsOyB9CiAgdmFyIGlzQnJvd3NlciA9IHR5cGVvZiBuYXZpZ2F0b3IgPT0gIm9iamVjdCI7
+CiAgcmV0dXJuIHsKICAgIGdldFRhZzogZ2V0VGFnLAogICAgZ2V0VW5rbm93blRhZzogaXNCcm93c2Vy
+ID8gZ2V0VW5rbm93blRhZ0dlbmVyaWNCcm93c2VyIDogZ2V0VW5rbm93blRhZywKICAgIHByb3RvdHlw
+ZUZvclRhZzogcHJvdG90eXBlRm9yVGFnLAogICAgZGlzY3JpbWluYXRvcjogZGlzY3JpbWluYXRvciB9
+Owp9CkMud2I9ZnVuY3Rpb24oZ2V0VGFnRmFsbGJhY2spIHsKICByZXR1cm4gZnVuY3Rpb24oaG9va3Mp
+IHsKICAgIGlmICh0eXBlb2YgbmF2aWdhdG9yICE9ICJvYmplY3QiKSByZXR1cm4gaG9va3M7CiAgICB2
+YXIgdWEgPSBuYXZpZ2F0b3IudXNlckFnZW50OwogICAgaWYgKHVhLmluZGV4T2YoIkR1bXBSZW5kZXJU
+cmVlIikgPj0gMCkgcmV0dXJuIGhvb2tzOwogICAgaWYgKHVhLmluZGV4T2YoIkNocm9tZSIpID49IDAp
+IHsKICAgICAgZnVuY3Rpb24gY29uZmlybShwKSB7CiAgICAgICAgcmV0dXJuIHR5cGVvZiB3aW5kb3cg
+PT0gIm9iamVjdCIgJiYgd2luZG93W3BdICYmIHdpbmRvd1twXS5uYW1lID09IHA7CiAgICAgIH0KICAg
+ICAgaWYgKGNvbmZpcm0oIldpbmRvdyIpICYmIGNvbmZpcm0oIkhUTUxFbGVtZW50IikpIHJldHVybiBo
+b29rczsKICAgIH0KICAgIGhvb2tzLmdldFRhZyA9IGdldFRhZ0ZhbGxiYWNrOwogIH07Cn0KQy5LVT1m
+dW5jdGlvbihob29rcykgewogIGlmICh0eXBlb2YgZGFydEV4cGVyaW1lbnRhbEZpeHVwR2V0VGFnICE9
+ICJmdW5jdGlvbiIpIHJldHVybiBob29rczsKICBob29rcy5nZXRUYWcgPSBkYXJ0RXhwZXJpbWVudGFs
+Rml4dXBHZXRUYWcoaG9va3MuZ2V0VGFnKTsKfQpDLmZRPWZ1bmN0aW9uKGhvb2tzKSB7CiAgdmFyIGdl
+dFRhZyA9IGhvb2tzLmdldFRhZzsKICB2YXIgcHJvdG90eXBlRm9yVGFnID0gaG9va3MucHJvdG90eXBl
+Rm9yVGFnOwogIGZ1bmN0aW9uIGdldFRhZ0ZpeGVkKG8pIHsKICAgIHZhciB0YWcgPSBnZXRUYWcobyk7
+CiAgICBpZiAodGFnID09ICJEb2N1bWVudCIpIHsKICAgICAgaWYgKCEhby54bWxWZXJzaW9uKSByZXR1
+cm4gIiFEb2N1bWVudCI7CiAgICAgIHJldHVybiAiIUhUTUxEb2N1bWVudCI7CiAgICB9CiAgICByZXR1
+cm4gdGFnOwogIH0KICBmdW5jdGlvbiBwcm90b3R5cGVGb3JUYWdGaXhlZCh0YWcpIHsKICAgIGlmICh0
+YWcgPT0gIkRvY3VtZW50IikgcmV0dXJuIG51bGw7CiAgICByZXR1cm4gcHJvdG90eXBlRm9yVGFnKHRh
+Zyk7CiAgfQogIGhvb2tzLmdldFRhZyA9IGdldFRhZ0ZpeGVkOwogIGhvb2tzLnByb3RvdHlwZUZvclRh
+ZyA9IHByb3RvdHlwZUZvclRhZ0ZpeGVkOwp9CkMuZGs9ZnVuY3Rpb24oaG9va3MpIHsKICB2YXIgdXNl
+ckFnZW50ID0gdHlwZW9mIG5hdmlnYXRvciA9PSAib2JqZWN0IiA/IG5hdmlnYXRvci51c2VyQWdlbnQg
+OiAiIjsKICBpZiAodXNlckFnZW50LmluZGV4T2YoIkZpcmVmb3giKSA9PSAtMSkgcmV0dXJuIGhvb2tz
+OwogIHZhciBnZXRUYWcgPSBob29rcy5nZXRUYWc7CiAgdmFyIHF1aWNrTWFwID0gewogICAgIkJlZm9y
+ZVVubG9hZEV2ZW50IjogIkV2ZW50IiwKICAgICJEYXRhVHJhbnNmZXIiOiAiQ2xpcGJvYXJkIiwKICAg
+ICJHZW9HZW9sb2NhdGlvbiI6ICJHZW9sb2NhdGlvbiIsCiAgICAiTG9jYXRpb24iOiAiIUxvY2F0aW9u
+IiwKICAgICJXb3JrZXJNZXNzYWdlRXZlbnQiOiAiTWVzc2FnZUV2ZW50IiwKICAgICJYTUxEb2N1bWVu
+dCI6ICIhRG9jdW1lbnQifTsKICBmdW5jdGlvbiBnZXRUYWdGaXJlZm94KG8pIHsKICAgIHZhciB0YWcg
+PSBnZXRUYWcobyk7CiAgICByZXR1cm4gcXVpY2tNYXBbdGFnXSB8fCB0YWc7CiAgfQogIGhvb2tzLmdl
+dFRhZyA9IGdldFRhZ0ZpcmVmb3g7Cn0KQy54aT1mdW5jdGlvbihob29rcykgewogIHZhciB1c2VyQWdl
+bnQgPSB0eXBlb2YgbmF2aWdhdG9yID09ICJvYmplY3QiID8gbmF2aWdhdG9yLnVzZXJBZ2VudCA6ICIi
+OwogIGlmICh1c2VyQWdlbnQuaW5kZXhPZigiVHJpZGVudC8iKSA9PSAtMSkgcmV0dXJuIGhvb2tzOwog
+IHZhciBnZXRUYWcgPSBob29rcy5nZXRUYWc7CiAgdmFyIHF1aWNrTWFwID0gewogICAgIkJlZm9yZVVu
+bG9hZEV2ZW50IjogIkV2ZW50IiwKICAgICJEYXRhVHJhbnNmZXIiOiAiQ2xpcGJvYXJkIiwKICAgICJI
+VE1MRERFbGVtZW50IjogIkhUTUxFbGVtZW50IiwKICAgICJIVE1MRFRFbGVtZW50IjogIkhUTUxFbGVt
+ZW50IiwKICAgICJIVE1MUGhyYXNlRWxlbWVudCI6ICJIVE1MRWxlbWVudCIsCiAgICAiUG9zaXRpb24i
+OiAiR2VvcG9zaXRpb24iCiAgfTsKICBmdW5jdGlvbiBnZXRUYWdJRShvKSB7CiAgICB2YXIgdGFnID0g
+Z2V0VGFnKG8pOwogICAgdmFyIG5ld1RhZyA9IHF1aWNrTWFwW3RhZ107CiAgICBpZiAobmV3VGFnKSBy
+ZXR1cm4gbmV3VGFnOwogICAgaWYgKHRhZyA9PSAiT2JqZWN0IikgewogICAgICBpZiAod2luZG93LkRh
+dGFWaWV3ICYmIChvIGluc3RhbmNlb2Ygd2luZG93LkRhdGFWaWV3KSkgcmV0dXJuICJEYXRhVmlldyI7
+CiAgICB9CiAgICByZXR1cm4gdGFnOwogIH0KICBmdW5jdGlvbiBwcm90b3R5cGVGb3JUYWdJRSh0YWcp
+IHsKICAgIHZhciBjb25zdHJ1Y3RvciA9IHdpbmRvd1t0YWddOwogICAgaWYgKGNvbnN0cnVjdG9yID09
+IG51bGwpIHJldHVybiBudWxsOwogICAgcmV0dXJuIGNvbnN0cnVjdG9yLnByb3RvdHlwZTsKICB9CiAg
+aG9va3MuZ2V0VGFnID0gZ2V0VGFnSUU7CiAgaG9va3MucHJvdG90eXBlRm9yVGFnID0gcHJvdG90eXBl
+Rm9yVGFnSUU7Cn0KQy5pNz1mdW5jdGlvbihob29rcykgeyByZXR1cm4gaG9va3M7IH0KCkMuQ3Q9bmV3
+IFAuYnkoKQpDLkVxPW5ldyBQLms1KCkKQy54TT1uZXcgUC51NSgpCkMuUWs9bmV3IFAuRTMoKQpDLk52
+PW5ldyBILmtyKCkKQy5OVT1uZXcgUC5KaSgpCkMucGQ9bmV3IFAuWmQoKQpDLkFkPW5ldyBNLkg3KDAs
+IkhpbnRBY3Rpb25LaW5kLmFkZE51bGxhYmxlSGludCIpCkMubmU9bmV3IE0uSDcoMSwiSGludEFjdGlv
+bktpbmQuYWRkTm9uTnVsbGFibGVIaW50IikKQy5teT1uZXcgTS5INygyLCJIaW50QWN0aW9uS2luZC5j
+aGFuZ2VUb051bGxhYmxlSGludCIpCkMucng9bmV3IE0uSDcoMywiSGludEFjdGlvbktpbmQuY2hhbmdl
+VG9Ob25OdWxsYWJsZUhpbnQiKQpDLndWPW5ldyBNLkg3KDQsIkhpbnRBY3Rpb25LaW5kLnJlbW92ZU51
+bGxhYmxlSGludCIpCkMuZlI9bmV3IE0uSDcoNSwiSGludEFjdGlvbktpbmQucmVtb3ZlTm9uTnVsbGFi
+bGVIaW50IikKQy5BMz1uZXcgUC5NeChudWxsKQpDLm5YPW5ldyBQLm9qKG51bGwpCkMuY3c9bmV3IEwu
+R2IoMCwiVW5pdE1pZ3JhdGlvblN0YXR1cy5hbHJlYWR5TWlncmF0ZWQiKQpDLmRjPW5ldyBMLkdiKDEs
+IlVuaXRNaWdyYXRpb25TdGF0dXMuaW5kZXRlcm1pbmF0ZSIpCkMuV0Q9bmV3IEwuR2IoMiwiVW5pdE1p
+Z3JhdGlvblN0YXR1cy5taWdyYXRpbmciKQpDLlhqPW5ldyBMLkdiKDMsIlVuaXRNaWdyYXRpb25TdGF0
+dXMub3B0aW5nT3V0IikKQy5sMD1ILlZNKHMoW0MuY3csQy5kYyxDLldELEMuWGpdKSxILk4wKCJqZDxH
+Yio+IikpCkMuYWs9SC5WTShzKFswLDAsMzI3NzYsMzM3OTIsMSwxMDI0MCwwLDBdKSx0LlYpCkMuY209
+SC5WTShzKFsiKjo6Y2xhc3MiLCIqOjpkaXIiLCIqOjpkcmFnZ2FibGUiLCIqOjpoaWRkZW4iLCIqOjpp
+ZCIsIio6OmluZXJ0IiwiKjo6aXRlbXByb3AiLCIqOjppdGVtcmVmIiwiKjo6aXRlbXNjb3BlIiwiKjo6
+bGFuZyIsIio6OnNwZWxsY2hlY2siLCIqOjp0aXRsZSIsIio6OnRyYW5zbGF0ZSIsIkE6OmFjY2Vzc2tl
+eSIsIkE6OmNvb3JkcyIsIkE6OmhyZWZsYW5nIiwiQTo6bmFtZSIsIkE6OnNoYXBlIiwiQTo6dGFiaW5k
+ZXgiLCJBOjp0YXJnZXQiLCJBOjp0eXBlIiwiQVJFQTo6YWNjZXNza2V5IiwiQVJFQTo6YWx0IiwiQVJF
+QTo6Y29vcmRzIiwiQVJFQTo6bm9ocmVmIiwiQVJFQTo6c2hhcGUiLCJBUkVBOjp0YWJpbmRleCIsIkFS
+RUE6OnRhcmdldCIsIkFVRElPOjpjb250cm9scyIsIkFVRElPOjpsb29wIiwiQVVESU86Om1lZGlhZ3Jv
+dXAiLCJBVURJTzo6bXV0ZWQiLCJBVURJTzo6cHJlbG9hZCIsIkJETzo6ZGlyIiwiQk9EWTo6YWxpbmsi
+LCJCT0RZOjpiZ2NvbG9yIiwiQk9EWTo6bGluayIsIkJPRFk6OnRleHQiLCJCT0RZOjp2bGluayIsIkJS
+OjpjbGVhciIsIkJVVFRPTjo6YWNjZXNza2V5IiwiQlVUVE9OOjpkaXNhYmxlZCIsIkJVVFRPTjo6bmFt
+ZSIsIkJVVFRPTjo6dGFiaW5kZXgiLCJCVVRUT046OnR5cGUiLCJCVVRUT046OnZhbHVlIiwiQ0FOVkFT
+OjpoZWlnaHQiLCJDQU5WQVM6OndpZHRoIiwiQ0FQVElPTjo6YWxpZ24iLCJDT0w6OmFsaWduIiwiQ09M
+OjpjaGFyIiwiQ09MOjpjaGFyb2ZmIiwiQ09MOjpzcGFuIiwiQ09MOjp2YWxpZ24iLCJDT0w6OndpZHRo
+IiwiQ09MR1JPVVA6OmFsaWduIiwiQ09MR1JPVVA6OmNoYXIiLCJDT0xHUk9VUDo6Y2hhcm9mZiIsIkNP
+TEdST1VQOjpzcGFuIiwiQ09MR1JPVVA6OnZhbGlnbiIsIkNPTEdST1VQOjp3aWR0aCIsIkNPTU1BTkQ6
+OmNoZWNrZWQiLCJDT01NQU5EOjpjb21tYW5kIiwiQ09NTUFORDo6ZGlzYWJsZWQiLCJDT01NQU5EOjps
+YWJlbCIsIkNPTU1BTkQ6OnJhZGlvZ3JvdXAiLCJDT01NQU5EOjp0eXBlIiwiREFUQTo6dmFsdWUiLCJE
+RUw6OmRhdGV0aW1lIiwiREVUQUlMUzo6b3BlbiIsIkRJUjo6Y29tcGFjdCIsIkRJVjo6YWxpZ24iLCJE
+TDo6Y29tcGFjdCIsIkZJRUxEU0VUOjpkaXNhYmxlZCIsIkZPTlQ6OmNvbG9yIiwiRk9OVDo6ZmFjZSIs
+IkZPTlQ6OnNpemUiLCJGT1JNOjphY2NlcHQiLCJGT1JNOjphdXRvY29tcGxldGUiLCJGT1JNOjplbmN0
+eXBlIiwiRk9STTo6bWV0aG9kIiwiRk9STTo6bmFtZSIsIkZPUk06Om5vdmFsaWRhdGUiLCJGT1JNOjp0
+YXJnZXQiLCJGUkFNRTo6bmFtZSIsIkgxOjphbGlnbiIsIkgyOjphbGlnbiIsIkgzOjphbGlnbiIsIkg0
+OjphbGlnbiIsIkg1OjphbGlnbiIsIkg2OjphbGlnbiIsIkhSOjphbGlnbiIsIkhSOjpub3NoYWRlIiwi
+SFI6OnNpemUiLCJIUjo6d2lkdGgiLCJIVE1MOjp2ZXJzaW9uIiwiSUZSQU1FOjphbGlnbiIsIklGUkFN
+RTo6ZnJhbWVib3JkZXIiLCJJRlJBTUU6OmhlaWdodCIsIklGUkFNRTo6bWFyZ2luaGVpZ2h0IiwiSUZS
+QU1FOjptYXJnaW53aWR0aCIsIklGUkFNRTo6d2lkdGgiLCJJTUc6OmFsaWduIiwiSU1HOjphbHQiLCJJ
+TUc6OmJvcmRlciIsIklNRzo6aGVpZ2h0IiwiSU1HOjpoc3BhY2UiLCJJTUc6OmlzbWFwIiwiSU1HOjpu
+YW1lIiwiSU1HOjp1c2VtYXAiLCJJTUc6OnZzcGFjZSIsIklNRzo6d2lkdGgiLCJJTlBVVDo6YWNjZXB0
+IiwiSU5QVVQ6OmFjY2Vzc2tleSIsIklOUFVUOjphbGlnbiIsIklOUFVUOjphbHQiLCJJTlBVVDo6YXV0
+b2NvbXBsZXRlIiwiSU5QVVQ6OmF1dG9mb2N1cyIsIklOUFVUOjpjaGVja2VkIiwiSU5QVVQ6OmRpc2Fi
+bGVkIiwiSU5QVVQ6OmlucHV0bW9kZSIsIklOUFVUOjppc21hcCIsIklOUFVUOjpsaXN0IiwiSU5QVVQ6
+Om1heCIsIklOUFVUOjptYXhsZW5ndGgiLCJJTlBVVDo6bWluIiwiSU5QVVQ6Om11bHRpcGxlIiwiSU5Q
+VVQ6Om5hbWUiLCJJTlBVVDo6cGxhY2Vob2xkZXIiLCJJTlBVVDo6cmVhZG9ubHkiLCJJTlBVVDo6cmVx
+dWlyZWQiLCJJTlBVVDo6c2l6ZSIsIklOUFVUOjpzdGVwIiwiSU5QVVQ6OnRhYmluZGV4IiwiSU5QVVQ6
+OnR5cGUiLCJJTlBVVDo6dXNlbWFwIiwiSU5QVVQ6OnZhbHVlIiwiSU5TOjpkYXRldGltZSIsIktFWUdF
+Tjo6ZGlzYWJsZWQiLCJLRVlHRU46OmtleXR5cGUiLCJLRVlHRU46Om5hbWUiLCJMQUJFTDo6YWNjZXNz
+a2V5IiwiTEFCRUw6OmZvciIsIkxFR0VORDo6YWNjZXNza2V5IiwiTEVHRU5EOjphbGlnbiIsIkxJOjp0
+eXBlIiwiTEk6OnZhbHVlIiwiTElOSzo6c2l6ZXMiLCJNQVA6Om5hbWUiLCJNRU5VOjpjb21wYWN0Iiwi
+TUVOVTo6bGFiZWwiLCJNRU5VOjp0eXBlIiwiTUVURVI6OmhpZ2giLCJNRVRFUjo6bG93IiwiTUVURVI6
+Om1heCIsIk1FVEVSOjptaW4iLCJNRVRFUjo6dmFsdWUiLCJPQkpFQ1Q6OnR5cGVtdXN0bWF0Y2giLCJP
+TDo6Y29tcGFjdCIsIk9MOjpyZXZlcnNlZCIsIk9MOjpzdGFydCIsIk9MOjp0eXBlIiwiT1BUR1JPVVA6
+OmRpc2FibGVkIiwiT1BUR1JPVVA6OmxhYmVsIiwiT1BUSU9OOjpkaXNhYmxlZCIsIk9QVElPTjo6bGFi
+ZWwiLCJPUFRJT046OnNlbGVjdGVkIiwiT1BUSU9OOjp2YWx1ZSIsIk9VVFBVVDo6Zm9yIiwiT1VUUFVU
+OjpuYW1lIiwiUDo6YWxpZ24iLCJQUkU6OndpZHRoIiwiUFJPR1JFU1M6Om1heCIsIlBST0dSRVNTOjpt
+aW4iLCJQUk9HUkVTUzo6dmFsdWUiLCJTRUxFQ1Q6OmF1dG9jb21wbGV0ZSIsIlNFTEVDVDo6ZGlzYWJs
+ZWQiLCJTRUxFQ1Q6Om11bHRpcGxlIiwiU0VMRUNUOjpuYW1lIiwiU0VMRUNUOjpyZXF1aXJlZCIsIlNF
+TEVDVDo6c2l6ZSIsIlNFTEVDVDo6dGFiaW5kZXgiLCJTT1VSQ0U6OnR5cGUiLCJUQUJMRTo6YWxpZ24i
+LCJUQUJMRTo6Ymdjb2xvciIsIlRBQkxFOjpib3JkZXIiLCJUQUJMRTo6Y2VsbHBhZGRpbmciLCJUQUJM
+RTo6Y2VsbHNwYWNpbmciLCJUQUJMRTo6ZnJhbWUiLCJUQUJMRTo6cnVsZXMiLCJUQUJMRTo6c3VtbWFy
+eSIsIlRBQkxFOjp3aWR0aCIsIlRCT0RZOjphbGlnbiIsIlRCT0RZOjpjaGFyIiwiVEJPRFk6OmNoYXJv
+ZmYiLCJUQk9EWTo6dmFsaWduIiwiVEQ6OmFiYnIiLCJURDo6YWxpZ24iLCJURDo6YXhpcyIsIlREOjpi
+Z2NvbG9yIiwiVEQ6OmNoYXIiLCJURDo6Y2hhcm9mZiIsIlREOjpjb2xzcGFuIiwiVEQ6OmhlYWRlcnMi
+LCJURDo6aGVpZ2h0IiwiVEQ6Om5vd3JhcCIsIlREOjpyb3dzcGFuIiwiVEQ6OnNjb3BlIiwiVEQ6OnZh
+bGlnbiIsIlREOjp3aWR0aCIsIlRFWFRBUkVBOjphY2Nlc3NrZXkiLCJURVhUQVJFQTo6YXV0b2NvbXBs
+ZXRlIiwiVEVYVEFSRUE6OmNvbHMiLCJURVhUQVJFQTo6ZGlzYWJsZWQiLCJURVhUQVJFQTo6aW5wdXRt
+b2RlIiwiVEVYVEFSRUE6Om5hbWUiLCJURVhUQVJFQTo6cGxhY2Vob2xkZXIiLCJURVhUQVJFQTo6cmVh
+ZG9ubHkiLCJURVhUQVJFQTo6cmVxdWlyZWQiLCJURVhUQVJFQTo6cm93cyIsIlRFWFRBUkVBOjp0YWJp
+bmRleCIsIlRFWFRBUkVBOjp3cmFwIiwiVEZPT1Q6OmFsaWduIiwiVEZPT1Q6OmNoYXIiLCJURk9PVDo6
+Y2hhcm9mZiIsIlRGT09UOjp2YWxpZ24iLCJUSDo6YWJiciIsIlRIOjphbGlnbiIsIlRIOjpheGlzIiwi
+VEg6OmJnY29sb3IiLCJUSDo6Y2hhciIsIlRIOjpjaGFyb2ZmIiwiVEg6OmNvbHNwYW4iLCJUSDo6aGVh
+ZGVycyIsIlRIOjpoZWlnaHQiLCJUSDo6bm93cmFwIiwiVEg6OnJvd3NwYW4iLCJUSDo6c2NvcGUiLCJU
+SDo6dmFsaWduIiwiVEg6OndpZHRoIiwiVEhFQUQ6OmFsaWduIiwiVEhFQUQ6OmNoYXIiLCJUSEVBRDo6
+Y2hhcm9mZiIsIlRIRUFEOjp2YWxpZ24iLCJUUjo6YWxpZ24iLCJUUjo6Ymdjb2xvciIsIlRSOjpjaGFy
+IiwiVFI6OmNoYXJvZmYiLCJUUjo6dmFsaWduIiwiVFJBQ0s6OmRlZmF1bHQiLCJUUkFDSzo6a2luZCIs
+IlRSQUNLOjpsYWJlbCIsIlRSQUNLOjpzcmNsYW5nIiwiVUw6OmNvbXBhY3QiLCJVTDo6dHlwZSIsIlZJ
+REVPOjpjb250cm9scyIsIlZJREVPOjpoZWlnaHQiLCJWSURFTzo6bG9vcCIsIlZJREVPOjptZWRpYWdy
+b3VwIiwiVklERU86Om11dGVkIiwiVklERU86OnByZWxvYWQiLCJWSURFTzo6d2lkdGgiXSksdC5pKQpD
+LlZDPUguVk0ocyhbMCwwLDY1NDkwLDQ1MDU1LDY1NTM1LDM0ODE1LDY1NTM0LDE4NDMxXSksdC5WKQpD
+Lm1LPUguVk0ocyhbMCwwLDI2NjI0LDEwMjMsNjU1MzQsMjA0Nyw2NTUzNCwyMDQ3XSksdC5WKQpDLlNx
+PUguVk0ocyhbIkhFQUQiLCJBUkVBIiwiQkFTRSIsIkJBU0VGT05UIiwiQlIiLCJDT0wiLCJDT0xHUk9V
+UCIsIkVNQkVEIiwiRlJBTUUiLCJGUkFNRVNFVCIsIkhSIiwiSU1BR0UiLCJJTUciLCJJTlBVVCIsIklT
+SU5ERVgiLCJMSU5LIiwiTUVUQSIsIlBBUkFNIiwiU09VUkNFIiwiU1RZTEUiLCJUSVRMRSIsIldCUiJd
+KSx0LmkpCkMuaFU9SC5WTShzKFtdKSx0LngpCkMuZG49SC5WTShzKFtdKSxILk4wKCJqZDxMTCo+Iikp
+CkMueEQ9SC5WTShzKFtdKSx0LmkpCkMudG89SC5WTShzKFswLDAsMzI3MjIsMTIyODcsNjU1MzQsMzQ4
+MTUsNjU1MzQsMTg0MzFdKSx0LlYpCkMucms9SC5WTShzKFtDLkFkLEMubmUsQy5teSxDLnJ4LEMud1Ys
+Qy5mUl0pLEguTjAoImpkPEg3Kj4iKSkKQy5GMz1ILlZNKHMoWzAsMCwyNDU3NiwxMDIzLDY1NTM0LDM0
+ODE1LDY1NTM0LDE4NDMxXSksdC5WKQpDLmVhPUguVk0ocyhbMCwwLDMyNzU0LDExMjYzLDY1NTM0LDM0
+ODE1LDY1NTM0LDE4NDMxXSksdC5WKQpDLlpKPUguVk0ocyhbMCwwLDMyNzIyLDEyMjg3LDY1NTM1LDM0
+ODE1LDY1NTM0LDE4NDMxXSksdC5WKQpDLldkPUguVk0ocyhbMCwwLDY1NDkwLDEyMjg3LDY1NTM1LDM0
+ODE1LDY1NTM0LDE4NDMxXSksdC5WKQpDLlF4PUguVk0ocyhbImJpbmQiLCJpZiIsInJlZiIsInJlcGVh
+dCIsInN5bnRheCJdKSx0LmkpCkMuQkk9SC5WTShzKFsiQTo6aHJlZiIsIkFSRUE6OmhyZWYiLCJCTE9D
+S1FVT1RFOjpjaXRlIiwiQk9EWTo6YmFja2dyb3VuZCIsIkNPTU1BTkQ6Omljb24iLCJERUw6OmNpdGUi
+LCJGT1JNOjphY3Rpb24iLCJJTUc6OnNyYyIsIklOUFVUOjpzcmMiLCJJTlM6OmNpdGUiLCJROjpjaXRl
+IiwiVklERU86OnBvc3RlciJdKSx0LmkpCkMuRHg9bmV3IEguTFAoMCx7fSxDLnhELEguTjAoIkxQPHFV
+Kix6TTxqOCo+Kj4iKSkKQy5DTT1uZXcgSC5MUCgwLHt9LEMueEQsSC5OMCgiTFA8cVUqLHFVKj4iKSkK
+Qy5pSD1ILlZNKHMoW10pLEguTjAoImpkPEdEKj4iKSkKQy5XTz1uZXcgSC5MUCgwLHt9LEMuaUgsSC5O
+MCgiTFA8R0QqLEA+IikpCkMuWTI9bmV3IEwuTzkoIk5hdmlnYXRpb25UcmVlTm9kZVR5cGUuZGlyZWN0
+b3J5IikKQy5yZj1uZXcgTC5POSgiTmF2aWdhdGlvblRyZWVOb2RlVHlwZS5maWxlIikKQy5UZT1uZXcg
+SC53digiY2FsbCIpCkMub0U9bmV3IFAuR1koITEpCkMud1E9bmV3IFAuRnkobnVsbCwyKX0pKCk7KGZ1
+bmN0aW9uIHN0YXRpY0ZpZWxkcygpeyQuem09bnVsbAokLnlqPTAKJC5tSj1udWxsCiQuUDQ9bnVsbAok
+Lk5GPW51bGwKJC5UWD1udWxsCiQueDc9bnVsbAokLm53PW51bGwKJC52dj1udWxsCiQuQnY9bnVsbAok
+LlM2PW51bGwKJC5rOD1udWxsCiQubWc9bnVsbAokLlVEPSExCiQuWDM9Qy5OVQokLnhnPUguVk0oW10s
+SC5OMCgiamQ8TWg+IikpCiQueG89bnVsbAokLkJPPW51bGwKJC5sdD1udWxsCiQuRVU9bnVsbAokLm9y
+PVAuRmwodC5OLHQuWSkKJC5JUj1udWxsCiQuSTY9bnVsbAokLkZmPW51bGx9KSgpOyhmdW5jdGlvbiBs
+YXp5SW5pdGlhbGl6ZXJzKCl7dmFyIHM9aHVua0hlbHBlcnMubGF6eUZpbmFsLHI9aHVua0hlbHBlcnMu
+bGF6eU9sZApzKCQsImZhIiwidyIsZnVuY3Rpb24oKXtyZXR1cm4gSC5ZZygiXyRkYXJ0X2RhcnRDbG9z
+dXJlIil9KQpzKCQsIlUyIiwiU24iLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oSC5TNyh7CnRvU3RyaW5n
+OmZ1bmN0aW9uKCl7cmV0dXJuIiRyZWNlaXZlciQifX0pKX0pCnMoJCwieHEiLCJscSIsZnVuY3Rpb24o
+KXtyZXR1cm4gSC5jTShILlM3KHskbWV0aG9kJDpudWxsLAp0b1N0cmluZzpmdW5jdGlvbigpe3JldHVy
+biIkcmVjZWl2ZXIkIn19KSl9KQpzKCQsIlIxIiwiTjkiLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oSC5T
+NyhudWxsKSl9KQpzKCQsImZOIiwiaUkiLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oZnVuY3Rpb24oKXt2
+YXIgJGFyZ3VtZW50c0V4cHIkPSckYXJndW1lbnRzJCcKdHJ5e251bGwuJG1ldGhvZCQoJGFyZ3VtZW50
+c0V4cHIkKX1jYXRjaChxKXtyZXR1cm4gcS5tZXNzYWdlfX0oKSl9KQpzKCQsInFpIiwiVU4iLGZ1bmN0
+aW9uKCl7cmV0dXJuIEguY00oSC5TNyh2b2lkIDApKX0pCnMoJCwicloiLCJaaCIsZnVuY3Rpb24oKXty
+ZXR1cm4gSC5jTShmdW5jdGlvbigpe3ZhciAkYXJndW1lbnRzRXhwciQ9JyRhcmd1bWVudHMkJwp0cnl7
+KHZvaWQgMCkuJG1ldGhvZCQoJGFyZ3VtZW50c0V4cHIkKX1jYXRjaChxKXtyZXR1cm4gcS5tZXNzYWdl
+fX0oKSl9KQpzKCQsImtxIiwick4iLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oSC5NaihudWxsKSl9KQpz
+KCQsInR0IiwiYzMiLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oZnVuY3Rpb24oKXt0cnl7bnVsbC4kbWV0
+aG9kJH1jYXRjaChxKXtyZXR1cm4gcS5tZXNzYWdlfX0oKSl9KQpzKCQsImR0IiwiSEsiLGZ1bmN0aW9u
+KCl7cmV0dXJuIEguY00oSC5Naih2b2lkIDApKX0pCnMoJCwiQTciLCJyMSIsZnVuY3Rpb24oKXtyZXR1
+cm4gSC5jTShmdW5jdGlvbigpe3RyeXsodm9pZCAwKS4kbWV0aG9kJH1jYXRjaChxKXtyZXR1cm4gcS5t
+ZXNzYWdlfX0oKSl9KQpzKCQsIldjIiwidXQiLGZ1bmN0aW9uKCl7cmV0dXJuIFAuT2ooKX0pCnMoJCwi
+a2giLCJyZiIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IFAucGcoKS4kMCgpfSkKcygkLCJkSCIsIkhHIixm
+dW5jdGlvbigpe3JldHVybiBuZXcgUC5jMigpLiQwKCl9KQpzKCQsImJ0IiwiVjciLGZ1bmN0aW9uKCl7
+cmV0dXJuIG5ldyBJbnQ4QXJyYXkoSC5YRihILlZNKFstMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwt
+MiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwt
+MiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMSwtMiwtMiwtMiwtMiwtMiw2MiwtMiw2MiwtMiw2Myw1Miw1
+Myw1NCw1NSw1Niw1Nyw1OCw1OSw2MCw2MSwtMiwtMiwtMiwtMSwtMiwtMiwtMiwwLDEsMiwzLDQsNSw2
+LDcsOCw5LDEwLDExLDEyLDEzLDE0LDE1LDE2LDE3LDE4LDE5LDIwLDIxLDIyLDIzLDI0LDI1LC0yLC0y
+LC0yLC0yLDYzLC0yLDI2LDI3LDI4LDI5LDMwLDMxLDMyLDMzLDM0LDM1LDM2LDM3LDM4LDM5LDQwLDQx
+LDQyLDQzLDQ0LDQ1LDQ2LDQ3LDQ4LDQ5LDUwLDUxLC0yLC0yLC0yLC0yLC0yXSx0LmEpKSl9KQpzKCQs
+Ik01Iiwid1EiLGZ1bmN0aW9uKCl7cmV0dXJuIHR5cGVvZiBwcm9jZXNzIT0idW5kZWZpbmVkIiYmT2Jq
+ZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHByb2Nlc3MpPT0iW29iamVjdCBwcm9jZXNzXSImJnBy
+b2Nlc3MucGxhdGZvcm09PSJ3aW4zMiJ9KQpzKCQsIm1mIiwiejQiLGZ1bmN0aW9uKCl7cmV0dXJuIFAu
+bnUoIl5bXFwtXFwuMC05QS1aX2Eten5dKiQiKX0pCnMoJCwiT1EiLCJ2WiIsZnVuY3Rpb24oKXtyZXR1
+cm4gUC5LTigpfSkKcygkLCJTQyIsIkFOIixmdW5jdGlvbigpe3JldHVybiBQLnRNKFsiQSIsIkFCQlIi
+LCJBQ1JPTllNIiwiQUREUkVTUyIsIkFSRUEiLCJBUlRJQ0xFIiwiQVNJREUiLCJBVURJTyIsIkIiLCJC
+REkiLCJCRE8iLCJCSUciLCJCTE9DS1FVT1RFIiwiQlIiLCJCVVRUT04iLCJDQU5WQVMiLCJDQVBUSU9O
+IiwiQ0VOVEVSIiwiQ0lURSIsIkNPREUiLCJDT0wiLCJDT0xHUk9VUCIsIkNPTU1BTkQiLCJEQVRBIiwi
+REFUQUxJU1QiLCJERCIsIkRFTCIsIkRFVEFJTFMiLCJERk4iLCJESVIiLCJESVYiLCJETCIsIkRUIiwi
+RU0iLCJGSUVMRFNFVCIsIkZJR0NBUFRJT04iLCJGSUdVUkUiLCJGT05UIiwiRk9PVEVSIiwiRk9STSIs
+IkgxIiwiSDIiLCJIMyIsIkg0IiwiSDUiLCJINiIsIkhFQURFUiIsIkhHUk9VUCIsIkhSIiwiSSIsIklG
+UkFNRSIsIklNRyIsIklOUFVUIiwiSU5TIiwiS0JEIiwiTEFCRUwiLCJMRUdFTkQiLCJMSSIsIk1BUCIs
+Ik1BUksiLCJNRU5VIiwiTUVURVIiLCJOQVYiLCJOT0JSIiwiT0wiLCJPUFRHUk9VUCIsIk9QVElPTiIs
+Ik9VVFBVVCIsIlAiLCJQUkUiLCJQUk9HUkVTUyIsIlEiLCJTIiwiU0FNUCIsIlNFQ1RJT04iLCJTRUxF
+Q1QiLCJTTUFMTCIsIlNPVVJDRSIsIlNQQU4iLCJTVFJJS0UiLCJTVFJPTkciLCJTVUIiLCJTVU1NQVJZ
+IiwiU1VQIiwiVEFCTEUiLCJUQk9EWSIsIlREIiwiVEVYVEFSRUEiLCJURk9PVCIsIlRIIiwiVEhFQUQi
+LCJUSU1FIiwiVFIiLCJUUkFDSyIsIlRUIiwiVSIsIlVMIiwiVkFSIiwiVklERU8iLCJXQlIiXSx0Lk4p
+fSkKcygkLCJYNCIsImhHIixmdW5jdGlvbigpe3JldHVybiBQLm51KCJeXFxTKyQiKX0pCnMoJCwid08i
+LCJvdyIsZnVuY3Rpb24oKXtyZXR1cm4gUC5ORChzZWxmKX0pCnMoJCwia3QiLCJSOCIsZnVuY3Rpb24o
+KXtyZXR1cm4gSC5ZZygiXyRkYXJ0X2RhcnRPYmplY3QiKX0pCnMoJCwiZksiLCJrSSIsZnVuY3Rpb24o
+KXtyZXR1cm4gZnVuY3Rpb24gRGFydE9iamVjdChhKXt0aGlzLm89YX19KQpyKCQsInF0IiwiekIiLGZ1
+bmN0aW9uKCl7cmV0dXJuIG5ldyBULm1RKCl9KQpyKCQsIk9sIiwiVUUiLGZ1bmN0aW9uKCl7cmV0dXJu
+IFAuaEsoQy5vbC5nbVcoVy54MygpKS5ocmVmKS5naFkoKS5xKDAsImF1dGhUb2tlbiIpfSkKcigkLCJo
+VCIsInlQIixmdW5jdGlvbigpe3JldHVybiBXLlpyKCkucXVlcnlTZWxlY3RvcigiLmVkaXQtbGlzdCAu
+cGFuZWwtY29udGVudCIpfSkKcigkLCJXNiIsImhMIixmdW5jdGlvbigpe3JldHVybiBXLlpyKCkucXVl
+cnlTZWxlY3RvcigiLmVkaXQtcGFuZWwgLnBhbmVsLWNvbnRlbnQiKX0pCnIoJCwiVFIiLCJEVyIsZnVu
+Y3Rpb24oKXtyZXR1cm4gVy5acigpLnF1ZXJ5U2VsZWN0b3IoImZvb3RlciIpfSkKcigkLCJFWSIsImZp
+IixmdW5jdGlvbigpe3JldHVybiBXLlpyKCkucXVlcnlTZWxlY3RvcigiaGVhZGVyIil9KQpyKCQsImF2
+IiwiRDkiLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCIjdW5pdC1uYW1lIil9
+KQpyKCQsInQwIiwiYk4iLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCIjbWln
+cmF0ZS11bml0LXN0YXR1cy1pY29uLWxhYmVsIil9KQpyKCQsImJBIiwiYzAiLGZ1bmN0aW9uKCl7cmV0
+dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCIjbWlncmF0ZS11bml0LXN0YXR1cy1pY29uIil9KQpyKCQs
+ImZlIiwiS0ciLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBMLlhBKCl9KQpzKCQsImVvIiwiblUiLGZ1bmN0
+aW9uKCl7cmV0dXJuIG5ldyBNLmxJKCQuSGsoKSl9KQpzKCQsInlyIiwiYkQiLGZ1bmN0aW9uKCl7cmV0
+dXJuIG5ldyBFLk9GKFAubnUoIi8iKSxQLm51KCJbXi9dJCIpLFAubnUoIl4vIikpfSkKcygkLCJNayIs
+IktrIixmdW5jdGlvbigpe3JldHVybiBuZXcgTC5JVihQLm51KCJbL1xcXFxdIiksUC5udSgiW14vXFxc
+XF0kIiksUC5udSgiXihcXFxcXFxcXFteXFxcXF0rXFxcXFteXFxcXC9dK3xbYS16QS1aXTpbL1xcXFxd
+KSIpLFAubnUoIl5bL1xcXFxdKD8hWy9cXFxcXSkiKSl9KQpzKCQsImFrIiwiRWIiLGZ1bmN0aW9uKCl7
+cmV0dXJuIG5ldyBGLnJ1KFAubnUoIi8iKSxQLm51KCIoXlthLXpBLVpdWy0rLmEtekEtWlxcZF0qOi8v
+fFteL10pJCIpLFAubnUoIlthLXpBLVpdWy0rLmEtekEtWlxcZF0qOi8vW14vXSoiKSxQLm51KCJeLyIp
+KX0pCnMoJCwibHMiLCJIayIsZnVuY3Rpb24oKXtyZXR1cm4gTy5SaCgpfSl9KSgpOyhmdW5jdGlvbiBu
+YXRpdmVTdXBwb3J0KCl7IWZ1bmN0aW9uKCl7dmFyIHM9ZnVuY3Rpb24oYSl7dmFyIG09e30KbVthXT0x
+CnJldHVybiBPYmplY3Qua2V5cyhodW5rSGVscGVycy5jb252ZXJ0VG9GYXN0T2JqZWN0KG0pKVswXX0K
+di5nZXRJc29sYXRlVGFnPWZ1bmN0aW9uKGEpe3JldHVybiBzKCJfX19kYXJ0XyIrYSt2Lmlzb2xhdGVU
+YWcpfQp2YXIgcj0iX19fZGFydF9pc29sYXRlX3RhZ3NfIgp2YXIgcT1PYmplY3Rbcl18fChPYmplY3Rb
+cl09T2JqZWN0LmNyZWF0ZShudWxsKSkKdmFyIHA9Il9aeFl4WCIKZm9yKHZhciBvPTA7O28rKyl7dmFy
+IG49cyhwKyJfIitvKyJfIikKaWYoIShuIGluIHEpKXtxW25dPTEKdi5pc29sYXRlVGFnPW4KYnJlYWt9
+fXYuZGlzcGF0Y2hQcm9wZXJ0eU5hbWU9di5nZXRJc29sYXRlVGFnKCJkaXNwYXRjaF9yZWNvcmQiKX0o
+KQpodW5rSGVscGVycy5zZXRPclVwZGF0ZUludGVyY2VwdG9yc0J5VGFnKHtET01FcnJvcjpKLkd2LE1l
+ZGlhRXJyb3I6Si5HdixOYXZpZ2F0b3I6Si5HdixOYXZpZ2F0b3JDb25jdXJyZW50SGFyZHdhcmU6Si5H
+dixOYXZpZ2F0b3JVc2VyTWVkaWFFcnJvcjpKLkd2LE92ZXJjb25zdHJhaW5lZEVycm9yOkouR3YsUG9z
+aXRpb25FcnJvcjpKLkd2LFJhbmdlOkouR3YsU1FMRXJyb3I6Si5HdixEYXRhVmlldzpILkVULEFycmF5
+QnVmZmVyVmlldzpILkVULEZsb2F0MzJBcnJheTpILkRnLEZsb2F0NjRBcnJheTpILkRnLEludDE2QXJy
+YXk6SC54aixJbnQzMkFycmF5OkguZEUsSW50OEFycmF5OkguWkEsVWludDE2QXJyYXk6SC5kVCxVaW50
+MzJBcnJheTpILlBxLFVpbnQ4Q2xhbXBlZEFycmF5OkguZUUsQ2FudmFzUGl4ZWxBcnJheTpILmVFLFVp
+bnQ4QXJyYXk6SC5WNixIVE1MQXVkaW9FbGVtZW50OlcucUUsSFRNTEJSRWxlbWVudDpXLnFFLEhUTUxC
+dXR0b25FbGVtZW50OlcucUUsSFRNTENhbnZhc0VsZW1lbnQ6Vy5xRSxIVE1MQ29udGVudEVsZW1lbnQ6
+Vy5xRSxIVE1MRExpc3RFbGVtZW50OlcucUUsSFRNTERhdGFFbGVtZW50OlcucUUsSFRNTERhdGFMaXN0
+RWxlbWVudDpXLnFFLEhUTUxEZXRhaWxzRWxlbWVudDpXLnFFLEhUTUxEaWFsb2dFbGVtZW50OlcucUUs
+SFRNTERpdkVsZW1lbnQ6Vy5xRSxIVE1MRW1iZWRFbGVtZW50OlcucUUsSFRNTEZpZWxkU2V0RWxlbWVu
+dDpXLnFFLEhUTUxIUkVsZW1lbnQ6Vy5xRSxIVE1MSGVhZEVsZW1lbnQ6Vy5xRSxIVE1MSGVhZGluZ0Vs
+ZW1lbnQ6Vy5xRSxIVE1MSHRtbEVsZW1lbnQ6Vy5xRSxIVE1MSUZyYW1lRWxlbWVudDpXLnFFLEhUTUxJ
+bWFnZUVsZW1lbnQ6Vy5xRSxIVE1MSW5wdXRFbGVtZW50OlcucUUsSFRNTExJRWxlbWVudDpXLnFFLEhU
+TUxMYWJlbEVsZW1lbnQ6Vy5xRSxIVE1MTGVnZW5kRWxlbWVudDpXLnFFLEhUTUxMaW5rRWxlbWVudDpX
+LnFFLEhUTUxNYXBFbGVtZW50OlcucUUsSFRNTE1lZGlhRWxlbWVudDpXLnFFLEhUTUxNZW51RWxlbWVu
+dDpXLnFFLEhUTUxNZXRhRWxlbWVudDpXLnFFLEhUTUxNZXRlckVsZW1lbnQ6Vy5xRSxIVE1MTW9kRWxl
+bWVudDpXLnFFLEhUTUxPTGlzdEVsZW1lbnQ6Vy5xRSxIVE1MT2JqZWN0RWxlbWVudDpXLnFFLEhUTUxP
+cHRHcm91cEVsZW1lbnQ6Vy5xRSxIVE1MT3B0aW9uRWxlbWVudDpXLnFFLEhUTUxPdXRwdXRFbGVtZW50
+OlcucUUsSFRNTFBhcmFtRWxlbWVudDpXLnFFLEhUTUxQaWN0dXJlRWxlbWVudDpXLnFFLEhUTUxQcmVF
+bGVtZW50OlcucUUsSFRNTFByb2dyZXNzRWxlbWVudDpXLnFFLEhUTUxRdW90ZUVsZW1lbnQ6Vy5xRSxI
+VE1MU2NyaXB0RWxlbWVudDpXLnFFLEhUTUxTaGFkb3dFbGVtZW50OlcucUUsSFRNTFNsb3RFbGVtZW50
+OlcucUUsSFRNTFNvdXJjZUVsZW1lbnQ6Vy5xRSxIVE1MU3BhbkVsZW1lbnQ6Vy5xRSxIVE1MU3R5bGVF
+bGVtZW50OlcucUUsSFRNTFRhYmxlQ2FwdGlvbkVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVDZWxsRWxlbWVu
+dDpXLnFFLEhUTUxUYWJsZURhdGFDZWxsRWxlbWVudDpXLnFFLEhUTUxUYWJsZUhlYWRlckNlbGxFbGVt
+ZW50OlcucUUsSFRNTFRhYmxlQ29sRWxlbWVudDpXLnFFLEhUTUxUZXh0QXJlYUVsZW1lbnQ6Vy5xRSxI
+VE1MVGltZUVsZW1lbnQ6Vy5xRSxIVE1MVGl0bGVFbGVtZW50OlcucUUsSFRNTFRyYWNrRWxlbWVudDpX
+LnFFLEhUTUxVTGlzdEVsZW1lbnQ6Vy5xRSxIVE1MVW5rbm93bkVsZW1lbnQ6Vy5xRSxIVE1MVmlkZW9F
+bGVtZW50OlcucUUsSFRNTERpcmVjdG9yeUVsZW1lbnQ6Vy5xRSxIVE1MRm9udEVsZW1lbnQ6Vy5xRSxI
+VE1MRnJhbWVFbGVtZW50OlcucUUsSFRNTEZyYW1lU2V0RWxlbWVudDpXLnFFLEhUTUxNYXJxdWVlRWxl
+bWVudDpXLnFFLEhUTUxFbGVtZW50OlcucUUsSFRNTEFuY2hvckVsZW1lbnQ6Vy5HaCxIVE1MQXJlYUVs
+ZW1lbnQ6Vy5mWSxIVE1MQmFzZUVsZW1lbnQ6Vy5uQixCbG9iOlcuQXosSFRNTEJvZHlFbGVtZW50Olcu
+UVAsQ0RBVEFTZWN0aW9uOlcubngsQ2hhcmFjdGVyRGF0YTpXLm54LENvbW1lbnQ6Vy5ueCxQcm9jZXNz
+aW5nSW5zdHJ1Y3Rpb246Vy5ueCxUZXh0OlcubngsQ1NTU3R5bGVEZWNsYXJhdGlvbjpXLm9KLE1TU3R5
+bGVDU1NQcm9wZXJ0aWVzOlcub0osQ1NTMlByb3BlcnRpZXM6Vy5vSixYTUxEb2N1bWVudDpXLlFGLERv
+Y3VtZW50OlcuUUYsRE9NRXhjZXB0aW9uOlcuTmgsRE9NSW1wbGVtZW50YXRpb246Vy5hZSxET01SZWN0
+UmVhZE9ubHk6Vy5JQixET01Ub2tlbkxpc3Q6Vy5uNyxFbGVtZW50OlcuY3YsQWJvcnRQYXltZW50RXZl
+bnQ6Vy5lYSxBbmltYXRpb25FdmVudDpXLmVhLEFuaW1hdGlvblBsYXliYWNrRXZlbnQ6Vy5lYSxBcHBs
+aWNhdGlvbkNhY2hlRXJyb3JFdmVudDpXLmVhLEJhY2tncm91bmRGZXRjaENsaWNrRXZlbnQ6Vy5lYSxC
+YWNrZ3JvdW5kRmV0Y2hFdmVudDpXLmVhLEJhY2tncm91bmRGZXRjaEZhaWxFdmVudDpXLmVhLEJhY2tn
+cm91bmRGZXRjaGVkRXZlbnQ6Vy5lYSxCZWZvcmVJbnN0YWxsUHJvbXB0RXZlbnQ6Vy5lYSxCZWZvcmVV
+bmxvYWRFdmVudDpXLmVhLEJsb2JFdmVudDpXLmVhLENhbk1ha2VQYXltZW50RXZlbnQ6Vy5lYSxDbGlw
+Ym9hcmRFdmVudDpXLmVhLENsb3NlRXZlbnQ6Vy5lYSxDdXN0b21FdmVudDpXLmVhLERldmljZU1vdGlv
+bkV2ZW50OlcuZWEsRGV2aWNlT3JpZW50YXRpb25FdmVudDpXLmVhLEVycm9yRXZlbnQ6Vy5lYSxFeHRl
+bmRhYmxlRXZlbnQ6Vy5lYSxFeHRlbmRhYmxlTWVzc2FnZUV2ZW50OlcuZWEsRmV0Y2hFdmVudDpXLmVh
+LEZvbnRGYWNlU2V0TG9hZEV2ZW50OlcuZWEsRm9yZWlnbkZldGNoRXZlbnQ6Vy5lYSxHYW1lcGFkRXZl
+bnQ6Vy5lYSxIYXNoQ2hhbmdlRXZlbnQ6Vy5lYSxJbnN0YWxsRXZlbnQ6Vy5lYSxNZWRpYUVuY3J5cHRl
+ZEV2ZW50OlcuZWEsTWVkaWFLZXlNZXNzYWdlRXZlbnQ6Vy5lYSxNZWRpYVF1ZXJ5TGlzdEV2ZW50Olcu
+ZWEsTWVkaWFTdHJlYW1FdmVudDpXLmVhLE1lZGlhU3RyZWFtVHJhY2tFdmVudDpXLmVhLE1lc3NhZ2VF
+dmVudDpXLmVhLE1JRElDb25uZWN0aW9uRXZlbnQ6Vy5lYSxNSURJTWVzc2FnZUV2ZW50OlcuZWEsTXV0
+YXRpb25FdmVudDpXLmVhLE5vdGlmaWNhdGlvbkV2ZW50OlcuZWEsUGFnZVRyYW5zaXRpb25FdmVudDpX
+LmVhLFBheW1lbnRSZXF1ZXN0RXZlbnQ6Vy5lYSxQYXltZW50UmVxdWVzdFVwZGF0ZUV2ZW50OlcuZWEs
+UG9wU3RhdGVFdmVudDpXLmVhLFByZXNlbnRhdGlvbkNvbm5lY3Rpb25BdmFpbGFibGVFdmVudDpXLmVh
+LFByZXNlbnRhdGlvbkNvbm5lY3Rpb25DbG9zZUV2ZW50OlcuZWEsUHJvbWlzZVJlamVjdGlvbkV2ZW50
+OlcuZWEsUHVzaEV2ZW50OlcuZWEsUlRDRGF0YUNoYW5uZWxFdmVudDpXLmVhLFJUQ0RUTUZUb25lQ2hh
+bmdlRXZlbnQ6Vy5lYSxSVENQZWVyQ29ubmVjdGlvbkljZUV2ZW50OlcuZWEsUlRDVHJhY2tFdmVudDpX
+LmVhLFNlY3VyaXR5UG9saWN5VmlvbGF0aW9uRXZlbnQ6Vy5lYSxTZW5zb3JFcnJvckV2ZW50OlcuZWEs
+U3BlZWNoUmVjb2duaXRpb25FcnJvcjpXLmVhLFNwZWVjaFJlY29nbml0aW9uRXZlbnQ6Vy5lYSxTcGVl
+Y2hTeW50aGVzaXNFdmVudDpXLmVhLFN0b3JhZ2VFdmVudDpXLmVhLFN5bmNFdmVudDpXLmVhLFRyYWNr
+RXZlbnQ6Vy5lYSxUcmFuc2l0aW9uRXZlbnQ6Vy5lYSxXZWJLaXRUcmFuc2l0aW9uRXZlbnQ6Vy5lYSxW
+UkRldmljZUV2ZW50OlcuZWEsVlJEaXNwbGF5RXZlbnQ6Vy5lYSxWUlNlc3Npb25FdmVudDpXLmVhLE1v
+am9JbnRlcmZhY2VSZXF1ZXN0RXZlbnQ6Vy5lYSxVU0JDb25uZWN0aW9uRXZlbnQ6Vy5lYSxJREJWZXJz
+aW9uQ2hhbmdlRXZlbnQ6Vy5lYSxBdWRpb1Byb2Nlc3NpbmdFdmVudDpXLmVhLE9mZmxpbmVBdWRpb0Nv
+bXBsZXRpb25FdmVudDpXLmVhLFdlYkdMQ29udGV4dEV2ZW50OlcuZWEsRXZlbnQ6Vy5lYSxJbnB1dEV2
+ZW50OlcuZWEsU3VibWl0RXZlbnQ6Vy5lYSxFdmVudFRhcmdldDpXLkQwLEZpbGU6Vy5oSCxIVE1MRm9y
+bUVsZW1lbnQ6Vy5oNCxIaXN0b3J5OlcuYnIsSFRNTERvY3VtZW50OlcuVmIsWE1MSHR0cFJlcXVlc3Q6
+Vy5mSixYTUxIdHRwUmVxdWVzdEV2ZW50VGFyZ2V0Olcud2EsSW1hZ2VEYXRhOlcuU2csTG9jYXRpb246
+Vy53NyxNb3VzZUV2ZW50OlcuQWosRHJhZ0V2ZW50OlcuQWosUG9pbnRlckV2ZW50OlcuQWosV2hlZWxF
+dmVudDpXLkFqLERvY3VtZW50RnJhZ21lbnQ6Vy51SCxTaGFkb3dSb290OlcudUgsRG9jdW1lbnRUeXBl
+OlcudUgsTm9kZTpXLnVILE5vZGVMaXN0OlcuQkgsUmFkaW9Ob2RlTGlzdDpXLkJILEhUTUxQYXJhZ3Jh
+cGhFbGVtZW50OlcuU04sUHJvZ3Jlc3NFdmVudDpXLmV3LFJlc291cmNlUHJvZ3Jlc3NFdmVudDpXLmV3
+LEhUTUxTZWxlY3RFbGVtZW50OlcubHAsSFRNTFRhYmxlRWxlbWVudDpXLlRiLEhUTUxUYWJsZVJvd0Vs
+ZW1lbnQ6Vy5JdixIVE1MVGFibGVTZWN0aW9uRWxlbWVudDpXLldQLEhUTUxUZW1wbGF0ZUVsZW1lbnQ6
+Vy55WSxDb21wb3NpdGlvbkV2ZW50OlcudzYsRm9jdXNFdmVudDpXLnc2LEtleWJvYXJkRXZlbnQ6Vy53
+NixUZXh0RXZlbnQ6Vy53NixUb3VjaEV2ZW50OlcudzYsVUlFdmVudDpXLnc2LFdpbmRvdzpXLks1LERP
+TVdpbmRvdzpXLks1LERlZGljYXRlZFdvcmtlckdsb2JhbFNjb3BlOlcuQ20sU2VydmljZVdvcmtlckds
+b2JhbFNjb3BlOlcuQ20sU2hhcmVkV29ya2VyR2xvYmFsU2NvcGU6Vy5DbSxXb3JrZXJHbG9iYWxTY29w
+ZTpXLkNtLEF0dHI6Vy5DUSxDbGllbnRSZWN0OlcudzQsRE9NUmVjdDpXLnc0LE5hbWVkTm9kZU1hcDpX
+LnJoLE1vek5hbWVkQXR0ck1hcDpXLnJoLElEQktleVJhbmdlOlAuaEYsU1ZHU2NyaXB0RWxlbWVudDpQ
+Lm5kLFNWR0FFbGVtZW50OlAuaGksU1ZHQW5pbWF0ZUVsZW1lbnQ6UC5oaSxTVkdBbmltYXRlTW90aW9u
+RWxlbWVudDpQLmhpLFNWR0FuaW1hdGVUcmFuc2Zvcm1FbGVtZW50OlAuaGksU1ZHQW5pbWF0aW9uRWxl
+bWVudDpQLmhpLFNWR0NpcmNsZUVsZW1lbnQ6UC5oaSxTVkdDbGlwUGF0aEVsZW1lbnQ6UC5oaSxTVkdE
+ZWZzRWxlbWVudDpQLmhpLFNWR0Rlc2NFbGVtZW50OlAuaGksU1ZHRGlzY2FyZEVsZW1lbnQ6UC5oaSxT
+VkdFbGxpcHNlRWxlbWVudDpQLmhpLFNWR0ZFQmxlbmRFbGVtZW50OlAuaGksU1ZHRkVDb2xvck1hdHJp
+eEVsZW1lbnQ6UC5oaSxTVkdGRUNvbXBvbmVudFRyYW5zZmVyRWxlbWVudDpQLmhpLFNWR0ZFQ29tcG9z
+aXRlRWxlbWVudDpQLmhpLFNWR0ZFQ29udm9sdmVNYXRyaXhFbGVtZW50OlAuaGksU1ZHRkVEaWZmdXNl
+TGlnaHRpbmdFbGVtZW50OlAuaGksU1ZHRkVEaXNwbGFjZW1lbnRNYXBFbGVtZW50OlAuaGksU1ZHRkVE
+aXN0YW50TGlnaHRFbGVtZW50OlAuaGksU1ZHRkVGbG9vZEVsZW1lbnQ6UC5oaSxTVkdGRUZ1bmNBRWxl
+bWVudDpQLmhpLFNWR0ZFRnVuY0JFbGVtZW50OlAuaGksU1ZHRkVGdW5jR0VsZW1lbnQ6UC5oaSxTVkdG
+RUZ1bmNSRWxlbWVudDpQLmhpLFNWR0ZFR2F1c3NpYW5CbHVyRWxlbWVudDpQLmhpLFNWR0ZFSW1hZ2VF
+bGVtZW50OlAuaGksU1ZHRkVNZXJnZUVsZW1lbnQ6UC5oaSxTVkdGRU1lcmdlTm9kZUVsZW1lbnQ6UC5o
+aSxTVkdGRU1vcnBob2xvZ3lFbGVtZW50OlAuaGksU1ZHRkVPZmZzZXRFbGVtZW50OlAuaGksU1ZHRkVQ
+b2ludExpZ2h0RWxlbWVudDpQLmhpLFNWR0ZFU3BlY3VsYXJMaWdodGluZ0VsZW1lbnQ6UC5oaSxTVkdG
+RVNwb3RMaWdodEVsZW1lbnQ6UC5oaSxTVkdGRVRpbGVFbGVtZW50OlAuaGksU1ZHRkVUdXJidWxlbmNl
+RWxlbWVudDpQLmhpLFNWR0ZpbHRlckVsZW1lbnQ6UC5oaSxTVkdGb3JlaWduT2JqZWN0RWxlbWVudDpQ
+LmhpLFNWR0dFbGVtZW50OlAuaGksU1ZHR2VvbWV0cnlFbGVtZW50OlAuaGksU1ZHR3JhcGhpY3NFbGVt
+ZW50OlAuaGksU1ZHSW1hZ2VFbGVtZW50OlAuaGksU1ZHTGluZUVsZW1lbnQ6UC5oaSxTVkdMaW5lYXJH
+cmFkaWVudEVsZW1lbnQ6UC5oaSxTVkdNYXJrZXJFbGVtZW50OlAuaGksU1ZHTWFza0VsZW1lbnQ6UC5o
+aSxTVkdNZXRhZGF0YUVsZW1lbnQ6UC5oaSxTVkdQYXRoRWxlbWVudDpQLmhpLFNWR1BhdHRlcm5FbGVt
+ZW50OlAuaGksU1ZHUG9seWdvbkVsZW1lbnQ6UC5oaSxTVkdQb2x5bGluZUVsZW1lbnQ6UC5oaSxTVkdS
+YWRpYWxHcmFkaWVudEVsZW1lbnQ6UC5oaSxTVkdSZWN0RWxlbWVudDpQLmhpLFNWR1NldEVsZW1lbnQ6
+UC5oaSxTVkdTdG9wRWxlbWVudDpQLmhpLFNWR1N0eWxlRWxlbWVudDpQLmhpLFNWR1NWR0VsZW1lbnQ6
+UC5oaSxTVkdTd2l0Y2hFbGVtZW50OlAuaGksU1ZHU3ltYm9sRWxlbWVudDpQLmhpLFNWR1RTcGFuRWxl
+bWVudDpQLmhpLFNWR1RleHRDb250ZW50RWxlbWVudDpQLmhpLFNWR1RleHRFbGVtZW50OlAuaGksU1ZH
+VGV4dFBhdGhFbGVtZW50OlAuaGksU1ZHVGV4dFBvc2l0aW9uaW5nRWxlbWVudDpQLmhpLFNWR1RpdGxl
+RWxlbWVudDpQLmhpLFNWR1VzZUVsZW1lbnQ6UC5oaSxTVkdWaWV3RWxlbWVudDpQLmhpLFNWR0dyYWRp
+ZW50RWxlbWVudDpQLmhpLFNWR0NvbXBvbmVudFRyYW5zZmVyRnVuY3Rpb25FbGVtZW50OlAuaGksU1ZH
+RkVEcm9wU2hhZG93RWxlbWVudDpQLmhpLFNWR01QYXRoRWxlbWVudDpQLmhpLFNWR0VsZW1lbnQ6UC5o
+aX0pCmh1bmtIZWxwZXJzLnNldE9yVXBkYXRlTGVhZlRhZ3Moe0RPTUVycm9yOnRydWUsTWVkaWFFcnJv
+cjp0cnVlLE5hdmlnYXRvcjp0cnVlLE5hdmlnYXRvckNvbmN1cnJlbnRIYXJkd2FyZTp0cnVlLE5hdmln
+YXRvclVzZXJNZWRpYUVycm9yOnRydWUsT3ZlcmNvbnN0cmFpbmVkRXJyb3I6dHJ1ZSxQb3NpdGlvbkVy
+cm9yOnRydWUsUmFuZ2U6dHJ1ZSxTUUxFcnJvcjp0cnVlLERhdGFWaWV3OnRydWUsQXJyYXlCdWZmZXJW
+aWV3OmZhbHNlLEZsb2F0MzJBcnJheTp0cnVlLEZsb2F0NjRBcnJheTp0cnVlLEludDE2QXJyYXk6dHJ1
+ZSxJbnQzMkFycmF5OnRydWUsSW50OEFycmF5OnRydWUsVWludDE2QXJyYXk6dHJ1ZSxVaW50MzJBcnJh
+eTp0cnVlLFVpbnQ4Q2xhbXBlZEFycmF5OnRydWUsQ2FudmFzUGl4ZWxBcnJheTp0cnVlLFVpbnQ4QXJy
+YXk6ZmFsc2UsSFRNTEF1ZGlvRWxlbWVudDp0cnVlLEhUTUxCUkVsZW1lbnQ6dHJ1ZSxIVE1MQnV0dG9u
+RWxlbWVudDp0cnVlLEhUTUxDYW52YXNFbGVtZW50OnRydWUsSFRNTENvbnRlbnRFbGVtZW50OnRydWUs
+SFRNTERMaXN0RWxlbWVudDp0cnVlLEhUTUxEYXRhRWxlbWVudDp0cnVlLEhUTUxEYXRhTGlzdEVsZW1l
+bnQ6dHJ1ZSxIVE1MRGV0YWlsc0VsZW1lbnQ6dHJ1ZSxIVE1MRGlhbG9nRWxlbWVudDp0cnVlLEhUTUxE
+aXZFbGVtZW50OnRydWUsSFRNTEVtYmVkRWxlbWVudDp0cnVlLEhUTUxGaWVsZFNldEVsZW1lbnQ6dHJ1
+ZSxIVE1MSFJFbGVtZW50OnRydWUsSFRNTEhlYWRFbGVtZW50OnRydWUsSFRNTEhlYWRpbmdFbGVtZW50
+OnRydWUsSFRNTEh0bWxFbGVtZW50OnRydWUsSFRNTElGcmFtZUVsZW1lbnQ6dHJ1ZSxIVE1MSW1hZ2VF
+bGVtZW50OnRydWUsSFRNTElucHV0RWxlbWVudDp0cnVlLEhUTUxMSUVsZW1lbnQ6dHJ1ZSxIVE1MTGFi
+ZWxFbGVtZW50OnRydWUsSFRNTExlZ2VuZEVsZW1lbnQ6dHJ1ZSxIVE1MTGlua0VsZW1lbnQ6dHJ1ZSxI
+VE1MTWFwRWxlbWVudDp0cnVlLEhUTUxNZWRpYUVsZW1lbnQ6dHJ1ZSxIVE1MTWVudUVsZW1lbnQ6dHJ1
+ZSxIVE1MTWV0YUVsZW1lbnQ6dHJ1ZSxIVE1MTWV0ZXJFbGVtZW50OnRydWUsSFRNTE1vZEVsZW1lbnQ6
+dHJ1ZSxIVE1MT0xpc3RFbGVtZW50OnRydWUsSFRNTE9iamVjdEVsZW1lbnQ6dHJ1ZSxIVE1MT3B0R3Jv
+dXBFbGVtZW50OnRydWUsSFRNTE9wdGlvbkVsZW1lbnQ6dHJ1ZSxIVE1MT3V0cHV0RWxlbWVudDp0cnVl
+LEhUTUxQYXJhbUVsZW1lbnQ6dHJ1ZSxIVE1MUGljdHVyZUVsZW1lbnQ6dHJ1ZSxIVE1MUHJlRWxlbWVu
+dDp0cnVlLEhUTUxQcm9ncmVzc0VsZW1lbnQ6dHJ1ZSxIVE1MUXVvdGVFbGVtZW50OnRydWUsSFRNTFNj
+cmlwdEVsZW1lbnQ6dHJ1ZSxIVE1MU2hhZG93RWxlbWVudDp0cnVlLEhUTUxTbG90RWxlbWVudDp0cnVl
+LEhUTUxTb3VyY2VFbGVtZW50OnRydWUsSFRNTFNwYW5FbGVtZW50OnRydWUsSFRNTFN0eWxlRWxlbWVu
+dDp0cnVlLEhUTUxUYWJsZUNhcHRpb25FbGVtZW50OnRydWUsSFRNTFRhYmxlQ2VsbEVsZW1lbnQ6dHJ1
+ZSxIVE1MVGFibGVEYXRhQ2VsbEVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVIZWFkZXJDZWxsRWxlbWVudDp0
+cnVlLEhUTUxUYWJsZUNvbEVsZW1lbnQ6dHJ1ZSxIVE1MVGV4dEFyZWFFbGVtZW50OnRydWUsSFRNTFRp
+bWVFbGVtZW50OnRydWUsSFRNTFRpdGxlRWxlbWVudDp0cnVlLEhUTUxUcmFja0VsZW1lbnQ6dHJ1ZSxI
+VE1MVUxpc3RFbGVtZW50OnRydWUsSFRNTFVua25vd25FbGVtZW50OnRydWUsSFRNTFZpZGVvRWxlbWVu
+dDp0cnVlLEhUTUxEaXJlY3RvcnlFbGVtZW50OnRydWUsSFRNTEZvbnRFbGVtZW50OnRydWUsSFRNTEZy
+YW1lRWxlbWVudDp0cnVlLEhUTUxGcmFtZVNldEVsZW1lbnQ6dHJ1ZSxIVE1MTWFycXVlZUVsZW1lbnQ6
+dHJ1ZSxIVE1MRWxlbWVudDpmYWxzZSxIVE1MQW5jaG9yRWxlbWVudDp0cnVlLEhUTUxBcmVhRWxlbWVu
+dDp0cnVlLEhUTUxCYXNlRWxlbWVudDp0cnVlLEJsb2I6ZmFsc2UsSFRNTEJvZHlFbGVtZW50OnRydWUs
+Q0RBVEFTZWN0aW9uOnRydWUsQ2hhcmFjdGVyRGF0YTp0cnVlLENvbW1lbnQ6dHJ1ZSxQcm9jZXNzaW5n
+SW5zdHJ1Y3Rpb246dHJ1ZSxUZXh0OnRydWUsQ1NTU3R5bGVEZWNsYXJhdGlvbjp0cnVlLE1TU3R5bGVD
+U1NQcm9wZXJ0aWVzOnRydWUsQ1NTMlByb3BlcnRpZXM6dHJ1ZSxYTUxEb2N1bWVudDp0cnVlLERvY3Vt
+ZW50OmZhbHNlLERPTUV4Y2VwdGlvbjp0cnVlLERPTUltcGxlbWVudGF0aW9uOnRydWUsRE9NUmVjdFJl
+YWRPbmx5OmZhbHNlLERPTVRva2VuTGlzdDp0cnVlLEVsZW1lbnQ6ZmFsc2UsQWJvcnRQYXltZW50RXZl
+bnQ6dHJ1ZSxBbmltYXRpb25FdmVudDp0cnVlLEFuaW1hdGlvblBsYXliYWNrRXZlbnQ6dHJ1ZSxBcHBs
+aWNhdGlvbkNhY2hlRXJyb3JFdmVudDp0cnVlLEJhY2tncm91bmRGZXRjaENsaWNrRXZlbnQ6dHJ1ZSxC
+YWNrZ3JvdW5kRmV0Y2hFdmVudDp0cnVlLEJhY2tncm91bmRGZXRjaEZhaWxFdmVudDp0cnVlLEJhY2tn
+cm91bmRGZXRjaGVkRXZlbnQ6dHJ1ZSxCZWZvcmVJbnN0YWxsUHJvbXB0RXZlbnQ6dHJ1ZSxCZWZvcmVV
+bmxvYWRFdmVudDp0cnVlLEJsb2JFdmVudDp0cnVlLENhbk1ha2VQYXltZW50RXZlbnQ6dHJ1ZSxDbGlw
+Ym9hcmRFdmVudDp0cnVlLENsb3NlRXZlbnQ6dHJ1ZSxDdXN0b21FdmVudDp0cnVlLERldmljZU1vdGlv
+bkV2ZW50OnRydWUsRGV2aWNlT3JpZW50YXRpb25FdmVudDp0cnVlLEVycm9yRXZlbnQ6dHJ1ZSxFeHRl
+bmRhYmxlRXZlbnQ6dHJ1ZSxFeHRlbmRhYmxlTWVzc2FnZUV2ZW50OnRydWUsRmV0Y2hFdmVudDp0cnVl
+LEZvbnRGYWNlU2V0TG9hZEV2ZW50OnRydWUsRm9yZWlnbkZldGNoRXZlbnQ6dHJ1ZSxHYW1lcGFkRXZl
+bnQ6dHJ1ZSxIYXNoQ2hhbmdlRXZlbnQ6dHJ1ZSxJbnN0YWxsRXZlbnQ6dHJ1ZSxNZWRpYUVuY3J5cHRl
+ZEV2ZW50OnRydWUsTWVkaWFLZXlNZXNzYWdlRXZlbnQ6dHJ1ZSxNZWRpYVF1ZXJ5TGlzdEV2ZW50OnRy
+dWUsTWVkaWFTdHJlYW1FdmVudDp0cnVlLE1lZGlhU3RyZWFtVHJhY2tFdmVudDp0cnVlLE1lc3NhZ2VF
+dmVudDp0cnVlLE1JRElDb25uZWN0aW9uRXZlbnQ6dHJ1ZSxNSURJTWVzc2FnZUV2ZW50OnRydWUsTXV0
+YXRpb25FdmVudDp0cnVlLE5vdGlmaWNhdGlvbkV2ZW50OnRydWUsUGFnZVRyYW5zaXRpb25FdmVudDp0
+cnVlLFBheW1lbnRSZXF1ZXN0RXZlbnQ6dHJ1ZSxQYXltZW50UmVxdWVzdFVwZGF0ZUV2ZW50OnRydWUs
+UG9wU3RhdGVFdmVudDp0cnVlLFByZXNlbnRhdGlvbkNvbm5lY3Rpb25BdmFpbGFibGVFdmVudDp0cnVl
+LFByZXNlbnRhdGlvbkNvbm5lY3Rpb25DbG9zZUV2ZW50OnRydWUsUHJvbWlzZVJlamVjdGlvbkV2ZW50
+OnRydWUsUHVzaEV2ZW50OnRydWUsUlRDRGF0YUNoYW5uZWxFdmVudDp0cnVlLFJUQ0RUTUZUb25lQ2hh
+bmdlRXZlbnQ6dHJ1ZSxSVENQZWVyQ29ubmVjdGlvbkljZUV2ZW50OnRydWUsUlRDVHJhY2tFdmVudDp0
+cnVlLFNlY3VyaXR5UG9saWN5VmlvbGF0aW9uRXZlbnQ6dHJ1ZSxTZW5zb3JFcnJvckV2ZW50OnRydWUs
+U3BlZWNoUmVjb2duaXRpb25FcnJvcjp0cnVlLFNwZWVjaFJlY29nbml0aW9uRXZlbnQ6dHJ1ZSxTcGVl
+Y2hTeW50aGVzaXNFdmVudDp0cnVlLFN0b3JhZ2VFdmVudDp0cnVlLFN5bmNFdmVudDp0cnVlLFRyYWNr
+RXZlbnQ6dHJ1ZSxUcmFuc2l0aW9uRXZlbnQ6dHJ1ZSxXZWJLaXRUcmFuc2l0aW9uRXZlbnQ6dHJ1ZSxW
+UkRldmljZUV2ZW50OnRydWUsVlJEaXNwbGF5RXZlbnQ6dHJ1ZSxWUlNlc3Npb25FdmVudDp0cnVlLE1v
+am9JbnRlcmZhY2VSZXF1ZXN0RXZlbnQ6dHJ1ZSxVU0JDb25uZWN0aW9uRXZlbnQ6dHJ1ZSxJREJWZXJz
+aW9uQ2hhbmdlRXZlbnQ6dHJ1ZSxBdWRpb1Byb2Nlc3NpbmdFdmVudDp0cnVlLE9mZmxpbmVBdWRpb0Nv
+bXBsZXRpb25FdmVudDp0cnVlLFdlYkdMQ29udGV4dEV2ZW50OnRydWUsRXZlbnQ6ZmFsc2UsSW5wdXRF
+dmVudDpmYWxzZSxTdWJtaXRFdmVudDpmYWxzZSxFdmVudFRhcmdldDpmYWxzZSxGaWxlOnRydWUsSFRN
+TEZvcm1FbGVtZW50OnRydWUsSGlzdG9yeTp0cnVlLEhUTUxEb2N1bWVudDp0cnVlLFhNTEh0dHBSZXF1
+ZXN0OnRydWUsWE1MSHR0cFJlcXVlc3RFdmVudFRhcmdldDpmYWxzZSxJbWFnZURhdGE6dHJ1ZSxMb2Nh
+dGlvbjp0cnVlLE1vdXNlRXZlbnQ6dHJ1ZSxEcmFnRXZlbnQ6dHJ1ZSxQb2ludGVyRXZlbnQ6dHJ1ZSxX
+aGVlbEV2ZW50OnRydWUsRG9jdW1lbnRGcmFnbWVudDp0cnVlLFNoYWRvd1Jvb3Q6dHJ1ZSxEb2N1bWVu
+dFR5cGU6dHJ1ZSxOb2RlOmZhbHNlLE5vZGVMaXN0OnRydWUsUmFkaW9Ob2RlTGlzdDp0cnVlLEhUTUxQ
+YXJhZ3JhcGhFbGVtZW50OnRydWUsUHJvZ3Jlc3NFdmVudDp0cnVlLFJlc291cmNlUHJvZ3Jlc3NFdmVu
+dDp0cnVlLEhUTUxTZWxlY3RFbGVtZW50OnRydWUsSFRNTFRhYmxlRWxlbWVudDp0cnVlLEhUTUxUYWJs
+ZVJvd0VsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVTZWN0aW9uRWxlbWVudDp0cnVlLEhUTUxUZW1wbGF0ZUVs
+ZW1lbnQ6dHJ1ZSxDb21wb3NpdGlvbkV2ZW50OnRydWUsRm9jdXNFdmVudDp0cnVlLEtleWJvYXJkRXZl
+bnQ6dHJ1ZSxUZXh0RXZlbnQ6dHJ1ZSxUb3VjaEV2ZW50OnRydWUsVUlFdmVudDpmYWxzZSxXaW5kb3c6
+dHJ1ZSxET01XaW5kb3c6dHJ1ZSxEZWRpY2F0ZWRXb3JrZXJHbG9iYWxTY29wZTp0cnVlLFNlcnZpY2VX
+b3JrZXJHbG9iYWxTY29wZTp0cnVlLFNoYXJlZFdvcmtlckdsb2JhbFNjb3BlOnRydWUsV29ya2VyR2xv
+YmFsU2NvcGU6dHJ1ZSxBdHRyOnRydWUsQ2xpZW50UmVjdDp0cnVlLERPTVJlY3Q6dHJ1ZSxOYW1lZE5v
+ZGVNYXA6dHJ1ZSxNb3pOYW1lZEF0dHJNYXA6dHJ1ZSxJREJLZXlSYW5nZTp0cnVlLFNWR1NjcmlwdEVs
+ZW1lbnQ6dHJ1ZSxTVkdBRWxlbWVudDp0cnVlLFNWR0FuaW1hdGVFbGVtZW50OnRydWUsU1ZHQW5pbWF0
+ZU1vdGlvbkVsZW1lbnQ6dHJ1ZSxTVkdBbmltYXRlVHJhbnNmb3JtRWxlbWVudDp0cnVlLFNWR0FuaW1h
+dGlvbkVsZW1lbnQ6dHJ1ZSxTVkdDaXJjbGVFbGVtZW50OnRydWUsU1ZHQ2xpcFBhdGhFbGVtZW50OnRy
+dWUsU1ZHRGVmc0VsZW1lbnQ6dHJ1ZSxTVkdEZXNjRWxlbWVudDp0cnVlLFNWR0Rpc2NhcmRFbGVtZW50
+OnRydWUsU1ZHRWxsaXBzZUVsZW1lbnQ6dHJ1ZSxTVkdGRUJsZW5kRWxlbWVudDp0cnVlLFNWR0ZFQ29s
+b3JNYXRyaXhFbGVtZW50OnRydWUsU1ZHRkVDb21wb25lbnRUcmFuc2ZlckVsZW1lbnQ6dHJ1ZSxTVkdG
+RUNvbXBvc2l0ZUVsZW1lbnQ6dHJ1ZSxTVkdGRUNvbnZvbHZlTWF0cml4RWxlbWVudDp0cnVlLFNWR0ZF
+RGlmZnVzZUxpZ2h0aW5nRWxlbWVudDp0cnVlLFNWR0ZFRGlzcGxhY2VtZW50TWFwRWxlbWVudDp0cnVl
+LFNWR0ZFRGlzdGFudExpZ2h0RWxlbWVudDp0cnVlLFNWR0ZFRmxvb2RFbGVtZW50OnRydWUsU1ZHRkVG
+dW5jQUVsZW1lbnQ6dHJ1ZSxTVkdGRUZ1bmNCRWxlbWVudDp0cnVlLFNWR0ZFRnVuY0dFbGVtZW50OnRy
+dWUsU1ZHRkVGdW5jUkVsZW1lbnQ6dHJ1ZSxTVkdGRUdhdXNzaWFuQmx1ckVsZW1lbnQ6dHJ1ZSxTVkdG
+RUltYWdlRWxlbWVudDp0cnVlLFNWR0ZFTWVyZ2VFbGVtZW50OnRydWUsU1ZHRkVNZXJnZU5vZGVFbGVt
+ZW50OnRydWUsU1ZHRkVNb3JwaG9sb2d5RWxlbWVudDp0cnVlLFNWR0ZFT2Zmc2V0RWxlbWVudDp0cnVl
+LFNWR0ZFUG9pbnRMaWdodEVsZW1lbnQ6dHJ1ZSxTVkdGRVNwZWN1bGFyTGlnaHRpbmdFbGVtZW50OnRy
+dWUsU1ZHRkVTcG90TGlnaHRFbGVtZW50OnRydWUsU1ZHRkVUaWxlRWxlbWVudDp0cnVlLFNWR0ZFVHVy
+YnVsZW5jZUVsZW1lbnQ6dHJ1ZSxTVkdGaWx0ZXJFbGVtZW50OnRydWUsU1ZHRm9yZWlnbk9iamVjdEVs
+ZW1lbnQ6dHJ1ZSxTVkdHRWxlbWVudDp0cnVlLFNWR0dlb21ldHJ5RWxlbWVudDp0cnVlLFNWR0dyYXBo
+aWNzRWxlbWVudDp0cnVlLFNWR0ltYWdlRWxlbWVudDp0cnVlLFNWR0xpbmVFbGVtZW50OnRydWUsU1ZH
+TGluZWFyR3JhZGllbnRFbGVtZW50OnRydWUsU1ZHTWFya2VyRWxlbWVudDp0cnVlLFNWR01hc2tFbGVt
+ZW50OnRydWUsU1ZHTWV0YWRhdGFFbGVtZW50OnRydWUsU1ZHUGF0aEVsZW1lbnQ6dHJ1ZSxTVkdQYXR0
+ZXJuRWxlbWVudDp0cnVlLFNWR1BvbHlnb25FbGVtZW50OnRydWUsU1ZHUG9seWxpbmVFbGVtZW50OnRy
+dWUsU1ZHUmFkaWFsR3JhZGllbnRFbGVtZW50OnRydWUsU1ZHUmVjdEVsZW1lbnQ6dHJ1ZSxTVkdTZXRF
+bGVtZW50OnRydWUsU1ZHU3RvcEVsZW1lbnQ6dHJ1ZSxTVkdTdHlsZUVsZW1lbnQ6dHJ1ZSxTVkdTVkdF
+bGVtZW50OnRydWUsU1ZHU3dpdGNoRWxlbWVudDp0cnVlLFNWR1N5bWJvbEVsZW1lbnQ6dHJ1ZSxTVkdU
+U3BhbkVsZW1lbnQ6dHJ1ZSxTVkdUZXh0Q29udGVudEVsZW1lbnQ6dHJ1ZSxTVkdUZXh0RWxlbWVudDp0
+cnVlLFNWR1RleHRQYXRoRWxlbWVudDp0cnVlLFNWR1RleHRQb3NpdGlvbmluZ0VsZW1lbnQ6dHJ1ZSxT
+VkdUaXRsZUVsZW1lbnQ6dHJ1ZSxTVkdVc2VFbGVtZW50OnRydWUsU1ZHVmlld0VsZW1lbnQ6dHJ1ZSxT
+VkdHcmFkaWVudEVsZW1lbnQ6dHJ1ZSxTVkdDb21wb25lbnRUcmFuc2ZlckZ1bmN0aW9uRWxlbWVudDp0
+cnVlLFNWR0ZFRHJvcFNoYWRvd0VsZW1lbnQ6dHJ1ZSxTVkdNUGF0aEVsZW1lbnQ6dHJ1ZSxTVkdFbGVt
+ZW50OmZhbHNlfSkKSC5MWi4kbmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILlJH
+LiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXciCkguVlAuJG5hdGl2ZVN1cGVyY2xh
+c3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5EZy4kbmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZm
+ZXJWaWV3IgpILldCLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXciCkguWkcuJG5h
+dGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5QZy4kbmF0aXZlU3VwZXJjbGFzc1Rh
+Zz0iQXJyYXlCdWZmZXJWaWV3In0pKCkKY29udmVydEFsbFRvRmFzdE9iamVjdCh3KQpjb252ZXJ0VG9G
+YXN0T2JqZWN0KCQpOyhmdW5jdGlvbihhKXtpZih0eXBlb2YgZG9jdW1lbnQ9PT0idW5kZWZpbmVkIil7
+YShudWxsKQpyZXR1cm59aWYodHlwZW9mIGRvY3VtZW50LmN1cnJlbnRTY3JpcHQhPSd1bmRlZmluZWQn
+KXthKGRvY3VtZW50LmN1cnJlbnRTY3JpcHQpCnJldHVybn12YXIgcz1kb2N1bWVudC5zY3JpcHRzCmZ1
+bmN0aW9uIG9uTG9hZChiKXtmb3IodmFyIHE9MDtxPHMubGVuZ3RoOysrcSlzW3FdLnJlbW92ZUV2ZW50
+TGlzdGVuZXIoImxvYWQiLG9uTG9hZCxmYWxzZSkKYShiLnRhcmdldCl9Zm9yKHZhciByPTA7cjxzLmxl
+bmd0aDsrK3Ipc1tyXS5hZGRFdmVudExpc3RlbmVyKCJsb2FkIixvbkxvYWQsZmFsc2UpfSkoZnVuY3Rp
+b24oYSl7di5jdXJyZW50U2NyaXB0PWEKaWYodHlwZW9mIGRhcnRNYWluUnVubmVyPT09ImZ1bmN0aW9u
+IilkYXJ0TWFpblJ1bm5lcihMLklxLFtdKQplbHNlIEwuSXEoW10pfSl9KSgpCi8vIyBzb3VyY2VNYXBw
+aW5nVVJMPW1pZ3JhdGlvbi5qcy5tYXAK
''';
diff --git a/pkg/nnbd_migration/lib/src/front_end/web/migration.dart b/pkg/nnbd_migration/lib/src/front_end/web/migration.dart
index 6d5f98b..e98bbea 100644
--- a/pkg/nnbd_migration/lib/src/front_end/web/migration.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/web/migration.dart
@@ -72,6 +72,20 @@
document.querySelector('.popup-pane .close').onClick.listen(
(_) => document.querySelector('.popup-pane').style.display = 'none');
+
+ migrateUnitStatusIcon.onClick.listen((MouseEvent event) {
+ var unitPath = unitName.innerText;
+ var unitNavItem = document
+ .querySelector('.nav-panel [data-name*="$unitPath"]')
+ .parentNode as Element;
+ var statusIcon = unitNavItem.querySelector('.status-icon');
+ var entity = navigationTree.find(unitPath);
+ if (entity is NavigationTreeFileNode) {
+ toggleFileMigrationStatus(entity);
+ updateIconsForNode(statusIcon, entity);
+ updateParentIcons(unitNavItem, entity);
+ }
+ });
});
window.addEventListener('popstate', (event) {
@@ -109,10 +123,18 @@
final Element unitName = document.querySelector('#unit-name');
+final Element migrateUnitStatusIconLabel =
+ document.querySelector('#migrate-unit-status-icon-label');
+
+final Element migrateUnitStatusIcon =
+ document.querySelector('#migrate-unit-status-icon');
+
String get rootPath => querySelector('.root').text.trim();
String get sdkVersion => document.getElementById('sdk-version').text;
+/*late final*/ List<NavigationTreeNode> navigationTree;
+
void addArrowClickHandler(Element arrow) {
var childList = (arrow.parentNode as Element).querySelector(':scope > ul');
// Animating height from "auto" to "0" is not supported by CSS [1], so all we
@@ -430,7 +452,8 @@
final response = await doGet<List<Object>>(path);
var navTree = document.querySelector('.nav-tree');
navTree.innerHtml = '';
- writeNavigationSubtree(navTree, NavigationTreeNode.listFromJson(response),
+ navigationTree = NavigationTreeNode.listFromJson(response);
+ writeNavigationSubtree(navTree, navigationTree,
enablePartialMigration: false);
} catch (e, st) {
handleError('Could not load navigation tree', e, st);
@@ -707,6 +730,19 @@
}
}
+/// Updates the navigation [icon] and current file icon according to the current
+/// migration status of [entity].
+void updateIconsForNode(Element icon, NavigationTreeNode entity) {
+ updateIconForStatus(icon, entity.migrationStatus);
+ // Update the status at the top of the file view if [entity] represents the
+ // current file.
+ var unitPath = unitName.innerText;
+ if (entity.path == unitPath) {
+ updateIconForStatus(migrateUnitStatusIcon, entity.migrationStatus);
+ }
+}
+
+/// Updates [icon] according to [status].
void updateIconForStatus(Element icon, UnitMigrationStatus status) {
switch (status) {
case UnitMigrationStatus.alreadyMigrated:
@@ -753,6 +789,7 @@
link.classes.remove('selected-file');
}
});
+ migrateUnitStatusIconLabel.classes.add('visible');
}
/// Updates the parent icons of [entity] with list item [element] in the
@@ -762,7 +799,7 @@
if (parent != null) {
var parentElement = (element.parentNode as Element).parentNode as Element;
var statusIcon = parentElement.querySelector(':scope > .status-icon');
- updateIconForStatus(statusIcon, parent.migrationStatus);
+ updateIconsForNode(statusIcon, parent);
updateParentIcons(parentElement, parent);
}
}
@@ -774,11 +811,11 @@
if (child is NavigationTreeDirectoryNode) {
updateSubtreeIcons(childNode, child);
var childIcon = childNode.querySelector(':scope > .status-icon');
- updateIconForStatus(childIcon, entity.migrationStatus);
+ updateIconsForNode(childIcon, entity);
} else {
var childIcon = (childNode.parentNode as Element)
.querySelector(':scope > .status-icon');
- updateIconForStatus(childIcon, child.migrationStatus);
+ updateIconsForNode(childIcon, child);
}
}
}
@@ -824,11 +861,11 @@
if (enablePartialMigration) {
var statusIcon = createIcon('indeterminate_check_box')
..classes.add('status-icon');
- updateIconForStatus(statusIcon, entity.migrationStatus);
+ updateIconsForNode(statusIcon, entity);
statusIcon.onClick.listen((MouseEvent event) {
toggleDirectoryMigrationStatus(entity);
updateSubtreeIcons(li, entity);
- updateIconForStatus(statusIcon, entity.migrationStatus);
+ updateIconsForNode(statusIcon, entity);
updateParentIcons(li, entity);
});
li.insertBefore(statusIcon, folderIcon);
@@ -837,10 +874,10 @@
} else if (entity is NavigationTreeFileNode) {
if (enablePartialMigration) {
var statusIcon = createIcon()..classes.add('status-icon');
- updateIconForStatus(statusIcon, entity.migrationStatus);
+ updateIconsForNode(statusIcon, entity);
statusIcon.onClick.listen((MouseEvent event) {
toggleFileMigrationStatus(entity);
- updateIconForStatus(statusIcon, entity.migrationStatus);
+ updateIconsForNode(statusIcon, entity);
updateParentIcons(li, entity);
});
li.append(statusIcon);
@@ -991,3 +1028,19 @@
}
}
}
+
+extension on List<NavigationTreeNode> {
+ /// Finds the node with path equal to [path], recursively, or `null`.
+ NavigationTreeNode find(String path) {
+ for (var node in this) {
+ if (node is NavigationTreeDirectoryNode) {
+ var foundInSubtree = node.subtree.find(path);
+ if (foundInSubtree != null) return foundInSubtree;
+ } else {
+ assert(node is NavigationTreeFileNode);
+ if (node.path == path) return node;
+ }
+ }
+ return null;
+ }
+}
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index f36f2b2..8e1285fa 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -4678,6 +4678,54 @@
await _checkSingleFileChanges(content, expected);
}
+ Future<void> test_loop_var_is_field() async {
+ var content = '''
+class C {
+ int x;
+ C(this.x);
+ f(List<int/*?*/> y) {
+ for (x in y) {}
+ }
+}
+''';
+ var expected = '''
+class C {
+ int? x;
+ C(this.x);
+ f(List<int?> y) {
+ for (x in y) {}
+ }
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ Future<void> test_loop_var_is_inherited_field_with_substitution() async {
+ var content = '''
+class B<T> {
+ T x;
+ B(this.x);
+}
+abstract class C implements B<int> {
+ f(List<int/*?*/> y) {
+ for (x in y) {}
+ }
+}
+''';
+ var expected = '''
+class B<T> {
+ T x;
+ B(this.x);
+}
+abstract class C implements B<int?> {
+ f(List<int?> y) {
+ for (x in y) {}
+ }
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
Future<void> test_make_downcast_explicit() async {
var content = 'int f(num n) => n;';
var expected = 'int f(num n) => n as int;';
diff --git a/runtime/bin/security_context_macos.cc b/runtime/bin/security_context_macos.cc
index c934fc5..927e139 100644
--- a/runtime/bin/security_context_macos.cc
+++ b/runtime/bin/security_context_macos.cc
@@ -106,6 +106,8 @@
uint8_t* out_alert) {
SSLFilter* filter = static_cast<SSLFilter*>(
SSL_get_ex_data(ssl, SSLFilter::filter_ssl_index));
+ SSLCertContext* context = static_cast<SSLCertContext*>(
+ SSL_get_ex_data(ssl, SSLFilter::ssl_cert_context_index));
const X509TrustState* certificate_trust_state =
filter->certificate_trust_state();
@@ -125,9 +127,90 @@
}
}
- Dart_CObject dart_cobject_ssl;
- dart_cobject_ssl.type = Dart_CObject_kInt64;
- dart_cobject_ssl.value.as_int64 = reinterpret_cast<intptr_t>(ssl);
+ STACK_OF(X509)* unverified = sk_X509_dup(SSL_get_peer_full_cert_chain(ssl));
+
+ // Convert BoringSSL formatted certificates to SecCertificate certificates.
+ ScopedCFMutableArrayRef cert_chain(NULL);
+ X509* root_cert = NULL;
+ int num_certs = sk_X509_num(unverified);
+ int current_cert = 0;
+ cert_chain.set(CFArrayCreateMutable(NULL, num_certs, NULL));
+ X509* ca;
+ while ((ca = sk_X509_shift(unverified)) != NULL) {
+ ScopedSecCertificateRef cert(CreateSecCertificateFromX509(ca));
+ if (cert == NULL) {
+ return ssl_verify_invalid;
+ }
+ CFArrayAppendValue(cert_chain.get(), cert.release());
+ ++current_cert;
+
+ if (current_cert == num_certs) {
+ root_cert = ca;
+ }
+ }
+
+ SSL_CTX* ssl_ctx = SSL_get_SSL_CTX(ssl);
+ X509_STORE* store = SSL_CTX_get_cert_store(ssl_ctx);
+ // Convert all trusted certificates provided by the user via
+ // setTrustedCertificatesBytes or the command line into SecCertificates.
+ ScopedCFMutableArrayRef trusted_certs(CFArrayCreateMutable(NULL, 0, NULL));
+ ASSERT(store != NULL);
+
+ if (store->objs != NULL) {
+ for (uintptr_t i = 0; i < sk_X509_OBJECT_num(store->objs); ++i) {
+ X509* ca = sk_X509_OBJECT_value(store->objs, i)->data.x509;
+ ScopedSecCertificateRef cert(CreateSecCertificateFromX509(ca));
+ if (cert == NULL) {
+ return ssl_verify_invalid;
+ }
+ CFArrayAppendValue(trusted_certs.get(), cert.release());
+ }
+ }
+
+ // Generate a policy for validating chains for SSL.
+ CFStringRef cfhostname = NULL;
+ if (filter->hostname() != NULL) {
+ cfhostname = CFStringCreateWithCString(NULL, filter->hostname(),
+ kCFStringEncodingUTF8);
+ }
+ ScopedCFStringRef hostname(cfhostname);
+ ScopedSecPolicyRef policy(
+ SecPolicyCreateSSL(filter->is_client(), hostname.get()));
+
+ // Create the trust object with the certificates provided by the user.
+ ScopedSecTrustRef trust(NULL);
+ OSStatus status = SecTrustCreateWithCertificates(cert_chain.get(),
+ policy.get(), trust.ptr());
+ if (status != noErr) {
+ return ssl_verify_invalid;
+ }
+
+ // If the user provided any additional CA certificates, add them to the trust
+ // object.
+ if (CFArrayGetCount(trusted_certs.get()) > 0) {
+ status = SecTrustSetAnchorCertificates(trust.get(), trusted_certs.get());
+ if (status != noErr) {
+ return ssl_verify_invalid;
+ }
+ }
+
+ // Specify whether or not to use the built-in CA certificates for
+ // verification.
+ status =
+ SecTrustSetAnchorCertificatesOnly(trust.get(), !context->trust_builtin());
+ if (status != noErr) {
+ return ssl_verify_invalid;
+ }
+
+ // Handler should release trust and root_cert.
+ Dart_CObject dart_cobject_trust;
+ dart_cobject_trust.type = Dart_CObject_kInt64;
+ dart_cobject_trust.value.as_int64 =
+ reinterpret_cast<intptr_t>(CFRetain(trust.get()));
+
+ Dart_CObject dart_cobject_root_cert;
+ dart_cobject_root_cert.type = Dart_CObject_kInt64;
+ dart_cobject_root_cert.value.as_int64 = reinterpret_cast<intptr_t>(root_cert);
Dart_CObject reply_send_port;
reply_send_port.type = Dart_CObject_kSendPort;
@@ -135,8 +218,9 @@
Dart_CObject array;
array.type = Dart_CObject_kArray;
- array.value.as_array.length = 2;
- Dart_CObject* values[] = {&dart_cobject_ssl, &reply_send_port};
+ array.value.as_array.length = 3;
+ Dart_CObject* values[] = {&dart_cobject_trust, &dart_cobject_root_cert,
+ &reply_send_port};
array.value.as_array.values = values;
Dart_PostCObject(filter->trust_evaluate_reply_port(), &array);
@@ -166,104 +250,28 @@
static void TrustEvaluateHandler(Dart_Port dest_port_id,
Dart_CObject* message) {
- CObjectArray request(message);
- ASSERT(request.Length() == 2);
-
- CObjectIntptr ssl_cobject(request[0]);
- SSL* ssl = reinterpret_cast<SSL*>(ssl_cobject.Value());
- SSLFilter* filter = static_cast<SSLFilter*>(
- SSL_get_ex_data(ssl, SSLFilter::filter_ssl_index));
- SSLCertContext* context = static_cast<SSLCertContext*>(
- SSL_get_ex_data(ssl, SSLFilter::ssl_cert_context_index));
- CObjectSendPort reply_port(request[1]);
- Dart_Port reply_port_id = reply_port.Value();
-
- STACK_OF(X509)* unverified = sk_X509_dup(SSL_get_peer_full_cert_chain(ssl));
-
- // Convert BoringSSL formatted certificates to SecCertificate certificates.
- ScopedCFMutableArrayRef cert_chain(NULL);
- X509* root_cert = NULL;
- int num_certs = sk_X509_num(unverified);
- int current_cert = 0;
- cert_chain.set(CFArrayCreateMutable(NULL, num_certs, NULL));
- X509* ca;
- while ((ca = sk_X509_shift(unverified)) != NULL) {
- ScopedSecCertificateRef cert(CreateSecCertificateFromX509(ca));
- if (cert == NULL) {
- postReply(reply_port_id, /*success=*/false);
- return;
- }
- CFArrayAppendValue(cert_chain.get(), cert.release());
- ++current_cert;
-
- if (current_cert == num_certs) {
- root_cert = ca;
- }
- }
-
- SSL_CTX* ssl_ctx = SSL_get_SSL_CTX(ssl);
- X509_STORE* store = SSL_CTX_get_cert_store(ssl_ctx);
- // Convert all trusted certificates provided by the user via
- // setTrustedCertificatesBytes or the command line into SecCertificates.
- ScopedCFMutableArrayRef trusted_certs(CFArrayCreateMutable(NULL, 0, NULL));
- ASSERT(store != NULL);
-
- if (store->objs != NULL) {
- for (uintptr_t i = 0; i < sk_X509_OBJECT_num(store->objs); ++i) {
- X509* ca = sk_X509_OBJECT_value(store->objs, i)->data.x509;
- ScopedSecCertificateRef cert(CreateSecCertificateFromX509(ca));
- if (cert == NULL) {
- postReply(reply_port_id, /*success=*/false);
- return;
- }
- CFArrayAppendValue(trusted_certs.get(), cert.release());
- }
- }
-
- // Generate a policy for validating chains for SSL.
- CFStringRef cfhostname = NULL;
- if (filter->hostname() != NULL) {
- cfhostname = CFStringCreateWithCString(NULL, filter->hostname(),
- kCFStringEncodingUTF8);
- }
- ScopedCFStringRef hostname(cfhostname);
- ScopedSecPolicyRef policy(
- SecPolicyCreateSSL(filter->is_client(), hostname.get()));
-
- // Create the trust object with the certificates provided by the user.
- ScopedSecTrustRef trust(NULL);
- OSStatus status = SecTrustCreateWithCertificates(cert_chain.get(),
- policy.get(), trust.ptr());
- if (status != noErr) {
- postReply(reply_port_id, /*success=*/false);
- return;
- }
-
- // If the user provided any additional CA certificates, add them to the trust
- // object.
- if (CFArrayGetCount(trusted_certs.get()) > 0) {
- status = SecTrustSetAnchorCertificates(trust.get(), trusted_certs.get());
- if (status != noErr) {
- postReply(reply_port_id, /*success=*/false);
- return;
- }
- }
-
- // Specify whether or not to use the built-in CA certificates for
- // verification.
- status =
- SecTrustSetAnchorCertificatesOnly(trust.get(), !context->trust_builtin());
- if (status != noErr) {
- postReply(reply_port_id, /*success=*/false);
- return;
- }
-
- SecTrustResultType trust_result;
-
// This is used for testing to confirm that trust evaluation doesn't block
// dart isolate.
+ // First sleep exposes problem where ssl data structures are released/freed
+ // by main isolate before this handler had a chance to access them.
+ // Second sleep(below) is there to maintain same long delay of certificate
+ // verification.
if (SSLCertContext::long_ssl_cert_evaluation()) {
- usleep(1000 * 1000 /*1 s*/);
+ usleep(2000 * 1000 /* 2 s*/);
+ }
+
+ CObjectArray request(message);
+ ASSERT(request.Length() == 3);
+ CObjectIntptr trust_cobject(request[0]);
+ ScopedSecTrustRef trust(reinterpret_cast<SecTrustRef>(trust_cobject.Value()));
+ CObjectIntptr root_cert_cobject(request[1]);
+ X509* root_cert = reinterpret_cast<X509*>(root_cert_cobject.Value());
+ CObjectSendPort reply_port(request[2]);
+ Dart_Port reply_port_id = reply_port.Value();
+
+ SecTrustResultType trust_result;
+ if (SSLCertContext::long_ssl_cert_evaluation()) {
+ usleep(3000 * 1000 /* 3 s*/);
}
// Perform the certificate verification.
@@ -277,11 +285,11 @@
// from calling SecTrustEvaluate.
bool res = SecTrustEvaluateWithError(trust.get(), NULL);
USE(res);
- status = SecTrustGetTrustResult(trust.get(), &trust_result);
+ OSStatus status = SecTrustGetTrustResult(trust.get(), &trust_result);
#else
// SecTrustEvaluate is deprecated as of OSX 10.15 and iOS 13.
- status = SecTrustEvaluate(trust.get(), &trust_result);
+ OSStatus status = SecTrustEvaluate(trust.get(), &trust_result);
#endif
postReply(reply_port_id,
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index bd8e8b7..9fdefe6 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -820,23 +820,26 @@
const Array& descriptor =
Array::Handle(zone, ic_data.arguments_descriptor());
Thread* thread = Thread::Current();
- const MegamorphicCache& cache = MegamorphicCache::Handle(
+
+ const auto& cache = MegamorphicCache::Handle(
zone, MegamorphicCacheTable::Lookup(thread, name, descriptor));
- SafepointMutexLocker ml(thread->isolate()->megamorphic_mutex());
- MegamorphicCacheEntries entries(Array::Handle(zone, cache.buckets()));
- for (intptr_t i = 0, n = entries.Length(); i < n; i++) {
- const intptr_t id =
- Smi::Value(entries[i].Get<MegamorphicCache::kClassIdIndex>());
- if (id == kIllegalCid) {
- continue;
+ {
+ SafepointMutexLocker ml(thread->isolate()->type_feedback_mutex());
+ MegamorphicCacheEntries entries(Array::Handle(zone, cache.buckets()));
+ for (intptr_t i = 0, n = entries.Length(); i < n; i++) {
+ const intptr_t id =
+ Smi::Value(entries[i].Get<MegamorphicCache::kClassIdIndex>());
+ if (id == kIllegalCid) {
+ continue;
+ }
+ Function& function = Function::ZoneHandle(zone);
+ function ^= entries[i].Get<MegamorphicCache::kTargetFunctionIndex>();
+ const intptr_t filled_entry_count = cache.filled_entry_count();
+ ASSERT(filled_entry_count > 0);
+ cid_ranges_.Add(new (zone) TargetInfo(
+ id, id, &function, Usage(function) / filled_entry_count,
+ StaticTypeExactnessState::NotTracking()));
}
- Function& function = Function::ZoneHandle(zone);
- function ^= entries[i].Get<MegamorphicCache::kTargetFunctionIndex>();
- const intptr_t filled_entry_count = cache.filled_entry_count();
- ASSERT(filled_entry_count > 0);
- cid_ranges_.Add(new (zone) TargetInfo(
- id, id, &function, Usage(function) / filled_entry_count,
- StaticTypeExactnessState::NotTracking()));
}
}
}
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 2fe5ead..3849287 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -359,6 +359,8 @@
NOT_IN_PRODUCT("IsolateGroup::type_canonicalization_mutex_")),
type_arguments_canonicalization_mutex_(NOT_IN_PRODUCT(
"IsolateGroup::type_arguments_canonicalization_mutex_")),
+ subtype_test_cache_mutex_(
+ NOT_IN_PRODUCT("IsolateGroup::subtype_test_cache_mutex_")),
program_lock_(new SafepointRwLock()),
active_mutators_monitor_(new Monitor()),
max_active_mutators_(Scavenger::MaxMutatorThreadCount()) {
@@ -1646,7 +1648,9 @@
mutex_(NOT_IN_PRODUCT("Isolate::mutex_")),
constant_canonicalization_mutex_(
NOT_IN_PRODUCT("Isolate::constant_canonicalization_mutex_")),
- megamorphic_mutex_(NOT_IN_PRODUCT("Isolate::megamorphic_mutex_")),
+ megamorphic_table_mutex_(
+ NOT_IN_PRODUCT("Isolate::megamorphic_table_mutex_")),
+ type_feedback_mutex_(NOT_IN_PRODUCT("Isolate::type_feedback_mutex_")),
kernel_data_lib_cache_mutex_(
NOT_IN_PRODUCT("Isolate::kernel_data_lib_cache_mutex_")),
kernel_data_class_cache_mutex_(
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 8407f4f..77991a9 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -964,7 +964,8 @@
Mutex* constant_canonicalization_mutex() {
return &constant_canonicalization_mutex_;
}
- Mutex* megamorphic_mutex() { return &megamorphic_mutex_; }
+ Mutex* megamorphic_table_mutex() { return &megamorphic_table_mutex_; }
+ Mutex* type_feedback_mutex() { return &type_feedback_mutex_; }
Mutex* kernel_data_lib_cache_mutex() { return &kernel_data_lib_cache_mutex_; }
Mutex* kernel_data_class_cache_mutex() {
@@ -1600,8 +1601,8 @@
Simulator* simulator_ = nullptr;
Mutex mutex_; // Protects compiler stats.
Mutex constant_canonicalization_mutex_; // Protects const canonicalization.
- Mutex megamorphic_mutex_; // Protects the table of megamorphic caches and
- // their entries.
+ Mutex megamorphic_table_mutex_;
+ Mutex type_feedback_mutex_;
Mutex kernel_data_lib_cache_mutex_;
Mutex kernel_data_class_cache_mutex_;
Mutex kernel_constants_mutex_;
diff --git a/runtime/vm/lockers.cc b/runtime/vm/lockers.cc
index 7ad731d..cb04006 100644
--- a/runtime/vm/lockers.cc
+++ b/runtime/vm/lockers.cc
@@ -40,7 +40,8 @@
return result;
}
-SafepointMutexLocker::SafepointMutexLocker(Mutex* mutex) : mutex_(mutex) {
+SafepointMutexLocker::SafepointMutexLocker(ThreadState* thread, Mutex* mutex)
+ : StackResource(thread), mutex_(mutex) {
ASSERT(mutex != NULL);
if (!mutex_->TryLock()) {
// We did not get the lock and could potentially block, so transition
diff --git a/runtime/vm/lockers.h b/runtime/vm/lockers.h
index 94a8070..d5b2576 100644
--- a/runtime/vm/lockers.h
+++ b/runtime/vm/lockers.h
@@ -226,9 +226,11 @@
* ...
* }
*/
-class SafepointMutexLocker : public ValueObject {
+class SafepointMutexLocker : public StackResource {
public:
- explicit SafepointMutexLocker(Mutex* mutex);
+ explicit SafepointMutexLocker(Mutex* mutex)
+ : SafepointMutexLocker(ThreadState::Current(), mutex) {}
+ SafepointMutexLocker(ThreadState* thread, Mutex* mutex);
virtual ~SafepointMutexLocker() { mutex_->Unlock(); }
private:
diff --git a/runtime/vm/megamorphic_cache_table.cc b/runtime/vm/megamorphic_cache_table.cc
index 04a4acd..7a1b7f6 100644
--- a/runtime/vm/megamorphic_cache_table.cc
+++ b/runtime/vm/megamorphic_cache_table.cc
@@ -17,13 +17,13 @@
const String& name,
const Array& descriptor) {
Isolate* isolate = thread->isolate();
- // Multiple compilation threads could access this lookup.
- SafepointMutexLocker ml(isolate->megamorphic_mutex());
+ SafepointMutexLocker ml(isolate->megamorphic_table_mutex());
+
ASSERT(name.IsSymbol());
// TODO(rmacnak): ASSERT(descriptor.IsCanonical());
// TODO(rmacnak): Make a proper hashtable a la symbol table.
- GrowableObjectArray& table = GrowableObjectArray::Handle(
+ auto& table = GrowableObjectArray::Handle(
isolate->object_store()->megamorphic_cache_table());
MegamorphicCache& cache = MegamorphicCache::Handle();
if (table.IsNull()) {
@@ -45,7 +45,10 @@
}
void MegamorphicCacheTable::PrintSizes(Isolate* isolate) {
- StackZone zone(Thread::Current());
+ auto thread = Thread::Current();
+ SafepointMutexLocker ml(thread->isolate()->megamorphic_table_mutex());
+
+ StackZone zone(thread);
intptr_t size = 0;
MegamorphicCache& cache = MegamorphicCache::Handle();
Array& buckets = Array::Handle();
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 160aa54..3f6ff74 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -15123,8 +15123,8 @@
intptr_t ICData::FindCheck(const GrowableArray<intptr_t>& cids) const {
const intptr_t len = NumberOfChecks();
+ GrowableArray<intptr_t> class_ids;
for (intptr_t i = 0; i < len; i++) {
- GrowableArray<intptr_t> class_ids;
GetClassIdsAt(i, &class_ids);
bool matches = true;
for (intptr_t k = 0; k < class_ids.length(); k++) {
@@ -15236,9 +15236,27 @@
return true;
}
+void ICData::EnsureHasCheck(const GrowableArray<intptr_t>& class_ids,
+ const Function& target,
+ intptr_t count) const {
+ SafepointMutexLocker ml(Isolate::Current()->type_feedback_mutex());
+
+ if (FindCheck(class_ids) != -1) return;
+ AddCheckInternal(class_ids, target, count);
+}
+
void ICData::AddCheck(const GrowableArray<intptr_t>& class_ids,
const Function& target,
intptr_t count) const {
+ SafepointMutexLocker ml(Isolate::Current()->type_feedback_mutex());
+ AddCheckInternal(class_ids, target, count);
+}
+
+void ICData::AddCheckInternal(const GrowableArray<intptr_t>& class_ids,
+ const Function& target,
+ intptr_t count) const {
+ ASSERT(Isolate::Current()->type_feedback_mutex()->IsOwnedByCurrentThread());
+
ASSERT(!is_tracking_exactness());
ASSERT(!target.IsNull());
ASSERT((target.name() == target_name()) || ValidateInterceptor(target));
@@ -15321,10 +15339,32 @@
}
}
+void ICData::EnsureHasReceiverCheck(intptr_t receiver_class_id,
+ const Function& target,
+ intptr_t count,
+ StaticTypeExactnessState exactness) const {
+ SafepointMutexLocker ml(Isolate::Current()->type_feedback_mutex());
+
+ GrowableArray<intptr_t> class_ids(1);
+ class_ids.Add(receiver_class_id);
+ if (FindCheck(class_ids) != -1) return;
+
+ AddReceiverCheckInternal(receiver_class_id, target, count, exactness);
+}
+
void ICData::AddReceiverCheck(intptr_t receiver_class_id,
const Function& target,
intptr_t count,
StaticTypeExactnessState exactness) const {
+ SafepointMutexLocker ml(Isolate::Current()->type_feedback_mutex());
+ AddReceiverCheckInternal(receiver_class_id, target, count, exactness);
+}
+
+void ICData::AddReceiverCheckInternal(
+ intptr_t receiver_class_id,
+ const Function& target,
+ intptr_t count,
+ StaticTypeExactnessState exactness) const {
#if defined(DEBUG)
GrowableArray<intptr_t> class_ids(1);
class_ids.Add(receiver_class_id);
@@ -15566,8 +15606,9 @@
result.IncrementCountAt(duplicate_class_id, count);
} else {
// This will make sure that Smi is first if it exists.
- result.AddReceiverCheck(class_id, Function::Handle(GetTargetAt(i)),
- count);
+ result.AddReceiverCheckInternal(class_id,
+ Function::Handle(GetTargetAt(i)), count,
+ StaticTypeExactnessState::NotTracking());
}
}
@@ -17131,14 +17172,78 @@
return result.raw();
}
-void MegamorphicCache::Insert(const Smi& class_id, const Object& target) const {
- SafepointMutexLocker ml(Isolate::Current()->megamorphic_mutex());
- EnsureCapacityLocked();
- InsertLocked(class_id, target);
+void MegamorphicCache::EnsureContains(const Smi& class_id,
+ const Object& target) const {
+ SafepointMutexLocker ml(Isolate::Current()->type_feedback_mutex());
+
+ if (LookupLocked(class_id) == Object::null()) {
+ InsertLocked(class_id, target);
+ }
+
+#if defined(DEBUG)
+ if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
+ if (target.IsFunction()) {
+ const auto& function = Function::Cast(target);
+ const auto& entry_point = Smi::Handle(
+ Smi::FromAlignedAddress(Code::EntryPointOf(function.CurrentCode())));
+ ASSERT(LookupLocked(class_id) == entry_point.raw());
+ }
+ } else {
+ ASSERT(LookupLocked(class_id) == target.raw());
+ }
+#endif // define(DEBUG)
+}
+
+ObjectPtr MegamorphicCache::Lookup(const Smi& class_id) const {
+ SafepointMutexLocker ml(Isolate::Current()->type_feedback_mutex());
+ return LookupLocked(class_id);
+}
+
+ObjectPtr MegamorphicCache::LookupLocked(const Smi& class_id) const {
+ auto thread = Thread::Current();
+ auto zone = thread->zone();
+ ASSERT(thread->IsMutatorThread());
+ ASSERT(thread->isolate()->type_feedback_mutex()->IsOwnedByCurrentThread());
+
+ const auto& backing_array = Array::Handle(zone, buckets());
+ intptr_t id_mask = mask();
+ intptr_t index = (class_id.Value() * kSpreadFactor) & id_mask;
+ intptr_t i = index;
+ do {
+ const classid_t current_cid =
+ Smi::Value(Smi::RawCast(GetClassId(backing_array, i)));
+ if (current_cid == class_id.Value()) {
+ return GetTargetFunction(backing_array, i);
+ } else if (current_cid == kIllegalCid) {
+ return Object::null();
+ }
+ i = (i + 1) & id_mask;
+ } while (i != index);
+ UNREACHABLE();
+}
+
+void MegamorphicCache::InsertLocked(const Smi& class_id,
+ const Object& target) const {
+ auto isolate_group = IsolateGroup::Current();
+ ASSERT(Isolate::Current()->type_feedback_mutex()->IsOwnedByCurrentThread());
+
+ // As opposed to ICData we are stopping mutator threads from other isolates
+ // while modifying the megamorphic cache, since updates are not atomic.
+ //
+ // NOTE: In the future we might change the megamorphic cache insertions to
+ // carefully use store-release barriers on the writer as well as
+ // load-acquire barriers on the reader, ...
+ isolate_group->RunWithStoppedMutators(
+ [&]() {
+ EnsureCapacityLocked();
+ InsertEntryLocked(class_id, target);
+ },
+ /*use_force_growth=*/true);
}
void MegamorphicCache::EnsureCapacityLocked() const {
- ASSERT(Isolate::Current()->megamorphic_mutex()->IsOwnedByCurrentThread());
+ ASSERT(Isolate::Current()->type_feedback_mutex()->IsOwnedByCurrentThread());
+
intptr_t old_capacity = mask() + 1;
double load_limit = kLoadFactor * static_cast<double>(old_capacity);
if (static_cast<double>(filled_entry_count() + 1) > load_limit) {
@@ -17161,15 +17266,16 @@
class_id ^= GetClassId(old_buckets, i);
if (class_id.Value() != kIllegalCid) {
target = GetTargetFunction(old_buckets, i);
- InsertLocked(class_id, target);
+ InsertEntryLocked(class_id, target);
}
}
}
}
-void MegamorphicCache::InsertLocked(const Smi& class_id,
- const Object& target) const {
- ASSERT(Isolate::Current()->megamorphic_mutex()->IsOwnedByCurrentThread());
+void MegamorphicCache::InsertEntryLocked(const Smi& class_id,
+ const Object& target) const {
+ ASSERT(Isolate::Current()->type_feedback_mutex()->IsOwnedByCurrentThread());
+
ASSERT(Thread::Current()->IsMutatorThread());
ASSERT(static_cast<double>(filled_entry_count() + 1) <=
(kLoadFactor * static_cast<double>(mask() + 1)));
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 3c70ead..ada80f9 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -2088,6 +2088,15 @@
// Adding checks.
+ // Ensures there is a check for [class_ids].
+ //
+ // Calls [AddCheck] iff there is no existing check. Ensures test (and
+ // potential update) will be performed under exclusive lock to guard against
+ // multiple threads trying to add the same check.
+ void EnsureHasCheck(const GrowableArray<intptr_t>& class_ids,
+ const Function& target,
+ intptr_t count = 1) const;
+
// Adds one more class test to ICData. Length of 'classes' must be equal to
// the number of arguments tested. Use only for num_args_tested > 1.
void AddCheck(const GrowableArray<intptr_t>& class_ids,
@@ -2096,6 +2105,18 @@
StaticTypeExactnessState GetExactnessAt(intptr_t count) const;
+ // Ensures there is a receiver check for [receiver_class_id].
+ //
+ // Calls [AddCheckReceiverCheck] iff there is no existing check. Ensures
+ // test (and potential update) will be performed under exclusive lock to
+ // guard against multiple threads trying to add the same check.
+ void EnsureHasReceiverCheck(
+ intptr_t receiver_class_id,
+ const Function& target,
+ intptr_t count = 1,
+ StaticTypeExactnessState exactness =
+ StaticTypeExactnessState::NotTracking()) const;
+
// Adds sorted so that Smi is the first class-id. Use only for
// num_args_tested == 1.
void AddReceiverCheck(intptr_t receiver_class_id,
@@ -2262,6 +2283,13 @@
intptr_t data_pos,
intptr_t num_args_tested,
const Function& target);
+ void AddCheckInternal(const GrowableArray<intptr_t>& class_ids,
+ const Function& target,
+ intptr_t count) const;
+ void AddReceiverCheckInternal(intptr_t receiver_class_id,
+ const Function& target,
+ intptr_t count,
+ StaticTypeExactnessState exactness) const;
// This bit is set when a call site becomes megamorphic and starts using a
// MegamorphicCache instead of ICData. It means that the entries in the
@@ -6822,7 +6850,8 @@
static MegamorphicCachePtr New(const String& target_name,
const Array& arguments_descriptor);
- void Insert(const Smi& class_id, const Object& target) const;
+ void EnsureContains(const Smi& class_id, const Object& target) const;
+ ObjectPtr Lookup(const Smi& class_id) const;
void SwitchToBareInstructions();
@@ -6830,8 +6859,6 @@
return RoundedAllocationSize(sizeof(MegamorphicCacheLayout));
}
- static MegamorphicCachePtr Clone(const MegamorphicCache& from);
-
private:
friend class Class;
friend class MegamorphicCacheTable;
@@ -6839,9 +6866,12 @@
static MegamorphicCachePtr New();
- // The caller must hold Isolate::megamorphic_mutex().
- void EnsureCapacityLocked() const;
+ // The caller must hold IsolateGroup::type_feedback_mutex().
void InsertLocked(const Smi& class_id, const Object& target) const;
+ void EnsureCapacityLocked() const;
+ ObjectPtr LookupLocked(const Smi& class_id) const;
+
+ void InsertEntryLocked(const Smi& class_id, const Object& target) const;
static inline void SetEntry(const Array& array,
intptr_t index,
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 94e3747..ccd43d8 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -3226,6 +3226,57 @@
EXPECT_EQ(Bool::True().raw(), test_result.raw());
}
+ISOLATE_UNIT_TEST_CASE(MegamorphicCache) {
+ const auto& name = String::Handle(String::New("name"));
+ const auto& args_descriptor =
+ Array::Handle(ArgumentsDescriptor::NewBoxed(1, 1, Object::null_array()));
+
+ const auto& cidA = Smi::Handle(Smi::New(1));
+ const auto& cidB = Smi::Handle(Smi::New(2));
+
+ const auto& valueA = Smi::Handle(Smi::New(42));
+ const auto& valueB = Smi::Handle(Smi::New(43));
+
+ // Test normal insert/lookup methods.
+ {
+ const auto& cache =
+ MegamorphicCache::Handle(MegamorphicCache::New(name, args_descriptor));
+
+ EXPECT(cache.Lookup(cidA) == Object::null());
+ cache.EnsureContains(cidA, valueA);
+ EXPECT(cache.Lookup(cidA) == valueA.raw());
+
+ EXPECT(cache.Lookup(cidB) == Object::null());
+ cache.EnsureContains(cidB, valueB);
+ EXPECT(cache.Lookup(cidB) == valueB.raw());
+ }
+
+ // Try to insert many keys to hit collisions & growth.
+ {
+ const auto& cache =
+ MegamorphicCache::Handle(MegamorphicCache::New(name, args_descriptor));
+
+ auto& cid = Smi::Handle();
+ auto& value = Object::Handle();
+ for (intptr_t i = 0; i < 100; ++i) {
+ cid = Smi::New(100 * i);
+ if (cid.Value() == kIllegalCid) continue;
+
+ value = Smi::New(i);
+ cache.EnsureContains(cid, value);
+ }
+ auto& expected = Object::Handle();
+ for (intptr_t i = 0; i < 100; ++i) {
+ cid = Smi::New(100 * i);
+ if (cid.Value() == kIllegalCid) continue;
+
+ expected = Smi::New(i);
+ value = cache.Lookup(cid);
+ EXPECT(Smi::Cast(value).Equals(Smi::Cast(expected)));
+ }
+ }
+}
+
ISOLATE_UNIT_TEST_CASE(FieldTests) {
const String& f = String::Handle(String::New("oneField"));
const String& getter_f = String::Handle(Field::GetterName(f));
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index 8ef9463..b5f1d00 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -1267,30 +1267,27 @@
const Instance& receiver = *args[0];
if (args.length() == 1) {
+ auto exactness = StaticTypeExactnessState::NotTracking();
if (ic_data.is_tracking_exactness()) {
#if !defined(DART_PRECOMPILED_RUNTIME)
- const auto state = receiver.IsNull()
- ? StaticTypeExactnessState::NotExact()
- : StaticTypeExactnessState::Compute(
- Type::Cast(AbstractType::Handle(
- ic_data.receivers_static_type())),
- receiver);
- ic_data.AddReceiverCheck(
- receiver.GetClassId(), target_function, count,
- /*exactness=*/state.CollapseSuperTypeExactness());
+ exactness = receiver.IsNull() ? StaticTypeExactnessState::NotExact()
+ : StaticTypeExactnessState::Compute(
+ Type::Cast(AbstractType::Handle(
+ ic_data.receivers_static_type())),
+ receiver);
#else
UNREACHABLE();
#endif
- } else {
- ic_data.AddReceiverCheck(args[0]->GetClassId(), target_function, count);
}
+ ic_data.EnsureHasReceiverCheck(receiver.GetClassId(), target_function,
+ count, exactness);
} else {
GrowableArray<intptr_t> class_ids(args.length());
ASSERT(ic_data.NumArgsTested() == args.length());
for (intptr_t i = 0; i < args.length(); i++) {
class_ids.Add(args[i]->GetClassId());
}
- ic_data.AddCheck(class_ids, target_function, count);
+ ic_data.EnsureHasCheck(class_ids, target_function, count);
}
if (FLAG_trace_ic_miss_in_optimized || FLAG_trace_ic) {
DartFrameIterator iterator(Thread::Current(),
@@ -1322,8 +1319,7 @@
static FunctionPtr InlineCacheMissHandler(
const GrowableArray<const Instance*>& args, // Checked arguments only.
- const ICData& ic_data,
- intptr_t count = 1) {
+ const ICData& ic_data) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
@@ -1365,7 +1361,7 @@
return target_function.raw();
}
- return InlineCacheMissHandlerGivenTargetFunction(args, ic_data, count,
+ return InlineCacheMissHandlerGivenTargetFunction(args, ic_data, 1,
target_function);
}
@@ -1416,7 +1412,7 @@
const Function& target = Function::Handle(zone, ic_data.GetTargetAt(0));
target.EnsureHasCode();
ASSERT(!target.IsNull() && target.HasCode());
- ic_data.AddReceiverCheck(arg.GetClassId(), target, 1);
+ ic_data.EnsureHasReceiverCheck(arg.GetClassId(), target, 1);
if (FLAG_trace_ic) {
DartFrameIterator iterator(thread,
StackFrameIterator::kNoCrossThreadIteration);
@@ -1444,7 +1440,7 @@
GrowableArray<intptr_t> cids(2);
cids.Add(arg0.GetClassId());
cids.Add(arg1.GetClassId());
- ic_data.AddCheck(cids, target);
+ ic_data.EnsureHasCheck(cids, target);
if (FLAG_trace_ic) {
DartFrameIterator iterator(thread,
StackFrameIterator::kNoCrossThreadIteration);
@@ -1945,7 +1941,7 @@
// Insert function found into cache.
const Smi& class_id = Smi::Handle(zone_, Smi::New(cls.id()));
- data.Insert(class_id, target_function);
+ data.EnsureContains(class_id, target_function);
arguments_.SetArgAt(0, StubCode::MegamorphicCall());
arguments_.SetReturn(data);
}
diff --git a/runtime/vm/thread_test.cc b/runtime/vm/thread_test.cc
index aaedbb7..95a0839 100644
--- a/runtime/vm/thread_test.cc
+++ b/runtime/vm/thread_test.cc
@@ -1029,6 +1029,38 @@
EXPECT(!lock.IsCurrentThreadWriter());
}
+template <typename LockType, typename LockerType>
+static void RunLockerWithLongJumpTest() {
+ const intptr_t kNumIterations = 5;
+ intptr_t execution_count = 0;
+ intptr_t thrown_count = 0;
+ LockType lock;
+ for (intptr_t i = 0; i < kNumIterations; ++i) {
+ LongJumpScope jump;
+ if (setjmp(*jump.Set()) == 0) {
+ LockerType locker(Thread::Current(), &lock);
+ execution_count++;
+ Thread::Current()->long_jump_base()->Jump(
+ 1, Object::background_compilation_error());
+ } else {
+ thrown_count++;
+ }
+ }
+ EXPECT_EQ(kNumIterations, execution_count);
+ EXPECT_EQ(kNumIterations, thrown_count);
+}
+ISOLATE_UNIT_TEST_CASE(SafepointRwLockWriteWithLongJmp) {
+ RunLockerWithLongJumpTest<SafepointRwLock, SafepointWriteRwLocker>();
+}
+
+ISOLATE_UNIT_TEST_CASE(SafepointRwLockReadWithLongJmp) {
+ RunLockerWithLongJumpTest<SafepointRwLock, SafepointReadRwLocker>();
+}
+
+ISOLATE_UNIT_TEST_CASE(SafepointMutexLockerWithLongJmp) {
+ RunLockerWithLongJumpTest<Mutex, SafepointMutexLocker>();
+}
+
struct ReaderThreadState {
ThreadJoinId reader_id = OSThread::kInvalidThreadJoinId;
SafepointRwLock* rw_lock = nullptr;
diff --git a/sdk/lib/_internal/js_runtime/lib/core_patch.dart b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
index 2b48b5d..1cd3bc4 100644
--- a/sdk/lib/_internal/js_runtime/lib/core_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
@@ -26,7 +26,7 @@
getTraceFromException,
RuntimeError;
-import 'dart:_foreign_helper' show JS, JS_GET_FLAG;
+import 'dart:_foreign_helper' show JS;
import 'dart:_native_typed_data' show NativeUint8List;
import 'dart:_rti' show getRuntimeType;
@@ -459,9 +459,15 @@
assertUnreachable();
}
+ factory List._ofArray(Iterable<E> elements) {
+ return JSArray<E>.markGrowable(
+ JS('effects:none;depends:no-static', '#.slice(0)', elements));
+ }
+
factory List._of(Iterable<E> elements) {
- // This is essentially `addAll`, but without a check for modifiability or
- // ConcurrentModificationError on the receiver.
+ if (elements is JSArray) return List._ofArray(elements);
+ // This is essentially `<E>[]..addAll(elements)`, but without a check for
+ // modifiability or ConcurrentModificationError on the receiver.
List<E> list = <E>[];
for (final e in elements) {
list.add(e);
diff --git a/sdk/lib/collection/linked_list.dart b/sdk/lib/collection/linked_list.dart
index 71e0226..6d6be81 100644
--- a/sdk/lib/collection/linked_list.dart
+++ b/sdk/lib/collection/linked_list.dart
@@ -6,7 +6,7 @@
/// A specialized double-linked list of elements that extends [LinkedListEntry].
///
-/// This is not a generic data structure. It only accepts elements that extend
+/// This is not a generic data structure. It only accepts elements that *extend*
/// the [LinkedListEntry] class. See the [Queue] implementations for generic
/// collections that allow constant time adding and removing at the ends.
///
@@ -17,6 +17,9 @@
/// Because the elements themselves contain the links of this linked list,
/// each element can be in only one list at a time. To add an element to another
/// list, it must first be removed from its current list (if any).
+/// For the same reason, the [remove] and [contains] methods
+/// are based on *identity*, even if the [LinkedListEntry] chooses
+/// to override [Object.operator==].
///
/// In return, each element knows its own place in the linked list, as well as
/// which list it is in. This allows constant time
@@ -61,6 +64,13 @@
return true;
}
+ /// Whether [entry] is a [LinkedListEntry] belonging to this list.
+ ///
+ /// The [entry] is considered as belonging to this list if
+ /// its [LinkedListEntry.list] is this list.
+ bool contains(Object? entry) =>
+ entry is LinkedListEntry && identical(this, entry.list);
+
Iterator<E> get iterator => _LinkedListIterator<E>(this);
int get length => _length;
diff --git a/tests/language/metadata/metadata_builtin_test.dart b/tests/language/metadata/metadata_builtin_test.dart
new file mode 100644
index 0000000..aceec19
--- /dev/null
+++ b/tests/language/metadata/metadata_builtin_test.dart
@@ -0,0 +1,125 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Verify that built-in identifiers can be used to specify metadata.
+
+const abstract = 0;
+const as = 0;
+const covariant = 0;
+const deferred = 0;
+const dynamic = 0;
+const export = 0;
+const external = 0;
+const factory = 0;
+const Function = 0;
+const get = 0;
+const implements = 0;
+const import = 0;
+const interface = 0;
+const late = 0;
+const library = 0;
+const mixin = 0;
+const operator = 0;
+const part = 0;
+const required = 0;
+const set = 0;
+const static = 0;
+const typedef = 0;
+
+@abstract
+@as
+@covariant
+@deferred
+@dynamic
+@export
+@external
+@factory
+@Function
+@get
+@implements
+@import
+@interface
+@late
+@library
+@mixin
+@operator
+@part
+@required
+@set
+@static
+@typedef
+void main(
+ @abstract
+ @as
+ @covariant
+ @deferred
+ @dynamic
+ @export
+ @external
+ @factory
+ @Function
+ @get
+ @implements
+ @import
+ @interface
+ @late
+ @library
+ @mixin
+ @operator
+ @part
+ @required
+ @set
+ @static
+ @typedef
+ List<String> args,
+) {
+ @abstract
+ @as
+ @covariant
+ @deferred
+ @dynamic
+ @export
+ @external
+ @factory
+ @Function
+ @get
+ @implements
+ @import
+ @interface
+ @late
+ @library
+ @mixin
+ @operator
+ @part
+ @required
+ @set
+ @static
+ @typedef
+ var x = true;
+
+ void f<
+ @abstract
+ @as
+ @covariant
+ @deferred
+ @dynamic
+ @export
+ @external
+ @factory
+ @Function
+ @get
+ @implements
+ @import
+ @interface
+ @late
+ @library
+ @mixin
+ @operator
+ @part
+ @required
+ @set
+ @static
+ @typedef
+ X>() {}
+}
diff --git a/tests/language_2/metadata/metadata_builtin_test.dart b/tests/language_2/metadata/metadata_builtin_test.dart
new file mode 100644
index 0000000..f5c346d
--- /dev/null
+++ b/tests/language_2/metadata/metadata_builtin_test.dart
@@ -0,0 +1,115 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Verify that built-in identifiers can be used to specify metadata.
+
+const abstract = 0;
+const as = 0;
+const covariant = 0;
+const deferred = 0;
+const dynamic = 0;
+const export = 0;
+const external = 0;
+const factory = 0;
+const Function = 0;
+const get = 0;
+const implements = 0;
+const import = 0;
+const interface = 0;
+const library = 0;
+const mixin = 0;
+const operator = 0;
+const part = 0;
+const set = 0;
+const static = 0;
+const typedef = 0;
+
+@abstract
+@as
+@covariant
+@deferred
+@dynamic
+@export
+@external
+@factory
+@Function
+@get
+@implements
+@import
+@interface
+@library
+@mixin
+@operator
+@part
+@set
+@static
+@typedef
+void main(
+ @abstract
+ @as
+ @covariant
+ @deferred
+ @dynamic
+ @export
+ @external
+ @factory
+ @Function
+ @get
+ @implements
+ @import
+ @interface
+ @library
+ @mixin
+ @operator
+ @part
+ @set
+ @static
+ @typedef
+ List<String> args,
+) {
+ @abstract
+ @as
+ @covariant
+ @deferred
+ @dynamic
+ @export
+ @external
+ @factory
+ @Function
+ @get
+ @implements
+ @import
+ @interface
+ @library
+ @mixin
+ @operator
+ @part
+ @set
+ @static
+ @typedef
+ var x = true;
+
+ void f<
+ @abstract
+ @as
+ @covariant
+ @deferred
+ @dynamic
+ @export
+ @external
+ @factory
+ @Function
+ @get
+ @implements
+ @import
+ @interface
+ @library
+ @mixin
+ @operator
+ @part
+ @set
+ @static
+ @typedef
+ X>() {}
+}
diff --git a/tests/lib/collection/linked_list_test.dart b/tests/lib/collection/linked_list_test.dart
index 2c06874..e2c6a7e 100644
--- a/tests/lib/collection/linked_list_test.dart
+++ b/tests/lib/collection/linked_list_test.dart
@@ -11,16 +11,19 @@
MyEntry(int this.value);
String toString() => value.toString();
+
+ int get hashCode => value.hashCode;
+ bool operator ==(Object o) => o is MyEntry && value == o.value;
}
-testPreviousNext() {
- var list = new LinkedList<MyEntry>();
+void testPreviousNext() {
+ var list = LinkedList<MyEntry>();
Expect.throws(() => list.first);
Expect.throws(() => list.last);
Expect.equals(0, list.length);
for (int i = 0; i < 3; i++) {
- list.add(new MyEntry(i));
+ list.add(MyEntry(i));
}
Expect.equals(3, list.length);
@@ -39,11 +42,11 @@
Expect.isNull(entry.previous);
}
-testUnlinked() {
- var unlinked = new MyEntry(0);
+void testUnlinked() {
+ var unlinked = MyEntry(0);
Expect.isNull(unlinked.previous);
Expect.isNull(unlinked.next);
- var list = new LinkedList<MyEntry>();
+ var list = LinkedList<MyEntry>();
list.add(unlinked);
Expect.isNull(unlinked.previous);
Expect.isNull(unlinked.next);
@@ -51,7 +54,7 @@
Expect.isNull(unlinked.previous);
Expect.isNull(unlinked.next);
list.add(unlinked);
- list.add(new MyEntry(1));
+ list.add(MyEntry(1));
Expect.isNull(unlinked.previous);
Expect.equals(1, unlinked.next!.value);
list.remove(unlinked);
@@ -62,11 +65,11 @@
Expect.equals(1, unlinked.previous!.value);
}
-testInsert() {
+void testInsert() {
// Insert last.
- var list = new LinkedList<MyEntry>();
+ var list = LinkedList<MyEntry>();
for (int i = 0; i < 10; i++) {
- list.add(new MyEntry(i));
+ list.add(MyEntry(i));
}
Expect.equals(10, list.length);
@@ -83,7 +86,7 @@
// Insert first.
for (int i = 0; i < 10; i++) {
- list.addFirst(new MyEntry(i));
+ list.addFirst(MyEntry(i));
}
Expect.equals(10, list.length);
@@ -97,9 +100,9 @@
list.clear();
// Insert after.
- list.addFirst(new MyEntry(0));
+ list.addFirst(MyEntry(0));
for (int i = 1; i < 10; i++) {
- list.last.insertAfter(new MyEntry(i));
+ list.last.insertAfter(MyEntry(i));
}
Expect.equals(10, list.length);
@@ -115,9 +118,9 @@
list.clear();
// Insert before.
- list.addFirst(new MyEntry(0));
+ list.addFirst(MyEntry(0));
for (int i = 1; i < 10; i++) {
- list.first.insertBefore(new MyEntry(i));
+ list.first.insertBefore(MyEntry(i));
}
Expect.equals(10, list.length);
@@ -131,10 +134,10 @@
list.clear();
}
-testRemove() {
- var list = new LinkedList<MyEntry>();
+void testRemove() {
+ var list = LinkedList<MyEntry>();
for (int i = 0; i < 10; i++) {
- list.add(new MyEntry(i));
+ list.add(MyEntry(i));
}
Expect.equals(10, list.length);
@@ -162,21 +165,51 @@
Expect.equals(0, list.length);
}
-testBadAdd() {
- var list1 = new LinkedList<MyEntry>();
- list1.addFirst(new MyEntry(0));
+void testContains() {
+ var list = LinkedList<MyEntry>();
+ var entry5 = MyEntry(5);
- var list2 = new LinkedList<MyEntry>();
- Expect.throws(() => list2.addFirst(list1.first));
+ // Empty lists contains nothing.
+ Expect.isFalse(list.contains(null));
+ Expect.isFalse(list.contains(Object()));
+ Expect.isFalse(list.contains(entry5));
- Expect.throws(() => new MyEntry(0).unlink());
+ // Works for singleton lists.
+ list.add(MyEntry(0));
+ Expect.isTrue(list.contains(list.first));
+ Expect.isFalse(list.contains(null));
+ Expect.isFalse(list.contains(Object()));
+ Expect.isFalse(list.contains(entry5));
+
+ // Works for larger lists.
+ for (int i = 1; i < 10; i++) {
+ list.add(MyEntry(i));
+ }
+ for (var entry in list) {
+ Expect.isTrue(list.contains(entry));
+ }
+ Expect.isFalse(list.contains(Object()));
+ Expect.isFalse(list.contains(null));
+ Expect.isFalse(list.contains(entry5));
+ // Based on identity, not equality.
+ Expect.equals(entry5, list.elementAt(5));
}
-testConcurrentModificationError() {
+void testBadAdd() {
+ var list1 = LinkedList<MyEntry>();
+ list1.addFirst(MyEntry(0));
+
+ var list2 = LinkedList<MyEntry>();
+ Expect.throws(() => list2.addFirst(list1.first));
+
+ Expect.throws(() => MyEntry(0).unlink());
+}
+
+void testConcurrentModificationError() {
test(function(LinkedList<MyEntry> ll)) {
- var ll = new LinkedList<MyEntry>();
+ var ll = LinkedList<MyEntry>();
for (int i = 0; i < 10; i++) {
- ll.add(new MyEntry(i));
+ ll.add(MyEntry(i));
}
Expect.throws(() => function(ll), (e) => e is ConcurrentModificationError);
}
@@ -269,11 +302,12 @@
});
}
-main() {
+void main() {
testPreviousNext();
testUnlinked();
testInsert();
testRemove();
+ testContains();
testBadAdd();
testConcurrentModificationError();
}
diff --git a/tests/lib_2/collection/linked_list_test.dart b/tests/lib_2/collection/linked_list_test.dart
index 03e01bb..dd73a0a 100644
--- a/tests/lib_2/collection/linked_list_test.dart
+++ b/tests/lib_2/collection/linked_list_test.dart
@@ -11,16 +11,19 @@
MyEntry(int this.value);
String toString() => value.toString();
+
+ int get hashCode => value.hashCode;
+ bool operator ==(Object o) => o is MyEntry && value == o.value;
}
-testPreviousNext() {
- var list = new LinkedList<MyEntry>();
+void testPreviousNext() {
+ var list = LinkedList<MyEntry>();
Expect.throws(() => list.first);
Expect.throws(() => list.last);
Expect.equals(0, list.length);
for (int i = 0; i < 3; i++) {
- list.add(new MyEntry(i));
+ list.add(MyEntry(i));
}
Expect.equals(3, list.length);
@@ -39,11 +42,11 @@
Expect.isNull(entry.previous);
}
-testUnlinked() {
- var unlinked = new MyEntry(0);
+void testUnlinked() {
+ var unlinked = MyEntry(0);
Expect.isNull(unlinked.previous);
Expect.isNull(unlinked.next);
- var list = new LinkedList<MyEntry>();
+ var list = LinkedList<MyEntry>();
list.add(unlinked);
Expect.isNull(unlinked.previous);
Expect.isNull(unlinked.next);
@@ -51,7 +54,7 @@
Expect.isNull(unlinked.previous);
Expect.isNull(unlinked.next);
list.add(unlinked);
- list.add(new MyEntry(1));
+ list.add(MyEntry(1));
Expect.isNull(unlinked.previous);
Expect.equals(1, unlinked.next.value);
list.remove(unlinked);
@@ -62,11 +65,11 @@
Expect.equals(1, unlinked.previous.value);
}
-testInsert() {
+void testInsert() {
// Insert last.
- var list = new LinkedList<MyEntry>();
+ var list = LinkedList<MyEntry>();
for (int i = 0; i < 10; i++) {
- list.add(new MyEntry(i));
+ list.add(MyEntry(i));
}
Expect.equals(10, list.length);
@@ -83,7 +86,7 @@
// Insert first.
for (int i = 0; i < 10; i++) {
- list.addFirst(new MyEntry(i));
+ list.addFirst(MyEntry(i));
}
Expect.equals(10, list.length);
@@ -97,9 +100,9 @@
list.clear();
// Insert after.
- list.addFirst(new MyEntry(0));
+ list.addFirst(MyEntry(0));
for (int i = 1; i < 10; i++) {
- list.last.insertAfter(new MyEntry(i));
+ list.last.insertAfter(MyEntry(i));
}
Expect.equals(10, list.length);
@@ -115,9 +118,9 @@
list.clear();
// Insert before.
- list.addFirst(new MyEntry(0));
+ list.addFirst(MyEntry(0));
for (int i = 1; i < 10; i++) {
- list.first.insertBefore(new MyEntry(i));
+ list.first.insertBefore(MyEntry(i));
}
Expect.equals(10, list.length);
@@ -131,10 +134,10 @@
list.clear();
}
-testRemove() {
- var list = new LinkedList<MyEntry>();
+void testRemove() {
+ var list = LinkedList<MyEntry>();
for (int i = 0; i < 10; i++) {
- list.add(new MyEntry(i));
+ list.add(MyEntry(i));
}
Expect.equals(10, list.length);
@@ -162,21 +165,51 @@
Expect.equals(0, list.length);
}
-testBadAdd() {
- var list1 = new LinkedList<MyEntry>();
- list1.addFirst(new MyEntry(0));
+void testContains() {
+ var list = LinkedList<MyEntry>();
+ var entry5 = MyEntry(5);
- var list2 = new LinkedList<MyEntry>();
- Expect.throws(() => list2.addFirst(list1.first));
+ // Empty lists contains nothing.
+ Expect.isFalse(list.contains(null));
+ Expect.isFalse(list.contains(Object()));
+ Expect.isFalse(list.contains(entry5));
- Expect.throws(() => new MyEntry(0).unlink());
+ // Works for singleton lists.
+ list.add(MyEntry(0));
+ Expect.isTrue(list.contains(list.first));
+ Expect.isFalse(list.contains(null));
+ Expect.isFalse(list.contains(Object()));
+ Expect.isFalse(list.contains(entry5));
+
+ // Works for larger lists.
+ for (int i = 1; i < 10; i++) {
+ list.add(MyEntry(i));
+ }
+ for (var entry in list) {
+ Expect.isTrue(list.contains(entry));
+ }
+ Expect.isFalse(list.contains(Object()));
+ Expect.isFalse(list.contains(null));
+ Expect.isFalse(list.contains(entry5));
+ // Based on identity, not equality.
+ Expect.isTrue(list.elementAt(5) == entry5);
}
-testConcurrentModificationError() {
+void testBadAdd() {
+ var list1 = LinkedList<MyEntry>();
+ list1.addFirst(MyEntry(0));
+
+ var list2 = LinkedList<MyEntry>();
+ Expect.throws(() => list2.addFirst(list1.first));
+
+ Expect.throws(() => MyEntry(0).unlink());
+}
+
+void testConcurrentModificationError() {
test(function(LinkedList<MyEntry> ll)) {
- var ll = new LinkedList<MyEntry>();
+ var ll = LinkedList<MyEntry>();
for (int i = 0; i < 10; i++) {
- ll.add(new MyEntry(i));
+ ll.add(MyEntry(i));
}
Expect.throws(() => function(ll), (e) => e is ConcurrentModificationError);
}
@@ -269,11 +302,12 @@
});
}
-main() {
+void main() {
testPreviousNext();
testUnlinked();
testInsert();
testRemove();
+ testContains();
testBadAdd();
testConcurrentModificationError();
}
diff --git a/tests/standalone/io/https_connection_closed_during_handshake_test.dart b/tests/standalone/io/https_connection_closed_during_handshake_test.dart
new file mode 100644
index 0000000..eed79c2
--- /dev/null
+++ b/tests/standalone/io/https_connection_closed_during_handshake_test.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--long-ssl-cert-evaluation
+
+// This test verifies that lost of connection during handshake doesn't cause
+// vm crashes.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+
+import "package:expect/expect.dart";
+
+String getFilename(String path) => Platform.script.resolve(path).toFilePath();
+
+final SecurityContext serverSecurityContext = () {
+ final context = SecurityContext();
+ context
+ .usePrivateKeyBytes(File(getFilename('localhost.key')).readAsBytesSync());
+ context.useCertificateChainBytes(
+ File(getFilename('localhost.crt')).readAsBytesSync());
+ return context;
+}();
+
+final SecurityContext clientSecurityContext = () {
+ final context = SecurityContext(withTrustedRoots: true);
+ context.setTrustedCertificatesBytes(
+ File(getFilename('localhost.crt')).readAsBytesSync());
+ return context;
+}();
+
+void main(List<String> args) async {
+ if (args.length >= 1 && args[0] == 'server') {
+ final server =
+ await SecureServerSocket.bind('localhost', 0, serverSecurityContext);
+ print('ok ${server.port}');
+ server.listen((socket) {
+ print('server: got connection');
+ socket.close();
+ });
+ await Future.delayed(Duration(seconds: 2));
+ print('server: exiting');
+ exit(1);
+ }
+
+ final serverProcess = await Process.start(
+ Platform.executable, [Platform.script.toFilePath(), 'server']);
+ final serverPortCompleter = Completer<int>();
+
+ serverProcess.stdout
+ .transform(utf8.decoder)
+ .transform(LineSplitter())
+ .listen((line) {
+ print('server stdout: $line');
+ if (line.startsWith('ok')) {
+ serverPortCompleter.complete(int.parse(line.substring('ok'.length)));
+ }
+ });
+ serverProcess.stderr
+ .transform(utf8.decoder)
+ .transform(LineSplitter())
+ .listen((line) => print('server stderr: $line'));
+
+ int port = await serverPortCompleter.future;
+
+ var thrownException;
+ try {
+ print('client connecting...');
+ await SecureSocket.connect('localhost', port,
+ context: clientSecurityContext);
+ print('client connected.');
+ } catch (e) {
+ thrownException = e;
+ } finally {
+ await serverProcess.kill();
+ }
+ print('thrownException: $thrownException');
+ Expect.isTrue(thrownException is HandshakeException);
+}
diff --git a/tests/standalone/io/localhost.crt b/tests/standalone/io/localhost.crt
new file mode 100644
index 0000000..eeab890
--- /dev/null
+++ b/tests/standalone/io/localhost.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDNjCCAh6gAwIBAgIUe+E1Xth9TMlsYY7qmf9zlfC1Ms0wDQYJKoZIhvcNAQEL
+BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MCAXDTE4MTIzMTIzMDAxMVoYDzIxMTgx
+MjA3MjMwMDExWjAUMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQDEEY2eWBX1rTDgsAWheltKiAHREteaqX4iaGwF6/TC
+6kMJajZQreySsib+lQ+FTLtMlPWorR5jMfsA6PDocRpK2zOObTqdVqJAiodUi0ov
+ds7wgaN7XnUfpPo8NDMA2tV8Bn2mfKWgC3QkUMPCDBkLqiYUuR6j5QJ4Vz2OFV5g
+1iR1HzgQgr4pbNjkUJJesr0r1J1a25YbYdLIvzss+aHBTWD+9HYfgWsfJGI3UFgc
+zoAJbKSIHYqDGsSKZMgmtixyyEjTDc6OAqjk10jhYdxdglXpTPOWP5YnwWsy8VbU
+1ozu93LlWkbbef95FD/XGH/ynglIe1laZwEXdyxOzT3bAgMBAAGjfjB8MB0GA1Ud
+DgQWBBS/3CUrYgiD2qwdEDStghi+X3+4pzAfBgNVHSMEGDAWgBS/3CUrYgiD2qwd
+EDStghi+X3+4pzAPBgNVHRMBAf8EBTADAQH/MBMGA1UdJQQMMAoGCCsGAQUFBwMB
+MBQGA1UdEQQNMAuCCWxvY2FsaG9zdDANBgkqhkiG9w0BAQsFAAOCAQEAu5adpS/h
+bWXYaDLW5JGZAiOVVkMDhspJDdPwDHUTqMPj3V6aaecZTc46Q7TLEkLxIjU5OjvR
+ZHh3vo9X4S84Yf7NHv8eX50MK/RrzZolUROhZ6gtYZKkdZtjQKQd62ih5EB6gNnZ
++IW9nedg7Sae2Yh22jDC9Tc+dbvroOd7IUwL9gVSCcwiqVjvuWkDa7jqjnRp4sog
+yY1Obr14tmUMgR73Db7q3g0cVToztLYIMJnhjiSUs8nk83m/9/O4SGqQmievoZ5N
+60OlhU6enfFoj1xKpXWSGv6mqqdX0G9Ehz1EIetFhkBK2pP/R00gf4OMKc4ubw8d
+yTSUIeMSOo0QjA==
+-----END CERTIFICATE-----
diff --git a/tests/standalone/io/localhost.key b/tests/standalone/io/localhost.key
new file mode 100644
index 0000000..20815e4
--- /dev/null
+++ b/tests/standalone/io/localhost.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDEEY2eWBX1rTDg
+sAWheltKiAHREteaqX4iaGwF6/TC6kMJajZQreySsib+lQ+FTLtMlPWorR5jMfsA
+6PDocRpK2zOObTqdVqJAiodUi0ovds7wgaN7XnUfpPo8NDMA2tV8Bn2mfKWgC3Qk
+UMPCDBkLqiYUuR6j5QJ4Vz2OFV5g1iR1HzgQgr4pbNjkUJJesr0r1J1a25YbYdLI
+vzss+aHBTWD+9HYfgWsfJGI3UFgczoAJbKSIHYqDGsSKZMgmtixyyEjTDc6OAqjk
+10jhYdxdglXpTPOWP5YnwWsy8VbU1ozu93LlWkbbef95FD/XGH/ynglIe1laZwEX
+dyxOzT3bAgMBAAECggEAHGsa5reHv0syCW8Z8dTFRKE/+ijL/UvRz3TpK1aO7G19
+9/BgHQOIhZ6yzjWWwVBk2W3ByYgGHoSRCAm7WUWDdRQefedRFpsG+2nYwaVKxGRp
+DC0OIASJ32NPLci3F8mgJdDfB3GLpA3k8JqQNSEBxFIOIPTP/xtjZ0Pl1SE9w7Uk
+8pwuJPJDPSAamguSNY5+HHcyta/i7Zsv2/S4BdV8Q8WQeCc6hcR3Zka1H0txgk8o
+qUurU2ApdnzINQ7ki0+D6CuVXEivmL/kPivQg0/khIQp1IXhdYdWCMKSUr1vkoAK
+0zc6H5DlDvdQPrjqdLGOUlVx5JnjTYd68/Wqje76eQKBgQD0uNR2yJYxmQmLC1y6
+TLXxvm0OOlmUiNMZgLOwDNdjXvOH/emtpHyyKhHpc3kzNK3xsNxyAYJRlaIUylj0
+C9dsipj+QTb4ICu0GlbLXsXN5iM592igoS4kMnP9KbzSc93k9BvMhh1emO8i3GB7
+v/1Cf/z+gP+viLMaPEFqKxI8FwKBgQDNGrjabA2jkawanHHUUhwscwB4RrvuuJTG
+Zv7L7QXBMYx7CUwJztV5amkUNrbBW/67/MMQB0Djv1pgMo4QCWeftb9oHFXGu3hV
+kUj7Or/Z2TWYtLIdxgTDbRRtit57z3NaCHCDgQhyAZUY3y8cvXFYdHDnJlqLTN77
+bzQub7BS3QKBgHtUep6yUB8GxSxxuXWaG0eNdGBrP6H/ooODvQrILfRCcfDjIdUE
+xGL1mLlSHI6VyeO4AiDiac673kckAtha72IgJyJbs1wwulW1wHAVfxJZHP+lk/D/
+ycUsOBAp7KMTCYzNCQV1wW9fG4UyEt3Kz9OntNR+Jl1MQxbBryXWNwZZAoGAO48x
+9MOB5mjL2GJrr6M0aTfv//1SX40cLs0D2oX2sNZJnATkHskANqTO5L7KrTWgsEhD
+AKmKj1gmz15+4GtKuxcVAQ+RXQddd0OcNNAnnAQ2SyTVwE2bXoCTeQfleYCRV6ix
+u45BvJF3EWTmEmt0uaH+kzERA/iLm+n79iwawMUCgYB7s6ZkEbyZbJDDT8MXU/37
+vvLo5/sPzJ6hMPIrWbKybmUfKAMBkXYV90bVfBxim+PEGyiIWSHlXRCgHLUc/C7C
+4s8ouWDR2F3zUWjadzRsPI58qWL9yVa5aGoSzoJu2qyuX4QKS8hOehxVMzIB4Mrf
+Hh0tvtntgpJAW2TwXMVxCw==
+-----END PRIVATE KEY-----
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 66ee0cf..8c060c3 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -63,6 +63,7 @@
[ $system != macos ]
io/https_nonblocking_trust_evaluation_test: SkipByDesign
+io/https_connection_closed_during_handshake_test: SkipByDesign # long_ssl_cert_evaluation needed for long handshake is only supported on mac.
[ $builder_tag == swarming && $system == macos ]
io/*: Skip # Issue 30618
diff --git a/tests/standalone_2/io/https_connection_closed_during_handshake_test.dart b/tests/standalone_2/io/https_connection_closed_during_handshake_test.dart
new file mode 100644
index 0000000..eed79c2
--- /dev/null
+++ b/tests/standalone_2/io/https_connection_closed_during_handshake_test.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--long-ssl-cert-evaluation
+
+// This test verifies that lost of connection during handshake doesn't cause
+// vm crashes.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+
+import "package:expect/expect.dart";
+
+String getFilename(String path) => Platform.script.resolve(path).toFilePath();
+
+final SecurityContext serverSecurityContext = () {
+ final context = SecurityContext();
+ context
+ .usePrivateKeyBytes(File(getFilename('localhost.key')).readAsBytesSync());
+ context.useCertificateChainBytes(
+ File(getFilename('localhost.crt')).readAsBytesSync());
+ return context;
+}();
+
+final SecurityContext clientSecurityContext = () {
+ final context = SecurityContext(withTrustedRoots: true);
+ context.setTrustedCertificatesBytes(
+ File(getFilename('localhost.crt')).readAsBytesSync());
+ return context;
+}();
+
+void main(List<String> args) async {
+ if (args.length >= 1 && args[0] == 'server') {
+ final server =
+ await SecureServerSocket.bind('localhost', 0, serverSecurityContext);
+ print('ok ${server.port}');
+ server.listen((socket) {
+ print('server: got connection');
+ socket.close();
+ });
+ await Future.delayed(Duration(seconds: 2));
+ print('server: exiting');
+ exit(1);
+ }
+
+ final serverProcess = await Process.start(
+ Platform.executable, [Platform.script.toFilePath(), 'server']);
+ final serverPortCompleter = Completer<int>();
+
+ serverProcess.stdout
+ .transform(utf8.decoder)
+ .transform(LineSplitter())
+ .listen((line) {
+ print('server stdout: $line');
+ if (line.startsWith('ok')) {
+ serverPortCompleter.complete(int.parse(line.substring('ok'.length)));
+ }
+ });
+ serverProcess.stderr
+ .transform(utf8.decoder)
+ .transform(LineSplitter())
+ .listen((line) => print('server stderr: $line'));
+
+ int port = await serverPortCompleter.future;
+
+ var thrownException;
+ try {
+ print('client connecting...');
+ await SecureSocket.connect('localhost', port,
+ context: clientSecurityContext);
+ print('client connected.');
+ } catch (e) {
+ thrownException = e;
+ } finally {
+ await serverProcess.kill();
+ }
+ print('thrownException: $thrownException');
+ Expect.isTrue(thrownException is HandshakeException);
+}
diff --git a/tests/standalone_2/io/localhost.crt b/tests/standalone_2/io/localhost.crt
new file mode 100644
index 0000000..eeab890
--- /dev/null
+++ b/tests/standalone_2/io/localhost.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDNjCCAh6gAwIBAgIUe+E1Xth9TMlsYY7qmf9zlfC1Ms0wDQYJKoZIhvcNAQEL
+BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MCAXDTE4MTIzMTIzMDAxMVoYDzIxMTgx
+MjA3MjMwMDExWjAUMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQDEEY2eWBX1rTDgsAWheltKiAHREteaqX4iaGwF6/TC
+6kMJajZQreySsib+lQ+FTLtMlPWorR5jMfsA6PDocRpK2zOObTqdVqJAiodUi0ov
+ds7wgaN7XnUfpPo8NDMA2tV8Bn2mfKWgC3QkUMPCDBkLqiYUuR6j5QJ4Vz2OFV5g
+1iR1HzgQgr4pbNjkUJJesr0r1J1a25YbYdLIvzss+aHBTWD+9HYfgWsfJGI3UFgc
+zoAJbKSIHYqDGsSKZMgmtixyyEjTDc6OAqjk10jhYdxdglXpTPOWP5YnwWsy8VbU
+1ozu93LlWkbbef95FD/XGH/ynglIe1laZwEXdyxOzT3bAgMBAAGjfjB8MB0GA1Ud
+DgQWBBS/3CUrYgiD2qwdEDStghi+X3+4pzAfBgNVHSMEGDAWgBS/3CUrYgiD2qwd
+EDStghi+X3+4pzAPBgNVHRMBAf8EBTADAQH/MBMGA1UdJQQMMAoGCCsGAQUFBwMB
+MBQGA1UdEQQNMAuCCWxvY2FsaG9zdDANBgkqhkiG9w0BAQsFAAOCAQEAu5adpS/h
+bWXYaDLW5JGZAiOVVkMDhspJDdPwDHUTqMPj3V6aaecZTc46Q7TLEkLxIjU5OjvR
+ZHh3vo9X4S84Yf7NHv8eX50MK/RrzZolUROhZ6gtYZKkdZtjQKQd62ih5EB6gNnZ
++IW9nedg7Sae2Yh22jDC9Tc+dbvroOd7IUwL9gVSCcwiqVjvuWkDa7jqjnRp4sog
+yY1Obr14tmUMgR73Db7q3g0cVToztLYIMJnhjiSUs8nk83m/9/O4SGqQmievoZ5N
+60OlhU6enfFoj1xKpXWSGv6mqqdX0G9Ehz1EIetFhkBK2pP/R00gf4OMKc4ubw8d
+yTSUIeMSOo0QjA==
+-----END CERTIFICATE-----
diff --git a/tests/standalone_2/io/localhost.key b/tests/standalone_2/io/localhost.key
new file mode 100644
index 0000000..20815e4
--- /dev/null
+++ b/tests/standalone_2/io/localhost.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDEEY2eWBX1rTDg
+sAWheltKiAHREteaqX4iaGwF6/TC6kMJajZQreySsib+lQ+FTLtMlPWorR5jMfsA
+6PDocRpK2zOObTqdVqJAiodUi0ovds7wgaN7XnUfpPo8NDMA2tV8Bn2mfKWgC3Qk
+UMPCDBkLqiYUuR6j5QJ4Vz2OFV5g1iR1HzgQgr4pbNjkUJJesr0r1J1a25YbYdLI
+vzss+aHBTWD+9HYfgWsfJGI3UFgczoAJbKSIHYqDGsSKZMgmtixyyEjTDc6OAqjk
+10jhYdxdglXpTPOWP5YnwWsy8VbU1ozu93LlWkbbef95FD/XGH/ynglIe1laZwEX
+dyxOzT3bAgMBAAECggEAHGsa5reHv0syCW8Z8dTFRKE/+ijL/UvRz3TpK1aO7G19
+9/BgHQOIhZ6yzjWWwVBk2W3ByYgGHoSRCAm7WUWDdRQefedRFpsG+2nYwaVKxGRp
+DC0OIASJ32NPLci3F8mgJdDfB3GLpA3k8JqQNSEBxFIOIPTP/xtjZ0Pl1SE9w7Uk
+8pwuJPJDPSAamguSNY5+HHcyta/i7Zsv2/S4BdV8Q8WQeCc6hcR3Zka1H0txgk8o
+qUurU2ApdnzINQ7ki0+D6CuVXEivmL/kPivQg0/khIQp1IXhdYdWCMKSUr1vkoAK
+0zc6H5DlDvdQPrjqdLGOUlVx5JnjTYd68/Wqje76eQKBgQD0uNR2yJYxmQmLC1y6
+TLXxvm0OOlmUiNMZgLOwDNdjXvOH/emtpHyyKhHpc3kzNK3xsNxyAYJRlaIUylj0
+C9dsipj+QTb4ICu0GlbLXsXN5iM592igoS4kMnP9KbzSc93k9BvMhh1emO8i3GB7
+v/1Cf/z+gP+viLMaPEFqKxI8FwKBgQDNGrjabA2jkawanHHUUhwscwB4RrvuuJTG
+Zv7L7QXBMYx7CUwJztV5amkUNrbBW/67/MMQB0Djv1pgMo4QCWeftb9oHFXGu3hV
+kUj7Or/Z2TWYtLIdxgTDbRRtit57z3NaCHCDgQhyAZUY3y8cvXFYdHDnJlqLTN77
+bzQub7BS3QKBgHtUep6yUB8GxSxxuXWaG0eNdGBrP6H/ooODvQrILfRCcfDjIdUE
+xGL1mLlSHI6VyeO4AiDiac673kckAtha72IgJyJbs1wwulW1wHAVfxJZHP+lk/D/
+ycUsOBAp7KMTCYzNCQV1wW9fG4UyEt3Kz9OntNR+Jl1MQxbBryXWNwZZAoGAO48x
+9MOB5mjL2GJrr6M0aTfv//1SX40cLs0D2oX2sNZJnATkHskANqTO5L7KrTWgsEhD
+AKmKj1gmz15+4GtKuxcVAQ+RXQddd0OcNNAnnAQ2SyTVwE2bXoCTeQfleYCRV6ix
+u45BvJF3EWTmEmt0uaH+kzERA/iLm+n79iwawMUCgYB7s6ZkEbyZbJDDT8MXU/37
+vvLo5/sPzJ6hMPIrWbKybmUfKAMBkXYV90bVfBxim+PEGyiIWSHlXRCgHLUc/C7C
+4s8ouWDR2F3zUWjadzRsPI58qWL9yVa5aGoSzoJu2qyuX4QKS8hOehxVMzIB4Mrf
+Hh0tvtntgpJAW2TwXMVxCw==
+-----END PRIVATE KEY-----
diff --git a/tests/standalone_2/standalone_2.status b/tests/standalone_2/standalone_2.status
index abe364c..9dc0156 100644
--- a/tests/standalone_2/standalone_2.status
+++ b/tests/standalone_2/standalone_2.status
@@ -72,6 +72,7 @@
[ $system != macos ]
io/https_nonblocking_trust_evaluation_test: SkipByDesign
+io/https_connection_closed_during_handshake_test: SkipByDesign # long_ssl_cert_evaluation needed for long handshake is only supported on mac.
[ $builder_tag == swarming && $system == macos ]
io/*: Skip # Issue 30618
diff --git a/tools/VERSION b/tools/VERSION
index 51f1ac0..1fa2f63 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 12
PATCH 0
-PRERELEASE 105
+PRERELEASE 106
PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/spec_parser/Dart.g b/tools/spec_parser/Dart.g
index ad410ba..a200f70 100644
--- a/tools/spec_parser/Dart.g
+++ b/tools/spec_parser/Dart.g
@@ -472,6 +472,7 @@
metadatum
: constructorDesignation arguments
+ | identifier
| qualifiedName
;
@@ -905,8 +906,7 @@
;
qualifiedName
- : typeIdentifier
- | typeIdentifier '.' identifier
+ : typeIdentifier '.' identifier
| typeIdentifier '.' typeIdentifier '.' identifier
;
@@ -1253,7 +1253,8 @@
;
constructorDesignation
- : qualifiedName
+ : typeIdentifier
+ | qualifiedName
| typeName typeArguments ('.' identifier)?
;
diff --git a/tools/spec_parser/SpecParser.java b/tools/spec_parser/SpecParser.java
index cc9d1ea..dc2c6e8 100644
--- a/tools/spec_parser/SpecParser.java
+++ b/tools/spec_parser/SpecParser.java
@@ -101,8 +101,8 @@
}
}
- /// From [arguments], obey the flags ("--<flag_name>") if known and ignore
- /// them if unknown; treat the remaining [arguments] as file paths and
+ /// From [arguments], obey the flags ("--<flag_name>", "-<any>") if known and
+ /// ignore them if unknown; treat the remaining [arguments] as file paths and
/// parse each of them. Return a [ParsingResult] specifying how many files
/// were parsed, and how many of them failed to parse.
private static ParsingResult parseFiles(String[] arguments)
@@ -113,13 +113,13 @@
result.numberOfFileArguments = arguments.length;
for (int i = 0; i < arguments.length; i++) {
String filePath = arguments[i];
- if (filePath.substring(0, 2).equals("--")) {
- result.numberOfFileArguments--;
- if (result.numberOfFileArguments == 0) return result;
- if (filePath.equals("--verbose")) verbose = true;
- if (filePath.equals("--batch")) runAsBatch();
- // Ignore all other flags.
- continue;
+ if (filePath.startsWith("-")) {
+ result.numberOfFileArguments--;
+ if (result.numberOfFileArguments == 0) return result;
+ if (filePath.equals("--verbose")) verbose = true;
+ if (filePath.equals("--batch")) runAsBatch();
+ // Ignore all other flags.
+ continue;
}
if (verbose) System.err.println("Parsing file: " + filePath);
DartLexer lexer = new DartLexer(new ANTLRFileStream(filePath));