Merge package:json_rpc_2 into the tools monorepo
diff --git a/.github/ISSUE_TEMPLATE/boolean_selector.md b/.github/ISSUE_TEMPLATE/boolean_selector.md
new file mode 100644
index 0000000..5686d2a
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/boolean_selector.md
@@ -0,0 +1,5 @@
+---
+name: "package:boolean_selector"
+about: "Create a bug or file a feature request against package:boolean_selector."
+labels: "package:boolean_selector"
+---
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/cli_config.md b/.github/ISSUE_TEMPLATE/cli_config.md
new file mode 100644
index 0000000..c47fbcf
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/cli_config.md
@@ -0,0 +1,5 @@
+---
+name: "package:cli_config"
+about: "Create a bug or file a feature request against package:cli_config."
+labels: "package:cli_config"
+---
diff --git a/.github/ISSUE_TEMPLATE/coverage.md b/.github/ISSUE_TEMPLATE/coverage.md
new file mode 100644
index 0000000..d0b0fb7
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/coverage.md
@@ -0,0 +1,5 @@
+---
+name: "package:coverage"
+about: "Create a bug or file a feature request against package:coverage."
+labels: "package:coverage"
+---
diff --git a/.github/ISSUE_TEMPLATE/extension_discovery.md b/.github/ISSUE_TEMPLATE/extension_discovery.md
new file mode 100644
index 0000000..165b7cb
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/extension_discovery.md
@@ -0,0 +1,5 @@
+---
+name: "package:extension_discovery"
+about: "Create a bug or file a feature request against package:extension_discovery."
+labels: "package:extension_discovery"
+---
diff --git a/.github/ISSUE_TEMPLATE/file.md b/.github/ISSUE_TEMPLATE/file.md
new file mode 100644
index 0000000..3430d7e
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/file.md
@@ -0,0 +1,5 @@
+---
+name: "package:file"
+about: "Create a bug or file a feature request against package:file."
+labels: "package:file"
+---
diff --git a/.github/ISSUE_TEMPLATE/graphs.md b/.github/ISSUE_TEMPLATE/graphs.md
new file mode 100644
index 0000000..b4cb60f
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/graphs.md
@@ -0,0 +1,5 @@
+---
+name: "package:graphs"
+about: "Create a bug or file a feature request against package:graphs."
+labels: "package:graphs"
+---
diff --git a/.github/ISSUE_TEMPLATE/unified_analytics.md b/.github/ISSUE_TEMPLATE/unified_analytics.md
new file mode 100644
index 0000000..163951e
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/unified_analytics.md
@@ -0,0 +1,5 @@
+---
+name: "package:unified_analytics - bug or enhancement"
+about: "Create a bug or file a feature request against package:unified_analytics."
+labels: "package:unified_analytics"
+---
diff --git a/.github/ISSUE_TEMPLATE/unified_analytics_event.yml b/.github/ISSUE_TEMPLATE/unified_analytics_event.yml
new file mode 100644
index 0000000..52c8d83
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/unified_analytics_event.yml
@@ -0,0 +1,47 @@
+name: "package:unified_analytics - request a new event"
+description: "Create a request for collecting a new event or new event data."
+labels: "package:unified_analytics"
+body:
+ - type: markdown
+ attributes:
+ value: |
+ An event is an action that a user, or the tool, performs.
+ You can see the events that are being collected [here](../../pkgs/unified_analytics/lib/src/enums.dart)
+ and the data associated with those events [here](../../pkgs/unified_analytics/lib/src/event.dart).
+ - type: checkboxes
+ attributes:
+ label: Has this already been approved in the privacy design documentation?
+ options:
+ - label: This field is already covered in the PDD
+ description: |
+ You can request that a new event be added to the package
+ regardless of whether it's included in the privacy design documentation.
+ However, the privacy team will need to approve before it is added.
+
+ - type: textarea
+ attributes:
+ label: Event name
+ description: |
+ If the event already exists, please tell us the name of the event
+ you would like to add data to.
+
+ If this is a new event, tell us the name, description, and tool owner.
+ Possible tool owners can be found in the `DashTool` enum [here](../../pkgs/unified_analytics/lib/src/enums.dart).
+
+ For example, pub_get represents pub package resolution details. The owner is the Dart tool.
+ validations:
+ required: true
+
+ - type: textarea
+ attributes:
+ label: Event data
+ description: |
+ Event data are key-value pairs that are associated with an event.
+ Please list the different event data associated with this event.
+ You should also include a description of the event data values.
+
+ For example, if the event is pub_get, one event data may be
+ the packageName. The values would be the name of the package
+ as a string.
+ validations:
+ required: true
diff --git a/.github/ISSUE_TEMPLATE/unified_analytics_user_property.yml b/.github/ISSUE_TEMPLATE/unified_analytics_user_property.yml
new file mode 100644
index 0000000..3fc960e
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/unified_analytics_user_property.yml
@@ -0,0 +1,37 @@
+name: "package:unified_analytics - request a new user property"
+description: "Create a request for collecting a new user property."
+labels: "package:unified_analytics"
+body:
+ - type: markdown
+ attributes:
+ value: |
+ A user property is a key-value pair that is used to segment users.
+ For example, the Flutter channel that the user is on. You can see
+ which user properties are being collected
+ [here](../../pkgs/unified_analytics/lib/src/user_property.dart).
+
+ - type: checkboxes
+ attributes:
+ label: Has this already been approved in the privacy design documentation?
+ options:
+ - label: This field is already covered in the PDD
+ description: |
+ You can request that a new user property be added to the package
+ regardless of whether it's included in the privacy design documentation.
+ However, the privacy team will need to approve before it is added.
+
+ - type: textarea
+ attributes:
+ label: User property name
+ description: |
+ Please tell us the name of the user property you would like to add (e.g. flutter_channel).
+ validations:
+ required: true
+
+ - type: textarea
+ attributes:
+ label: User property values
+ description: |
+ Please list or describe the unique values for this property (e.g. master, beta, stable).
+ validations:
+ required: true
diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml
new file mode 100644
index 0000000..bf6b38a
--- /dev/null
+++ b/.github/dependabot.yaml
@@ -0,0 +1,14 @@
+# Dependabot configuration file.
+version: 2
+
+updates:
+ - package-ecosystem: github-actions
+ directory: /
+ schedule:
+ interval: monthly
+ labels:
+ - autosubmit
+ groups:
+ github-actions:
+ patterns:
+ - "*"
diff --git a/.github/labeler.yml b/.github/labeler.yml
new file mode 100644
index 0000000..c3d5de0
--- /dev/null
+++ b/.github/labeler.yml
@@ -0,0 +1,49 @@
+# Configuration for .github/workflows/pull_request_label.yml.
+
+'type-infra':
+ - changed-files:
+ - any-glob-to-any-file: '.github/**'
+
+'package:boolean_selector':
+ - changed-files:
+ - any-glob-to-any-file: 'pkgs/boolean_selector/**'
+
+'package:cli_config':
+ - changed-files:
+ - any-glob-to-any-file: 'pkgs/cli_config/**'
+
+'package:coverage':
+ - changed-files:
+ - any-glob-to-any-file: 'pkgs/coverage/**'
+
+'package:extension_discovery':
+ - changed-files:
+ - any-glob-to-any-file: 'pkgs/extension_discovery/**'
+
+'package:file':
+ - changed-files:
+ - any-glob-to-any-file: 'pkgs/file/**'
+
+'package:file_testing':
+ - changed-files:
+ - any-glob-to-any-file: 'pkgs/file_testing/**'
+
+'package:graphs':
+ - changed-files:
+ - any-glob-to-any-file: 'pkgs/graphs/**'
+
+'package:mime':
+ - changed-files:
+ - any-glob-to-any-file: 'pkgs/mime/**'
+
+'package:oauth2':
+ - changed-files:
+ - any-glob-to-any-file: 'pkgs/oauth2/**'
+
+'package:source_map_stack_trace':
+ - changed-files:
+ - any-glob-to-any-file: 'pkgs/source_map_stack_trace/**'
+
+'package:unified_analytics':
+ - changed-files:
+ - any-glob-to-any-file: 'pkgs/unified_analytics/**'
diff --git a/.github/workflows/boolean_selector.yaml b/.github/workflows/boolean_selector.yaml
new file mode 100644
index 0000000..9d90c41
--- /dev/null
+++ b/.github/workflows/boolean_selector.yaml
@@ -0,0 +1,72 @@
+name: package:boolean_selector
+
+on:
+ # Run on PRs and pushes to the default branch.
+ push:
+ branches: [ main ]
+ paths:
+ - '.github/workflows/boolean_selector.yml'
+ - 'pkgs/boolean_selector/**'
+ pull_request:
+ branches: [ main ]
+ paths:
+ - '.github/workflows/boolean_selector.yml'
+ - 'pkgs/boolean_selector/**'
+ schedule:
+ - cron: "0 0 * * 0"
+
+env:
+ PUB_ENVIRONMENT: bot.github
+
+
+defaults:
+ run:
+ working-directory: pkgs/boolean_selector/
+
+jobs:
+ # Check code formatting and static analysis on a single OS (linux)
+ # against Dart dev.
+ analyze:
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ sdk: [dev]
+ steps:
+ - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
+ - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672
+ with:
+ sdk: ${{ matrix.sdk }}
+ - id: install
+ name: Install dependencies
+ run: dart pub get
+ - name: Check formatting
+ run: dart format --output=none --set-exit-if-changed .
+ if: always() && steps.install.outcome == 'success'
+ - name: Analyze code
+ run: dart analyze --fatal-infos
+ if: always() && steps.install.outcome == 'success'
+
+ test:
+ needs: analyze
+ runs-on: ${{ matrix.os }}
+ strategy:
+ fail-fast: false
+ matrix:
+ # Add macos-latest and/or windows-latest if relevant for this package.
+ os: [ubuntu-latest]
+ sdk: [3.1, dev]
+ steps:
+ - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
+ - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672
+ with:
+ sdk: ${{ matrix.sdk }}
+ - id: install
+ name: Install dependencies
+ run: dart pub get
+ - name: Run VM tests
+ run: dart test --platform vm
+ if: always() && steps.install.outcome == 'success'
+ - name: Run Chrome tests
+ run: dart test --platform chrome
+ if: always() && steps.install.outcome == 'success'
diff --git a/.github/workflows/cli_config.yml b/.github/workflows/cli_config.yml
new file mode 100644
index 0000000..78eed42
--- /dev/null
+++ b/.github/workflows/cli_config.yml
@@ -0,0 +1,80 @@
+name: package:cli_config
+permissions: read-all
+
+on:
+ pull_request:
+ branches: [main]
+ paths:
+ - ".github/workflows/cli_config.yml"
+ - "pkgs/cli_config/**"
+ push:
+ branches: [main]
+ paths:
+ - ".github/workflows/cli_config.yml"
+ - "pkgs/cli_config/**"
+ schedule:
+ - cron: "0 0 * * 0" # weekly
+
+jobs:
+ build_linux:
+ runs-on: ubuntu-latest
+ defaults:
+ run:
+ working-directory: pkgs/cli_config
+ strategy:
+ matrix:
+ sdk: [stable, dev] # {pkgs.versions}
+ include:
+ - sdk: stable
+ run-tests: true
+ steps:
+ - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
+ - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672
+ with:
+ sdk: ${{matrix.sdk}}
+
+ - run: dart pub get
+
+ - run: dart analyze --fatal-infos
+
+ - run: dart format --output=none --set-exit-if-changed .
+ if: ${{matrix.run-tests}}
+
+ - run: dart test
+ if: ${{matrix.run-tests}}
+
+ - name: Install coverage
+ run: dart pub global activate coverage
+ if: ${{ matrix.sdk == 'stable' }}
+ - name: Collect coverage
+ run: dart pub global run coverage:test_with_coverage
+ if: ${{ matrix.sdk == 'stable' }}
+ - name: Upload coverage
+ uses: coverallsapp/github-action@643bc377ffa44ace6394b2b5d0d3950076de9f63
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ flag-name: cli_config_linux
+ path-to-lcov: ./pkgs/cli_config/coverage/lcov.info
+ if: ${{ matrix.sdk == 'stable' }}
+
+ build_windows:
+ runs-on: windows-latest
+ defaults:
+ run:
+ working-directory: pkgs/cli_config
+ strategy:
+ matrix:
+ sdk: [stable, dev] # {pkgs.versions}
+ include:
+ - sdk: stable
+ run-tests: true
+ steps:
+ - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
+ - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672
+ with:
+ sdk: ${{matrix.sdk}}
+
+ - run: dart pub get
+
+ - run: dart test
+ if: ${{matrix.run-tests}}
diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml
new file mode 100644
index 0000000..a66a53c
--- /dev/null
+++ b/.github/workflows/coverage.yml
@@ -0,0 +1,99 @@
+name: Dart CI
+
+on:
+ # Run on PRs and pushes to the default branch.
+ push:
+ branches: [ main ]
+ paths:
+ - '.github/workflows/coverage.yml'
+ - 'pkgs/coverage/**'
+ pull_request:
+ branches: [ main ]
+ paths:
+ - '.github/workflows/coverage.yml'
+ - 'pkgs/coverage/**'
+ schedule:
+ - cron: "0 0 * * 0"
+
+env:
+ PUB_ENVIRONMENT: bot.github
+
+jobs:
+ # Check code formatting and static analysis on a single OS (linux)
+ # against Dart dev.
+ analyze:
+ runs-on: ubuntu-latest
+ defaults:
+ run:
+ working-directory: pkgs/coverage/
+ strategy:
+ fail-fast: false
+ matrix:
+ sdk: [dev]
+ steps:
+ - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
+ - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672
+ with:
+ sdk: ${{ matrix.sdk }}
+ - id: install
+ name: Install dependencies
+ run: dart pub get
+ - name: Check formatting
+ run: dart format --output=none --set-exit-if-changed .
+ if: always() && steps.install.outcome == 'success'
+ - name: Analyze code
+ run: dart analyze --fatal-infos
+ if: always() && steps.install.outcome == 'success'
+
+ # Run tests on a matrix consisting of two dimensions:
+ # 1. OS: ubuntu-latest, macos-latest, windows-latest
+ # 2. release channel: dev
+ test:
+ needs: analyze
+ runs-on: ${{ matrix.os }}
+ defaults:
+ run:
+ working-directory: pkgs/coverage/
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ubuntu-latest, macos-latest, windows-latest]
+ sdk: [3.4, dev]
+ exclude:
+ # VM service times out on windows before Dart 3.5
+ # https://github.com/dart-lang/coverage/issues/490
+ - os: windows-latest
+ sdk: 3.4
+ steps:
+ - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
+ - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672
+ with:
+ sdk: ${{ matrix.sdk }}
+ - id: install
+ name: Install dependencies
+ run: dart pub get
+ - name: Run VM tests
+ run: dart test --platform vm
+ if: always() && steps.install.outcome == 'success'
+
+ coverage:
+ needs: test
+ runs-on: ubuntu-latest
+ defaults:
+ run:
+ working-directory: pkgs/coverage/
+ steps:
+ - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
+ - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672
+ with:
+ sdk: dev
+ - id: install
+ name: Install dependencies
+ run: dart pub get
+ - name: Collect and report coverage
+ run: dart run bin/test_with_coverage.dart --port=9292
+ - name: Upload coverage
+ uses: coverallsapp/github-action@643bc377ffa44ace6394b2b5d0d3950076de9f63
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ path-to-lcov: pkgs/coverage/coverage/lcov.info
diff --git a/.github/workflows/extension_discovery.yml b/.github/workflows/extension_discovery.yml
new file mode 100644
index 0000000..b92fddf
--- /dev/null
+++ b/.github/workflows/extension_discovery.yml
@@ -0,0 +1,48 @@
+name: package:extension_discovery
+permissions: read-all
+
+on:
+ pull_request:
+ branches: [ main ]
+ paths:
+ - '.github/workflows/unified_analytics.yml'
+ - 'pkgs/extension_discovery/**'
+ push:
+ branches: [ main ]
+ paths:
+ - '.github/workflows/extension_discovery.yml'
+ - 'pkgs/extension_discovery/**'
+ schedule:
+ - cron: '0 0 * * 0' # weekly
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ defaults:
+ run:
+ working-directory: pkgs/extension_discovery
+ strategy:
+ fail-fast: false
+ matrix:
+ sdk: [stable, dev] # {pkgs.versions}
+ include:
+ - sdk: stable
+ check-formatting: true
+ steps:
+ - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
+ - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672
+ with:
+ sdk: ${{matrix.sdk}}
+
+ - run: dart pub get
+ - run: |
+ (cd example/hello_world && dart pub get)
+ (cd example/hello_world_app && dart pub get)
+ (cd example/hello_world_german && dart pub get)
+
+ - run: dart analyze --fatal-infos
+
+ - run: dart format --output=none --set-exit-if-changed .
+ if: ${{matrix.check-formatting}}
+
+ - run: dart test
diff --git a/.github/workflows/file.yml b/.github/workflows/file.yml
new file mode 100644
index 0000000..06ce285
--- /dev/null
+++ b/.github/workflows/file.yml
@@ -0,0 +1,66 @@
+name: package:file
+permissions: read-all
+
+on:
+ # Run on PRs and pushes to the default branch.
+ push:
+ branches: [ main ]
+ paths:
+ - '.github/workflows/file.yml'
+ - 'pkgs/file/**'
+ - 'pkgs/file_testing/**'
+ pull_request:
+ branches: [ main ]
+ paths:
+ - '.github/workflows/file.yml'
+ - 'pkgs/file/**'
+ - 'pkgs/file_testing/**'
+ schedule:
+ - cron: "0 0 * * 0"
+
+jobs:
+ correctness:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ package: [file, file_testing]
+
+ steps:
+ - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
+ - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672
+ with:
+ sdk: dev
+
+ - name: Install ${{ matrix.package }} dependencies
+ working-directory: pkgs/${{ matrix.package }}
+ run: dart pub get
+
+ - name: Verify formatting in ${{ matrix.package }}
+ working-directory: pkgs/${{ matrix.package }}
+ run: dart format --output=none --set-exit-if-changed .
+
+ - name: Analyze package ${{ matrix.package }} source
+ working-directory: pkgs/${{ matrix.package }}
+ run: dart analyze --fatal-infos
+
+ test:
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ package: [file]
+ os: [ubuntu-latest, macos-latest, windows-latest]
+ sdk: [stable, dev]
+
+ steps:
+ - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
+ - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672
+ with:
+ sdk: ${{ matrix.sdk }}
+
+ - name: Install ${{ matrix.package }} dependencies
+ working-directory: pkgs/${{ matrix.package }}
+ run: dart pub get
+
+ - name: Run ${{ matrix.package }} Tests
+ working-directory: pkgs/${{ matrix.package }}
+ run: dart pub run test -j1
diff --git a/.github/workflows/graphs.yml b/.github/workflows/graphs.yml
new file mode 100644
index 0000000..8de9cf5
--- /dev/null
+++ b/.github/workflows/graphs.yml
@@ -0,0 +1,67 @@
+name: package:graphs
+permissions: read-all
+
+on:
+ # Run on PRs and pushes to the default branch.
+ push:
+ branches: [ main ]
+ paths:
+ - '.github/workflows/graphs.yml'
+ - 'pkgs/graphs/**'
+ pull_request:
+ branches: [ main ]
+ paths:
+ - '.github/workflows/graphs.yml'
+ - 'pkgs/graphs/**'
+ schedule:
+ - cron: "0 0 * * 0"
+
+env:
+ PUB_ENVIRONMENT: bot.github
+
+jobs:
+ # Check code formatting and static analysis on a single OS (linux)
+ # against Dart beta.
+ analyze:
+ runs-on: ubuntu-latest
+ defaults:
+ run:
+ working-directory: pkgs/graphs/
+ strategy:
+ fail-fast: false
+ matrix:
+ sdk: [dev]
+ steps:
+ - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
+ - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672
+ with:
+ sdk: ${{ matrix.sdk }}
+ - id: install
+ run: dart pub get
+ - run: dart format --output=none --set-exit-if-changed .
+ if: always() && steps.install.outcome == 'success'
+ - run: dart analyze --fatal-infos
+ if: always() && steps.install.outcome == 'success'
+
+ test:
+ needs: analyze
+ runs-on: ${{ matrix.os }}
+ defaults:
+ run:
+ working-directory: pkgs/graphs/
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ubuntu-latest]
+ sdk: [3.4, dev]
+ steps:
+ - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
+ - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672
+ with:
+ sdk: ${{ matrix.sdk }}
+ - id: install
+ run: dart pub get
+ - run: dart test --platform vm
+ if: always() && steps.install.outcome == 'success'
+ - run: dart test --platform chrome
+ if: always() && steps.install.outcome == 'success'
diff --git a/.github/workflows/health.yaml b/.github/workflows/health.yaml
new file mode 100644
index 0000000..f258f8b
--- /dev/null
+++ b/.github/workflows/health.yaml
@@ -0,0 +1,14 @@
+name: Health
+on:
+ pull_request:
+ branches: [ main ]
+ types: [opened, synchronize, reopened, labeled, unlabeled]
+
+jobs:
+ health:
+ uses: dart-lang/ecosystem/.github/workflows/health.yaml@main
+ with:
+ ignore_coverage: "**.mock.dart,**.g.dart"
+ ignore_license: "**.mock.dart,**.g.dart,**.mocks.dart"
+ permissions:
+ pull-requests: write
diff --git a/.github/workflows/mime.yml b/.github/workflows/mime.yml
new file mode 100644
index 0000000..fe07a21
--- /dev/null
+++ b/.github/workflows/mime.yml
@@ -0,0 +1,45 @@
+name: Dart CI
+
+on:
+ schedule:
+ # “At 00:00 (UTC) on Sunday.”
+ - cron: '0 0 * * 0'
+ push:
+ branches: [ main ]
+ paths:
+ - '.github/workflows/mime.yml'
+ - 'pkgs/mime/**'
+ pull_request:
+ branches: [ main ]
+ paths:
+ - '.github/workflows/mime.yml'
+ - 'pkgs/mime/**'
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ defaults:
+ run:
+ working-directory: pkgs/mime/
+
+ strategy:
+ matrix:
+ os: [ubuntu-latest]
+ sdk: [3.2, dev]
+ steps:
+ # These are the latest versions of the github actions; dependabot will
+ # send PRs to keep these up-to-date.
+ - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
+ - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672
+
+ - name: Install dependencies
+ run: dart pub get
+
+ - name: Verify formatting
+ run: dart format --output=none --set-exit-if-changed .
+
+ - name: Analyze project source
+ run: dart analyze --fatal-infos
+
+ - name: Run tests
+ run: dart test
diff --git a/.github/workflows/no-response.yml b/.github/workflows/no-response.yml
new file mode 100644
index 0000000..ab1ac49
--- /dev/null
+++ b/.github/workflows/no-response.yml
@@ -0,0 +1,37 @@
+# A workflow to close issues where the author hasn't responded to a request for
+# more information; see https://github.com/actions/stale.
+
+name: No Response
+
+# Run as a daily cron.
+on:
+ schedule:
+ # Every day at 8am
+ - cron: '0 8 * * *'
+
+# All permissions not specified are set to 'none'.
+permissions:
+ issues: write
+ pull-requests: write
+
+jobs:
+ no-response:
+ runs-on: ubuntu-latest
+ if: ${{ github.repository_owner == 'dart-lang' }}
+ steps:
+ - uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e
+ with:
+ # Don't automatically mark inactive issues+PRs as stale.
+ days-before-stale: -1
+ # Close needs-info issues and PRs after 14 days of inactivity.
+ days-before-close: 14
+ stale-issue-label: "needs-info"
+ close-issue-message: >
+ Without additional information we're not able to resolve this issue.
+ Feel free to add more info or respond to any questions above and we
+ can reopen the case. Thanks for your contribution!
+ stale-pr-label: "needs-info"
+ close-pr-message: >
+ Without additional information we're not able to resolve this PR.
+ Feel free to add more info or respond to any questions above.
+ Thanks for your contribution!
diff --git a/.github/workflows/oauth2.yml b/.github/workflows/oauth2.yml
new file mode 100644
index 0000000..fa5d2de
--- /dev/null
+++ b/.github/workflows/oauth2.yml
@@ -0,0 +1,79 @@
+name: Dart CI
+
+on:
+ # Run on PRs and pushes to the default branch.
+ push:
+ branches: [ main ]
+ paths:
+ - '.github/workflows/oauth2.yml'
+ - 'pkgs/oauth2/**'
+ pull_request:
+ branches: [ main ]
+ paths:
+ - '.github/workflows/oauth2.yml'
+ - 'pkgs/oauth2/**'
+ schedule:
+ - cron: "0 0 * * 0"
+
+env:
+ PUB_ENVIRONMENT: bot.github
+
+jobs:
+ # Check code formatting and lints against Dart dev, check analyzer warnings
+ # against the oldest supported SDK.
+ analyze:
+ runs-on: ubuntu-latest
+ defaults:
+ run:
+ working-directory: pkgs/oauth2/
+ strategy:
+ fail-fast: false
+ matrix:
+ sdk: [dev]
+ steps:
+ - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
+ - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672
+ with:
+ sdk: ${{ matrix.sdk }}
+ - id: install
+ name: Install dependencies
+ run: dart pub get
+ - name: Check formatting
+ run: dart format --output=none --set-exit-if-changed .
+ if: matrix.sdk == 'dev' && steps.install.outcome == 'success'
+ - name: Analyze code
+ run: dart analyze --fatal-infos
+ if: matrix.sdk == 'dev' && steps.install.outcome == 'success'
+ - name: Analyze code
+ run: dart analyze
+ if: matrix.sdk != 'dev' && steps.install.outcome == 'success'
+
+ # Run tests on a matrix consisting of two dimensions:
+ # 1. OS: ubuntu-latest, (macos-latest, windows-latest)
+ # 2. release channel: dev
+ test:
+ needs: analyze
+ runs-on: ${{ matrix.os }}
+ defaults:
+ run:
+ working-directory: pkgs/oauth2/
+ strategy:
+ fail-fast: false
+ matrix:
+ # Add macos-latest and/or windows-latest if relevant for this package.
+ os: [ubuntu-latest]
+ sdk: [3.4, dev]
+ steps:
+ - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
+ - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672
+ with:
+ sdk: ${{ matrix.sdk }}
+ - id: install
+ name: Install dependencies
+ run: dart pub get
+ - name: Run VM tests
+ run: dart test --platform vm
+ if: always() && steps.install.outcome == 'success'
+ - name: Run Chrome tests
+ run: dart test --platform chrome
+ if: always() && steps.install.outcome == 'success'
diff --git a/.github/workflows/post_summaries.yaml b/.github/workflows/post_summaries.yaml
new file mode 100644
index 0000000..f5c8be8
--- /dev/null
+++ b/.github/workflows/post_summaries.yaml
@@ -0,0 +1,17 @@
+name: Comment on the pull request
+
+on:
+ # Trigger this workflow after the Health workflow completes. This workflow will have permissions to
+ # do things like create comments on the PR, even if the original workflow couldn't.
+ workflow_run:
+ workflows:
+ - Publish
+ - Health
+ types:
+ - completed
+
+jobs:
+ upload:
+ uses: dart-lang/ecosystem/.github/workflows/post_summaries.yaml@main
+ permissions:
+ pull-requests: write
diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml
new file mode 100644
index 0000000..2ec45aa
--- /dev/null
+++ b/.github/workflows/publish.yaml
@@ -0,0 +1,16 @@
+# A CI configuration to auto-publish pub packages.
+
+name: Publish
+
+on:
+ pull_request:
+ branches: [ main ]
+ push:
+ tags: [ '[A-z]+-v[0-9]+.[0-9]+.[0-9]+' ]
+
+jobs:
+ publish:
+ if: ${{ github.repository_owner == 'dart-lang' }}
+ uses: dart-lang/ecosystem/.github/workflows/publish.yaml@main
+ with:
+ write-comments: false
diff --git a/.github/workflows/pull_request_label.yml b/.github/workflows/pull_request_label.yml
new file mode 100644
index 0000000..54e3df5
--- /dev/null
+++ b/.github/workflows/pull_request_label.yml
@@ -0,0 +1,22 @@
+# This workflow applies labels to pull requests based on the paths that are
+# modified in the pull request.
+#
+# Edit `.github/labeler.yml` to configure labels. For more information, see
+# https://github.com/actions/labeler.
+
+name: Pull Request Labeler
+permissions: read-all
+
+on:
+ pull_request_target
+
+jobs:
+ label:
+ permissions:
+ pull-requests: write
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/labeler@8558fd74291d67161a8a78ce36a881fa63b766a9
+ with:
+ repo-token: "${{ secrets.GITHUB_TOKEN }}"
+ sync-labels: true
diff --git a/.github/workflows/source_map_stack_trace.yml b/.github/workflows/source_map_stack_trace.yml
new file mode 100644
index 0000000..9d3f0c7
--- /dev/null
+++ b/.github/workflows/source_map_stack_trace.yml
@@ -0,0 +1,76 @@
+name: Dart CI
+
+on:
+ # Run on PRs and pushes to the default branch.
+ push:
+ branches: [ main ]
+ paths:
+ - '.github/workflows/source_map_stack_trace.yml'
+ - 'pkgs/source_map_stack_trace/**'
+ pull_request:
+ branches: [ main ]
+ paths:
+ - '.github/workflows/source_map_stack_trace.yml'
+ - 'pkgs/source_map_stack_trace/**'
+ schedule:
+ - cron: "0 0 * * 0"
+
+env:
+ PUB_ENVIRONMENT: bot.github
+
+jobs:
+ # Check code formatting and static analysis on a single OS (linux)
+ # against Dart dev.
+ analyze:
+ runs-on: ubuntu-latest
+ defaults:
+ run:
+ working-directory: pkgs/source_map_stack_trace/
+ strategy:
+ fail-fast: false
+ matrix:
+ sdk: [dev]
+ steps:
+ - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
+ - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672
+ with:
+ sdk: ${{ matrix.sdk }}
+ - id: install
+ name: Install dependencies
+ run: dart pub get
+ - name: Check formatting
+ run: dart format --output=none --set-exit-if-changed .
+ if: always() && steps.install.outcome == 'success'
+ - name: Analyze code
+ run: dart analyze --fatal-infos
+ if: always() && steps.install.outcome == 'success'
+
+ # Run tests on a matrix consisting of two dimensions:
+ # 1. OS: ubuntu-latest, (macos-latest, windows-latest)
+ # 2. release channel: dev
+ test:
+ needs: analyze
+ runs-on: ${{ matrix.os }}
+ defaults:
+ run:
+ working-directory: pkgs/source_map_stack_trace/
+ strategy:
+ fail-fast: false
+ matrix:
+ # Add macos-latest and/or windows-latest if relevant for this package.
+ os: [ubuntu-latest]
+ sdk: [3.3, dev]
+ steps:
+ - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
+ - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672
+ with:
+ sdk: ${{ matrix.sdk }}
+ - id: install
+ name: Install dependencies
+ run: dart pub get
+ - name: Run VM tests
+ run: dart test --platform vm
+ if: always() && steps.install.outcome == 'success'
+ - name: Run Chrome tests
+ run: dart test --platform chrome
+ if: always() && steps.install.outcome == 'success'
diff --git a/.github/workflows/unified_analytics.yml b/.github/workflows/unified_analytics.yml
new file mode 100644
index 0000000..4b1c33e
--- /dev/null
+++ b/.github/workflows/unified_analytics.yml
@@ -0,0 +1,44 @@
+name: package:unified_analytics
+permissions: read-all
+
+on:
+ pull_request:
+ branches: [ main ]
+ paths:
+ - '.github/workflows/unified_analytics.yml'
+ - 'pkgs/unified_analytics/**'
+ push:
+ branches: [ main ]
+ paths:
+ - '.github/workflows/unified_analytics.yml'
+ - 'pkgs/unified_analytics/**'
+ schedule:
+ - cron: '0 0 * * 0' # weekly
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ defaults:
+ run:
+ working-directory: pkgs/unified_analytics
+ strategy:
+ matrix:
+ sdk: [stable, dev] # {pkgs.versions}
+ include:
+ - sdk: stable
+ run-tests: true
+ steps:
+ - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
+ - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672
+ with:
+ sdk: ${{matrix.sdk}}
+
+ - run: dart pub get
+
+ - run: dart analyze --fatal-infos
+
+ - run: dart format --output=none --set-exit-if-changed .
+ if: ${{matrix.run-tests}}
+
+ - run: dart test
+ if: ${{matrix.run-tests}}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5509140
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+*.DS_Store
diff --git a/CODEOWNERS b/CODEOWNERS
new file mode 100644
index 0000000..7694822
--- /dev/null
+++ b/CODEOWNERS
@@ -0,0 +1,5 @@
+# The CODEOWNERS file helps to define individuals or teams that responsible
+# for code within the repository
+# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
+
+/pkgs/unified_analytics/ @andrewkolos
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..3c28563
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,51 @@
+# How to Contribute
+
+We'd love to accept your patches and contributions to this project. There are
+just a few small guidelines you need to follow.
+
+## Contributor License Agreement
+
+Contributions to this project must be accompanied by a Contributor License
+Agreement (CLA). You (or your employer) retain the copyright to your
+contribution; this simply gives us permission to use and redistribute your
+contributions as part of the project. Head over to
+<https://cla.developers.google.com/> to see your current agreements on file or
+to sign a new one.
+
+You generally only need to submit a CLA once, so if you've already submitted one
+(even if it was for a different project), you probably don't need to do it
+again.
+
+## Code Reviews
+
+All submissions, including submissions by project members, require review. We
+use GitHub pull requests for this purpose. Consult
+[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
+information on using pull requests.
+
+## Coding style
+
+The Dart source code in this repo follows the:
+
+ * [Dart style guide](https://dart.dev/guides/language/effective-dart/style)
+
+You should familiarize yourself with those guidelines.
+
+## File headers
+
+All files in the Dart project must start with the following header; if you add a
+new file please also add this. The year should be a single number stating the
+year the file was created (don't use a range like "2011-2012"). Additionally, if
+you edit an existing file, you shouldn't update the year.
+
+ // Copyright (c) 2023, 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.
+
+## Community Guidelines
+
+This project follows
+[Google's Open Source Community Guidelines](https://opensource.google/conduct/).
+
+We pledge to maintain an open and welcoming environment. For details, see our
+[code of conduct](https://dart.dev/code-of-conduct).
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..4fd5739
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,27 @@
+Copyright 2023, the Dart project authors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of Google LLC nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..ac4edf2
--- /dev/null
+++ b/README.md
@@ -0,0 +1,35 @@
+<!-- [](https://github.com/dart-lang/tools/actions/workflows/dart.yml) -->
+
+## Overview
+
+This repository is home to tooling related Dart packages. Generally, this means
+packages published through the
+[tools.dart.dev](https://pub.dev/publishers/tools.dart.dev) publisher that
+don't naturally belong to other topic monorepos (like
+[dart-lang/build](https://github.com/dart-lang/build),
+[dart-lang/test](https://github.com/dart-lang/test), or
+[dart-lang/shelf](https://github.com/dart-lang/shelf)).
+
+## Packages
+
+| Package | Description | Version |
+| --- | --- | --- |
+| [boolean_selector](pkgs/boolean_selector/) | A flexible syntax for boolean expressions, based on a simplified version of Dart's expression syntax. | [](https://pub.dev/packages/boolean_selector) |
+| [cli_config](pkgs/cli_config/) | A library to take config values from configuration files, CLI arguments, and environment variables. | [](https://pub.dev/packages/cli_config) |
+| [coverage](pkgs/coverage/) | Coverage data manipulation and formatting. | [](https://pub.dev/packages/coverage) |
+| [extension_discovery](pkgs/extension_discovery/) | A convention and utilities for package extension discovery. | [](https://pub.dev/packages/extension_discovery) |
+| [file](pkgs/file/) | A pluggable, mockable file system abstraction for Dart. | [](https://pub.dev/packages/file) |
+| [file_testing](pkgs/file_testing/) | Testing utilities for package:file (published but unlisted). | [](https://pub.dev/packages/file_testing) |
+| [graphs](pkgs/graphs/) | Graph algorithms that operate on graphs in any representation | [](https://pub.dev/packages/graphs) |
+| [mime](pkgs/mime/) | Utilities for handling media (MIME) types. | [](https://pub.dev/packages/mime) |
+| [oauth2](pkgs/oauth2/) | A client library for authenticatingand making requests via OAuth2. | [](https://pub.dev/packages/oauth2) |
+| [source_map_stack_trace](pkgs/source_map_stack_trace/) | A package for applying source maps to stack traces. | [](https://pub.dev/packages/source_map_stack_trace) |
+| [unified_analytics](pkgs/unified_analytics/) | A package for logging analytics for all Dart and Flutter related tooling to Google Analytics. | [](https://pub.dev/packages/unified_analytics) |
+
+## Publishing automation
+
+For information about our publishing automation and release process, see
+https://github.com/dart-lang/ecosystem/wiki/Publishing-automation.
+
+For additional information about contributing, see our
+[contributing](CONTRIBUTING.md) page.
diff --git a/pkgs/boolean_selector/.gitignore b/pkgs/boolean_selector/.gitignore
new file mode 100644
index 0000000..49ce72d
--- /dev/null
+++ b/pkgs/boolean_selector/.gitignore
@@ -0,0 +1,3 @@
+.dart_tool/
+.packages
+pubspec.lock
diff --git a/pkgs/boolean_selector/AUTHORS b/pkgs/boolean_selector/AUTHORS
new file mode 100644
index 0000000..e8063a8
--- /dev/null
+++ b/pkgs/boolean_selector/AUTHORS
@@ -0,0 +1,6 @@
+# Below is a list of people and organizations that have contributed
+# to the project. Names should be added to the list like so:
+#
+# Name/Organization <email address>
+
+Google Inc.
diff --git a/pkgs/boolean_selector/CHANGELOG.md b/pkgs/boolean_selector/CHANGELOG.md
new file mode 100644
index 0000000..f870787
--- /dev/null
+++ b/pkgs/boolean_selector/CHANGELOG.md
@@ -0,0 +1,44 @@
+## 2.1.2
+
+* Increase the SDK minimum to `3.1.0`.
+* Move to `dart-lang/tools` monorepo.
+
+## 2.1.1
+
+* Increase the SDK minimum to `2.17.0`.
+* Populate the pubspec `repository` field.
+
+## 2.1.0
+
+* Stable release for null safety.
+
+## 2.0.0
+
+* Breaking: `BooleanSelector.evaluate` always takes a `bool Function(String)`.
+ For use cases previously passing a `Set<String>`, tear off the `.contains`
+ method. For use cases passing an `Iterable<String>` it may be worthwhile to
+ first use `.toSet()` before tearing off `.contains`.
+
+## 1.0.5
+
+* Update package metadata & add `example/` folder
+
+## 1.0.4
+
+* Now requires Dart 2.
+
+## 1.0.3
+
+* Work around an inference bug in the new common front-end.
+
+## 1.0.2
+
+* Declare compatibility with `string_scanner` 1.0.0.
+
+## 1.0.1
+
+* Fix all strong mode warnings.
+
+## 1.0.0
+
+* Initial release.
diff --git a/pkgs/boolean_selector/LICENSE b/pkgs/boolean_selector/LICENSE
new file mode 100644
index 0000000..ac7d7af
--- /dev/null
+++ b/pkgs/boolean_selector/LICENSE
@@ -0,0 +1,27 @@
+Copyright 2016, the Dart project authors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of Google LLC nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/pkgs/boolean_selector/README.md b/pkgs/boolean_selector/README.md
new file mode 100644
index 0000000..8d58dbb
--- /dev/null
+++ b/pkgs/boolean_selector/README.md
@@ -0,0 +1,42 @@
+[](https://github.com/dart-lang/tools/actions/workflows/boolean_selector.yaml)
+[](https://pub.dev/packages/boolean_selector)
+[](https://pub.dev/packages/boolean_selector/publisher)
+
+The `boolean_selector` package defines a simple and flexible syntax for boolean
+expressions. It can be used for filtering based on user-defined expressions. For
+example, the [`test`][test] package uses boolean selectors to allow users to
+define what platforms their tests support.
+
+[test]: https://github.com/dart-lang/test
+
+The boolean selector syntax is based on a simplified version of Dart's
+expression syntax. Selectors can contain identifiers, parentheses, and boolean
+operators, including `||`, `&&`, `!`, and `? :`. Any valid Dart identifier is
+allowed, and identifiers may also contain hyphens. For example, `chrome`,
+`chrome || content-shell`, and `js || (vm && linux)` are all valid boolean
+selectors.
+
+A boolean selector is parsed from a string using
+[`BooleanSelector.parse()`][parse], and evaluated against a set of variables
+using [`BooleanSelector.evaluate()`][evaluate]. The variables are supplied as
+a function that takes a variable name and returns its value. For example:
+
+[parse]: https://pub.dev/documentation/boolean_selector/latest/boolean_selector/BooleanSelector/BooleanSelector.parse.html
+
+[evaluate]: https://pub.dev/documentation/boolean_selector/latest/boolean_selector/BooleanSelector/evaluate.html
+
+```dart
+import 'package:boolean_selector/boolean_selector.dart';
+
+void main(List<String> args) {
+ var selector = BooleanSelector.parse("(x && y) || z");
+ print(selector.evaluate((variable) => args.contains(variable)));
+}
+```
+
+## Versioning
+
+If this package adds new features to the boolean selector syntax, it will
+increment its major version number. This ensures that packages that expose the
+syntax to their users will be able to update their own minor versions, so their
+users can indicate that they rely on the new syntax.
diff --git a/pkgs/boolean_selector/analysis_options.yaml b/pkgs/boolean_selector/analysis_options.yaml
new file mode 100644
index 0000000..178039f
--- /dev/null
+++ b/pkgs/boolean_selector/analysis_options.yaml
@@ -0,0 +1,7 @@
+include: package:dart_flutter_team_lints/analysis_options.yaml
+
+linter:
+ rules:
+ - avoid_unused_constructor_parameters
+ - cancel_subscriptions
+ - package_api_docs
diff --git a/pkgs/boolean_selector/example/example.dart b/pkgs/boolean_selector/example/example.dart
new file mode 100644
index 0000000..a4f7879
--- /dev/null
+++ b/pkgs/boolean_selector/example/example.dart
@@ -0,0 +1,6 @@
+import 'package:boolean_selector/boolean_selector.dart';
+
+void main(List<String> args) {
+ var selector = BooleanSelector.parse('(x && y) || z');
+ print(selector.evaluate((variable) => args.contains(variable)));
+}
diff --git a/pkgs/boolean_selector/lib/boolean_selector.dart b/pkgs/boolean_selector/lib/boolean_selector.dart
new file mode 100644
index 0000000..1c42641
--- /dev/null
+++ b/pkgs/boolean_selector/lib/boolean_selector.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:source_span/source_span.dart';
+
+import 'src/all.dart';
+import 'src/impl.dart';
+import 'src/none.dart';
+
+/// A boolean expression that evaluates to `true` or `false` based on certain
+/// inputs.
+///
+/// The syntax is mostly Dart's expression syntax restricted to boolean
+/// operations. See [the README][] for full details.
+///
+/// [the README]: https://github.com/dart-lang/boolean_selector/blob/master/README.md
+///
+/// Boolean selectors support structural equality. Two selectors that have the
+/// same parsed structure are considered equal.
+abstract class BooleanSelector {
+ /// A selector that accepts all inputs.
+ static const all = All();
+
+ /// A selector that accepts no inputs.
+ static const none = None();
+
+ /// All the variables in this selector, in the order they appear.
+ Iterable<String> get variables;
+
+ /// Parses [selector].
+ ///
+ /// This will throw a [SourceSpanFormatException] if the selector is
+ /// malformed or if it uses an undefined variable.
+ factory BooleanSelector.parse(String selector) = BooleanSelectorImpl.parse;
+
+ /// Returns whether the selector matches the given [semantics].
+ ///
+ /// The [semantics] define which variables evaluate to `true` or `false`. When
+ /// passed a variable name it should return the value of that variable.
+ bool evaluate(bool Function(String variable) semantics);
+
+ /// Returns a new [BooleanSelector] that matches only inputs matched by both
+ /// `this` and [other].
+ BooleanSelector intersection(BooleanSelector other);
+
+ /// Returns a new [BooleanSelector] that matches all inputs matched by either
+ /// `this` or [other].
+ BooleanSelector union(BooleanSelector other);
+
+ /// Throws a [FormatException] if any variables are undefined.
+ ///
+ /// The [isDefined] function should return `true` for any variables that are
+ /// considered valid, and `false` for any invalid or undefined variables.
+ void validate(bool Function(String variable) isDefined);
+}
diff --git a/pkgs/boolean_selector/lib/src/all.dart b/pkgs/boolean_selector/lib/src/all.dart
new file mode 100644
index 0000000..3424319
--- /dev/null
+++ b/pkgs/boolean_selector/lib/src/all.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import '../boolean_selector.dart';
+
+/// A selector that matches all inputs.
+class All implements BooleanSelector {
+ // TODO(nweiz): Stop explicitly providing a type argument when sdk#32412 is
+ // fixed.
+ @override
+ final Iterable<String> variables = const <String>[];
+
+ const All();
+
+ @override
+ bool evaluate(bool Function(String variable) semantics) => true;
+
+ @override
+ BooleanSelector intersection(BooleanSelector other) => other;
+
+ @override
+ BooleanSelector union(BooleanSelector other) => this;
+
+ @override
+ void validate(bool Function(String variable) isDefined) {}
+
+ @override
+ String toString() => '<all>';
+}
diff --git a/pkgs/boolean_selector/lib/src/ast.dart b/pkgs/boolean_selector/lib/src/ast.dart
new file mode 100644
index 0000000..d0d8583
--- /dev/null
+++ b/pkgs/boolean_selector/lib/src/ast.dart
@@ -0,0 +1,210 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:source_span/source_span.dart';
+
+import 'visitor.dart';
+
+/// The superclass of nodes in the boolean selector abstract syntax tree.
+abstract class Node {
+ /// The span indicating where this node came from.
+ ///
+ /// This is a [FileSpan] because the nodes are parsed from a single continuous
+ /// string, but the string itself isn't actually a file. It might come from a
+ /// statically-parsed annotation or from a parameter.
+ ///
+ /// This may be `null` for nodes without source information.
+ FileSpan? get span;
+
+ /// All the variables in this node, in the order they appear.
+ Iterable<String> get variables;
+
+ /// Calls the appropriate [Visitor] method on `this` and returns the result.
+ T accept<T>(Visitor<T> visitor);
+}
+
+/// A single variable.
+class VariableNode implements Node {
+ @override
+ final FileSpan? span;
+
+ /// The variable name.
+ final String name;
+
+ @override
+ Iterable<String> get variables => [name];
+
+ VariableNode(this.name, [this.span]);
+
+ @override
+ T accept<T>(Visitor<T> visitor) => visitor.visitVariable(this);
+
+ @override
+ String toString() => name;
+
+ @override
+ bool operator ==(Object other) => other is VariableNode && name == other.name;
+
+ @override
+ int get hashCode => name.hashCode;
+}
+
+/// A negation expression.
+class NotNode implements Node {
+ @override
+ final FileSpan? span;
+
+ /// The expression being negated.
+ final Node child;
+
+ @override
+ Iterable<String> get variables => child.variables;
+
+ NotNode(this.child, [this.span]);
+
+ @override
+ T accept<T>(Visitor<T> visitor) => visitor.visitNot(this);
+
+ @override
+ String toString() =>
+ child is VariableNode || child is NotNode ? '!$child' : '!($child)';
+
+ @override
+ bool operator ==(Object other) => other is NotNode && child == other.child;
+
+ @override
+ int get hashCode => ~child.hashCode;
+}
+
+/// An or expression.
+class OrNode implements Node {
+ @override
+ FileSpan? get span => _expandSafe(left.span, right.span);
+
+ /// The left-hand branch of the expression.
+ final Node left;
+
+ /// The right-hand branch of the expression.
+ final Node right;
+
+ @override
+ Iterable<String> get variables sync* {
+ yield* left.variables;
+ yield* right.variables;
+ }
+
+ OrNode(this.left, this.right);
+
+ @override
+ T accept<T>(Visitor<T> visitor) => visitor.visitOr(this);
+
+ @override
+ String toString() {
+ var string1 = left is AndNode || left is ConditionalNode ? '($left)' : left;
+ var string2 =
+ right is AndNode || right is ConditionalNode ? '($right)' : right;
+
+ return '$string1 || $string2';
+ }
+
+ @override
+ bool operator ==(Object other) =>
+ other is OrNode && left == other.left && right == other.right;
+
+ @override
+ int get hashCode => left.hashCode ^ right.hashCode;
+}
+
+/// An and expression.
+class AndNode implements Node {
+ @override
+ FileSpan? get span => _expandSafe(left.span, right.span);
+
+ /// The left-hand branch of the expression.
+ final Node left;
+
+ /// The right-hand branch of the expression.
+ final Node right;
+
+ @override
+ Iterable<String> get variables sync* {
+ yield* left.variables;
+ yield* right.variables;
+ }
+
+ AndNode(this.left, this.right);
+
+ @override
+ T accept<T>(Visitor<T> visitor) => visitor.visitAnd(this);
+
+ @override
+ String toString() {
+ var string1 = left is OrNode || left is ConditionalNode ? '($left)' : left;
+ var string2 =
+ right is OrNode || right is ConditionalNode ? '($right)' : right;
+
+ return '$string1 && $string2';
+ }
+
+ @override
+ bool operator ==(Object other) =>
+ other is AndNode && left == other.left && right == other.right;
+
+ @override
+ int get hashCode => left.hashCode ^ right.hashCode;
+}
+
+/// A ternary conditional expression.
+class ConditionalNode implements Node {
+ @override
+ FileSpan? get span => _expandSafe(condition.span, whenFalse.span);
+
+ /// The condition expression to check.
+ final Node condition;
+
+ /// The branch to run if the condition is true.
+ final Node whenTrue;
+
+ /// The branch to run if the condition is false.
+ final Node whenFalse;
+
+ @override
+ Iterable<String> get variables sync* {
+ yield* condition.variables;
+ yield* whenTrue.variables;
+ yield* whenFalse.variables;
+ }
+
+ ConditionalNode(this.condition, this.whenTrue, this.whenFalse);
+
+ @override
+ T accept<T>(Visitor<T> visitor) => visitor.visitConditional(this);
+
+ @override
+ String toString() {
+ var conditionString =
+ condition is ConditionalNode ? '($condition)' : condition;
+ var trueString = whenTrue is ConditionalNode ? '($whenTrue)' : whenTrue;
+ return '$conditionString ? $trueString : $whenFalse';
+ }
+
+ @override
+ bool operator ==(Object other) =>
+ other is ConditionalNode &&
+ condition == other.condition &&
+ whenTrue == other.whenTrue &&
+ whenFalse == other.whenFalse;
+
+ @override
+ int get hashCode =>
+ condition.hashCode ^ whenTrue.hashCode ^ whenFalse.hashCode;
+}
+
+/// Like [FileSpan.expand], except if [start] and [end] are `null` or from
+/// different files it returns `null` rather than throwing an error.
+FileSpan? _expandSafe(FileSpan? start, FileSpan? end) {
+ if (start == null || end == null) return null;
+ if (start.file != end.file) return null;
+ return start.expand(end);
+}
diff --git a/pkgs/boolean_selector/lib/src/evaluator.dart b/pkgs/boolean_selector/lib/src/evaluator.dart
new file mode 100644
index 0000000..ee57149
--- /dev/null
+++ b/pkgs/boolean_selector/lib/src/evaluator.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'ast.dart';
+import 'visitor.dart';
+
+/// A visitor for evaluating boolean selectors against a specific set of
+/// semantics.
+class Evaluator implements Visitor<bool> {
+ final bool Function(String variable) _semantics;
+
+ Evaluator(this._semantics);
+
+ @override
+ bool visitVariable(VariableNode node) => _semantics(node.name);
+
+ @override
+ bool visitNot(NotNode node) => !node.child.accept(this);
+
+ @override
+ bool visitOr(OrNode node) =>
+ node.left.accept(this) || node.right.accept(this);
+
+ @override
+ bool visitAnd(AndNode node) =>
+ node.left.accept(this) && node.right.accept(this);
+
+ @override
+ bool visitConditional(ConditionalNode node) => node.condition.accept(this)
+ ? node.whenTrue.accept(this)
+ : node.whenFalse.accept(this);
+}
diff --git a/pkgs/boolean_selector/lib/src/impl.dart b/pkgs/boolean_selector/lib/src/impl.dart
new file mode 100644
index 0000000..cafb1a4
--- /dev/null
+++ b/pkgs/boolean_selector/lib/src/impl.dart
@@ -0,0 +1,72 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:source_span/source_span.dart';
+
+import '../boolean_selector.dart';
+import 'ast.dart';
+import 'evaluator.dart';
+import 'intersection_selector.dart';
+import 'parser.dart';
+import 'union_selector.dart';
+import 'validator.dart';
+
+/// The concrete implementation of a [BooleanSelector] parsed from a string.
+///
+/// This is separate from [BooleanSelector] so that [intersection] and [union]
+/// can check to see whether they're passed a [BooleanSelectorImpl] or a
+/// different class that implements [BooleanSelector].
+class BooleanSelectorImpl implements BooleanSelector {
+ /// The parsed AST.
+ final Node _selector;
+
+ /// Parses [selector].
+ ///
+ /// This will throw a [SourceSpanFormatException] if the selector is
+ /// malformed or if it uses an undefined variable.
+ BooleanSelectorImpl.parse(String selector)
+ : _selector = Parser(selector).parse();
+
+ BooleanSelectorImpl._(this._selector);
+
+ @override
+ Iterable<String> get variables => _selector.variables;
+
+ @override
+ bool evaluate(bool Function(String variable) semantics) =>
+ _selector.accept(Evaluator(semantics));
+
+ @override
+ BooleanSelector intersection(BooleanSelector other) {
+ if (other == BooleanSelector.all) return this;
+ if (other == BooleanSelector.none) return other;
+ return other is BooleanSelectorImpl
+ ? BooleanSelectorImpl._(AndNode(_selector, other._selector))
+ : IntersectionSelector(this, other);
+ }
+
+ @override
+ BooleanSelector union(BooleanSelector other) {
+ if (other == BooleanSelector.all) return other;
+ if (other == BooleanSelector.none) return this;
+ return other is BooleanSelectorImpl
+ ? BooleanSelectorImpl._(OrNode(_selector, other._selector))
+ : UnionSelector(this, other);
+ }
+
+ @override
+ void validate(bool Function(String variable) isDefined) {
+ _selector.accept(Validator(isDefined));
+ }
+
+ @override
+ String toString() => _selector.toString();
+
+ @override
+ bool operator ==(Object other) =>
+ other is BooleanSelectorImpl && _selector == other._selector;
+
+ @override
+ int get hashCode => _selector.hashCode;
+}
diff --git a/pkgs/boolean_selector/lib/src/intersection_selector.dart b/pkgs/boolean_selector/lib/src/intersection_selector.dart
new file mode 100644
index 0000000..3bf468c
--- /dev/null
+++ b/pkgs/boolean_selector/lib/src/intersection_selector.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import '../boolean_selector.dart';
+import 'union_selector.dart';
+
+/// A selector that matches inputs that both of its sub-selectors match.
+class IntersectionSelector implements BooleanSelector {
+ final BooleanSelector _selector1;
+ final BooleanSelector _selector2;
+
+ @override
+ Iterable<String> get variables sync* {
+ yield* _selector1.variables;
+ yield* _selector2.variables;
+ }
+
+ IntersectionSelector(this._selector1, this._selector2);
+
+ @override
+ bool evaluate(bool Function(String variable) semantics) =>
+ _selector1.evaluate(semantics) && _selector2.evaluate(semantics);
+
+ @override
+ BooleanSelector intersection(BooleanSelector other) =>
+ IntersectionSelector(this, other);
+
+ @override
+ BooleanSelector union(BooleanSelector other) => UnionSelector(this, other);
+
+ @override
+ void validate(bool Function(String variable) isDefined) {
+ _selector1.validate(isDefined);
+ _selector2.validate(isDefined);
+ }
+
+ @override
+ String toString() => '($_selector1) && ($_selector2)';
+
+ @override
+ bool operator ==(Object other) =>
+ other is IntersectionSelector &&
+ _selector1 == other._selector1 &&
+ _selector2 == other._selector2;
+
+ @override
+ int get hashCode => _selector1.hashCode ^ _selector2.hashCode;
+}
diff --git a/pkgs/boolean_selector/lib/src/none.dart b/pkgs/boolean_selector/lib/src/none.dart
new file mode 100644
index 0000000..08ac08a
--- /dev/null
+++ b/pkgs/boolean_selector/lib/src/none.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import '../boolean_selector.dart';
+
+/// A selector that matches no inputs.
+class None implements BooleanSelector {
+ @override
+ final Iterable<String> variables = const [];
+
+ const None();
+
+ @override
+ bool evaluate(bool Function(String variable) semantics) => false;
+
+ @override
+ BooleanSelector intersection(BooleanSelector other) => this;
+
+ @override
+ BooleanSelector union(BooleanSelector other) => other;
+
+ @override
+ void validate(bool Function(String) isDefined) {}
+
+ @override
+ String toString() => '<none>';
+}
diff --git a/pkgs/boolean_selector/lib/src/parser.dart b/pkgs/boolean_selector/lib/src/parser.dart
new file mode 100644
index 0000000..368ce5e
--- /dev/null
+++ b/pkgs/boolean_selector/lib/src/parser.dart
@@ -0,0 +1,103 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:source_span/source_span.dart';
+
+import 'ast.dart';
+import 'scanner.dart';
+import 'token.dart';
+
+/// A class for parsing a boolean selector.
+///
+/// Boolean selectors use a stripped-down version of the Dart expression syntax
+/// that only contains variables, parentheses, and boolean operators. Variables
+/// may also contain dashes, contrary to Dart's syntax; this allows consistency
+/// with command-line arguments.
+class Parser {
+ /// The scanner that tokenizes the selector.
+ final Scanner _scanner;
+
+ Parser(String selector) : _scanner = Scanner(selector);
+
+ /// Parses the selector.
+ ///
+ /// This must only be called once per parser.
+ Node parse() {
+ var selector = _conditional();
+
+ if (_scanner.peek().type != TokenType.endOfFile) {
+ throw SourceSpanFormatException(
+ 'Expected end of input.', _scanner.peek().span);
+ }
+
+ return selector;
+ }
+
+ /// Parses a conditional:
+ ///
+ /// conditionalExpression:
+ /// logicalOrExpression ("?" conditionalExpression ":"
+ /// conditionalExpression)?
+ Node _conditional() {
+ var condition = _or();
+ if (!_scanner.scan(TokenType.questionMark)) return condition;
+
+ var whenTrue = _conditional();
+ if (!_scanner.scan(TokenType.colon)) {
+ throw SourceSpanFormatException('Expected ":".', _scanner.peek().span);
+ }
+
+ var whenFalse = _conditional();
+ return ConditionalNode(condition, whenTrue, whenFalse);
+ }
+
+ /// Parses a logical or:
+ ///
+ /// logicalOrExpression:
+ /// logicalAndExpression ("||" logicalOrExpression)?
+ Node _or() {
+ var left = _and();
+ if (!_scanner.scan(TokenType.or)) return left;
+ return OrNode(left, _or());
+ }
+
+ /// Parses a logical and:
+ ///
+ /// logicalAndExpression:
+ /// simpleExpression ("&&" logicalAndExpression)?
+ Node _and() {
+ var left = _simpleExpression();
+ if (!_scanner.scan(TokenType.and)) return left;
+ return AndNode(left, _and());
+ }
+
+ /// Parses a simple expression:
+ ///
+ /// simpleExpression:
+ /// "!" simpleExpression |
+ /// "(" conditionalExpression ")" |
+ /// IDENTIFIER
+ Node _simpleExpression() {
+ var token = _scanner.next();
+ switch (token.type) {
+ case TokenType.not:
+ var child = _simpleExpression();
+ return NotNode(child, token.span.expand(child.span!));
+
+ case TokenType.leftParen:
+ var child = _conditional();
+ if (!_scanner.scan(TokenType.rightParen)) {
+ throw SourceSpanFormatException(
+ 'Expected ")".', _scanner.peek().span);
+ }
+ return child;
+
+ case TokenType.identifier:
+ return VariableNode((token as IdentifierToken).name, token.span);
+
+ default:
+ throw SourceSpanFormatException('Expected expression.', token.span);
+ }
+ }
+}
diff --git a/pkgs/boolean_selector/lib/src/scanner.dart b/pkgs/boolean_selector/lib/src/scanner.dart
new file mode 100644
index 0000000..25c4a11
--- /dev/null
+++ b/pkgs/boolean_selector/lib/src/scanner.dart
@@ -0,0 +1,144 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:string_scanner/string_scanner.dart';
+
+import 'token.dart';
+
+/// A regular expression matching both whitespace and single-line comments.
+///
+/// This will only match if consumes at least one character.
+final _whitespaceAndSingleLineComments = RegExp(r'([ \t\n]+|//[^\n]*(\n|$))+');
+
+/// A regular expression matching the body of a multi-line comment, after `/*`
+/// but before `*/` or a nested `/*`.
+///
+/// This will only match if it consumes at least one character.
+final _multiLineCommentBody = RegExp(r'([^/*]|/[^*]|\*[^/])+');
+
+/// A regular expression matching a hyphenated identifier.
+///
+/// This is like a standard Dart identifier, except that it can also contain
+/// hyphens.
+final _hyphenatedIdentifier = RegExp(r'[a-zA-Z_-][a-zA-Z0-9_-]*');
+
+/// A scanner that converts a boolean selector string into a stream of tokens.
+class Scanner {
+ /// The underlying string scanner.
+ final SpanScanner _scanner;
+
+ /// The next token to emit.
+ Token? _next;
+
+ /// Whether the scanner has emitted a [TokenType.endOfFile] token.
+ bool _endOfFileEmitted = false;
+
+ Scanner(String selector) : _scanner = SpanScanner(selector);
+
+ /// Returns the next token that will be returned by [next].
+ ///
+ /// Throws a [StateError] if a [TokenType.endOfFile] token has already been
+ /// consumed.
+ Token peek() => _next ??= _readNext();
+
+ /// Consumes and returns the next token in the stream.
+ ///
+ /// Throws a [StateError] if a [TokenType.endOfFile] token has already been
+ /// consumed.
+ Token next() {
+ var token = _next ?? _readNext();
+ _endOfFileEmitted = token.type == TokenType.endOfFile;
+ _next = null;
+ return token;
+ }
+
+ /// If the next token matches [type], consumes it and returns `true`;
+ /// otherwise, returns `false`.
+ ///
+ /// Throws a [StateError] if a [TokenType.endOfFile] token has already been
+ /// consumed.
+ bool scan(TokenType type) {
+ if (peek().type != type) return false;
+ next();
+ return true;
+ }
+
+ /// Scan and return the next token in the stream.
+ Token _readNext() {
+ if (_endOfFileEmitted) throw StateError('No more tokens.');
+
+ _consumeWhitespace();
+ if (_scanner.isDone) {
+ return Token(TokenType.endOfFile, _scanner.spanFrom(_scanner.state));
+ }
+
+ return switch (_scanner.peekChar()) {
+ 0x28 /* ( */ => _scanOperator(TokenType.leftParen),
+ 0x29 /* ) */ => _scanOperator(TokenType.rightParen),
+ 0x3F /* ? */ => _scanOperator(TokenType.questionMark),
+ 0x3A /* : */ => _scanOperator(TokenType.colon),
+ 0x21 /* ! */ => _scanOperator(TokenType.not),
+ 0x7C /* | */ => _scanOr(),
+ 0x26 /* & */ => _scanAnd(),
+ _ => _scanIdentifier()
+ };
+ }
+
+ /// Scans a single-character operator and returns a token of type [type].
+ ///
+ /// This assumes that the caller has already verified that the next character
+ /// is correct for the given operator.
+ Token _scanOperator(TokenType type) {
+ var start = _scanner.state;
+ _scanner.readChar();
+ return Token(type, _scanner.spanFrom(start));
+ }
+
+ /// Scans a `||` operator and returns the appropriate token.
+ ///
+ /// This validates that the next two characters are `||`.
+ Token _scanOr() {
+ var start = _scanner.state;
+ _scanner.expect('||');
+ return Token(TokenType.or, _scanner.spanFrom(start));
+ }
+
+ /// Scans a `&&` operator and returns the appropriate token.
+ ///
+ /// This validates that the next two characters are `&&`.
+ Token _scanAnd() {
+ var start = _scanner.state;
+ _scanner.expect('&&');
+ return Token(TokenType.and, _scanner.spanFrom(start));
+ }
+
+ /// Scans and returns an identifier token.
+ Token _scanIdentifier() {
+ _scanner.expect(_hyphenatedIdentifier, name: 'expression');
+ return IdentifierToken(_scanner.lastMatch![0]!, _scanner.lastSpan!);
+ }
+
+ /// Consumes all whitespace and comments immediately following the cursor's
+ /// current position.
+ void _consumeWhitespace() {
+ while (_scanner.scan(_whitespaceAndSingleLineComments) ||
+ _multiLineComment()) {
+ // Do nothing.
+ }
+ }
+
+ /// Consumes a single multi-line comment.
+ ///
+ /// Returns whether or not a comment was consumed.
+ bool _multiLineComment() {
+ if (!_scanner.scan('/*')) return false;
+
+ while (_scanner.scan(_multiLineCommentBody) || _multiLineComment()) {
+ // Do nothing.
+ }
+ _scanner.expect('*/');
+
+ return true;
+ }
+}
diff --git a/pkgs/boolean_selector/lib/src/token.dart b/pkgs/boolean_selector/lib/src/token.dart
new file mode 100644
index 0000000..19e6864
--- /dev/null
+++ b/pkgs/boolean_selector/lib/src/token.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:source_span/source_span.dart';
+
+/// A token in a boolean selector.
+class Token {
+ /// The type of the token.
+ final TokenType type;
+
+ /// The span indicating where this token came from.
+ ///
+ /// This is a [FileSpan] because the tokens are parsed from a single
+ /// continuous string, but the string itself isn't actually a file. It might
+ /// come from a statically-parsed annotation or from a parameter.
+ final FileSpan span;
+
+ Token(this.type, this.span);
+}
+
+/// A token representing an identifier.
+class IdentifierToken implements Token {
+ @override
+ final type = TokenType.identifier;
+ @override
+ final FileSpan span;
+
+ /// The name of the identifier.
+ final String name;
+
+ IdentifierToken(this.name, this.span);
+
+ @override
+ String toString() => 'identifier "$name"';
+}
+
+/// An enumeration of types of tokens.
+class TokenType {
+ /// A `(` character.
+ static const leftParen = TokenType._('left paren');
+
+ /// A `)` character.
+ static const rightParen = TokenType._('right paren');
+
+ /// A `||` sequence.
+ static const or = TokenType._('or');
+
+ /// A `&&` sequence.
+ static const and = TokenType._('and');
+
+ /// A `!` character.
+ static const not = TokenType._('not');
+
+ /// A `?` character.
+ static const questionMark = TokenType._('question mark');
+
+ /// A `:` character.
+ static const colon = TokenType._('colon');
+
+ /// A named identifier.
+ static const identifier = TokenType._('identifier');
+
+ /// The end of the selector.
+ static const endOfFile = TokenType._('end of file');
+
+ /// The name of the token type.
+ final String name;
+
+ const TokenType._(this.name);
+
+ @override
+ String toString() => name;
+}
diff --git a/pkgs/boolean_selector/lib/src/union_selector.dart b/pkgs/boolean_selector/lib/src/union_selector.dart
new file mode 100644
index 0000000..e355eb2
--- /dev/null
+++ b/pkgs/boolean_selector/lib/src/union_selector.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import '../boolean_selector.dart';
+import 'intersection_selector.dart';
+
+/// A selector that matches inputs that either of its sub-selectors match.
+class UnionSelector implements BooleanSelector {
+ final BooleanSelector _selector1;
+ final BooleanSelector _selector2;
+
+ UnionSelector(this._selector1, this._selector2);
+
+ @override
+ List<String> get variables =>
+ _selector1.variables.toList()..addAll(_selector2.variables);
+
+ @override
+ bool evaluate(bool Function(String variable) semantics) =>
+ _selector1.evaluate(semantics) || _selector2.evaluate(semantics);
+
+ @override
+ BooleanSelector intersection(BooleanSelector other) =>
+ IntersectionSelector(this, other);
+
+ @override
+ BooleanSelector union(BooleanSelector other) => UnionSelector(this, other);
+
+ @override
+ void validate(bool Function(String variable) isDefined) {
+ _selector1.validate(isDefined);
+ _selector2.validate(isDefined);
+ }
+
+ @override
+ String toString() => '($_selector1) && ($_selector2)';
+
+ @override
+ bool operator ==(Object other) =>
+ other is UnionSelector &&
+ _selector1 == other._selector1 &&
+ _selector2 == other._selector2;
+
+ @override
+ int get hashCode => _selector1.hashCode ^ _selector2.hashCode;
+}
diff --git a/pkgs/boolean_selector/lib/src/validator.dart b/pkgs/boolean_selector/lib/src/validator.dart
new file mode 100644
index 0000000..a7f49f2
--- /dev/null
+++ b/pkgs/boolean_selector/lib/src/validator.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:source_span/source_span.dart';
+
+import 'ast.dart';
+import 'visitor.dart';
+
+typedef _IsDefined = bool Function(String variable);
+
+/// An AST visitor that ensures that all variables are valid.
+class Validator extends RecursiveVisitor {
+ final _IsDefined _isDefined;
+
+ Validator(this._isDefined);
+
+ @override
+ void visitVariable(VariableNode node) {
+ if (_isDefined(node.name)) return;
+ throw SourceSpanFormatException('Undefined variable.', node.span);
+ }
+}
diff --git a/pkgs/boolean_selector/lib/src/visitor.dart b/pkgs/boolean_selector/lib/src/visitor.dart
new file mode 100644
index 0000000..c6808c2
--- /dev/null
+++ b/pkgs/boolean_selector/lib/src/visitor.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'ast.dart';
+
+/// The interface for visitors of the boolean selector AST.
+abstract class Visitor<T> {
+ T visitVariable(VariableNode node);
+ T visitNot(NotNode node);
+ T visitOr(OrNode node);
+ T visitAnd(AndNode node);
+ T visitConditional(ConditionalNode node);
+}
+
+/// An abstract superclass for side-effect-based visitors.
+///
+/// The default implementations of this visitor's methods just traverse the AST
+/// and do nothing with it.
+abstract class RecursiveVisitor implements Visitor<void> {
+ const RecursiveVisitor();
+
+ @override
+ void visitVariable(VariableNode node) {}
+
+ @override
+ void visitNot(NotNode node) {
+ node.child.accept(this);
+ }
+
+ @override
+ void visitOr(OrNode node) {
+ node.left.accept(this);
+ node.right.accept(this);
+ }
+
+ @override
+ void visitAnd(AndNode node) {
+ node.left.accept(this);
+ node.right.accept(this);
+ }
+
+ @override
+ void visitConditional(ConditionalNode node) {
+ node.condition.accept(this);
+ node.whenTrue.accept(this);
+ node.whenFalse.accept(this);
+ }
+}
diff --git a/pkgs/boolean_selector/pubspec.yaml b/pkgs/boolean_selector/pubspec.yaml
new file mode 100644
index 0000000..8d9a8b6
--- /dev/null
+++ b/pkgs/boolean_selector/pubspec.yaml
@@ -0,0 +1,17 @@
+name: boolean_selector
+version: 2.1.2
+description: >-
+ A flexible syntax for boolean expressions, based on a simplified version of
+ Dart's expression syntax.
+repository: https://github.com/dart-lang/tools/tree/main/pkgs/boolean_selector
+
+environment:
+ sdk: ^3.1.0
+
+dependencies:
+ source_span: ^1.8.0
+ string_scanner: ^1.1.0
+
+dev_dependencies:
+ dart_flutter_team_lints: ^3.0.0
+ test: ^1.16.0
diff --git a/pkgs/boolean_selector/test/equality_test.dart b/pkgs/boolean_selector/test/equality_test.dart
new file mode 100644
index 0000000..c5ccb64
--- /dev/null
+++ b/pkgs/boolean_selector/test/equality_test.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:boolean_selector/boolean_selector.dart';
+import 'package:test/test.dart';
+
+void main() {
+ test('variable', () {
+ _expectEqualsSelf('foo');
+ });
+
+ test('not', () {
+ _expectEqualsSelf('!foo');
+ });
+
+ test('or', () {
+ _expectEqualsSelf('foo || bar');
+ });
+
+ test('and', () {
+ _expectEqualsSelf('foo && bar');
+ });
+
+ test('conditional', () {
+ _expectEqualsSelf('foo ? bar : baz');
+ });
+
+ test('all', () {
+ expect(BooleanSelector.all, equals(BooleanSelector.all));
+ });
+
+ test('none', () {
+ expect(BooleanSelector.none, equals(BooleanSelector.none));
+ });
+
+ test("redundant parens don't matter", () {
+ expect(BooleanSelector.parse('foo && (bar && baz)'),
+ equals(BooleanSelector.parse('foo && (bar && baz)')));
+ });
+
+ test('meaningful parens do matter', () {
+ expect(BooleanSelector.parse('(foo && bar) || baz'),
+ equals(BooleanSelector.parse('foo && bar || baz')));
+ });
+}
+
+void _expectEqualsSelf(String selector) {
+ expect(
+ BooleanSelector.parse(selector), equals(BooleanSelector.parse(selector)));
+}
diff --git a/pkgs/boolean_selector/test/evaluate_test.dart b/pkgs/boolean_selector/test/evaluate_test.dart
new file mode 100644
index 0000000..2d94906
--- /dev/null
+++ b/pkgs/boolean_selector/test/evaluate_test.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:boolean_selector/boolean_selector.dart';
+import 'package:test/test.dart';
+
+void main() {
+ group('operator:', () {
+ test('conditional', () {
+ _expectEval('true ? true : false', true);
+ _expectEval('true ? false : true', false);
+ _expectEval('false ? true : false', false);
+ _expectEval('false ? false : true', true);
+ });
+
+ test('or', () {
+ _expectEval('true || true', true);
+ _expectEval('true || false', true);
+ _expectEval('false || true', true);
+ _expectEval('false || false', false);
+ });
+
+ test('and', () {
+ _expectEval('true && true', true);
+ _expectEval('true && false', false);
+ _expectEval('false && true', false);
+ _expectEval('false && false', false);
+ });
+
+ test('not', () {
+ _expectEval('!true', false);
+ _expectEval('!false', true);
+ });
+ });
+
+ test('with a semantics function', () {
+ _expectEval('foo', false, semantics: (variable) => variable.contains('a'));
+ _expectEval('bar', true, semantics: (variable) => variable.contains('a'));
+ _expectEval('baz', true, semantics: (variable) => variable.contains('a'));
+ });
+}
+
+/// Asserts that [expression] evaluates to [result] against [semantics].
+///
+/// By default, "true" is true and all other variables are "false".
+void _expectEval(String expression, bool result,
+ {bool Function(String variable)? semantics}) {
+ expect(_eval(expression, semantics: semantics), equals(result),
+ reason: 'Expected "$expression" to evaluate to $result.');
+}
+
+/// Returns the result of evaluating [expression] on [semantics].
+///
+/// By default, "true" is true and all other variables are "false".
+bool _eval(String expression, {bool Function(String variable)? semantics}) {
+ var selector = BooleanSelector.parse(expression);
+ return selector.evaluate(semantics ?? (v) => v == 'true');
+}
diff --git a/pkgs/boolean_selector/test/parser_test.dart b/pkgs/boolean_selector/test/parser_test.dart
new file mode 100644
index 0000000..ba55e70
--- /dev/null
+++ b/pkgs/boolean_selector/test/parser_test.dart
@@ -0,0 +1,298 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:boolean_selector/src/ast.dart';
+import 'package:boolean_selector/src/parser.dart';
+import 'package:test/test.dart';
+
+/// A matcher that asserts that a value is a [ConditionalNode].
+const _isConditionalNode = TypeMatcher<ConditionalNode>();
+
+/// A matcher that asserts that a value is an [OrNode].
+const _isOrNode = TypeMatcher<OrNode>();
+
+/// A matcher that asserts that a value is an [AndNode].
+const _isAndNode = TypeMatcher<AndNode>();
+
+/// A matcher that asserts that a value is a [NotNode].
+const _isNotNode = TypeMatcher<NotNode>();
+
+void main() {
+ group('parses a conditional expression', () {
+ test('with identifiers', () {
+ var node = _parse(' a ? b : c ');
+ expect(node.toString(), equals('a ? b : c'));
+
+ expect(node.span, isNotNull);
+ expect(node.span!.text, equals('a ? b : c'));
+ expect(node.span!.start.offset, equals(2));
+ expect(node.span!.end.offset, equals(11));
+ });
+
+ test('with nested ors', () {
+ // Should parse as "(a || b) ? (c || d) : (e || f)".
+ // Should not parse as "a || (b ? (c || d) : (e || f))".
+ // Should not parse as "((a || b) ? (c || d) : e) || f".
+ // Should not parse as "a || (b ? (c || d) : e) || f".
+ _expectToString('a || b ? c || d : e || f', 'a || b ? c || d : e || f');
+ });
+
+ test('with a conditional expression as branch 1', () {
+ // Should parse as "a ? (b ? c : d) : e".
+ var node = _parse('a ? b ? c : d : e');
+ expect(node, _isConditionalNode);
+ node as ConditionalNode; // promote node
+
+ expect(node.condition, _isVar('a'));
+ expect(node.whenFalse, _isVar('e'));
+
+ expect(node.whenTrue, _isConditionalNode);
+ var whenTrue = node.whenTrue as ConditionalNode;
+ expect(whenTrue.condition, _isVar('b'));
+ expect(whenTrue.whenTrue, _isVar('c'));
+ expect(whenTrue.whenFalse, _isVar('d'));
+ });
+
+ test('with a conditional expression as branch 2', () {
+ // Should parse as "a ? b : (c ? d : e)".
+ // Should not parse as "(a ? b : c) ? d : e".
+ var node = _parse('a ? b : c ? d : e');
+ expect(node, _isConditionalNode);
+ node as ConditionalNode; //promote node
+
+ expect(node.condition, _isVar('a'));
+ expect(node.whenTrue, _isVar('b'));
+
+ expect(node.whenFalse, _isConditionalNode);
+ var whenFalse = node.whenFalse as ConditionalNode;
+ expect(whenFalse.condition, _isVar('c'));
+ expect(whenFalse.whenTrue, _isVar('d'));
+ expect(whenFalse.whenFalse, _isVar('e'));
+ });
+
+ group('which must have', () {
+ test('an expression after the ?', () {
+ expect(() => _parse('a ?'), throwsFormatException);
+ expect(() => _parse('a ? && b'), throwsFormatException);
+ });
+
+ test('a :', () {
+ expect(() => _parse('a ? b'), throwsFormatException);
+ expect(() => _parse('a ? b && c'), throwsFormatException);
+ });
+
+ test('an expression after the :', () {
+ expect(() => _parse('a ? b :'), throwsFormatException);
+ expect(() => _parse('a ? b : && c'), throwsFormatException);
+ });
+ });
+ });
+
+ group('parses an or expression', () {
+ test('with identifiers', () {
+ var node = _parse(' a || b ');
+ expect(node, _isOrNode);
+ node as OrNode; //promote node
+
+ expect(node.left, _isVar('a'));
+ expect(node.right, _isVar('b'));
+
+ expect(node.span, isNotNull);
+ expect(node.span!.text, equals('a || b'));
+ expect(node.span!.start.offset, equals(2));
+ expect(node.span!.end.offset, equals(8));
+ });
+
+ test('with nested ands', () {
+ // Should parse as "(a && b) || (c && d)".
+ // Should not parse as "a && (b || c) && d".
+ var node = _parse('a && b || c && d');
+ expect(node, _isOrNode);
+ node as OrNode; //promote node
+
+ expect(node.left, _isAndNode);
+ var left = node.left as AndNode;
+ expect(left.left, _isVar('a'));
+ expect(left.right, _isVar('b'));
+
+ expect(node.right, _isAndNode);
+ var right = node.right as AndNode;
+ expect(right.left, _isVar('c'));
+ expect(right.right, _isVar('d'));
+ });
+
+ test('with trailing ors', () {
+ // Should parse as "a || (b || (c || d))", although it doesn't affect the
+ // semantics.
+ var node = _parse('a || b || c || d');
+
+ for (var variable in ['a', 'b', 'c']) {
+ expect(node, _isOrNode);
+ node as OrNode; //promote node
+
+ expect(node.left, _isVar(variable));
+ node = node.right;
+ }
+ expect(node, _isVar('d'));
+ });
+
+ test('which must have an expression after the ||', () {
+ expect(() => _parse('a ||'), throwsFormatException);
+ expect(() => _parse('a || && b'), throwsFormatException);
+ });
+ });
+
+ group('parses an and expression', () {
+ test('with identifiers', () {
+ var node = _parse(' a && b ');
+ expect(node, _isAndNode);
+ node as AndNode; //promote node
+
+ expect(node.left, _isVar('a'));
+ expect(node.right, _isVar('b'));
+
+ expect(node.span, isNotNull);
+ expect(node.span!.text, equals('a && b'));
+ expect(node.span!.start.offset, equals(2));
+ expect(node.span!.end.offset, equals(8));
+ });
+
+ test('with nested nots', () {
+ // Should parse as "(!a) && (!b)", obviously.
+ // Should not parse as "!(a && (!b))".
+ var node = _parse('!a && !b');
+ expect(node, _isAndNode);
+ node as AndNode; //promote node
+
+ expect(node.left, _isNotNode);
+ var left = node.left as NotNode;
+ expect(left.child, _isVar('a'));
+
+ expect(node.right, _isNotNode);
+ var right = node.right as NotNode;
+ expect(right.child, _isVar('b'));
+ });
+
+ test('with trailing ands', () {
+ // Should parse as "a && (b && (c && d))", although it doesn't affect the
+ // semantics since .
+ var node = _parse('a && b && c && d');
+
+ for (var variable in ['a', 'b', 'c']) {
+ expect(node, _isAndNode);
+ node as AndNode; //promote node
+
+ expect(node.left, _isVar(variable));
+ node = node.right;
+ }
+ expect(node, _isVar('d'));
+ });
+
+ test('which must have an expression after the &&', () {
+ expect(() => _parse('a &&'), throwsFormatException);
+ expect(() => _parse('a && && b'), throwsFormatException);
+ });
+ });
+
+ group('parses a not expression', () {
+ test('with an identifier', () {
+ var node = _parse(' ! a ');
+ expect(node, _isNotNode);
+ node as NotNode; //promote node
+ expect(node.child, _isVar('a'));
+
+ expect(node.span, isNotNull);
+ expect(node.span!.text, equals('! a'));
+ expect(node.span!.start.offset, equals(2));
+ expect(node.span!.end.offset, equals(5));
+ });
+
+ test('with a parenthesized expression', () {
+ var node = _parse('!(a || b)');
+ expect(node, _isNotNode);
+ node as NotNode; //promote node
+
+ expect(node.child, _isOrNode);
+ var child = node.child as OrNode;
+ expect(child.left, _isVar('a'));
+ expect(child.right, _isVar('b'));
+ });
+
+ test('with a nested not', () {
+ var node = _parse('!!a');
+ expect(node, _isNotNode);
+ node as NotNode; //promote node
+
+ expect(node.child, _isNotNode);
+ var child = node.child as NotNode;
+ expect(child.child, _isVar('a'));
+ });
+
+ test('which must have an expression after the !', () {
+ expect(() => _parse('!'), throwsFormatException);
+ expect(() => _parse('! && a'), throwsFormatException);
+ });
+ });
+
+ group('parses a parenthesized expression', () {
+ test('with an identifier', () {
+ var node = _parse('(a)');
+ expect(node, _isVar('a'));
+ });
+
+ test('controls precedence', () {
+ // Without parentheses, this would parse as "(a || b) ? c : d".
+ var node = _parse('a || (b ? c : d)');
+
+ expect(node, _isOrNode);
+ node as OrNode; //promote node
+
+ expect(node.left, _isVar('a'));
+
+ expect(node.right, _isConditionalNode);
+ var right = node.right as ConditionalNode;
+ expect(right.condition, _isVar('b'));
+ expect(right.whenTrue, _isVar('c'));
+ expect(right.whenFalse, _isVar('d'));
+ });
+
+ group('which must have', () {
+ test('an expression within the ()', () {
+ expect(() => _parse('()'), throwsFormatException);
+ expect(() => _parse('( && a )'), throwsFormatException);
+ });
+
+ test('a matching )', () {
+ expect(() => _parse('( a'), throwsFormatException);
+ });
+ });
+ });
+
+ group('disallows', () {
+ test('an empty selector', () {
+ expect(() => _parse(''), throwsFormatException);
+ });
+
+ test('too many expressions', () {
+ expect(() => _parse('a b'), throwsFormatException);
+ });
+ });
+}
+
+/// Parses [selector] and returns its root node.
+Node _parse(String selector) => Parser(selector).parse();
+
+/// A matcher that asserts that a value is a [VariableNode] with the given
+/// [name].
+Matcher _isVar(String name) => predicate(
+ (dynamic value) => value is VariableNode && value.name == name,
+ 'is a variable named "$name"');
+
+void _expectToString(String selector, [String? result]) {
+ result ??= selector;
+ expect(_toString(selector), equals(result),
+ reason: 'Expected toString of "$selector" to be "$result".');
+}
+
+String _toString(String selector) => Parser(selector).parse().toString();
diff --git a/pkgs/boolean_selector/test/scanner_test.dart b/pkgs/boolean_selector/test/scanner_test.dart
new file mode 100644
index 0000000..7ad78e2
--- /dev/null
+++ b/pkgs/boolean_selector/test/scanner_test.dart
@@ -0,0 +1,279 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:boolean_selector/src/scanner.dart';
+import 'package:boolean_selector/src/token.dart';
+import 'package:test/test.dart';
+
+/// A matcher that asserts that a value is a [IdentifierToken].
+const _isIdentifierToken = TypeMatcher<IdentifierToken>();
+
+void main() {
+ group('peek()', () {
+ test('returns the next token without consuming it', () {
+ var scanner = Scanner('( )');
+ expect(scanner.peek().type, equals(TokenType.leftParen));
+ expect(scanner.peek().type, equals(TokenType.leftParen));
+ expect(scanner.peek().type, equals(TokenType.leftParen));
+ });
+
+ test('returns an end-of-file token at the end of a file', () {
+ var scanner = Scanner('( )');
+ scanner.next();
+ scanner.next();
+
+ var token = scanner.peek();
+ expect(token.type, equals(TokenType.endOfFile));
+ expect(token.span.start.offset, equals(3));
+ expect(token.span.end.offset, equals(3));
+ });
+
+ test('throws a StateError if called after end-of-file was consumed', () {
+ var scanner = Scanner('( )');
+ scanner.next();
+ scanner.next();
+ scanner.next();
+ expect(() => scanner.peek(), throwsStateError);
+ });
+ });
+
+ group('next()', () {
+ test('consumes and returns the next token', () {
+ var scanner = Scanner('( )');
+ expect(scanner.next().type, equals(TokenType.leftParen));
+ expect(scanner.peek().type, equals(TokenType.rightParen));
+ expect(scanner.next().type, equals(TokenType.rightParen));
+ });
+
+ test('returns an end-of-file token at the end of a file', () {
+ var scanner = Scanner('( )');
+ scanner.next();
+ scanner.next();
+
+ var token = scanner.next();
+ expect(token.type, equals(TokenType.endOfFile));
+ expect(token.span.start.offset, equals(3));
+ expect(token.span.end.offset, equals(3));
+ });
+
+ test('throws a StateError if called after end-of-file was consumed', () {
+ var scanner = Scanner('( )');
+ scanner.next();
+ scanner.next();
+ scanner.next();
+ expect(() => scanner.next(), throwsStateError);
+ });
+ });
+
+ group('scan()', () {
+ test('consumes a matching token and returns true', () {
+ var scanner = Scanner('( )');
+ expect(scanner.scan(TokenType.leftParen), isTrue);
+ expect(scanner.peek().type, equals(TokenType.rightParen));
+ });
+
+ test("doesn't consume a matching token and returns false", () {
+ var scanner = Scanner('( )');
+ expect(scanner.scan(TokenType.questionMark), isFalse);
+ expect(scanner.peek().type, equals(TokenType.leftParen));
+ });
+
+ test('throws a StateError called after end-of-file was consumed', () {
+ var scanner = Scanner('( )');
+ scanner.next();
+ scanner.next();
+ scanner.next();
+ expect(() => scanner.scan(TokenType.endOfFile), throwsStateError);
+ });
+ });
+
+ group('scans a simple token:', () {
+ test('left paren', () => _expectSimpleScan('(', TokenType.leftParen));
+ test('right paren', () => _expectSimpleScan(')', TokenType.rightParen));
+ test('or', () => _expectSimpleScan('||', TokenType.or));
+ test('and', () => _expectSimpleScan('&&', TokenType.and));
+ test('not', () => _expectSimpleScan('!', TokenType.not));
+ test('question mark', () => _expectSimpleScan('?', TokenType.questionMark));
+ test('colon', () => _expectSimpleScan(':', TokenType.colon));
+ });
+
+ group('scans an identifier that', () {
+ test('is simple', () {
+ var token = _scan(' foo ');
+ expect(token, _isIdentifierToken);
+ token as IdentifierToken; // promote token
+
+ expect(token.name, equals('foo'));
+ expect(token.span.text, equals('foo'));
+ expect(token.span.start.offset, equals(3));
+ expect(token.span.end.offset, equals(6));
+ });
+
+ test('is a single character', () {
+ var token = _scan('f');
+ expect(token, _isIdentifierToken);
+ expect((token as IdentifierToken).name, equals('f'));
+ });
+
+ test('has a leading underscore', () {
+ var token = _scan('_foo');
+ expect(token, _isIdentifierToken);
+ expect((token as IdentifierToken).name, equals('_foo'));
+ });
+
+ test('has a leading dash', () {
+ var token = _scan('-foo');
+ expect(token, _isIdentifierToken);
+ expect((token as IdentifierToken).name, equals('-foo'));
+ });
+
+ test('contains an underscore', () {
+ var token = _scan('foo_bar');
+ expect(token, _isIdentifierToken);
+ expect((token as IdentifierToken).name, equals('foo_bar'));
+ });
+
+ test('contains a dash', () {
+ var token = _scan('foo-bar');
+ expect(token, _isIdentifierToken);
+ expect((token as IdentifierToken).name, equals('foo-bar'));
+ });
+
+ test('is capitalized', () {
+ var token = _scan('FOO');
+ expect(token, _isIdentifierToken);
+ expect((token as IdentifierToken).name, equals('FOO'));
+ });
+
+ test('contains numbers', () {
+ var token = _scan('foo123');
+ expect(token, _isIdentifierToken);
+ expect((token as IdentifierToken).name, equals('foo123'));
+ });
+ });
+
+ test('scans an empty selector', () {
+ expect(_scan('').type, equals(TokenType.endOfFile));
+ });
+
+ test('scans multiple tokens', () {
+ var scanner = Scanner('(foo && bar)');
+
+ var token = scanner.next();
+ expect(token.type, equals(TokenType.leftParen));
+ expect(token.span.start.offset, equals(0));
+ expect(token.span.end.offset, equals(1));
+
+ token = scanner.next();
+ expect(token.type, equals(TokenType.identifier));
+ expect((token as IdentifierToken).name, equals('foo'));
+ expect(token.span.start.offset, equals(1));
+ expect(token.span.end.offset, equals(4));
+
+ token = scanner.next();
+ expect(token.type, equals(TokenType.and));
+ expect(token.span.start.offset, equals(5));
+ expect(token.span.end.offset, equals(7));
+
+ token = scanner.next();
+ expect(token.type, equals(TokenType.identifier));
+ expect((token as IdentifierToken).name, equals('bar'));
+ expect(token.span.start.offset, equals(8));
+ expect(token.span.end.offset, equals(11));
+
+ token = scanner.next();
+ expect(token.type, equals(TokenType.rightParen));
+ expect(token.span.start.offset, equals(11));
+ expect(token.span.end.offset, equals(12));
+
+ token = scanner.next();
+ expect(token.type, equals(TokenType.endOfFile));
+ expect(token.span.start.offset, equals(12));
+ expect(token.span.end.offset, equals(12));
+ });
+
+ group('ignores', () {
+ test('a single-line comment', () {
+ var scanner = Scanner('( // &&\n// ||\n)');
+ expect(scanner.next().type, equals(TokenType.leftParen));
+ expect(scanner.next().type, equals(TokenType.rightParen));
+ expect(scanner.next().type, equals(TokenType.endOfFile));
+ });
+
+ test('a single-line comment without a trailing newline', () {
+ var scanner = Scanner('( // &&');
+ expect(scanner.next().type, equals(TokenType.leftParen));
+ expect(scanner.next().type, equals(TokenType.endOfFile));
+ });
+
+ test('a multi-line comment', () {
+ var scanner = Scanner('( /* && * /\n|| */\n)');
+ expect(scanner.next().type, equals(TokenType.leftParen));
+ expect(scanner.next().type, equals(TokenType.rightParen));
+ expect(scanner.next().type, equals(TokenType.endOfFile));
+ });
+
+ test('a multi-line nested comment', () {
+ var scanner = Scanner('(/* && /* ? /* || */ : */ ! */)');
+ expect(scanner.next().type, equals(TokenType.leftParen));
+ expect(scanner.next().type, equals(TokenType.rightParen));
+ expect(scanner.next().type, equals(TokenType.endOfFile));
+ });
+
+ test("Dart's notion of whitespace", () {
+ var scanner = Scanner('( \t \n)');
+ expect(scanner.next().type, equals(TokenType.leftParen));
+ expect(scanner.next().type, equals(TokenType.rightParen));
+ expect(scanner.next().type, equals(TokenType.endOfFile));
+ });
+ });
+
+ group('disallows', () {
+ test('a single |', () {
+ expect(() => _scan('|'), throwsFormatException);
+ });
+
+ test('"| |"', () {
+ expect(() => _scan('| |'), throwsFormatException);
+ });
+
+ test('a single &', () {
+ expect(() => _scan('&'), throwsFormatException);
+ });
+
+ test('"& &"', () {
+ expect(() => _scan('& &'), throwsFormatException);
+ });
+
+ test('an unknown operator', () {
+ expect(() => _scan('=='), throwsFormatException);
+ });
+
+ test('unicode', () {
+ expect(() => _scan('öh'), throwsFormatException);
+ });
+
+ test('an unclosed multi-line comment', () {
+ expect(() => _scan('/*'), throwsFormatException);
+ });
+
+ test('an unopened multi-line comment', () {
+ expect(() => _scan('*/'), throwsFormatException);
+ });
+ });
+}
+
+/// Asserts that the first token scanned from [selector] has type [type],
+/// and that that token's span is exactly [selector].
+void _expectSimpleScan(String selector, TokenType type) {
+ // Complicate the selector to test that the span covers it correctly.
+ var token = _scan(' $selector ');
+ expect(token.type, equals(type));
+ expect(token.span.text, equals(selector));
+ expect(token.span.start.offset, equals(3));
+ expect(token.span.end.offset, equals(3 + selector.length));
+}
+
+/// Scans a single token from [selector].
+Token _scan(String selector) => Scanner(selector).next();
diff --git a/pkgs/boolean_selector/test/to_string_test.dart b/pkgs/boolean_selector/test/to_string_test.dart
new file mode 100644
index 0000000..971e5b9
--- /dev/null
+++ b/pkgs/boolean_selector/test/to_string_test.dart
@@ -0,0 +1,84 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:boolean_selector/boolean_selector.dart';
+import 'package:test/test.dart';
+
+void main() {
+ group('toString() for', () {
+ test('a variable is its name', () {
+ _expectToString('foo');
+ _expectToString('a-b');
+ });
+
+ group('not', () {
+ test("doesn't parenthesize a variable", () => _expectToString('!a'));
+ test("doesn't parenthesize a nested not", () => _expectToString('!!a'));
+ test('parenthesizes an or', () => _expectToString('!(a || b)'));
+ test('parenthesizes an and', () => _expectToString('!(a && b)'));
+ test('parenthesizes a condition', () => _expectToString('!(a ? b : c)'));
+ });
+
+ group('or', () {
+ test("doesn't parenthesize variables", () => _expectToString('a || b'));
+ test("doesn't parenthesize nots", () => _expectToString('!a || !b'));
+
+ test("doesn't parenthesize ors", () {
+ _expectToString('a || b || c || d');
+ _expectToString('((a || b) || c) || d', 'a || b || c || d');
+ });
+
+ test('parenthesizes ands',
+ () => _expectToString('a && b || c && d', '(a && b) || (c && d)'));
+
+ test('parenthesizes conditions',
+ () => _expectToString('(a ? b : c) || (e ? f : g)'));
+ });
+
+ group('and', () {
+ test("doesn't parenthesize variables", () => _expectToString('a && b'));
+ test("doesn't parenthesize nots", () => _expectToString('!a && !b'));
+
+ test(
+ 'parenthesizes ors',
+ () =>
+ _expectToString('(a || b) && (c || d)', '(a || b) && (c || d)'));
+
+ test("doesn't parenthesize ands", () {
+ _expectToString('a && b && c && d');
+ _expectToString('((a && b) && c) && d', 'a && b && c && d');
+ });
+
+ test('parenthesizes conditions',
+ () => _expectToString('(a ? b : c) && (e ? f : g)'));
+ });
+
+ group('conditional', () {
+ test(
+ "doesn't parenthesize variables", () => _expectToString('a ? b : c'));
+
+ test("doesn't parenthesize nots", () => _expectToString('!a ? !b : !c'));
+
+ test("doesn't parenthesize ors",
+ () => _expectToString('a || b ? c || d : e || f'));
+
+ test("doesn't parenthesize ands",
+ () => _expectToString('a && b ? c && d : e && f'));
+
+ test('parenthesizes non-trailing conditions', () {
+ _expectToString('(a ? b : c) ? (e ? f : g) : h ? i : j');
+ _expectToString('(a ? b : c) ? (e ? f : g) : (h ? i : j)',
+ '(a ? b : c) ? (e ? f : g) : h ? i : j');
+ });
+ });
+ });
+}
+
+void _expectToString(String selector, [String? result]) {
+ result ??= selector;
+ expect(_toString(selector), equals(result),
+ reason: 'Expected toString of "$selector" to be "$result".');
+}
+
+String _toString(String selector) => BooleanSelector.parse(selector).toString();
diff --git a/pkgs/boolean_selector/test/validate_test.dart b/pkgs/boolean_selector/test/validate_test.dart
new file mode 100644
index 0000000..ec5b7eb
--- /dev/null
+++ b/pkgs/boolean_selector/test/validate_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:boolean_selector/boolean_selector.dart';
+import 'package:test/test.dart';
+
+var _selector = BooleanSelector.parse('foo && bar && baz');
+
+void main() {
+ test('throws if any variables are undefined', () {
+ expect(() => _selector.validate((variable) => variable == 'bar'),
+ throwsFormatException);
+ });
+
+ test("doesn't throw if all variables are defined", () {
+ // Should not throw.
+ _selector.validate((variable) => true);
+ });
+}
diff --git a/pkgs/boolean_selector/test/variables_test.dart b/pkgs/boolean_selector/test/variables_test.dart
new file mode 100644
index 0000000..5331409
--- /dev/null
+++ b/pkgs/boolean_selector/test/variables_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:boolean_selector/boolean_selector.dart';
+import 'package:test/test.dart';
+
+void main() {
+ test('a variable reports itself', () {
+ expect(BooleanSelector.parse('foo').variables, equals(['foo']));
+ });
+
+ test('a negation reports its contents', () {
+ expect(BooleanSelector.parse('!foo').variables, equals(['foo']));
+ });
+
+ test('a parenthesized expression reports its contents', () {
+ expect(BooleanSelector.parse('(foo)').variables, equals(['foo']));
+ });
+
+ test('an or reports its contents', () {
+ expect(
+ BooleanSelector.parse('foo || bar').variables, equals(['foo', 'bar']));
+ });
+
+ test('an and reports its contents', () {
+ expect(
+ BooleanSelector.parse('foo && bar').variables, equals(['foo', 'bar']));
+ });
+
+ test('a conditional reports its contents', () {
+ expect(BooleanSelector.parse('foo ? bar : baz').variables,
+ equals(['foo', 'bar', 'baz']));
+ });
+
+ test('BooleanSelector.all reports no variables', () {
+ expect(BooleanSelector.all.variables, isEmpty);
+ });
+
+ test('BooleanSelector.none reports no variables', () {
+ expect(BooleanSelector.none.variables, isEmpty);
+ });
+}
diff --git a/pkgs/cli_config/.gitignore b/pkgs/cli_config/.gitignore
new file mode 100644
index 0000000..58e48f3
--- /dev/null
+++ b/pkgs/cli_config/.gitignore
@@ -0,0 +1,9 @@
+# https://dart.dev/guides/libraries/private-files
+# Created by `dart pub`
+.dart_tool/
+
+# Avoid committing pubspec.lock for library packages; see
+# https://dart.dev/guides/libraries/private-files#pubspeclock.
+pubspec.lock
+
+coverage/
diff --git a/pkgs/cli_config/CHANGELOG.md b/pkgs/cli_config/CHANGELOG.md
new file mode 100644
index 0000000..55fcd2d
--- /dev/null
+++ b/pkgs/cli_config/CHANGELOG.md
@@ -0,0 +1,22 @@
+## 0.2.1-wip
+
+- Require Dart 3.4.
+
+## 0.2.0
+
+- **Breaking Change** Rename `Config.fromArgs` to `Config.fromArguments`.
+- Add `Config.fromArgumentsSync`.
+
+## 0.1.2
+
+- Add usage docs to the readme.
+- Require Dart 3.0.
+
+## 0.1.1
+
+- Support non-String map keys in YAML configuration files.
+- Support null values in YAML configuration files.
+
+## 0.1.0
+
+- Initial version.
diff --git a/pkgs/cli_config/LICENSE b/pkgs/cli_config/LICENSE
new file mode 100644
index 0000000..ac90031
--- /dev/null
+++ b/pkgs/cli_config/LICENSE
@@ -0,0 +1,27 @@
+Copyright 2023, the Dart project authors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of Google LLC nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/pkgs/cli_config/README.md b/pkgs/cli_config/README.md
new file mode 100644
index 0000000..54c08e4
--- /dev/null
+++ b/pkgs/cli_config/README.md
@@ -0,0 +1,71 @@
+[](https://github.com/dart-lang/tools/actions/workflows/cli_config.yml)
+[](https://coveralls.io/github/dart-lang/tools?branch=main)
+[](https://pub.dev/packages/cli_config)
+[](https://pub.dev/packages/cli_config/publisher)
+
+A library to take config values from configuration files, CLI arguments, and
+environment variables.
+
+## Usage
+
+Configuration can be provided from commandline arguments, environment variables,
+and configuration files. This library makes these accessible via a uniform API.
+
+Configuration can be provided via the three sources as follows:
+1. commandline argument defines as `-Dsome_key=some_value`,
+2. environment variables as `SOME_KEY=some_value`, and
+3. config files as JSON or YAML as `{'some_key': 'some_value'}`.
+
+The default lookup behavior is that commandline argument defines take precedence
+over environment variables, which take precedence over the configuration file.
+
+If a single value is requested from this configuration, the first source that
+can provide the value will provide it. For example
+`config.string('some_key')` with `{'some_key': 'file_value'}` in the config file
+and `-Dsome_key=cli_value` as commandline argument returns
+`'cli_value'`. The implication is that you can not remove keys from the
+configuration file, only overwrite or append them.
+
+If a list value is requested from this configuration, the values provided by the
+various sources can be combined or not. For example
+`config.optionalStringList('some_key', combineAllConfigs: true)` returns
+`['cli_value', 'file_value']`.
+
+The config is hierarchical in nature, using `.` as the hierarchy separator for
+lookup and commandline defines. The hierarchy should be materialized in the JSON
+or YAML configuration file. For environment variables `__` is used as hierarchy
+separator.
+
+Hierarchical configuration can be provided via the three sources as follows:
+1. commandline argument defines as `-Dsome_key.some_nested_key=some_value`,
+2. environment variables as `SOME_KEY__SOME_NESTED_KEY=some_value`, and
+3. config files as JSON or YAML as
+ ```yaml
+ some_key:
+ some_nested_key:
+ some_value
+ ```
+
+The config is opinionated on the format of the keys in the sources.
+* Command-line argument keys should be lower-cased alphanumeric
+ characters or underscores, with `.` for hierarchy.
+* Environment variables keys should be upper-cased alphanumeric
+ characters or underscores, with `__` for hierarchy.
+* Config files keys should be lower-cased alphanumeric
+ characters or underscores.
+
+In the API they are made available lower-cased and with underscores, and
+`.` as hierarchy separator.
+
+## Example usage
+
+This example creates a configuration which first looks for command-line defines
+in the `arguments` list then looks in `Platform.environment`, then looks in any
+local configuration file.
+
+```dart
+final config = await Config.fromArguments(arguments: arguments);
+final pathValue =
+ config.optionalPath('my_path', resolveUri: true, mustExist: false);
+print(pathValue?.toFilePath());
+```
diff --git a/pkgs/cli_config/analysis_options.yaml b/pkgs/cli_config/analysis_options.yaml
new file mode 100644
index 0000000..dd3dcda
--- /dev/null
+++ b/pkgs/cli_config/analysis_options.yaml
@@ -0,0 +1,12 @@
+include: package:dart_flutter_team_lints/analysis_options.yaml
+
+analyzer:
+ language:
+ strict-raw-types: true
+
+linter:
+ rules:
+ - prefer_const_declarations
+ - prefer_expression_function_bodies
+ - prefer_final_in_for_each
+ - prefer_final_locals
diff --git a/pkgs/cli_config/example/bin/cli_config_example.dart b/pkgs/cli_config/example/bin/cli_config_example.dart
new file mode 100644
index 0000000..1256bd7
--- /dev/null
+++ b/pkgs/cli_config/example/bin/cli_config_example.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2023, 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:cli_config/cli_config.dart';
+
+Future<void> main(List<String> args) async {
+ final config = await Config.fromArguments(arguments: args);
+ final myPath =
+ config.optionalPath('my_path', resolveUri: true, mustExist: false);
+ print(myPath?.toFilePath());
+}
diff --git a/pkgs/cli_config/example/pubspec.yaml b/pkgs/cli_config/example/pubspec.yaml
new file mode 100644
index 0000000..cec900a
--- /dev/null
+++ b/pkgs/cli_config/example/pubspec.yaml
@@ -0,0 +1,11 @@
+name: cli_config_example
+description: An example for cli_config.
+
+publish_to: none
+
+environment:
+ sdk: ">=2.19.3 <4.0.0"
+
+dependencies:
+ cli_config:
+ path: ../
diff --git a/pkgs/cli_config/lib/cli_config.dart b/pkgs/cli_config/lib/cli_config.dart
new file mode 100644
index 0000000..51df312
--- /dev/null
+++ b/pkgs/cli_config/lib/cli_config.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2023, 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.
+
+/// A library to take config values from configuration files, CLI arguments,
+/// and environment variables.
+library;
+
+export 'src/config.dart';
diff --git a/pkgs/cli_config/lib/src/cli_parser.dart b/pkgs/cli_config/lib/src/cli_parser.dart
new file mode 100644
index 0000000..9396a7a
--- /dev/null
+++ b/pkgs/cli_config/lib/src/cli_parser.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2023, 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:args/args.dart';
+
+class CliParser {
+ final ArgParser parser = () {
+ final parser = ArgParser();
+ parser.addFlag(
+ 'help',
+ abbr: 'h',
+ help: 'Show this help.',
+ );
+ parser.addMultiOption(
+ 'define',
+ abbr: 'D',
+ help: '''Define or override a config property from command line.
+The same option can be passed multiple times.
+Keys should only contain lower-case alphanumeric characters, underscores,
+and '.'s''',
+ );
+ parser.addOption(
+ 'config',
+ abbr: 'c',
+ help: '''Path to JSON or YAML config file.
+Keys should only contain lower-case alphanumeric characters, and underscores.
+Hierarchies should be maps.''',
+ );
+ return parser;
+ }();
+
+ ArgResults parse(List<String> args) => parser.parse(args);
+}
+
+class DefinesParser {
+ static final _defineRegex = RegExp('([a-z_.]+)=(.+)');
+
+ Map<String, List<String>> parse(List<String> args) {
+ final defines = <String, List<String>>{};
+ for (final arg in args) {
+ final match = _defineRegex.matchAsPrefix(arg);
+ if (match == null || match.group(0) != arg) {
+ throw FormatException("Define '$arg' does not match expected pattern "
+ "'${_defineRegex.pattern}'.");
+ }
+ final key = match.group(1)!;
+ final value = match.group(2)!;
+ defines[key] = (defines[key] ?? [])..add(value);
+ }
+ return defines;
+ }
+}
diff --git a/pkgs/cli_config/lib/src/cli_source.dart b/pkgs/cli_config/lib/src/cli_source.dart
new file mode 100644
index 0000000..20e662c
--- /dev/null
+++ b/pkgs/cli_config/lib/src/cli_source.dart
@@ -0,0 +1,95 @@
+// Copyright (c) 2023, 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 'config.dart';
+import 'source.dart';
+
+class CliSource extends Source {
+ /// Configuration options passed in via CLI arguments.
+ ///
+ /// Options can be passed multiple times, so the values here are a list.
+ ///
+ /// Stored as a flat non-hierarchical structure, keys contain `.`.
+ final Map<String, List<String>> _cli;
+
+ /// If provided, used to resolve paths within [_cli].
+ ///
+ /// Typically the current working directory at application start.
+ @override
+ final Uri? baseUri;
+
+ CliSource(this._cli, this.baseUri);
+
+ @override
+ String? optionalString(String key) {
+ final value = _cli[key];
+ if (value == null) {
+ return null;
+ }
+ if (value.length > 1) {
+ throw FormatException(
+ "More than one value was passed for '$key' in the CLI defines."
+ ' Values passed: $value');
+ }
+ return value.single;
+ }
+
+ @override
+ List<String>? optionalStringList(
+ String key, {
+ String? splitPattern,
+ }) {
+ final cliValue = _cli[key];
+ if (cliValue == null) {
+ return null;
+ }
+ if (splitPattern != null) {
+ return [for (final value in cliValue) ...value.split(splitPattern)];
+ }
+ return cliValue;
+ }
+
+ @override
+ bool? optionalBool(String key) {
+ final stringValue = optionalString(key);
+ if (stringValue != null) {
+ Source.throwIfUnexpectedValue(key, stringValue, Config.boolStrings.keys);
+ return Config.boolStrings[stringValue]!;
+ }
+ return null;
+ }
+
+ @override
+ int? optionalInt(String key) {
+ final stringValue = optionalString(key);
+ if (stringValue != null) {
+ try {
+ return int.parse(stringValue);
+ } on FormatException catch (e) {
+ throw FormatException(
+ "Unexpected value '$stringValue' for key '$key'. Expected an int."
+ ' ${e.message}');
+ }
+ }
+ return null;
+ }
+
+ @override
+ double? optionalDouble(String key) {
+ final stringValue = optionalString(key);
+ if (stringValue != null) {
+ try {
+ return double.parse(stringValue);
+ } on FormatException catch (e) {
+ throw FormatException(
+ "Unexpected value '$stringValue' for key '$key'. Expected a double."
+ ' ${e.message}');
+ }
+ }
+ return null;
+ }
+
+ @override
+ String toString() => 'CliSource($_cli)';
+}
diff --git a/pkgs/cli_config/lib/src/config.dart b/pkgs/cli_config/lib/src/config.dart
new file mode 100644
index 0000000..85e2c0c
--- /dev/null
+++ b/pkgs/cli_config/lib/src/config.dart
@@ -0,0 +1,650 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:core' as core show bool, double, int;
+import 'dart:core' hide bool, double, int;
+import 'dart:io';
+
+import 'cli_parser.dart';
+import 'cli_source.dart';
+import 'environment_parser.dart';
+import 'environment_source.dart';
+import 'file_parser.dart';
+import 'file_source.dart';
+import 'source.dart';
+
+/// A hierarchical configuration.
+///
+/// Configuration can be provided from three sources: commandline arguments,
+/// environment variables and configuration files. This configuration makes
+/// these accessible via a uniform API.
+///
+/// Configuration can be provided via the three sources as follows:
+/// 1. commandline argument defines as `-Dsome_key=some_value`,
+/// 2. environment variables as `SOME_KEY=some_value`, and
+/// 3. config files as JSON or YAML as `{'some_key': 'some_value'}`.
+///
+/// The default lookup behavior is that commandline argument defines take
+/// precedence over environment variables, which take precedence over the
+/// configuration file.
+///
+/// If a single value is requested from this configuration, the first source
+/// that can provide the value will provide it. For example
+/// `config.string('some_key')` with `{'some_key': 'file_value'}` in the
+/// config file and `-Dsome_key=cli_value` as commandline argument returns
+/// `'cli_value'`. The implication is that you can not remove keys from the
+/// configuration file, only overwrite or append them.
+///
+/// If a list value is requested from this configuration, the values provided
+/// by the various sources can be combined or not. For example
+/// `config.optionalStringList('some_key', combineAllConfigs: true)` returns
+/// `['cli_value', 'file_value']`.
+///
+/// The config is hierarchical in nature, using `.` as the hierarchy separator
+/// for lookup and commandline defines. The hierarchy should be materialized in
+/// the JSON or YAML configuration file. For environment variables `__` is used
+/// as hierarchy separator.
+///
+/// Hierarchical configuration can be provided via the three sources as follows:
+/// 1. commandline argument defines as `-Dsome_key.some_nested_key=some_value`,
+/// 2. environment variables as `SOME_KEY__SOME_NESTED_KEY=some_value`, and
+/// 3. config files as JSON or YAML as
+/// ```yaml
+/// some_key:
+/// some_nested_key:
+/// some_value
+/// ```
+///
+/// The config is opinionated on the format of the keys in the sources.
+/// * Command-line argument keys should be lower-cased alphanumeric
+/// characters or underscores, with `.` for hierarchy.
+/// * Environment variables keys should be upper-cased alphanumeric
+/// characters or underscores, with `__` for hierarchy.
+/// * Config files keys should be lower-cased alphanumeric
+/// characters or underscores.
+///
+/// In the API they are made available lower-cased and with underscores, and
+/// `.` as hierarchy separator.
+class Config {
+ final CliSource _cliSource;
+ final EnvironmentSource _environmentSource;
+ final FileSource _fileSource;
+
+ /// Config sources, ordered by precedence.
+ late final _sources = [_cliSource, _environmentSource, _fileSource];
+
+ Config._(
+ this._cliSource,
+ this._environmentSource,
+ this._fileSource,
+ );
+
+ /// Constructs a config by parsing the three sources.
+ ///
+ /// If provided, [commandLineDefines] must be a list of `<key>=<value>`.
+ ///
+ /// If provided, [workingDirectory] is used to resolves paths inside
+ /// [commandLineDefines].
+ ///
+ /// If provided, [environment] must be a map containing environment variables.
+ ///
+ /// If provided, [fileParsed] must be valid parsed YSON or YAML (maps, lists,
+ /// strings, integers, and booleans).
+ ///
+ /// If provided [fileSourceUri] is used to resolve paths inside
+ /// [fileParsed] and to provide better error messages on parsing the
+ /// configuration file.
+ factory Config({
+ List<String> commandLineDefines = const [],
+ Uri? workingDirectory,
+ Map<String, String> environment = const {},
+ Map<String, dynamic> fileParsed = const {},
+ Uri? fileSourceUri,
+ }) {
+ // Parse config file.
+ final fileConfig = FileParser().parseToplevelMap(fileParsed);
+
+ // Parse CLI argument defines.
+ final cliConfig = DefinesParser().parse(commandLineDefines);
+
+ // Parse environment.
+ final environmentConfig = EnvironmentParser().parse(environment);
+
+ return Config._(
+ CliSource(cliConfig, workingDirectory?.normalizePath()),
+ EnvironmentSource(environmentConfig),
+ FileSource(fileConfig, fileSourceUri?.normalizePath()),
+ );
+ }
+
+ /// Constructs a config by parsing the three sources.
+ ///
+ /// If provided, [commandLineDefines] must be a list of `<key>=<value>`.
+ ///
+ /// If provided, [workingDirectory] is used to resolves paths inside
+ /// [commandLineDefines].
+ ///
+ /// If provided, [environment] must be a map containing environment variables.
+ ///
+ /// If provided, [fileContents] must be valid JSON or YAML.
+ ///
+ /// If provided [fileSourceUri] is used to resolve paths inside
+ /// [fileContents] and to provide better error messages on parsing the
+ /// configuration file.
+ factory Config.fromConfigFileContents({
+ List<String> commandLineDefines = const [],
+ Uri? workingDirectory,
+ Map<String, String> environment = const {},
+ String? fileContents,
+ Uri? fileSourceUri,
+ }) {
+ // Parse config file.
+ final Map<String, dynamic> fileConfig;
+ if (fileContents != null) {
+ fileConfig = FileParser().parse(
+ fileContents,
+ sourceUrl: fileSourceUri,
+ );
+ } else {
+ fileConfig = {};
+ }
+
+ // Parse CLI argument defines.
+ final cliConfig = DefinesParser().parse(commandLineDefines);
+
+ // Parse environment.
+ final environmentConfig = EnvironmentParser().parse(environment);
+
+ return Config._(
+ CliSource(cliConfig, workingDirectory),
+ EnvironmentSource(environmentConfig),
+ FileSource(fileConfig, fileSourceUri),
+ );
+ }
+
+ /// Constructs a config by parsing CLI arguments and loading the config file.
+ ///
+ /// The [arguments] must be commandline arguments.
+ ///
+ /// If provided, [environment] must be a map containing environment variables.
+ /// If not provided, [environment] defaults to [Platform.environment].
+ ///
+ /// If provided, [workingDirectory] is used to resolves paths inside
+ /// [environment].
+ /// If not provided, [workingDirectory] defaults to [Directory.current].
+ ///
+ /// This async constructor is intended to be used directly in CLI files.
+ static Future<Config> fromArguments({
+ required List<String> arguments,
+ Map<String, String>? environment,
+ Uri? workingDirectory,
+ }) async {
+ final results = CliParser().parse(arguments);
+
+ // Load config file.
+ final configFile = results['config'] as String?;
+ String? fileContents;
+ Uri? fileSourceUri;
+ if (configFile != null) {
+ fileContents = await File(configFile).readAsString();
+ fileSourceUri = Uri.file(configFile);
+ }
+
+ return Config.fromConfigFileContents(
+ commandLineDefines: results['define'] as List<String>,
+ workingDirectory: workingDirectory ?? Directory.current.uri,
+ environment: environment ?? Platform.environment,
+ fileContents: fileContents,
+ fileSourceUri: fileSourceUri,
+ );
+ }
+
+ /// Constructs a config by parsing CLI arguments and loading the config file.
+ ///
+ /// The [arguments] must be commandline arguments.
+ ///
+ /// If provided, [environment] must be a map containing environment variables.
+ /// If not provided, [environment] defaults to [Platform.environment].
+ ///
+ /// If provided, [workingDirectory] is used to resolves paths inside
+ /// [environment].
+ /// If not provided, [workingDirectory] defaults to [Directory.current].
+ ///
+ /// This synchronous constructor is intended to be used directly in CLI files.
+ static Config fromArgumentsSync({
+ required List<String> arguments,
+ Map<String, String>? environment,
+ Uri? workingDirectory,
+ }) {
+ final results = CliParser().parse(arguments);
+
+ // Load config file.
+ final configFile = results['config'] as String?;
+ String? fileContents;
+ Uri? fileSourceUri;
+ if (configFile != null) {
+ fileContents = File(configFile).readAsStringSync();
+ fileSourceUri = Uri.file(configFile);
+ }
+
+ return Config.fromConfigFileContents(
+ commandLineDefines: results['define'] as List<String>,
+ workingDirectory: workingDirectory ?? Directory.current.uri,
+ environment: environment ?? Platform.environment,
+ fileContents: fileContents,
+ fileSourceUri: fileSourceUri,
+ );
+ }
+
+ /// Lookup a string value in this config.
+ ///
+ /// First tries CLI argument defines, then environment variables, and
+ /// finally the config file.
+ ///
+ /// Throws if one of the configs does not contain the expected value type.
+ ///
+ /// If [validValues] is provided, throws if an unxpected value is provided.
+ String string(String key, {Iterable<String>? validValues}) {
+ final value = optionalString(key, validValues: validValues);
+ _throwIfNull(key, value);
+ return value!;
+ }
+
+ /// Lookup an optional string value in this config.
+ ///
+ /// First tries CLI argument defines, then environment variables, and
+ /// finally the config file.
+ ///
+ /// If [validValues] is provided, throws if an unxpected value is provided.
+ String? optionalString(String key, {Iterable<String>? validValues}) {
+ String? value;
+ for (final source in _sources) {
+ value ??= source.optionalString(key);
+ }
+ if (value != null && validValues != null) {
+ Source.throwIfUnexpectedValue(key, value, validValues);
+ }
+ return value;
+ }
+
+ /// Lookup an optional string list in this config.
+ ///
+ /// If none of the sources provide a list, lookup will fail.
+ /// If an empty list is provided by one of the sources, lookup wil succeed.
+ ///
+ /// First tries CLI argument defines, then environment variables, and
+ /// finally the config file.
+ ///
+ /// If [combineAllConfigs] combines results from cli, environment, and
+ /// config file. Otherwise, precedence rules apply.
+ ///
+ /// If provided, [splitCliPattern] splits cli defines.
+ /// For example: `-Dfoo=bar;baz` can be split on `;`.
+ /// If not provided, a list can still be provided with multiple cli defines.
+ /// For example: `-Dfoo=bar -Dfoo=baz`.
+ ///
+ /// If provided, [splitEnvironmentPattern] splits environment values.
+ List<String> stringList(
+ String key, {
+ core.bool combineAllConfigs = true,
+ String? splitCliPattern,
+ String? splitEnvironmentPattern,
+ }) {
+ final value = optionalStringList(
+ key,
+ combineAllConfigs: combineAllConfigs,
+ splitCliPattern: splitCliPattern,
+ splitEnvironmentPattern: splitEnvironmentPattern,
+ );
+ _throwIfNull(key, value);
+ return value!;
+ }
+
+ /// Lookup an optional string list in this config.
+ ///
+ /// First tries CLI argument defines, then environment variables, and
+ /// finally the config file.
+ ///
+ /// If [combineAllConfigs] combines results from cli, environment, and
+ /// config file. Otherwise, precedence rules apply.
+ ///
+ /// If provided, [splitCliPattern] splits cli defines.
+ /// For example: `-Dfoo=bar;baz` can be split on `;`.
+ /// If not provided, a list can still be provided with multiple cli defines.
+ /// For example: `-Dfoo=bar -Dfoo=baz`.
+ ///
+ /// If provided, [splitEnvironmentPattern] splits environment values.
+ List<String>? optionalStringList(
+ String key, {
+ core.bool combineAllConfigs = true,
+ String? splitCliPattern,
+ String? splitEnvironmentPattern,
+ }) {
+ List<String>? result;
+ for (final entry in {
+ _cliSource: splitCliPattern,
+ _environmentSource: splitEnvironmentPattern,
+ _fileSource: null
+ }.entries) {
+ final source = entry.key;
+ final splitPattern = entry.value;
+ final value = source.optionalStringList(key, splitPattern: splitPattern);
+ if (value != null) {
+ if (combineAllConfigs) {
+ (result ??= []).addAll(value);
+ } else {
+ return value;
+ }
+ }
+ }
+ return result;
+ }
+
+ static const boolStrings = {
+ '0': false,
+ '1': true,
+ 'false': false,
+ 'FALSE': false,
+ 'no': false,
+ 'NO': false,
+ 'true': true,
+ 'TRUE': true,
+ 'yes': true,
+ 'YES': true,
+ };
+
+ /// Lookup a boolean value in this config.
+ ///
+ /// First tries CLI argument defines, then environment variables, and
+ /// finally the config file.
+ ///
+ /// For cli defines and environment variables, the value must be one of
+ /// [boolStrings].
+ /// For the config file, it must be a boolean.
+ ///
+ /// Throws if one of the configs does not contain the expected value type.
+ core.bool bool(String key) {
+ final value = optionalBool(key);
+ _throwIfNull(key, value);
+ return value!;
+ }
+
+ /// Lookup an optional boolean value in this config.
+ ///
+ /// First tries CLI argument defines, then environment variables, and
+ /// finally the config file.
+ ///
+ /// For cli defines and environment variables, the value must be one of
+ /// [boolStrings].
+ /// For the config file, it must be a boolean or null.
+ core.bool? optionalBool(String key) {
+ core.bool? value;
+ for (final source in _sources) {
+ value ??= source.optionalBool(key);
+ }
+ return value;
+ }
+
+ /// Lookup an integer value in this config.
+ ///
+ /// First tries CLI argument defines, then environment variables, and
+ /// finally the config file.
+ ///
+ /// For cli defines and environment variables, the value must be parseble
+ /// by [core.int.parse].
+ /// For the config file, it must be an integer.
+ core.int int(String key) {
+ final value = optionalInt(key);
+ _throwIfNull(key, value);
+ return value!;
+ }
+
+ /// Lookup an optional integer value in this config.
+ ///
+ /// First tries CLI argument defines, then environment variables, and
+ /// finally the config file.
+ ///
+ /// For cli defines and environment variables, the value must be parseble
+ /// by [core.int.parse].
+ /// For the config file, it must be an integer or null.
+ core.int? optionalInt(String key) {
+ core.int? value;
+ for (final source in _sources) {
+ value ??= source.optionalInt(key);
+ }
+ return value;
+ }
+
+ /// Lookup an double value in this config.
+ ///
+ /// First tries CLI argument defines, then environment variables, and
+ /// finally the config file.
+ ///
+ /// For cli defines and environment variables, the value must be parseble
+ /// by [core.double.parse].
+ /// For the config file, it must be an double.
+ core.double double(String key) {
+ final value = optionalDouble(key);
+ _throwIfNull(key, value);
+ return value!;
+ }
+
+ /// Lookup an optional double value in this config.
+ ///
+ /// First tries CLI argument defines, then environment variables, and
+ /// finally the config file.
+ ///
+ /// For cli defines and environment variables, the value must be parseble
+ /// by [core.double.parse].
+ /// For the config file, it must be an double or null.
+ core.double? optionalDouble(String key) {
+ core.double? value;
+ for (final source in _sources) {
+ value ??= source.optionalDouble(key);
+ }
+ return value;
+ }
+
+ /// Lookup a path in this config.
+ ///
+ /// First tries CLI argument defines, then environment variables, and
+ /// finally the config file.
+ ///
+ /// Throws if one of the configs does not contain the expected value type.
+ ///
+ /// If [resolveUri], resolves the paths in a source relative to the base
+ /// uri of that source. The base uri for the config file is the path of the
+ /// file. The base uri for environment values is the current working
+ /// directory.
+ ///
+ /// If [mustExist], throws if the path doesn't resolve to a file or directory
+ /// on the file system.
+ ///
+ /// Throws if one of the configs does not contain the expected value type.
+ Uri path(
+ String key, {
+ core.bool resolveUri = true,
+ core.bool mustExist = false,
+ }) {
+ final value =
+ optionalPath(key, resolveUri: resolveUri, mustExist: mustExist);
+ _throwIfNull(key, value);
+ return value!;
+ }
+
+ /// Lookup an optional path in this config.
+ ///
+ /// First tries CLI argument defines, then environment variables, and
+ /// finally the config file.
+ ///
+ /// Throws if one of the configs does not contain the expected value type.
+ ///
+ /// If [resolveUri], resolves the paths in a source relative to the base
+ /// uri of that source. The base uri for the config file is the path of the
+ /// file. The base uri for environment values is the current working
+ /// directory.
+ ///
+ /// If [mustExist], throws if the path doesn't resolve to a file or directory
+ /// on the file system.
+ Uri? optionalPath(
+ String key, {
+ core.bool resolveUri = true,
+ core.bool mustExist = false,
+ }) {
+ for (final source in _sources) {
+ final path = source.optionalString(key);
+ if (path != null) {
+ final value = _pathToUri(
+ path,
+ resolveUri: resolveUri,
+ baseUri: source.baseUri,
+ );
+ if (mustExist) {
+ _throwIfNotExists(key, value);
+ }
+ return value;
+ }
+ }
+ return null;
+ }
+
+ Uri _pathToUri(
+ String path, {
+ required core.bool resolveUri,
+ required Uri? baseUri,
+ }) {
+ final uri = Source.fileSystemPathToUri(path);
+ if (resolveUri && baseUri != null) {
+ return baseUri.resolveUri(uri);
+ }
+ return uri;
+ }
+
+ /// Lookup a list of paths in this config.
+ ///
+ /// If none of the sources provide a path, lookup will fail.
+ /// If an empty list is provided by one of the sources, lookup wil succeed.
+ ///
+ /// If [combineAllConfigs] combines results from cli, environment, and
+ /// config file. Otherwise, precedence rules apply.
+ ///
+ /// If provided, [splitCliPattern] splits cli defines.
+ ///
+ /// If provided, [splitEnvironmentPattern] splits environment values.
+ ///
+ /// If [resolveUri], resolves the paths in a source relative to the base
+ /// uri of that source. The base uri for the config file is the path of the
+ /// file. The base uri for environment values is the current working
+ /// directory.
+ List<Uri> pathList(
+ String key, {
+ core.bool combineAllConfigs = true,
+ String? splitCliPattern,
+ String? splitEnvironmentPattern,
+ core.bool resolveUri = true,
+ }) {
+ final value = optionalPathList(
+ key,
+ combineAllConfigs: combineAllConfigs,
+ splitCliPattern: splitCliPattern,
+ splitEnvironmentPattern: splitEnvironmentPattern,
+ resolveUri: resolveUri,
+ );
+ _throwIfNull(key, value);
+ return value!;
+ }
+
+ /// Lookup an optional list of paths in this config.
+ ///
+ /// If [combineAllConfigs] combines results from cli, environment, and
+ /// config file. Otherwise, precedence rules apply.
+ ///
+ /// If provided, [splitCliPattern] splits cli defines.
+ ///
+ /// If provided, [splitEnvironmentPattern] splits environment values.
+ ///
+ /// If [resolveUri], resolves the paths in a source relative to the base
+ /// uri of that source. The base uri for the config file is the path of the
+ /// file. The base uri for environment values is the current working
+ /// directory.
+ List<Uri>? optionalPathList(
+ String key, {
+ core.bool combineAllConfigs = true,
+ String? splitCliPattern,
+ String? splitEnvironmentPattern,
+ core.bool resolveUri = true,
+ }) {
+ List<Uri>? result;
+ for (final entry in {
+ _cliSource: splitCliPattern,
+ _environmentSource: splitEnvironmentPattern,
+ _fileSource: null
+ }.entries) {
+ final source = entry.key;
+ final splitPattern = entry.value;
+ final paths = source.optionalStringList(
+ key,
+ splitPattern: splitPattern,
+ );
+ if (paths != null) {
+ final value = [
+ for (final path in paths)
+ _pathToUri(
+ path,
+ resolveUri: resolveUri,
+ baseUri: source.baseUri,
+ )
+ ];
+ if (combineAllConfigs) {
+ (result ??= []).addAll(value);
+ } else {
+ return value;
+ }
+ }
+ }
+ return result;
+ }
+
+ /// Lookup a value of type [T] in this configuration.
+ ///
+ /// Does not support specialized options such as `splitPattern`. One must
+ /// use the specialized methods such as [optionalStringList] for that.
+ ///
+ /// If sources cannot lookup type [T], they return null.
+ T valueOf<T>(String key) {
+ T? value;
+ for (final source in _sources) {
+ value ??= source.optionalValueOf<T>(key);
+ }
+ if (null is! T) {
+ _throwIfNull(key, value);
+ }
+ return value as T;
+ }
+
+ void _throwIfNull(String key, Object? value) {
+ if (value == null) {
+ throw FormatException('No value was provided for required key: $key');
+ }
+ }
+
+ void _throwIfNotExists(String key, Uri value) {
+ final fileSystemEntity = value.fileSystemEntity;
+ if (!fileSystemEntity.existsSync()) {
+ throw FormatException("Path '$value' for key '$key' doesn't exist.");
+ }
+ }
+
+ @override
+ String toString() => 'Config($_sources)';
+}
+
+extension on Uri {
+ FileSystemEntity get fileSystemEntity {
+ if (path.endsWith(Platform.pathSeparator) || path.endsWith('/')) {
+ return Directory.fromUri(this);
+ }
+ return File.fromUri(this);
+ }
+}
diff --git a/pkgs/cli_config/lib/src/environment_parser.dart b/pkgs/cli_config/lib/src/environment_parser.dart
new file mode 100644
index 0000000..d91b8fa
--- /dev/null
+++ b/pkgs/cli_config/lib/src/environment_parser.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2023, 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 EnvironmentParser {
+ /// Parses an environment key into an config key.
+ ///
+ /// Environment keys can only contain alphanumeric characters and underscores.
+ /// Treats `__` as hierarchy separator, and replaces it with `.`.
+ ///
+ /// Often, environment variables are uppercased.
+ /// Replaces all uppercase characters with lowercase characters.
+ String parseKey(String key) => key.replaceAll('__', '.').toLowerCase();
+
+ Map<String, String> parse(Map<String, String> environment) => {
+ for (final entry in environment.entries)
+ parseKey(entry.key): entry.value,
+ };
+}
diff --git a/pkgs/cli_config/lib/src/environment_source.dart b/pkgs/cli_config/lib/src/environment_source.dart
new file mode 100644
index 0000000..9cff18f
--- /dev/null
+++ b/pkgs/cli_config/lib/src/environment_source.dart
@@ -0,0 +1,86 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'config.dart';
+import 'source.dart';
+
+class EnvironmentSource extends Source {
+ /// Configuration options passed in via the [Platform.environment].
+ ///
+ /// The keys have been transformed by `EnvironmentParser.parseKey`.
+ ///
+ /// Environment values are left intact.
+ ///
+ /// Stored as a flat non-hierarchical structure, keys contain `.`.
+ final Map<String, String> _environment;
+
+ EnvironmentSource(this._environment);
+
+ @override
+ String? optionalString(String key) => _environment[key];
+
+ @override
+ List<String>? optionalStringList(
+ String key, {
+ String? splitPattern,
+ }) {
+ final envValue = _environment[key];
+ if (envValue == null) {
+ return null;
+ }
+ if (splitPattern != null) {
+ return envValue.split(splitPattern);
+ }
+ return [envValue];
+ }
+
+ @override
+ bool? optionalBool(String key) {
+ final stringValue = optionalString(key);
+ if (stringValue != null) {
+ Source.throwIfUnexpectedValue(key, stringValue, Config.boolStrings.keys);
+ return Config.boolStrings[stringValue]!;
+ }
+ return null;
+ }
+
+ @override
+ int? optionalInt(String key) {
+ final stringValue = optionalString(key);
+ if (stringValue != null) {
+ try {
+ return int.parse(stringValue);
+ } on FormatException catch (e) {
+ throw FormatException(
+ "Unexpected value '$stringValue' for key '$key'. Expected an int."
+ ' ${e.message}');
+ }
+ }
+ return null;
+ }
+
+ @override
+ double? optionalDouble(String key) {
+ final stringValue = optionalString(key);
+ if (stringValue != null) {
+ try {
+ return double.parse(stringValue);
+ } on FormatException catch (e) {
+ throw FormatException(
+ "Unexpected value '$stringValue' for key '$key'. Expected a double."
+ ' ${e.message}');
+ }
+ }
+ return null;
+ }
+
+ @override
+ String toString() => 'EnvironmentSource($_environment)';
+
+ /// Environment path are not resolved.
+ @override
+ Uri? get baseUri => null;
+}
diff --git a/pkgs/cli_config/lib/src/file_parser.dart b/pkgs/cli_config/lib/src/file_parser.dart
new file mode 100644
index 0000000..2a647e5
--- /dev/null
+++ b/pkgs/cli_config/lib/src/file_parser.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2023, 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:yaml/yaml.dart';
+
+class FileParser {
+ Map<String, Object?> parse(
+ String fileContents, {
+ Uri? sourceUrl,
+ }) {
+ final parsedYaml = loadYaml(
+ fileContents,
+ sourceUrl: sourceUrl,
+ );
+ if (parsedYaml is! Map) {
+ throw const FormatException(
+ 'YAML config must be set of key value pairs.');
+ }
+ return parseToplevelMap(parsedYaml);
+ }
+
+ Map<String, Object?> parseToplevelMap(Map<dynamic, dynamic> input) {
+ final result = <String, Object?>{};
+ for (final entry in input.entries) {
+ final key = parseToplevelKey(entry.key);
+ final value = entry.value as Object?;
+ result[key] = value;
+ }
+ return result;
+ }
+
+ static final _keyRegex = RegExp('([a-z-_]+)');
+
+ String parseToplevelKey(Object? key) {
+ if (key is! String) {
+ throw FormatException("Key '$key' is not a String.");
+ }
+ final match = _keyRegex.matchAsPrefix(key);
+ if (match == null || match.group(0) != key) {
+ throw FormatException("Define '$key' does not match expected pattern "
+ "'${_keyRegex.pattern}'.");
+ }
+ return key.replaceAll('-', '_');
+ }
+}
diff --git a/pkgs/cli_config/lib/src/file_source.dart b/pkgs/cli_config/lib/src/file_source.dart
new file mode 100644
index 0000000..d0594c6
--- /dev/null
+++ b/pkgs/cli_config/lib/src/file_source.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2023, 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 'source.dart';
+
+class FileSource extends Source {
+ /// Configuration options passed in via a JSON or YAML configuration file.
+ ///
+ /// Stored as a partial hierarchical data structure. The values can be maps
+ /// in which subsequent parts of a key after a `.` can be resolved.
+ final Map<String, dynamic> _file;
+
+ /// If provided, used to resolve paths within [_file].
+ @override
+ final Uri? baseUri;
+
+ FileSource(this._file, this.baseUri);
+
+ @override
+ String? optionalString(String key) => optionalValueOf<String>(key);
+
+ @override
+ List<String>? optionalStringList(
+ String key, {
+ String? splitPattern,
+ }) {
+ assert(splitPattern == null);
+ return optionalValueOf<List<dynamic>>(key)?.cast<String>();
+ }
+
+ @override
+ bool? optionalBool(String key) => optionalValueOf<bool>(key);
+
+ @override
+ int? optionalInt(String key) => optionalValueOf<int>(key);
+
+ @override
+ double? optionalDouble(String key) => optionalValueOf<double>(key);
+
+ @override
+ T? optionalValueOf<T>(String key) {
+ Object? cursor = _file;
+ var current = '';
+ for (final keyPart in key.split('.')) {
+ if (cursor == null) {
+ return null;
+ }
+ if (cursor is! Map) {
+ throw FormatException(
+ "Unexpected value '$cursor' for key '$current' in config file. "
+ 'Expected a Map.');
+ } else {
+ cursor = cursor[keyPart];
+ }
+ current += '.$keyPart';
+ }
+ if (cursor is! T?) {
+ throw FormatException(
+ "Unexpected value '$cursor' for key '$current' in config file. "
+ 'Expected a $T.');
+ }
+ return cursor;
+ }
+
+ @override
+ String toString() => 'FileSource(file: $_file, fileUri: $baseUri)';
+}
diff --git a/pkgs/cli_config/lib/src/source.dart b/pkgs/cli_config/lib/src/source.dart
new file mode 100644
index 0000000..14c7965
--- /dev/null
+++ b/pkgs/cli_config/lib/src/source.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+abstract class Source {
+ /// If provided, the uri used for resolving paths.
+ Uri? get baseUri;
+
+ /// Lookup a nullable string value.
+ String? optionalString(String key);
+
+ /// Lookup a nullable string list.
+ ///
+ /// If provided, [splitPattern] splits config.
+ List<String>? optionalStringList(
+ String key, {
+ String? splitPattern,
+ });
+
+ /// Lookup an optional boolean value.
+ bool? optionalBool(String key);
+
+ /// Lookup an optional int value.
+ int? optionalInt(String key);
+
+ /// Lookup an optional int value.
+ double? optionalDouble(String key);
+
+ /// Lookup an optional value of type [T].
+ ///
+ /// Does not support specialized options such as `splitPattern`. One must
+ /// use the specialized methods such as [optionalStringList] for that.
+ ///
+ /// Returns `null` if the source cannot provide a value of type [T].
+ T? optionalValueOf<T>(String key) {
+ if (T == bool) {
+ return optionalBool(key) as T?;
+ }
+ if (T == String) {
+ return optionalString(key) as T?;
+ }
+ if (T == List<String>) {
+ return optionalStringList(key) as T?;
+ }
+ return null;
+ }
+
+ static void throwIfUnexpectedValue<T>(
+ String key, T value, Iterable<T> validValues) {
+ if (!validValues.contains(value)) {
+ throw FormatException(
+ "Unexpected value '$value' for key '$key'. Expected one of: "
+ "${validValues.map((e) => "'$e'").join(', ')}.");
+ }
+ }
+
+ static Uri fileSystemPathToUri(String path) {
+ if (path.endsWith(Platform.pathSeparator)) {
+ return Uri.directory(path);
+ }
+ return Uri.file(path);
+ }
+}
diff --git a/pkgs/cli_config/pubspec.yaml b/pkgs/cli_config/pubspec.yaml
new file mode 100644
index 0000000..e2b0721
--- /dev/null
+++ b/pkgs/cli_config/pubspec.yaml
@@ -0,0 +1,17 @@
+name: cli_config
+description: >-
+ A library to take config values from configuration files, CLI arguments, and
+ environment variables.
+version: 0.2.1-wip
+repository: https://github.com/dart-lang/tools/tree/main/pkgs/cli_config
+
+environment:
+ sdk: ^3.4.0
+
+dependencies:
+ args: ^2.4.0
+ yaml: ^3.1.1
+
+dev_dependencies:
+ dart_flutter_team_lints: ^3.0.0
+ test: ^1.21.0
diff --git a/pkgs/cli_config/test/cli_config_example_test.dart b/pkgs/cli_config/test/cli_config_example_test.dart
new file mode 100644
index 0000000..43ed7b9
--- /dev/null
+++ b/pkgs/cli_config/test/cli_config_example_test.dart
@@ -0,0 +1,106 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:test/test.dart';
+
+import 'helpers.dart';
+
+void main() {
+ test('resolve command line paths relative to working directory', () async {
+ await inTempDir((tempUri) async {
+ final rootUri = Directory.current.uri.normalizePath();
+ final examplePackageUri =
+ rootUri.resolve('example${Platform.pathSeparator}');
+ final entryPoint = 'bin${Platform.pathSeparator}cli_config_example.dart';
+ const pubSpec = 'pubspec.yaml';
+ for (final filename in [entryPoint, pubSpec]) {
+ final targetUri = tempUri.resolve(filename);
+ await File.fromUri(targetUri).create(recursive: true);
+ await File.fromUri(examplePackageUri.resolve(filename))
+ .copy(targetUri.toFilePath());
+ }
+ final pubspecFile = File.fromUri(tempUri.resolve(pubSpec));
+ await pubspecFile.writeAsString(
+ (await pubspecFile.readAsString())
+ .replaceAll('path: ../', 'path: ${rootUri.toFilePath()}'),
+ );
+
+ final pubGetResult = await runProcess(
+ executable: Uri.file(Platform.resolvedExecutable),
+ arguments: ['pub', 'get'],
+ workingDirectory: tempUri,
+ );
+ expect(pubGetResult.exitCode, 0);
+
+ {
+ final commandLinePath = Uri.file(
+ 'a${Platform.pathSeparator}b${Platform.pathSeparator}d.ext');
+ final result = await runProcess(
+ executable: Uri.file(Platform.resolvedExecutable),
+ arguments: [
+ tempUri.resolve(entryPoint).toFilePath(),
+ '-Dmy_path=${commandLinePath.toFilePath()}'
+ ],
+ workingDirectory: rootUri,
+ );
+ final stdout = (result.stdout as String).trim();
+ final resolvedPath = Uri.file(stdout);
+ expect(resolvedPath, rootUri.resolveUri(commandLinePath));
+ }
+
+ {
+ final commandLinePath = Uri.file(
+ 'a${Platform.pathSeparator}b${Platform.pathSeparator}d.ext');
+ final result = await runProcess(
+ executable: Uri.file(Platform.resolvedExecutable),
+ arguments: [
+ tempUri.resolve(entryPoint).toFilePath(),
+ '-Dmy_path=${commandLinePath.toFilePath()}'
+ ],
+ workingDirectory: tempUri,
+ );
+ final stdout = (result.stdout as String).trim();
+ final resolvedPath = Uri.file(stdout);
+ expect(resolvedPath, tempUri.resolveUri(commandLinePath));
+ }
+
+ final pathInFile =
+ Uri.file('a${Platform.pathSeparator}b${Platform.pathSeparator}d.ext');
+ final configUri = tempUri.resolve('config.yaml');
+ await File.fromUri(configUri).writeAsString('''
+my_path: ${pathInFile.toFilePath()}
+''');
+
+ {
+ final result = await runProcess(
+ executable: Uri.file(Platform.resolvedExecutable),
+ arguments: [
+ tempUri.resolve(entryPoint).toFilePath(),
+ '--config=${configUri.toFilePath()}'
+ ],
+ workingDirectory: tempUri,
+ );
+ final stdout = (result.stdout as String).trim();
+ final resolvedPath = Uri.file(stdout);
+ expect(resolvedPath, tempUri.resolveUri(pathInFile));
+ }
+
+ {
+ final result = await runProcess(
+ executable: Uri.file(Platform.resolvedExecutable),
+ arguments: [
+ tempUri.resolve(entryPoint).toFilePath(),
+ '--config=${configUri.toFilePath()}'
+ ],
+ workingDirectory: rootUri,
+ );
+ final stdout = (result.stdout as String).trim();
+ final resolvedPath = Uri.file(stdout);
+ expect(resolvedPath, tempUri.resolveUri(pathInFile));
+ }
+ });
+ });
+}
diff --git a/pkgs/cli_config/test/cli_config_test.dart b/pkgs/cli_config/test/cli_config_test.dart
new file mode 100644
index 0000000..073002c
--- /dev/null
+++ b/pkgs/cli_config/test/cli_config_test.dart
@@ -0,0 +1,567 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:cli_config/cli_config.dart';
+import 'package:test/test.dart';
+
+import 'helpers.dart';
+
+void main() {
+ test('optionalStringList', () {
+ const path1 = 'path/in/cli_arguments/';
+ const path2 = 'path/in/cli_arguments_2/';
+ const path3 = 'path/in/environment/';
+ const path4 = 'path/in/environment_2/';
+ const path5 = 'path/in/config_file/';
+ const path6 = 'path/in/config_file_2/';
+ final config = Config.fromConfigFileContents(
+ commandLineDefines: [
+ 'build.out_dir=$path1',
+ 'build.out_dir=$path2',
+ ],
+ environment: {
+ 'BUILD__OUT_DIR': '$path3:$path4',
+ },
+ fileContents: jsonEncode(
+ {
+ 'build': {
+ 'out_dir': [
+ path5,
+ path6,
+ ],
+ }
+ },
+ ),
+ );
+
+ {
+ final result = config.optionalStringList(
+ 'build.out_dir',
+ combineAllConfigs: true,
+ splitEnvironmentPattern: ':',
+ );
+ expect(result, [path1, path2, path3, path4, path5, path6]);
+ }
+
+ {
+ final result = config.optionalStringList(
+ 'build.out_dir',
+ combineAllConfigs: false,
+ splitEnvironmentPattern: ':',
+ );
+ expect(result, [path1, path2]);
+ }
+ });
+
+ test('optionalString cli precedence', () {
+ const path1 = 'path/in/cli_arguments/';
+ const path2 = 'path/in/environment/';
+ const path3 = 'path/in/config_file/';
+ final config = Config.fromConfigFileContents(
+ commandLineDefines: [
+ 'build.out_dir=$path1',
+ ],
+ environment: {
+ 'BUILD__OUT_DIR': path2,
+ },
+ fileContents: jsonEncode(
+ {
+ 'build': {
+ 'out_dir': path3,
+ }
+ },
+ ),
+ );
+
+ final result = config.optionalString(
+ 'build.out_dir',
+ );
+ expect(result, path1);
+ });
+
+ test('optionalString environment precedence', () {
+ const path2 = 'path/in/environment/';
+ const path3 = 'path/in/config_file/';
+ final config = Config.fromConfigFileContents(
+ commandLineDefines: [],
+ environment: {
+ 'BUILD__OUT_DIR': path2,
+ },
+ fileContents: jsonEncode(
+ {
+ 'build': {
+ 'out_dir': path3,
+ }
+ },
+ ),
+ );
+
+ final result = config.optionalString(
+ 'build.out_dir',
+ );
+ expect(result, path2);
+ });
+
+ test('optionalString config file', () {
+ const path3 = 'path/in/config_file/';
+ final config = Config.fromConfigFileContents(
+ commandLineDefines: [],
+ environment: {},
+ fileContents: jsonEncode(
+ {
+ 'build': {
+ 'out_dir': path3,
+ }
+ },
+ ),
+ );
+
+ final result = config.optionalString(
+ 'build.out_dir',
+ );
+ expect(result, path3);
+ });
+
+ test('optionalBool define', () {
+ final config = Config(
+ commandLineDefines: ['my_bool=true'],
+ );
+
+ expect(config.optionalBool('my_bool'), true);
+ });
+
+ test('optionalBool environment', () {
+ final config = Config(
+ environment: {
+ 'MY_BOOL': 'true',
+ },
+ );
+
+ expect(config.optionalBool('my_bool'), true);
+ });
+
+ test('optionalBool file', () {
+ final config = Config.fromConfigFileContents(
+ fileContents: jsonEncode(
+ {'my_bool': true},
+ ),
+ );
+
+ expect(config.optionalBool('my_bool'), true);
+ });
+
+ test('Read file and parse CLI args', () async {
+ final temp = await Directory.systemTemp.createTemp();
+ final configFile = File.fromUri(temp.uri.resolve('config.yaml'));
+ await configFile.writeAsString(jsonEncode(
+ {
+ 'build': {
+ 'out_dir': 'path/in/config_file/',
+ }
+ },
+ ));
+ final config = await Config.fromArguments(
+ arguments: [
+ '--config',
+ configFile.path,
+ '-Dbuild.out_dir=path/in/cli_arguments/',
+ ],
+ environment: {
+ 'BUILD__OUT_DIR': 'path/in/environment',
+ },
+ );
+
+ final result = config.optionalString('build.out_dir');
+ expect(result, 'path/in/cli_arguments/');
+ });
+
+ test('Resolve config file path relative to config file', () async {
+ final temp = await Directory.systemTemp.createTemp();
+ final tempUri = temp.uri;
+ final configUri = tempUri.resolve('config.yaml');
+ final configFile = File.fromUri(configUri);
+ const relativePath = 'path/in/config_file/';
+ final resolvedPath = configUri.resolve(relativePath);
+
+ await configFile.writeAsString(jsonEncode(
+ {
+ 'build': {
+ 'out_dir': relativePath,
+ }
+ },
+ ));
+
+ final config = await Config.fromArguments(
+ arguments: [
+ '--config',
+ configFile.path,
+ ],
+ );
+ final result = config.optionalPath('build.out_dir');
+ expect(result!.path, resolvedPath.path);
+
+ final configSync = Config.fromArgumentsSync(
+ arguments: [
+ '--config',
+ configFile.path,
+ ],
+ );
+ final resultSync = configSync.optionalPath('build.out_dir');
+ expect(resultSync!.path, resolvedPath.path);
+ });
+
+ test('provide pre-parsed config', () {
+ const path3 = 'path/in/config_file/';
+ final config = Config(
+ commandLineDefines: [],
+ environment: {},
+ fileParsed: {
+ 'build': {
+ 'out_dir': path3,
+ }
+ },
+ );
+
+ final result = config.optionalString('build.out_dir');
+ expect(result, path3);
+ });
+
+ test('path exists', () async {
+ await inTempDir((tempUri) async {
+ final tempFileUri = tempUri.resolve('file.ext');
+ await File.fromUri(tempFileUri).create();
+ final nonExistUri = tempUri.resolve('foo.ext');
+ final config = Config(
+ commandLineDefines: [],
+ environment: {},
+ fileParsed: {
+ 'build': {
+ 'out_dir': tempUri.toFilePath(),
+ 'file': tempFileUri.toFilePath(),
+ 'non_exist': nonExistUri.toFilePath(),
+ }
+ },
+ );
+
+ final result = config.optionalPath('build.out_dir', mustExist: true);
+ expect(result, tempUri);
+ final result2 = config.optionalPath('build.file', mustExist: true);
+ expect(result2, tempFileUri);
+ expect(
+ () => config.optionalPath('build.non_exist', mustExist: true),
+ throwsFormatException,
+ );
+ });
+ });
+
+ test('wrong CLI key format', () {
+ expect(
+ () => Config(commandLineDefines: ['CAPITALIZED=value']),
+ throwsFormatException,
+ );
+ });
+
+ test('CLI two values when expecting one', () {
+ final config = Config(commandLineDefines: ['key=value', 'key=value2']);
+ expect(
+ () => config.string('key'),
+ throwsFormatException,
+ );
+ });
+
+ test('CLI split optionalStringList', () {
+ final config = Config(commandLineDefines: ['key=value;value2']);
+ final value = config.optionalStringList('key', splitCliPattern: ';');
+ expect(value, ['value', 'value2']);
+ });
+
+ test('CLI path', () {
+ final uri = Uri.file('some/path.ext');
+ final config = Config(commandLineDefines: ['key=${uri.path}']);
+ final value = config.optionalPath('key');
+ expect(value, uri);
+ });
+
+ test('CLI path list', () {
+ final uri = Uri.file('some/path.ext');
+ final uri2 = Uri.file('some/directory/');
+ final config = Config(commandLineDefines: ['key=${uri.path}:${uri2.path}']);
+ final value = config.optionalPathList('key', splitCliPattern: ':');
+ expect(value, [uri, uri2]);
+ });
+
+ test('toString', () {
+ final config = Config(
+ commandLineDefines: ['key=foo'],
+ environment: {'key': 'bar'},
+ fileParsed: {'key': 'baz'},
+ );
+ config.toString();
+ });
+
+ test('Missing nonullable throws FormatException', () {
+ final config = Config.fromConfigFileContents();
+ expect(() => config.bool('key'), throwsFormatException);
+ expect(() => config.string('key'), throwsFormatException);
+ expect(() => config.path('key'), throwsFormatException);
+ });
+
+ test('string not validValue throws FormatException', () {
+ final config = Config(environment: {'foo': 'bar'});
+ expect(
+ () => config.string('foo', validValues: ['not_bar']),
+ throwsFormatException,
+ );
+ });
+
+ test('optionalString validValues', () {
+ final config = Config();
+ expect(config.optionalString('foo', validValues: ['bar']), isNull);
+ });
+
+ test('valueOf file source', () {
+ final config = Config(fileParsed: {
+ 'key': {'some': 'map'}
+ });
+ final value = config.valueOf<Map<dynamic, dynamic>>('key');
+ expect(value, {'some': 'map'});
+ });
+
+ test('valueOf command line source', () {
+ final config = Config(commandLineDefines: [
+ 'string_key=value',
+ 'bool_key=true',
+ 'string_list_key=value1',
+ 'string_list_key=value2',
+ ]);
+ expect(config.valueOf<String>('string_key'), 'value');
+ expect(config.valueOf<bool>('bool_key'), true);
+ expect(
+ config.valueOf<List<String>>('string_list_key'),
+ ['value1', 'value2'],
+ );
+ });
+
+ test('environment split optionalStringList', () {
+ final config = Config(environment: {'key': 'value;value2'});
+ final value =
+ config.optionalStringList('key', splitEnvironmentPattern: ';');
+ expect(value, ['value', 'value2']);
+ });
+
+ test('environment non split optionalStringList', () {
+ final config = Config(environment: {'key': 'value'});
+ final value = config.optionalStringList('key');
+ expect(value, ['value']);
+ });
+
+ test('environment path', () {
+ final uri = Uri.file('some/path.ext');
+ final config = Config(environment: {'key': uri.path});
+ final value = config.optionalPath('key');
+ expect(value, uri);
+ });
+
+ test('environment path list', () {
+ final uri = Uri.file('some/path.ext');
+ final uri2 = Uri.file('some/directory/');
+ final config = Config(environment: {'key': '${uri.path}:${uri2.path}'});
+ final value = config.optionalPathList('key', splitEnvironmentPattern: ':');
+ expect(value, [uri, uri2]);
+ });
+
+ test('Unexpected config file contents', () {
+ expect(() => Config.fromConfigFileContents(fileContents: 'asdf'),
+ throwsFormatException);
+ expect(() => Config.fromConfigFileContents(fileContents: "['asdf']"),
+ throwsFormatException);
+ expect(
+ () => Config.fromConfigFileContents(
+ fileContents: '''
+WRONGKEY:
+ 1
+'''
+ .trim()),
+ throwsFormatException,
+ );
+ expect(
+ () => Config.fromConfigFileContents(
+ fileContents: '''
+1: 'asdf'
+'''
+ .trim()),
+ throwsFormatException,
+ );
+ });
+
+ test('file config try to access object as wrong type', () {
+ final config = Config.fromConfigFileContents(fileContents: '''foo:
+ bar:
+ true
+''');
+ expect(config.bool('foo.bar'), true);
+ expect(() => config.bool('foo.bar.baz'), throwsFormatException);
+ expect(() => config.string('foo.bar'), throwsFormatException);
+ });
+
+ test('file config path list unresolved', () {
+ final uri = Uri.file('some/path.ext');
+ final uri2 = Uri.file('some/directory/');
+ final config = Config(fileParsed: {
+ 'key': [uri.path, uri2.path]
+ });
+ final value = config.optionalPathList('key', resolveUri: false);
+ expect(value, [uri, uri2]);
+ });
+
+ test('file config path list resolved', () {
+ final configUri = Uri.file('path/to/config.json');
+ final uri = Uri.file('some/path.ext');
+ final uri2 = Uri.file('some/directory/');
+ final config = Config(
+ fileSourceUri: configUri,
+ fileParsed: {
+ 'key': [uri.path, uri2.path]
+ },
+ );
+ final value = config.optionalPathList('key', resolveUri: true);
+ expect(value, [configUri.resolveUri(uri), configUri.resolveUri(uri2)]);
+ });
+
+ test('resolveUri in working directory', () {
+ final systemTemp = Directory.systemTemp.uri;
+ final tempUri = systemTemp.resolve('x/y/z/');
+
+ final relativePath = Uri.file('a/b/c/d.ext');
+ final absolutePath = tempUri.resolveUri(relativePath);
+ final config = Config(
+ commandLineDefines: ['path=${relativePath.path}'],
+ workingDirectory: tempUri,
+ );
+
+ expect(config.optionalPath('path', mustExist: false, resolveUri: true),
+ absolutePath);
+ });
+
+ test('ints', () {
+ final config = Config(
+ commandLineDefines: ['cl=1', 'not_parsable=asdf'],
+ environment: {
+ 'env': '2',
+ 'not_parsable2': 'asfd',
+ },
+ fileParsed: {'file': 3},
+ );
+
+ expect(config.int('cl'), 1);
+ expect(config.optionalInt('env'), 2);
+ expect(config.optionalInt('file'), 3);
+ expect(config.optionalInt('nothing'), null);
+ expect(() => config.optionalInt('not_parsable'), throwsFormatException);
+ expect(() => config.optionalInt('not_parsable2'), throwsFormatException);
+ });
+
+ test('doubles', () {
+ final config = Config(
+ commandLineDefines: ['cl=1.1', 'not_parsable=asdf'],
+ environment: {
+ 'env': '2.2',
+ 'not_parsable2': 'asfd',
+ },
+ fileParsed: {'file': 3.3},
+ );
+
+ expect(config.double('cl'), 1.1);
+ expect(config.optionalDouble('env'), 2.2);
+ expect(config.optionalDouble('file'), 3.3);
+ expect(config.optionalDouble('nothing'), null);
+ expect(() => config.optionalDouble('not_parsable'), throwsFormatException);
+ expect(() => config.optionalDouble('not_parsable2'), throwsFormatException);
+ });
+
+ test('stringList and optionalStringList', () {
+ {
+ final config = Config(
+ fileParsed: {},
+ );
+
+ expect(config.optionalStringList('my_list'), null);
+ expect(() => config.stringList('my_list'), throwsFormatException);
+ }
+
+ {
+ final config = Config(
+ fileParsed: {'my_list': <String>[]},
+ );
+
+ expect(config.optionalStringList('my_list'), <String>[]);
+ expect(config.stringList('my_list'), <String>[]);
+ }
+ });
+
+ test('pathList and optionalPathList', () {
+ {
+ final config = Config(
+ fileParsed: {},
+ );
+
+ expect(config.optionalPathList('my_list'), null);
+ expect(() => config.pathList('my_list'), throwsFormatException);
+ }
+
+ {
+ final config = Config(
+ fileParsed: {'my_list': <String>[]},
+ );
+
+ expect(config.optionalPathList('my_list'), <String>[]);
+ expect(config.pathList('my_list'), <String>[]);
+ }
+ });
+
+ test('non-string key maps', () {
+ // This is valid in YAML (not in JSON).
+ //
+ // Such values cannot be accessed with our hierarchical keys, but they can
+ // be accessed with [Config.valueOf].
+ final config = Config(
+ fileParsed: {
+ 'my_non_string_key_map': {
+ 1: 'asdf',
+ 2: 'foo',
+ },
+ },
+ );
+
+ expect(
+ config.valueOf<Map<Object, Object?>>('my_non_string_key_map'),
+ {
+ 1: 'asdf',
+ 2: 'foo',
+ },
+ );
+ });
+
+ test('null values in maps', () {
+ final config = Config(
+ fileParsed: {
+ 'my_non_string_key_map': {
+ 'x': null,
+ 'y': 42,
+ },
+ },
+ );
+
+ expect(
+ config.valueOf<Map<Object, Object?>>('my_non_string_key_map'),
+ {
+ 'x': null,
+ 'y': 42,
+ },
+ );
+ });
+}
diff --git a/pkgs/cli_config/test/cli_config_windows_test.dart b/pkgs/cli_config/test/cli_config_windows_test.dart
new file mode 100644
index 0000000..2c401f2
--- /dev/null
+++ b/pkgs/cli_config/test/cli_config_windows_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2023, 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.
+
+@TestOn('windows')
+library;
+
+import 'package:cli_config/cli_config.dart';
+import 'package:test/test.dart';
+
+void main() {
+ test('path resolving windows', () {
+ const path = 'C:\\foo\\bar\\';
+ final workingDirectory = Uri.parse('file:///C:/baz/baf/');
+
+ final config = Config(
+ commandLineDefines: ['key=$path'],
+ workingDirectory: workingDirectory,
+ );
+ final value = config.path('key', resolveUri: true);
+ expect(value.toFilePath(), path);
+ });
+}
diff --git a/pkgs/cli_config/test/helpers.dart b/pkgs/cli_config/test/helpers.dart
new file mode 100644
index 0000000..d9fb40e
--- /dev/null
+++ b/pkgs/cli_config/test/helpers.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+const keepTempKey = 'KEEP_TEMPORARY_DIRECTORIES';
+
+Future<void> inTempDir(
+ Future<void> Function(Uri tempUri) fun, {
+ String? prefix,
+}) async {
+ final tempDir = await Directory.systemTemp.createTemp(prefix);
+ // Deal with Windows temp folder aliases.
+ final tempUri =
+ Directory(await tempDir.resolveSymbolicLinks()).uri.normalizePath();
+ try {
+ await fun(tempUri);
+ } finally {
+ if (!Platform.environment.containsKey(keepTempKey) ||
+ Platform.environment[keepTempKey]!.isEmpty) {
+ await tempDir.delete(recursive: true);
+ }
+ }
+}
+
+Future<ProcessResult> runProcess({
+ required Uri executable,
+ List<String> arguments = const [],
+ required Uri workingDirectory,
+}) async {
+ final result = await Process.run(
+ executable.toFilePath(),
+ arguments,
+ workingDirectory: workingDirectory.toFilePath(),
+ );
+ if (result.exitCode != 0) {
+ print(result.stdout);
+ print(result.stderr);
+ print(result.exitCode);
+ }
+ return result;
+}
diff --git a/pkgs/coverage/.gitignore b/pkgs/coverage/.gitignore
new file mode 100644
index 0000000..1a25097
--- /dev/null
+++ b/pkgs/coverage/.gitignore
@@ -0,0 +1,18 @@
+# Pub
+packages
+pubspec.lock
+build
+.dart_tool/
+.pub
+.packages
+
+# IDEs
+.project
+.settings
+.idea
+*.iml
+
+# Temp files
+*~
+coverage/
+var/
diff --git a/pkgs/coverage/AUTHORS b/pkgs/coverage/AUTHORS
new file mode 100644
index 0000000..7513829
--- /dev/null
+++ b/pkgs/coverage/AUTHORS
@@ -0,0 +1,12 @@
+# Below is a list of people and organizations that have contributed
+# to the coverage project. Names should be added to the list like so:
+#
+# Name/Organization <email address>
+
+Google Inc.
+Achilleas Anagnostopoulos <achilleas.imap.mbox@gmail.com>
+Adam Singer <adammichaelsinger@gmail.com>
+Cédric Belin <cedxbelin@gmail.com>
+Evan Weible <ekweible@gmail.com>
+Günter Zöchbauer <guenter@gzoechbauer.com>
+Will Drach <will.drach@gmail.com>
diff --git a/pkgs/coverage/CHANGELOG.md b/pkgs/coverage/CHANGELOG.md
new file mode 100644
index 0000000..a58d0dc
--- /dev/null
+++ b/pkgs/coverage/CHANGELOG.md
@@ -0,0 +1,496 @@
+## 1.10.0
+
+- Fix bug where tests involving multiple isolates never finish (#520).
+
+## 1.9.2
+
+- Fix repository link in pubspec.
+
+## 1.9.1
+
+- Remove outdated VM service version checks.
+- Move to `dart-lang/tools`.
+
+## 1.9.0
+
+- Require Dart ^3.4
+- Fix bug where some ranges were able to bypass the `--scope-output` filters.
+- Add --ignore-files option allowing to exclude files from coverage reports using glob patterns
+
+## 1.8.0
+
+- Copy collect_coverage's `--scope-output` flag to test_with_coverage.
+
+## 1.7.2
+
+- Update `package:vm_service` constraints to '>=12.0.0 <15.0.0'.
+
+## 1.7.1
+
+- Update `package:vm_service` constraints to '>=12.0.0 <14.0.0'.
+
+## 1.7.0
+
+- Require Dart 3.0.0
+- Update `package:vm_service` constraints to '^12.0.0'.
+- Add `coverableLineCache` parameter to `collect`. This allows the set of
+ coverable lines to be cached between calls to `collect`, avoiding the need to
+ force compile the same libraries repeatedly. This is only useful when running
+ multiple coverage collections over the same libraries.
+
+## 1.6.4
+
+- allow omitting space between `//` and `coverage` in coverage ignore comments
+- allow text after coverage ignore comments
+- throw FormatException when encountering unbalanced ignore comments instead of silently erroring
+- Update `package:vm_service` constraints to '>= 9.4.0 <12.0.0'.
+
+## 1.6.3
+
+- Require Dart 2.18
+- Update `package:vm_service` constraints to '>=9.4.0 <12.0.0'.
+
+## 1.6.2
+
+- Update `package:vm_service` constraints to '>=9.4.0 <11.0.0'.
+
+## 1.6.1
+
+- Handle SentinelExceptions thrown by vm_service.
+
+## 1.6.0
+
+- Update to vm_service 9.4.0.
+- Use IsolateRef.isolateGroupId to speed up coverage collection.
+- Ignore uncoverable abstract methods.
+- Fix bug where 'ingore-line' comments etc are applied even if they're inside
+ string literals.
+- Change the LICENSE file to the standard Dart BSD license.
+
+## 1.5.0
+
+- Support passing extra arguments to `test_with_coverage` which are then passed
+ to `package:test`.
+
+ Example: `dart run coverage:test_with_coverage -- --preset CI`
+
+## 1.4.0
+
+- Added `HitMap.parseJsonSync` which takes a cache of ignored lines which can
+ speedup calls when `checkIgnoredLines` is true and the function is called
+ several times with overlapping files in the input json.
+- Bump the version of vm_service to 9.0.0.
+
+## 1.3.2
+
+- Fix test_with_coverage listening to an unsupported signal on windows.
+- Fix `--reportOn` on windows using incorrect path separators.
+
+## 1.3.1
+
+- Fix running `dart pub global run coverage:test_with_coverage` or
+ `dart run coverage:test_with_coverage`
+
+## 1.3.0
+
+- Bump the minimum Dart SDK version to 2.15.0
+- Add a `--package` flag, which takes the package's root directory, instead of
+ the .package file. Deprecate the `--packages` flag.
+- Deprecate the packagesPath parameter and add packagePath instead, in
+ `HitMap.parseJson`, `HitMap.parseFiles`, `createHitmap`, and `parseCoverage`.
+- Add a new executable to the package, `test_with_coverage`. This simplifies the
+ most common use case of coverage, running all the tests for a package, and
+ generating an lcov.info file.
+- Use the `libraryFilters` option in `getSourceReport` to speed up coverage runs
+ that use `scopedOutput`.
+
+## 1.2.0
+
+- Support branch level coverage information, when running tests in the Dart VM.
+ This is not supported for web tests yet.
+- Add flag `--branch-coverage` (abbr `-b`) to collect_coverage that collects
+ branch coverage information. The VM must also be run with the
+ `--branch-coverage` flag.
+- Add flag `--pretty-print-branch` to format_coverage that works similarly to
+ pretty print, but outputs branch level coverage, rather than line level.
+- Update `--lcov` (abbr `-l`) in format_coverage to output branch level
+ coverage, in addition to line level.
+- Add an optional bool flag to `collect` that controls whether branch coverage
+ is collected.
+- Add a `branchHits` field to `HitMap`.
+- Add support for scraping the service URI from the new Dart VM service message.
+- Correctly parse package_config files on Windows when the root URI is relative.
+
+## 1.1.0
+
+- Support function level coverage information, when running tests in the Dart
+ VM. This is not supported for web tests yet.
+- Add flag `--function-coverage` (abbr `-f`) to collect_coverage that collects
+ function coverage information.
+- Add flag `--pretty-print-func` (abbr `-f`) to format_coverage that works
+ similarly to pretty print, but outputs function level coverage, rather than
+ line level.
+- Update `--lcov` (abbr `-l`) in format_coverage to output function level
+ coverage, in addition to line level.
+- Add an optional bool flag to `collect` that controls whether function coverage
+ is collected.
+- Added `HitMap.parseJson`, `FileHitMaps.merge`, `HitMap.parseFiles`,
+ `HitMap.toJson`, `FileHitMapsFormatter.formatLcov`, and
+ `FileHitMapsFormatter.prettyPrint` that switch from using `Map<int, int>` to
+ represent line coverage to using `HitMap` (which contains both line and
+ function coverage). Document the old versions of these functions as
+ deprecated. We will delete the old functions when we update to coverage
+ version 2.0.0.
+- Ensure `createHitmap` returns a sorted hitmap. This fixes a potential issue
+ with ignore line annotations.
+- Use the `reportLines` flag in `vm_service`'s `getSourceReport` RPC. This
+ typically halves the number of RPCs that the coverage collector needs to run.
+- Require Dart `>=2.14.0`
+
+## 1.0.4
+
+- Updated dependency on `vm_service` package from `>=6.1.0 <8.0.0`to
+ `>=8.1.0 <9.0.0`.
+
+## 1.0.3
+
+- Updated dependency on `vm_service` package from `^6.1.0` to `>=6.1.0 <8.0.0`.
+
+## 1.0.2
+
+- Fix an issue where the `--packages` argument wasn't passed to
+ `format_coverage`.
+
+## 1.0.1
+
+- Allow the chrome `sourceUriProvider` to return `null`.
+
+## 1.0.0
+
+- Migrate to null safety.
+- Removed support for SDK `1.x.x`.
+
+## 0.15.2
+
+- Update `args`, `logging`, and `package_config` deps to allow the latest stable
+ releases.
+
+## 0.15.1
+
+- Updated dependency on `vm_service` package from `>=1.0.0 < 5.0.0` to
+ `>=1.0.0 <7.0.0`.
+
+## 0.15.0
+
+- BREAKING CHANGE: Eliminate the `--package-root` option from
+ `bin/run_and_collect.dart` and `bin/format_coverage.dart` as well as from
+ `runAndCollect` and the `Resolver` constructor.
+
+## 0.14.2
+
+- Fix an issue where `--wait-paused` with `collect` would attempt to collect
+ coverage if no isolates have started.
+
+## 0.14.1
+
+- Updated dependency on `vm_service` package from `>=1.0.0 < 5.0.0` to
+ `>=1.0.0 <6.0.0`.
+
+## 0.14.0
+
+- Add flag `--check-ignore` that is used to ignore lines from coverage depending
+ on the comments.
+
+ Use // coverage:ignore-line to ignore one line. Use // coverage:ignore-start
+ and // coverage:ignore-end to ignore range of lines inclusive. Use //
+ coverage:ignore-file to ignore the whole file.
+
+## 0.13.11
+
+- Revert breaking change in 13.10
+
+## 0.13.10
+
+- Add flag `--check-ignore` that is used to ignore lines from coverage depending
+ on the comments.
+
+ Use // coverage:ignore-line to ignore one line. Use // coverage:ignore-start
+ and // coverage:ignore-end to ignore range of lines inclusive. Use //
+ coverage:ignore-file to ignore the whole file.
+
+## 0.13.9
+
+- Don't crash on empty JSON input files.
+- Loosen the dependency on the `vm_service` package from `>=1.0.0 <4.0.0` to
+ `>=1.0.0 <5.0.0`.
+
+## 0.13.8
+
+- Update to package_config `1.9.0` which supports package_config.json files and
+ should be forwards compatible with `2.0.0`.
+- Deprecate the `packageRoot` argument on `Resolver`.
+
+## 0.13.7
+
+- Loosen the dependency on the `vm_service` package from `>=1.0.0 <3.0.0` to
+ `>=1.0.0 <4.0.0`.
+
+## 0.13.6
+
+- Now consider all `.json` files for the `format_coverage` command.
+
+## 0.13.5
+
+- Update `parseChromeCoverage` to merge coverage information for a given line.
+- Handle source map parse errors in `parseChromeCoverage`. Coverage will not be
+ considered for Dart files that have corresponding invalid source maps.
+
+## 0.13.4
+
+- Add `parseChromeCoverage` for creating a Dart based coverage report from a
+ Chrome coverage report.
+
+## 0.13.3+3 - 2019-12-03
+
+- Re-loosen the dependency on the `vm_service` package from `>=1.0.0 < 2.1.2` to
+ `>=1.0.0 <3.0.0` now that breakage introduced in version `2.1.2` has been
+ resolved. Fixed in:
+ https://github.com/dart-lang/sdk/commit/7a911ce3f1e945f2cbd1967c6109127e3acbab5a.
+
+## 0.13.3+2 - 2019-12-02
+
+- Tighten the dependency on the `vm_service` package from `>=1.0.0 <3.0.0` down
+ to `>=1.0.0 <2.1.2` in order to exclude version `2.1.2` which is broken on the
+ current stable Dart VM due to a missing SDK constraint in its pubspec.yaml.
+ The breakage was introduced in:
+ https://github.com/dart-lang/sdk/commit/9e636b5ab4de850fb19bc262e0686fdf14bfbfc0.
+
+## 0.13.3+1 - 2019-10-10
+
+- Loosen the dependency on the `vm_service` package from `^1.0.0` to
+ `>=1.0.0 <3.0.0`. Ensures dependency version range compatibility with the
+ latest versions of package `test`.
+
+## 0.13.3
+
+- Adds a new named argument to `collect` to filter coverage results by a set of
+ VM isolate IDs.
+- Migrates implementation of VM service protocol library from
+ `package:vm_service_lib`, which is no longer maintained, to
+ `package:vm_service`, which is.
+
+## 0.13.2
+
+- Add new multi-flag option `--scope-output` which restricts coverage output so
+ that only scripts that start with the provided path are considered.
+
+## 0.13.1
+
+- Handle scenario where the VM returns empty coverage information for a range.
+
+## 0.13.0
+
+- BREAKING CHANGE: Skips collecting coverage for `dart:` libraries by default,
+ which provides a significant performance boost. To restore the previous
+ behaviour and collect coverage for these libraries, use the `--include-dart`
+ flag.
+- Disables WebSocket compression for coverage collection. Since almost all
+ coverage collection runs happen over the loopback interface to localhost, this
+ improves performance and reduces CPU usage.
+- Migrates implementation of VM service protocol library from
+ `package:vm_service_client`, which is no longer maintained, to
+ `package:vm_service_lib`, which is.
+
+## 0.12.4
+
+- `collect()` now immediately throws `ArgumentError` if a null URI is passed in
+ the `serviceUri` parameter to avoid a less-easily debuggable null dereference
+ later. See dart-lang/coverage#240 for details.
+
+## 0.12.3
+
+- Fixed dart-lang/coverage#194. During collection, we now track each script by
+ its (unique) VMScriptRef. This ensures we look up the correct script when
+ computing the affected line for each hit token. The hitmap remains URI based,
+ since in the end, we want a single, unified set of line to hitCount mappings
+ per script.
+
+## 0.12.2
+
+- Dart SDK upper bound raised to <3.0.0.
+
+## 0.12.1
+
+- Minor type, dartfmt fixes.
+- Require package:args >= 1.4.0.
+
+## 0.12.0
+
+- BREAKING CHANGE: This version requires Dart SDK 2.0.0-dev.64.1 or later.
+- Strong mode fixes as of Dart SDK 2.0.0-dev.64.1.
+
+## 0.11.0
+
+- BREAKING CHANGE: This version requires Dart SDK 2.0.0-dev.30 or later.
+- Updated to Dart 2.0 constants from dart:convert.
+
+## 0.10.0
+
+- BREAKING CHANGE: `createHitmap` and `mergeHitmaps` now specify generic types
+ (`Map<String, Map<int, int>>`) on their hit map parameter/return value.
+- Updated package:args dependency to 1.0.0.
+
+## 0.9.3
+
+- Strong mode fixes as of Dart SDK 1.24.0.
+- Restrict the SDK lower version constraint to `>=1.21.0`. Required for method
+ generics.
+- Eliminate dependency on package:async.
+
+## 0.9.2
+
+- Strong mode fixes as of Dart SDK 1.22.0.
+
+## 0.9.1
+
+- Temporarily add back support for the `--host` and `--port` options to
+ `collect_coverage`. This is a temporary measure for backwards-compatibility
+ that may stop working on Dart SDKs >= 1.22. See the related
+ [breaking change note](https://groups.google.com/a/dartlang.org/forum/#!msg/announce/VxSw-V5tx8k/wPV0GfX7BwAJ)
+ for the Dart VM service protocol.
+
+## 0.9.0
+
+- BREAKING CHANGE: `collect` no longer supports the `host` and `port`
+ parameters. These are replaced with a `serviceUri` parameter. As of Dart SDK
+ 1.22, the Dart VM will emit Observatory URIs that include an authentication
+ token for security reasons. Automated tools will need to scrape stdout for
+ this URI and pass it to `collect_coverage`.
+- BREAKING CHANGE: `collect_coverage`: the `--host` and `--port` options have
+ been replaced with a `--uri` option. See the above change for details.
+- BREAKING CHANGE: `runAndCollect` now defaults to running in checked mode.
+- Added `extractObservatoryUri`: scrapes an input string for an Observatory URI.
+ Potentially useful for automated tooling after Dart SDK 1.22.
+
+## 0.8.1
+
+- Added optional `checked` parameter to `runAndCollect` to run in checked mode.
+
+## 0.8.0+2
+
+- Strong mode fixes as of Dart SDK 1.20.1.
+
+## 0.8.0+1
+
+- Make strong mode clean.
+
+## 0.8.0
+
+- Moved `Formatter.format` parameters `reportOn` and `basePath` to constructor.
+ Eliminated `pathFilter` parameter.
+
+## 0.7.9
+
+- `format_coverage`: add `--base-directory` option. Source paths in
+ LCOV/pretty-print output are relative to this directory, or absolute if
+ unspecified.
+
+## 0.7.8
+
+- `format_coverage`: support `--packages` option for package specs.
+
+## 0.7.7
+
+- Add fallback URI resolution for Bazel http(s) URIs that don't contain a
+ `packages` path component.
+
+## 0.7.6
+
+- Add [Bazel](http://bazel.io) support to `format_coverage`.
+
+## 0.7.5
+
+- Bugfix in `collect_coverage`: prevent hang if initial VM service connection is
+ slow.
+- Workaround for VM behaviour in which `evaluate:source` ranges may appear in
+ the returned source report manifesting in a crash in `collect_coverage`. These
+ generally correspond to source evaluations in the debugger and add little
+ value to line coverage.
+- `format_coverage`: may be slower for large sets of coverage JSON input files.
+ Unlikely to be an issue due to elimination of `--coverage-dir` VM flag.
+
+## 0.7.4
+
+- Require at least Dart SDK 1.16.0.
+
+- Bugfix in format_coverage: if `--report-on` is not specified, emit all
+ coverage, rather than none.
+
+## 0.7.3
+
+- Added support for the latest Dart SDK.
+
+## 0.7.2
+
+- `Formatter.format` added two optional arguments: `reportOn` and `pathFilter`.
+ They can be used independently to limit the files which are included in the
+ output.
+
+- Added `runAndCollect` API to library.
+
+## 0.7.1
+
+- Added `collect` top-level method.
+
+- Updated support for latest `0.11.0` dev build.
+
+- Replaced `ServiceEvent.eventType` with `ServiceEvent.kind`.
+ - `ServiceEvent.eventType` is deprecated and will be removed in `0.8`.
+
+## 0.7.0
+
+- `format_coverage` no longer emits SDK coverage unless --sdk-root is set
+ explicitly.
+
+- Removed support for collecting coverage from old (<1.9.0) Dart SDKs.
+
+- Removed deprecated `Resolver.pkgRoot`.
+
+## 0.6.5
+
+- Fixed early collection bug when --wait-paused is set.
+
+## 0.6.4
+
+- Optimized formatters and fixed return value of `format` methods.
+
+- Added `Resolver.packageRoot` – deprecated `Resolver.pkgRoot`.
+
+## 0.6.3
+
+- Support the latest release of `args` package.
+
+- Support the latest release of `logging` package.
+
+- Fixed error when trying to access invalid paths.
+
+- Require at least Dart SDK v1.9.0.
+
+## 0.6.2
+
+- Support observatory protocol changes for VM >= 1.11.0.
+
+## 0.6.1
+
+- Support observatory protocol changes for VM >= 1.10.0.
+
+## 0.6.0+1
+
+- Add support for `pub global run`.
+
+## 0.6.0
+
+- Add support for SDK versions >= 1.9.0. For Dartium/content-shell versions past
+ 1.9.0, coverage collection is no longer done over the remote debugging port,
+ but via the observatory port emitted on stdout. Backward compatibility with
+ SDKs back to 1.5.x is provided.
diff --git a/pkgs/coverage/LICENSE b/pkgs/coverage/LICENSE
new file mode 100644
index 0000000..000cd7b
--- /dev/null
+++ b/pkgs/coverage/LICENSE
@@ -0,0 +1,27 @@
+Copyright 2014, the Dart project authors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of Google LLC nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/pkgs/coverage/PATENTS b/pkgs/coverage/PATENTS
new file mode 100644
index 0000000..6954196
--- /dev/null
+++ b/pkgs/coverage/PATENTS
@@ -0,0 +1,23 @@
+Additional IP Rights Grant (Patents)
+
+"This implementation" means the copyrightable works distributed by
+Google as part of the Dart Project.
+
+Google hereby grants to you a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable (except as stated in this
+section) patent license to make, have made, use, offer to sell, sell,
+import, transfer, and otherwise run, modify and propagate the contents
+of this implementation of Dart, where such license applies only to
+those patent claims, both currently owned by Google and acquired in
+the future, licensable by Google that are necessarily infringed by
+this implementation of Dart. This grant does not include claims that
+would be infringed only as a consequence of further modification of
+this implementation. If you or your agent or exclusive licensee
+institute or order or agree to the institution of patent litigation
+against any entity (including a cross-claim or counterclaim in a
+lawsuit) alleging that this implementation of Dart or any code
+incorporated within this implementation of Dart constitutes direct or
+contributory patent infringement, or inducement of patent
+infringement, then any patent rights granted to you under this License
+for this implementation of Dart shall terminate as of the date such
+litigation is filed.
diff --git a/pkgs/coverage/README.md b/pkgs/coverage/README.md
new file mode 100644
index 0000000..81736a4
--- /dev/null
+++ b/pkgs/coverage/README.md
@@ -0,0 +1,123 @@
+Coverage provides coverage data collection, manipulation, and formatting for
+Dart.
+
+[](https://github.com/dart-lang/tools/actions/workflows/coverage.yml)
+[](https://coveralls.io/github/dart-lang/tools?branch=main)
+[](https://pub.dev/packages/coverage)
+
+## Tools
+
+`collect_coverage` collects coverage JSON from the Dart VM Service.
+`format_coverage` formats JSON coverage data into either
+[LCOV](https://github.com/linux-test-project/lcov) or pretty-printed format.
+
+#### Install coverage
+
+ dart pub global activate coverage
+
+Consider adding the `dart pub global run` executables directory to your path.
+See
+[Running a script from your PATH](https://dart.dev/tools/pub/cmd/pub-global#running-a-script-from-your-path)
+for more details.
+
+#### Running tests with coverage
+
+For the common use case where you just want to run all your tests, and generate
+an lcov.info file, you can use the test_with_coverage script:
+
+```
+dart pub global run coverage:test_with_coverage
+```
+
+By default, this script assumes it's being run from the root directory of a
+package, and outputs a coverage.json and lcov.info file to ./coverage/
+
+This script is essentially the same as running:
+
+```
+dart run --pause-isolates-on-exit --disable-service-auth-codes --enable-vm-service=8181 test &
+dart pub global run coverage:collect_coverage --wait-paused --uri=http://127.0.0.1:8181/ -o coverage/coverage.json --resume-isolates --scope-output=foo
+dart pub global run coverage:format_coverage --packages=.dart_tool/package_config.json --lcov -i coverage/coverage.json -o coverage/lcov.info
+```
+
+For more complicated use cases, where you want to control each of these stages,
+see the sections below.
+
+#### Collecting coverage from the VM
+
+```
+dart --pause-isolates-on-exit --disable-service-auth-codes --enable-vm-service=NNNN script.dart
+dart pub global run coverage:collect_coverage --uri=http://... -o coverage.json --resume-isolates
+```
+
+or if the `dart pub global run` executables are on your PATH,
+
+```
+collect_coverage --uri=http://... -o coverage.json --resume-isolates
+```
+
+where `--uri` specifies the Dart VM Service URI emitted by the VM.
+
+If `collect_coverage` is invoked before the script from which coverage is to be
+collected, it will wait until it detects a VM observatory to which it can
+connect. An optional `--connect-timeout` may be specified (in seconds). The
+`--wait-paused` flag may be enabled, causing `collect_coverage` to wait until
+all isolates are paused before collecting coverage.
+
+#### Formatting coverage data
+
+```
+dart pub global run coverage:format_coverage --package=app_package -i coverage.json
+```
+
+or if the `dart pub global run` exectuables are on your PATH,
+
+```
+format_coverage --package=app_package -i coverage.json
+```
+
+where `app_package` is the path to the package whose coverage is being collected
+(defaults to the current working directory). If `--sdk-root` is set, Dart SDK
+coverage will also be output.
+
+#### Ignore lines from coverage
+
+- `// coverage:ignore-line` to ignore one line.
+- `// coverage:ignore-start` and `// coverage:ignore-end` to ignore range of
+ lines inclusive.
+- `// coverage:ignore-file` to ignore the whole file.
+
+Then pass `--check-ignore` to `format_coverage`.
+
+#### Function and branch coverage
+
+To gather function level coverage information, pass `--function-coverage` to
+collect_coverage:
+
+```
+dart --pause-isolates-on-exit --disable-service-auth-codes --enable-vm-service=NNNN script.dart
+dart pub global run coverage:collect_coverage --uri=http://... -o coverage.json --resume-isolates --function-coverage
+```
+
+To gather branch level coverage information, pass `--branch-coverage` to _both_
+collect_coverage and the Dart command you're gathering coverage from:
+
+```
+dart --pause-isolates-on-exit --disable-service-auth-codes --enable-vm-service=NNNN --branch-coverage script.dart
+dart pub global run coverage:collect_coverage --uri=http://... -o coverage.json --resume-isolates --branch-coverage
+```
+
+Branch coverage requires Dart VM 2.17.0, with service API v3.56. Function,
+branch, and line coverage can all be gathered at the same time, by combining
+those flags:
+
+```
+dart --pause-isolates-on-exit --disable-service-auth-codes --enable-vm-service=NNNN --branch-coverage script.dart
+dart pub global run coverage:collect_coverage --uri=http://... -o coverage.json --resume-isolates --function-coverage --branch-coverage
+```
+
+These flags can also be passed to test_with_coverage:
+
+```
+pub global run coverage:test_with_coverage --branch-coverage --function-coverage
+```
diff --git a/pkgs/coverage/analysis_options.yaml b/pkgs/coverage/analysis_options.yaml
new file mode 100644
index 0000000..1d9542a
--- /dev/null
+++ b/pkgs/coverage/analysis_options.yaml
@@ -0,0 +1,23 @@
+include: package:dart_flutter_team_lints/analysis_options.yaml
+
+analyzer:
+ language:
+ strict-casts: true
+
+ exclude:
+ - var/**
+
+linter:
+ rules:
+ - always_declare_return_types
+ - avoid_slow_async_io
+ - cancel_subscriptions
+ - comment_references
+ - literal_only_boolean_expressions
+ - package_api_docs
+ - prefer_final_locals
+ - sort_constructors_first
+ - sort_unnamed_constructors_first
+ - test_types_in_equals
+ - throw_in_finally
+ - type_annotate_public_apis
diff --git a/pkgs/coverage/benchmark/.gitignore b/pkgs/coverage/benchmark/.gitignore
new file mode 100644
index 0000000..1269488
--- /dev/null
+++ b/pkgs/coverage/benchmark/.gitignore
@@ -0,0 +1 @@
+data
diff --git a/pkgs/coverage/benchmark/many_isolates.dart b/pkgs/coverage/benchmark/many_isolates.dart
new file mode 100644
index 0000000..185576a
--- /dev/null
+++ b/pkgs/coverage/benchmark/many_isolates.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:isolate';
+import 'dart:math';
+
+Future<void> main(List<String> args, dynamic message) async {
+ if (message == null) {
+ // If there is no message, it means this instance was created by
+ // run_benchmarks.dart. In that case, this is the parent instance that
+ // spawns all the others.
+ var sum = 0;
+ for (var i = 0; i < 10; ++i) {
+ final port = ReceivePort();
+ final isolate =
+ Isolate.spawnUri(Uri.file('many_isolates.dart'), [], port.sendPort);
+ sum += await port.first as int;
+ await isolate;
+ }
+ print('sum = $sum');
+ } else {
+ // If there is a message, it means this instance is one of the child
+ // instances. The message is the port that this instance replies on.
+ (message as SendPort).send(Random().nextInt(1000));
+ }
+}
diff --git a/pkgs/coverage/benchmark/run_benchmarks.dart b/pkgs/coverage/benchmark/run_benchmarks.dart
new file mode 100644
index 0000000..1bd2990
--- /dev/null
+++ b/pkgs/coverage/benchmark/run_benchmarks.dart
@@ -0,0 +1,143 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:benchmark_harness/benchmark_harness.dart';
+
+import '../bin/collect_coverage.dart' as collect_coverage;
+import '../bin/format_coverage.dart' as format_coverage;
+
+// Runs a test script with various different coverage configurations.
+class CoverageBenchmark extends AsyncBenchmarkBase {
+ CoverageBenchmark(
+ ScoreEmitter emitter,
+ super.name,
+ this.script, {
+ this.gatherCoverage = false,
+ this.functionCoverage = false,
+ this.branchCoverage = false,
+ }) : super(emitter: emitter);
+
+ final String script;
+ final bool gatherCoverage;
+ final bool functionCoverage;
+ final bool branchCoverage;
+ int iteration = 0;
+
+ @override
+ Future<void> run() async {
+ print('Running $name...');
+ final covFile = 'data/$name $iteration coverage.json';
+ final lcovFile = 'data/$name $iteration lcov.info';
+ ++iteration;
+
+ await Process.start(
+ Platform.executable,
+ [
+ if (branchCoverage) '--branch-coverage',
+ 'run',
+ if (gatherCoverage) ...[
+ '--pause-isolates-on-exit',
+ '--disable-service-auth-codes',
+ '--enable-vm-service=1234',
+ ],
+ script,
+ ],
+ mode: ProcessStartMode.detached,
+ );
+ if (gatherCoverage) {
+ await collect_coverage.main([
+ '--wait-paused',
+ '--resume-isolates',
+ '--uri=http://127.0.0.1:1234/',
+ if (branchCoverage) '--branch-coverage',
+ if (functionCoverage) '--function-coverage',
+ '-o',
+ covFile,
+ ]);
+
+ await format_coverage.main([
+ '--lcov',
+ '--check-ignore',
+ '-i',
+ covFile,
+ '-o',
+ lcovFile,
+ ]);
+ }
+ }
+}
+
+// Emitter that just captures the value.
+class CaptureEmitter implements ScoreEmitter {
+ late double capturedValue;
+
+ @override
+ void emit(String testName, double value) {
+ capturedValue = value;
+ }
+}
+
+// Prints a JSON representation of the benchmark results, in a format compatible
+// with the github benchmark action.
+class JsonEmitter implements ScoreEmitter {
+ JsonEmitter(this._baseline);
+
+ final double _baseline;
+ final _results = <String, double>{};
+
+ @override
+ void emit(String testName, double value) {
+ _results[testName] = value;
+ }
+
+ String write() => '[${_results.entries.map((entry) => """{
+ "name": "${entry.key}",
+ "unit": "times slower",
+ "value": ${(entry.value / _baseline).toStringAsFixed(2)}
+}""").join(',\n')}]';
+}
+
+Future<void> runBenchmark(CoverageBenchmark benchmark) async {
+ for (var i = 0; i < 3; ++i) {
+ try {
+ await benchmark.report().timeout(const Duration(minutes: 2));
+ return;
+ } on TimeoutException {
+ print('Timed out');
+ }
+ }
+ print('Timed out too many times. Giving up.');
+ exit(127);
+}
+
+Future<String> runBenchmarkSet(String name, String script) async {
+ final captureEmitter = CaptureEmitter();
+ await runBenchmark(
+ CoverageBenchmark(captureEmitter, '$name - no coverage', script));
+ final benchmarkBaseline = captureEmitter.capturedValue;
+
+ final emitter = JsonEmitter(benchmarkBaseline);
+ await runBenchmark(CoverageBenchmark(
+ emitter, '$name - basic coverage', script,
+ gatherCoverage: true));
+ await runBenchmark(CoverageBenchmark(
+ emitter, '$name - function coverage', script,
+ gatherCoverage: true, functionCoverage: true));
+ await runBenchmark(CoverageBenchmark(
+ emitter, '$name - branch coverage', script,
+ gatherCoverage: true, branchCoverage: true));
+ return emitter.write();
+}
+
+Future<void> main() async {
+ // Assume this script was started from the root coverage directory. Change to
+ // the benchmark directory.
+ Directory.current = 'benchmark';
+ final result = await runBenchmarkSet('Many isolates', 'many_isolates.dart');
+ await File('data/benchmark_result.json').writeAsString(result);
+ exit(0);
+}
diff --git a/pkgs/coverage/bin/collect_coverage.dart b/pkgs/coverage/bin/collect_coverage.dart
new file mode 100644
index 0000000..b02ac21
--- /dev/null
+++ b/pkgs/coverage/bin/collect_coverage.dart
@@ -0,0 +1,149 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:convert' show json;
+import 'dart:io';
+
+import 'package:args/args.dart';
+import 'package:coverage/src/collect.dart';
+import 'package:logging/logging.dart';
+import 'package:stack_trace/stack_trace.dart';
+
+Future<void> main(List<String> arguments) async {
+ Logger.root.level = Level.WARNING;
+ Logger.root.onRecord.listen((LogRecord rec) {
+ print('${rec.level.name}: ${rec.time}: ${rec.message}');
+ });
+
+ final options = _parseArgs(arguments);
+ await Chain.capture(() async {
+ final coverage = await collect(options.serviceUri, options.resume,
+ options.waitPaused, options.includeDart, options.scopedOutput,
+ timeout: options.timeout,
+ functionCoverage: options.functionCoverage,
+ branchCoverage: options.branchCoverage);
+ options.out.write(json.encode(coverage));
+ await options.out.close();
+ }, onError: (dynamic error, Chain chain) {
+ stderr.writeln(error);
+ stderr.writeln(chain.terse);
+ // See http://www.retro11.de/ouxr/211bsd/usr/include/sysexits.h.html
+ // EX_SOFTWARE
+ exit(70);
+ });
+}
+
+class Options {
+ Options(
+ this.serviceUri,
+ this.out,
+ this.timeout,
+ this.waitPaused,
+ this.resume,
+ this.includeDart,
+ this.functionCoverage,
+ this.branchCoverage,
+ this.scopedOutput);
+
+ final Uri serviceUri;
+ final IOSink out;
+ final Duration? timeout;
+ final bool waitPaused;
+ final bool resume;
+ final bool includeDart;
+ final bool functionCoverage;
+ final bool branchCoverage;
+ final Set<String> scopedOutput;
+}
+
+Options _parseArgs(List<String> arguments) {
+ final parser = ArgParser()
+ ..addOption('host',
+ abbr: 'H',
+ help: 'remote VM host. DEPRECATED: use --uri',
+ defaultsTo: '127.0.0.1')
+ ..addOption('port',
+ abbr: 'p',
+ help: 'remote VM port. DEPRECATED: use --uri',
+ defaultsTo: '8181')
+ ..addOption('uri', abbr: 'u', help: 'VM observatory service URI')
+ ..addOption('out',
+ abbr: 'o', defaultsTo: 'stdout', help: 'output: may be file or stdout')
+ ..addOption('connect-timeout',
+ abbr: 't', help: 'connect timeout in seconds')
+ ..addMultiOption('scope-output',
+ help: 'restrict coverage results so that only scripts that start with '
+ 'the provided package path are considered')
+ ..addFlag('wait-paused',
+ abbr: 'w',
+ defaultsTo: false,
+ help: 'wait for all isolates to be paused before collecting coverage')
+ ..addFlag('resume-isolates',
+ abbr: 'r', defaultsTo: false, help: 'resume all isolates on exit')
+ ..addFlag('include-dart',
+ abbr: 'd', defaultsTo: false, help: 'include "dart:" libraries')
+ ..addFlag('function-coverage',
+ abbr: 'f', defaultsTo: false, help: 'Collect function coverage info')
+ ..addFlag('branch-coverage',
+ abbr: 'b',
+ defaultsTo: false,
+ help: 'Collect branch coverage info (Dart VM must also be run with '
+ '--branch-coverage for this to work)')
+ ..addFlag('help', abbr: 'h', negatable: false, help: 'show this help');
+
+ final args = parser.parse(arguments);
+
+ void printUsage() {
+ print('Usage: dart collect_coverage.dart --uri=http://... [OPTION...]\n');
+ print(parser.usage);
+ }
+
+ Never fail(String message) {
+ print('Error: $message\n');
+ printUsage();
+ exit(1);
+ }
+
+ if (args['help'] as bool) {
+ printUsage();
+ exit(0);
+ }
+
+ Uri serviceUri;
+ if (args['uri'] == null) {
+ // TODO(cbracken) eliminate --host and --port support when VM defaults to
+ // requiring an auth token. Estimated for Dart SDK 1.22.
+ serviceUri = Uri.parse('http://${args['host']}:${args['port']}/');
+ } else {
+ try {
+ serviceUri = Uri.parse(args['uri'] as String);
+ } on FormatException {
+ fail('Invalid service URI specified: ${args['uri']}');
+ }
+ }
+
+ final scopedOutput = args['scope-output'] as List<String>;
+ IOSink out;
+ if (args['out'] == 'stdout') {
+ out = stdout;
+ } else {
+ final outfile = File(args['out'] as String)..createSync(recursive: true);
+ out = outfile.openWrite();
+ }
+ final timeout = (args['connect-timeout'] == null)
+ ? null
+ : Duration(seconds: int.parse(args['connect-timeout'] as String));
+ return Options(
+ serviceUri,
+ out,
+ timeout,
+ args['wait-paused'] as bool,
+ args['resume-isolates'] as bool,
+ args['include-dart'] as bool,
+ args['function-coverage'] as bool,
+ args['branch-coverage'] as bool,
+ scopedOutput.toSet(),
+ );
+}
diff --git a/pkgs/coverage/bin/format_coverage.dart b/pkgs/coverage/bin/format_coverage.dart
new file mode 100644
index 0000000..d24f60d
--- /dev/null
+++ b/pkgs/coverage/bin/format_coverage.dart
@@ -0,0 +1,310 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:args/args.dart';
+import 'package:coverage/coverage.dart';
+import 'package:glob/glob.dart';
+import 'package:path/path.dart' as p;
+
+/// [Environment] stores gathered arguments information.
+class Environment {
+ Environment({
+ required this.baseDirectory,
+ required this.bazel,
+ required this.bazelWorkspace,
+ required this.checkIgnore,
+ required this.input,
+ required this.lcov,
+ required this.output,
+ required this.packagesPath,
+ required this.packagePath,
+ required this.prettyPrint,
+ required this.prettyPrintFunc,
+ required this.prettyPrintBranch,
+ required this.reportOn,
+ required this.ignoreFiles,
+ required this.sdkRoot,
+ required this.verbose,
+ required this.workers,
+ });
+
+ String? baseDirectory;
+ bool bazel;
+ String bazelWorkspace;
+ bool checkIgnore;
+ String input;
+ bool lcov;
+ IOSink output;
+ String? packagesPath;
+ String packagePath;
+ bool prettyPrint;
+ bool prettyPrintFunc;
+ bool prettyPrintBranch;
+ List<String>? reportOn;
+ List<String>? ignoreFiles;
+ String? sdkRoot;
+ bool verbose;
+ int workers;
+}
+
+Future<void> main(List<String> arguments) async {
+ final env = parseArgs(arguments);
+
+ final files = filesToProcess(env.input);
+ if (env.verbose) {
+ print('Environment:');
+ print(' # files: ${files.length}');
+ print(' # workers: ${env.workers}');
+ print(' sdk-root: ${env.sdkRoot}');
+ print(' package-path: ${env.packagePath}');
+ print(' packages-path: ${env.packagesPath}');
+ print(' report-on: ${env.reportOn}');
+ print(' check-ignore: ${env.checkIgnore}');
+ }
+
+ final clock = Stopwatch()..start();
+ final hitmap = await HitMap.parseFiles(
+ files,
+ checkIgnoredLines: env.checkIgnore,
+ // ignore: deprecated_member_use_from_same_package
+ packagesPath: env.packagesPath,
+ packagePath: env.packagePath,
+ );
+
+ // All workers are done. Process the data.
+ if (env.verbose) {
+ print('Done creating global hitmap. Took ${clock.elapsedMilliseconds} ms.');
+ }
+
+ final ignoreGlobs = env.ignoreFiles?.map(Glob.new).toSet();
+
+ String output;
+ final resolver = env.bazel
+ ? BazelResolver(workspacePath: env.bazelWorkspace)
+ : await Resolver.create(
+ packagesPath: env.packagesPath,
+ packagePath: env.packagePath,
+ sdkRoot: env.sdkRoot,
+ );
+ final loader = Loader();
+ if (env.prettyPrint) {
+ output = await hitmap.prettyPrint(resolver, loader,
+ reportOn: env.reportOn,
+ ignoreGlobs: ignoreGlobs,
+ reportFuncs: env.prettyPrintFunc,
+ reportBranches: env.prettyPrintBranch);
+ } else {
+ assert(env.lcov);
+ output = hitmap.formatLcov(resolver,
+ reportOn: env.reportOn,
+ ignoreGlobs: ignoreGlobs,
+ basePath: env.baseDirectory);
+ }
+
+ env.output.write(output);
+ await env.output.flush();
+ if (env.verbose) {
+ print('Done flushing output. Took ${clock.elapsedMilliseconds} ms.');
+ }
+
+ if (env.verbose) {
+ if (resolver.failed.isNotEmpty) {
+ print('Failed to resolve:');
+ for (var error in resolver.failed.toSet()) {
+ print(' $error');
+ }
+ }
+ if (loader.failed.isNotEmpty) {
+ print('Failed to load:');
+ for (var error in loader.failed.toSet()) {
+ print(' $error');
+ }
+ }
+ }
+ await env.output.close();
+}
+
+/// Checks the validity of the provided arguments. Does not initialize actual
+/// processing.
+Environment parseArgs(List<String> arguments) {
+ final parser = ArgParser();
+
+ parser
+ ..addOption('sdk-root', abbr: 's', help: 'path to the SDK root')
+ ..addOption('packages', help: '[DEPRECATED] path to the package spec file')
+ ..addOption('package',
+ help: 'root directory of the package', defaultsTo: '.')
+ ..addOption('in', abbr: 'i', help: 'input(s): may be file or directory')
+ ..addOption('out',
+ abbr: 'o', defaultsTo: 'stdout', help: 'output: may be file or stdout')
+ ..addMultiOption('report-on',
+ help: 'which directories or files to report coverage on')
+ ..addOption('workers',
+ abbr: 'j', defaultsTo: '1', help: 'number of workers')
+ ..addOption('bazel-workspace',
+ defaultsTo: '', help: 'Bazel workspace directory')
+ ..addOption('base-directory',
+ abbr: 'b',
+ help: 'the base directory relative to which source paths are output')
+ ..addFlag('bazel',
+ defaultsTo: false, help: 'use Bazel-style path resolution')
+ ..addFlag('pretty-print',
+ abbr: 'r',
+ negatable: false,
+ help: 'convert line coverage data to pretty print format')
+ ..addFlag('pretty-print-func',
+ abbr: 'f',
+ negatable: false,
+ help: 'convert function coverage data to pretty print format')
+ ..addFlag('pretty-print-branch',
+ negatable: false,
+ help: 'convert branch coverage data to pretty print format')
+ ..addFlag('lcov',
+ abbr: 'l',
+ negatable: false,
+ help: 'convert coverage data to lcov format')
+ ..addFlag('verbose', abbr: 'v', negatable: false, help: 'verbose output')
+ ..addFlag(
+ 'check-ignore',
+ abbr: 'c',
+ negatable: false,
+ help: 'check for coverage ignore comments.'
+ ' Not supported in web coverage.',
+ )
+ ..addMultiOption(
+ 'ignore-files',
+ defaultsTo: [],
+ help: 'Ignore files by glob patterns',
+ )
+ ..addFlag('help', abbr: 'h', negatable: false, help: 'show this help');
+
+ final args = parser.parse(arguments);
+
+ void printUsage() {
+ print('Usage: dart format_coverage.dart [OPTION...]\n');
+ print(parser.usage);
+ }
+
+ Never fail(String msg) {
+ print('\n$msg\n');
+ printUsage();
+ exit(1);
+ }
+
+ if (args['help'] as bool) {
+ printUsage();
+ exit(0);
+ }
+
+ var sdkRoot = args['sdk-root'] as String?;
+ if (sdkRoot != null) {
+ sdkRoot = p.normalize(p.join(p.absolute(sdkRoot), 'lib'));
+ if (!FileSystemEntity.isDirectorySync(sdkRoot)) {
+ fail('Provided SDK root "${args["sdk-root"]}" is not a valid SDK '
+ 'top-level directory');
+ }
+ }
+
+ final packagesPath = args['packages'] as String?;
+ if (packagesPath != null) {
+ if (!FileSystemEntity.isFileSync(packagesPath)) {
+ fail('Package spec "${args["packages"]}" not found, or not a file.');
+ }
+ }
+
+ final packagePath = args['package'] as String;
+ if (!FileSystemEntity.isDirectorySync(packagePath)) {
+ fail('Package spec "${args["package"]}" not found, or not a directory.');
+ }
+
+ if (args['in'] == null) fail('No input files given.');
+ final input = p.absolute(p.normalize(args['in'] as String));
+ if (!FileSystemEntity.isDirectorySync(input) &&
+ !FileSystemEntity.isFileSync(input)) {
+ fail('Provided input "${args["in"]}" is neither a directory nor a file.');
+ }
+
+ IOSink output;
+ if (args['out'] == 'stdout') {
+ output = stdout;
+ } else {
+ final outpath = p.absolute(p.normalize(args['out'] as String));
+ final outfile = File(outpath)..createSync(recursive: true);
+ output = outfile.openWrite();
+ }
+
+ final reportOnRaw = args['report-on'] as List<String>;
+ final reportOn = reportOnRaw.isNotEmpty ? reportOnRaw : null;
+
+ final bazel = args['bazel'] as bool;
+ final bazelWorkspace = args['bazel-workspace'] as String;
+ if (bazelWorkspace.isNotEmpty && !bazel) {
+ stderr.writeln('warning: ignoring --bazel-workspace: --bazel not set');
+ }
+
+ String? baseDirectory;
+ if (args['base-directory'] != null) {
+ baseDirectory = p.absolute(args['base-directory'] as String);
+ }
+
+ final lcov = args['lcov'] as bool;
+ var prettyPrint = args['pretty-print'] as bool;
+ final prettyPrintFunc = args['pretty-print-func'] as bool;
+ final prettyPrintBranch = args['pretty-print-branch'] as bool;
+ final numModesChosen = (prettyPrint ? 1 : 0) +
+ (prettyPrintFunc ? 1 : 0) +
+ (prettyPrintBranch ? 1 : 0) +
+ (lcov ? 1 : 0);
+ if (numModesChosen > 1) {
+ fail('Choose one of the pretty-print modes or lcov output');
+ }
+
+ // The pretty printer is used by all modes other than lcov.
+ if (!lcov) prettyPrint = true;
+
+ int workers;
+ try {
+ workers = int.parse('${args["workers"]}');
+ } catch (e) {
+ fail('Invalid worker count: $e');
+ }
+
+ final checkIgnore = args['check-ignore'] as bool;
+ final ignoredGlobs = args['ignore-files'] as List<String>;
+ final verbose = args['verbose'] as bool;
+ return Environment(
+ baseDirectory: baseDirectory,
+ bazel: bazel,
+ bazelWorkspace: bazelWorkspace,
+ checkIgnore: checkIgnore,
+ input: input,
+ lcov: lcov,
+ output: output,
+ packagesPath: packagesPath,
+ packagePath: packagePath,
+ prettyPrint: prettyPrint,
+ prettyPrintFunc: prettyPrintFunc,
+ prettyPrintBranch: prettyPrintBranch,
+ reportOn: reportOn,
+ ignoreFiles: ignoredGlobs,
+ sdkRoot: sdkRoot,
+ verbose: verbose,
+ workers: workers);
+}
+
+/// Given an absolute path absPath, this function returns a [List] of files
+/// are contained by it if it is a directory, or a [List] containing the file if
+/// it is a file.
+List<File> filesToProcess(String absPath) {
+ if (FileSystemEntity.isDirectorySync(absPath)) {
+ return Directory(absPath)
+ .listSync(recursive: true)
+ .whereType<File>()
+ .where((e) => e.path.endsWith('.json'))
+ .toList();
+ }
+ return <File>[File(absPath)];
+}
diff --git a/pkgs/coverage/bin/run_and_collect.dart b/pkgs/coverage/bin/run_and_collect.dart
new file mode 100644
index 0000000..c255d01
--- /dev/null
+++ b/pkgs/coverage/bin/run_and_collect.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:coverage/src/run_and_collect.dart';
+
+Future<void> main(List<String> args) async {
+ final Map results = await runAndCollect(args[0]);
+ print(results);
+}
diff --git a/pkgs/coverage/bin/test_with_coverage.dart b/pkgs/coverage/bin/test_with_coverage.dart
new file mode 100644
index 0000000..010e608
--- /dev/null
+++ b/pkgs/coverage/bin/test_with_coverage.dart
@@ -0,0 +1,229 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:args/args.dart';
+import 'package:coverage/src/util.dart'
+ show StandardOutExtension, extractVMServiceUri;
+import 'package:package_config/package_config.dart';
+import 'package:path/path.dart' as path;
+
+import 'collect_coverage.dart' as collect_coverage;
+import 'format_coverage.dart' as format_coverage;
+
+final _allProcesses = <Process>[];
+
+Future<void> _dartRun(List<String> args,
+ {void Function(String)? onStdout, String? workingDir}) async {
+ final process = await Process.start(
+ Platform.executable,
+ args,
+ workingDirectory: workingDir,
+ );
+ _allProcesses.add(process);
+ final broadStdout = process.stdout.asBroadcastStream();
+ broadStdout.listen(stdout.add);
+ if (onStdout != null) {
+ broadStdout.lines().listen(onStdout);
+ }
+ process.stderr.listen(stderr.add);
+ final result = await process.exitCode;
+ if (result != 0) {
+ throw ProcessException(Platform.executable, args, '', result);
+ }
+}
+
+Future<String?> _packageNameFromConfig(String packageDir) async {
+ final config = await findPackageConfig(Directory(packageDir));
+ return config?.packageOf(Uri.directory(packageDir))?.name;
+}
+
+void _watchExitSignal(ProcessSignal signal) {
+ signal.watch().listen((sig) {
+ for (final process in _allProcesses) {
+ process.kill(sig);
+ }
+ exit(1);
+ });
+}
+
+ArgParser _createArgParser() => ArgParser()
+ ..addOption(
+ 'package',
+ help: 'Root directory of the package to test.',
+ defaultsTo: '.',
+ )
+ ..addOption(
+ 'package-name',
+ help: 'Name of the package to test. '
+ 'Deduced from --package if not provided.',
+ )
+ ..addOption('port', help: 'VM service port.', defaultsTo: '8181')
+ ..addOption(
+ 'out',
+ abbr: 'o',
+ help: 'Output directory. Defaults to <package-dir>/coverage.',
+ )
+ ..addOption('test', help: 'Test script to run.', defaultsTo: 'test')
+ ..addFlag(
+ 'function-coverage',
+ abbr: 'f',
+ defaultsTo: false,
+ help: 'Collect function coverage info.',
+ )
+ ..addFlag(
+ 'branch-coverage',
+ abbr: 'b',
+ defaultsTo: false,
+ help: 'Collect branch coverage info.',
+ )
+ ..addMultiOption('scope-output',
+ help: 'restrict coverage results so that only scripts that start with '
+ 'the provided package path are considered. Defaults to the name of '
+ 'the package under test.')
+ ..addFlag('help', abbr: 'h', negatable: false, help: 'Show this help.');
+
+class Flags {
+ Flags(
+ this.packageDir,
+ this.packageName,
+ this.outDir,
+ this.port,
+ this.testScript,
+ this.functionCoverage,
+ this.branchCoverage,
+ this.scopeOutput, {
+ required this.rest,
+ });
+
+ final String packageDir;
+ final String packageName;
+ final String outDir;
+ final String port;
+ final String testScript;
+ final bool functionCoverage;
+ final bool branchCoverage;
+ final List<String> scopeOutput;
+ final List<String> rest;
+}
+
+Future<Flags> _parseArgs(List<String> arguments) async {
+ final parser = _createArgParser();
+ final args = parser.parse(arguments);
+
+ void printUsage() {
+ print('''
+Runs tests and collects coverage for a package.
+
+By default this script assumes it's being run from the root directory of a
+package, and outputs a coverage.json and lcov.info to ./coverage/
+
+Usage: test_with_coverage [OPTIONS...] [-- <test script OPTIONS>]
+
+${parser.usage}
+''');
+ }
+
+ Never fail(String msg) {
+ print('\n$msg\n');
+ printUsage();
+ exit(1);
+ }
+
+ if (args['help'] as bool) {
+ printUsage();
+ exit(0);
+ }
+
+ final packageDir = path.canonicalize(args['package'] as String);
+ if (!FileSystemEntity.isDirectorySync(packageDir)) {
+ fail('--package is not a valid directory.');
+ }
+
+ final packageName = (args['package-name'] as String?) ??
+ await _packageNameFromConfig(packageDir);
+ if (packageName == null) {
+ fail(
+ "Couldn't figure out package name from --package. Make sure this is a "
+ 'package directory, or try passing --package-name explicitly.',
+ );
+ }
+
+ return Flags(
+ packageDir,
+ packageName,
+ (args['out'] as String?) ?? path.join(packageDir, 'coverage'),
+ args['port'] as String,
+ args['test'] as String,
+ args['function-coverage'] as bool,
+ args['branch-coverage'] as bool,
+ args['scope-output'] as List<String>,
+ rest: args.rest,
+ );
+}
+
+Future<void> main(List<String> arguments) async {
+ final flags = await _parseArgs(arguments);
+ final outJson = path.join(flags.outDir, 'coverage.json');
+ final outLcov = path.join(flags.outDir, 'lcov.info');
+
+ if (!FileSystemEntity.isDirectorySync(flags.outDir)) {
+ await Directory(flags.outDir).create(recursive: true);
+ }
+
+ _watchExitSignal(ProcessSignal.sighup);
+ _watchExitSignal(ProcessSignal.sigint);
+ if (!Platform.isWindows) {
+ _watchExitSignal(ProcessSignal.sigterm);
+ }
+
+ final serviceUriCompleter = Completer<Uri>();
+ final testProcess = _dartRun(
+ [
+ if (flags.branchCoverage) '--branch-coverage',
+ 'run',
+ '--pause-isolates-on-exit',
+ '--disable-service-auth-codes',
+ '--enable-vm-service=${flags.port}',
+ flags.testScript,
+ ...flags.rest,
+ ],
+ onStdout: (line) {
+ if (!serviceUriCompleter.isCompleted) {
+ final uri = extractVMServiceUri(line);
+ if (uri != null) {
+ serviceUriCompleter.complete(uri);
+ }
+ }
+ },
+ );
+ final serviceUri = await serviceUriCompleter.future;
+
+ final scopes =
+ flags.scopeOutput.isEmpty ? [flags.packageName] : flags.scopeOutput;
+ await collect_coverage.main([
+ '--wait-paused',
+ '--resume-isolates',
+ '--uri=$serviceUri',
+ for (final scope in scopes) '--scope-output=$scope',
+ if (flags.branchCoverage) '--branch-coverage',
+ if (flags.functionCoverage) '--function-coverage',
+ '-o',
+ outJson,
+ ]);
+ await testProcess;
+
+ await format_coverage.main([
+ '--lcov',
+ '--check-ignore',
+ '--package=${flags.packageDir}',
+ '-i',
+ outJson,
+ '-o',
+ outLcov,
+ ]);
+ exit(0);
+}
diff --git a/pkgs/coverage/lib/coverage.dart b/pkgs/coverage/lib/coverage.dart
new file mode 100644
index 0000000..9cc81ab
--- /dev/null
+++ b/pkgs/coverage/lib/coverage.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+export 'src/chrome.dart';
+export 'src/collect.dart';
+export 'src/formatter.dart';
+export 'src/hitmap.dart' hide hitmapToJson;
+export 'src/resolver.dart';
+export 'src/run_and_collect.dart';
diff --git a/pkgs/coverage/lib/src/chrome.dart b/pkgs/coverage/lib/src/chrome.dart
new file mode 100644
index 0000000..2a97696
--- /dev/null
+++ b/pkgs/coverage/lib/src/chrome.dart
@@ -0,0 +1,171 @@
+// 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:source_maps/parser.dart';
+
+import 'hitmap.dart';
+
+/// Returns a Dart based hit-map containing coverage report for the provided
+/// Chrome [preciseCoverage].
+///
+/// [sourceProvider] returns the source content for the Chrome scriptId, or null
+/// if not available.
+///
+/// [sourceMapProvider] returns the associated source map content for the Chrome
+/// scriptId, or null if not available.
+///
+/// [sourceUriProvider] returns the uri for the provided sourceUrl and
+/// associated scriptId, or null if not available.
+///
+/// Chrome coverage information for which the corresponding source map or source
+/// content is null will be ignored.
+Future<Map<String, dynamic>> parseChromeCoverage(
+ List<Map<String, dynamic>> preciseCoverage,
+ Future<String?> Function(String scriptId) sourceProvider,
+ Future<String?> Function(String scriptId) sourceMapProvider,
+ Future<Uri?> Function(String sourceUrl, String scriptId) sourceUriProvider,
+) async {
+ final coverageReport = <Uri, Map<int, bool>>{};
+ for (var entry in preciseCoverage) {
+ final scriptId = entry['scriptId'] as String;
+
+ final mapResponse = await sourceMapProvider(scriptId);
+ if (mapResponse == null) continue;
+
+ SingleMapping mapping;
+ try {
+ mapping = parse(mapResponse) as SingleMapping;
+ } on FormatException {
+ continue;
+ // ignore: avoid_catching_errors
+ } on ArgumentError {
+ continue;
+ }
+
+ final compiledSource = await sourceProvider(scriptId);
+ if (compiledSource == null) continue;
+
+ final coverageInfo = _coverageInfoFor(entry);
+ final offsetCoverage = _offsetCoverage(coverageInfo, compiledSource.length);
+ final coveredPositions = _coveredPositions(compiledSource, offsetCoverage);
+
+ for (var lineEntry in mapping.lines) {
+ for (var columnEntry in lineEntry.entries) {
+ final sourceUrlId = columnEntry.sourceUrlId;
+ if (sourceUrlId == null) continue;
+ final sourceUrl = mapping.urls[sourceUrlId];
+
+ // Ignore coverage information for the SDK.
+ if (sourceUrl.startsWith('org-dartlang-sdk:')) continue;
+
+ final uri = await sourceUriProvider(sourceUrl, scriptId);
+ if (uri == null) continue;
+ final coverage = coverageReport.putIfAbsent(uri, () => <int, bool>{});
+
+ final sourceLine = columnEntry.sourceLine!;
+ final current = coverage[sourceLine + 1] ?? false;
+ coverage[sourceLine + 1] = current ||
+ coveredPositions.contains(
+ _Position(lineEntry.line + 1, columnEntry.column + 1));
+ }
+ }
+ }
+
+ final coverageHitMaps = <Uri, HitMap>{};
+ coverageReport.forEach((uri, coverage) {
+ final hitMap = HitMap();
+ for (var line in coverage.keys.toList()..sort()) {
+ hitMap.lineHits[line] = coverage[line]! ? 1 : 0;
+ }
+ coverageHitMaps[uri] = hitMap;
+ });
+
+ final allCoverage = <Map<String, dynamic>>[];
+ coverageHitMaps.forEach((uri, hitMap) {
+ allCoverage.add(hitmapToJson(hitMap, uri));
+ });
+ return <String, dynamic>{'type': 'CodeCoverage', 'coverage': allCoverage};
+}
+
+/// Returns all covered positions in a provided source.
+Set<_Position> _coveredPositions(
+ String compiledSource, List<bool> offsetCoverage) {
+ final positions = <_Position>{};
+ // Line is 1 based.
+ var line = 1;
+ // Column is 1 based.
+ var column = 0;
+ for (var offset = 0; offset < compiledSource.length; offset++) {
+ if (compiledSource[offset] == '\n') {
+ line++;
+ column = 0;
+ } else {
+ column++;
+ }
+ if (offsetCoverage[offset]) positions.add(_Position(line, column));
+ }
+ return positions;
+}
+
+/// Returns coverage information for a Chrome entry.
+List<_CoverageInfo> _coverageInfoFor(Map<String, dynamic> entry) {
+ final result = <_CoverageInfo>[];
+ for (var functions
+ in (entry['functions'] as List).cast<Map<String, dynamic>>()) {
+ for (var range
+ in (functions['ranges'] as List).cast<Map<String, dynamic>>()) {
+ result.add(_CoverageInfo(
+ range['startOffset'] as int,
+ range['endOffset'] as int,
+ (range['count'] as int) > 0,
+ ));
+ }
+ }
+ return result;
+}
+
+/// Returns the coverage information for each offset.
+List<bool> _offsetCoverage(List<_CoverageInfo> coverageInfo, int sourceLength) {
+ final offsetCoverage = List.filled(sourceLength, false);
+
+ // Sort coverage information by their size.
+ // Coverage information takes granularity as precedence.
+ coverageInfo.sort((a, b) =>
+ (b.endOffset - b.startOffset).compareTo(a.endOffset - a.startOffset));
+
+ for (var range in coverageInfo) {
+ for (var i = range.startOffset; i < range.endOffset; i++) {
+ offsetCoverage[i] = range.isCovered;
+ }
+ }
+
+ return offsetCoverage;
+}
+
+class _CoverageInfo {
+ _CoverageInfo(this.startOffset, this.endOffset, this.isCovered);
+
+ /// 0 based byte offset.
+ final int startOffset;
+
+ /// 0 based byte offset.
+ final int endOffset;
+
+ final bool isCovered;
+}
+
+/// A covered position in a source file where [line] and [column] are 1 based.
+class _Position {
+ _Position(this.line, this.column);
+
+ final int line;
+ final int column;
+
+ @override
+ int get hashCode => Object.hash(line, column);
+
+ @override
+ bool operator ==(Object o) =>
+ o is _Position && o.line == line && o.column == column;
+}
diff --git a/pkgs/coverage/lib/src/collect.dart b/pkgs/coverage/lib/src/collect.dart
new file mode 100644
index 0000000..76227ba
--- /dev/null
+++ b/pkgs/coverage/lib/src/collect.dart
@@ -0,0 +1,447 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:vm_service/vm_service.dart';
+
+import 'hitmap.dart';
+import 'isolate_paused_listener.dart';
+import 'util.dart';
+
+const _retryInterval = Duration(milliseconds: 200);
+const _debugTokenPositions = bool.fromEnvironment('DEBUG_COVERAGE');
+
+/// Collects coverage for all isolates in the running VM.
+///
+/// Collects a hit-map containing merged coverage for all isolates in the Dart
+/// VM associated with the specified [serviceUri]. Returns a map suitable for
+/// input to the coverage formatters that ship with this package.
+///
+/// [serviceUri] must specify the http/https URI of the service port of a
+/// running Dart VM and must not be null.
+///
+/// If [resume] is true, all isolates will be resumed once coverage collection
+/// is complete.
+///
+/// If [waitPaused] is true, collection will not begin for an isolate until it
+/// is in the paused state.
+///
+/// If [includeDart] is true, code coverage for core `dart:*` libraries will be
+/// collected.
+///
+/// If [functionCoverage] is true, function coverage information will be
+/// collected.
+///
+/// If [branchCoverage] is true, branch coverage information will be collected.
+/// This will only work correctly if the target VM was run with the
+/// --branch-coverage flag.
+///
+/// If [scopedOutput] is non-empty, coverage will be restricted so that only
+/// scripts that start with any of the provided paths are considered.
+///
+/// If [isolateIds] is set, the coverage gathering will be restricted to only
+/// those VM isolates.
+///
+/// If [coverableLineCache] is set, the collector will avoid recompiling
+/// libraries it has already seen (see VmService.getSourceReport's
+/// librariesAlreadyCompiled parameter). This is only useful when doing more
+/// than one [collect] call over the same libraries. Pass an empty map to the
+/// first call, and then pass the same map to all subsequent calls.
+///
+/// [serviceOverrideForTesting] is for internal testing only, and should not be
+/// set by users.
+Future<Map<String, dynamic>> collect(Uri serviceUri, bool resume,
+ bool waitPaused, bool includeDart, Set<String>? scopedOutput,
+ {Set<String>? isolateIds,
+ Duration? timeout,
+ bool functionCoverage = false,
+ bool branchCoverage = false,
+ Map<String, Set<int>>? coverableLineCache,
+ VmService? serviceOverrideForTesting}) async {
+ scopedOutput ??= <String>{};
+
+ late VmService service;
+ if (serviceOverrideForTesting != null) {
+ service = serviceOverrideForTesting;
+ } else {
+ // Create websocket URI. Handle any trailing slashes.
+ final pathSegments =
+ serviceUri.pathSegments.where((c) => c.isNotEmpty).toList()..add('ws');
+ final uri = serviceUri.replace(scheme: 'ws', pathSegments: pathSegments);
+
+ await retry(() async {
+ try {
+ final options = const CompressionOptions(enabled: false);
+ final socket = await WebSocket.connect('$uri', compression: options);
+ final controller = StreamController<String>();
+ socket.listen((data) => controller.add(data as String), onDone: () {
+ controller.close();
+ service.dispose();
+ });
+ service = VmService(controller.stream, socket.add,
+ log: StdoutLog(), disposeHandler: socket.close);
+ await service.getVM().timeout(_retryInterval);
+ } on TimeoutException {
+ // The signature changed in vm_service version 6.0.0.
+ // ignore: await_only_futures
+ await service.dispose();
+ rethrow;
+ }
+ }, _retryInterval, timeout: timeout);
+ }
+
+ try {
+ return await _getAllCoverage(
+ service,
+ includeDart,
+ functionCoverage,
+ branchCoverage,
+ scopedOutput,
+ isolateIds,
+ coverableLineCache,
+ waitPaused);
+ } finally {
+ if (resume && !waitPaused) {
+ await _resumeIsolates(service);
+ }
+ // The signature changed in vm_service version 6.0.0.
+ // ignore: await_only_futures
+ await service.dispose();
+ }
+}
+
+Future<Map<String, dynamic>> _getAllCoverage(
+ VmService service,
+ bool includeDart,
+ bool functionCoverage,
+ bool branchCoverage,
+ Set<String> scopedOutput,
+ Set<String>? isolateIds,
+ Map<String, Set<int>>? coverableLineCache,
+ bool waitPaused) async {
+ final allCoverage = <Map<String, dynamic>>[];
+
+ final sourceReportKinds = [
+ SourceReportKind.kCoverage,
+ if (branchCoverage) SourceReportKind.kBranchCoverage,
+ ];
+
+ final librariesAlreadyCompiled = coverableLineCache?.keys.toList();
+
+ // Program counters are shared between isolates in the same group. So we need
+ // to make sure we're only gathering coverage data for one isolate in each
+ // group, otherwise we'll double count the hits.
+ final coveredIsolateGroups = <String>{};
+
+ Future<void> collectIsolate(IsolateRef isolateRef) async {
+ if (!(isolateIds?.contains(isolateRef.id) ?? true)) return;
+
+ // coveredIsolateGroups is only relevant for the !waitPaused flow. The
+ // waitPaused flow achieves the same once-per-group behavior using the
+ // isLastIsolateInGroup flag.
+ final isolateGroupId = isolateRef.isolateGroupId;
+ if (isolateGroupId != null) {
+ if (coveredIsolateGroups.contains(isolateGroupId)) return;
+ coveredIsolateGroups.add(isolateGroupId);
+ }
+
+ late final SourceReport isolateReport;
+ try {
+ isolateReport = await service.getSourceReport(
+ isolateRef.id!,
+ sourceReportKinds,
+ forceCompile: true,
+ reportLines: true,
+ libraryFilters: scopedOutput.isNotEmpty
+ ? List.from(scopedOutput.map((filter) => 'package:$filter/'))
+ : null,
+ librariesAlreadyCompiled: librariesAlreadyCompiled,
+ );
+ } on SentinelException {
+ return;
+ }
+
+ final coverage = await _processSourceReport(
+ service,
+ isolateRef,
+ isolateReport,
+ includeDart,
+ functionCoverage,
+ coverableLineCache,
+ scopedOutput);
+ allCoverage.addAll(coverage);
+ }
+
+ if (waitPaused) {
+ await IsolatePausedListener(service,
+ (IsolateRef isolateRef, bool isLastIsolateInGroup) async {
+ if (isLastIsolateInGroup) {
+ await collectIsolate(isolateRef);
+ }
+ }, stderr.writeln)
+ .waitUntilAllExited();
+ } else {
+ for (final isolateRef in await getAllIsolates(service)) {
+ await collectIsolate(isolateRef);
+ }
+ }
+
+ return <String, dynamic>{'type': 'CodeCoverage', 'coverage': allCoverage};
+}
+
+Future _resumeIsolates(VmService service) async {
+ final vm = await service.getVM();
+ final futures = <Future>[];
+ for (var isolateRef in vm.isolates!) {
+ // Guard against sync as well as async errors: sync - when we are writing
+ // message to the socket, the socket might be closed; async - when we are
+ // waiting for the response, the socket again closes.
+ futures.add(Future.sync(() async {
+ final isolate = await service.getIsolate(isolateRef.id!);
+ if (isolate.pauseEvent!.kind != EventKind.kResume) {
+ await service.resume(isolateRef.id!);
+ }
+ }));
+ }
+ try {
+ await Future.wait(futures);
+ } catch (_) {
+ // Ignore resume isolate failures
+ }
+}
+
+/// Returns the line number to which the specified token position maps.
+///
+/// Performs a binary search within the script's token position table to locate
+/// the line in question.
+int? _getLineFromTokenPos(Script script, int tokenPos) {
+ // TODO(cbracken): investigate whether caching this lookup results in
+ // significant performance gains.
+ var min = 0;
+ var max = script.tokenPosTable!.length;
+ while (min < max) {
+ final mid = min + ((max - min) >> 1);
+ final row = script.tokenPosTable![mid];
+ if (row[1] > tokenPos) {
+ max = mid;
+ } else {
+ for (var i = 1; i < row.length; i += 2) {
+ if (row[i] == tokenPos) return row.first;
+ }
+ min = mid + 1;
+ }
+ }
+ return null;
+}
+
+/// Returns a JSON coverage list backward-compatible with pre-1.16.0 SDKs.
+Future<List<Map<String, dynamic>>> _processSourceReport(
+ VmService service,
+ IsolateRef isolateRef,
+ SourceReport report,
+ bool includeDart,
+ bool functionCoverage,
+ Map<String, Set<int>>? coverableLineCache,
+ Set<String> scopedOutput) async {
+ final hitMaps = <Uri, HitMap>{};
+ final scripts = <ScriptRef, Script>{};
+ final libraries = <LibraryRef>{};
+ final needScripts = functionCoverage;
+
+ Future<Script?> getScript(ScriptRef? scriptRef) async {
+ if (scriptRef == null) {
+ return null;
+ }
+ if (!scripts.containsKey(scriptRef)) {
+ scripts[scriptRef] =
+ await service.getObject(isolateRef.id!, scriptRef.id!) as Script;
+ }
+ return scripts[scriptRef];
+ }
+
+ HitMap getHitMap(Uri scriptUri) => hitMaps.putIfAbsent(scriptUri, HitMap.new);
+
+ Future<void> processFunction(FuncRef funcRef) async {
+ final func = await service.getObject(isolateRef.id!, funcRef.id!) as Func;
+ if ((func.implicit ?? false) || (func.isAbstract ?? false)) {
+ return;
+ }
+ final location = func.location;
+ if (location == null) {
+ return;
+ }
+ final script = await getScript(location.script);
+ if (script == null) {
+ return;
+ }
+ final funcName = await _getFuncName(service, isolateRef, func);
+ // TODO(liama): Is this still necessary, or is location.line valid?
+ final tokenPos = location.tokenPos!;
+ final line = _getLineFromTokenPos(script, tokenPos);
+ if (line == null) {
+ if (_debugTokenPositions) {
+ stderr.writeln(
+ 'tokenPos $tokenPos in function ${funcRef.name} has no line '
+ 'mapping for script ${script.uri!}');
+ }
+ return;
+ }
+ final hits = getHitMap(Uri.parse(script.uri!));
+ hits.funcHits ??= <int, int>{};
+ (hits.funcNames ??= <int, String>{})[line] = funcName;
+ }
+
+ for (var range in report.ranges!) {
+ final scriptRef = report.scripts![range.scriptIndex!];
+ final scriptUriString = scriptRef.uri;
+ if (!scopedOutput.includesScript(scriptUriString)) {
+ // Sometimes a range's script can be different to the function's script
+ // (eg mixins), so we have to re-check the scope filter.
+ // See https://github.com/dart-lang/tools/issues/530
+ continue;
+ }
+ final scriptUri = Uri.parse(scriptUriString!);
+
+ // If we have a coverableLineCache, use it in the same way we use
+ // SourceReportCoverage.misses: to add zeros to the coverage result for all
+ // the lines that don't have a hit. Afterwards, add all the lines that were
+ // hit or missed to the cache, so that the next coverage collection won't
+ // need to compile this library.
+ final coverableLines =
+ coverableLineCache?.putIfAbsent(scriptUriString, () => <int>{});
+
+ // Not returned in scripts section of source report.
+ if (scriptUri.scheme == 'evaluate') continue;
+
+ // Skip scripts from dart:.
+ if (!includeDart && scriptUri.scheme == 'dart') continue;
+
+ // Look up the hit maps for this script (shared across isolates).
+ final hits = getHitMap(scriptUri);
+
+ Script? script;
+ if (needScripts) {
+ script = await getScript(scriptRef);
+ if (script == null) continue;
+ }
+
+ // If the script's library isn't loaded, load it then look up all its funcs.
+ final libRef = script?.library;
+ if (functionCoverage && libRef != null && !libraries.contains(libRef)) {
+ libraries.add(libRef);
+ final library =
+ await service.getObject(isolateRef.id!, libRef.id!) as Library;
+ if (library.functions != null) {
+ for (var funcRef in library.functions!) {
+ await processFunction(funcRef);
+ }
+ }
+ if (library.classes != null) {
+ for (var classRef in library.classes!) {
+ final clazz =
+ await service.getObject(isolateRef.id!, classRef.id!) as Class;
+ if (clazz.functions != null) {
+ for (var funcRef in clazz.functions!) {
+ await processFunction(funcRef);
+ }
+ }
+ }
+ }
+ }
+
+ // Collect hits and misses.
+ final coverage = range.coverage;
+
+ if (coverage == null) continue;
+
+ void forEachLine(List<int>? tokenPositions, void Function(int line) body) {
+ if (tokenPositions == null) return;
+ for (final line in tokenPositions) {
+ body(line);
+ }
+ }
+
+ if (coverableLines != null) {
+ for (final line in coverableLines) {
+ hits.lineHits.putIfAbsent(line, () => 0);
+ }
+ }
+
+ forEachLine(coverage.hits, (line) {
+ hits.lineHits.increment(line);
+ coverableLines?.add(line);
+ if (hits.funcNames != null && hits.funcNames!.containsKey(line)) {
+ hits.funcHits!.increment(line);
+ }
+ });
+ forEachLine(coverage.misses, (line) {
+ hits.lineHits.putIfAbsent(line, () => 0);
+ coverableLines?.add(line);
+ });
+ hits.funcNames?.forEach((line, funcName) {
+ hits.funcHits?.putIfAbsent(line, () => 0);
+ });
+
+ final branchCoverage = range.branchCoverage;
+ if (branchCoverage != null) {
+ hits.branchHits ??= <int, int>{};
+ forEachLine(branchCoverage.hits, (line) {
+ hits.branchHits!.increment(line);
+ });
+ forEachLine(branchCoverage.misses, (line) {
+ hits.branchHits!.putIfAbsent(line, () => 0);
+ });
+ }
+ }
+
+ // Output JSON
+ final coverage = <Map<String, dynamic>>[];
+ hitMaps.forEach((uri, hits) {
+ coverage.add(hitmapToJson(hits, uri));
+ });
+ return coverage;
+}
+
+extension _MapExtension<T> on Map<T, int> {
+ void increment(T key) => this[key] = (this[key] ?? 0) + 1;
+}
+
+Future<String> _getFuncName(
+ VmService service, IsolateRef isolateRef, Func func) async {
+ if (func.name == null) {
+ return '${func.type}:${func.location!.tokenPos}';
+ }
+ final owner = func.owner;
+ if (owner is ClassRef) {
+ final cls = await service.getObject(isolateRef.id!, owner.id!) as Class;
+ if (cls.name != null) return '${cls.name}.${func.name}';
+ }
+ return func.name!;
+}
+
+class StdoutLog extends Log {
+ @override
+ void warning(String message) => print(message);
+
+ @override
+ void severe(String message) => print(message);
+}
+
+extension _ScopedOutput on Set<String> {
+ bool includesScript(String? scriptUriString) {
+ if (scriptUriString == null) return false;
+
+ // If the set is empty, it means the user didn't specify a --scope-output
+ // flag, so allow everything.
+ if (isEmpty) return true;
+
+ final scriptUri = Uri.parse(scriptUriString);
+ if (scriptUri.scheme != 'package') return false;
+
+ final scope = scriptUri.pathSegments.first;
+ return contains(scope);
+ }
+}
diff --git a/pkgs/coverage/lib/src/formatter.dart b/pkgs/coverage/lib/src/formatter.dart
new file mode 100644
index 0000000..a37df73
--- /dev/null
+++ b/pkgs/coverage/lib/src/formatter.dart
@@ -0,0 +1,223 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:glob/glob.dart';
+import 'package:path/path.dart' as p;
+
+import 'hitmap.dart';
+import 'resolver.dart';
+
+@Deprecated('Migrate to FileHitMapsFormatter')
+abstract class Formatter {
+ /// Returns the formatted coverage data.
+ Future<String> format(Map<String, Map<int, int>> hitmap);
+}
+
+/// Converts the given hitmap to lcov format and appends the result to
+/// env.output.
+///
+/// Returns a [Future] that completes as soon as all map entries have been
+/// emitted.
+@Deprecated('Migrate to FileHitMapsFormatter.formatLcov')
+class LcovFormatter implements Formatter {
+ /// Creates a LCOV formatter.
+ ///
+ /// If [reportOn] is provided, coverage report output is limited to files
+ /// prefixed with one of the paths included. If [basePath] is provided, paths
+ /// are reported relative to that path.
+ LcovFormatter(this.resolver, {this.reportOn, this.basePath});
+
+ final Resolver resolver;
+ final String? basePath;
+ final List<String>? reportOn;
+
+ @override
+ Future<String> format(Map<String, Map<int, int>> hitmap) {
+ return Future.value(hitmap
+ .map((key, value) => MapEntry(key, HitMap(value)))
+ .formatLcov(resolver, basePath: basePath, reportOn: reportOn));
+ }
+}
+
+/// Converts the given hitmap to a pretty-print format and appends the result
+/// to env.output.
+///
+/// Returns a [Future] that completes as soon as all map entries have been
+/// emitted.
+@Deprecated('Migrate to FileHitMapsFormatter.prettyPrint')
+class PrettyPrintFormatter implements Formatter {
+ /// Creates a pretty-print formatter.
+ ///
+ /// If [reportOn] is provided, coverage report output is limited to files
+ /// prefixed with one of the paths included.
+ PrettyPrintFormatter(this.resolver, this.loader,
+ {this.reportOn, this.reportFuncs = false});
+
+ final Resolver resolver;
+ final Loader loader;
+ final List<String>? reportOn;
+ final bool reportFuncs;
+
+ @override
+ Future<String> format(Map<String, Map<int, int>> hitmap) {
+ return hitmap.map((key, value) => MapEntry(key, HitMap(value))).prettyPrint(
+ resolver, loader,
+ reportOn: reportOn, reportFuncs: reportFuncs);
+ }
+}
+
+extension FileHitMapsFormatter on Map<String, HitMap> {
+ /// Converts the given hitmap to lcov format.
+ ///
+ /// If [reportOn] is provided, coverage report output is limited to files
+ /// prefixed with one of the paths included. If [basePath] is provided, paths
+ /// are reported relative to that path.
+ String formatLcov(
+ Resolver resolver, {
+ String? basePath,
+ List<String>? reportOn,
+ Set<Glob>? ignoreGlobs,
+ }) {
+ final pathFilter = _getPathFilter(
+ reportOn: reportOn,
+ ignoreGlobs: ignoreGlobs,
+ );
+ final buf = StringBuffer();
+ for (final entry in entries) {
+ final v = entry.value;
+ final lineHits = v.lineHits;
+ final funcHits = v.funcHits;
+ final funcNames = v.funcNames;
+ final branchHits = v.branchHits;
+ var source = resolver.resolve(entry.key);
+ if (source == null) {
+ continue;
+ }
+
+ if (!pathFilter(source)) {
+ continue;
+ }
+
+ if (basePath != null) {
+ source = p.relative(source, from: basePath);
+ }
+
+ buf.write('SF:$source\n');
+ if (funcHits != null && funcNames != null) {
+ for (final k in funcNames.keys.toList()..sort()) {
+ buf.write('FN:$k,${funcNames[k]}\n');
+ }
+ for (final k in funcHits.keys.toList()..sort()) {
+ if (funcHits[k]! != 0) {
+ buf.write('FNDA:${funcHits[k]},${funcNames[k]}\n');
+ }
+ }
+ buf.write('FNF:${funcNames.length}\n');
+ buf.write('FNH:${funcHits.values.where((v) => v > 0).length}\n');
+ }
+ for (final k in lineHits.keys.toList()..sort()) {
+ buf.write('DA:$k,${lineHits[k]}\n');
+ }
+ buf.write('LF:${lineHits.length}\n');
+ buf.write('LH:${lineHits.values.where((v) => v > 0).length}\n');
+ if (branchHits != null) {
+ for (final k in branchHits.keys.toList()..sort()) {
+ buf.write('BRDA:$k,0,0,${branchHits[k]}\n');
+ }
+ }
+ buf.write('end_of_record\n');
+ }
+
+ return buf.toString();
+ }
+
+ /// Converts the given hitmap to a pretty-print format.
+ ///
+ /// If [reportOn] is provided, coverage report output is limited to files
+ /// prefixed with one of the paths included. If [reportFuncs] is provided,
+ /// only function coverage information will be shown.
+ Future<String> prettyPrint(
+ Resolver resolver,
+ Loader loader, {
+ List<String>? reportOn,
+ Set<Glob>? ignoreGlobs,
+ bool reportFuncs = false,
+ bool reportBranches = false,
+ }) async {
+ final pathFilter = _getPathFilter(
+ reportOn: reportOn,
+ ignoreGlobs: ignoreGlobs,
+ );
+ final buf = StringBuffer();
+ for (final entry in entries) {
+ final v = entry.value;
+ if (reportFuncs && v.funcHits == null) {
+ throw StateError(
+ 'Function coverage formatting was requested, but the hit map is '
+ 'missing function coverage information. Did you run '
+ 'collect_coverage with the --function-coverage flag?',
+ );
+ }
+ if (reportBranches && v.branchHits == null) {
+ throw StateError(
+ 'Branch coverage formatting was requested, but the hit map is '
+ 'missing branch coverage information. Did you run '
+ 'collect_coverage with the --branch-coverage flag?');
+ }
+ final hits = reportFuncs
+ ? v.funcHits!
+ : reportBranches
+ ? v.branchHits!
+ : v.lineHits;
+ final source = resolver.resolve(entry.key);
+ if (source == null) {
+ continue;
+ }
+
+ if (!pathFilter(source)) {
+ continue;
+ }
+
+ final lines = await loader.load(source);
+ if (lines == null) {
+ continue;
+ }
+ buf.writeln(source);
+ for (var line = 1; line <= lines.length; line++) {
+ var prefix = _prefix;
+ if (hits.containsKey(line)) {
+ prefix = hits[line].toString().padLeft(_prefix.length);
+ }
+ buf.writeln('$prefix|${lines[line - 1]}');
+ }
+ }
+
+ return buf.toString();
+ }
+}
+
+const _prefix = ' ';
+
+typedef _PathFilter = bool Function(String path);
+
+_PathFilter _getPathFilter({List<String>? reportOn, Set<Glob>? ignoreGlobs}) {
+ if (reportOn == null && ignoreGlobs == null) return (String path) => true;
+
+ final absolutePaths = reportOn?.map(p.canonicalize).toList();
+
+ return (String path) {
+ final canonicalizedPath = p.canonicalize(path);
+
+ if (absolutePaths != null &&
+ !absolutePaths.any(canonicalizedPath.startsWith)) {
+ return false;
+ }
+ if (ignoreGlobs != null &&
+ ignoreGlobs.any((glob) => glob.matches(canonicalizedPath))) {
+ return false;
+ }
+
+ return true;
+ };
+}
diff --git a/pkgs/coverage/lib/src/hitmap.dart b/pkgs/coverage/lib/src/hitmap.dart
new file mode 100644
index 0000000..4c3b468
--- /dev/null
+++ b/pkgs/coverage/lib/src/hitmap.dart
@@ -0,0 +1,386 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert' show json;
+import 'dart:io';
+
+import 'resolver.dart';
+import 'util.dart';
+
+/// Contains line and function hit information for a single script.
+class HitMap {
+ /// Constructs a HitMap.
+ HitMap([
+ Map<int, int>? lineHits,
+ this.funcHits,
+ this.funcNames,
+ this.branchHits,
+ ]) : lineHits = lineHits ?? {};
+
+ /// Map from line to hit count for that line.
+ final Map<int, int> lineHits;
+
+ /// Map from the first line of each function, to the hit count for that
+ /// function. Null if function coverage info was not gathered.
+ Map<int, int>? funcHits;
+
+ /// Map from the first line of each function, to the function name. Null if
+ /// function coverage info was not gathered.
+ Map<int, String>? funcNames;
+
+ /// Map from branch line, to the hit count for that branch. Null if branch
+ /// coverage info was not gathered.
+ Map<int, int>? branchHits;
+
+ /// Creates a single hitmap from a raw json object.
+ ///
+ /// Note that when [checkIgnoredLines] is `true` all files will be
+ /// read to get ignore comments. This will add some overhead.
+ /// To combat this when calling this function multiple times from the
+ /// same source (e.g. test runs of different files) a cache is taken
+ /// via [ignoredLinesInFilesCache]. If this cache contains the parsed
+ /// data for the specific file already, the file will not be read and
+ /// parsed again.
+ ///
+ /// Throws away all entries that are not resolvable.
+ static Map<String, HitMap> parseJsonSync(
+ List<Map<String, dynamic>> jsonResult, {
+ required bool checkIgnoredLines,
+ required Map<String, List<List<int>>?> ignoredLinesInFilesCache,
+ required Resolver resolver,
+ }) {
+ final loader = Loader();
+
+ // Map of source file to map of line to hit count for that line.
+ final globalHitMap = <String, HitMap>{};
+
+ for (var e in jsonResult) {
+ final source = e['source'] as String?;
+ if (source == null) {
+ // Couldn't resolve import, so skip this entry.
+ continue;
+ }
+
+ var ignoredLinesList = <List<int>>[];
+
+ if (checkIgnoredLines) {
+ if (ignoredLinesInFilesCache.containsKey(source)) {
+ final cacheHit = ignoredLinesInFilesCache[source];
+ if (cacheHit == null) {
+ // Null-entry indicates that the whole file was ignored.
+ continue;
+ }
+ ignoredLinesList = cacheHit;
+ } else {
+ final path = resolver.resolve(source);
+ if (path != null) {
+ final lines = loader.loadSync(path) ?? [];
+ ignoredLinesList = getIgnoredLines(path, lines);
+
+ // Ignore the whole file.
+ if (ignoredLinesList.length == 1 &&
+ ignoredLinesList[0][0] == 0 &&
+ ignoredLinesList[0][1] == lines.length) {
+ // Null-entry indicates that the whole file was ignored.
+ ignoredLinesInFilesCache[source] = null;
+ continue;
+ }
+ ignoredLinesInFilesCache[source] = ignoredLinesList;
+ } else {
+ // Couldn't resolve source. Allow cache to answer next time
+ // anyway.
+ ignoredLinesInFilesCache[source] = ignoredLinesList;
+ }
+ }
+ }
+
+ // Move to the first ignore range.
+ final ignoredLines = ignoredLinesList.iterator;
+ var hasCurrent = ignoredLines.moveNext();
+
+ bool shouldIgnoreLine(Iterator<List<int>> ignoredRanges, int line) {
+ if (!hasCurrent || ignoredRanges.current.isEmpty) {
+ return false;
+ }
+
+ if (line < ignoredRanges.current[0]) return false;
+
+ while (hasCurrent &&
+ ignoredRanges.current.isNotEmpty &&
+ ignoredRanges.current[1] < line) {
+ hasCurrent = ignoredRanges.moveNext();
+ }
+
+ if (hasCurrent &&
+ ignoredRanges.current.isNotEmpty &&
+ ignoredRanges.current[0] <= line &&
+ line <= ignoredRanges.current[1]) {
+ return true;
+ }
+
+ return false;
+ }
+
+ void addToMap(Map<int, int> map, int line, int count) {
+ final oldCount = map.putIfAbsent(line, () => 0);
+ map[line] = count + oldCount;
+ }
+
+ void fillHitMap(List hits, Map<int, int> hitMap) {
+ // Ignore line annotations require hits to be sorted.
+ hits = _sortHits(hits);
+ // hits is a flat array of the following format:
+ // [ <line|linerange>, <hitcount>,...]
+ // line: number.
+ // linerange: '<line>-<line>'.
+ for (var i = 0; i < hits.length; i += 2) {
+ final k = hits[i];
+ if (k is int) {
+ // Single line.
+ if (shouldIgnoreLine(ignoredLines, k)) continue;
+
+ addToMap(hitMap, k, hits[i + 1] as int);
+ } else if (k is String) {
+ // Linerange. We expand line ranges to actual lines at this point.
+ final splitPos = k.indexOf('-');
+ final start = int.parse(k.substring(0, splitPos));
+ final end = int.parse(k.substring(splitPos + 1));
+ for (var j = start; j <= end; j++) {
+ if (shouldIgnoreLine(ignoredLines, j)) continue;
+
+ addToMap(hitMap, j, hits[i + 1] as int);
+ }
+ } else {
+ throw StateError('Expected value of type int or String');
+ }
+ }
+ }
+
+ final sourceHitMap = globalHitMap.putIfAbsent(source, HitMap.new);
+ fillHitMap(e['hits'] as List, sourceHitMap.lineHits);
+ if (e.containsKey('funcHits')) {
+ sourceHitMap.funcHits ??= <int, int>{};
+ fillHitMap(e['funcHits'] as List, sourceHitMap.funcHits!);
+ }
+ if (e.containsKey('funcNames')) {
+ sourceHitMap.funcNames ??= <int, String>{};
+ final funcNames = e['funcNames'] as List;
+ for (var i = 0; i < funcNames.length; i += 2) {
+ sourceHitMap.funcNames![funcNames[i] as int] =
+ funcNames[i + 1] as String;
+ }
+ }
+ if (e.containsKey('branchHits')) {
+ sourceHitMap.branchHits ??= <int, int>{};
+ fillHitMap(e['branchHits'] as List, sourceHitMap.branchHits!);
+ }
+ }
+ return globalHitMap;
+ }
+
+ /// Creates a single hitmap from a raw json object.
+ ///
+ /// Throws away all entries that are not resolvable.
+ static Future<Map<String, HitMap>> parseJson(
+ List<Map<String, dynamic>> jsonResult, {
+ bool checkIgnoredLines = false,
+ @Deprecated('Use packagePath') String? packagesPath,
+ String? packagePath,
+ }) async {
+ final resolver = await Resolver.create(
+ packagesPath: packagesPath, packagePath: packagePath);
+ return parseJsonSync(jsonResult,
+ checkIgnoredLines: checkIgnoredLines,
+ ignoredLinesInFilesCache: {},
+ resolver: resolver);
+ }
+
+ /// Generates a merged hitmap from a set of coverage JSON files.
+ static Future<Map<String, HitMap>> parseFiles(
+ Iterable<File> files, {
+ bool checkIgnoredLines = false,
+ @Deprecated('Use packagePath') String? packagesPath,
+ String? packagePath,
+ }) async {
+ final globalHitmap = <String, HitMap>{};
+ for (var file in files) {
+ final contents = file.readAsStringSync();
+ final jsonMap = json.decode(contents) as Map<String, dynamic>;
+ if (jsonMap.containsKey('coverage')) {
+ final jsonResult = jsonMap['coverage'] as List;
+ globalHitmap.merge(await HitMap.parseJson(
+ jsonResult.cast<Map<String, dynamic>>(),
+ checkIgnoredLines: checkIgnoredLines,
+ // ignore: deprecated_member_use_from_same_package
+ packagesPath: packagesPath,
+ packagePath: packagePath,
+ ));
+ }
+ }
+ return globalHitmap;
+ }
+}
+
+extension FileHitMaps on Map<String, HitMap> {
+ /// Merges [newMap] into this one.
+ void merge(Map<String, HitMap> newMap) {
+ newMap.forEach((file, v) {
+ final fileResult = this[file];
+ if (fileResult != null) {
+ _mergeHitCounts(v.lineHits, fileResult.lineHits);
+ if (v.funcHits != null) {
+ fileResult.funcHits ??= <int, int>{};
+ _mergeHitCounts(v.funcHits!, fileResult.funcHits!);
+ }
+ if (v.funcNames != null) {
+ fileResult.funcNames ??= <int, String>{};
+ v.funcNames?.forEach((line, name) {
+ fileResult.funcNames![line] = name;
+ });
+ }
+ if (v.branchHits != null) {
+ fileResult.branchHits ??= <int, int>{};
+ _mergeHitCounts(v.branchHits!, fileResult.branchHits!);
+ }
+ } else {
+ this[file] = v;
+ }
+ });
+ }
+
+ static void _mergeHitCounts(Map<int, int> src, Map<int, int> dest) {
+ src.forEach((line, count) {
+ final lineFileResult = dest[line];
+ if (lineFileResult == null) {
+ dest[line] = count;
+ } else {
+ dest[line] = lineFileResult + count;
+ }
+ });
+ }
+}
+
+/// Class containing information about a coverage hit.
+class _HitInfo {
+ _HitInfo(this.firstLine, this.hitRange, this.hitCount);
+
+ /// The line number of the first line of this hit range.
+ final int firstLine;
+
+ /// A hit range is either a number (1 line) or a String of the form
+ /// "start-end" (multi-line range).
+ final dynamic hitRange;
+
+ /// How many times this hit range was executed.
+ final int hitCount;
+}
+
+/// Creates a single hitmap from a raw json object.
+///
+/// Throws away all entries that are not resolvable.
+@Deprecated('Migrate to HitMap.parseJson')
+Future<Map<String, Map<int, int>>> createHitmap(
+ List<Map<String, dynamic>> jsonResult, {
+ bool checkIgnoredLines = false,
+ @Deprecated('Use packagePath') String? packagesPath,
+ String? packagePath,
+}) async {
+ final result = await HitMap.parseJson(
+ jsonResult,
+ checkIgnoredLines: checkIgnoredLines,
+ packagesPath: packagesPath,
+ packagePath: packagePath,
+ );
+ return result.map((key, value) => MapEntry(key, value.lineHits));
+}
+
+/// Merges [newMap] into [result].
+@Deprecated('Migrate to FileHitMaps.merge')
+void mergeHitmaps(
+ Map<String, Map<int, int>> newMap, Map<String, Map<int, int>> result) {
+ newMap.forEach((file, v) {
+ final fileResult = result[file];
+ if (fileResult != null) {
+ v.forEach((line, count) {
+ final lineFileResult = fileResult[line];
+ if (lineFileResult == null) {
+ fileResult[line] = count;
+ } else {
+ fileResult[line] = lineFileResult + count;
+ }
+ });
+ } else {
+ result[file] = v;
+ }
+ });
+}
+
+/// Generates a merged hitmap from a set of coverage JSON files.
+@Deprecated('Migrate to HitMap.parseFiles')
+Future<Map<String, Map<int, int>>> parseCoverage(
+ Iterable<File> files,
+ int _, {
+ bool checkIgnoredLines = false,
+ @Deprecated('Use packagePath') String? packagesPath,
+ String? packagePath,
+}) async {
+ final result = await HitMap.parseFiles(files,
+ checkIgnoredLines: checkIgnoredLines,
+ packagesPath: packagesPath,
+ packagePath: packagePath);
+ return result.map((key, value) => MapEntry(key, value.lineHits));
+}
+
+/// Returns a JSON hit map backward-compatible with pre-1.16.0 SDKs.
+@Deprecated('Will be removed in 2.0.0')
+Map<String, dynamic> toScriptCoverageJson(Uri scriptUri, Map<int, int> hitMap) {
+ return hitmapToJson(HitMap(hitMap), scriptUri);
+}
+
+List<T> _flattenMap<T>(Map map) {
+ final kvs = <T>[];
+ map.forEach((k, v) {
+ kvs.add(k as T);
+ kvs.add(v as T);
+ });
+ return kvs;
+}
+
+/// Returns a JSON hit map backward-compatible with pre-1.16.0 SDKs.
+Map<String, dynamic> hitmapToJson(HitMap hitmap, Uri scriptUri) =>
+ <String, dynamic>{
+ 'source': '$scriptUri',
+ 'script': {
+ 'type': '@Script',
+ 'fixedId': true,
+ 'id':
+ 'libraries/1/scripts/${Uri.encodeComponent(scriptUri.toString())}',
+ 'uri': '$scriptUri',
+ '_kind': 'library',
+ },
+ 'hits': _flattenMap<int>(hitmap.lineHits),
+ if (hitmap.funcHits != null)
+ 'funcHits': _flattenMap<int>(hitmap.funcHits!),
+ if (hitmap.funcNames != null)
+ 'funcNames': _flattenMap<dynamic>(hitmap.funcNames!),
+ if (hitmap.branchHits != null)
+ 'branchHits': _flattenMap<int>(hitmap.branchHits!),
+ };
+
+/// Sorts the hits array based on the line numbers.
+List _sortHits(List hits) {
+ final structuredHits = <_HitInfo>[];
+ for (var i = 0; i < hits.length - 1; i += 2) {
+ final lineOrLineRange = hits[i];
+ final firstLineInRange = lineOrLineRange is int
+ ? lineOrLineRange
+ : int.parse((lineOrLineRange as String).split('-')[0]);
+ structuredHits.add(_HitInfo(firstLineInRange, hits[i], hits[i + 1] as int));
+ }
+ structuredHits.sort((a, b) => a.firstLine.compareTo(b.firstLine));
+ return structuredHits
+ .map((item) => [item.hitRange, item.hitCount])
+ .expand((item) => item)
+ .toList();
+}
diff --git a/pkgs/coverage/lib/src/isolate_paused_listener.dart b/pkgs/coverage/lib/src/isolate_paused_listener.dart
new file mode 100644
index 0000000..a89a88b
--- /dev/null
+++ b/pkgs/coverage/lib/src/isolate_paused_listener.dart
@@ -0,0 +1,275 @@
+// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:collection';
+
+import 'package:meta/meta.dart';
+import 'package:vm_service/vm_service.dart';
+
+import 'util.dart';
+
+typedef SyncIsolateCallback = void Function(IsolateRef isolate);
+typedef AsyncIsolateCallback = Future<void> Function(IsolateRef isolate);
+typedef AsyncIsolatePausedCallback = Future<void> Function(
+ IsolateRef isolate, bool isLastIsolateInGroup);
+typedef AsyncVmServiceEventCallback = Future<void> Function(Event event);
+typedef SyncErrorLogger = void Function(String message);
+
+/// Calls onIsolatePaused whenever an isolate reaches the pause-on-exit state,
+/// and passes a flag stating whether that isolate is the last one in the group.
+class IsolatePausedListener {
+ IsolatePausedListener(this._service, this._onIsolatePaused, this._log);
+
+ final VmService _service;
+ final AsyncIsolatePausedCallback _onIsolatePaused;
+ final SyncErrorLogger _log;
+
+ final _isolateGroups = <String, IsolateGroupState>{};
+
+ int _numNonMainIsolates = 0;
+ final _allNonMainIsolatesExited = Completer<void>();
+ bool _finished = false;
+
+ IsolateRef? _mainIsolate;
+ final _mainIsolatePaused = Completer<bool>();
+
+ /// Starts listening and returns a future that completes when all isolates
+ /// have exited.
+ Future<void> waitUntilAllExited() async {
+ await listenToIsolateLifecycleEvents(_service, _onStart, _onPause, _onExit);
+
+ await _allNonMainIsolatesExited.future;
+
+ // Resume the main isolate.
+ try {
+ if (_mainIsolate != null) {
+ if (await _mainIsolatePaused.future) {
+ await _runCallbackAndResume(_mainIsolate!, true);
+ }
+ }
+ } finally {
+ _finished = true;
+ }
+ }
+
+ IsolateGroupState _getGroup(IsolateRef isolateRef) =>
+ _isolateGroups[isolateRef.isolateGroupId!] ??= IsolateGroupState();
+
+ void _onStart(IsolateRef isolateRef) {
+ if (_finished) return;
+ final group = _getGroup(isolateRef);
+ group.start(isolateRef.id!);
+ if (_mainIsolate == null && _isMainIsolate(isolateRef)) {
+ _mainIsolate = isolateRef;
+ } else {
+ ++_numNonMainIsolates;
+ }
+ }
+
+ Future<void> _onPause(IsolateRef isolateRef) async {
+ if (_finished) return;
+ final group = _getGroup(isolateRef);
+ group.pause(isolateRef.id!);
+ if (isolateRef.id! == _mainIsolate?.id) {
+ _mainIsolatePaused.complete(true);
+
+ // If the main isolate is the only isolate, then _allNonMainIsolatesExited
+ // will never be completed. So check that case here.
+ _checkCompleted();
+ } else {
+ await _runCallbackAndResume(isolateRef, group.noRunningIsolates);
+ }
+ }
+
+ Future<void> _runCallbackAndResume(
+ IsolateRef isolateRef, bool isLastIsolateInGroup) async {
+ if (isLastIsolateInGroup) {
+ _getGroup(isolateRef).collected = true;
+ }
+ try {
+ await _onIsolatePaused(isolateRef, isLastIsolateInGroup);
+ } finally {
+ await _service.resume(isolateRef.id!);
+ }
+ }
+
+ void _onExit(IsolateRef isolateRef) {
+ if (_finished) return;
+ final group = _getGroup(isolateRef);
+ group.exit(isolateRef.id!);
+ if (group.noLiveIsolates && !group.collected) {
+ _log('ERROR: An isolate exited without pausing, causing '
+ 'coverage data to be lost for group ${isolateRef.isolateGroupId!}.');
+ }
+ if (isolateRef.id! == _mainIsolate?.id) {
+ if (!_mainIsolatePaused.isCompleted) {
+ // Main isolate exited without pausing.
+ _mainIsolatePaused.complete(false);
+ }
+ } else {
+ --_numNonMainIsolates;
+ _checkCompleted();
+ }
+ }
+
+ void _checkCompleted() {
+ if (_numNonMainIsolates == 0 && !_allNonMainIsolatesExited.isCompleted) {
+ _allNonMainIsolatesExited.complete();
+ }
+ }
+
+ static bool _isMainIsolate(IsolateRef isolateRef) {
+ // HACK: This should pretty reliably detect the main isolate, but it's not
+ // foolproof and relies on unstable features. The Dart standalone embedder
+ // and Flutter both call the main isolate "main", and they both also list
+ // this isolate first when querying isolates from the VM service. So
+ // selecting the first isolate named "main" combines these conditions and
+ // should be reliable enough for now, while we wait for a better test.
+ // TODO(https://github.com/dart-lang/sdk/issues/56732): Switch to more
+ // reliable test when it's available.
+ return isolateRef.name == 'main';
+ }
+}
+
+/// Listens to isolate start and pause events, and backfills events for isolates
+/// that existed before listening started.
+///
+/// Ensures that:
+/// - Every [onIsolatePaused] and [onIsolateExited] call will be preceeded by
+/// an [onIsolateStarted] call for the same isolate.
+/// - Not every [onIsolateExited] call will be preceeded by a [onIsolatePaused]
+/// call, but a [onIsolatePaused] will never follow a [onIsolateExited].
+/// - [onIsolateExited] will always run after [onIsolatePaused] completes, even
+/// if an exit event arrives while [onIsolatePaused] is being awaited.
+/// - Each callback will only be called once per isolate.
+Future<void> listenToIsolateLifecycleEvents(
+ VmService service,
+ SyncIsolateCallback onIsolateStarted,
+ AsyncIsolateCallback onIsolatePaused,
+ SyncIsolateCallback onIsolateExited) async {
+ final started = <String>{};
+ void onStart(IsolateRef isolateRef) {
+ if (started.add(isolateRef.id!)) onIsolateStarted(isolateRef);
+ }
+
+ final paused = <String, Future<void>>{};
+ Future<void> onPause(IsolateRef isolateRef) async {
+ try {
+ onStart(isolateRef);
+ } finally {
+ await (paused[isolateRef.id!] ??= onIsolatePaused(isolateRef));
+ }
+ }
+
+ final exited = <String>{};
+ Future<void> onExit(IsolateRef isolateRef) async {
+ onStart(isolateRef);
+ if (exited.add(isolateRef.id!)) {
+ try {
+ // Wait for in-progress pause callbacks, and prevent future pause
+ // callbacks from running.
+ await (paused[isolateRef.id!] ??= Future<void>.value());
+ } finally {
+ onIsolateExited(isolateRef);
+ }
+ }
+ }
+
+ final eventBuffer = IsolateEventBuffer((Event event) async {
+ switch (event.kind) {
+ case EventKind.kIsolateStart:
+ return onStart(event.isolate!);
+ case EventKind.kPauseExit:
+ return await onPause(event.isolate!);
+ case EventKind.kIsolateExit:
+ return await onExit(event.isolate!);
+ }
+ });
+
+ // Listen for isolate start/exit events.
+ service.onIsolateEvent.listen(eventBuffer.add);
+ await service.streamListen(EventStreams.kIsolate);
+
+ // Listen for isolate paused events.
+ service.onDebugEvent.listen(eventBuffer.add);
+ await service.streamListen(EventStreams.kDebug);
+
+ // Backfill. Add/pause isolates that existed before we subscribed.
+ for (final isolateRef in await getAllIsolates(service)) {
+ onStart(isolateRef);
+ final isolate = await service.getIsolate(isolateRef.id!);
+ if (isolate.pauseEvent?.kind == EventKind.kPauseExit) {
+ await onPause(isolateRef);
+ }
+ }
+
+ // Flush the buffered stream events, and the start processing them as they
+ // arrive.
+ await eventBuffer.flush();
+}
+
+/// Keeps track of isolates in an isolate group.
+class IsolateGroupState {
+ // IDs of the isolates running in this group.
+ @visibleForTesting
+ final running = <String>{};
+
+ // IDs of the isolates paused just before exiting in this group.
+ @visibleForTesting
+ final paused = <String>{};
+
+ bool collected = false;
+
+ bool get noRunningIsolates => running.isEmpty;
+ bool get noLiveIsolates => running.isEmpty && paused.isEmpty;
+
+ void start(String id) {
+ paused.remove(id);
+ running.add(id);
+ }
+
+ void pause(String id) {
+ running.remove(id);
+ paused.add(id);
+ }
+
+ void exit(String id) {
+ running.remove(id);
+ paused.remove(id);
+ }
+
+ @override
+ String toString() => '{running: $running, paused: $paused}';
+}
+
+/// Buffers VM service isolate [Event]s until [flush] is called.
+///
+/// [flush] passes each buffered event to the handler function. After that, any
+/// further events are immediately passed to the handler. [flush] returns a
+/// future that completes when all the events in the queue have been handled (as
+/// well as any events that arrive while flush is in progress).
+class IsolateEventBuffer {
+ IsolateEventBuffer(this._handler);
+
+ final AsyncVmServiceEventCallback _handler;
+ final _buffer = Queue<Event>();
+ var _flushed = false;
+
+ Future<void> add(Event event) async {
+ if (_flushed) {
+ await _handler(event);
+ } else {
+ _buffer.add(event);
+ }
+ }
+
+ Future<void> flush() async {
+ while (_buffer.isNotEmpty) {
+ final event = _buffer.removeFirst();
+ await _handler(event);
+ }
+ _flushed = true;
+ }
+}
diff --git a/pkgs/coverage/lib/src/resolver.dart b/pkgs/coverage/lib/src/resolver.dart
new file mode 100644
index 0000000..cb5b728
--- /dev/null
+++ b/pkgs/coverage/lib/src/resolver.dart
@@ -0,0 +1,216 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:package_config/package_config.dart';
+import 'package:path/path.dart' as p;
+
+/// [Resolver] resolves imports with respect to a given environment.
+class Resolver {
+ @Deprecated('Use Resolver.create')
+ Resolver({this.packagesPath, this.sdkRoot})
+ : _packages = packagesPath != null ? _parsePackages(packagesPath) : null,
+ packagePath = null;
+
+ Resolver._(
+ {this.packagesPath,
+ this.packagePath,
+ this.sdkRoot,
+ Map<String, Uri>? packages})
+ : _packages = packages;
+
+ static Future<Resolver> create({
+ String? packagesPath,
+ String? packagePath,
+ String? sdkRoot,
+ }) async {
+ return Resolver._(
+ packagesPath: packagesPath,
+ packagePath: packagePath,
+ sdkRoot: sdkRoot,
+ packages: packagesPath != null
+ ? _parsePackages(packagesPath)
+ : (packagePath != null ? await _parsePackage(packagePath) : null),
+ );
+ }
+
+ final String? packagesPath;
+ final String? packagePath;
+ final String? sdkRoot;
+ final List<String> failed = [];
+ final Map<String, Uri>? _packages;
+
+ /// Returns the absolute path wrt. to the given environment or null, if the
+ /// import could not be resolved.
+ String? resolve(String scriptUri) {
+ final uri = Uri.parse(scriptUri);
+ if (uri.scheme == 'dart') {
+ final sdkRoot = this.sdkRoot;
+ if (sdkRoot == null) {
+ // No sdk-root given, do not resolve dart: URIs.
+ return null;
+ }
+ String filePath;
+ if (uri.pathSegments.length > 1) {
+ var path = uri.pathSegments[0];
+ // Drop patch files, since we don't have their source in the compiled
+ // SDK.
+ if (path.endsWith('-patch')) {
+ failed.add('$uri');
+ return null;
+ }
+ // Canonicalize path. For instance: _collection-dev => _collection_dev.
+ path = path.replaceAll('-', '_');
+ final pathSegments = [
+ sdkRoot,
+ path,
+ ...uri.pathSegments.sublist(1),
+ ];
+ filePath = p.joinAll(pathSegments);
+ } else {
+ // Resolve 'dart:something' to be something/something.dart in the SDK.
+ final lib = uri.path;
+ filePath = p.join(sdkRoot, lib, '$lib.dart');
+ }
+ return resolveSymbolicLinks(filePath);
+ }
+ if (uri.scheme == 'package') {
+ final packages = _packages;
+ if (packages == null) {
+ return null;
+ }
+
+ final packageName = uri.pathSegments[0];
+ final packageUri = packages[packageName];
+ if (packageUri == null) {
+ failed.add('$uri');
+ return null;
+ }
+ final packagePath = p.fromUri(packageUri);
+ final pathInPackage = p.joinAll(uri.pathSegments.sublist(1));
+ return resolveSymbolicLinks(p.join(packagePath, pathInPackage));
+ }
+ if (uri.scheme == 'file') {
+ return resolveSymbolicLinks(p.fromUri(uri));
+ }
+ // We cannot deal with anything else.
+ failed.add('$uri');
+ return null;
+ }
+
+ /// Returns a canonicalized path, or `null` if the path cannot be resolved.
+ String? resolveSymbolicLinks(String path) {
+ final normalizedPath = p.normalize(path);
+ final type = FileSystemEntity.typeSync(normalizedPath, followLinks: true);
+ if (type == FileSystemEntityType.notFound) return null;
+ return File(normalizedPath).resolveSymbolicLinksSync();
+ }
+
+ static Map<String, Uri> _parsePackages(String packagesPath) {
+ final content = File(packagesPath).readAsStringSync();
+ final packagesUri = p.toUri(packagesPath);
+ final parsed =
+ PackageConfig.parseString(content, Uri.base.resolveUri(packagesUri));
+ return {
+ for (var package in parsed.packages) package.name: package.packageUriRoot
+ };
+ }
+
+ static Future<Map<String, Uri>?> _parsePackage(String packagePath) async {
+ final parsed = await findPackageConfig(Directory(packagePath));
+ if (parsed == null) return null;
+ return {
+ for (var package in parsed.packages) package.name: package.packageUriRoot
+ };
+ }
+}
+
+/// Bazel URI resolver.
+class BazelResolver extends Resolver {
+ /// Creates a Bazel resolver with the specified workspace path, if any.
+ BazelResolver({this.workspacePath = ''});
+
+ final String workspacePath;
+
+ /// Returns the absolute path wrt. to the given environment or null, if the
+ /// import could not be resolved.
+ @override
+ String? resolve(String scriptUri) {
+ final uri = Uri.parse(scriptUri);
+ if (uri.scheme == 'dart') {
+ // Ignore the SDK
+ return null;
+ }
+ if (uri.scheme == 'package') {
+ // TODO(cbracken) belongs in a Bazel package
+ return _resolveBazelPackage(uri.pathSegments);
+ }
+ if (uri.scheme == 'file') {
+ final runfilesPathSegment =
+ '.runfiles/$workspacePath'.replaceAll(RegExp(r'/*$'), '/');
+ final runfilesPos = uri.path.indexOf(runfilesPathSegment);
+ if (runfilesPos >= 0) {
+ final pathStart = runfilesPos + runfilesPathSegment.length;
+ return uri.path.substring(pathStart);
+ }
+ return null;
+ }
+ if (uri.scheme == 'https' || uri.scheme == 'http') {
+ return _extractHttpPath(uri);
+ }
+ // We cannot deal with anything else.
+ failed.add('$uri');
+ return null;
+ }
+
+ String _extractHttpPath(Uri uri) {
+ final packagesPos = uri.pathSegments.indexOf('packages');
+ if (packagesPos >= 0) {
+ final workspacePath = uri.pathSegments.sublist(packagesPos + 1);
+ return _resolveBazelPackage(workspacePath);
+ }
+ return uri.pathSegments.join('/');
+ }
+
+ String _resolveBazelPackage(List<String> pathSegments) {
+ // TODO(cbracken) belongs in a Bazel package
+ final packageName = pathSegments[0];
+ final pathInPackage = pathSegments.sublist(1).join('/');
+ final packagePath = packageName.contains('.')
+ ? packageName.replaceAll('.', '/')
+ : 'third_party/dart/$packageName';
+ return '$packagePath/lib/$pathInPackage';
+ }
+}
+
+/// Loads the lines of imported resources.
+class Loader {
+ final List<String> failed = [];
+
+ /// Loads an imported resource and returns a [Future] with a [List] of lines.
+ /// Returns `null` if the resource could not be loaded.
+ Future<List<String>?> load(String path) async {
+ try {
+ // Ensure `readAsLines` runs within the try block so errors are caught.
+ return await File(path).readAsLines();
+ } catch (_) {
+ failed.add(path);
+ return null;
+ }
+ }
+
+ /// Loads an imported resource and returns a [List] of lines.
+ /// Returns `null` if the resource could not be loaded.
+ List<String>? loadSync(String path) {
+ try {
+ // Ensure `readAsLinesSync` runs within the try block so errors are
+ // caught.
+ return File(path).readAsLinesSync();
+ } catch (_) {
+ failed.add(path);
+ return null;
+ }
+ }
+}
diff --git a/pkgs/coverage/lib/src/run_and_collect.dart b/pkgs/coverage/lib/src/run_and_collect.dart
new file mode 100644
index 0000000..f2a9cbc
--- /dev/null
+++ b/pkgs/coverage/lib/src/run_and_collect.dart
@@ -0,0 +1,50 @@
+// 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 'dart:async';
+import 'dart:io';
+
+import 'collect.dart';
+import 'util.dart';
+
+Future<Map<String, dynamic>> runAndCollect(String scriptPath,
+ {List<String>? scriptArgs,
+ bool checked = false,
+ bool includeDart = false,
+ Duration? timeout}) async {
+ final dartArgs = [
+ '--enable-vm-service',
+ '--pause_isolates_on_exit',
+ if (checked) '--checked',
+ scriptPath,
+ ...?scriptArgs,
+ ];
+
+ final process = await Process.start(Platform.executable, dartArgs);
+
+ final serviceUri = await serviceUriFromProcess(process.stdout.lines());
+ Map<String, dynamic> coverage;
+ try {
+ coverage = await collect(
+ serviceUri,
+ true,
+ true,
+ includeDart,
+ <String>{},
+ timeout: timeout,
+ );
+ } finally {
+ await process.stderr.drain<void>();
+ }
+ final exitStatus = await process.exitCode;
+ if (exitStatus != 0) {
+ throw ProcessException(
+ Platform.executable,
+ dartArgs,
+ 'Process failed.',
+ exitStatus,
+ );
+ }
+ return coverage;
+}
diff --git a/pkgs/coverage/lib/src/util.dart b/pkgs/coverage/lib/src/util.dart
new file mode 100644
index 0000000..cc7f584
--- /dev/null
+++ b/pkgs/coverage/lib/src/util.dart
@@ -0,0 +1,186 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:vm_service/vm_service.dart';
+
+// TODO(cbracken) make generic
+/// Retries the specified function with the specified interval and returns
+/// the result on successful completion.
+Future<dynamic> retry(Future Function() f, Duration interval,
+ {Duration? timeout}) async {
+ var keepGoing = true;
+
+ Future<dynamic> withTimeout(Future Function() f, {Duration? duration}) {
+ if (duration == null) {
+ return f();
+ }
+
+ return f().timeout(duration, onTimeout: () {
+ keepGoing = false;
+ final msg = duration.inSeconds == 0
+ ? '${duration.inMilliseconds}ms'
+ : '${duration.inSeconds}s';
+ throw StateError('Failed to complete within $msg');
+ });
+ }
+
+ return withTimeout(() async {
+ while (keepGoing) {
+ try {
+ return await f();
+ } catch (_) {
+ if (keepGoing) {
+ await Future<dynamic>.delayed(interval);
+ }
+ }
+ }
+ }, duration: timeout);
+}
+
+/// Scrapes and returns the Dart VM service URI from a string, or null if not
+/// found.
+///
+/// Potentially useful as a means to extract it from log statements.
+Uri? extractVMServiceUri(String str) {
+ final listeningMessageRegExp = RegExp(
+ r'(?:Observatory|The Dart VM service is) listening on ((http|//)[a-zA-Z0-9:/=_\-\.\[\]]+)',
+ );
+ final match = listeningMessageRegExp.firstMatch(str);
+ if (match != null) {
+ return Uri.parse(match[1]!);
+ }
+ return null;
+}
+
+/// Returns an open port by creating a temporary Socket
+Future<int> getOpenPort() async {
+ ServerSocket socket;
+
+ try {
+ socket = await ServerSocket.bind(InternetAddress.loopbackIPv4, 0);
+ } catch (_) {
+ // try again v/ V6 only. Slight possibility that V4 is disabled
+ socket =
+ await ServerSocket.bind(InternetAddress.loopbackIPv6, 0, v6Only: true);
+ }
+
+ try {
+ return socket.port;
+ } finally {
+ await socket.close();
+ }
+}
+
+final muliLineIgnoreStart = RegExp(r'//\s*coverage:ignore-start[\w\d\s]*$');
+final muliLineIgnoreEnd = RegExp(r'//\s*coverage:ignore-end[\w\d\s]*$');
+final singleLineIgnore = RegExp(r'//\s*coverage:ignore-line[\w\d\s]*$');
+final ignoreFile = RegExp(r'//\s*coverage:ignore-file[\w\d\s]*$');
+
+/// Return list containing inclusive range of lines to be ignored by coverage.
+/// If there is a error in balancing the statements it will throw a
+/// [FormatException],
+/// unless `coverage:ignore-file` is found.
+/// Return [0, lines.length] if the whole file is ignored.
+///
+/// ```
+/// 1. final str = ''; // coverage:ignore-line
+/// 2. final str = '';
+/// 3. final str = ''; // coverage:ignore-start
+/// 4. final str = '';
+/// 5. final str = ''; // coverage:ignore-end
+/// ```
+///
+/// Returns
+/// ```
+/// [
+/// [1,1],
+/// [3,5],
+/// ]
+/// ```
+///
+List<List<int>> getIgnoredLines(String filePath, List<String>? lines) {
+ final ignoredLines = <List<int>>[];
+ if (lines == null) return ignoredLines;
+
+ final allLines = [
+ [0, lines.length]
+ ];
+
+ FormatException? err;
+ var i = 0;
+ while (i < lines.length) {
+ if (lines[i].contains(ignoreFile)) return allLines;
+
+ if (lines[i].contains(muliLineIgnoreEnd)) {
+ err ??= FormatException(
+ 'unmatched coverage:ignore-end found at $filePath:${i + 1}',
+ );
+ }
+
+ if (lines[i].contains(singleLineIgnore)) ignoredLines.add([i + 1, i + 1]);
+
+ if (lines[i].contains(muliLineIgnoreStart)) {
+ final start = i;
+ var isUnmatched = true;
+ ++i;
+ while (i < lines.length) {
+ if (lines[i].contains(ignoreFile)) return allLines;
+ if (lines[i].contains(muliLineIgnoreStart)) {
+ err ??= FormatException(
+ 'coverage:ignore-start found at $filePath:${i + 1}'
+ ' before previous coverage:ignore-start ended',
+ );
+ break;
+ }
+
+ if (lines[i].contains(muliLineIgnoreEnd)) {
+ ignoredLines.add([start + 1, i + 1]);
+ isUnmatched = false;
+ break;
+ }
+ ++i;
+ }
+
+ if (isUnmatched) {
+ err ??= FormatException(
+ 'coverage:ignore-start found at $filePath:${start + 1}'
+ ' has no matching coverage:ignore-end',
+ );
+ }
+ }
+ ++i;
+ }
+
+ if (err == null) {
+ return ignoredLines;
+ }
+
+ throw err;
+}
+
+extension StandardOutExtension on Stream<List<int>> {
+ Stream<String> lines() =>
+ transform(const SystemEncoding().decoder).transform(const LineSplitter());
+}
+
+Future<Uri> serviceUriFromProcess(Stream<String> procStdout) {
+ // Capture the VM service URI.
+ final serviceUriCompleter = Completer<Uri>();
+ procStdout.listen((line) {
+ if (!serviceUriCompleter.isCompleted) {
+ final serviceUri = extractVMServiceUri(line);
+ if (serviceUri != null) {
+ serviceUriCompleter.complete(serviceUri);
+ }
+ }
+ });
+ return serviceUriCompleter.future;
+}
+
+Future<List<IsolateRef>> getAllIsolates(VmService service) async =>
+ (await service.getVM()).isolates ?? [];
diff --git a/pkgs/coverage/pubspec.yaml b/pkgs/coverage/pubspec.yaml
new file mode 100644
index 0000000..87a96d0
--- /dev/null
+++ b/pkgs/coverage/pubspec.yaml
@@ -0,0 +1,32 @@
+name: coverage
+version: 1.10.0
+description: Coverage data manipulation and formatting
+repository: https://github.com/dart-lang/tools/tree/main/pkgs/coverage
+
+environment:
+ sdk: ^3.4.0
+
+dependencies:
+ args: ^2.0.0
+ glob: ^2.1.2
+ logging: ^1.0.0
+ meta: ^1.0.2
+ package_config: ^2.0.0
+ path: ^1.8.0
+ source_maps: ^0.10.10
+ stack_trace: ^1.10.0
+ vm_service: '>=12.0.0 <15.0.0'
+
+dev_dependencies:
+ benchmark_harness: ^2.2.0
+ build_runner: ^2.3.1
+ dart_flutter_team_lints: ^3.0.0
+ mockito: ^5.4.4
+ test: ^1.24.7
+ test_descriptor: ^2.0.0
+ test_process: ^2.0.0
+
+executables:
+ collect_coverage:
+ format_coverage:
+ test_with_coverage:
diff --git a/pkgs/coverage/test/README.md b/pkgs/coverage/test/README.md
new file mode 100644
index 0000000..8fa00df
--- /dev/null
+++ b/pkgs/coverage/test/README.md
@@ -0,0 +1,9 @@
+## Regenerating mocks
+
+Some of the tests use a mock VmService that is automatically generated by
+Mockito. If the VmService changes, run this command in the root directory of
+this repo to regenerate that mock:
+
+```bash
+dart run build_runner build
+```
diff --git a/pkgs/coverage/test/chrome_test.dart b/pkgs/coverage/test/chrome_test.dart
new file mode 100644
index 0000000..50e7600
--- /dev/null
+++ b/pkgs/coverage/test/chrome_test.dart
@@ -0,0 +1,78 @@
+// 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.
+
+// TODO(https://github.com/dart-lang/tools/issues/494): Fix and re-enable this.
+@TestOn('!windows')
+library;
+
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:coverage/coverage.dart';
+import 'package:test/test.dart';
+
+// The scriptId for the main_test.js in the sample report.
+const String mainScriptId = '31';
+
+Future<String> sourceMapProvider(String scriptId) async {
+ if (scriptId != mainScriptId) {
+ return 'something invalid!';
+ }
+ return File('test/test_files/main_test.js.map').readAsString();
+}
+
+Future<String?> sourceProvider(String scriptId) async {
+ if (scriptId != mainScriptId) return null;
+ return File('test/test_files/main_test.js').readAsString();
+}
+
+Future<Uri> sourceUriProvider(String sourceUrl, String scriptId) async =>
+ Uri.parse(sourceUrl);
+
+void main() {
+ test('reports correctly', () async {
+ final preciseCoverage = json.decode(
+ await File('test/test_files/chrome_precise_report.txt')
+ .readAsString()) as List;
+
+ final report = await parseChromeCoverage(
+ preciseCoverage.cast(),
+ sourceProvider,
+ sourceMapProvider,
+ sourceUriProvider,
+ );
+
+ final sourceReport =
+ (report['coverage'] as List<Map<String, dynamic>>).firstWhere(
+ (Map<String, dynamic> report) =>
+ report['source'].toString().contains('main_test.dart'),
+ );
+
+ final expectedHits = {
+ 7: 1,
+ 11: 1,
+ 13: 1,
+ 14: 1,
+ 17: 0,
+ 19: 0,
+ 20: 0,
+ 22: 1,
+ 23: 1,
+ 24: 1,
+ 25: 1,
+ 28: 1,
+ 30: 0,
+ 32: 1,
+ 34: 1,
+ 35: 1,
+ 36: 1,
+ };
+
+ final hitMap = sourceReport['hits'] as List<int>;
+ expect(hitMap.length, equals(expectedHits.keys.length * 2));
+ for (var i = 0; i < hitMap.length; i += 2) {
+ expect(expectedHits[hitMap[i]], equals(hitMap[i + 1]));
+ }
+ });
+}
diff --git a/pkgs/coverage/test/collect_coverage_api_test.dart b/pkgs/coverage/test/collect_coverage_api_test.dart
new file mode 100644
index 0000000..fd3de43
--- /dev/null
+++ b/pkgs/coverage/test/collect_coverage_api_test.dart
@@ -0,0 +1,157 @@
+// 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 'dart:async';
+
+import 'package:coverage/coverage.dart';
+import 'package:coverage/src/util.dart';
+import 'package:path/path.dart' as p;
+import 'package:test/test.dart';
+
+import 'test_util.dart';
+
+final _isolateLibPath = p.join('test', 'test_files', 'test_app_isolate.dart');
+
+final _sampleAppFileUri = p.toUri(p.absolute(testAppPath)).toString();
+final _isolateLibFileUri = p.toUri(p.absolute(_isolateLibPath)).toString();
+
+void main() {
+ test('collect_coverage_api', () async {
+ final coverage = coverageDataFromJson(await _collectCoverage());
+ expect(coverage, isNotEmpty);
+
+ final sources = coverage.sources();
+
+ for (var sampleCoverageData in sources[_sampleAppFileUri]!) {
+ expect(sampleCoverageData['hits'], isNotEmpty);
+ }
+
+ for (var sampleCoverageData in sources[_isolateLibFileUri]!) {
+ expect(sampleCoverageData['hits'], isNotEmpty);
+ }
+ });
+
+ test('collect_coverage_api with scoped output', () async {
+ final coverage = coverageDataFromJson(
+ await _collectCoverage(scopedOutput: <String>{}..add('coverage')),
+ );
+ expect(coverage, isNotEmpty);
+
+ final sources = coverage.sources();
+
+ for (var key in sources.keys) {
+ final uri = Uri.parse(key);
+ expect(uri.path.startsWith('coverage'), isTrue);
+ }
+ });
+
+ test('collect_coverage_api with isolateIds', () async {
+ final coverage =
+ coverageDataFromJson(await _collectCoverage(isolateIds: true));
+ expect(coverage, isEmpty);
+ });
+
+ test('collect_coverage_api with function coverage', () async {
+ final coverage =
+ coverageDataFromJson(await _collectCoverage(functionCoverage: true));
+ expect(coverage, isNotEmpty);
+
+ final sources = coverage.sources();
+
+ final functionInfo = functionInfoFromSources(sources);
+
+ expect(
+ functionInfo[_sampleAppFileUri]!,
+ {
+ 'main': 1,
+ 'usedMethod': 1,
+ 'unusedMethod': 0,
+ },
+ );
+
+ expect(
+ functionInfo[_isolateLibFileUri]!,
+ {
+ 'BarClass.BarClass': 1,
+ 'fooAsync': 1,
+ 'fooSync': 1,
+ 'isolateTask': 1,
+ 'BarClass.baz': 1
+ },
+ );
+ });
+
+ test('collect_coverage_api with branch coverage', () async {
+ final coverage =
+ coverageDataFromJson(await _collectCoverage(branchCoverage: true));
+ expect(coverage, isNotEmpty);
+
+ final sources = coverage.sources();
+
+ // Dart VM versions before 2.17 don't support branch coverage.
+ expect(sources[_sampleAppFileUri],
+ everyElement(containsPair('branchHits', isNotEmpty)));
+ expect(sources[_isolateLibFileUri],
+ everyElement(containsPair('branchHits', isNotEmpty)));
+ });
+
+ test('collect_coverage_api with coverableLineCache', () async {
+ final coverableLineCache = <String, Set<int>>{};
+ final coverage =
+ await _collectCoverage(coverableLineCache: coverableLineCache);
+ final result = await HitMap.parseJson(
+ coverage['coverage'] as List<Map<String, dynamic>>);
+
+ expect(coverableLineCache, contains(_sampleAppFileUri));
+ expect(coverableLineCache, contains(_isolateLibFileUri));
+
+ // Expect that we have some missed lines.
+ expect(result[_sampleAppFileUri]!.lineHits.containsValue(0), isTrue);
+ expect(result[_isolateLibFileUri]!.lineHits.containsValue(0), isTrue);
+
+ // Clear _sampleAppFileUri's cache entry, then gather coverage again. We're
+ // doing this to verify that force compilation is disabled for these
+ // libraries. The result should be that _isolateLibFileUri should be the
+ // same, but _sampleAppFileUri should be missing all its missed lines.
+ coverableLineCache[_sampleAppFileUri] = {};
+ final coverage2 =
+ await _collectCoverage(coverableLineCache: coverableLineCache);
+ final result2 = await HitMap.parseJson(
+ coverage2['coverage'] as List<Map<String, dynamic>>);
+
+ // _isolateLibFileUri still has missed lines, but _sampleAppFileUri doesn't.
+ expect(result2[_sampleAppFileUri]!.lineHits.containsValue(0), isFalse);
+ expect(result2[_isolateLibFileUri]!.lineHits.containsValue(0), isTrue);
+
+ // _isolateLibFileUri is the same. _sampleAppFileUri is the same, but
+ // without all its missed lines.
+ expect(result2[_isolateLibFileUri]!.lineHits,
+ result[_isolateLibFileUri]!.lineHits);
+ result[_sampleAppFileUri]!.lineHits.removeWhere((line, hits) => hits == 0);
+ expect(result2[_sampleAppFileUri]!.lineHits,
+ result[_sampleAppFileUri]!.lineHits);
+ }, skip: !platformVersionCheck(3, 2));
+}
+
+Future<Map<String, dynamic>> _collectCoverage(
+ {Set<String> scopedOutput = const {},
+ bool isolateIds = false,
+ bool functionCoverage = false,
+ bool branchCoverage = false,
+ Map<String, Set<int>>? coverableLineCache}) async {
+ final openPort = await getOpenPort();
+
+ // run the sample app, with the right flags
+ final sampleProcess = await runTestApp(openPort);
+
+ final serviceUri = await serviceUriFromProcess(sampleProcess.stdoutStream());
+ final isolateIdSet = isolateIds ? <String>{} : null;
+
+ return collect(serviceUri, true, true, false, scopedOutput,
+ timeout: timeout,
+ isolateIds: isolateIdSet,
+ functionCoverage: functionCoverage,
+ branchCoverage: branchCoverage,
+ coverableLineCache: coverableLineCache);
+}
diff --git a/pkgs/coverage/test/collect_coverage_mock_test.dart b/pkgs/coverage/test/collect_coverage_mock_test.dart
new file mode 100644
index 0000000..372bd48
--- /dev/null
+++ b/pkgs/coverage/test/collect_coverage_mock_test.dart
@@ -0,0 +1,416 @@
+// Copyright (c) 2022, 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:coverage/coverage.dart';
+import 'package:mockito/annotations.dart';
+import 'package:mockito/mockito.dart';
+import 'package:test/test.dart';
+import 'package:vm_service/vm_service.dart';
+
+import 'collect_coverage_mock_test.mocks.dart';
+
+@GenerateMocks([VmService])
+SourceReportRange _range(int scriptIndex, SourceReportCoverage coverage) =>
+ SourceReportRange(scriptIndex: scriptIndex, coverage: coverage);
+
+IsolateRef _isoRef(String id, String isoGroupId) =>
+ IsolateRef(id: id, isolateGroupId: isoGroupId);
+
+IsolateGroupRef _isoGroupRef(String id) => IsolateGroupRef(id: id);
+
+IsolateGroup _isoGroup(String id, List<IsolateRef> isolates) =>
+ IsolateGroup(id: id, isolates: isolates);
+
+class FakeSentinelException implements SentinelException {
+ @override
+ dynamic noSuchMethod(Invocation invocation) {}
+}
+
+MockVmService _mockService(
+ int majorVersion,
+ int minorVersion, {
+ Map<String, List<String>> isolateGroups = const {
+ 'isolateGroup': ['isolate'],
+ },
+}) {
+ final service = MockVmService();
+ final isoRefs = <IsolateRef>[];
+ final isoGroupRefs = <IsolateGroupRef>[];
+ final isoGroups = <IsolateGroup>[];
+ for (final group in isolateGroups.entries) {
+ isoGroupRefs.add(_isoGroupRef(group.key));
+ final isosOfGroup = <IsolateRef>[];
+ for (final isoId in group.value) {
+ isosOfGroup.add(_isoRef(isoId, group.key));
+ }
+ isoGroups.add(_isoGroup(group.key, isosOfGroup));
+ isoRefs.addAll(isosOfGroup);
+ }
+ when(service.getVM()).thenAnswer(
+ (_) async => VM(isolates: isoRefs, isolateGroups: isoGroupRefs));
+ for (final group in isoGroups) {
+ when(service.getIsolateGroup(group.id)).thenAnswer((_) async => group);
+ }
+ when(service.getVersion()).thenAnswer(
+ (_) async => Version(major: majorVersion, minor: minorVersion));
+ return service;
+}
+
+void main() {
+ group('Mock VM Service', () {
+ test('Collect coverage', () async {
+ final service = _mockService(4, 13);
+ when(service.getSourceReport(
+ 'isolate',
+ ['Coverage'],
+ forceCompile: true,
+ reportLines: true,
+ )).thenAnswer((_) async => SourceReport(
+ ranges: [
+ _range(
+ 0,
+ SourceReportCoverage(
+ hits: [12],
+ misses: [47],
+ ),
+ ),
+ _range(
+ 1,
+ SourceReportCoverage(
+ hits: [95],
+ misses: [52],
+ ),
+ ),
+ ],
+ scripts: [
+ ScriptRef(
+ uri: 'package:foo/foo.dart',
+ id: 'foo',
+ ),
+ ScriptRef(
+ uri: 'package:bar/bar.dart',
+ id: 'bar',
+ ),
+ ],
+ ));
+
+ final jsonResult = await collect(Uri(), false, false, false, null,
+ serviceOverrideForTesting: service);
+ final result = await HitMap.parseJson(
+ jsonResult['coverage'] as List<Map<String, dynamic>>);
+
+ expect(result.length, 2);
+ expect(result['package:foo/foo.dart']?.lineHits, {12: 1, 47: 0});
+ expect(result['package:bar/bar.dart']?.lineHits, {95: 1, 52: 0});
+ });
+
+ test('Collect coverage, scoped output', () async {
+ final service = _mockService(4, 13);
+ when(service.getSourceReport(
+ 'isolate',
+ ['Coverage'],
+ forceCompile: true,
+ reportLines: true,
+ libraryFilters: ['package:foo/'],
+ )).thenAnswer((_) async => SourceReport(
+ ranges: [
+ _range(
+ 0,
+ SourceReportCoverage(
+ hits: [12],
+ misses: [47],
+ ),
+ ),
+ ],
+ scripts: [
+ ScriptRef(
+ uri: 'package:foo/foo.dart',
+ id: 'foo',
+ ),
+ ],
+ ));
+
+ final jsonResult = await collect(Uri(), false, false, false, {'foo'},
+ serviceOverrideForTesting: service);
+ final result = await HitMap.parseJson(
+ jsonResult['coverage'] as List<Map<String, dynamic>>);
+
+ expect(result.length, 1);
+ expect(result['package:foo/foo.dart']?.lineHits, {12: 1, 47: 0});
+ });
+
+ test('Collect coverage, fast isolate group deduping', () async {
+ final service = _mockService(4, 13, isolateGroups: {
+ 'isolateGroupA': ['isolate1', 'isolate2'],
+ 'isolateGroupB': ['isolate3'],
+ });
+ when(service.getSourceReport(
+ 'isolate1',
+ ['Coverage'],
+ forceCompile: true,
+ reportLines: true,
+ )).thenAnswer((_) async => SourceReport(
+ ranges: [
+ _range(
+ 0,
+ SourceReportCoverage(
+ hits: [12],
+ misses: [47],
+ ),
+ ),
+ _range(
+ 1,
+ SourceReportCoverage(
+ hits: [95],
+ misses: [52],
+ ),
+ ),
+ ],
+ scripts: [
+ ScriptRef(
+ uri: 'package:foo/foo.dart',
+ id: 'foo',
+ ),
+ ScriptRef(
+ uri: 'package:bar/bar.dart',
+ id: 'bar',
+ ),
+ ],
+ ));
+ when(service.getSourceReport(
+ 'isolate3',
+ ['Coverage'],
+ forceCompile: true,
+ reportLines: true,
+ )).thenAnswer((_) async => SourceReport(
+ ranges: [
+ _range(
+ 0,
+ SourceReportCoverage(
+ hits: [34],
+ misses: [61],
+ ),
+ ),
+ ],
+ scripts: [
+ ScriptRef(
+ uri: 'package:baz/baz.dart',
+ id: 'baz',
+ ),
+ ],
+ ));
+
+ final jsonResult = await collect(Uri(), false, false, false, null,
+ serviceOverrideForTesting: service);
+ final result = await HitMap.parseJson(
+ jsonResult['coverage'] as List<Map<String, dynamic>>);
+
+ expect(result.length, 3);
+ expect(result['package:foo/foo.dart']?.lineHits, {12: 1, 47: 0});
+ expect(result['package:bar/bar.dart']?.lineHits, {95: 1, 52: 0});
+ expect(result['package:baz/baz.dart']?.lineHits, {34: 1, 61: 0});
+ verifyNever(service.getSourceReport('isolate2', ['Coverage'],
+ forceCompile: true, reportLines: true));
+ verifyNever(service.getIsolateGroup('isolateGroupA'));
+ verifyNever(service.getIsolateGroup('isolateGroupB'));
+ });
+
+ test(
+ 'Collect coverage, no scoped output, '
+ 'handles SentinelException from getSourceReport', () async {
+ final service = _mockService(4, 13);
+ when(service.getSourceReport(
+ 'isolate',
+ ['Coverage'],
+ forceCompile: true,
+ reportLines: true,
+ )).thenThrow(FakeSentinelException());
+
+ final jsonResult = await collect(Uri(), false, false, false, null,
+ serviceOverrideForTesting: service);
+ final result = await HitMap.parseJson(
+ jsonResult['coverage'] as List<Map<String, dynamic>>);
+
+ expect(result.length, 0);
+ });
+
+ test('Collect coverage, coverableLineCache', () async {
+ // Expect that on the first getSourceReport call, librariesAlreadyCompiled
+ // is empty.
+ final service = _mockService(4, 13);
+ when(service.getSourceReport(
+ 'isolate',
+ ['Coverage'],
+ forceCompile: true,
+ reportLines: true,
+ librariesAlreadyCompiled: [],
+ )).thenAnswer((_) async => SourceReport(
+ ranges: [
+ _range(
+ 0,
+ SourceReportCoverage(
+ hits: [12],
+ misses: [47],
+ ),
+ ),
+ _range(
+ 1,
+ SourceReportCoverage(
+ hits: [95],
+ misses: [52],
+ ),
+ ),
+ ],
+ scripts: [
+ ScriptRef(
+ uri: 'package:foo/foo.dart',
+ id: 'foo',
+ ),
+ ScriptRef(
+ uri: 'package:bar/bar.dart',
+ id: 'bar',
+ ),
+ ],
+ ));
+
+ final coverableLineCache = <String, Set<int>>{};
+ final jsonResult = await collect(Uri(), false, false, false, null,
+ coverableLineCache: coverableLineCache,
+ serviceOverrideForTesting: service);
+ final result = await HitMap.parseJson(
+ jsonResult['coverage'] as List<Map<String, dynamic>>);
+
+ expect(result.length, 2);
+ expect(result['package:foo/foo.dart']?.lineHits, {12: 1, 47: 0});
+ expect(result['package:bar/bar.dart']?.lineHits, {95: 1, 52: 0});
+
+ // The coverableLineCache should now be filled with all the lines that
+ // were hit or missed.
+ expect(coverableLineCache, {
+ 'package:foo/foo.dart': {12, 47},
+ 'package:bar/bar.dart': {95, 52},
+ });
+
+ // The second getSourceReport call should now list all the libraries we've
+ // seen. The response won't contain any misses for these libraries,
+ // because they won't be force compiled. We'll also return a 3rd library,
+ // which will contain misses, as it hasn't been compiled yet.
+ when(service.getSourceReport(
+ 'isolate',
+ ['Coverage'],
+ forceCompile: true,
+ reportLines: true,
+ librariesAlreadyCompiled: [
+ 'package:foo/foo.dart',
+ 'package:bar/bar.dart'
+ ],
+ )).thenAnswer((_) async => SourceReport(
+ ranges: [
+ _range(
+ 0,
+ SourceReportCoverage(
+ hits: [47],
+ ),
+ ),
+ _range(
+ 1,
+ SourceReportCoverage(
+ hits: [95],
+ ),
+ ),
+ _range(
+ 2,
+ SourceReportCoverage(
+ hits: [36],
+ misses: [81],
+ ),
+ ),
+ ],
+ scripts: [
+ ScriptRef(
+ uri: 'package:foo/foo.dart',
+ id: 'foo',
+ ),
+ ScriptRef(
+ uri: 'package:bar/bar.dart',
+ id: 'bar',
+ ),
+ ScriptRef(
+ uri: 'package:baz/baz.dart',
+ id: 'baz',
+ ),
+ ],
+ ));
+
+ final jsonResult2 = await collect(Uri(), false, false, false, null,
+ coverableLineCache: coverableLineCache,
+ serviceOverrideForTesting: service);
+ final result2 = await HitMap.parseJson(
+ jsonResult2['coverage'] as List<Map<String, dynamic>>);
+
+ // The missed lines still appear in foo and bar, even though they weren't
+ // returned in the response. They were read from the cache.
+ expect(result2.length, 3);
+ expect(result2['package:foo/foo.dart']?.lineHits, {12: 0, 47: 1});
+ expect(result2['package:bar/bar.dart']?.lineHits, {95: 1, 52: 0});
+ expect(result2['package:baz/baz.dart']?.lineHits, {36: 1, 81: 0});
+
+ // The coverableLineCache should now also contain the baz library.
+ expect(coverableLineCache, {
+ 'package:foo/foo.dart': {12, 47},
+ 'package:bar/bar.dart': {95, 52},
+ 'package:baz/baz.dart': {36, 81},
+ });
+ });
+
+ test(
+ 'Collect coverage, scoped output, '
+ 'handles SourceReports that contain unfiltered ranges', () async {
+ // Regression test for https://github.com/dart-lang/tools/issues/530
+ final service = _mockService(4, 13);
+ when(service.getSourceReport(
+ 'isolate',
+ ['Coverage'],
+ forceCompile: true,
+ reportLines: true,
+ libraryFilters: ['package:foo/'],
+ )).thenAnswer((_) async => SourceReport(
+ ranges: [
+ _range(
+ 0,
+ SourceReportCoverage(
+ hits: [12],
+ misses: [47],
+ ),
+ ),
+ _range(
+ 1,
+ SourceReportCoverage(
+ hits: [86],
+ misses: [91],
+ ),
+ ),
+ ],
+ scripts: [
+ ScriptRef(
+ uri: 'package:foo/foo.dart',
+ id: 'foo',
+ ),
+ ScriptRef(
+ uri: 'package:bar/bar.dart',
+ id: 'bar',
+ ),
+ ],
+ ));
+
+ final jsonResult = await collect(Uri(), false, false, false, {'foo'},
+ serviceOverrideForTesting: service);
+ final result = await HitMap.parseJson(
+ jsonResult['coverage'] as List<Map<String, dynamic>>);
+
+ expect(result.length, 1);
+ expect(result['package:foo/foo.dart']?.lineHits, {12: 1, 47: 0});
+ });
+ });
+}
diff --git a/pkgs/coverage/test/collect_coverage_mock_test.mocks.dart b/pkgs/coverage/test/collect_coverage_mock_test.mocks.dart
new file mode 100644
index 0000000..86f596a
--- /dev/null
+++ b/pkgs/coverage/test/collect_coverage_mock_test.mocks.dart
@@ -0,0 +1,2047 @@
+// Mocks generated by Mockito 5.4.4 from annotations
+// in coverage/test/collect_coverage_mock_test.dart.
+// Do not manually edit this file.
+
+// ignore_for_file: no_leading_underscores_for_library_prefixes
+import 'dart:async' as _i3;
+
+import 'package:mockito/mockito.dart' as _i1;
+import 'package:mockito/src/dummies.dart' as _i4;
+import 'package:vm_service/src/vm_service.dart' as _i2;
+
+// ignore_for_file: type=lint
+// ignore_for_file: avoid_redundant_argument_values
+// ignore_for_file: avoid_setters_without_getters
+// ignore_for_file: comment_references
+// ignore_for_file: deprecated_member_use
+// ignore_for_file: deprecated_member_use_from_same_package
+// ignore_for_file: implementation_imports
+// ignore_for_file: invalid_use_of_visible_for_testing_member
+// ignore_for_file: prefer_const_constructors
+// ignore_for_file: unnecessary_parenthesis
+// ignore_for_file: camel_case_types
+// ignore_for_file: subtype_of_sealed_class
+
+class _FakeBreakpoint_0 extends _i1.SmartFake implements _i2.Breakpoint {
+ _FakeBreakpoint_0(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakeSuccess_1 extends _i1.SmartFake implements _i2.Success {
+ _FakeSuccess_1(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakeIdZone_2 extends _i1.SmartFake implements _i2.IdZone {
+ _FakeIdZone_2(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakeResponse_3 extends _i1.SmartFake implements _i2.Response {
+ _FakeResponse_3(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakeAllocationProfile_4 extends _i1.SmartFake
+ implements _i2.AllocationProfile {
+ _FakeAllocationProfile_4(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakeCpuSamples_5 extends _i1.SmartFake implements _i2.CpuSamples {
+ _FakeCpuSamples_5(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakeClassList_6 extends _i1.SmartFake implements _i2.ClassList {
+ _FakeClassList_6(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakeFlagList_7 extends _i1.SmartFake implements _i2.FlagList {
+ _FakeFlagList_7(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakeInboundReferences_8 extends _i1.SmartFake
+ implements _i2.InboundReferences {
+ _FakeInboundReferences_8(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakeInstanceSet_9 extends _i1.SmartFake implements _i2.InstanceSet {
+ _FakeInstanceSet_9(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakeInstanceRef_10 extends _i1.SmartFake implements _i2.InstanceRef {
+ _FakeInstanceRef_10(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakeIsolate_11 extends _i1.SmartFake implements _i2.Isolate {
+ _FakeIsolate_11(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakeIsolateGroup_12 extends _i1.SmartFake implements _i2.IsolateGroup {
+ _FakeIsolateGroup_12(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakeEvent_13 extends _i1.SmartFake implements _i2.Event {
+ _FakeEvent_13(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakeMemoryUsage_14 extends _i1.SmartFake implements _i2.MemoryUsage {
+ _FakeMemoryUsage_14(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakeScriptList_15 extends _i1.SmartFake implements _i2.ScriptList {
+ _FakeScriptList_15(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakeObj_16 extends _i1.SmartFake implements _i2.Obj {
+ _FakeObj_16(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakePerfettoCpuSamples_17 extends _i1.SmartFake
+ implements _i2.PerfettoCpuSamples {
+ _FakePerfettoCpuSamples_17(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakePerfettoTimeline_18 extends _i1.SmartFake
+ implements _i2.PerfettoTimeline {
+ _FakePerfettoTimeline_18(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakePortList_19 extends _i1.SmartFake implements _i2.PortList {
+ _FakePortList_19(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakeRetainingPath_20 extends _i1.SmartFake implements _i2.RetainingPath {
+ _FakeRetainingPath_20(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakeProcessMemoryUsage_21 extends _i1.SmartFake
+ implements _i2.ProcessMemoryUsage {
+ _FakeProcessMemoryUsage_21(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakeStack_22 extends _i1.SmartFake implements _i2.Stack {
+ _FakeStack_22(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakeProtocolList_23 extends _i1.SmartFake implements _i2.ProtocolList {
+ _FakeProtocolList_23(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakeSourceReport_24 extends _i1.SmartFake implements _i2.SourceReport {
+ _FakeSourceReport_24(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakeVersion_25 extends _i1.SmartFake implements _i2.Version {
+ _FakeVersion_25(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakeVM_26 extends _i1.SmartFake implements _i2.VM {
+ _FakeVM_26(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakeTimeline_27 extends _i1.SmartFake implements _i2.Timeline {
+ _FakeTimeline_27(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakeTimelineFlags_28 extends _i1.SmartFake implements _i2.TimelineFlags {
+ _FakeTimelineFlags_28(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakeTimestamp_29 extends _i1.SmartFake implements _i2.Timestamp {
+ _FakeTimestamp_29(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakeUriList_30 extends _i1.SmartFake implements _i2.UriList {
+ _FakeUriList_30(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakeReloadReport_31 extends _i1.SmartFake implements _i2.ReloadReport {
+ _FakeReloadReport_31(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+class _FakeFuture_32<T1> extends _i1.SmartFake implements _i3.Future<T1> {
+ _FakeFuture_32(
+ Object parent,
+ Invocation parentInvocation,
+ ) : super(
+ parent,
+ parentInvocation,
+ );
+}
+
+/// A class which mocks [VmService].
+///
+/// See the documentation for Mockito's code generation for more information.
+class MockVmService extends _i1.Mock implements _i2.VmService {
+ MockVmService() {
+ _i1.throwOnMissingStub(this);
+ }
+
+ @override
+ _i3.Stream<String> get onSend => (super.noSuchMethod(
+ Invocation.getter(#onSend),
+ returnValue: _i3.Stream<String>.empty(),
+ ) as _i3.Stream<String>);
+
+ @override
+ _i3.Stream<String> get onReceive => (super.noSuchMethod(
+ Invocation.getter(#onReceive),
+ returnValue: _i3.Stream<String>.empty(),
+ ) as _i3.Stream<String>);
+
+ @override
+ _i3.Future<void> get onDone => (super.noSuchMethod(
+ Invocation.getter(#onDone),
+ returnValue: _i3.Future<void>.value(),
+ ) as _i3.Future<void>);
+
+ @override
+ _i3.Stream<_i2.Event> get onVMEvent => (super.noSuchMethod(
+ Invocation.getter(#onVMEvent),
+ returnValue: _i3.Stream<_i2.Event>.empty(),
+ ) as _i3.Stream<_i2.Event>);
+
+ @override
+ _i3.Stream<_i2.Event> get onIsolateEvent => (super.noSuchMethod(
+ Invocation.getter(#onIsolateEvent),
+ returnValue: _i3.Stream<_i2.Event>.empty(),
+ ) as _i3.Stream<_i2.Event>);
+
+ @override
+ _i3.Stream<_i2.Event> get onDebugEvent => (super.noSuchMethod(
+ Invocation.getter(#onDebugEvent),
+ returnValue: _i3.Stream<_i2.Event>.empty(),
+ ) as _i3.Stream<_i2.Event>);
+
+ @override
+ _i3.Stream<_i2.Event> get onProfilerEvent => (super.noSuchMethod(
+ Invocation.getter(#onProfilerEvent),
+ returnValue: _i3.Stream<_i2.Event>.empty(),
+ ) as _i3.Stream<_i2.Event>);
+
+ @override
+ _i3.Stream<_i2.Event> get onGCEvent => (super.noSuchMethod(
+ Invocation.getter(#onGCEvent),
+ returnValue: _i3.Stream<_i2.Event>.empty(),
+ ) as _i3.Stream<_i2.Event>);
+
+ @override
+ _i3.Stream<_i2.Event> get onExtensionEvent => (super.noSuchMethod(
+ Invocation.getter(#onExtensionEvent),
+ returnValue: _i3.Stream<_i2.Event>.empty(),
+ ) as _i3.Stream<_i2.Event>);
+
+ @override
+ _i3.Stream<_i2.Event> get onTimelineEvent => (super.noSuchMethod(
+ Invocation.getter(#onTimelineEvent),
+ returnValue: _i3.Stream<_i2.Event>.empty(),
+ ) as _i3.Stream<_i2.Event>);
+
+ @override
+ _i3.Stream<_i2.Event> get onLoggingEvent => (super.noSuchMethod(
+ Invocation.getter(#onLoggingEvent),
+ returnValue: _i3.Stream<_i2.Event>.empty(),
+ ) as _i3.Stream<_i2.Event>);
+
+ @override
+ _i3.Stream<_i2.Event> get onServiceEvent => (super.noSuchMethod(
+ Invocation.getter(#onServiceEvent),
+ returnValue: _i3.Stream<_i2.Event>.empty(),
+ ) as _i3.Stream<_i2.Event>);
+
+ @override
+ _i3.Stream<_i2.Event> get onHeapSnapshotEvent => (super.noSuchMethod(
+ Invocation.getter(#onHeapSnapshotEvent),
+ returnValue: _i3.Stream<_i2.Event>.empty(),
+ ) as _i3.Stream<_i2.Event>);
+
+ @override
+ _i3.Stream<_i2.Event> get onStdoutEvent => (super.noSuchMethod(
+ Invocation.getter(#onStdoutEvent),
+ returnValue: _i3.Stream<_i2.Event>.empty(),
+ ) as _i3.Stream<_i2.Event>);
+
+ @override
+ _i3.Stream<_i2.Event> get onStderrEvent => (super.noSuchMethod(
+ Invocation.getter(#onStderrEvent),
+ returnValue: _i3.Stream<_i2.Event>.empty(),
+ ) as _i3.Stream<_i2.Event>);
+
+ @override
+ _i3.Stream<_i2.Event> onEvent(String? streamId) => (super.noSuchMethod(
+ Invocation.method(
+ #onEvent,
+ [streamId],
+ ),
+ returnValue: _i3.Stream<_i2.Event>.empty(),
+ ) as _i3.Stream<_i2.Event>);
+
+ @override
+ _i3.Future<_i2.Breakpoint> addBreakpoint(
+ String? isolateId,
+ String? scriptId,
+ int? line, {
+ int? column,
+ }) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #addBreakpoint,
+ [
+ isolateId,
+ scriptId,
+ line,
+ ],
+ {#column: column},
+ ),
+ returnValue: _i3.Future<_i2.Breakpoint>.value(_FakeBreakpoint_0(
+ this,
+ Invocation.method(
+ #addBreakpoint,
+ [
+ isolateId,
+ scriptId,
+ line,
+ ],
+ {#column: column},
+ ),
+ )),
+ ) as _i3.Future<_i2.Breakpoint>);
+
+ @override
+ _i3.Future<_i2.Breakpoint> addBreakpointWithScriptUri(
+ String? isolateId,
+ String? scriptUri,
+ int? line, {
+ int? column,
+ }) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #addBreakpointWithScriptUri,
+ [
+ isolateId,
+ scriptUri,
+ line,
+ ],
+ {#column: column},
+ ),
+ returnValue: _i3.Future<_i2.Breakpoint>.value(_FakeBreakpoint_0(
+ this,
+ Invocation.method(
+ #addBreakpointWithScriptUri,
+ [
+ isolateId,
+ scriptUri,
+ line,
+ ],
+ {#column: column},
+ ),
+ )),
+ ) as _i3.Future<_i2.Breakpoint>);
+
+ @override
+ _i3.Future<_i2.Breakpoint> addBreakpointAtEntry(
+ String? isolateId,
+ String? functionId,
+ ) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #addBreakpointAtEntry,
+ [
+ isolateId,
+ functionId,
+ ],
+ ),
+ returnValue: _i3.Future<_i2.Breakpoint>.value(_FakeBreakpoint_0(
+ this,
+ Invocation.method(
+ #addBreakpointAtEntry,
+ [
+ isolateId,
+ functionId,
+ ],
+ ),
+ )),
+ ) as _i3.Future<_i2.Breakpoint>);
+
+ @override
+ _i3.Future<_i2.Success> clearCpuSamples(String? isolateId) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #clearCpuSamples,
+ [isolateId],
+ ),
+ returnValue: _i3.Future<_i2.Success>.value(_FakeSuccess_1(
+ this,
+ Invocation.method(
+ #clearCpuSamples,
+ [isolateId],
+ ),
+ )),
+ ) as _i3.Future<_i2.Success>);
+
+ @override
+ _i3.Future<_i2.Success> clearVMTimeline() => (super.noSuchMethod(
+ Invocation.method(
+ #clearVMTimeline,
+ [],
+ ),
+ returnValue: _i3.Future<_i2.Success>.value(_FakeSuccess_1(
+ this,
+ Invocation.method(
+ #clearVMTimeline,
+ [],
+ ),
+ )),
+ ) as _i3.Future<_i2.Success>);
+
+ @override
+ _i3.Future<_i2.IdZone> createIdZone(
+ String? isolateId,
+ String? backingBufferKind,
+ String? idAssignmentPolicy, {
+ int? capacity,
+ }) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #createIdZone,
+ [
+ isolateId,
+ backingBufferKind,
+ idAssignmentPolicy,
+ ],
+ {#capacity: capacity},
+ ),
+ returnValue: _i3.Future<_i2.IdZone>.value(_FakeIdZone_2(
+ this,
+ Invocation.method(
+ #createIdZone,
+ [
+ isolateId,
+ backingBufferKind,
+ idAssignmentPolicy,
+ ],
+ {#capacity: capacity},
+ ),
+ )),
+ ) as _i3.Future<_i2.IdZone>);
+
+ @override
+ _i3.Future<_i2.Success> deleteIdZone(
+ String? isolateId,
+ String? idZoneId,
+ ) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #deleteIdZone,
+ [
+ isolateId,
+ idZoneId,
+ ],
+ ),
+ returnValue: _i3.Future<_i2.Success>.value(_FakeSuccess_1(
+ this,
+ Invocation.method(
+ #deleteIdZone,
+ [
+ isolateId,
+ idZoneId,
+ ],
+ ),
+ )),
+ ) as _i3.Future<_i2.Success>);
+
+ @override
+ _i3.Future<_i2.Success> invalidateIdZone(
+ String? isolateId,
+ String? idZoneId,
+ ) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #invalidateIdZone,
+ [
+ isolateId,
+ idZoneId,
+ ],
+ ),
+ returnValue: _i3.Future<_i2.Success>.value(_FakeSuccess_1(
+ this,
+ Invocation.method(
+ #invalidateIdZone,
+ [
+ isolateId,
+ idZoneId,
+ ],
+ ),
+ )),
+ ) as _i3.Future<_i2.Success>);
+
+ @override
+ _i3.Future<_i2.Response> invoke(
+ String? isolateId,
+ String? targetId,
+ String? selector,
+ List<String>? argumentIds, {
+ bool? disableBreakpoints,
+ String? idZoneId,
+ }) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #invoke,
+ [
+ isolateId,
+ targetId,
+ selector,
+ argumentIds,
+ ],
+ {
+ #disableBreakpoints: disableBreakpoints,
+ #idZoneId: idZoneId,
+ },
+ ),
+ returnValue: _i3.Future<_i2.Response>.value(_FakeResponse_3(
+ this,
+ Invocation.method(
+ #invoke,
+ [
+ isolateId,
+ targetId,
+ selector,
+ argumentIds,
+ ],
+ {
+ #disableBreakpoints: disableBreakpoints,
+ #idZoneId: idZoneId,
+ },
+ ),
+ )),
+ ) as _i3.Future<_i2.Response>);
+
+ @override
+ _i3.Future<_i2.Response> evaluate(
+ String? isolateId,
+ String? targetId,
+ String? expression, {
+ Map<String, String>? scope,
+ bool? disableBreakpoints,
+ String? idZoneId,
+ }) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #evaluate,
+ [
+ isolateId,
+ targetId,
+ expression,
+ ],
+ {
+ #scope: scope,
+ #disableBreakpoints: disableBreakpoints,
+ #idZoneId: idZoneId,
+ },
+ ),
+ returnValue: _i3.Future<_i2.Response>.value(_FakeResponse_3(
+ this,
+ Invocation.method(
+ #evaluate,
+ [
+ isolateId,
+ targetId,
+ expression,
+ ],
+ {
+ #scope: scope,
+ #disableBreakpoints: disableBreakpoints,
+ #idZoneId: idZoneId,
+ },
+ ),
+ )),
+ ) as _i3.Future<_i2.Response>);
+
+ @override
+ _i3.Future<_i2.Response> evaluateInFrame(
+ String? isolateId,
+ int? frameIndex,
+ String? expression, {
+ Map<String, String>? scope,
+ bool? disableBreakpoints,
+ String? idZoneId,
+ }) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #evaluateInFrame,
+ [
+ isolateId,
+ frameIndex,
+ expression,
+ ],
+ {
+ #scope: scope,
+ #disableBreakpoints: disableBreakpoints,
+ #idZoneId: idZoneId,
+ },
+ ),
+ returnValue: _i3.Future<_i2.Response>.value(_FakeResponse_3(
+ this,
+ Invocation.method(
+ #evaluateInFrame,
+ [
+ isolateId,
+ frameIndex,
+ expression,
+ ],
+ {
+ #scope: scope,
+ #disableBreakpoints: disableBreakpoints,
+ #idZoneId: idZoneId,
+ },
+ ),
+ )),
+ ) as _i3.Future<_i2.Response>);
+
+ @override
+ _i3.Future<_i2.AllocationProfile> getAllocationProfile(
+ String? isolateId, {
+ bool? reset,
+ bool? gc,
+ }) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #getAllocationProfile,
+ [isolateId],
+ {
+ #reset: reset,
+ #gc: gc,
+ },
+ ),
+ returnValue:
+ _i3.Future<_i2.AllocationProfile>.value(_FakeAllocationProfile_4(
+ this,
+ Invocation.method(
+ #getAllocationProfile,
+ [isolateId],
+ {
+ #reset: reset,
+ #gc: gc,
+ },
+ ),
+ )),
+ ) as _i3.Future<_i2.AllocationProfile>);
+
+ @override
+ _i3.Future<_i2.CpuSamples> getAllocationTraces(
+ String? isolateId, {
+ int? timeOriginMicros,
+ int? timeExtentMicros,
+ String? classId,
+ }) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #getAllocationTraces,
+ [isolateId],
+ {
+ #timeOriginMicros: timeOriginMicros,
+ #timeExtentMicros: timeExtentMicros,
+ #classId: classId,
+ },
+ ),
+ returnValue: _i3.Future<_i2.CpuSamples>.value(_FakeCpuSamples_5(
+ this,
+ Invocation.method(
+ #getAllocationTraces,
+ [isolateId],
+ {
+ #timeOriginMicros: timeOriginMicros,
+ #timeExtentMicros: timeExtentMicros,
+ #classId: classId,
+ },
+ ),
+ )),
+ ) as _i3.Future<_i2.CpuSamples>);
+
+ @override
+ _i3.Future<_i2.ClassList> getClassList(String? isolateId) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #getClassList,
+ [isolateId],
+ ),
+ returnValue: _i3.Future<_i2.ClassList>.value(_FakeClassList_6(
+ this,
+ Invocation.method(
+ #getClassList,
+ [isolateId],
+ ),
+ )),
+ ) as _i3.Future<_i2.ClassList>);
+
+ @override
+ _i3.Future<_i2.CpuSamples> getCpuSamples(
+ String? isolateId,
+ int? timeOriginMicros,
+ int? timeExtentMicros,
+ ) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #getCpuSamples,
+ [
+ isolateId,
+ timeOriginMicros,
+ timeExtentMicros,
+ ],
+ ),
+ returnValue: _i3.Future<_i2.CpuSamples>.value(_FakeCpuSamples_5(
+ this,
+ Invocation.method(
+ #getCpuSamples,
+ [
+ isolateId,
+ timeOriginMicros,
+ timeExtentMicros,
+ ],
+ ),
+ )),
+ ) as _i3.Future<_i2.CpuSamples>);
+
+ @override
+ _i3.Future<_i2.FlagList> getFlagList() => (super.noSuchMethod(
+ Invocation.method(
+ #getFlagList,
+ [],
+ ),
+ returnValue: _i3.Future<_i2.FlagList>.value(_FakeFlagList_7(
+ this,
+ Invocation.method(
+ #getFlagList,
+ [],
+ ),
+ )),
+ ) as _i3.Future<_i2.FlagList>);
+
+ @override
+ _i3.Future<_i2.InboundReferences> getInboundReferences(
+ String? isolateId,
+ String? targetId,
+ int? limit, {
+ String? idZoneId,
+ }) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #getInboundReferences,
+ [
+ isolateId,
+ targetId,
+ limit,
+ ],
+ {#idZoneId: idZoneId},
+ ),
+ returnValue:
+ _i3.Future<_i2.InboundReferences>.value(_FakeInboundReferences_8(
+ this,
+ Invocation.method(
+ #getInboundReferences,
+ [
+ isolateId,
+ targetId,
+ limit,
+ ],
+ {#idZoneId: idZoneId},
+ ),
+ )),
+ ) as _i3.Future<_i2.InboundReferences>);
+
+ @override
+ _i3.Future<_i2.InstanceSet> getInstances(
+ String? isolateId,
+ String? objectId,
+ int? limit, {
+ bool? includeSubclasses,
+ bool? includeImplementers,
+ String? idZoneId,
+ }) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #getInstances,
+ [
+ isolateId,
+ objectId,
+ limit,
+ ],
+ {
+ #includeSubclasses: includeSubclasses,
+ #includeImplementers: includeImplementers,
+ #idZoneId: idZoneId,
+ },
+ ),
+ returnValue: _i3.Future<_i2.InstanceSet>.value(_FakeInstanceSet_9(
+ this,
+ Invocation.method(
+ #getInstances,
+ [
+ isolateId,
+ objectId,
+ limit,
+ ],
+ {
+ #includeSubclasses: includeSubclasses,
+ #includeImplementers: includeImplementers,
+ #idZoneId: idZoneId,
+ },
+ ),
+ )),
+ ) as _i3.Future<_i2.InstanceSet>);
+
+ @override
+ _i3.Future<_i2.InstanceRef> getInstancesAsList(
+ String? isolateId,
+ String? objectId, {
+ bool? includeSubclasses,
+ bool? includeImplementers,
+ String? idZoneId,
+ }) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #getInstancesAsList,
+ [
+ isolateId,
+ objectId,
+ ],
+ {
+ #includeSubclasses: includeSubclasses,
+ #includeImplementers: includeImplementers,
+ #idZoneId: idZoneId,
+ },
+ ),
+ returnValue: _i3.Future<_i2.InstanceRef>.value(_FakeInstanceRef_10(
+ this,
+ Invocation.method(
+ #getInstancesAsList,
+ [
+ isolateId,
+ objectId,
+ ],
+ {
+ #includeSubclasses: includeSubclasses,
+ #includeImplementers: includeImplementers,
+ #idZoneId: idZoneId,
+ },
+ ),
+ )),
+ ) as _i3.Future<_i2.InstanceRef>);
+
+ @override
+ _i3.Future<_i2.Isolate> getIsolate(String? isolateId) => (super.noSuchMethod(
+ Invocation.method(
+ #getIsolate,
+ [isolateId],
+ ),
+ returnValue: _i3.Future<_i2.Isolate>.value(_FakeIsolate_11(
+ this,
+ Invocation.method(
+ #getIsolate,
+ [isolateId],
+ ),
+ )),
+ ) as _i3.Future<_i2.Isolate>);
+
+ @override
+ _i3.Future<_i2.IsolateGroup> getIsolateGroup(String? isolateGroupId) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #getIsolateGroup,
+ [isolateGroupId],
+ ),
+ returnValue: _i3.Future<_i2.IsolateGroup>.value(_FakeIsolateGroup_12(
+ this,
+ Invocation.method(
+ #getIsolateGroup,
+ [isolateGroupId],
+ ),
+ )),
+ ) as _i3.Future<_i2.IsolateGroup>);
+
+ @override
+ _i3.Future<_i2.Event> getIsolatePauseEvent(String? isolateId) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #getIsolatePauseEvent,
+ [isolateId],
+ ),
+ returnValue: _i3.Future<_i2.Event>.value(_FakeEvent_13(
+ this,
+ Invocation.method(
+ #getIsolatePauseEvent,
+ [isolateId],
+ ),
+ )),
+ ) as _i3.Future<_i2.Event>);
+
+ @override
+ _i3.Future<_i2.MemoryUsage> getMemoryUsage(String? isolateId) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #getMemoryUsage,
+ [isolateId],
+ ),
+ returnValue: _i3.Future<_i2.MemoryUsage>.value(_FakeMemoryUsage_14(
+ this,
+ Invocation.method(
+ #getMemoryUsage,
+ [isolateId],
+ ),
+ )),
+ ) as _i3.Future<_i2.MemoryUsage>);
+
+ @override
+ _i3.Future<_i2.MemoryUsage> getIsolateGroupMemoryUsage(
+ String? isolateGroupId) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #getIsolateGroupMemoryUsage,
+ [isolateGroupId],
+ ),
+ returnValue: _i3.Future<_i2.MemoryUsage>.value(_FakeMemoryUsage_14(
+ this,
+ Invocation.method(
+ #getIsolateGroupMemoryUsage,
+ [isolateGroupId],
+ ),
+ )),
+ ) as _i3.Future<_i2.MemoryUsage>);
+
+ @override
+ _i3.Future<_i2.ScriptList> getScripts(String? isolateId) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #getScripts,
+ [isolateId],
+ ),
+ returnValue: _i3.Future<_i2.ScriptList>.value(_FakeScriptList_15(
+ this,
+ Invocation.method(
+ #getScripts,
+ [isolateId],
+ ),
+ )),
+ ) as _i3.Future<_i2.ScriptList>);
+
+ @override
+ _i3.Future<_i2.Obj> getObject(
+ String? isolateId,
+ String? objectId, {
+ int? offset,
+ int? count,
+ String? idZoneId,
+ }) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #getObject,
+ [
+ isolateId,
+ objectId,
+ ],
+ {
+ #offset: offset,
+ #count: count,
+ #idZoneId: idZoneId,
+ },
+ ),
+ returnValue: _i3.Future<_i2.Obj>.value(_FakeObj_16(
+ this,
+ Invocation.method(
+ #getObject,
+ [
+ isolateId,
+ objectId,
+ ],
+ {
+ #offset: offset,
+ #count: count,
+ #idZoneId: idZoneId,
+ },
+ ),
+ )),
+ ) as _i3.Future<_i2.Obj>);
+
+ @override
+ _i3.Future<_i2.PerfettoCpuSamples> getPerfettoCpuSamples(
+ String? isolateId, {
+ int? timeOriginMicros,
+ int? timeExtentMicros,
+ }) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #getPerfettoCpuSamples,
+ [isolateId],
+ {
+ #timeOriginMicros: timeOriginMicros,
+ #timeExtentMicros: timeExtentMicros,
+ },
+ ),
+ returnValue:
+ _i3.Future<_i2.PerfettoCpuSamples>.value(_FakePerfettoCpuSamples_17(
+ this,
+ Invocation.method(
+ #getPerfettoCpuSamples,
+ [isolateId],
+ {
+ #timeOriginMicros: timeOriginMicros,
+ #timeExtentMicros: timeExtentMicros,
+ },
+ ),
+ )),
+ ) as _i3.Future<_i2.PerfettoCpuSamples>);
+
+ @override
+ _i3.Future<_i2.PerfettoTimeline> getPerfettoVMTimeline({
+ int? timeOriginMicros,
+ int? timeExtentMicros,
+ }) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #getPerfettoVMTimeline,
+ [],
+ {
+ #timeOriginMicros: timeOriginMicros,
+ #timeExtentMicros: timeExtentMicros,
+ },
+ ),
+ returnValue:
+ _i3.Future<_i2.PerfettoTimeline>.value(_FakePerfettoTimeline_18(
+ this,
+ Invocation.method(
+ #getPerfettoVMTimeline,
+ [],
+ {
+ #timeOriginMicros: timeOriginMicros,
+ #timeExtentMicros: timeExtentMicros,
+ },
+ ),
+ )),
+ ) as _i3.Future<_i2.PerfettoTimeline>);
+
+ @override
+ _i3.Future<_i2.PortList> getPorts(String? isolateId) => (super.noSuchMethod(
+ Invocation.method(
+ #getPorts,
+ [isolateId],
+ ),
+ returnValue: _i3.Future<_i2.PortList>.value(_FakePortList_19(
+ this,
+ Invocation.method(
+ #getPorts,
+ [isolateId],
+ ),
+ )),
+ ) as _i3.Future<_i2.PortList>);
+
+ @override
+ _i3.Future<_i2.RetainingPath> getRetainingPath(
+ String? isolateId,
+ String? targetId,
+ int? limit, {
+ String? idZoneId,
+ }) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #getRetainingPath,
+ [
+ isolateId,
+ targetId,
+ limit,
+ ],
+ {#idZoneId: idZoneId},
+ ),
+ returnValue: _i3.Future<_i2.RetainingPath>.value(_FakeRetainingPath_20(
+ this,
+ Invocation.method(
+ #getRetainingPath,
+ [
+ isolateId,
+ targetId,
+ limit,
+ ],
+ {#idZoneId: idZoneId},
+ ),
+ )),
+ ) as _i3.Future<_i2.RetainingPath>);
+
+ @override
+ _i3.Future<_i2.ProcessMemoryUsage> getProcessMemoryUsage() =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #getProcessMemoryUsage,
+ [],
+ ),
+ returnValue:
+ _i3.Future<_i2.ProcessMemoryUsage>.value(_FakeProcessMemoryUsage_21(
+ this,
+ Invocation.method(
+ #getProcessMemoryUsage,
+ [],
+ ),
+ )),
+ ) as _i3.Future<_i2.ProcessMemoryUsage>);
+
+ @override
+ _i3.Future<_i2.Stack> getStack(
+ String? isolateId, {
+ int? limit,
+ String? idZoneId,
+ }) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #getStack,
+ [isolateId],
+ {
+ #limit: limit,
+ #idZoneId: idZoneId,
+ },
+ ),
+ returnValue: _i3.Future<_i2.Stack>.value(_FakeStack_22(
+ this,
+ Invocation.method(
+ #getStack,
+ [isolateId],
+ {
+ #limit: limit,
+ #idZoneId: idZoneId,
+ },
+ ),
+ )),
+ ) as _i3.Future<_i2.Stack>);
+
+ @override
+ _i3.Future<_i2.ProtocolList> getSupportedProtocols() => (super.noSuchMethod(
+ Invocation.method(
+ #getSupportedProtocols,
+ [],
+ ),
+ returnValue: _i3.Future<_i2.ProtocolList>.value(_FakeProtocolList_23(
+ this,
+ Invocation.method(
+ #getSupportedProtocols,
+ [],
+ ),
+ )),
+ ) as _i3.Future<_i2.ProtocolList>);
+
+ @override
+ _i3.Future<_i2.SourceReport> getSourceReport(
+ String? isolateId,
+ List<String>? reports, {
+ String? scriptId,
+ int? tokenPos,
+ int? endTokenPos,
+ bool? forceCompile,
+ bool? reportLines,
+ List<String>? libraryFilters,
+ List<String>? librariesAlreadyCompiled,
+ }) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #getSourceReport,
+ [
+ isolateId,
+ reports,
+ ],
+ {
+ #scriptId: scriptId,
+ #tokenPos: tokenPos,
+ #endTokenPos: endTokenPos,
+ #forceCompile: forceCompile,
+ #reportLines: reportLines,
+ #libraryFilters: libraryFilters,
+ #librariesAlreadyCompiled: librariesAlreadyCompiled,
+ },
+ ),
+ returnValue: _i3.Future<_i2.SourceReport>.value(_FakeSourceReport_24(
+ this,
+ Invocation.method(
+ #getSourceReport,
+ [
+ isolateId,
+ reports,
+ ],
+ {
+ #scriptId: scriptId,
+ #tokenPos: tokenPos,
+ #endTokenPos: endTokenPos,
+ #forceCompile: forceCompile,
+ #reportLines: reportLines,
+ #libraryFilters: libraryFilters,
+ #librariesAlreadyCompiled: librariesAlreadyCompiled,
+ },
+ ),
+ )),
+ ) as _i3.Future<_i2.SourceReport>);
+
+ @override
+ _i3.Future<_i2.Version> getVersion() => (super.noSuchMethod(
+ Invocation.method(
+ #getVersion,
+ [],
+ ),
+ returnValue: _i3.Future<_i2.Version>.value(_FakeVersion_25(
+ this,
+ Invocation.method(
+ #getVersion,
+ [],
+ ),
+ )),
+ ) as _i3.Future<_i2.Version>);
+
+ @override
+ _i3.Future<_i2.VM> getVM() => (super.noSuchMethod(
+ Invocation.method(
+ #getVM,
+ [],
+ ),
+ returnValue: _i3.Future<_i2.VM>.value(_FakeVM_26(
+ this,
+ Invocation.method(
+ #getVM,
+ [],
+ ),
+ )),
+ ) as _i3.Future<_i2.VM>);
+
+ @override
+ _i3.Future<_i2.Timeline> getVMTimeline({
+ int? timeOriginMicros,
+ int? timeExtentMicros,
+ }) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #getVMTimeline,
+ [],
+ {
+ #timeOriginMicros: timeOriginMicros,
+ #timeExtentMicros: timeExtentMicros,
+ },
+ ),
+ returnValue: _i3.Future<_i2.Timeline>.value(_FakeTimeline_27(
+ this,
+ Invocation.method(
+ #getVMTimeline,
+ [],
+ {
+ #timeOriginMicros: timeOriginMicros,
+ #timeExtentMicros: timeExtentMicros,
+ },
+ ),
+ )),
+ ) as _i3.Future<_i2.Timeline>);
+
+ @override
+ _i3.Future<_i2.TimelineFlags> getVMTimelineFlags() => (super.noSuchMethod(
+ Invocation.method(
+ #getVMTimelineFlags,
+ [],
+ ),
+ returnValue: _i3.Future<_i2.TimelineFlags>.value(_FakeTimelineFlags_28(
+ this,
+ Invocation.method(
+ #getVMTimelineFlags,
+ [],
+ ),
+ )),
+ ) as _i3.Future<_i2.TimelineFlags>);
+
+ @override
+ _i3.Future<_i2.Timestamp> getVMTimelineMicros() => (super.noSuchMethod(
+ Invocation.method(
+ #getVMTimelineMicros,
+ [],
+ ),
+ returnValue: _i3.Future<_i2.Timestamp>.value(_FakeTimestamp_29(
+ this,
+ Invocation.method(
+ #getVMTimelineMicros,
+ [],
+ ),
+ )),
+ ) as _i3.Future<_i2.Timestamp>);
+
+ @override
+ _i3.Future<_i2.Success> pause(String? isolateId) => (super.noSuchMethod(
+ Invocation.method(
+ #pause,
+ [isolateId],
+ ),
+ returnValue: _i3.Future<_i2.Success>.value(_FakeSuccess_1(
+ this,
+ Invocation.method(
+ #pause,
+ [isolateId],
+ ),
+ )),
+ ) as _i3.Future<_i2.Success>);
+
+ @override
+ _i3.Future<_i2.Success> kill(String? isolateId) => (super.noSuchMethod(
+ Invocation.method(
+ #kill,
+ [isolateId],
+ ),
+ returnValue: _i3.Future<_i2.Success>.value(_FakeSuccess_1(
+ this,
+ Invocation.method(
+ #kill,
+ [isolateId],
+ ),
+ )),
+ ) as _i3.Future<_i2.Success>);
+
+ @override
+ _i3.Future<_i2.UriList> lookupResolvedPackageUris(
+ String? isolateId,
+ List<String>? uris, {
+ bool? local,
+ }) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #lookupResolvedPackageUris,
+ [
+ isolateId,
+ uris,
+ ],
+ {#local: local},
+ ),
+ returnValue: _i3.Future<_i2.UriList>.value(_FakeUriList_30(
+ this,
+ Invocation.method(
+ #lookupResolvedPackageUris,
+ [
+ isolateId,
+ uris,
+ ],
+ {#local: local},
+ ),
+ )),
+ ) as _i3.Future<_i2.UriList>);
+
+ @override
+ _i3.Future<_i2.UriList> lookupPackageUris(
+ String? isolateId,
+ List<String>? uris,
+ ) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #lookupPackageUris,
+ [
+ isolateId,
+ uris,
+ ],
+ ),
+ returnValue: _i3.Future<_i2.UriList>.value(_FakeUriList_30(
+ this,
+ Invocation.method(
+ #lookupPackageUris,
+ [
+ isolateId,
+ uris,
+ ],
+ ),
+ )),
+ ) as _i3.Future<_i2.UriList>);
+
+ @override
+ _i3.Future<_i2.Success> registerService(
+ String? service,
+ String? alias,
+ ) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #registerService,
+ [
+ service,
+ alias,
+ ],
+ ),
+ returnValue: _i3.Future<_i2.Success>.value(_FakeSuccess_1(
+ this,
+ Invocation.method(
+ #registerService,
+ [
+ service,
+ alias,
+ ],
+ ),
+ )),
+ ) as _i3.Future<_i2.Success>);
+
+ @override
+ _i3.Future<_i2.ReloadReport> reloadSources(
+ String? isolateId, {
+ bool? force,
+ bool? pause,
+ String? rootLibUri,
+ String? packagesUri,
+ }) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #reloadSources,
+ [isolateId],
+ {
+ #force: force,
+ #pause: pause,
+ #rootLibUri: rootLibUri,
+ #packagesUri: packagesUri,
+ },
+ ),
+ returnValue: _i3.Future<_i2.ReloadReport>.value(_FakeReloadReport_31(
+ this,
+ Invocation.method(
+ #reloadSources,
+ [isolateId],
+ {
+ #force: force,
+ #pause: pause,
+ #rootLibUri: rootLibUri,
+ #packagesUri: packagesUri,
+ },
+ ),
+ )),
+ ) as _i3.Future<_i2.ReloadReport>);
+
+ @override
+ _i3.Future<_i2.Success> removeBreakpoint(
+ String? isolateId,
+ String? breakpointId,
+ ) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #removeBreakpoint,
+ [
+ isolateId,
+ breakpointId,
+ ],
+ ),
+ returnValue: _i3.Future<_i2.Success>.value(_FakeSuccess_1(
+ this,
+ Invocation.method(
+ #removeBreakpoint,
+ [
+ isolateId,
+ breakpointId,
+ ],
+ ),
+ )),
+ ) as _i3.Future<_i2.Success>);
+
+ @override
+ _i3.Future<_i2.Success> requestHeapSnapshot(String? isolateId) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #requestHeapSnapshot,
+ [isolateId],
+ ),
+ returnValue: _i3.Future<_i2.Success>.value(_FakeSuccess_1(
+ this,
+ Invocation.method(
+ #requestHeapSnapshot,
+ [isolateId],
+ ),
+ )),
+ ) as _i3.Future<_i2.Success>);
+
+ @override
+ _i3.Future<_i2.Success> resume(
+ String? isolateId, {
+ String? step,
+ int? frameIndex,
+ }) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #resume,
+ [isolateId],
+ {
+ #step: step,
+ #frameIndex: frameIndex,
+ },
+ ),
+ returnValue: _i3.Future<_i2.Success>.value(_FakeSuccess_1(
+ this,
+ Invocation.method(
+ #resume,
+ [isolateId],
+ {
+ #step: step,
+ #frameIndex: frameIndex,
+ },
+ ),
+ )),
+ ) as _i3.Future<_i2.Success>);
+
+ @override
+ _i3.Future<_i2.Breakpoint> setBreakpointState(
+ String? isolateId,
+ String? breakpointId,
+ bool? enable,
+ ) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #setBreakpointState,
+ [
+ isolateId,
+ breakpointId,
+ enable,
+ ],
+ ),
+ returnValue: _i3.Future<_i2.Breakpoint>.value(_FakeBreakpoint_0(
+ this,
+ Invocation.method(
+ #setBreakpointState,
+ [
+ isolateId,
+ breakpointId,
+ enable,
+ ],
+ ),
+ )),
+ ) as _i3.Future<_i2.Breakpoint>);
+
+ @override
+ _i3.Future<_i2.Success> setExceptionPauseMode(
+ String? isolateId,
+ String? mode,
+ ) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #setExceptionPauseMode,
+ [
+ isolateId,
+ mode,
+ ],
+ ),
+ returnValue: _i3.Future<_i2.Success>.value(_FakeSuccess_1(
+ this,
+ Invocation.method(
+ #setExceptionPauseMode,
+ [
+ isolateId,
+ mode,
+ ],
+ ),
+ )),
+ ) as _i3.Future<_i2.Success>);
+
+ @override
+ _i3.Future<_i2.Success> setIsolatePauseMode(
+ String? isolateId, {
+ String? exceptionPauseMode,
+ bool? shouldPauseOnExit,
+ }) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #setIsolatePauseMode,
+ [isolateId],
+ {
+ #exceptionPauseMode: exceptionPauseMode,
+ #shouldPauseOnExit: shouldPauseOnExit,
+ },
+ ),
+ returnValue: _i3.Future<_i2.Success>.value(_FakeSuccess_1(
+ this,
+ Invocation.method(
+ #setIsolatePauseMode,
+ [isolateId],
+ {
+ #exceptionPauseMode: exceptionPauseMode,
+ #shouldPauseOnExit: shouldPauseOnExit,
+ },
+ ),
+ )),
+ ) as _i3.Future<_i2.Success>);
+
+ @override
+ _i3.Future<_i2.Response> setFlag(
+ String? name,
+ String? value,
+ ) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #setFlag,
+ [
+ name,
+ value,
+ ],
+ ),
+ returnValue: _i3.Future<_i2.Response>.value(_FakeResponse_3(
+ this,
+ Invocation.method(
+ #setFlag,
+ [
+ name,
+ value,
+ ],
+ ),
+ )),
+ ) as _i3.Future<_i2.Response>);
+
+ @override
+ _i3.Future<_i2.Success> setLibraryDebuggable(
+ String? isolateId,
+ String? libraryId,
+ bool? isDebuggable,
+ ) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #setLibraryDebuggable,
+ [
+ isolateId,
+ libraryId,
+ isDebuggable,
+ ],
+ ),
+ returnValue: _i3.Future<_i2.Success>.value(_FakeSuccess_1(
+ this,
+ Invocation.method(
+ #setLibraryDebuggable,
+ [
+ isolateId,
+ libraryId,
+ isDebuggable,
+ ],
+ ),
+ )),
+ ) as _i3.Future<_i2.Success>);
+
+ @override
+ _i3.Future<_i2.Success> setName(
+ String? isolateId,
+ String? name,
+ ) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #setName,
+ [
+ isolateId,
+ name,
+ ],
+ ),
+ returnValue: _i3.Future<_i2.Success>.value(_FakeSuccess_1(
+ this,
+ Invocation.method(
+ #setName,
+ [
+ isolateId,
+ name,
+ ],
+ ),
+ )),
+ ) as _i3.Future<_i2.Success>);
+
+ @override
+ _i3.Future<_i2.Success> setTraceClassAllocation(
+ String? isolateId,
+ String? classId,
+ bool? enable,
+ ) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #setTraceClassAllocation,
+ [
+ isolateId,
+ classId,
+ enable,
+ ],
+ ),
+ returnValue: _i3.Future<_i2.Success>.value(_FakeSuccess_1(
+ this,
+ Invocation.method(
+ #setTraceClassAllocation,
+ [
+ isolateId,
+ classId,
+ enable,
+ ],
+ ),
+ )),
+ ) as _i3.Future<_i2.Success>);
+
+ @override
+ _i3.Future<_i2.Success> setVMName(String? name) => (super.noSuchMethod(
+ Invocation.method(
+ #setVMName,
+ [name],
+ ),
+ returnValue: _i3.Future<_i2.Success>.value(_FakeSuccess_1(
+ this,
+ Invocation.method(
+ #setVMName,
+ [name],
+ ),
+ )),
+ ) as _i3.Future<_i2.Success>);
+
+ @override
+ _i3.Future<_i2.Success> setVMTimelineFlags(List<String>? recordedStreams) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #setVMTimelineFlags,
+ [recordedStreams],
+ ),
+ returnValue: _i3.Future<_i2.Success>.value(_FakeSuccess_1(
+ this,
+ Invocation.method(
+ #setVMTimelineFlags,
+ [recordedStreams],
+ ),
+ )),
+ ) as _i3.Future<_i2.Success>);
+
+ @override
+ _i3.Future<_i2.Success> streamCancel(String? streamId) => (super.noSuchMethod(
+ Invocation.method(
+ #streamCancel,
+ [streamId],
+ ),
+ returnValue: _i3.Future<_i2.Success>.value(_FakeSuccess_1(
+ this,
+ Invocation.method(
+ #streamCancel,
+ [streamId],
+ ),
+ )),
+ ) as _i3.Future<_i2.Success>);
+
+ @override
+ _i3.Future<_i2.Success> streamCpuSamplesWithUserTag(List<String>? userTags) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #streamCpuSamplesWithUserTag,
+ [userTags],
+ ),
+ returnValue: _i3.Future<_i2.Success>.value(_FakeSuccess_1(
+ this,
+ Invocation.method(
+ #streamCpuSamplesWithUserTag,
+ [userTags],
+ ),
+ )),
+ ) as _i3.Future<_i2.Success>);
+
+ @override
+ _i3.Future<_i2.Success> streamListen(String? streamId) => (super.noSuchMethod(
+ Invocation.method(
+ #streamListen,
+ [streamId],
+ ),
+ returnValue: _i3.Future<_i2.Success>.value(_FakeSuccess_1(
+ this,
+ Invocation.method(
+ #streamListen,
+ [streamId],
+ ),
+ )),
+ ) as _i3.Future<_i2.Success>);
+
+ @override
+ _i3.Future<_i2.Response> callMethod(
+ String? method, {
+ String? isolateId,
+ Map<String, dynamic>? args,
+ }) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #callMethod,
+ [method],
+ {
+ #isolateId: isolateId,
+ #args: args,
+ },
+ ),
+ returnValue: _i3.Future<_i2.Response>.value(_FakeResponse_3(
+ this,
+ Invocation.method(
+ #callMethod,
+ [method],
+ {
+ #isolateId: isolateId,
+ #args: args,
+ },
+ ),
+ )),
+ ) as _i3.Future<_i2.Response>);
+
+ @override
+ _i3.Future<_i2.Response> callServiceExtension(
+ String? method, {
+ String? isolateId,
+ Map<String, dynamic>? args,
+ }) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #callServiceExtension,
+ [method],
+ {
+ #isolateId: isolateId,
+ #args: args,
+ },
+ ),
+ returnValue: _i3.Future<_i2.Response>.value(_FakeResponse_3(
+ this,
+ Invocation.method(
+ #callServiceExtension,
+ [method],
+ {
+ #isolateId: isolateId,
+ #args: args,
+ },
+ ),
+ )),
+ ) as _i3.Future<_i2.Response>);
+
+ @override
+ _i3.Future<void> dispose() => (super.noSuchMethod(
+ Invocation.method(
+ #dispose,
+ [],
+ ),
+ returnValue: _i3.Future<void>.value(),
+ returnValueForMissingStub: _i3.Future<void>.value(),
+ ) as _i3.Future<void>);
+
+ @override
+ _i3.Future<T> wrapFuture<T>(
+ String? name,
+ _i3.Future<T>? future,
+ ) =>
+ (super.noSuchMethod(
+ Invocation.method(
+ #wrapFuture,
+ [
+ name,
+ future,
+ ],
+ ),
+ returnValue: _i4.ifNotNull(
+ _i4.dummyValueOrNull<T>(
+ this,
+ Invocation.method(
+ #wrapFuture,
+ [
+ name,
+ future,
+ ],
+ ),
+ ),
+ (T v) => _i3.Future<T>.value(v),
+ ) ??
+ _FakeFuture_32<T>(
+ this,
+ Invocation.method(
+ #wrapFuture,
+ [
+ name,
+ future,
+ ],
+ ),
+ ),
+ ) as _i3.Future<T>);
+
+ @override
+ void registerServiceCallback(
+ String? service,
+ _i2.ServiceCallback? cb,
+ ) =>
+ super.noSuchMethod(
+ Invocation.method(
+ #registerServiceCallback,
+ [
+ service,
+ cb,
+ ],
+ ),
+ returnValueForMissingStub: null,
+ );
+}
diff --git a/pkgs/coverage/test/collect_coverage_test.dart b/pkgs/coverage/test/collect_coverage_test.dart
new file mode 100644
index 0000000..7262757
--- /dev/null
+++ b/pkgs/coverage/test/collect_coverage_test.dart
@@ -0,0 +1,325 @@
+// 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.
+
+@Retry(3)
+library;
+
+import 'dart:async';
+import 'dart:convert' show json;
+import 'dart:io';
+
+import 'package:coverage/coverage.dart';
+import 'package:coverage/src/util.dart';
+import 'package:path/path.dart' as p;
+import 'package:test/test.dart';
+import 'package:test_process/test_process.dart';
+
+import 'test_util.dart';
+
+final _isolateLibPath = p.join('test', 'test_files', 'test_app_isolate.dart');
+final _collectAppPath = p.join('bin', 'collect_coverage.dart');
+
+final _sampleAppFileUri = p.toUri(p.absolute(testAppPath)).toString();
+final _isolateLibFileUri = p.toUri(p.absolute(_isolateLibPath)).toString();
+
+void main() {
+ test('collect_coverage', () async {
+ final resultString = await _getCoverageResult();
+
+ // analyze the output json
+ final coverage =
+ coverageDataFromJson(json.decode(resultString) as Map<String, dynamic>);
+
+ expect(coverage, isNotEmpty);
+
+ final sources = coverage.sources();
+
+ for (var sampleCoverageData in sources[_sampleAppFileUri]!) {
+ expect(sampleCoverageData['hits'], isNotNull);
+ }
+
+ for (var sampleCoverageData in sources[_isolateLibFileUri]!) {
+ expect(sampleCoverageData['hits'], isNotEmpty);
+ }
+ });
+
+ test('createHitmap returns a sorted hitmap', () async {
+ final coverage = [
+ {
+ 'source': 'foo',
+ 'script': '{type: @Script, fixedId: true, '
+ 'id: bar.dart, uri: bar.dart, _kind: library}',
+ 'hits': [
+ 45,
+ 1,
+ 46,
+ 1,
+ 49,
+ 0,
+ 50,
+ 0,
+ 15,
+ 1,
+ 16,
+ 2,
+ 17,
+ 2,
+ ]
+ }
+ ];
+ // ignore: deprecated_member_use_from_same_package
+ final hitMap = await createHitmap(
+ coverage.cast<Map<String, dynamic>>(),
+ );
+ final expectedHits = {15: 1, 16: 2, 17: 2, 45: 1, 46: 1, 49: 0, 50: 0};
+ expect(hitMap['foo'], expectedHits);
+ });
+
+ test('HitMap.parseJson returns a sorted hitmap', () async {
+ final coverage = [
+ {
+ 'source': 'foo',
+ 'script': '{type: @Script, fixedId: true, '
+ 'id: bar.dart, uri: bar.dart, _kind: library}',
+ 'hits': [
+ 45,
+ 1,
+ 46,
+ 1,
+ 49,
+ 0,
+ 50,
+ 0,
+ 15,
+ 1,
+ 16,
+ 2,
+ 17,
+ 2,
+ ]
+ }
+ ];
+ final hitMap = await HitMap.parseJson(
+ coverage.cast<Map<String, dynamic>>(),
+ );
+ final expectedHits = {15: 1, 16: 2, 17: 2, 45: 1, 46: 1, 49: 0, 50: 0};
+ expect(hitMap['foo']?.lineHits, expectedHits);
+ });
+
+ test('HitMap.parseJson', () async {
+ final resultString = await _collectCoverage(true, true);
+ final jsonResult = json.decode(resultString) as Map<String, dynamic>;
+ final coverage = jsonResult['coverage'] as List;
+ final hitMap = await HitMap.parseJson(
+ coverage.cast<Map<String, dynamic>>(),
+ );
+ expect(hitMap, contains(_sampleAppFileUri));
+
+ final isolateFile = hitMap[_isolateLibFileUri];
+ final expectedHits = {
+ 11: 1,
+ 12: 1,
+ 13: 1,
+ 15: 0,
+ 19: 1,
+ 23: 1,
+ 24: 2,
+ 28: 1,
+ 29: 1,
+ 30: 1,
+ 32: 0,
+ 38: 1,
+ 39: 1,
+ 41: 1,
+ 42: 4,
+ 43: 1,
+ 44: 3,
+ 45: 1,
+ 48: 1,
+ 49: 1,
+ 51: 1,
+ 54: 1,
+ 55: 1,
+ 56: 1,
+ 59: 1,
+ 60: 1,
+ 62: 1,
+ 63: 1,
+ 64: 1,
+ 66: 1,
+ 67: 1,
+ 68: 1,
+ 71: 3,
+ };
+ expect(isolateFile?.lineHits, expectedHits);
+ expect(isolateFile?.funcHits, {11: 1, 19: 1, 23: 1, 28: 1, 38: 1});
+ expect(isolateFile?.funcNames, {
+ 11: 'fooSync',
+ 19: 'BarClass.BarClass',
+ 23: 'BarClass.baz',
+ 28: 'fooAsync',
+ 38: 'isolateTask'
+ });
+ expect(
+ isolateFile?.branchHits,
+ {
+ 11: 1,
+ 12: 1,
+ 15: 0,
+ 19: 1,
+ 23: 1,
+ 28: 1,
+ 29: 1,
+ 32: 0,
+ 38: 1,
+ 42: 1,
+ 71: 1,
+ },
+ );
+ });
+
+ test('parseCoverage', () async {
+ final tempDir = await Directory.systemTemp.createTemp('coverage.test.');
+
+ try {
+ final outputFile = File(p.join(tempDir.path, 'coverage.json'));
+
+ final coverageResults = await _getCoverageResult();
+ await outputFile.writeAsString(coverageResults, flush: true);
+
+ // ignore: deprecated_member_use_from_same_package
+ final parsedResult = await parseCoverage([outputFile], 1);
+
+ expect(parsedResult, contains(_sampleAppFileUri));
+ expect(parsedResult, contains(_isolateLibFileUri));
+ } finally {
+ await tempDir.delete(recursive: true);
+ }
+ });
+
+ test('HitMap.parseFiles', () async {
+ final tempDir = await Directory.systemTemp.createTemp('coverage.test.');
+
+ try {
+ final outputFile = File(p.join(tempDir.path, 'coverage.json'));
+
+ final coverageResults = await _getCoverageResult();
+ await outputFile.writeAsString(coverageResults, flush: true);
+
+ final parsedResult = await HitMap.parseFiles([outputFile]);
+
+ expect(parsedResult, contains(_sampleAppFileUri));
+ expect(parsedResult, contains(_isolateLibFileUri));
+ } finally {
+ await tempDir.delete(recursive: true);
+ }
+ });
+
+ test('HitMap.parseFiles with packagesPath and checkIgnoredLines', () async {
+ final tempDir = await Directory.systemTemp.createTemp('coverage.test.');
+
+ try {
+ final outputFile = File(p.join(tempDir.path, 'coverage.json'));
+
+ final coverageResults = await _getCoverageResult();
+ await outputFile.writeAsString(coverageResults, flush: true);
+
+ final parsedResult = await HitMap.parseFiles([outputFile],
+ packagePath: '.', checkIgnoredLines: true);
+
+ // This file has ignore:coverage-file.
+ expect(parsedResult, isNot(contains(_sampleAppFileUri)));
+ expect(parsedResult, contains(_isolateLibFileUri));
+ } finally {
+ await tempDir.delete(recursive: true);
+ }
+ });
+
+ test('mergeHitmaps', () {
+ final resultMap = <String, Map<int, int>>{
+ 'foo.dart': {10: 2, 20: 0},
+ 'bar.dart': {10: 3, 20: 1, 30: 0},
+ };
+ final newMap = <String, Map<int, int>>{
+ 'bar.dart': {10: 2, 20: 0, 40: 3},
+ 'baz.dart': {10: 1, 20: 0, 30: 1},
+ };
+ // ignore: deprecated_member_use_from_same_package
+ mergeHitmaps(newMap, resultMap);
+ expect(resultMap, <String, Map<int, int>>{
+ 'foo.dart': {10: 2, 20: 0},
+ 'bar.dart': {10: 5, 20: 1, 30: 0, 40: 3},
+ 'baz.dart': {10: 1, 20: 0, 30: 1},
+ });
+ });
+
+ test('FileHitMaps.merge', () {
+ final resultMap = <String, HitMap>{
+ 'foo.dart':
+ HitMap({10: 2, 20: 0}, {15: 0, 25: 1}, {15: 'bobble', 25: 'cobble'}),
+ 'bar.dart': HitMap(
+ {10: 3, 20: 1, 30: 0}, {15: 5, 25: 0}, {15: 'gobble', 25: 'wobble'}),
+ };
+ final newMap = <String, HitMap>{
+ 'bar.dart': HitMap(
+ {10: 2, 20: 0, 40: 3}, {15: 1, 35: 4}, {15: 'gobble', 35: 'dobble'}),
+ 'baz.dart': HitMap(
+ {10: 1, 20: 0, 30: 1}, {15: 0, 25: 2}, {15: 'lobble', 25: 'zobble'}),
+ };
+ resultMap.merge(newMap);
+ expect(resultMap['foo.dart']?.lineHits, <int, int>{10: 2, 20: 0});
+ expect(resultMap['foo.dart']?.funcHits, <int, int>{15: 0, 25: 1});
+ expect(resultMap['foo.dart']?.funcNames,
+ <int, String>{15: 'bobble', 25: 'cobble'});
+ expect(resultMap['bar.dart']?.lineHits,
+ <int, int>{10: 5, 20: 1, 30: 0, 40: 3});
+ expect(resultMap['bar.dart']?.funcHits, <int, int>{15: 6, 25: 0, 35: 4});
+ expect(resultMap['bar.dart']?.funcNames,
+ <int, String>{15: 'gobble', 25: 'wobble', 35: 'dobble'});
+ expect(resultMap['baz.dart']?.lineHits, <int, int>{10: 1, 20: 0, 30: 1});
+ expect(resultMap['baz.dart']?.funcHits, <int, int>{15: 0, 25: 2});
+ expect(resultMap['baz.dart']?.funcNames,
+ <int, String>{15: 'lobble', 25: 'zobble'});
+ });
+}
+
+String? _coverageData;
+
+Future<String> _getCoverageResult() async =>
+ _coverageData ??= await _collectCoverage(false, false);
+
+Future<String> _collectCoverage(
+ bool functionCoverage, bool branchCoverage) async {
+ expect(FileSystemEntity.isFileSync(testAppPath), isTrue);
+
+ final openPort = await getOpenPort();
+
+ // Run the sample app with the right flags.
+ final sampleProcess = await runTestApp(openPort);
+
+ // Capture the VM service URI.
+ final serviceUri = await serviceUriFromProcess(sampleProcess.stdoutStream());
+
+ // Run the collection tool.
+ // TODO: need to get all of this functionality in the lib
+ final toolResult = await TestProcess.start(Platform.resolvedExecutable, [
+ _collectAppPath,
+ if (functionCoverage) '--function-coverage',
+ if (branchCoverage) '--branch-coverage',
+ '--uri',
+ '$serviceUri',
+ '--resume-isolates',
+ '--wait-paused'
+ ]);
+
+ await toolResult.shouldExit(0).timeout(
+ timeout,
+ onTimeout: () =>
+ throw StateError('We timed out waiting for the tool to finish.'),
+ );
+
+ await sampleProcess.shouldExit();
+
+ return toolResult.stdoutStream().join('\n');
+}
diff --git a/pkgs/coverage/test/format_coverage_test.dart b/pkgs/coverage/test/format_coverage_test.dart
new file mode 100644
index 0000000..85493f7
--- /dev/null
+++ b/pkgs/coverage/test/format_coverage_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:path/path.dart' as p;
+import 'package:test/test.dart';
+
+import '../bin/format_coverage.dart';
+
+void main() {
+ late Directory testDir;
+ setUp(() {
+ testDir = Directory.systemTemp.createTempSync('coverage_test_temp');
+ });
+
+ tearDown(() async {
+ if (testDir.existsSync()) testDir.deleteSync(recursive: true);
+ });
+
+ test('considers all json files', () async {
+ final fileA = File(p.join(testDir.path, 'coverage_a.json'));
+ fileA.createSync();
+ final fileB = File(p.join(testDir.path, 'coverage_b.json'));
+ fileB.createSync();
+ final fileC = File(p.join(testDir.path, 'not_coverage.foo'));
+ fileC.createSync();
+
+ final files = filesToProcess(testDir.path);
+ expect(files.length, equals(2));
+ expect(
+ files.map((f) => f.path),
+ containsAll(
+ [endsWith('coverage_a.json'), endsWith('coverage_b.json')]));
+ });
+}
diff --git a/pkgs/coverage/test/function_coverage_test.dart b/pkgs/coverage/test/function_coverage_test.dart
new file mode 100644
index 0000000..965d0d0
--- /dev/null
+++ b/pkgs/coverage/test/function_coverage_test.dart
@@ -0,0 +1,107 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:convert' show json;
+import 'dart:io';
+
+import 'package:coverage/coverage.dart';
+import 'package:coverage/src/util.dart';
+import 'package:path/path.dart' as p;
+import 'package:test/test.dart';
+import 'package:test_process/test_process.dart';
+
+import 'test_util.dart';
+
+final _collectAppPath = p.join('bin', 'collect_coverage.dart');
+final _funcCovApp = p.join('test', 'test_files', 'function_coverage_app.dart');
+final _sampleAppFileUri = p.toUri(p.absolute(_funcCovApp)).toString();
+
+void main() {
+ test('Function coverage', () async {
+ final resultString = await _collectCoverage();
+ final jsonResult = json.decode(resultString) as Map<String, dynamic>;
+ final coverage = jsonResult['coverage'] as List;
+ final hitMap = await HitMap.parseJson(
+ coverage.cast<Map<String, dynamic>>(),
+ );
+
+ // function_coverage_app.dart.
+ expect(hitMap, contains(_sampleAppFileUri));
+ final isolateFile = hitMap[_sampleAppFileUri]!;
+ expect(isolateFile.funcHits, {
+ 7: 1,
+ 16: 1,
+ 21: 1,
+ 25: 1,
+ 29: 1,
+ 36: 1,
+ 42: 1,
+ 47: 1,
+ });
+ expect(isolateFile.funcNames, {
+ 7: 'normalFunction',
+ 16: 'SomeClass.SomeClass',
+ 21: 'SomeClass.normalMethod',
+ 25: 'SomeClass.staticMethod',
+ 29: 'SomeClass.abstractMethod',
+ 36: 'SomeExtension.extensionMethod',
+ 42: 'OtherClass.otherMethod',
+ 47: 'main',
+ });
+
+ // test_library.dart.
+ final testLibraryPath =
+ p.absolute(p.join('test', 'test_files', 'test_library.dart'));
+ final testLibraryUri = p.toUri(testLibraryPath).toString();
+ expect(hitMap, contains(testLibraryUri));
+ final libraryfile = hitMap[testLibraryUri]!;
+ expect(libraryfile.funcHits, {7: 1});
+ expect(libraryfile.funcNames, {7: 'libraryFunction'});
+
+ // test_library_part.dart.
+ final testLibraryPartPath =
+ p.absolute(p.join('test', 'test_files', 'test_library_part.dart'));
+ final testLibraryPartUri = p.toUri(testLibraryPartPath).toString();
+ expect(hitMap, contains(testLibraryPartUri));
+ final libraryPartFile = hitMap[testLibraryPartUri]!;
+ expect(libraryPartFile.funcHits, {7: 1});
+ expect(libraryPartFile.funcNames, {7: 'otherLibraryFunction'});
+ });
+}
+
+Future<String> _collectCoverage() async {
+ expect(FileSystemEntity.isFileSync(_funcCovApp), isTrue);
+
+ final openPort = await getOpenPort();
+
+ // Run the sample app with the right flags.
+ final sampleProcess = await TestProcess.start(Platform.resolvedExecutable, [
+ '--enable-vm-service=$openPort',
+ '--pause_isolates_on_exit',
+ _funcCovApp
+ ]);
+
+ final serviceUri = await serviceUriFromProcess(sampleProcess.stdoutStream());
+
+ // Run the collection tool.
+ final toolResult = await TestProcess.start(Platform.resolvedExecutable, [
+ _collectAppPath,
+ '--function-coverage',
+ '--uri',
+ '$serviceUri',
+ '--resume-isolates',
+ '--wait-paused'
+ ]);
+
+ await toolResult.shouldExit(0).timeout(
+ timeout,
+ onTimeout: () =>
+ throw StateError('We timed out waiting for the tool to finish.'),
+ );
+
+ await sampleProcess.shouldExit();
+
+ return toolResult.stdoutStream().join('\n');
+}
diff --git a/pkgs/coverage/test/isolate_paused_listener_test.dart b/pkgs/coverage/test/isolate_paused_listener_test.dart
new file mode 100644
index 0000000..4fc7d4b
--- /dev/null
+++ b/pkgs/coverage/test/isolate_paused_listener_test.dart
@@ -0,0 +1,753 @@
+// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:coverage/src/isolate_paused_listener.dart';
+import 'package:mockito/mockito.dart';
+import 'package:test/test.dart';
+import 'package:vm_service/vm_service.dart';
+
+import 'collect_coverage_mock_test.mocks.dart';
+
+Event event(
+ String id, {
+ String? kind,
+ String? groupId,
+ String? name,
+}) =>
+ Event(
+ kind: kind,
+ isolate: IsolateRef(
+ isolateGroupId: groupId,
+ id: id,
+ name: name,
+ ));
+
+Isolate isolate(
+ String id, {
+ String? groupId,
+ String? name,
+ String? pauseKind,
+}) =>
+ Isolate(
+ isolateGroupId: groupId,
+ id: id,
+ name: name,
+ pauseEvent: pauseKind == null ? null : Event(kind: pauseKind),
+ );
+
+(MockVmService, StreamController<Event>) createServiceAndEventStreams() {
+ final service = MockVmService();
+ when(service.streamListen(any)).thenAnswer((_) async => Success());
+
+ // The VM service events we care about come in on 2 different streams,
+ // onIsolateEvent and onDebugEvent. We want to write tests that send sequences
+ // of events like [I1, D1, I2, D2, I3, D3], but since I and D go to separate
+ // streams, the listener may see them arrive like [I1, I2, I3, D1, D2, D3] or
+ // [D1, D2, D3, I1, I2, I3] or any other interleaving. So instead we send all
+ // the events through a single stream that gets split up. This emulates how
+ // the events work in reality, since they all come from a single web socket.
+ final allEvents = StreamController<Event>();
+ final isolateEvents = StreamController<Event>();
+ final debugEvents = StreamController<Event>();
+ allEvents.stream.listen((Event e) {
+ if (e.kind == EventKind.kIsolateStart ||
+ e.kind == EventKind.kIsolateStart) {
+ isolateEvents.add(e);
+ } else {
+ debugEvents.add(e);
+ }
+ });
+ when(service.onIsolateEvent).thenAnswer((_) => isolateEvents.stream);
+ when(service.onDebugEvent).thenAnswer((_) => debugEvents.stream);
+
+ return (service, allEvents);
+}
+
+void main() {
+ group('IsolateEventBuffer', () {
+ test('buffers events', () async {
+ final received = <String>[];
+ final eventBuffer = IsolateEventBuffer((Event event) async {
+ await Future<void>.delayed(Duration.zero);
+ received.add(event.isolate!.id!);
+ });
+
+ await eventBuffer.add(event('a'));
+ await eventBuffer.add(event('b'));
+ await eventBuffer.add(event('c'));
+ expect(received, <String>[]);
+
+ await eventBuffer.flush();
+ expect(received, ['a', 'b', 'c']);
+
+ await eventBuffer.flush();
+ expect(received, ['a', 'b', 'c']);
+
+ await eventBuffer.add(event('d'));
+ await eventBuffer.add(event('e'));
+ await eventBuffer.add(event('f'));
+ expect(received, ['a', 'b', 'c', 'd', 'e', 'f']);
+
+ await eventBuffer.flush();
+ expect(received, ['a', 'b', 'c', 'd', 'e', 'f']);
+ });
+
+ test('buffers events during flush', () async {
+ final received = <String>[];
+ final pause = Completer<void>();
+ final eventBuffer = IsolateEventBuffer((Event event) async {
+ await pause.future;
+ received.add(event.isolate!.id!);
+ });
+
+ await eventBuffer.add(event('a'));
+ await eventBuffer.add(event('b'));
+ await eventBuffer.add(event('c'));
+ expect(received, <String>[]);
+
+ final flushing = eventBuffer.flush();
+ expect(received, <String>[]);
+
+ await eventBuffer.add(event('d'));
+ await eventBuffer.add(event('e'));
+ await eventBuffer.add(event('f'));
+ expect(received, <String>[]);
+
+ pause.complete();
+ await flushing;
+ expect(received, ['a', 'b', 'c', 'd', 'e', 'f']);
+ });
+ });
+
+ test('IsolateEventBuffer', () {
+ final group = IsolateGroupState();
+ expect(group.running, isEmpty);
+ expect(group.paused, isEmpty);
+ expect(group.noRunningIsolates, isTrue);
+ expect(group.noLiveIsolates, isTrue);
+
+ group.start('a');
+ expect(group.running, unorderedEquals(['a']));
+ expect(group.paused, isEmpty);
+ expect(group.noRunningIsolates, isFalse);
+ expect(group.noLiveIsolates, isFalse);
+
+ group.start('a');
+ expect(group.running, unorderedEquals(['a']));
+ expect(group.paused, isEmpty);
+ expect(group.noRunningIsolates, isFalse);
+ expect(group.noLiveIsolates, isFalse);
+
+ group.start('b');
+ expect(group.running, unorderedEquals(['a', 'b']));
+ expect(group.paused, isEmpty);
+ expect(group.noRunningIsolates, isFalse);
+ expect(group.noLiveIsolates, isFalse);
+
+ group.pause('a');
+ expect(group.running, unorderedEquals(['b']));
+ expect(group.paused, unorderedEquals(['a']));
+ expect(group.noRunningIsolates, isFalse);
+ expect(group.noLiveIsolates, isFalse);
+
+ group.pause('a');
+ expect(group.running, unorderedEquals(['b']));
+ expect(group.paused, unorderedEquals(['a']));
+ expect(group.noRunningIsolates, isFalse);
+ expect(group.noLiveIsolates, isFalse);
+
+ group.pause('c');
+ expect(group.running, unorderedEquals(['b']));
+ expect(group.paused, unorderedEquals(['a', 'c']));
+ expect(group.noRunningIsolates, isFalse);
+ expect(group.noLiveIsolates, isFalse);
+
+ group.start('c');
+ expect(group.running, unorderedEquals(['b', 'c']));
+ expect(group.paused, unorderedEquals(['a']));
+ expect(group.noRunningIsolates, isFalse);
+ expect(group.noLiveIsolates, isFalse);
+
+ group.pause('c');
+ expect(group.running, unorderedEquals(['b']));
+ expect(group.paused, unorderedEquals(['a', 'c']));
+ expect(group.noRunningIsolates, isFalse);
+ expect(group.noLiveIsolates, isFalse);
+
+ group.exit('a');
+ expect(group.running, unorderedEquals(['b']));
+ expect(group.paused, unorderedEquals(['c']));
+ expect(group.noRunningIsolates, isFalse);
+ expect(group.noLiveIsolates, isFalse);
+
+ group.pause('b');
+ expect(group.running, isEmpty);
+ expect(group.paused, unorderedEquals(['b', 'c']));
+ expect(group.noRunningIsolates, isTrue);
+ expect(group.noLiveIsolates, isFalse);
+
+ group.exit('b');
+ expect(group.running, isEmpty);
+ expect(group.paused, unorderedEquals(['c']));
+ expect(group.noRunningIsolates, isTrue);
+ expect(group.noLiveIsolates, isFalse);
+
+ group.exit('c');
+ expect(group.running, isEmpty);
+ expect(group.paused, isEmpty);
+ expect(group.noRunningIsolates, isTrue);
+ expect(group.noLiveIsolates, isTrue);
+ });
+
+ group('listenToIsolateLifecycleEvents', () {
+ late MockVmService service;
+ late StreamController<Event> allEvents;
+ late Completer<List<Isolate>> isolates;
+ late Future<void> backfilled;
+ late Future<void> testEnded;
+
+ late List<String> received;
+ Future<void>? delayTheOnPauseCallback;
+
+ void startEvent(String id) =>
+ allEvents.add(event(id, kind: EventKind.kIsolateStart));
+ void exitEvent(String id) =>
+ allEvents.add(event(id, kind: EventKind.kIsolateExit));
+ void pauseEvent(String id) =>
+ allEvents.add(event(id, kind: EventKind.kPauseExit));
+ void otherEvent(String id, String kind) =>
+ allEvents.add(event(id, kind: kind));
+
+ Future<void> backfill(List<Isolate> isos) async {
+ isolates.complete(isos);
+ await backfilled;
+ }
+
+ // We end the test by sending an exit event with a specific ID.
+ const endTestEventId = 'END';
+ Future<void> endTest() {
+ exitEvent(endTestEventId);
+ return testEnded;
+ }
+
+ setUp(() {
+ (service, allEvents) = createServiceAndEventStreams();
+
+ isolates = Completer<List<Isolate>>();
+ when(service.getVM())
+ .thenAnswer((_) async => VM(isolates: await isolates.future));
+ when(service.getIsolate(any)).thenAnswer((invocation) async {
+ final id = invocation.positionalArguments[0];
+ return (await isolates.future).firstWhere((iso) => iso.id == id);
+ });
+
+ received = <String>[];
+ delayTheOnPauseCallback = null;
+ final testEnder = Completer<void>();
+ testEnded = testEnder.future;
+ backfilled = listenToIsolateLifecycleEvents(
+ service,
+ (iso) {
+ if (iso.id == endTestEventId) return;
+ received.add('Start ${iso.id}');
+ },
+ (iso) async {
+ received.add('Pause ${iso.id}');
+ if (delayTheOnPauseCallback != null) {
+ await delayTheOnPauseCallback;
+ received.add('Pause done ${iso.id}');
+ }
+ },
+ (iso) {
+ if (iso.id == endTestEventId) {
+ testEnder.complete();
+ } else {
+ received.add('Exit ${iso.id}');
+ }
+ },
+ );
+ });
+
+ test('ordinary flows', () async {
+ // Events sent before backfill.
+ startEvent('A');
+ startEvent('C');
+ startEvent('B');
+ pauseEvent('C');
+ pauseEvent('A');
+ startEvent('D');
+ pauseEvent('D');
+ exitEvent('A');
+
+ // Run backfill.
+ await backfill([
+ isolate('B'),
+ isolate('C', pauseKind: EventKind.kPauseExit),
+ isolate('D'),
+ isolate('E'),
+ isolate('F', pauseKind: EventKind.kPauseExit),
+ ]);
+
+ // All the backfill events happen before any of the real events.
+ expect(received, [
+ // Backfill events.
+ 'Start B',
+ 'Start C',
+ 'Pause C',
+ 'Start D',
+ 'Start E',
+ 'Start F',
+ 'Pause F',
+
+ // Real events from before backfill.
+ 'Start A',
+ 'Pause A',
+ 'Pause D',
+ 'Exit A',
+ ]);
+
+ // Events sent after backfill.
+ received.clear();
+ startEvent('G');
+ exitEvent('C');
+ exitEvent('B');
+ exitEvent('G');
+ exitEvent('D');
+ exitEvent('E');
+ exitEvent('F');
+
+ await endTest();
+ expect(received, [
+ 'Start G',
+ 'Exit C',
+ 'Exit B',
+ 'Exit G',
+ 'Exit D',
+ 'Exit E',
+ 'Exit F',
+ ]);
+
+ verify(service.streamListen(EventStreams.kIsolate)).called(1);
+ verify(service.streamListen(EventStreams.kDebug)).called(1);
+ });
+
+ test('pause and exit events without start', () async {
+ await backfill([]);
+
+ pauseEvent('A');
+ exitEvent('B');
+
+ await endTest();
+ expect(received, [
+ 'Start A',
+ 'Pause A',
+ 'Start B',
+ 'Exit B',
+ ]);
+ });
+
+ test('pause event after exit is ignored', () async {
+ await backfill([]);
+
+ exitEvent('A');
+ pauseEvent('A');
+
+ await endTest();
+ expect(received, [
+ 'Start A',
+ 'Exit A',
+ ]);
+ });
+
+ test('event deduping', () async {
+ startEvent('A');
+ startEvent('A');
+ pauseEvent('A');
+ pauseEvent('A');
+ exitEvent('A');
+ exitEvent('A');
+
+ pauseEvent('B');
+ startEvent('B');
+
+ exitEvent('C');
+ startEvent('C');
+
+ await backfill([]);
+ await endTest();
+ expect(received, [
+ 'Start A',
+ 'Pause A',
+ 'Exit A',
+ 'Start B',
+ 'Pause B',
+ 'Start C',
+ 'Exit C',
+ ]);
+ });
+
+ test('ignore other events', () async {
+ await backfill([]);
+
+ startEvent('A');
+ pauseEvent('A');
+ otherEvent('A', EventKind.kResume);
+ exitEvent('A');
+
+ startEvent('B');
+ otherEvent('B', EventKind.kPauseBreakpoint);
+ exitEvent('B');
+
+ otherEvent('C', EventKind.kInspect);
+
+ await endTest();
+ expect(received, [
+ 'Start A',
+ 'Pause A',
+ 'Exit A',
+ 'Start B',
+ 'Exit B',
+ ]);
+ });
+
+ test('exit event during pause callback', () async {
+ final delayingTheOnPauseCallback = Completer<void>();
+ delayTheOnPauseCallback = delayingTheOnPauseCallback.future;
+ await backfill([]);
+
+ startEvent('A');
+ pauseEvent('A');
+ exitEvent('A');
+
+ while (received.length < 2) {
+ await Future<void>.delayed(Duration.zero);
+ }
+
+ expect(received, [
+ 'Start A',
+ 'Pause A',
+ ]);
+
+ delayingTheOnPauseCallback.complete();
+ await endTest();
+ expect(received, [
+ 'Start A',
+ 'Pause A',
+ 'Pause done A',
+ 'Exit A',
+ ]);
+ });
+
+ test('exit event during pause callback, event deduping', () async {
+ final delayingTheOnPauseCallback = Completer<void>();
+ delayTheOnPauseCallback = delayingTheOnPauseCallback.future;
+ await backfill([]);
+
+ startEvent('A');
+ pauseEvent('A');
+ exitEvent('A');
+ pauseEvent('A');
+ pauseEvent('A');
+ exitEvent('A');
+ exitEvent('A');
+
+ while (received.length < 2) {
+ await Future<void>.delayed(Duration.zero);
+ }
+
+ expect(received, [
+ 'Start A',
+ 'Pause A',
+ ]);
+
+ delayingTheOnPauseCallback.complete();
+ await endTest();
+ expect(received, [
+ 'Start A',
+ 'Pause A',
+ 'Pause done A',
+ 'Exit A',
+ ]);
+ });
+ });
+
+ group('IsolatePausedListener', () {
+ late MockVmService service;
+ late StreamController<Event> allEvents;
+ late Future<void> allIsolatesExited;
+
+ late List<String> received;
+ late bool stopped;
+
+ void startEvent(String id, String groupId, [String? name]) =>
+ allEvents.add(event(
+ id,
+ kind: EventKind.kIsolateStart,
+ groupId: groupId,
+ name: name ?? id,
+ ));
+ void exitEvent(String id, String groupId, [String? name]) =>
+ allEvents.add(event(
+ id,
+ kind: EventKind.kIsolateExit,
+ groupId: groupId,
+ name: name ?? id,
+ ));
+ void pauseEvent(String id, String groupId, [String? name]) =>
+ allEvents.add(event(
+ id,
+ kind: EventKind.kPauseExit,
+ groupId: groupId,
+ name: name ?? id,
+ ));
+
+ Future<void> endTest() async {
+ await allIsolatesExited;
+ stopped = true;
+ }
+
+ setUp(() {
+ (service, allEvents) = createServiceAndEventStreams();
+
+ // Backfill was tested above, so this test does everything using events,
+ // for simplicity. No need to report any isolates.
+ when(service.getVM()).thenAnswer((_) async => VM());
+
+ received = <String>[];
+ when(service.resume(any)).thenAnswer((invocation) async {
+ final id = invocation.positionalArguments[0];
+ received.add('Resume $id');
+ return Success();
+ });
+
+ stopped = false;
+ allIsolatesExited = IsolatePausedListener(
+ service,
+ (iso, isLastIsolateInGroup) async {
+ expect(stopped, isFalse);
+ received.add('Pause ${iso.id}. Last in group ${iso.isolateGroupId}? '
+ '${isLastIsolateInGroup ? 'Yes' : 'No'}');
+ },
+ (message) => received.add(message),
+ ).waitUntilAllExited();
+ });
+
+ test('ordinary flows', () async {
+ startEvent('A', '1');
+ startEvent('B', '1');
+ pauseEvent('A', '1');
+ startEvent('C', '1');
+ pauseEvent('B', '1');
+ exitEvent('A', '1');
+ startEvent('D', '2');
+ startEvent('E', '2');
+ startEvent('F', '2');
+ pauseEvent('C', '1');
+ pauseEvent('F', '2');
+ pauseEvent('E', '2');
+ exitEvent('C', '1');
+ exitEvent('E', '2');
+ startEvent('G', '3');
+ exitEvent('F', '2');
+ startEvent('H', '3');
+ startEvent('I', '3');
+ pauseEvent('I', '3');
+ exitEvent('I', '3');
+ pauseEvent('H', '3');
+ exitEvent('H', '3');
+ pauseEvent('D', '2');
+ pauseEvent('G', '3');
+ exitEvent('D', '2');
+ exitEvent('G', '3');
+ exitEvent('B', '1');
+
+ await endTest();
+
+ // Events sent after waitUntilAllExited is finished do nothing.
+ startEvent('Z', '9');
+ pauseEvent('Z', '9');
+ exitEvent('Z', '9');
+
+ expect(received, [
+ 'Pause A. Last in group 1? No',
+ 'Resume A',
+ 'Pause B. Last in group 1? No',
+ 'Resume B',
+ 'Pause C. Last in group 1? Yes',
+ 'Resume C',
+ 'Pause F. Last in group 2? No',
+ 'Resume F',
+ 'Pause E. Last in group 2? No',
+ 'Resume E',
+ 'Pause I. Last in group 3? No',
+ 'Resume I',
+ 'Pause H. Last in group 3? No',
+ 'Resume H',
+ 'Pause D. Last in group 2? Yes',
+ 'Resume D',
+ 'Pause G. Last in group 3? Yes',
+ 'Resume G',
+ ]);
+ });
+
+ test('exit without pausing', () async {
+ // If an isolate exits without pausing, this may mess up coverage
+ // collection (if it happens to be the last isolate in the group, that
+ // group won't be collected). The best we can do is log an error, and make
+ // sure not to wait forever for pause events that aren't coming.
+ startEvent('A', '1');
+ startEvent('B', '1');
+ exitEvent('A', '1');
+ pauseEvent('B', '1');
+ startEvent('C', '2');
+ startEvent('D', '2');
+ pauseEvent('D', '2');
+ exitEvent('D', '2');
+ exitEvent('C', '2');
+ exitEvent('B', '1');
+
+ await endTest();
+
+ // B was paused correctly and was the last to exit isolate 1, so isolate 1
+ // was collected ok.
+ expect(received, [
+ 'Pause B. Last in group 1? Yes',
+ 'Resume B',
+ 'Pause D. Last in group 2? No',
+ 'Resume D',
+ 'ERROR: An isolate exited without pausing, causing coverage data to '
+ 'be lost for group 2.',
+ ]);
+ });
+
+ test('main isolate resumed last', () async {
+ startEvent('A', '1', 'main');
+ startEvent('B', '1', 'main'); // Second isolate named main, ignored.
+ pauseEvent('B', '1', 'main');
+ startEvent('C', '2', 'main'); // Third isolate named main, ignored.
+ pauseEvent('A', '1', 'main');
+ startEvent('D', '2');
+ pauseEvent('C', '2');
+ exitEvent('C', '2');
+ pauseEvent('D', '2');
+ exitEvent('D', '2');
+ exitEvent('B', '1');
+
+ await endTest();
+
+ expect(received, [
+ 'Pause B. Last in group 1? No',
+ 'Resume B',
+ 'Pause C. Last in group 2? No',
+ 'Resume C',
+ 'Pause D. Last in group 2? Yes',
+ 'Resume D',
+ 'Pause A. Last in group 1? Yes',
+ 'Resume A',
+ ]);
+ });
+
+ test('main isolate exits without pausing', () async {
+ startEvent('A', '1', 'main');
+ startEvent('B', '1');
+ pauseEvent('B', '1');
+ exitEvent('A', '1', 'main');
+ exitEvent('B', '1');
+
+ await endTest();
+
+ expect(received, [
+ 'Pause B. Last in group 1? No',
+ 'Resume B',
+ 'ERROR: An isolate exited without pausing, causing coverage data to '
+ 'be lost for group 1.',
+ ]);
+ });
+
+ test('main isolate is the only isolate', () async {
+ startEvent('A', '1', 'main');
+ pauseEvent('A', '1', 'main');
+
+ await endTest();
+
+ expect(received, [
+ 'Pause A. Last in group 1? Yes',
+ 'Resume A',
+ ]);
+ });
+
+ test('all other isolates exit before main isolate pauses', () async {
+ startEvent('A', '1', 'main');
+ startEvent('B', '1');
+ pauseEvent('B', '1');
+ exitEvent('B', '1');
+
+ await Future<void>.delayed(Duration.zero);
+
+ pauseEvent('A', '1', 'main');
+ exitEvent('A', '1', 'main');
+
+ await endTest();
+
+ expect(received, [
+ 'Pause B. Last in group 1? No',
+ 'Resume B',
+ 'Pause A. Last in group 1? Yes',
+ 'Resume A',
+ ]);
+ });
+
+ test('group reopened', () async {
+ // If an isolate is reported in a group after the group as believed to be
+ // closed, reopen the group. This double counts some coverage, but at
+ // least won't miss any.
+
+ startEvent('Z', '9'); // Separate isolate to keep the system alive until
+ pauseEvent('Z', '9'); // the test is complete.
+
+ startEvent('A', '1');
+ startEvent('B', '1');
+ pauseEvent('A', '1');
+ pauseEvent('B', '1');
+ exitEvent('B', '1');
+ exitEvent('A', '1');
+
+ startEvent('D', '2');
+ startEvent('E', '2');
+ pauseEvent('E', '2');
+ pauseEvent('D', '2');
+ exitEvent('E', '2');
+ exitEvent('D', '2');
+
+ startEvent('C', '1');
+ pauseEvent('F', '2');
+ pauseEvent('C', '1');
+ exitEvent('C', '1');
+ exitEvent('F', '2');
+
+ exitEvent('Z', '9');
+
+ await endTest();
+
+ expect(received, [
+ 'Pause Z. Last in group 9? Yes',
+ 'Resume Z',
+ 'Pause A. Last in group 1? No',
+ 'Resume A',
+ 'Pause B. Last in group 1? Yes',
+ 'Resume B',
+ 'Pause E. Last in group 2? No',
+ 'Resume E',
+ 'Pause D. Last in group 2? Yes',
+ 'Resume D',
+ 'Pause F. Last in group 2? Yes',
+ 'Resume F',
+ 'Pause C. Last in group 1? Yes',
+ 'Resume C',
+ ]);
+ });
+ });
+}
diff --git a/pkgs/coverage/test/lcov_test.dart b/pkgs/coverage/test/lcov_test.dart
new file mode 100644
index 0000000..ca62117
--- /dev/null
+++ b/pkgs/coverage/test/lcov_test.dart
@@ -0,0 +1,364 @@
+// 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 'dart:async';
+import 'dart:io';
+
+import 'package:coverage/coverage.dart';
+import 'package:coverage/src/util.dart';
+import 'package:glob/glob.dart';
+import 'package:path/path.dart' as p;
+import 'package:test/test.dart';
+import 'package:test_process/test_process.dart';
+
+final _sampleAppPath = p.join('test', 'test_files', 'test_app.dart');
+final _sampleGeneratedPath = p.join('test', 'test_files', 'test_app.g.dart');
+final _isolateLibPath = p.join('test', 'test_files', 'test_app_isolate.dart');
+
+final _sampleAppFileUri = p.toUri(p.absolute(_sampleAppPath)).toString();
+final _sampleGeneratedFileUri =
+ p.toUri(p.absolute(_sampleGeneratedPath)).toString();
+final _isolateLibFileUri = p.toUri(p.absolute(_isolateLibPath)).toString();
+
+void main() {
+ test('validate hitMap', () async {
+ final hitmap = await _getHitMap();
+
+ expect(hitmap, contains(_sampleAppFileUri));
+ expect(hitmap, contains(_sampleGeneratedFileUri));
+ expect(hitmap, contains(_isolateLibFileUri));
+ expect(hitmap, contains('package:coverage/src/util.dart'));
+
+ final sampleAppHitMap = hitmap[_sampleAppFileUri];
+ final sampleAppHitLines = sampleAppHitMap?.lineHits;
+ final sampleAppHitFuncs = sampleAppHitMap?.funcHits;
+ final sampleAppFuncNames = sampleAppHitMap?.funcNames;
+ final sampleAppBranchHits = sampleAppHitMap?.branchHits;
+
+ expect(sampleAppHitLines, containsPair(53, greaterThanOrEqualTo(1)),
+ reason: 'be careful if you modify the test file');
+ expect(sampleAppHitLines, containsPair(57, 0),
+ reason: 'be careful if you modify the test file');
+ expect(sampleAppHitLines, isNot(contains(39)),
+ reason: 'be careful if you modify the test file');
+ expect(sampleAppHitFuncs, containsPair(52, 1),
+ reason: 'be careful if you modify the test file');
+ expect(sampleAppHitFuncs, containsPair(56, 0),
+ reason: 'be careful if you modify the test file');
+ expect(sampleAppFuncNames, containsPair(52, 'usedMethod'),
+ reason: 'be careful if you modify the test file');
+ expect(sampleAppBranchHits, containsPair(48, 1),
+ reason: 'be careful if you modify the test file');
+ });
+
+ test('validate hitMap, old VM without branch coverage', () async {
+ final hitmap = await _getHitMap();
+
+ expect(hitmap, contains(_sampleAppFileUri));
+ expect(hitmap, contains(_sampleGeneratedFileUri));
+ expect(hitmap, contains(_isolateLibFileUri));
+ expect(hitmap, contains('package:coverage/src/util.dart'));
+
+ final sampleAppHitMap = hitmap[_sampleAppFileUri];
+ final sampleAppHitLines = sampleAppHitMap?.lineHits;
+ final sampleAppHitFuncs = sampleAppHitMap?.funcHits;
+ final sampleAppFuncNames = sampleAppHitMap?.funcNames;
+
+ expect(sampleAppHitLines, containsPair(53, greaterThanOrEqualTo(1)),
+ reason: 'be careful if you modify the test file');
+ expect(sampleAppHitLines, containsPair(57, 0),
+ reason: 'be careful if you modify the test file');
+ expect(sampleAppHitLines, isNot(contains(39)),
+ reason: 'be careful if you modify the test file');
+ expect(sampleAppHitFuncs, containsPair(52, 1),
+ reason: 'be careful if you modify the test file');
+ expect(sampleAppHitFuncs, containsPair(56, 0),
+ reason: 'be careful if you modify the test file');
+ expect(sampleAppFuncNames, containsPair(52, 'usedMethod'),
+ reason: 'be careful if you modify the test file');
+ });
+
+ group('LcovFormatter', () {
+ test('format()', () async {
+ final hitmap = await _getHitMap();
+
+ final resolver = await Resolver.create(packagePath: '.');
+ // ignore: deprecated_member_use_from_same_package
+ final formatter = LcovFormatter(resolver);
+
+ final res = await formatter
+ .format(hitmap.map((key, value) => MapEntry(key, value.lineHits)));
+
+ expect(res, contains(p.absolute(_sampleAppPath)));
+ expect(res, contains(p.absolute(_sampleGeneratedPath)));
+ expect(res, contains(p.absolute(_isolateLibPath)));
+ expect(res, contains(p.absolute(p.join('lib', 'src', 'util.dart'))));
+ });
+
+ test('formatLcov()', () async {
+ final hitmap = await _getHitMap();
+
+ final resolver = await Resolver.create(packagePath: '.');
+ final res = hitmap.formatLcov(resolver);
+
+ expect(res, contains(p.absolute(_sampleAppPath)));
+ expect(res, contains(p.absolute(_sampleGeneratedPath)));
+ expect(res, contains(p.absolute(_isolateLibPath)));
+ expect(res, contains(p.absolute(p.join('lib', 'src', 'util.dart'))));
+ });
+
+ test('formatLcov() includes files in reportOn list', () async {
+ final hitmap = await _getHitMap();
+
+ final resolver = await Resolver.create(packagePath: '.');
+ final res = hitmap.formatLcov(resolver, reportOn: ['lib/', 'test/']);
+
+ expect(res, contains(p.absolute(_sampleAppPath)));
+ expect(res, contains(p.absolute(_sampleGeneratedPath)));
+ expect(res, contains(p.absolute(_isolateLibPath)));
+ expect(res, contains(p.absolute(p.join('lib', 'src', 'util.dart'))));
+ });
+
+ test('formatLcov() excludes files not in reportOn list', () async {
+ final hitmap = await _getHitMap();
+
+ final resolver = await Resolver.create(packagePath: '.');
+ final res = hitmap.formatLcov(resolver, reportOn: ['lib/']);
+
+ expect(res, isNot(contains(p.absolute(_sampleAppPath))));
+ expect(res, isNot(contains(p.absolute(_sampleGeneratedPath))));
+ expect(res, isNot(contains(p.absolute(_isolateLibPath))));
+ expect(res, contains(p.absolute(p.join('lib', 'src', 'util.dart'))));
+ });
+
+ test('formatLcov() excludes files matching glob patterns', () async {
+ final hitmap = await _getHitMap();
+
+ final resolver = await Resolver.create(packagePath: '.');
+ final res = hitmap.formatLcov(
+ resolver,
+ ignoreGlobs: {Glob('**/*.g.dart'), Glob('**/util.dart')},
+ );
+
+ expect(res, contains(p.absolute(_sampleAppPath)));
+ expect(res, isNot(contains(p.absolute(_sampleGeneratedPath))));
+ expect(res, contains(p.absolute(_isolateLibPath)));
+ expect(
+ res,
+ isNot(contains(p.absolute(p.join('lib', 'src', 'util.dart')))),
+ );
+ });
+
+ test(
+ 'formatLcov() excludes files matching glob patterns regardless of their'
+ 'presence on reportOn list', () async {
+ final hitmap = await _getHitMap();
+
+ final resolver = await Resolver.create(packagePath: '.');
+ final res = hitmap.formatLcov(
+ resolver,
+ reportOn: ['test/'],
+ ignoreGlobs: {Glob('**/*.g.dart')},
+ );
+
+ expect(res, contains(p.absolute(_sampleAppPath)));
+ expect(res, isNot(contains(p.absolute(_sampleGeneratedPath))));
+ expect(res, contains(p.absolute(_isolateLibPath)));
+ });
+
+ test('formatLcov() uses paths relative to basePath', () async {
+ final hitmap = await _getHitMap();
+
+ final resolver = await Resolver.create(packagePath: '.');
+ final res = hitmap.formatLcov(resolver, basePath: p.absolute('lib'));
+
+ expect(
+ res, isNot(contains(p.absolute(p.join('lib', 'src', 'util.dart')))));
+ expect(res, contains(p.join('src', 'util.dart')));
+ });
+ });
+
+ group('PrettyPrintFormatter', () {
+ test('format()', () async {
+ final hitmap = await _getHitMap();
+
+ final resolver = await Resolver.create(packagePath: '.');
+ // ignore: deprecated_member_use_from_same_package
+ final formatter = PrettyPrintFormatter(resolver, Loader());
+
+ final res = await formatter
+ .format(hitmap.map((key, value) => MapEntry(key, value.lineHits)));
+
+ expect(res, contains(p.absolute(_sampleAppPath)));
+ expect(res, contains(p.absolute(_sampleGeneratedPath)));
+ expect(res, contains(p.absolute(_isolateLibPath)));
+ expect(res, contains(p.absolute(p.join('lib', 'src', 'util.dart'))));
+
+ // be very careful if you change the test file
+ expect(res, contains(' 0| return a - b;'));
+
+ expect(res, contains('| return withTimeout(() async {'),
+ reason: 'be careful if you change lib/src/util.dart');
+
+ final hitLineRegexp = RegExp(r'\s+(\d+)\| return a \+ b;');
+ final match = hitLineRegexp.allMatches(res).single;
+
+ final hitCount = int.parse(match[1]!);
+ expect(hitCount, greaterThanOrEqualTo(1));
+ });
+
+ test('prettyPrint()', () async {
+ final hitmap = await _getHitMap();
+
+ final resolver = await Resolver.create(packagePath: '.');
+ final res = await hitmap.prettyPrint(resolver, Loader());
+
+ expect(res, contains(p.absolute(_sampleAppPath)));
+ expect(res, contains(p.absolute(_sampleGeneratedPath)));
+ expect(res, contains(p.absolute(_isolateLibPath)));
+ expect(res, contains(p.absolute(p.join('lib', 'src', 'util.dart'))));
+
+ // be very careful if you change the test file
+ expect(res, contains(' 0| return a - b;'));
+
+ expect(res, contains('| return withTimeout(() async {'),
+ reason: 'be careful if you change lib/src/util.dart');
+
+ final hitLineRegexp = RegExp(r'\s+(\d+)\| return a \+ b;');
+ final match = hitLineRegexp.allMatches(res).single;
+
+ final hitCount = int.parse(match[1]!);
+ expect(hitCount, greaterThanOrEqualTo(1));
+ });
+
+ test('prettyPrint() includes files in reportOn list', () async {
+ final hitmap = await _getHitMap();
+
+ final resolver = await Resolver.create(packagePath: '.');
+ final res = await hitmap
+ .prettyPrint(resolver, Loader(), reportOn: ['lib/', 'test/']);
+
+ expect(res, contains(p.absolute(_sampleAppPath)));
+ expect(res, contains(p.absolute(_sampleGeneratedPath)));
+ expect(res, contains(p.absolute(_isolateLibPath)));
+ expect(res, contains(p.absolute(p.join('lib', 'src', 'util.dart'))));
+ });
+
+ test('prettyPrint() excludes files not in reportOn list', () async {
+ final hitmap = await _getHitMap();
+
+ final resolver = await Resolver.create(packagePath: '.');
+ final res =
+ await hitmap.prettyPrint(resolver, Loader(), reportOn: ['lib/']);
+
+ expect(res, isNot(contains(p.absolute(_sampleAppPath))));
+ expect(res, isNot(contains(p.absolute(_sampleGeneratedPath))));
+ expect(res, isNot(contains(p.absolute(_isolateLibPath))));
+ expect(res, contains(p.absolute(p.join('lib', 'src', 'util.dart'))));
+ });
+
+ test('prettyPrint() excludes files matching glob patterns', () async {
+ final hitmap = await _getHitMap();
+
+ final resolver = await Resolver.create(packagePath: '.');
+ final res = await hitmap.prettyPrint(
+ resolver,
+ Loader(),
+ ignoreGlobs: {Glob('**/*.g.dart'), Glob('**/util.dart')},
+ );
+
+ expect(res, contains(p.absolute(_sampleAppPath)));
+ expect(res, isNot(contains(p.absolute(_sampleGeneratedPath))));
+ expect(res, contains(p.absolute(_isolateLibPath)));
+ expect(
+ res,
+ isNot(contains(p.absolute(p.join('lib', 'src', 'util.dart')))),
+ );
+ });
+
+ test(
+ 'prettyPrint() excludes files matching glob patterns regardless of'
+ 'their presence on reportOn list', () async {
+ final hitmap = await _getHitMap();
+
+ final resolver = await Resolver.create(packagePath: '.');
+ final res = await hitmap.prettyPrint(
+ resolver,
+ Loader(),
+ reportOn: ['test/'],
+ ignoreGlobs: {Glob('**/*.g.dart')},
+ );
+
+ expect(res, contains(p.absolute(_sampleAppPath)));
+ expect(res, isNot(contains(p.absolute(_sampleGeneratedPath))));
+ expect(res, contains(p.absolute(_isolateLibPath)));
+ });
+
+ test('prettyPrint() functions', () async {
+ final hitmap = await _getHitMap();
+
+ final resolver = await Resolver.create(packagePath: '.');
+ final res =
+ await hitmap.prettyPrint(resolver, Loader(), reportFuncs: true);
+
+ expect(res, contains(p.absolute(_sampleAppPath)));
+ expect(res, contains(p.absolute(_sampleGeneratedPath)));
+ expect(res, contains(p.absolute(_isolateLibPath)));
+ expect(res, contains(p.absolute(p.join('lib', 'src', 'util.dart'))));
+
+ // be very careful if you change the test file
+ expect(res, contains(' 1|Future<void> main() async {'));
+ expect(res, contains(' 1|int usedMethod(int a, int b) {'));
+ expect(res, contains(' 0|int unusedMethod(int a, int b) {'));
+ expect(res, contains(' | return a + b;'));
+ });
+
+ test('prettyPrint() branches', () async {
+ final hitmap = await _getHitMap();
+
+ final resolver = await Resolver.create(packagePath: '.');
+ final res =
+ await hitmap.prettyPrint(resolver, Loader(), reportBranches: true);
+
+ expect(res, contains(p.absolute(_sampleAppPath)));
+ expect(res, contains(p.absolute(_sampleGeneratedPath)));
+ expect(res, contains(p.absolute(_isolateLibPath)));
+ expect(res, contains(p.absolute(p.join('lib', 'src', 'util.dart'))));
+
+ // be very careful if you change the test file
+ expect(res, contains(' 1| if (x == answer) {'));
+ expect(res, contains(' 0| while (i < lines.length) {'));
+ expect(res, contains(' | bar.baz();'));
+ });
+ });
+}
+
+Future<Map<String, HitMap>> _getHitMap() async {
+ expect(FileSystemEntity.isFileSync(_sampleAppPath), isTrue);
+
+ // select service port.
+ final port = await getOpenPort();
+
+ // start sample app.
+ final sampleAppArgs = [
+ '--pause-isolates-on-exit',
+ '--enable-vm-service=$port',
+ '--branch-coverage',
+ _sampleAppPath
+ ];
+ final sampleProcess =
+ await TestProcess.start(Platform.resolvedExecutable, sampleAppArgs);
+
+ final serviceUri = await serviceUriFromProcess(sampleProcess.stdoutStream());
+
+ // collect hit map.
+ final coverageJson = (await collect(serviceUri, true, true, false, <String>{},
+ functionCoverage: true,
+ branchCoverage: true))['coverage'] as List<Map<String, dynamic>>;
+ final hitMap = HitMap.parseJson(coverageJson);
+
+ await sampleProcess.shouldExit(0);
+
+ return hitMap;
+}
diff --git a/pkgs/coverage/test/resolver_test.dart b/pkgs/coverage/test/resolver_test.dart
new file mode 100644
index 0000000..1161aee
--- /dev/null
+++ b/pkgs/coverage/test/resolver_test.dart
@@ -0,0 +1,211 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:coverage/src/resolver.dart';
+import 'package:path/path.dart' as p;
+import 'package:test/test.dart';
+import 'package:test_descriptor/test_descriptor.dart' as d;
+
+void main() {
+ group('Default Resolver', () {
+ setUp(() async {
+ final sandboxUriPath = p.toUri(d.sandbox).toString();
+ await d.dir('bar', [
+ d.dir('lib', [
+ d.file('bar.dart', 'final fizz = "bar";'),
+ ])
+ ]).create();
+
+ await d.dir('foo', [
+ d.dir('.dart_tool', [
+ d.file('bad_package_config.json', 'thisIsntAPackageConfigFile!'),
+ d.file('package_config.json', '''
+{
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "foo",
+ "rootUri": "../",
+ "packageUri": "lib/"
+ },
+ {
+ "name": "bar",
+ "rootUri": "$sandboxUriPath/bar",
+ "packageUri": "lib/"
+ }
+ ]
+}
+'''),
+ ]),
+ d.dir('lib', [
+ d.file('foo.dart', 'final foo = "bar";'),
+ ]),
+ ]).create();
+
+ await d.dir('sdk', [
+ d.dir('io', [
+ d.file('io.dart', 'final io = "hello";'),
+ ]),
+ d.dir('io_patch', [
+ d.file('io.dart', 'final patch = true;'),
+ ]),
+ d.dir('io_dev', [
+ d.file('io.dart', 'final dev = true;'),
+ ]),
+ ]).create();
+ });
+
+ test('can be created from a package_config.json', () async {
+ final resolver = await Resolver.create(
+ packagesPath:
+ p.join(d.sandbox, 'foo', '.dart_tool', 'package_config.json'));
+ expect(resolver.resolve('package:foo/foo.dart'),
+ p.join(d.sandbox, 'foo', 'lib', 'foo.dart'));
+ expect(resolver.resolve('package:bar/bar.dart'),
+ p.join(d.sandbox, 'bar', 'lib', 'bar.dart'));
+ });
+
+ test('can be created from a package directory', () async {
+ final resolver =
+ await Resolver.create(packagePath: p.join(d.sandbox, 'foo'));
+ expect(resolver.resolve('package:foo/foo.dart'),
+ p.join(d.sandbox, 'foo', 'lib', 'foo.dart'));
+ });
+
+ test('errors if the packagesFile is an unknown format', () async {
+ expect(
+ () async => await Resolver.create(
+ packagesPath: p.join(
+ d.sandbox, 'foo', '.dart_tool', 'bad_package_config.json')),
+ throwsA(isA<FormatException>()));
+ });
+
+ test('resolves dart: URIs', () async {
+ final resolver = await Resolver.create(
+ packagePath: p.join(d.sandbox, 'foo'),
+ sdkRoot: p.join(d.sandbox, 'sdk'));
+ expect(resolver.resolve('dart:io'),
+ p.join(d.sandbox, 'sdk', 'io', 'io.dart'));
+ expect(resolver.resolve('dart:io-patch/io.dart'), null);
+ expect(resolver.resolve('dart:io-dev/io.dart'),
+ p.join(d.sandbox, 'sdk', 'io_dev', 'io.dart'));
+ });
+
+ test('cannot resolve SDK URIs if sdkRoot is null', () async {
+ final resolver =
+ await Resolver.create(packagePath: p.join(d.sandbox, 'foo'));
+ expect(resolver.resolve('dart:convert'), null);
+ });
+
+ test('cannot resolve package URIs if packagePath is null', () async {
+ // ignore: deprecated_member_use_from_same_package
+ final resolver = Resolver();
+ expect(resolver.resolve('package:foo/foo.dart'), null);
+ });
+
+ test('cannot resolve package URIs if packagePath is not found', () async {
+ final resolver =
+ await Resolver.create(packagePath: p.join(d.sandbox, 'foo'));
+ expect(resolver.resolve('package:baz/baz.dart'), null);
+ });
+
+ test('cannot resolve unexpected URI schemes', () async {
+ final resolver =
+ await Resolver.create(packagePath: p.join(d.sandbox, 'foo'));
+ expect(resolver.resolve('thing:foo/foo.dart'), null);
+ });
+ });
+
+ group('Bazel resolver', () {
+ const workspace = 'foo';
+ final resolver = BazelResolver(workspacePath: workspace);
+
+ test('does not resolve SDK URIs', () {
+ expect(resolver.resolve('dart:convert'), null);
+ });
+
+ test('resolves third-party package URIs', () {
+ expect(resolver.resolve('package:foo/bar.dart'),
+ 'third_party/dart/foo/lib/bar.dart');
+ expect(resolver.resolve('package:foo/src/bar.dart'),
+ 'third_party/dart/foo/lib/src/bar.dart');
+ });
+
+ test('resolves non-third-party package URIs', () {
+ expect(
+ resolver.resolve('package:foo.bar/baz.dart'), 'foo/bar/lib/baz.dart');
+ expect(resolver.resolve('package:foo.bar/src/baz.dart'),
+ 'foo/bar/lib/src/baz.dart');
+ });
+
+ test('resolves file URIs', () {
+ expect(
+ resolver
+ .resolve('file://x/y/z.runfiles/$workspace/foo/bar/lib/baz.dart'),
+ 'foo/bar/lib/baz.dart');
+ expect(
+ resolver.resolve(
+ 'file://x/y/z.runfiles/$workspace/foo/bar/lib/src/baz.dart'),
+ 'foo/bar/lib/src/baz.dart');
+ });
+
+ test('resolves HTTPS URIs containing /packages/', () {
+ expect(resolver.resolve('https://host:8080/a/b/packages/foo/bar.dart'),
+ 'third_party/dart/foo/lib/bar.dart');
+ expect(
+ resolver.resolve('https://host:8080/a/b/packages/foo/src/bar.dart'),
+ 'third_party/dart/foo/lib/src/bar.dart');
+ expect(
+ resolver.resolve('https://host:8080/a/b/packages/foo.bar/baz.dart'),
+ 'foo/bar/lib/baz.dart');
+ expect(
+ resolver
+ .resolve('https://host:8080/a/b/packages/foo.bar/src/baz.dart'),
+ 'foo/bar/lib/src/baz.dart');
+ });
+
+ test('resolves HTTP URIs containing /packages/', () {
+ expect(resolver.resolve('http://host:8080/a/b/packages/foo/bar.dart'),
+ 'third_party/dart/foo/lib/bar.dart');
+ expect(resolver.resolve('http://host:8080/a/b/packages/foo/src/bar.dart'),
+ 'third_party/dart/foo/lib/src/bar.dart');
+ expect(resolver.resolve('http://host:8080/a/b/packages/foo.bar/baz.dart'),
+ 'foo/bar/lib/baz.dart');
+ expect(
+ resolver
+ .resolve('http://host:8080/a/b/packages/foo.bar/src/baz.dart'),
+ 'foo/bar/lib/src/baz.dart');
+ });
+
+ test('resolves HTTPS URIs without /packages/', () {
+ expect(
+ resolver
+ .resolve('https://host:8080/third_party/dart/foo/lib/bar.dart'),
+ 'third_party/dart/foo/lib/bar.dart');
+ expect(
+ resolver.resolve(
+ 'https://host:8080/third_party/dart/foo/lib/src/bar.dart'),
+ 'third_party/dart/foo/lib/src/bar.dart');
+ expect(resolver.resolve('https://host:8080/foo/lib/bar.dart'),
+ 'foo/lib/bar.dart');
+ expect(resolver.resolve('https://host:8080/foo/lib/src/bar.dart'),
+ 'foo/lib/src/bar.dart');
+ });
+
+ test('resolves HTTP URIs without /packages/', () {
+ expect(
+ resolver
+ .resolve('http://host:8080/third_party/dart/foo/lib/bar.dart'),
+ 'third_party/dart/foo/lib/bar.dart');
+ expect(
+ resolver.resolve(
+ 'http://host:8080/third_party/dart/foo/lib/src/bar.dart'),
+ 'third_party/dart/foo/lib/src/bar.dart');
+ expect(resolver.resolve('http://host:8080/foo/lib/bar.dart'),
+ 'foo/lib/bar.dart');
+ expect(resolver.resolve('http://host:8080/foo/lib/src/bar.dart'),
+ 'foo/lib/src/bar.dart');
+ });
+ });
+}
diff --git a/pkgs/coverage/test/run_and_collect_test.dart b/pkgs/coverage/test/run_and_collect_test.dart
new file mode 100644
index 0000000..e371f90
--- /dev/null
+++ b/pkgs/coverage/test/run_and_collect_test.dart
@@ -0,0 +1,128 @@
+// 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:coverage/coverage.dart';
+import 'package:path/path.dart' as p;
+import 'package:test/test.dart';
+
+import 'test_util.dart';
+
+final _isolateLibPath = p.join('test', 'test_files', 'test_app_isolate.dart');
+
+final _sampleAppFileUri = p.toUri(p.absolute(testAppPath)).toString();
+final _isolateLibFileUri = p.toUri(p.absolute(_isolateLibPath)).toString();
+
+void main() {
+ test('runAndCollect', () async {
+ // use runAndCollect and verify that the results match w/ running manually
+ final coverage = coverageDataFromJson(await runAndCollect(testAppPath));
+ expect(coverage, isNotEmpty);
+
+ final sources = coverage.sources();
+
+ for (var sampleCoverageData in sources[_sampleAppFileUri]!) {
+ expect(sampleCoverageData['hits'], isNotNull);
+ }
+
+ for (var sampleCoverageData in sources[_isolateLibFileUri]!) {
+ expect(sampleCoverageData['hits'], isNotEmpty);
+ }
+
+ final hitMap = await HitMap.parseJson(coverage, checkIgnoredLines: true);
+ checkHitmap(hitMap);
+ final resolver = await Resolver.create();
+ final ignoredLinesInFilesCache = <String, List<List<int>>?>{};
+ final hitMap2 = HitMap.parseJsonSync(coverage,
+ checkIgnoredLines: true,
+ ignoredLinesInFilesCache: ignoredLinesInFilesCache,
+ resolver: resolver);
+ checkHitmap(hitMap2);
+ checkIgnoredLinesInFilesCache(ignoredLinesInFilesCache);
+
+ // Asking again the cache should answer questions about ignored lines,
+ // so providing a resolver that throws when asked for files should be ok.
+ final hitMap3 = HitMap.parseJsonSync(coverage,
+ checkIgnoredLines: true,
+ ignoredLinesInFilesCache: ignoredLinesInFilesCache,
+ resolver: ThrowingResolver());
+ checkHitmap(hitMap3);
+ checkIgnoredLinesInFilesCache(ignoredLinesInFilesCache);
+ });
+}
+
+class ThrowingResolver implements Resolver {
+ @override
+ List<String> get failed => throw UnimplementedError();
+
+ @override
+ String? get packagePath => throw UnimplementedError();
+
+ @override
+ String? get packagesPath => throw UnimplementedError();
+
+ @override
+ String? resolve(String scriptUri) => throw UnimplementedError();
+
+ @override
+ String? resolveSymbolicLinks(String path) => throw UnimplementedError();
+
+ @override
+ String? get sdkRoot => throw UnimplementedError();
+}
+
+void checkIgnoredLinesInFilesCache(
+ Map<String, List<List<int>>?> ignoredLinesInFilesCache) {
+ final keys = ignoredLinesInFilesCache.keys.toList();
+ final testAppKey =
+ keys.where((element) => element.endsWith('test_app.dart')).single;
+ final testAppIsolateKey =
+ keys.where((element) => element.endsWith('test_app_isolate.dart')).single;
+ final packageUtilKey = keys
+ .where((element) => element.endsWith('package:coverage/src/util.dart'))
+ .single;
+ expect(ignoredLinesInFilesCache[packageUtilKey], isEmpty);
+ expect(ignoredLinesInFilesCache[testAppKey], null /* means whole file */);
+ expect(ignoredLinesInFilesCache[testAppIsolateKey], [
+ [51, 51],
+ [53, 57],
+ [62, 65],
+ [66, 72]
+ ]);
+}
+
+void checkHitmap(Map<String, HitMap> hitMap) {
+ expect(hitMap, isNot(contains(_sampleAppFileUri)));
+
+ final actualHitMap = hitMap[_isolateLibFileUri];
+ final actualLineHits = actualHitMap?.lineHits;
+ final expectedLineHits = {
+ 11: 1,
+ 12: 1,
+ 13: 1,
+ 15: 0,
+ 19: 1,
+ 23: 1,
+ 24: 2,
+ 28: 1,
+ 29: 1,
+ 30: 1,
+ 32: 0,
+ 38: 1,
+ 39: 1,
+ 41: 1,
+ 42: 4,
+ 43: 1,
+ 44: 3,
+ 45: 1,
+ 48: 1,
+ 49: 1,
+ 59: 1,
+ 60: 1
+ };
+
+ expect(actualLineHits, expectedLineHits);
+ expect(actualHitMap?.funcHits, isNull);
+ expect(actualHitMap?.funcNames, isNull);
+ expect(actualHitMap?.branchHits, isNull);
+}
diff --git a/pkgs/coverage/test/test_files/chrome_precise_report.txt b/pkgs/coverage/test/test_files/chrome_precise_report.txt
new file mode 100644
index 0000000..41a3e64
--- /dev/null
+++ b/pkgs/coverage/test/test_files/chrome_precise_report.txt
@@ -0,0 +1 @@
+[{"scriptId":"5","url":"http://localhost:33587/JvrQonmMf3ATS3rRCO76ZTlBfGvy%2Fj69/packages/test/src/runner/browser/static/host.dart.js","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":598832,"count":1}],"isBlockCoverage":true},{"functionName":"dartProgram","ranges":[{"startOffset":1228,"endOffset":598788,"count":1}],"isBlockCoverage":true},{"functionName":"copyProperties","ranges":[{"startOffset":1255,"endOffset":1430,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1465,"endOffset":2035,"count":1},{"startOffset":1646,"endOffset":1659,"count":0},{"startOffset":1822,"endOffset":1884,"count":0},{"startOffset":1886,"endOffset":1989,"count":0},{"startOffset":1995,"endOffset":2034,"count":0}],"isBlockCoverage":true},{"functionName":"cls","ranges":[{"startOffset":1492,"endOffset":1510,"count":1}],"isBlockCoverage":true},{"functionName":"setFunctionNamesIfNecessary","ranges":[{"startOffset":2041,"endOffset":2464,"count":1},{"startOffset":2168,"endOffset":2460,"count":0}],"isBlockCoverage":true},{"functionName":"t","ranges":[{"startOffset":2093,"endOffset":2113,"count":0}],"isBlockCoverage":false},{"functionName":"inherit","ranges":[{"startOffset":2467,"endOffset":2862,"count":1},{"startOffset":2710,"endOffset":2858,"count":0}],"isBlockCoverage":true},{"functionName":"inheritMany","ranges":[{"startOffset":2865,"endOffset":2982,"count":1}],"isBlockCoverage":true},{"functionName":"mixin","ranges":[{"startOffset":2985,"endOffset":3106,"count":1}],"isBlockCoverage":true},{"functionName":"lazy","ranges":[{"startOffset":3109,"endOffset":3858,"count":1}],"isBlockCoverage":true},{"functionName":"holder.<computed>","ranges":[{"startOffset":3271,"endOffset":3853,"count":1},{"startOffset":3606,"endOffset":3644,"count":0},{"startOffset":3716,"endOffset":3736,"count":0}],"isBlockCoverage":true},{"functionName":"holder.<computed>","ranges":[{"startOffset":3311,"endOffset":3364,"count":0}],"isBlockCoverage":false},{"functionName":"holder.<computed>","ranges":[{"startOffset":3766,"endOffset":3817,"count":1}],"isBlockCoverage":true},{"functionName":"makeConstList","ranges":[{"startOffset":3861,"endOffset":3976,"count":1}],"isBlockCoverage":true},{"functionName":"convertToFastObject","ranges":[{"startOffset":3979,"endOffset":4116,"count":1}],"isBlockCoverage":true},{"functionName":"t","ranges":[{"startOffset":4026,"endOffset":4046,"count":1}],"isBlockCoverage":true},{"functionName":"convertAllToFastObject","ranges":[{"startOffset":4119,"endOffset":4270,"count":1}],"isBlockCoverage":true},{"functionName":"tearOffGetter","ranges":[{"startOffset":4300,"endOffset":5215,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff","ranges":[{"startOffset":5218,"endOffset":5626,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":5357,"endOffset":5539,"count":1}],"isBlockCoverage":true},{"functionName":"installTearOff","ranges":[{"startOffset":5652,"endOffset":6582,"count":1}],"isBlockCoverage":true},{"functionName":"installStaticTearOff","ranges":[{"startOffset":6585,"endOffset":6908,"count":1}],"isBlockCoverage":true},{"functionName":"installInstanceTearOff","ranges":[{"startOffset":6911,"endOffset":7260,"count":1}],"isBlockCoverage":true},{"functionName":"setOrUpdateInterceptorsByTag","ranges":[{"startOffset":7263,"endOffset":7466,"count":1},{"startOffset":7427,"endOffset":7465,"count":0}],"isBlockCoverage":true},{"functionName":"setOrUpdateLeafTags","ranges":[{"startOffset":7469,"endOffset":7645,"count":1},{"startOffset":7606,"endOffset":7644,"count":0}],"isBlockCoverage":true},{"functionName":"updateTypes","ranges":[{"startOffset":7648,"endOffset":7801,"count":0}],"isBlockCoverage":false},{"functionName":"updateHolder","ranges":[{"startOffset":7804,"endOffset":7908,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":7929,"endOffset":9593,"count":1}],"isBlockCoverage":true},{"functionName":"mkInstance","ranges":[{"startOffset":7963,"endOffset":8325,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":8083,"endOffset":8316,"count":1}],"isBlockCoverage":true},{"functionName":"mkStatic","ranges":[{"startOffset":8344,"endOffset":8674,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":8449,"endOffset":8665,"count":1}],"isBlockCoverage":true},{"functionName":"initializeDeferredHunk","ranges":[{"startOffset":9599,"endOffset":9720,"count":0}],"isBlockCoverage":false},{"functionName":"getGlobalFromName","ranges":[{"startOffset":9723,"endOffset":9920,"count":0}],"isBlockCoverage":false},{"functionName":"JS_CONST","ranges":[{"startOffset":9952,"endOffset":9979,"count":0}],"isBlockCoverage":false},{"functionName":"hexDigitValue","ranges":[{"startOffset":10000,"endOffset":10228,"count":1},{"startOffset":10205,"endOffset":10227,"count":0}],"isBlockCoverage":true},{"functionName":"SubListIterable$","ranges":[{"startOffset":10252,"endOffset":10660,"count":0}],"isBlockCoverage":false},{"functionName":"MappedIterable_MappedIterable","ranges":[{"startOffset":10697,"endOffset":11098,"count":0}],"isBlockCoverage":false},{"functionName":"IterableElementError_noElement","ranges":[{"startOffset":11136,"endOffset":11199,"count":0}],"isBlockCoverage":false},{"functionName":"IterableElementError_tooFew","ranges":[{"startOffset":11234,"endOffset":11303,"count":0}],"isBlockCoverage":false},{"functionName":"CodeUnits","ranges":[{"startOffset":11320,"endOffset":11375,"count":0}],"isBlockCoverage":false},{"functionName":"EfficientLengthIterable","ranges":[{"startOffset":11406,"endOffset":11448,"count":0}],"isBlockCoverage":false},{"functionName":"ListIterable","ranges":[{"startOffset":11468,"endOffset":11499,"count":0}],"isBlockCoverage":false},{"functionName":"SubListIterable","ranges":[{"startOffset":11522,"endOffset":11702,"count":0}],"isBlockCoverage":false},{"functionName":"ListIterator","ranges":[{"startOffset":11722,"endOffset":11941,"count":0}],"isBlockCoverage":false},{"functionName":"MappedIterable","ranges":[{"startOffset":11963,"endOffset":12085,"count":0}],"isBlockCoverage":false},{"functionName":"EfficientLengthMappedIterable","ranges":[{"startOffset":12122,"endOffset":12259,"count":0}],"isBlockCoverage":false},{"functionName":"MappedIterator","ranges":[{"startOffset":12281,"endOffset":12439,"count":0}],"isBlockCoverage":false},{"functionName":"MappedListIterable","ranges":[{"startOffset":12465,"endOffset":12578,"count":0}],"isBlockCoverage":false},{"functionName":"WhereIterable","ranges":[{"startOffset":12599,"endOffset":12720,"count":0}],"isBlockCoverage":false},{"functionName":"WhereIterator","ranges":[{"startOffset":12741,"endOffset":12851,"count":0}],"isBlockCoverage":false},{"functionName":"ExpandIterable","ranges":[{"startOffset":12873,"endOffset":12995,"count":0}],"isBlockCoverage":false},{"functionName":"ExpandIterator","ranges":[{"startOffset":13017,"endOffset":13211,"count":0}],"isBlockCoverage":false},{"functionName":"SkipWhileIterable","ranges":[{"startOffset":13236,"endOffset":13361,"count":0}],"isBlockCoverage":false},{"functionName":"SkipWhileIterator","ranges":[{"startOffset":13386,"endOffset":13540,"count":0}],"isBlockCoverage":false},{"functionName":"EmptyIterator","ranges":[{"startOffset":13561,"endOffset":13616,"count":1}],"isBlockCoverage":true},{"functionName":"FixedLengthListMixin","ranges":[{"startOffset":13644,"endOffset":13683,"count":0}],"isBlockCoverage":false},{"functionName":"UnmodifiableListMixin","ranges":[{"startOffset":13712,"endOffset":13752,"count":0}],"isBlockCoverage":false},{"functionName":"UnmodifiableListBase","ranges":[{"startOffset":13780,"endOffset":13819,"count":0}],"isBlockCoverage":false},{"functionName":"ReversedListIterable","ranges":[{"startOffset":13847,"endOffset":13938,"count":0}],"isBlockCoverage":false},{"functionName":"Symbol","ranges":[{"startOffset":13952,"endOffset":14013,"count":1}],"isBlockCoverage":true},{"functionName":"ConstantMap__throwUnmodifiable","ranges":[{"startOffset":14051,"endOffset":14153,"count":0}],"isBlockCoverage":false},{"functionName":"instantiate1","ranges":[{"startOffset":14173,"endOffset":14345,"count":0}],"isBlockCoverage":false},{"functionName":"unminifyOrTag","ranges":[{"startOffset":14366,"endOffset":14570,"count":0}],"isBlockCoverage":false},{"functionName":"getType","ranges":[{"startOffset":14585,"endOffset":14656,"count":1}],"isBlockCoverage":true},{"functionName":"isJsIndexable","ranges":[{"startOffset":14677,"endOffset":14915,"count":0}],"isBlockCoverage":false},{"functionName":"S","ranges":[{"startOffset":14924,"endOffset":15426,"count":1},{"startOffset":15015,"endOffset":15425,"count":0}],"isBlockCoverage":true},{"functionName":"Primitives_objectHashCode","ranges":[{"startOffset":15459,"endOffset":15659,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_parseInt","ranges":[{"startOffset":15686,"endOffset":16847,"count":1},{"startOffset":15821,"endOffset":15869,"count":0},{"startOffset":15981,"endOffset":15988,"count":0},{"startOffset":16026,"endOffset":16051,"count":0},{"startOffset":16201,"endOffset":16328,"count":0},{"startOffset":16338,"endOffset":16456,"count":0},{"startOffset":16466,"endOffset":16539,"count":0},{"startOffset":16541,"endOffset":16846,"count":0}],"isBlockCoverage":true},{"functionName":"Primitives_objectTypeName","ranges":[{"startOffset":16880,"endOffset":17014,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives__objectClassName","ranges":[{"startOffset":17049,"endOffset":18437,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_currentUri","ranges":[{"startOffset":18466,"endOffset":18560,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives__fromCharCodeApply","ranges":[{"startOffset":18597,"endOffset":19022,"count":1},{"startOffset":18798,"endOffset":19021,"count":0}],"isBlockCoverage":true},{"functionName":"Primitives_stringFromCodePoints","ranges":[{"startOffset":19061,"endOffset":19851,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_stringFromCharCodes","ranges":[{"startOffset":19889,"endOffset":20367,"count":1},{"startOffset":20086,"endOffset":20133,"count":0},{"startOffset":20163,"endOffset":20210,"count":0},{"startOffset":20244,"endOffset":20296,"count":0}],"isBlockCoverage":true},{"functionName":"Primitives_stringFromNativeUint8List","ranges":[{"startOffset":20411,"endOffset":20838,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_stringFromCharCode","ranges":[{"startOffset":20875,"endOffset":21388,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_lazyAsJsDate","ranges":[{"startOffset":21419,"endOffset":21566,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_getYear","ranges":[{"startOffset":21592,"endOffset":21708,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_getMonth","ranges":[{"startOffset":21735,"endOffset":21848,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_getDay","ranges":[{"startOffset":21873,"endOffset":21985,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_getHours","ranges":[{"startOffset":22012,"endOffset":22125,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_getMinutes","ranges":[{"startOffset":22154,"endOffset":22269,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_getSeconds","ranges":[{"startOffset":22298,"endOffset":22413,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_getMilliseconds","ranges":[{"startOffset":22447,"endOffset":22567,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_functionNoSuchMethod","ranges":[{"startOffset":22606,"endOffset":23376,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_applyFunction","ranges":[{"startOffset":23408,"endOffset":25001,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives__genericApplyFunction2","ranges":[{"startOffset":25042,"endOffset":28197,"count":0}],"isBlockCoverage":false},{"functionName":"iae","ranges":[{"startOffset":28208,"endOffset":28295,"count":0}],"isBlockCoverage":false},{"functionName":"ioore","ranges":[{"startOffset":28308,"endOffset":28473,"count":0}],"isBlockCoverage":false},{"functionName":"diagnoseIndexError","ranges":[{"startOffset":28499,"endOffset":29047,"count":0}],"isBlockCoverage":false},{"functionName":"diagnoseRangeError","ranges":[{"startOffset":29073,"endOffset":29430,"count":0}],"isBlockCoverage":false},{"functionName":"argumentErrorValue","ranges":[{"startOffset":29456,"endOffset":29540,"count":0}],"isBlockCoverage":false},{"functionName":"checkNum","ranges":[{"startOffset":29556,"endOffset":29696,"count":0}],"isBlockCoverage":false},{"functionName":"wrapException","ranges":[{"startOffset":29717,"endOffset":30104,"count":0}],"isBlockCoverage":false},{"functionName":"toStringWrapper","ranges":[{"startOffset":30127,"endOffset":30193,"count":0}],"isBlockCoverage":false},{"functionName":"throwExpression","ranges":[{"startOffset":30216,"endOffset":30269,"count":0}],"isBlockCoverage":false},{"functionName":"throwConcurrentModificationError","ranges":[{"startOffset":30309,"endOffset":30410,"count":0}],"isBlockCoverage":false},{"functionName":"TypeErrorDecoder_extractPattern","ranges":[{"startOffset":30449,"endOffset":31458,"count":0}],"isBlockCoverage":false},{"functionName":"TypeErrorDecoder_provokeCallErrorOn","ranges":[{"startOffset":31501,"endOffset":31745,"count":0}],"isBlockCoverage":false},{"functionName":"TypeErrorDecoder_provokePropertyErrorOn","ranges":[{"startOffset":31792,"endOffset":31974,"count":0}],"isBlockCoverage":false},{"functionName":"NullError$","ranges":[{"startOffset":31992,"endOffset":32102,"count":0}],"isBlockCoverage":false},{"functionName":"JsNoSuchMethodError$","ranges":[{"startOffset":32130,"endOffset":32326,"count":0}],"isBlockCoverage":false},{"functionName":"unwrapException","ranges":[{"startOffset":32349,"endOffset":36809,"count":0}],"isBlockCoverage":false},{"functionName":"getTraceFromException","ranges":[{"startOffset":36838,"endOffset":37203,"count":0}],"isBlockCoverage":false},{"functionName":"fillLiteralMap","ranges":[{"startOffset":37225,"endOffset":37561,"count":0}],"isBlockCoverage":false},{"functionName":"invokeClosure","ranges":[{"startOffset":37582,"endOffset":38172,"count":1},{"startOffset":37758,"endOffset":37800,"count":0},{"startOffset":37864,"endOffset":37916,"count":0},{"startOffset":37925,"endOffset":37983,"count":0},{"startOffset":37992,"endOffset":38056,"count":0},{"startOffset":38064,"endOffset":38171,"count":0}],"isBlockCoverage":true},{"functionName":"convertDartClosureToJS","ranges":[{"startOffset":38202,"endOffset":38679,"count":1},{"startOffset":38314,"endOffset":38321,"count":0},{"startOffset":38390,"endOffset":38407,"count":0}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":38426,"endOffset":38578,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":38476,"endOffset":38569,"count":1}],"isBlockCoverage":true},{"functionName":"Closure_fromTearOff","ranges":[{"startOffset":38706,"endOffset":41471,"count":1},{"startOffset":39469,"endOffset":39486,"count":0},{"startOffset":40204,"endOffset":40709,"count":0}],"isBlockCoverage":true},{"functionName":"static_tear_off","ranges":[{"startOffset":39300,"endOffset":39368,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":40070,"endOffset":40176,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":40110,"endOffset":40165,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":40461,"endOffset":40599,"count":0}],"isBlockCoverage":false},{"functionName":"Closure_cspForwardCall","ranges":[{"startOffset":41501,"endOffset":42886,"count":1},{"startOffset":41627,"endOffset":41634,"count":0},{"startOffset":41646,"endOffset":41801,"count":0},{"startOffset":41810,"endOffset":41967,"count":0},{"startOffset":41976,"endOffset":42139,"count":0},{"startOffset":42148,"endOffset":42317,"count":0},{"startOffset":42326,"endOffset":42501,"count":0},{"startOffset":42510,"endOffset":42691,"count":0}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":41671,"endOffset":41781,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":41835,"endOffset":41947,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":42001,"endOffset":42119,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":42173,"endOffset":42297,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":42351,"endOffset":42481,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":42535,"endOffset":42671,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":42726,"endOffset":42851,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":42762,"endOffset":42838,"count":0}],"isBlockCoverage":false},{"functionName":"Closure_forwardCallTo","ranges":[{"startOffset":42915,"endOffset":44616,"count":1},{"startOffset":43278,"endOffset":43304,"count":0},{"startOffset":43569,"endOffset":43586,"count":0},{"startOffset":43798,"endOffset":43916,"count":0},{"startOffset":44191,"endOffset":44208,"count":0},{"startOffset":44406,"endOffset":44518,"count":0}],"isBlockCoverage":true},{"functionName":"Closure_cspForwardInterceptedCall","ranges":[{"startOffset":44657,"endOffset":46449,"count":1},{"startOffset":44855,"endOffset":44862,"count":0},{"startOffset":44874,"endOffset":44974,"count":0},{"startOffset":44983,"endOffset":45158,"count":0},{"startOffset":45167,"endOffset":45346,"count":0},{"startOffset":45355,"endOffset":45540,"count":0},{"startOffset":45549,"endOffset":45740,"count":0},{"startOffset":45749,"endOffset":45946,"count":0},{"startOffset":45955,"endOffset":46158,"count":0}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":45008,"endOffset":45128,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":45192,"endOffset":45316,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":45380,"endOffset":45510,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":45574,"endOffset":45710,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":45774,"endOffset":45916,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":45980,"endOffset":46128,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":46193,"endOffset":46401,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":46235,"endOffset":46388,"count":0}],"isBlockCoverage":false},{"functionName":"Closure_forwardInterceptedCallTo","ranges":[{"startOffset":46489,"endOffset":48059,"count":1},{"startOffset":47112,"endOffset":47138,"count":0},{"startOffset":47326,"endOffset":47636,"count":0},{"startOffset":47950,"endOffset":47967,"count":0}],"isBlockCoverage":true},{"functionName":"closureFromTearOff","ranges":[{"startOffset":48085,"endOffset":48339,"count":1}],"isBlockCoverage":true},{"functionName":"BoundClosure_selfOf","ranges":[{"startOffset":48366,"endOffset":48419,"count":0}],"isBlockCoverage":false},{"functionName":"BoundClosure_receiverOf","ranges":[{"startOffset":48450,"endOffset":48507,"count":0}],"isBlockCoverage":false},{"functionName":"BoundClosure_computeFieldNamed","ranges":[{"startOffset":48545,"endOffset":48918,"count":1}],"isBlockCoverage":true},{"functionName":"stringTypeCheck","ranges":[{"startOffset":48941,"endOffset":49144,"count":1},{"startOffset":48992,"endOffset":49005,"count":0},{"startOffset":49064,"endOffset":49143,"count":0}],"isBlockCoverage":true},{"functionName":"stringTypeCast","ranges":[{"startOffset":49166,"endOffset":49339,"count":1},{"startOffset":49220,"endOffset":49236,"count":0},{"startOffset":49259,"endOffset":49338,"count":0}],"isBlockCoverage":true},{"functionName":"doubleTypeCheck","ranges":[{"startOffset":49362,"endOffset":49565,"count":0}],"isBlockCoverage":false},{"functionName":"numTypeCheck","ranges":[{"startOffset":49585,"endOffset":49785,"count":0}],"isBlockCoverage":false},{"functionName":"boolTypeCheck","ranges":[{"startOffset":49806,"endOffset":50008,"count":0}],"isBlockCoverage":false},{"functionName":"intTypeCheck","ranges":[{"startOffset":50028,"endOffset":50259,"count":1},{"startOffset":50079,"endOffset":50092,"count":0},{"startOffset":50182,"endOffset":50258,"count":0}],"isBlockCoverage":true},{"functionName":"intTypeCast","ranges":[{"startOffset":50278,"endOffset":50479,"count":1},{"startOffset":50363,"endOffset":50379,"count":0},{"startOffset":50402,"endOffset":50478,"count":0}],"isBlockCoverage":true},{"functionName":"propertyTypeError","ranges":[{"startOffset":50504,"endOffset":50660,"count":0}],"isBlockCoverage":false},{"functionName":"interceptedTypeCheck","ranges":[{"startOffset":50688,"endOffset":50942,"count":1},{"startOffset":50800,"endOffset":50830,"count":0},{"startOffset":50892,"endOffset":50941,"count":0}],"isBlockCoverage":true},{"functionName":"stringSuperNativeTypeCheck","ranges":[{"startOffset":50976,"endOffset":51227,"count":0}],"isBlockCoverage":false},{"functionName":"listTypeCheck","ranges":[{"startOffset":51248,"endOffset":51467,"count":1},{"startOffset":51380,"endOffset":51466,"count":0}],"isBlockCoverage":true},{"functionName":"listSuperNativeTypeCheck","ranges":[{"startOffset":51499,"endOffset":51766,"count":0}],"isBlockCoverage":false},{"functionName":"extractFunctionTypeObjectFromInternal","ranges":[{"startOffset":51811,"endOffset":52082,"count":1},{"startOffset":52062,"endOffset":52081,"count":0}],"isBlockCoverage":true},{"functionName":"functionTypeTest","ranges":[{"startOffset":52106,"endOffset":52520,"count":1},{"startOffset":52204,"endOffset":52217,"count":0},{"startOffset":52417,"endOffset":52430,"count":0}],"isBlockCoverage":true},{"functionName":"functionTypeCheck","ranges":[{"startOffset":52545,"endOffset":53038,"count":1},{"startOffset":52686,"endOffset":52699,"count":0},{"startOffset":52824,"endOffset":52979,"count":0}],"isBlockCoverage":true},{"functionName":"futureOrCheck","ranges":[{"startOffset":53059,"endOffset":53270,"count":1},{"startOffset":53106,"endOffset":53153,"count":0},{"startOffset":53163,"endOffset":53248,"count":0}],"isBlockCoverage":true},{"functionName":"TypeErrorImplementation$","ranges":[{"startOffset":53302,"endOffset":53507,"count":0}],"isBlockCoverage":false},{"functionName":"CastErrorImplementation$","ranges":[{"startOffset":53539,"endOffset":53744,"count":0}],"isBlockCoverage":false},{"functionName":"_typeDescription","ranges":[{"startOffset":53768,"endOffset":54148,"count":0}],"isBlockCoverage":false},{"functionName":"throwCyclicInit","ranges":[{"startOffset":54171,"endOffset":54292,"count":0}],"isBlockCoverage":false},{"functionName":"RuntimeError$","ranges":[{"startOffset":54313,"endOffset":54380,"count":0}],"isBlockCoverage":false},{"functionName":"getIsolateAffinityTag","ranges":[{"startOffset":54409,"endOffset":54472,"count":1}],"isBlockCoverage":true},{"functionName":"setRuntimeTypeInfo","ranges":[{"startOffset":54498,"endOffset":54572,"count":1}],"isBlockCoverage":true},{"functionName":"getRuntimeTypeInfo","ranges":[{"startOffset":54598,"endOffset":54689,"count":1},{"startOffset":54651,"endOffset":54658,"count":0}],"isBlockCoverage":true},{"functionName":"getRuntimeTypeArguments","ranges":[{"startOffset":54720,"endOffset":54876,"count":0}],"isBlockCoverage":false},{"functionName":"getRuntimeTypeArgumentIntercepted","ranges":[{"startOffset":54917,"endOffset":55240,"count":1},{"startOffset":55207,"endOffset":55213,"count":0}],"isBlockCoverage":true},{"functionName":"getRuntimeTypeArgument","ranges":[{"startOffset":55270,"endOffset":55575,"count":1},{"startOffset":55542,"endOffset":55548,"count":0}],"isBlockCoverage":true},{"functionName":"getTypeArgumentByIndex","ranges":[{"startOffset":55605,"endOffset":55768,"count":1}],"isBlockCoverage":true},{"functionName":"runtimeTypeToString","ranges":[{"startOffset":55795,"endOffset":55864,"count":0}],"isBlockCoverage":false},{"functionName":"_runtimeTypeToString","ranges":[{"startOffset":55892,"endOffset":57053,"count":0}],"isBlockCoverage":false},{"functionName":"_functionRtiToString","ranges":[{"startOffset":57081,"endOffset":59945,"count":0}],"isBlockCoverage":false},{"functionName":"_joinArguments","ranges":[{"startOffset":59967,"endOffset":60636,"count":0}],"isBlockCoverage":false},{"functionName":"substitute","ranges":[{"startOffset":60654,"endOffset":61121,"count":1},{"startOffset":60849,"endOffset":60856,"count":0},{"startOffset":60992,"endOffset":61120,"count":0}],"isBlockCoverage":true},{"functionName":"checkSubtype","ranges":[{"startOffset":61141,"endOffset":61627,"count":1},{"startOffset":61512,"endOffset":61525,"count":0}],"isBlockCoverage":true},{"functionName":"assertSubtype","ranges":[{"startOffset":61648,"endOffset":62224,"count":1},{"startOffset":61923,"endOffset":62223,"count":0}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":61987,"endOffset":62115,"count":0}],"isBlockCoverage":false},{"functionName":"assertIsSubtype","ranges":[{"startOffset":62247,"endOffset":62611,"count":1},{"startOffset":62464,"endOffset":62605,"count":0}],"isBlockCoverage":true},{"functionName":"throwTypeError","ranges":[{"startOffset":62633,"endOffset":62746,"count":0}],"isBlockCoverage":false},{"functionName":"areSubtypes","ranges":[{"startOffset":62765,"endOffset":63196,"count":1},{"startOffset":62841,"endOffset":62853,"count":0},{"startOffset":62875,"endOffset":63042,"count":0},{"startOffset":63158,"endOffset":63171,"count":0}],"isBlockCoverage":true},{"functionName":"computeSignature","ranges":[{"startOffset":63220,"endOffset":63407,"count":0}],"isBlockCoverage":false},{"functionName":"isSupertypeOfNullRecursive","ranges":[{"startOffset":63441,"endOffset":63818,"count":0}],"isBlockCoverage":false},{"functionName":"checkSubtypeOfRuntimeType","ranges":[{"startOffset":63851,"endOffset":64616,"count":1},{"startOffset":63918,"endOffset":64038,"count":0},{"startOffset":64201,"endOffset":64290,"count":0}],"isBlockCoverage":true},{"functionName":"assertSubtypeOfRuntimeType","ranges":[{"startOffset":64650,"endOffset":64869,"count":1},{"startOffset":64755,"endOffset":64842,"count":0}],"isBlockCoverage":true},{"functionName":"_isSubtype","ranges":[{"startOffset":64887,"endOffset":67156,"count":1},{"startOffset":65190,"endOffset":65202,"count":0},{"startOffset":65318,"endOffset":65331,"count":0},{"startOffset":65421,"endOffset":65427,"count":0},{"startOffset":65435,"endOffset":65465,"count":0},{"startOffset":65507,"endOffset":65520,"count":0},{"startOffset":65562,"endOffset":65575,"count":0},{"startOffset":65945,"endOffset":65951,"count":0},{"startOffset":65992,"endOffset":66068,"count":0},{"startOffset":66152,"endOffset":66605,"count":0},{"startOffset":66860,"endOffset":66873,"count":0},{"startOffset":67044,"endOffset":67050,"count":0}],"isBlockCoverage":true},{"functionName":"_isFunctionSubtype","ranges":[{"startOffset":67182,"endOffset":69335,"count":1},{"startOffset":67490,"endOffset":67503,"count":0},{"startOffset":67571,"endOffset":67584,"count":0},{"startOffset":67698,"endOffset":67711,"count":0},{"startOffset":67752,"endOffset":67765,"count":0},{"startOffset":67825,"endOffset":67838,"count":0},{"startOffset":68299,"endOffset":68331,"count":0},{"startOffset":68388,"endOffset":68401,"count":0},{"startOffset":68503,"endOffset":68516,"count":0},{"startOffset":68659,"endOffset":68672,"count":0},{"startOffset":68848,"endOffset":68861,"count":0},{"startOffset":68938,"endOffset":69054,"count":0},{"startOffset":69179,"endOffset":69334,"count":0}],"isBlockCoverage":true},{"functionName":"namedParametersSubtypeCheck","ranges":[{"startOffset":69370,"endOffset":69743,"count":0}],"isBlockCoverage":false},{"functionName":"instantiatedGenericFunctionType","ranges":[{"startOffset":69782,"endOffset":69981,"count":0}],"isBlockCoverage":false},{"functionName":"finishBindInstantiatedFunctionType","ranges":[{"startOffset":70023,"endOffset":70893,"count":0}],"isBlockCoverage":false},{"functionName":"bindInstantiatedType","ranges":[{"startOffset":70921,"endOffset":71830,"count":0}],"isBlockCoverage":false},{"functionName":"bindInstantiatedTypes","ranges":[{"startOffset":71859,"endOffset":72120,"count":0}],"isBlockCoverage":false},{"functionName":"JsLinkedHashMap_JsLinkedHashMap$es6","ranges":[{"startOffset":72163,"endOffset":72233,"count":1}],"isBlockCoverage":true},{"functionName":"defineProperty","ranges":[{"startOffset":72255,"endOffset":72427,"count":0}],"isBlockCoverage":false},{"functionName":"lookupAndCacheInterceptor","ranges":[{"startOffset":72460,"endOffset":74952,"count":0}],"isBlockCoverage":false},{"functionName":"patchInteriorProto","ranges":[{"startOffset":74978,"endOffset":75265,"count":0}],"isBlockCoverage":false},{"functionName":"makeLeafDispatchRecord","ranges":[{"startOffset":75295,"endOffset":75430,"count":1}],"isBlockCoverage":true},{"functionName":"makeDefaultDispatchRecord","ranges":[{"startOffset":75463,"endOffset":75734,"count":1}],"isBlockCoverage":true},{"functionName":"initNativeDispatch","ranges":[{"startOffset":75760,"endOffset":75916,"count":1},{"startOffset":75826,"endOffset":75833,"count":0}],"isBlockCoverage":true},{"functionName":"initNativeDispatchContinue","ranges":[{"startOffset":75950,"endOffset":77230,"count":1}],"isBlockCoverage":true},{"functionName":"fun","ranges":[{"startOffset":76329,"endOffset":76351,"count":0}],"isBlockCoverage":false},{"functionName":"initHooks","ranges":[{"startOffset":77247,"endOffset":78506,"count":1},{"startOffset":77761,"endOffset":78174,"count":0}],"isBlockCoverage":true},{"functionName":"applyHooksTransformer","ranges":[{"startOffset":78535,"endOffset":78613,"count":1}],"isBlockCoverage":true},{"functionName":"JSSyntaxRegExp_makeNative","ranges":[{"startOffset":78646,"endOffset":79188,"count":0}],"isBlockCoverage":false},{"functionName":"stringContainsUnchecked","ranges":[{"startOffset":79219,"endOffset":79767,"count":0}],"isBlockCoverage":false},{"functionName":"stringReplaceFirstRE","ranges":[{"startOffset":79795,"endOffset":80070,"count":0}],"isBlockCoverage":false},{"functionName":"stringReplaceAllUnchecked","ranges":[{"startOffset":80103,"endOffset":81120,"count":0}],"isBlockCoverage":false},{"functionName":"stringReplaceFirstUnchecked","ranges":[{"startOffset":81155,"endOffset":82205,"count":0}],"isBlockCoverage":false},{"functionName":"stringReplaceRangeUnchecked","ranges":[{"startOffset":82240,"endOffset":82446,"count":0}],"isBlockCoverage":false},{"functionName":"ConstantMapView","ranges":[{"startOffset":82469,"endOffset":82552,"count":0}],"isBlockCoverage":false},{"functionName":"ConstantMap","ranges":[{"startOffset":82571,"endOffset":82601,"count":0}],"isBlockCoverage":false},{"functionName":"ConstantStringMap","ranges":[{"startOffset":82626,"endOffset":82792,"count":1}],"isBlockCoverage":true},{"functionName":"Instantiation","ranges":[{"startOffset":82813,"endOffset":82845,"count":0}],"isBlockCoverage":false},{"functionName":"Instantiation1","ranges":[{"startOffset":82867,"endOffset":82960,"count":0}],"isBlockCoverage":false},{"functionName":"JSInvocationMirror","ranges":[{"startOffset":82986,"endOffset":83199,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_functionNoSuchMethod_closure","ranges":[{"startOffset":83246,"endOffset":83401,"count":0}],"isBlockCoverage":false},{"functionName":"TypeErrorDecoder","ranges":[{"startOffset":83425,"endOffset":83645,"count":0}],"isBlockCoverage":false},{"functionName":"NullError","ranges":[{"startOffset":83662,"endOffset":83747,"count":0}],"isBlockCoverage":false},{"functionName":"JsNoSuchMethodError","ranges":[{"startOffset":83774,"endOffset":83900,"count":0}],"isBlockCoverage":false},{"functionName":"UnknownJsTypeError","ranges":[{"startOffset":83926,"endOffset":83991,"count":0}],"isBlockCoverage":false},{"functionName":"ExceptionAndStackTrace","ranges":[{"startOffset":84021,"endOffset":84127,"count":0}],"isBlockCoverage":false},{"functionName":"unwrapException_saveStackTrace","ranges":[{"startOffset":84165,"endOffset":84236,"count":0}],"isBlockCoverage":false},{"functionName":"_StackTrace","ranges":[{"startOffset":84255,"endOffset":84353,"count":0}],"isBlockCoverage":false},{"functionName":"Closure","ranges":[{"startOffset":84368,"endOffset":84394,"count":0}],"isBlockCoverage":false},{"functionName":"TearOffClosure","ranges":[{"startOffset":84416,"endOffset":84449,"count":0}],"isBlockCoverage":false},{"functionName":"StaticClosure","ranges":[{"startOffset":84470,"endOffset":84502,"count":1}],"isBlockCoverage":true},{"functionName":"BoundClosure","ranges":[{"startOffset":84522,"endOffset":84673,"count":1}],"isBlockCoverage":true},{"functionName":"TypeErrorImplementation","ranges":[{"startOffset":84704,"endOffset":84773,"count":0}],"isBlockCoverage":false},{"functionName":"CastErrorImplementation","ranges":[{"startOffset":84804,"endOffset":84873,"count":0}],"isBlockCoverage":false},{"functionName":"RuntimeError","ranges":[{"startOffset":84893,"endOffset":84951,"count":0}],"isBlockCoverage":false},{"functionName":"TypeImpl","ranges":[{"startOffset":84967,"endOffset":85065,"count":0}],"isBlockCoverage":false},{"functionName":"JsLinkedHashMap","ranges":[{"startOffset":85088,"endOffset":85289,"count":1}],"isBlockCoverage":true},{"functionName":"JsLinkedHashMap_values_closure","ranges":[{"startOffset":85327,"endOffset":85401,"count":0}],"isBlockCoverage":false},{"functionName":"LinkedHashMapCell","ranges":[{"startOffset":85426,"endOffset":85584,"count":1}],"isBlockCoverage":true},{"functionName":"LinkedHashMapKeyIterable","ranges":[{"startOffset":85616,"endOffset":85720,"count":0}],"isBlockCoverage":false},{"functionName":"LinkedHashMapKeyIterator","ranges":[{"startOffset":85752,"endOffset":85950,"count":0}],"isBlockCoverage":false},{"functionName":"initHooks_closure","ranges":[{"startOffset":85975,"endOffset":86037,"count":1}],"isBlockCoverage":true},{"functionName":"initHooks_closure0","ranges":[{"startOffset":86063,"endOffset":86133,"count":1}],"isBlockCoverage":true},{"functionName":"initHooks_closure1","ranges":[{"startOffset":86159,"endOffset":86231,"count":1}],"isBlockCoverage":true},{"functionName":"JSSyntaxRegExp","ranges":[{"startOffset":86253,"endOffset":86424,"count":0}],"isBlockCoverage":false},{"functionName":"_MatchImplementation","ranges":[{"startOffset":86452,"endOffset":86517,"count":0}],"isBlockCoverage":false},{"functionName":"_AllMatchesIterable","ranges":[{"startOffset":86544,"endOffset":86674,"count":0}],"isBlockCoverage":false},{"functionName":"_AllMatchesIterator","ranges":[{"startOffset":86701,"endOffset":86887,"count":0}],"isBlockCoverage":false},{"functionName":"StringMatch","ranges":[{"startOffset":86906,"endOffset":86990,"count":0}],"isBlockCoverage":false},{"functionName":"_StringAllMatchesIterable","ranges":[{"startOffset":87023,"endOffset":87163,"count":0}],"isBlockCoverage":false},{"functionName":"_StringAllMatchesIterator","ranges":[{"startOffset":87196,"endOffset":87384,"count":0}],"isBlockCoverage":false},{"functionName":"_ensureNativeList","ranges":[{"startOffset":87409,"endOffset":87450,"count":0}],"isBlockCoverage":false},{"functionName":"NativeInt8List__create1","ranges":[{"startOffset":87481,"endOffset":87535,"count":0}],"isBlockCoverage":false},{"functionName":"_checkValidIndex","ranges":[{"startOffset":87559,"endOffset":87716,"count":1},{"startOffset":87653,"endOffset":87710,"count":0}],"isBlockCoverage":true},{"functionName":"_checkValidRange","ranges":[{"startOffset":87740,"endOffset":88027,"count":0}],"isBlockCoverage":false},{"functionName":"NativeByteBuffer","ranges":[{"startOffset":88051,"endOffset":88086,"count":0}],"isBlockCoverage":false},{"functionName":"NativeTypedData","ranges":[{"startOffset":88109,"endOffset":88143,"count":0}],"isBlockCoverage":false},{"functionName":"NativeTypedArray","ranges":[{"startOffset":88167,"endOffset":88202,"count":0}],"isBlockCoverage":false},{"functionName":"NativeTypedArrayOfDouble","ranges":[{"startOffset":88234,"endOffset":88277,"count":0}],"isBlockCoverage":false},{"functionName":"NativeTypedArrayOfInt","ranges":[{"startOffset":88306,"endOffset":88346,"count":0}],"isBlockCoverage":false},{"functionName":"NativeInt16List","ranges":[{"startOffset":88369,"endOffset":88403,"count":0}],"isBlockCoverage":false},{"functionName":"NativeInt32List","ranges":[{"startOffset":88426,"endOffset":88460,"count":0}],"isBlockCoverage":false},{"functionName":"NativeInt8List","ranges":[{"startOffset":88482,"endOffset":88515,"count":0}],"isBlockCoverage":false},{"functionName":"NativeUint16List","ranges":[{"startOffset":88539,"endOffset":88574,"count":0}],"isBlockCoverage":false},{"functionName":"NativeUint32List","ranges":[{"startOffset":88598,"endOffset":88633,"count":0}],"isBlockCoverage":false},{"functionName":"NativeUint8ClampedList","ranges":[{"startOffset":88663,"endOffset":88704,"count":0}],"isBlockCoverage":false},{"functionName":"NativeUint8List","ranges":[{"startOffset":88727,"endOffset":88761,"count":0}],"isBlockCoverage":false},{"functionName":"_NativeTypedArrayOfDouble_NativeTypedArray_ListMixin","ranges":[{"startOffset":88821,"endOffset":88892,"count":0}],"isBlockCoverage":false},{"functionName":"_NativeTypedArrayOfDouble_NativeTypedArray_ListMixin_FixedLengthListMixin","ranges":[{"startOffset":88973,"endOffset":89065,"count":0}],"isBlockCoverage":false},{"functionName":"_NativeTypedArrayOfInt_NativeTypedArray_ListMixin","ranges":[{"startOffset":89122,"endOffset":89190,"count":0}],"isBlockCoverage":false},{"functionName":"_NativeTypedArrayOfInt_NativeTypedArray_ListMixin_FixedLengthListMixin","ranges":[{"startOffset":89268,"endOffset":89357,"count":0}],"isBlockCoverage":false},{"functionName":"extractKeys","ranges":[{"startOffset":89376,"endOffset":89483,"count":0}],"isBlockCoverage":false},{"functionName":"printString","ranges":[{"startOffset":89502,"endOffset":89949,"count":0}],"isBlockCoverage":false},{"functionName":"makeDispatchRecord","ranges":[{"startOffset":89987,"endOffset":90120,"count":1}],"isBlockCoverage":true},{"functionName":"getNativeInterceptor","ranges":[{"startOffset":90148,"endOffset":91834,"count":1},{"startOffset":90602,"endOffset":90616,"count":0},{"startOffset":90731,"endOffset":90881,"count":0},{"startOffset":90889,"endOffset":90978,"count":0},{"startOffset":90979,"endOffset":91030,"count":0},{"startOffset":91071,"endOffset":91833,"count":0}],"isBlockCoverage":true},{"functionName":"JSArray_JSArray$fixed","ranges":[{"startOffset":91863,"endOffset":92096,"count":0}],"isBlockCoverage":false},{"functionName":"JSArray_JSArray$markFixed","ranges":[{"startOffset":92129,"endOffset":92239,"count":0}],"isBlockCoverage":false},{"functionName":"JSArray_markFixedList","ranges":[{"startOffset":92268,"endOffset":92371,"count":1}],"isBlockCoverage":true},{"functionName":"JSArray_markUnmodifiableList","ranges":[{"startOffset":92407,"endOffset":92516,"count":0}],"isBlockCoverage":false},{"functionName":"JSString__isWhitespace","ranges":[{"startOffset":92546,"endOffset":93301,"count":0}],"isBlockCoverage":false},{"functionName":"JSString__skipLeadingWhitespace","ranges":[{"startOffset":93340,"endOffset":93658,"count":0}],"isBlockCoverage":false},{"functionName":"JSString__skipTrailingWhitespace","ranges":[{"startOffset":93698,"endOffset":94027,"count":0}],"isBlockCoverage":false},{"functionName":"getInterceptor$","ranges":[{"startOffset":94050,"endOffset":94813,"count":1},{"startOffset":94193,"endOffset":94238,"count":0},{"startOffset":94426,"endOffset":94452,"count":0},{"startOffset":94569,"endOffset":94695,"count":0}],"isBlockCoverage":true},{"functionName":"getInterceptor$ansx","ranges":[{"startOffset":94840,"endOffset":95426,"count":0}],"isBlockCoverage":false},{"functionName":"getInterceptor$asx","ranges":[{"startOffset":95452,"endOffset":95962,"count":1},{"startOffset":95520,"endOffset":95548,"count":0},{"startOffset":95585,"endOffset":95601,"count":0},{"startOffset":95718,"endOffset":95844,"count":0},{"startOffset":95909,"endOffset":95961,"count":0}],"isBlockCoverage":true},{"functionName":"getInterceptor$ax","ranges":[{"startOffset":95987,"endOffset":96421,"count":1},{"startOffset":96044,"endOffset":96060,"count":0},{"startOffset":96177,"endOffset":96303,"count":0},{"startOffset":96368,"endOffset":96420,"count":0}],"isBlockCoverage":true},{"functionName":"getInterceptor$n","ranges":[{"startOffset":96445,"endOffset":96718,"count":0}],"isBlockCoverage":false},{"functionName":"getInterceptor$s","ranges":[{"startOffset":96742,"endOffset":97015,"count":1},{"startOffset":96838,"endOffset":97014,"count":0}],"isBlockCoverage":true},{"functionName":"getInterceptor$x","ranges":[{"startOffset":97039,"endOffset":97396,"count":1},{"startOffset":97096,"endOffset":97112,"count":0},{"startOffset":97152,"endOffset":97278,"count":0}],"isBlockCoverage":true},{"functionName":"get$hashCode$","ranges":[{"startOffset":97417,"endOffset":97508,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator$ax","ranges":[{"startOffset":97531,"endOffset":97624,"count":0}],"isBlockCoverage":false},{"functionName":"get$length$asx","ranges":[{"startOffset":97646,"endOffset":97738,"count":1}],"isBlockCoverage":true},{"functionName":"get$onClick$x","ranges":[{"startOffset":97759,"endOffset":97850,"count":1}],"isBlockCoverage":true},{"functionName":"$add$ansx","ranges":[{"startOffset":97867,"endOffset":98056,"count":0}],"isBlockCoverage":false},{"functionName":"$eq$","ranges":[{"startOffset":98068,"endOffset":98298,"count":1},{"startOffset":98129,"endOffset":98147,"count":0},{"startOffset":98232,"endOffset":98297,"count":0}],"isBlockCoverage":true},{"functionName":"$gt$n","ranges":[{"startOffset":98311,"endOffset":98496,"count":1},{"startOffset":98429,"endOffset":98495,"count":0}],"isBlockCoverage":true},{"functionName":"$index$asx","ranges":[{"startOffset":98514,"endOffset":98872,"count":1},{"startOffset":98581,"endOffset":98800,"count":0}],"isBlockCoverage":true},{"functionName":"$indexSet$ax","ranges":[{"startOffset":98892,"endOffset":98998,"count":1}],"isBlockCoverage":true},{"functionName":"_codeUnitAt$1$s","ranges":[{"startOffset":99021,"endOffset":99122,"count":1}],"isBlockCoverage":true},{"functionName":"_removeChild$1$x","ranges":[{"startOffset":99146,"endOffset":99248,"count":0}],"isBlockCoverage":false},{"functionName":"_removeEventListener$3$x","ranges":[{"startOffset":99280,"endOffset":99406,"count":0}],"isBlockCoverage":false},{"functionName":"addEventListener$3$x","ranges":[{"startOffset":99434,"endOffset":99556,"count":1}],"isBlockCoverage":true},{"functionName":"codeUnitAt$1$s","ranges":[{"startOffset":99578,"endOffset":99678,"count":0}],"isBlockCoverage":false},{"functionName":"contains$1$asx","ranges":[{"startOffset":99700,"endOffset":99800,"count":0}],"isBlockCoverage":false},{"functionName":"elementAt$1$ax","ranges":[{"startOffset":99822,"endOffset":99922,"count":0}],"isBlockCoverage":false},{"functionName":"endsWith$1$s","ranges":[{"startOffset":99942,"endOffset":100040,"count":0}],"isBlockCoverage":false},{"functionName":"fillRange$3$x","ranges":[{"startOffset":100061,"endOffset":100176,"count":1}],"isBlockCoverage":true},{"functionName":"indexOf$2$s","ranges":[{"startOffset":100195,"endOffset":100300,"count":0}],"isBlockCoverage":false},{"functionName":"matchAsPrefix$2$s","ranges":[{"startOffset":100325,"endOffset":100436,"count":0}],"isBlockCoverage":false},{"functionName":"noSuchMethod$1$","ranges":[{"startOffset":100459,"endOffset":100560,"count":0}],"isBlockCoverage":false},{"functionName":"padRight$1$s","ranges":[{"startOffset":100580,"endOffset":100678,"count":0}],"isBlockCoverage":false},{"functionName":"postMessage$3$x","ranges":[{"startOffset":100701,"endOffset":100818,"count":1}],"isBlockCoverage":true},{"functionName":"replaceFirst$2$s","ranges":[{"startOffset":100842,"endOffset":100952,"count":0}],"isBlockCoverage":false},{"functionName":"replaceRange$3$asx","ranges":[{"startOffset":100978,"endOffset":101098,"count":0}],"isBlockCoverage":false},{"functionName":"startsWith$1$s","ranges":[{"startOffset":101120,"endOffset":101220,"count":0}],"isBlockCoverage":false},{"functionName":"startsWith$2$s","ranges":[{"startOffset":101242,"endOffset":101350,"count":0}],"isBlockCoverage":false},{"functionName":"substring$1$s","ranges":[{"startOffset":101371,"endOffset":101470,"count":0}],"isBlockCoverage":false},{"functionName":"substring$2$s","ranges":[{"startOffset":101491,"endOffset":101598,"count":1}],"isBlockCoverage":true},{"functionName":"toString$0$","ranges":[{"startOffset":101617,"endOffset":101706,"count":0}],"isBlockCoverage":false},{"functionName":"trim$0$s","ranges":[{"startOffset":101722,"endOffset":101808,"count":0}],"isBlockCoverage":false},{"functionName":"waitUntilDone$0$x","ranges":[{"startOffset":101833,"endOffset":101928,"count":0}],"isBlockCoverage":false},{"functionName":"Interceptor","ranges":[{"startOffset":101947,"endOffset":101977,"count":0}],"isBlockCoverage":false},{"functionName":"JSBool","ranges":[{"startOffset":101991,"endOffset":102016,"count":0}],"isBlockCoverage":false},{"functionName":"JSNull","ranges":[{"startOffset":102030,"endOffset":102055,"count":0}],"isBlockCoverage":false},{"functionName":"JavaScriptObject","ranges":[{"startOffset":102079,"endOffset":102114,"count":0}],"isBlockCoverage":false},{"functionName":"PlainJavaScriptObject","ranges":[{"startOffset":102143,"endOffset":102183,"count":0}],"isBlockCoverage":false},{"functionName":"UnknownJavaScriptObject","ranges":[{"startOffset":102214,"endOffset":102256,"count":0}],"isBlockCoverage":false},{"functionName":"JavaScriptFunction","ranges":[{"startOffset":102282,"endOffset":102319,"count":0}],"isBlockCoverage":false},{"functionName":"JSArray","ranges":[{"startOffset":102334,"endOffset":102383,"count":0}],"isBlockCoverage":true},{"functionName":"JSUnmodifiableArray","ranges":[{"startOffset":102410,"endOffset":102471,"count":0}],"isBlockCoverage":false},{"functionName":"ArrayIterator","ranges":[{"startOffset":102492,"endOffset":102698,"count":0}],"isBlockCoverage":false},{"functionName":"JSNumber","ranges":[{"startOffset":102714,"endOffset":102741,"count":0}],"isBlockCoverage":false},{"functionName":"JSInt","ranges":[{"startOffset":102754,"endOffset":102778,"count":0}],"isBlockCoverage":true},{"functionName":"JSDouble","ranges":[{"startOffset":102794,"endOffset":102821,"count":0}],"isBlockCoverage":false},{"functionName":"JSString","ranges":[{"startOffset":102837,"endOffset":102864,"count":0}],"isBlockCoverage":true},{"functionName":"_AsyncRun__initializeScheduleImmediate","ranges":[{"startOffset":102922,"endOffset":103739,"count":1},{"startOffset":103025,"endOffset":103089,"count":0},{"startOffset":103548,"endOffset":103738,"count":0}],"isBlockCoverage":true},{"functionName":"_AsyncRun__scheduleImmediateJsOverride","ranges":[{"startOffset":103785,"endOffset":103984,"count":0}],"isBlockCoverage":false},{"functionName":"_AsyncRun__scheduleImmediateWithSetImmediate","ranges":[{"startOffset":104036,"endOffset":104236,"count":0}],"isBlockCoverage":false},{"functionName":"_AsyncRun__scheduleImmediateWithTimer","ranges":[{"startOffset":104281,"endOffset":104400,"count":0}],"isBlockCoverage":false},{"functionName":"Timer__createTimer","ranges":[{"startOffset":104426,"endOffset":104694,"count":0}],"isBlockCoverage":false},{"functionName":"Timer__createPeriodicTimer","ranges":[{"startOffset":104728,"endOffset":105021,"count":1},{"startOffset":104985,"endOffset":104988,"count":0}],"isBlockCoverage":true},{"functionName":"_TimerImpl$","ranges":[{"startOffset":105040,"endOffset":105179,"count":0}],"isBlockCoverage":false},{"functionName":"_TimerImpl$periodic","ranges":[{"startOffset":105206,"endOffset":105354,"count":1}],"isBlockCoverage":true},{"functionName":"_makeAsyncAwaitCompleter","ranges":[{"startOffset":105386,"endOffset":105529,"count":1}],"isBlockCoverage":true},{"functionName":"_asyncStartSync","ranges":[{"startOffset":105552,"endOffset":105848,"count":1}],"isBlockCoverage":true},{"functionName":"_asyncAwait","ranges":[{"startOffset":105867,"endOffset":106009,"count":1}],"isBlockCoverage":true},{"functionName":"_asyncReturn","ranges":[{"startOffset":106029,"endOffset":106143,"count":1}],"isBlockCoverage":true},{"functionName":"_asyncRethrow","ranges":[{"startOffset":106164,"endOffset":106332,"count":0}],"isBlockCoverage":false},{"functionName":"_awaitOnObject","ranges":[{"startOffset":106354,"endOffset":107170,"count":1},{"startOffset":106791,"endOffset":107164,"count":0}],"isBlockCoverage":true},{"functionName":"_wrapJsFunctionForAsync","ranges":[{"startOffset":107201,"endOffset":107687,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":107246,"endOffset":107537,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":107283,"endOffset":107528,"count":1},{"startOffset":107425,"endOffset":107518,"count":0}],"isBlockCoverage":true},{"functionName":"_Future$zoneValue","ranges":[{"startOffset":107712,"endOffset":107914,"count":0}],"isBlockCoverage":false},{"functionName":"_Future__chainForeignFuture","ranges":[{"startOffset":107949,"endOffset":108400,"count":0}],"isBlockCoverage":false},{"functionName":"_Future__chainCoreFuture","ranges":[{"startOffset":108432,"endOffset":109081,"count":0}],"isBlockCoverage":false},{"functionName":"_Future__propagateToListeners","ranges":[{"startOffset":109118,"endOffset":112741,"count":1},{"startOffset":109462,"endOffset":109649,"count":0},{"startOffset":110172,"endOffset":110183,"count":0},{"startOffset":110194,"endOffset":110220,"count":0},{"startOffset":110323,"endOffset":110467,"count":0},{"startOffset":110515,"endOffset":110754,"count":0},{"startOffset":110835,"endOffset":110858,"count":0},{"startOffset":110970,"endOffset":111079,"count":0},{"startOffset":111261,"endOffset":111383,"count":0},{"startOffset":111427,"endOffset":111453,"count":0},{"startOffset":111547,"endOffset":112035,"count":0},{"startOffset":112531,"endOffset":112674,"count":0}],"isBlockCoverage":true},{"functionName":"_registerErrorHandler","ranges":[{"startOffset":112770,"endOffset":113325,"count":0}],"isBlockCoverage":false},{"functionName":"_microtaskLoop","ranges":[{"startOffset":113347,"endOffset":113621,"count":1}],"isBlockCoverage":true},{"functionName":"_startMicrotaskLoop","ranges":[{"startOffset":113648,"endOffset":113983,"count":1},{"startOffset":113877,"endOffset":113969,"count":0}],"isBlockCoverage":true},{"functionName":"_scheduleAsyncCallback","ranges":[{"startOffset":114013,"endOffset":114484,"count":1},{"startOffset":114386,"endOffset":114478,"count":0}],"isBlockCoverage":true},{"functionName":"_schedulePriorityAsyncCallback","ranges":[{"startOffset":114522,"endOffset":115197,"count":0}],"isBlockCoverage":false},{"functionName":"scheduleMicrotask","ranges":[{"startOffset":115222,"endOffset":115926,"count":0}],"isBlockCoverage":false},{"functionName":"StreamIterator_StreamIterator","ranges":[{"startOffset":115963,"endOffset":116090,"count":0}],"isBlockCoverage":false},{"functionName":"StreamController_StreamController","ranges":[{"startOffset":116131,"endOffset":116365,"count":1}],"isBlockCoverage":true},{"functionName":"_runGuarded","ranges":[{"startOffset":116384,"endOffset":116791,"count":1},{"startOffset":116615,"endOffset":116785,"count":0}],"isBlockCoverage":true},{"functionName":"_nullDataHandler","ranges":[{"startOffset":116815,"endOffset":116838,"count":0}],"isBlockCoverage":false},{"functionName":"_nullErrorHandler","ranges":[{"startOffset":116863,"endOffset":117021,"count":0}],"isBlockCoverage":false},{"functionName":"_nullDoneHandler","ranges":[{"startOffset":117045,"endOffset":117063,"count":0}],"isBlockCoverage":false},{"functionName":"Timer_Timer$periodic","ranges":[{"startOffset":117091,"endOffset":117502,"count":1},{"startOffset":117293,"endOffset":117345,"count":0}],"isBlockCoverage":true},{"functionName":"_ZoneSpecification$","ranges":[{"startOffset":117529,"endOffset":117972,"count":1}],"isBlockCoverage":true},{"functionName":"_parentDelegate","ranges":[{"startOffset":117995,"endOffset":118126,"count":1},{"startOffset":118068,"endOffset":118125,"count":0}],"isBlockCoverage":true},{"functionName":"_rootHandleUncaughtError","ranges":[{"startOffset":118158,"endOffset":118395,"count":0}],"isBlockCoverage":false},{"functionName":"_rootRun","ranges":[{"startOffset":118411,"endOffset":118914,"count":1},{"startOffset":118731,"endOffset":118749,"count":0},{"startOffset":118859,"endOffset":118860,"count":0}],"isBlockCoverage":true},{"functionName":"_rootRunUnary","ranges":[{"startOffset":118935,"endOffset":119510,"count":1},{"startOffset":119455,"endOffset":119456,"count":0}],"isBlockCoverage":true},{"functionName":"_rootRunBinary","ranges":[{"startOffset":119532,"endOffset":120183,"count":0}],"isBlockCoverage":false},{"functionName":"_rootRegisterCallback","ranges":[{"startOffset":120212,"endOffset":120314,"count":1}],"isBlockCoverage":true},{"functionName":"_rootRegisterUnaryCallback","ranges":[{"startOffset":120348,"endOffset":120466,"count":1}],"isBlockCoverage":true},{"functionName":"_rootRegisterBinaryCallback","ranges":[{"startOffset":120501,"endOffset":120627,"count":1}],"isBlockCoverage":true},{"functionName":"_rootErrorCallback","ranges":[{"startOffset":120653,"endOffset":120783,"count":0}],"isBlockCoverage":false},{"functionName":"_rootScheduleMicrotask","ranges":[{"startOffset":120813,"endOffset":121143,"count":1},{"startOffset":121071,"endOffset":121101,"count":0}],"isBlockCoverage":true},{"functionName":"_rootCreateTimer","ranges":[{"startOffset":121167,"endOffset":121430,"count":0}],"isBlockCoverage":false},{"functionName":"_rootCreatePeriodicTimer","ranges":[{"startOffset":121462,"endOffset":121766,"count":1}],"isBlockCoverage":true},{"functionName":"_rootPrint","ranges":[{"startOffset":121784,"endOffset":121874,"count":0}],"isBlockCoverage":false},{"functionName":"_printToZone","ranges":[{"startOffset":121894,"endOffset":121956,"count":0}],"isBlockCoverage":false},{"functionName":"_rootFork","ranges":[{"startOffset":121973,"endOffset":123508,"count":1},{"startOffset":122278,"endOffset":122319,"count":0},{"startOffset":123450,"endOffset":123483,"count":0}],"isBlockCoverage":true},{"functionName":"runZoned","ranges":[{"startOffset":123524,"endOffset":125443,"count":1},{"startOffset":124003,"endOffset":124288,"count":0},{"startOffset":124511,"endOffset":125049,"count":0},{"startOffset":125155,"endOffset":125442,"count":0}],"isBlockCoverage":true},{"functionName":"_runZoned","ranges":[{"startOffset":125460,"endOffset":125673,"count":1}],"isBlockCoverage":true},{"functionName":"_AsyncRun__initializeScheduleImmediate_internalCallback","ranges":[{"startOffset":125736,"endOffset":125836,"count":1}],"isBlockCoverage":true},{"functionName":"_AsyncRun__initializeScheduleImmediate_closure","ranges":[{"startOffset":125890,"endOffset":126032,"count":1}],"isBlockCoverage":true},{"functionName":"_AsyncRun__scheduleImmediateJsOverride_internalCallback","ranges":[{"startOffset":126095,"endOffset":126197,"count":0}],"isBlockCoverage":false},{"functionName":"_AsyncRun__scheduleImmediateWithSetImmediate_internalCallback","ranges":[{"startOffset":126266,"endOffset":126374,"count":0}],"isBlockCoverage":false},{"functionName":"_TimerImpl","ranges":[{"startOffset":126392,"endOffset":126443,"count":1}],"isBlockCoverage":true},{"functionName":"_TimerImpl_internalCallback","ranges":[{"startOffset":126478,"endOffset":126579,"count":0}],"isBlockCoverage":false},{"functionName":"_TimerImpl$periodic_closure","ranges":[{"startOffset":126614,"endOffset":126784,"count":1}],"isBlockCoverage":true},{"functionName":"_AsyncAwaitCompleter","ranges":[{"startOffset":126812,"endOffset":126934,"count":1}],"isBlockCoverage":true},{"functionName":"_AsyncAwaitCompleter_complete_closure","ranges":[{"startOffset":126979,"endOffset":127087,"count":0}],"isBlockCoverage":false},{"functionName":"_AsyncAwaitCompleter_completeError_closure","ranges":[{"startOffset":127137,"endOffset":127270,"count":0}],"isBlockCoverage":false},{"functionName":"_awaitOnObject_closure","ranges":[{"startOffset":127300,"endOffset":127373,"count":1}],"isBlockCoverage":true},{"functionName":"_awaitOnObject_closure0","ranges":[{"startOffset":127404,"endOffset":127478,"count":1}],"isBlockCoverage":true},{"functionName":"_wrapJsFunctionForAsync_closure","ranges":[{"startOffset":127517,"endOffset":127597,"count":1}],"isBlockCoverage":true},{"functionName":"Future","ranges":[{"startOffset":127611,"endOffset":127636,"count":0}],"isBlockCoverage":false},{"functionName":"_Completer","ranges":[{"startOffset":127654,"endOffset":127683,"count":0}],"isBlockCoverage":false},{"functionName":"_AsyncCompleter","ranges":[{"startOffset":127706,"endOffset":127791,"count":1}],"isBlockCoverage":true},{"functionName":"_SyncCompleter","ranges":[{"startOffset":127813,"endOffset":127897,"count":1}],"isBlockCoverage":true},{"functionName":"_FutureListener","ranges":[{"startOffset":127920,"endOffset":128132,"count":1}],"isBlockCoverage":true},{"functionName":"_Future","ranges":[{"startOffset":128147,"endOffset":128297,"count":1}],"isBlockCoverage":true},{"functionName":"_Future__addListener_closure","ranges":[{"startOffset":128333,"endOffset":128435,"count":1}],"isBlockCoverage":true},{"functionName":"_Future__prependListeners_closure","ranges":[{"startOffset":128476,"endOffset":128581,"count":0}],"isBlockCoverage":false},{"functionName":"_Future__chainForeignFuture_closure","ranges":[{"startOffset":128624,"endOffset":128704,"count":0}],"isBlockCoverage":false},{"functionName":"_Future__chainForeignFuture_closure0","ranges":[{"startOffset":128748,"endOffset":128829,"count":0}],"isBlockCoverage":false},{"functionName":"_Future__chainForeignFuture_closure1","ranges":[{"startOffset":128873,"endOffset":129000,"count":0}],"isBlockCoverage":false},{"functionName":"_Future__asyncComplete_closure","ranges":[{"startOffset":129038,"endOffset":129139,"count":1}],"isBlockCoverage":true},{"functionName":"_Future__chainFuture_closure","ranges":[{"startOffset":129175,"endOffset":129274,"count":0}],"isBlockCoverage":false},{"functionName":"_Future__asyncCompleteError_closure","ranges":[{"startOffset":129317,"endOffset":129455,"count":0}],"isBlockCoverage":false},{"functionName":"_Future__propagateToListeners_handleWhenCompleteCallback","ranges":[{"startOffset":129519,"endOffset":129716,"count":0}],"isBlockCoverage":false},{"functionName":"_Future__propagateToListeners_handleWhenCompleteCallback_closure","ranges":[{"startOffset":129788,"endOffset":129905,"count":0}],"isBlockCoverage":false},{"functionName":"_Future__propagateToListeners_handleValueCallback","ranges":[{"startOffset":129962,"endOffset":130120,"count":1}],"isBlockCoverage":true},{"functionName":"_Future__propagateToListeners_handleError","ranges":[{"startOffset":130169,"endOffset":130313,"count":0}],"isBlockCoverage":false},{"functionName":"_AsyncCallbackEntry","ranges":[{"startOffset":130340,"endOffset":130430,"count":1}],"isBlockCoverage":true},{"functionName":"Stream","ranges":[{"startOffset":130444,"endOffset":130469,"count":0}],"isBlockCoverage":false},{"functionName":"Stream_pipe_closure","ranges":[{"startOffset":130496,"endOffset":130568,"count":1}],"isBlockCoverage":true},{"functionName":"Stream_length_closure","ranges":[{"startOffset":130597,"endOffset":130690,"count":0}],"isBlockCoverage":false},{"functionName":"Stream_length_closure0","ranges":[{"startOffset":130720,"endOffset":130815,"count":0}],"isBlockCoverage":false},{"functionName":"StreamSubscription","ranges":[{"startOffset":130841,"endOffset":130878,"count":0}],"isBlockCoverage":false},{"functionName":"StreamTransformerBase","ranges":[{"startOffset":130907,"endOffset":130947,"count":0}],"isBlockCoverage":false},{"functionName":"_StreamController","ranges":[{"startOffset":130972,"endOffset":131008,"count":0}],"isBlockCoverage":false},{"functionName":"_StreamController__subscribe_closure","ranges":[{"startOffset":131052,"endOffset":131132,"count":1}],"isBlockCoverage":true},{"functionName":"_StreamController__recordCancel_complete","ranges":[{"startOffset":131180,"endOffset":131264,"count":0}],"isBlockCoverage":false},{"functionName":"_SyncStreamControllerDispatch","ranges":[{"startOffset":131301,"endOffset":131349,"count":0}],"isBlockCoverage":false},{"functionName":"_SyncStreamController","ranges":[{"startOffset":131378,"endOffset":131643,"count":1}],"isBlockCoverage":true},{"functionName":"_ControllerStream","ranges":[{"startOffset":131668,"endOffset":131760,"count":1}],"isBlockCoverage":true},{"functionName":"_ControllerSubscription","ranges":[{"startOffset":131791,"endOffset":132051,"count":1}],"isBlockCoverage":true},{"functionName":"_StreamSinkWrapper","ranges":[{"startOffset":132077,"endOffset":132173,"count":1}],"isBlockCoverage":true},{"functionName":"_AddStreamState_cancel_closure","ranges":[{"startOffset":132211,"endOffset":132285,"count":0}],"isBlockCoverage":false},{"functionName":"_BufferingStreamSubscription","ranges":[{"startOffset":132321,"endOffset":132368,"count":0}],"isBlockCoverage":false},{"functionName":"_BufferingStreamSubscription__sendError_sendError","ranges":[{"startOffset":132425,"endOffset":132577,"count":0}],"isBlockCoverage":false},{"functionName":"_BufferingStreamSubscription__sendDone_sendDone","ranges":[{"startOffset":132632,"endOffset":132723,"count":0}],"isBlockCoverage":false},{"functionName":"_StreamImpl","ranges":[{"startOffset":132742,"endOffset":132772,"count":0}],"isBlockCoverage":false},{"functionName":"_DelayedEvent","ranges":[{"startOffset":132793,"endOffset":132825,"count":0}],"isBlockCoverage":false},{"functionName":"_DelayedData","ranges":[{"startOffset":132845,"endOffset":132950,"count":0}],"isBlockCoverage":false},{"functionName":"_DelayedError","ranges":[{"startOffset":132971,"endOffset":133084,"count":0}],"isBlockCoverage":false},{"functionName":"_DelayedDone","ranges":[{"startOffset":133104,"endOffset":133135,"count":1}],"isBlockCoverage":true},{"functionName":"_PendingEvents","ranges":[{"startOffset":133157,"endOffset":133190,"count":0}],"isBlockCoverage":false},{"functionName":"_PendingEvents_schedule_closure","ranges":[{"startOffset":133229,"endOffset":133334,"count":0}],"isBlockCoverage":false},{"functionName":"_StreamImplEvents","ranges":[{"startOffset":133359,"endOffset":133515,"count":0}],"isBlockCoverage":false},{"functionName":"_DoneStreamSubscription","ranges":[{"startOffset":133546,"endOffset":133698,"count":0}],"isBlockCoverage":false},{"functionName":"_StreamIterator","ranges":[{"startOffset":133721,"endOffset":133881,"count":0}],"isBlockCoverage":false},{"functionName":"_EmptyStream","ranges":[{"startOffset":133901,"endOffset":133955,"count":0}],"isBlockCoverage":false},{"functionName":"Timer","ranges":[{"startOffset":133968,"endOffset":133992,"count":0}],"isBlockCoverage":false},{"functionName":"AsyncError","ranges":[{"startOffset":134010,"endOffset":134096,"count":0}],"isBlockCoverage":false},{"functionName":"_ZoneFunction","ranges":[{"startOffset":134117,"endOffset":134229,"count":1}],"isBlockCoverage":true},{"functionName":"ZoneSpecification","ranges":[{"startOffset":134254,"endOffset":134290,"count":0}],"isBlockCoverage":false},{"functionName":"_ZoneSpecification","ranges":[{"startOffset":134316,"endOffset":134791,"count":1}],"isBlockCoverage":true},{"functionName":"ZoneDelegate","ranges":[{"startOffset":134811,"endOffset":134842,"count":0}],"isBlockCoverage":false},{"functionName":"Zone","ranges":[{"startOffset":134854,"endOffset":134877,"count":0}],"isBlockCoverage":false},{"functionName":"_ZoneDelegate","ranges":[{"startOffset":134898,"endOffset":134967,"count":0}],"isBlockCoverage":false},{"functionName":"_Zone","ranges":[{"startOffset":134980,"endOffset":135004,"count":0}],"isBlockCoverage":false},{"functionName":"_CustomZone","ranges":[{"startOffset":135023,"endOffset":135402,"count":1}],"isBlockCoverage":true},{"functionName":"_CustomZone_bindCallback_closure","ranges":[{"startOffset":135442,"endOffset":135573,"count":0}],"isBlockCoverage":false},{"functionName":"_CustomZone_bindUnaryCallback_closure","ranges":[{"startOffset":135618,"endOffset":135785,"count":1}],"isBlockCoverage":true},{"functionName":"_CustomZone_bindCallbackGuarded_closure","ranges":[{"startOffset":135832,"endOffset":135947,"count":1}],"isBlockCoverage":true},{"functionName":"_CustomZone_bindUnaryCallbackGuarded_closure","ranges":[{"startOffset":135999,"endOffset":136142,"count":1}],"isBlockCoverage":true},{"functionName":"_rootHandleUncaughtError_closure","ranges":[{"startOffset":136182,"endOffset":136291,"count":0}],"isBlockCoverage":false},{"functionName":"_RootZone","ranges":[{"startOffset":136308,"endOffset":136336,"count":1}],"isBlockCoverage":true},{"functionName":"_RootZone_bindCallback_closure","ranges":[{"startOffset":136374,"endOffset":136494,"count":0}],"isBlockCoverage":false},{"functionName":"_RootZone_bindCallbackGuarded_closure","ranges":[{"startOffset":136539,"endOffset":136643,"count":0}],"isBlockCoverage":false},{"functionName":"_RootZone_bindUnaryCallbackGuarded_closure","ranges":[{"startOffset":136693,"endOffset":136825,"count":0}],"isBlockCoverage":false},{"functionName":"runZoned_closure","ranges":[{"startOffset":136849,"endOffset":136910,"count":1}],"isBlockCoverage":true},{"functionName":"HashMap_HashMap","ranges":[{"startOffset":136933,"endOffset":136996,"count":1}],"isBlockCoverage":true},{"functionName":"_HashMap__getTableEntry","ranges":[{"startOffset":137027,"endOffset":137130,"count":0}],"isBlockCoverage":false},{"functionName":"_HashMap__setTableEntry","ranges":[{"startOffset":137161,"endOffset":137288,"count":0}],"isBlockCoverage":false},{"functionName":"_HashMap__newHashTable","ranges":[{"startOffset":137318,"endOffset":137510,"count":0}],"isBlockCoverage":false},{"functionName":"LinkedHashMap_LinkedHashMap$_literal","ranges":[{"startOffset":137554,"endOffset":137777,"count":0}],"isBlockCoverage":false},{"functionName":"LinkedHashMap_LinkedHashMap$_empty","ranges":[{"startOffset":137819,"endOffset":137889,"count":1}],"isBlockCoverage":true},{"functionName":"LinkedHashMap__makeEmpty","ranges":[{"startOffset":137921,"endOffset":137989,"count":1}],"isBlockCoverage":true},{"functionName":"LinkedHashSet_LinkedHashSet","ranges":[{"startOffset":138024,"endOffset":138085,"count":1}],"isBlockCoverage":true},{"functionName":"_LinkedHashSet__newHashTable","ranges":[{"startOffset":138121,"endOffset":138287,"count":0}],"isBlockCoverage":false},{"functionName":"IterableBase_iterableToShortString","ranges":[{"startOffset":138329,"endOffset":139079,"count":0}],"isBlockCoverage":false},{"functionName":"IterableBase_iterableToFullString","ranges":[{"startOffset":139120,"endOffset":139770,"count":0}],"isBlockCoverage":false},{"functionName":"_isToStringVisiting","ranges":[{"startOffset":139797,"endOffset":139972,"count":0}],"isBlockCoverage":false},{"functionName":"_iterablePartsToStrings","ranges":[{"startOffset":140003,"endOffset":142710,"count":0}],"isBlockCoverage":false},{"functionName":"MapBase_mapToString","ranges":[{"startOffset":142737,"endOffset":143352,"count":0}],"isBlockCoverage":false},{"functionName":"_HashMap","ranges":[{"startOffset":143368,"endOffset":143571,"count":1}],"isBlockCoverage":true},{"functionName":"_HashMapKeyIterable","ranges":[{"startOffset":143598,"endOffset":143685,"count":0}],"isBlockCoverage":false},{"functionName":"_HashMapKeyIterator","ranges":[{"startOffset":143712,"endOffset":143907,"count":0}],"isBlockCoverage":false},{"functionName":"_LinkedHashSet","ranges":[{"startOffset":143929,"endOffset":144201,"count":1}],"isBlockCoverage":true},{"functionName":"_LinkedHashSetCell","ranges":[{"startOffset":144227,"endOffset":144358,"count":0}],"isBlockCoverage":false},{"functionName":"_LinkedHashSetIterator","ranges":[{"startOffset":144388,"endOffset":144596,"count":0}],"isBlockCoverage":false},{"functionName":"IterableBase","ranges":[{"startOffset":144616,"endOffset":144647,"count":0}],"isBlockCoverage":false},{"functionName":"ListBase","ranges":[{"startOffset":144663,"endOffset":144690,"count":0}],"isBlockCoverage":false},{"functionName":"ListMixin","ranges":[{"startOffset":144707,"endOffset":144735,"count":0}],"isBlockCoverage":false},{"functionName":"MapBase","ranges":[{"startOffset":144750,"endOffset":144776,"count":0}],"isBlockCoverage":false},{"functionName":"MapBase_mapToString_closure","ranges":[{"startOffset":144811,"endOffset":144911,"count":0}],"isBlockCoverage":false},{"functionName":"MapMixin","ranges":[{"startOffset":144927,"endOffset":144954,"count":0}],"isBlockCoverage":false},{"functionName":"_UnmodifiableMapMixin","ranges":[{"startOffset":144983,"endOffset":145023,"count":0}],"isBlockCoverage":false},{"functionName":"MapView","ranges":[{"startOffset":145038,"endOffset":145064,"count":0}],"isBlockCoverage":false},{"functionName":"UnmodifiableMapView","ranges":[{"startOffset":145091,"endOffset":145178,"count":1}],"isBlockCoverage":true},{"functionName":"_SetBase","ranges":[{"startOffset":145194,"endOffset":145221,"count":0}],"isBlockCoverage":false},{"functionName":"_ListBase_Object_ListMixin","ranges":[{"startOffset":145255,"endOffset":145300,"count":0}],"isBlockCoverage":false},{"functionName":"_UnmodifiableMapView_MapView__UnmodifiableMapMixin","ranges":[{"startOffset":145358,"endOffset":145427,"count":0}],"isBlockCoverage":false},{"functionName":"_parseJson","ranges":[{"startOffset":145445,"endOffset":145914,"count":1},{"startOffset":145555,"endOffset":145607,"count":0},{"startOffset":145686,"endOffset":145846,"count":0}],"isBlockCoverage":true},{"functionName":"_convertJsonToDartLazy","ranges":[{"startOffset":145944,"endOffset":146324,"count":1}],"isBlockCoverage":true},{"functionName":"Utf8Decoder__convertIntercepted","ranges":[{"startOffset":146363,"endOffset":146629,"count":1},{"startOffset":146529,"endOffset":146609,"count":0}],"isBlockCoverage":true},{"functionName":"Utf8Decoder__convertInterceptedUint8List","ranges":[{"startOffset":146677,"endOffset":147268,"count":0}],"isBlockCoverage":false},{"functionName":"Utf8Decoder__useTextDecoderChecked","ranges":[{"startOffset":147310,"endOffset":147479,"count":0}],"isBlockCoverage":false},{"functionName":"Utf8Decoder__useTextDecoderUnchecked","ranges":[{"startOffset":147523,"endOffset":147743,"count":0}],"isBlockCoverage":false},{"functionName":"Utf8Decoder__unsafe","ranges":[{"startOffset":147770,"endOffset":148014,"count":0}],"isBlockCoverage":false},{"functionName":"Utf8Decoder__makeDecoder","ranges":[{"startOffset":148046,"endOffset":148262,"count":0}],"isBlockCoverage":false},{"functionName":"_scanOneByteCharacters","ranges":[{"startOffset":148292,"endOffset":148695,"count":1},{"startOffset":148570,"endOffset":148589,"count":0},{"startOffset":148635,"endOffset":148651,"count":0}],"isBlockCoverage":true},{"functionName":"Base64Codec__checkPadding","ranges":[{"startOffset":148728,"endOffset":149339,"count":0}],"isBlockCoverage":false},{"functionName":"JsonUnsupportedObjectError$","ranges":[{"startOffset":149374,"endOffset":149504,"count":0}],"isBlockCoverage":false},{"functionName":"_defaultToEncodable","ranges":[{"startOffset":149531,"endOffset":149587,"count":0}],"isBlockCoverage":false},{"functionName":"_JsonStringStringifier_stringify","ranges":[{"startOffset":149627,"endOffset":149885,"count":1},{"startOffset":149869,"endOffset":149873,"count":0}],"isBlockCoverage":true},{"functionName":"_JsonStringStringifier_printOn","ranges":[{"startOffset":149923,"endOffset":150125,"count":1}],"isBlockCoverage":true},{"functionName":"_JsonMap","ranges":[{"startOffset":150141,"endOffset":150254,"count":1}],"isBlockCoverage":true},{"functionName":"_JsonMapKeyIterable","ranges":[{"startOffset":150281,"endOffset":150355,"count":0}],"isBlockCoverage":false},{"functionName":"AsciiCodec","ranges":[{"startOffset":150373,"endOffset":150435,"count":1}],"isBlockCoverage":true},{"functionName":"_UnicodeSubsetEncoder","ranges":[{"startOffset":150464,"endOffset":150504,"count":0}],"isBlockCoverage":false},{"functionName":"AsciiEncoder","ranges":[{"startOffset":150524,"endOffset":150586,"count":1}],"isBlockCoverage":true},{"functionName":"Base64Codec","ranges":[{"startOffset":150605,"endOffset":150663,"count":1}],"isBlockCoverage":true},{"functionName":"Base64Encoder","ranges":[{"startOffset":150684,"endOffset":150744,"count":1}],"isBlockCoverage":true},{"functionName":"Codec","ranges":[{"startOffset":150757,"endOffset":150781,"count":0}],"isBlockCoverage":false},{"functionName":"_FusedCodec","ranges":[{"startOffset":150800,"endOffset":150919,"count":0}],"isBlockCoverage":false},{"functionName":"Converter","ranges":[{"startOffset":150936,"endOffset":150964,"count":0}],"isBlockCoverage":false},{"functionName":"Encoding","ranges":[{"startOffset":150980,"endOffset":151007,"count":0}],"isBlockCoverage":false},{"functionName":"JsonUnsupportedObjectError","ranges":[{"startOffset":151041,"endOffset":151150,"count":0}],"isBlockCoverage":false},{"functionName":"JsonCyclicError","ranges":[{"startOffset":151173,"endOffset":151271,"count":0}],"isBlockCoverage":false},{"functionName":"JsonCodec","ranges":[{"startOffset":151288,"endOffset":151378,"count":1}],"isBlockCoverage":true},{"functionName":"JsonEncoder","ranges":[{"startOffset":151397,"endOffset":151487,"count":1}],"isBlockCoverage":true},{"functionName":"JsonDecoder","ranges":[{"startOffset":151506,"endOffset":151564,"count":1}],"isBlockCoverage":true},{"functionName":"_JsonStringifier","ranges":[{"startOffset":151588,"endOffset":151623,"count":0}],"isBlockCoverage":false},{"functionName":"_JsonStringifier_writeMap_closure","ranges":[{"startOffset":151664,"endOffset":151776,"count":1}],"isBlockCoverage":true},{"functionName":"_JsonStringStringifier","ranges":[{"startOffset":151806,"endOffset":151942,"count":1}],"isBlockCoverage":true},{"functionName":"Utf8Codec","ranges":[{"startOffset":151959,"endOffset":152022,"count":1}],"isBlockCoverage":true},{"functionName":"Utf8Encoder","ranges":[{"startOffset":152041,"endOffset":152071,"count":1}],"isBlockCoverage":true},{"functionName":"_Utf8Encoder","ranges":[{"startOffset":152091,"endOffset":152192,"count":0}],"isBlockCoverage":false},{"functionName":"Utf8Decoder","ranges":[{"startOffset":152211,"endOffset":152276,"count":1}],"isBlockCoverage":true},{"functionName":"_Utf8Decoder","ranges":[{"startOffset":152296,"endOffset":152498,"count":1}],"isBlockCoverage":true},{"functionName":"_Utf8Decoder_convert_addSingleBytes","ranges":[{"startOffset":152541,"endOffset":152721,"count":1}],"isBlockCoverage":true},{"functionName":"int_parse","ranges":[{"startOffset":152738,"endOffset":153106,"count":1},{"startOffset":152965,"endOffset":153105,"count":0}],"isBlockCoverage":true},{"functionName":"Error__objectToString","ranges":[{"startOffset":153135,"endOffset":153309,"count":0}],"isBlockCoverage":false},{"functionName":"List_List$filled","ranges":[{"startOffset":153333,"endOffset":153687,"count":0}],"isBlockCoverage":false},{"functionName":"List_List$from","ranges":[{"startOffset":153709,"endOffset":154115,"count":0}],"isBlockCoverage":false},{"functionName":"List_List$unmodifiable","ranges":[{"startOffset":154145,"endOffset":154366,"count":0}],"isBlockCoverage":false},{"functionName":"String_String$fromCharCodes","ranges":[{"startOffset":154401,"endOffset":155216,"count":1},{"startOffset":154876,"endOffset":154928,"count":0},{"startOffset":154950,"endOffset":155215,"count":0}],"isBlockCoverage":true},{"functionName":"String_String$fromCharCode","ranges":[{"startOffset":155250,"endOffset":155332,"count":0}],"isBlockCoverage":false},{"functionName":"String__stringFromIterable","ranges":[{"startOffset":155366,"endOffset":156339,"count":0}],"isBlockCoverage":false},{"functionName":"RegExp_RegExp","ranges":[{"startOffset":156360,"endOffset":156499,"count":0}],"isBlockCoverage":false},{"functionName":"StringBuffer__writeAll","ranges":[{"startOffset":156529,"endOffset":157013,"count":0}],"isBlockCoverage":false},{"functionName":"NoSuchMethodError$","ranges":[{"startOffset":157039,"endOffset":157217,"count":0}],"isBlockCoverage":false},{"functionName":"Uri_base","ranges":[{"startOffset":157233,"endOffset":157431,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__uriEncode","ranges":[{"startOffset":157454,"endOffset":158643,"count":0}],"isBlockCoverage":false},{"functionName":"DateTime__fourDigits","ranges":[{"startOffset":158671,"endOffset":158964,"count":0}],"isBlockCoverage":false},{"functionName":"DateTime__threeDigits","ranges":[{"startOffset":158993,"endOffset":159121,"count":0}],"isBlockCoverage":false},{"functionName":"DateTime__twoDigits","ranges":[{"startOffset":159148,"endOffset":159231,"count":0}],"isBlockCoverage":false},{"functionName":"Duration$","ranges":[{"startOffset":159248,"endOffset":159321,"count":1}],"isBlockCoverage":true},{"functionName":"Error_safeToString","ranges":[{"startOffset":159347,"endOffset":159619,"count":0}],"isBlockCoverage":false},{"functionName":"ArgumentError$","ranges":[{"startOffset":159641,"endOffset":159728,"count":0}],"isBlockCoverage":false},{"functionName":"ArgumentError$value","ranges":[{"startOffset":159755,"endOffset":159857,"count":0}],"isBlockCoverage":false},{"functionName":"RangeError$value","ranges":[{"startOffset":159881,"endOffset":159996,"count":0}],"isBlockCoverage":false},{"functionName":"RangeError$range","ranges":[{"startOffset":160020,"endOffset":160181,"count":0}],"isBlockCoverage":false},{"functionName":"RangeError_checkValueInInterval","ranges":[{"startOffset":160220,"endOffset":160409,"count":0}],"isBlockCoverage":false},{"functionName":"RangeError_checkValidRange","ranges":[{"startOffset":160443,"endOffset":160875,"count":1},{"startOffset":160520,"endOffset":160540,"count":0},{"startOffset":160589,"endOffset":160665,"count":0},{"startOffset":160743,"endOffset":160819,"count":0}],"isBlockCoverage":true},{"functionName":"RangeError_checkNotNegative","ranges":[{"startOffset":160910,"endOffset":161106,"count":0}],"isBlockCoverage":false},{"functionName":"IndexError$","ranges":[{"startOffset":161125,"endOffset":161363,"count":0}],"isBlockCoverage":false},{"functionName":"UnsupportedError$","ranges":[{"startOffset":161388,"endOffset":161459,"count":0}],"isBlockCoverage":false},{"functionName":"UnimplementedError$","ranges":[{"startOffset":161486,"endOffset":161559,"count":0}],"isBlockCoverage":false},{"functionName":"StateError$","ranges":[{"startOffset":161578,"endOffset":161643,"count":0}],"isBlockCoverage":false},{"functionName":"ConcurrentModificationError$","ranges":[{"startOffset":161679,"endOffset":161775,"count":0}],"isBlockCoverage":false},{"functionName":"FormatException$","ranges":[{"startOffset":161799,"endOffset":161901,"count":0}],"isBlockCoverage":false},{"functionName":"List_List$generate","ranges":[{"startOffset":161927,"endOffset":162297,"count":1}],"isBlockCoverage":true},{"functionName":"Uri_parse","ranges":[{"startOffset":162314,"endOffset":168453,"count":1},{"startOffset":162832,"endOffset":162938,"count":0},{"startOffset":162980,"endOffset":163068,"count":0},{"startOffset":163649,"endOffset":163694,"count":0},{"startOffset":163774,"endOffset":163797,"count":0},{"startOffset":163894,"endOffset":163917,"count":0},{"startOffset":163983,"endOffset":164000,"count":0},{"startOffset":164205,"endOffset":164232,"count":0},{"startOffset":164283,"endOffset":164308,"count":0},{"startOffset":164355,"endOffset":164382,"count":0},{"startOffset":164432,"endOffset":164455,"count":0},{"startOffset":164497,"endOffset":164520,"count":0},{"startOffset":164568,"endOffset":164594,"count":0},{"startOffset":164644,"endOffset":164667,"count":0},{"startOffset":164709,"endOffset":164731,"count":0},{"startOffset":164797,"endOffset":164813,"count":0},{"startOffset":164867,"endOffset":167872,"count":0},{"startOffset":167927,"endOffset":168319,"count":0}],"isBlockCoverage":true},{"functionName":"Uri_decodeComponent","ranges":[{"startOffset":168480,"endOffset":168661,"count":0}],"isBlockCoverage":false},{"functionName":"Uri_splitQueryString","ranges":[{"startOffset":168689,"endOffset":168954,"count":1}],"isBlockCoverage":true},{"functionName":"Uri__parseIPv4Address","ranges":[{"startOffset":168983,"endOffset":170538,"count":0}],"isBlockCoverage":false},{"functionName":"Uri_parseIPv6Address","ranges":[{"startOffset":170566,"endOffset":173975,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__Uri$notSimple","ranges":[{"startOffset":174002,"endOffset":175800,"count":1},{"startOffset":174254,"endOffset":174277,"count":0},{"startOffset":174370,"endOffset":174515,"count":0},{"startOffset":174608,"endOffset":174632,"count":0},{"startOffset":174717,"endOffset":174774,"count":0},{"startOffset":174901,"endOffset":174925,"count":0},{"startOffset":175007,"endOffset":175031,"count":0},{"startOffset":175196,"endOffset":175202,"count":0},{"startOffset":175211,"endOffset":175291,"count":0},{"startOffset":175429,"endOffset":175453,"count":0},{"startOffset":175507,"endOffset":175535,"count":0},{"startOffset":175639,"endOffset":175645,"count":0},{"startOffset":175734,"endOffset":175785,"count":0}],"isBlockCoverage":true},{"functionName":"_Uri__Uri","ranges":[{"startOffset":175817,"endOffset":177057,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__defaultPort","ranges":[{"startOffset":177082,"endOffset":177220,"count":1},{"startOffset":177148,"endOffset":177219,"count":0}],"isBlockCoverage":true},{"functionName":"_Uri__fail","ranges":[{"startOffset":177238,"endOffset":177345,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__Uri$file","ranges":[{"startOffset":177367,"endOffset":177497,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__checkNonWindowsPathReservedCharacters","ranges":[{"startOffset":177548,"endOffset":177751,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__checkWindowsPathReservedCharacters","ranges":[{"startOffset":177799,"endOffset":178489,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__checkWindowsDriveLetter","ranges":[{"startOffset":178526,"endOffset":179005,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__makeFileUri","ranges":[{"startOffset":179030,"endOffset":179320,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__makeWindowsFileUrl","ranges":[{"startOffset":179352,"endOffset":181689,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__makePort","ranges":[{"startOffset":181711,"endOffset":181840,"count":1},{"startOffset":181808,"endOffset":181815,"count":0}],"isBlockCoverage":true},{"functionName":"_Uri__makeHost","ranges":[{"startOffset":181862,"endOffset":182764,"count":1},{"startOffset":181952,"endOffset":181959,"count":0},{"startOffset":181993,"endOffset":182003,"count":0},{"startOffset":182067,"endOffset":182435,"count":0},{"startOffset":182479,"endOffset":182497,"count":0},{"startOffset":182603,"endOffset":182701,"count":0}],"isBlockCoverage":true},{"functionName":"_Uri__normalizeRegName","ranges":[{"startOffset":182794,"endOffset":186280,"count":1},{"startOffset":182973,"endOffset":182991,"count":0},{"startOffset":183204,"endOffset":184074,"count":0},{"startOffset":184178,"endOffset":184209,"count":0},{"startOffset":184281,"endOffset":184310,"count":0},{"startOffset":184389,"endOffset":184714,"count":0},{"startOffset":184747,"endOffset":185904,"count":0},{"startOffset":186013,"endOffset":186268,"count":0},{"startOffset":186269,"endOffset":186273,"count":0}],"isBlockCoverage":true},{"functionName":"_Uri__makeScheme","ranges":[{"startOffset":186304,"endOffset":187376,"count":1},{"startOffset":186414,"endOffset":186424,"count":0},{"startOffset":186532,"endOffset":186609,"count":0},{"startOffset":186653,"endOffset":186671,"count":0},{"startOffset":186911,"endOffset":186942,"count":0},{"startOffset":187014,"endOffset":187041,"count":0},{"startOffset":187069,"endOffset":187121,"count":0},{"startOffset":187178,"endOffset":187203,"count":0},{"startOffset":187337,"endOffset":187359,"count":0}],"isBlockCoverage":true},{"functionName":"_Uri__canonicalizeScheme","ranges":[{"startOffset":187408,"endOffset":187669,"count":1},{"startOffset":187478,"endOffset":187668,"count":0}],"isBlockCoverage":true},{"functionName":"_Uri__makeUserInfo","ranges":[{"startOffset":187695,"endOffset":187864,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__makePath","ranges":[{"startOffset":187886,"endOffset":189059,"count":1},{"startOffset":188222,"endOffset":188245,"count":0},{"startOffset":188255,"endOffset":188280,"count":0},{"startOffset":188343,"endOffset":188423,"count":0},{"startOffset":188520,"endOffset":188795,"count":0},{"startOffset":188827,"endOffset":188878,"count":0},{"startOffset":188965,"endOffset":188987,"count":0}],"isBlockCoverage":true},{"functionName":"_Uri__normalizePath","ranges":[{"startOffset":189086,"endOffset":189363,"count":1},{"startOffset":189174,"endOffset":189190,"count":0},{"startOffset":189191,"endOffset":189237,"count":0},{"startOffset":189247,"endOffset":189311,"count":0}],"isBlockCoverage":true},{"functionName":"_Uri__makeQuery","ranges":[{"startOffset":189386,"endOffset":189559,"count":1},{"startOffset":189539,"endOffset":189558,"count":0}],"isBlockCoverage":true},{"functionName":"_Uri__makeFragment","ranges":[{"startOffset":189585,"endOffset":189750,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__normalizeEscape","ranges":[{"startOffset":189779,"endOffset":190943,"count":1},{"startOffset":189942,"endOffset":189962,"count":0},{"startOffset":190024,"endOffset":190035,"count":0},{"startOffset":190351,"endOffset":190362,"count":0},{"startOffset":190534,"endOffset":190565,"count":0},{"startOffset":190630,"endOffset":190655,"count":0},{"startOffset":190678,"endOffset":190787,"count":0},{"startOffset":190845,"endOffset":190923,"count":0}],"isBlockCoverage":true},{"functionName":"_Uri__escapeChar","ranges":[{"startOffset":190967,"endOffset":192472,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__normalizeOrSubstring","ranges":[{"startOffset":192506,"endOffset":192779,"count":1},{"startOffset":192768,"endOffset":192772,"count":0}],"isBlockCoverage":true},{"functionName":"_Uri__normalize","ranges":[{"startOffset":192802,"endOffset":196002,"count":1},{"startOffset":193232,"endOffset":193251,"count":0},{"startOffset":193299,"endOffset":193317,"count":0},{"startOffset":193526,"endOffset":193556,"count":0},{"startOffset":193627,"endOffset":193656,"count":0},{"startOffset":193933,"endOffset":194100,"count":0},{"startOffset":194114,"endOffset":195678,"count":0},{"startOffset":195738,"endOffset":195990,"count":0},{"startOffset":195991,"endOffset":195995,"count":0}],"isBlockCoverage":true},{"functionName":"_Uri__mayContainDotSegments","ranges":[{"startOffset":196037,"endOffset":196202,"count":1},{"startOffset":196122,"endOffset":196134,"count":0}],"isBlockCoverage":true},{"functionName":"_Uri__removeDotSegments","ranges":[{"startOffset":196233,"endOffset":197172,"count":1},{"startOffset":196374,"endOffset":197171,"count":0}],"isBlockCoverage":true},{"functionName":"_Uri__normalizeRelativePath","ranges":[{"startOffset":197207,"endOffset":198750,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__escapeScheme","ranges":[{"startOffset":198776,"endOffset":199463,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__toWindowsFilePath","ranges":[{"startOffset":199494,"endOffset":200490,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__hexCharPairToByte","ranges":[{"startOffset":200521,"endOffset":201052,"count":1},{"startOffset":200917,"endOffset":201009,"count":0}],"isBlockCoverage":true},{"functionName":"_Uri__uriDecode","ranges":[{"startOffset":201075,"endOffset":202742,"count":1},{"startOffset":201518,"endOffset":201552,"count":0},{"startOffset":201719,"endOffset":201730,"count":0},{"startOffset":201831,"endOffset":201913,"count":0},{"startOffset":202110,"endOffset":202185,"count":0},{"startOffset":202270,"endOffset":202327,"count":0},{"startOffset":202497,"endOffset":202532,"count":0}],"isBlockCoverage":true},{"functionName":"_Uri__isAlphabeticCharacter","ranges":[{"startOffset":202777,"endOffset":202890,"count":1}],"isBlockCoverage":true},{"functionName":"UriData__writeUri","ranges":[{"startOffset":202915,"endOffset":203591,"count":0}],"isBlockCoverage":false},{"functionName":"UriData__validateMimeType","ranges":[{"startOffset":203624,"endOffset":203975,"count":0}],"isBlockCoverage":false},{"functionName":"UriData__parse","ranges":[{"startOffset":203997,"endOffset":205905,"count":0}],"isBlockCoverage":false},{"functionName":"UriData__uriEncodeBytes","ranges":[{"startOffset":205936,"endOffset":207460,"count":0}],"isBlockCoverage":false},{"functionName":"_createTables","ranges":[{"startOffset":207481,"endOffset":213521,"count":1}],"isBlockCoverage":true},{"functionName":"_scan","ranges":[{"startOffset":213534,"endOffset":214326,"count":1},{"startOffset":213774,"endOffset":213792,"count":0},{"startOffset":213934,"endOffset":213964,"count":0},{"startOffset":214075,"endOffset":214085,"count":0},{"startOffset":214130,"endOffset":214158,"count":0}],"isBlockCoverage":true},{"functionName":"NoSuchMethodError_toString_closure","ranges":[{"startOffset":214368,"endOffset":214471,"count":0}],"isBlockCoverage":false},{"functionName":"bool","ranges":[{"startOffset":214483,"endOffset":214506,"count":0}],"isBlockCoverage":false},{"functionName":"DateTime","ranges":[{"startOffset":214522,"endOffset":214608,"count":0}],"isBlockCoverage":false},{"functionName":"double","ranges":[{"startOffset":214622,"endOffset":214647,"count":0}],"isBlockCoverage":false},{"functionName":"Duration","ranges":[{"startOffset":214663,"endOffset":214719,"count":1}],"isBlockCoverage":true},{"functionName":"Duration_toString_sixDigits","ranges":[{"startOffset":214754,"endOffset":214800,"count":0}],"isBlockCoverage":false},{"functionName":"Duration_toString_twoDigits","ranges":[{"startOffset":214835,"endOffset":214881,"count":0}],"isBlockCoverage":false},{"functionName":"Error","ranges":[{"startOffset":214894,"endOffset":214918,"count":0}],"isBlockCoverage":false},{"functionName":"NullThrownError","ranges":[{"startOffset":214941,"endOffset":214975,"count":0}],"isBlockCoverage":false},{"functionName":"ArgumentError","ranges":[{"startOffset":214996,"endOffset":215154,"count":0}],"isBlockCoverage":false},{"functionName":"RangeError","ranges":[{"startOffset":215172,"endOffset":215373,"count":0}],"isBlockCoverage":false},{"functionName":"IndexError","ranges":[{"startOffset":215391,"endOffset":215571,"count":0}],"isBlockCoverage":false},{"functionName":"NoSuchMethodError","ranges":[{"startOffset":215596,"endOffset":215830,"count":0}],"isBlockCoverage":false},{"functionName":"UnsupportedError","ranges":[{"startOffset":215854,"endOffset":215916,"count":0}],"isBlockCoverage":false},{"functionName":"UnimplementedError","ranges":[{"startOffset":215942,"endOffset":216006,"count":0}],"isBlockCoverage":false},{"functionName":"StateError","ranges":[{"startOffset":216024,"endOffset":216080,"count":0}],"isBlockCoverage":false},{"functionName":"ConcurrentModificationError","ranges":[{"startOffset":216115,"endOffset":216195,"count":0}],"isBlockCoverage":false},{"functionName":"OutOfMemoryError","ranges":[{"startOffset":216219,"endOffset":216254,"count":1}],"isBlockCoverage":true},{"functionName":"StackOverflowError","ranges":[{"startOffset":216280,"endOffset":216317,"count":0}],"isBlockCoverage":false},{"functionName":"CyclicInitializationError","ranges":[{"startOffset":216350,"endOffset":216426,"count":0}],"isBlockCoverage":false},{"functionName":"_Exception","ranges":[{"startOffset":216444,"endOffset":216500,"count":0}],"isBlockCoverage":false},{"functionName":"FormatException","ranges":[{"startOffset":216523,"endOffset":216640,"count":0}],"isBlockCoverage":false},{"functionName":"Function","ranges":[{"startOffset":216656,"endOffset":216683,"count":0}],"isBlockCoverage":false},{"functionName":"int","ranges":[{"startOffset":216694,"endOffset":216716,"count":0}],"isBlockCoverage":false},{"functionName":"Iterable","ranges":[{"startOffset":216732,"endOffset":216759,"count":0}],"isBlockCoverage":false},{"functionName":"Iterator","ranges":[{"startOffset":216775,"endOffset":216802,"count":0}],"isBlockCoverage":false},{"functionName":"List","ranges":[{"startOffset":216814,"endOffset":216837,"count":0}],"isBlockCoverage":false},{"functionName":"Map","ranges":[{"startOffset":216848,"endOffset":216870,"count":0}],"isBlockCoverage":false},{"functionName":"Null","ranges":[{"startOffset":216882,"endOffset":216905,"count":0}],"isBlockCoverage":false},{"functionName":"num","ranges":[{"startOffset":216916,"endOffset":216938,"count":0}],"isBlockCoverage":false},{"functionName":"Object","ranges":[{"startOffset":216952,"endOffset":216977,"count":0}],"isBlockCoverage":true},{"functionName":"Match","ranges":[{"startOffset":216990,"endOffset":217014,"count":0}],"isBlockCoverage":false},{"functionName":"StackTrace","ranges":[{"startOffset":217032,"endOffset":217061,"count":0}],"isBlockCoverage":false},{"functionName":"_StringStackTrace","ranges":[{"startOffset":217086,"endOffset":217153,"count":0}],"isBlockCoverage":false},{"functionName":"String","ranges":[{"startOffset":217167,"endOffset":217192,"count":0}],"isBlockCoverage":false},{"functionName":"StringBuffer","ranges":[{"startOffset":217212,"endOffset":217272,"count":1}],"isBlockCoverage":true},{"functionName":"Symbol0","ranges":[{"startOffset":217287,"endOffset":217313,"count":0}],"isBlockCoverage":false},{"functionName":"Uri_splitQueryString_closure","ranges":[{"startOffset":217349,"endOffset":217424,"count":1}],"isBlockCoverage":true},{"functionName":"Uri__parseIPv4Address_error","ranges":[{"startOffset":217459,"endOffset":217529,"count":0}],"isBlockCoverage":false},{"functionName":"Uri_parseIPv6Address_error","ranges":[{"startOffset":217563,"endOffset":217632,"count":0}],"isBlockCoverage":false},{"functionName":"Uri_parseIPv6Address_parseHex","ranges":[{"startOffset":217669,"endOffset":217768,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri","ranges":[{"startOffset":217780,"endOffset":218078,"count":1}],"isBlockCoverage":true},{"functionName":"_Uri__Uri$notSimple_closure","ranges":[{"startOffset":218113,"endOffset":218213,"count":1}],"isBlockCoverage":true},{"functionName":"_Uri__checkNonWindowsPathReservedCharacters_closure","ranges":[{"startOffset":218272,"endOffset":218375,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__makePath_closure","ranges":[{"startOffset":218405,"endOffset":218446,"count":0}],"isBlockCoverage":false},{"functionName":"UriData","ranges":[{"startOffset":218461,"endOffset":218582,"count":0}],"isBlockCoverage":false},{"functionName":"_createTables_closure","ranges":[{"startOffset":218611,"endOffset":218651,"count":1}],"isBlockCoverage":true},{"functionName":"_createTables_build","ranges":[{"startOffset":218678,"endOffset":218742,"count":1}],"isBlockCoverage":true},{"functionName":"_createTables_setChars","ranges":[{"startOffset":218772,"endOffset":218813,"count":1}],"isBlockCoverage":true},{"functionName":"_createTables_setRange","ranges":[{"startOffset":218843,"endOffset":218884,"count":1}],"isBlockCoverage":true},{"functionName":"_SimpleUri","ranges":[{"startOffset":218902,"endOffset":219213,"count":0}],"isBlockCoverage":false},{"functionName":"_DataUri","ranges":[{"startOffset":219229,"endOffset":219531,"count":0}],"isBlockCoverage":false},{"functionName":"convertNativePromiseToDartFuture","ranges":[{"startOffset":219571,"endOffset":219951,"count":0}],"isBlockCoverage":false},{"functionName":"_StructuredClone","ranges":[{"startOffset":219975,"endOffset":220010,"count":0}],"isBlockCoverage":false},{"functionName":"_StructuredClone_walk_closure","ranges":[{"startOffset":220047,"endOffset":220148,"count":1}],"isBlockCoverage":true},{"functionName":"_AcceptStructuredClone","ranges":[{"startOffset":220178,"endOffset":220219,"count":0}],"isBlockCoverage":false},{"functionName":"_AcceptStructuredClone_walk_closure","ranges":[{"startOffset":220262,"endOffset":220369,"count":1}],"isBlockCoverage":true},{"functionName":"_StructuredCloneDart2Js","ranges":[{"startOffset":220400,"endOffset":220496,"count":1}],"isBlockCoverage":true},{"functionName":"_AcceptStructuredCloneDart2Js","ranges":[{"startOffset":220533,"endOffset":220664,"count":1}],"isBlockCoverage":true},{"functionName":"convertNativePromiseToDartFuture_closure","ranges":[{"startOffset":220712,"endOffset":220800,"count":0}],"isBlockCoverage":false},{"functionName":"convertNativePromiseToDartFuture_closure0","ranges":[{"startOffset":220849,"endOffset":220938,"count":0}],"isBlockCoverage":false},{"functionName":"SvgElement","ranges":[{"startOffset":220956,"endOffset":220985,"count":0}],"isBlockCoverage":false},{"functionName":"Uint8List","ranges":[{"startOffset":221002,"endOffset":221030,"count":0}],"isBlockCoverage":false},{"functionName":"_convertDartFunctionFast","ranges":[{"startOffset":221062,"endOffset":221474,"count":1},{"startOffset":221174,"endOffset":221190,"count":0}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":221203,"endOffset":221337,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":221239,"endOffset":221328,"count":0}],"isBlockCoverage":false},{"functionName":"_callDartFunctionFast","ranges":[{"startOffset":221503,"endOffset":221700,"count":0}],"isBlockCoverage":false},{"functionName":"allowInterop","ranges":[{"startOffset":221720,"endOffset":222089,"count":1},{"startOffset":221983,"endOffset":221992,"count":0}],"isBlockCoverage":true},{"functionName":"max","ranges":[{"startOffset":222100,"endOffset":222411,"count":0}],"isBlockCoverage":false},{"functionName":"window","ranges":[{"startOffset":222437,"endOffset":222476,"count":1}],"isBlockCoverage":true},{"functionName":"WebSocket_WebSocket","ranges":[{"startOffset":222503,"endOffset":222557,"count":1}],"isBlockCoverage":true},{"functionName":"_EventStreamSubscription$","ranges":[{"startOffset":222590,"endOffset":222884,"count":1},{"startOffset":222677,"endOffset":222683,"count":0}],"isBlockCoverage":true},{"functionName":"_convertNativeToDart_Window","ranges":[{"startOffset":222919,"endOffset":223033,"count":1},{"startOffset":222966,"endOffset":222973,"count":0}],"isBlockCoverage":true},{"functionName":"_DOMWindowCrossFrame__createSafe","ranges":[{"startOffset":223073,"endOffset":223232,"count":1},{"startOffset":223119,"endOffset":223169,"count":0}],"isBlockCoverage":true},{"functionName":"_wrapZone","ranges":[{"startOffset":223249,"endOffset":223507,"count":1},{"startOffset":223425,"endOffset":223441,"count":0}],"isBlockCoverage":true},{"functionName":"HtmlElement","ranges":[{"startOffset":223526,"endOffset":223556,"count":0}],"isBlockCoverage":false},{"functionName":"AnchorElement","ranges":[{"startOffset":223577,"endOffset":223609,"count":0}],"isBlockCoverage":false},{"functionName":"AreaElement","ranges":[{"startOffset":223628,"endOffset":223658,"count":0}],"isBlockCoverage":false},{"functionName":"Blob","ranges":[{"startOffset":223670,"endOffset":223693,"count":0}],"isBlockCoverage":false},{"functionName":"CharacterData","ranges":[{"startOffset":223714,"endOffset":223746,"count":0}],"isBlockCoverage":false},{"functionName":"DomException","ranges":[{"startOffset":223766,"endOffset":223797,"count":0}],"isBlockCoverage":false},{"functionName":"DomTokenList","ranges":[{"startOffset":223817,"endOffset":223848,"count":0}],"isBlockCoverage":false},{"functionName":"Element","ranges":[{"startOffset":223863,"endOffset":223889,"count":0}],"isBlockCoverage":false},{"functionName":"Event","ranges":[{"startOffset":223902,"endOffset":223926,"count":0}],"isBlockCoverage":false},{"functionName":"EventTarget","ranges":[{"startOffset":223945,"endOffset":223975,"count":0}],"isBlockCoverage":false},{"functionName":"File","ranges":[{"startOffset":223987,"endOffset":224010,"count":0}],"isBlockCoverage":false},{"functionName":"FormElement","ranges":[{"startOffset":224029,"endOffset":224059,"count":0}],"isBlockCoverage":false},{"functionName":"HtmlCollection","ranges":[{"startOffset":224081,"endOffset":224114,"count":0}],"isBlockCoverage":false},{"functionName":"IFrameElement","ranges":[{"startOffset":224135,"endOffset":224167,"count":0}],"isBlockCoverage":false},{"functionName":"Location","ranges":[{"startOffset":224183,"endOffset":224210,"count":0}],"isBlockCoverage":false},{"functionName":"MessageEvent","ranges":[{"startOffset":224230,"endOffset":224261,"count":0}],"isBlockCoverage":false},{"functionName":"MessagePort","ranges":[{"startOffset":224280,"endOffset":224310,"count":0}],"isBlockCoverage":false},{"functionName":"MouseEvent","ranges":[{"startOffset":224328,"endOffset":224357,"count":0}],"isBlockCoverage":false},{"functionName":"Node","ranges":[{"startOffset":224369,"endOffset":224392,"count":0}],"isBlockCoverage":false},{"functionName":"SelectElement","ranges":[{"startOffset":224413,"endOffset":224445,"count":0}],"isBlockCoverage":false},{"functionName":"UIEvent","ranges":[{"startOffset":224460,"endOffset":224486,"count":0}],"isBlockCoverage":false},{"functionName":"Window","ranges":[{"startOffset":224500,"endOffset":224525,"count":0}],"isBlockCoverage":false},{"functionName":"_EventStream","ranges":[{"startOffset":224545,"endOffset":224707,"count":0}],"isBlockCoverage":false},{"functionName":"_ElementEventStreamImpl","ranges":[{"startOffset":224738,"endOffset":224911,"count":1}],"isBlockCoverage":true},{"functionName":"_EventStreamSubscription","ranges":[{"startOffset":224943,"endOffset":225168,"count":1}],"isBlockCoverage":true},{"functionName":"_EventStreamSubscription_closure","ranges":[{"startOffset":225208,"endOffset":225285,"count":1}],"isBlockCoverage":true},{"functionName":"ImmutableListMixin","ranges":[{"startOffset":225311,"endOffset":225348,"count":0}],"isBlockCoverage":false},{"functionName":"FixedSizeListIterator","ranges":[{"startOffset":225377,"endOffset":225561,"count":0}],"isBlockCoverage":false},{"functionName":"_DOMWindowCrossFrame","ranges":[{"startOffset":225589,"endOffset":225655,"count":1}],"isBlockCoverage":true},{"functionName":"_HtmlCollection_Interceptor_ListMixin","ranges":[{"startOffset":225700,"endOffset":225756,"count":0}],"isBlockCoverage":false},{"functionName":"_HtmlCollection_Interceptor_ListMixin_ImmutableListMixin","ranges":[{"startOffset":225820,"endOffset":225895,"count":0}],"isBlockCoverage":false},{"functionName":"NullStreamSink","ranges":[{"startOffset":225924,"endOffset":226081,"count":0}],"isBlockCoverage":false},{"functionName":"NullStreamSink_addStream_closure","ranges":[{"startOffset":226117,"endOffset":226193,"count":0}],"isBlockCoverage":false},{"functionName":"Context_Context","ranges":[{"startOffset":226225,"endOffset":226413,"count":0}],"isBlockCoverage":false},{"functionName":"_parseUri","ranges":[{"startOffset":226430,"endOffset":226613,"count":0}],"isBlockCoverage":false},{"functionName":"_validateArgList","ranges":[{"startOffset":226637,"endOffset":227693,"count":0}],"isBlockCoverage":false},{"functionName":"Context","ranges":[{"startOffset":227708,"endOffset":227798,"count":0}],"isBlockCoverage":false},{"functionName":"Context_join_closure","ranges":[{"startOffset":227826,"endOffset":227865,"count":0}],"isBlockCoverage":false},{"functionName":"Context_joinAll_closure","ranges":[{"startOffset":227896,"endOffset":227938,"count":0}],"isBlockCoverage":false},{"functionName":"Context_split_closure","ranges":[{"startOffset":227967,"endOffset":228007,"count":0}],"isBlockCoverage":false},{"functionName":"_validateArgList_closure","ranges":[{"startOffset":228039,"endOffset":228082,"count":0}],"isBlockCoverage":false},{"functionName":"InternalStyle","ranges":[{"startOffset":228110,"endOffset":228142,"count":0}],"isBlockCoverage":false},{"functionName":"StreamChannelController$","ranges":[{"startOffset":228174,"endOffset":228991,"count":1}],"isBlockCoverage":true},{"functionName":"StreamChannelController","ranges":[{"startOffset":229022,"endOffset":229129,"count":1}],"isBlockCoverage":true},{"functionName":"isAlphabetic","ranges":[{"startOffset":229149,"endOffset":229311,"count":0}],"isBlockCoverage":false},{"functionName":"isDriveLetter","ranges":[{"startOffset":229332,"endOffset":229761,"count":0}],"isBlockCoverage":false},{"functionName":"ParsedPath_ParsedPath$parse","ranges":[{"startOffset":229808,"endOffset":231004,"count":0}],"isBlockCoverage":false},{"functionName":"ParsedPath","ranges":[{"startOffset":231022,"endOffset":231169,"count":0}],"isBlockCoverage":false},{"functionName":"ParsedPath_normalize_closure","ranges":[{"startOffset":231205,"endOffset":231277,"count":0}],"isBlockCoverage":false},{"functionName":"PathException$","ranges":[{"startOffset":231299,"endOffset":231367,"count":0}],"isBlockCoverage":false},{"functionName":"PathException","ranges":[{"startOffset":231388,"endOffset":231447,"count":0}],"isBlockCoverage":false},{"functionName":"Style__getPlatformStyle","ranges":[{"startOffset":231490,"endOffset":231852,"count":0}],"isBlockCoverage":false},{"functionName":"Style","ranges":[{"startOffset":231865,"endOffset":231889,"count":0}],"isBlockCoverage":false},{"functionName":"PosixStyle","ranges":[{"startOffset":231914,"endOffset":231998,"count":0}],"isBlockCoverage":false},{"functionName":"UrlStyle","ranges":[{"startOffset":232018,"endOffset":232098,"count":0}],"isBlockCoverage":false},{"functionName":"WindowsStyle","ranges":[{"startOffset":232122,"endOffset":232211,"count":0}],"isBlockCoverage":false},{"functionName":"WindowsStyle_absolutePathToUri_closure","ranges":[{"startOffset":232253,"endOffset":232310,"count":0}],"isBlockCoverage":false},{"functionName":"Chain_Chain$parse","ranges":[{"startOffset":232344,"endOffset":233600,"count":0}],"isBlockCoverage":false},{"functionName":"Chain","ranges":[{"startOffset":233613,"endOffset":233663,"count":0}],"isBlockCoverage":false},{"functionName":"Chain_Chain$parse_closure","ranges":[{"startOffset":233696,"endOffset":233740,"count":0}],"isBlockCoverage":false},{"functionName":"Chain_Chain$parse_closure0","ranges":[{"startOffset":233774,"endOffset":233819,"count":0}],"isBlockCoverage":false},{"functionName":"Chain_toTrace_closure","ranges":[{"startOffset":233848,"endOffset":233888,"count":0}],"isBlockCoverage":false},{"functionName":"Chain_toString_closure0","ranges":[{"startOffset":233919,"endOffset":233961,"count":0}],"isBlockCoverage":false},{"functionName":"Chain_toString__closure0","ranges":[{"startOffset":233993,"endOffset":234036,"count":0}],"isBlockCoverage":false},{"functionName":"Chain_toString_closure","ranges":[{"startOffset":234066,"endOffset":234134,"count":0}],"isBlockCoverage":false},{"functionName":"Chain_toString__closure","ranges":[{"startOffset":234165,"endOffset":234234,"count":0}],"isBlockCoverage":false},{"functionName":"Frame_Frame$parseVM","ranges":[{"startOffset":234273,"endOffset":234389,"count":0}],"isBlockCoverage":false},{"functionName":"Frame_Frame$parseV8","ranges":[{"startOffset":234416,"endOffset":234532,"count":0}],"isBlockCoverage":false},{"functionName":"Frame_Frame$parseFirefox","ranges":[{"startOffset":234564,"endOffset":234685,"count":0}],"isBlockCoverage":false},{"functionName":"Frame_Frame$parseFriendly","ranges":[{"startOffset":234718,"endOffset":234840,"count":0}],"isBlockCoverage":false},{"functionName":"Frame__uriOrPathToUri","ranges":[{"startOffset":234869,"endOffset":235427,"count":0}],"isBlockCoverage":false},{"functionName":"Frame__catchFormatException","ranges":[{"startOffset":235462,"endOffset":235866,"count":0}],"isBlockCoverage":false},{"functionName":"Frame","ranges":[{"startOffset":235879,"endOffset":236016,"count":0}],"isBlockCoverage":false},{"functionName":"Frame_Frame$parseVM_closure","ranges":[{"startOffset":236051,"endOffset":236122,"count":0}],"isBlockCoverage":false},{"functionName":"Frame_Frame$parseV8_closure","ranges":[{"startOffset":236157,"endOffset":236228,"count":0}],"isBlockCoverage":false},{"functionName":"Frame_Frame$parseV8_closure_parseLocation","ranges":[{"startOffset":236277,"endOffset":236362,"count":0}],"isBlockCoverage":false},{"functionName":"Frame_Frame$parseFirefox_closure","ranges":[{"startOffset":236402,"endOffset":236478,"count":0}],"isBlockCoverage":false},{"functionName":"Frame_Frame$parseFriendly_closure","ranges":[{"startOffset":236519,"endOffset":236596,"count":0}],"isBlockCoverage":false},{"functionName":"LazyTrace","ranges":[{"startOffset":236620,"endOffset":236712,"count":0}],"isBlockCoverage":false},{"functionName":"LazyTrace_terse_closure","ranges":[{"startOffset":236739,"endOffset":236806,"count":0}],"isBlockCoverage":false},{"functionName":"Trace_Trace$from","ranges":[{"startOffset":236839,"endOffset":237153,"count":0}],"isBlockCoverage":false},{"functionName":"Trace_Trace$parse","ranges":[{"startOffset":237178,"endOffset":238690,"count":0}],"isBlockCoverage":false},{"functionName":"Trace__parseVM","ranges":[{"startOffset":238712,"endOffset":239434,"count":0}],"isBlockCoverage":false},{"functionName":"Trace$parseV8","ranges":[{"startOffset":239455,"endOffset":240083,"count":0}],"isBlockCoverage":false},{"functionName":"Trace$parseJSCore","ranges":[{"startOffset":240108,"endOffset":240613,"count":0}],"isBlockCoverage":false},{"functionName":"Trace$parseFirefox","ranges":[{"startOffset":240639,"endOffset":241158,"count":0}],"isBlockCoverage":false},{"functionName":"Trace$parseFriendly","ranges":[{"startOffset":241185,"endOffset":241840,"count":0}],"isBlockCoverage":false},{"functionName":"Trace","ranges":[{"startOffset":241853,"endOffset":241933,"count":0}],"isBlockCoverage":false},{"functionName":"Trace_Trace$from_closure","ranges":[{"startOffset":241965,"endOffset":242033,"count":0}],"isBlockCoverage":false},{"functionName":"Trace__parseVM_closure","ranges":[{"startOffset":242063,"endOffset":242104,"count":0}],"isBlockCoverage":false},{"functionName":"Trace$parseV8_closure","ranges":[{"startOffset":242133,"endOffset":242173,"count":0}],"isBlockCoverage":false},{"functionName":"Trace$parseV8_closure0","ranges":[{"startOffset":242203,"endOffset":242244,"count":0}],"isBlockCoverage":false},{"functionName":"Trace$parseJSCore_closure","ranges":[{"startOffset":242277,"endOffset":242321,"count":0}],"isBlockCoverage":false},{"functionName":"Trace$parseJSCore_closure0","ranges":[{"startOffset":242355,"endOffset":242400,"count":0}],"isBlockCoverage":false},{"functionName":"Trace$parseFirefox_closure","ranges":[{"startOffset":242434,"endOffset":242479,"count":0}],"isBlockCoverage":false},{"functionName":"Trace$parseFirefox_closure0","ranges":[{"startOffset":242514,"endOffset":242560,"count":0}],"isBlockCoverage":false},{"functionName":"Trace$parseFriendly_closure","ranges":[{"startOffset":242595,"endOffset":242641,"count":0}],"isBlockCoverage":false},{"functionName":"Trace$parseFriendly_closure0","ranges":[{"startOffset":242677,"endOffset":242724,"count":0}],"isBlockCoverage":false},{"functionName":"Trace_terse_closure","ranges":[{"startOffset":242751,"endOffset":242789,"count":0}],"isBlockCoverage":false},{"functionName":"Trace_foldFrames_closure","ranges":[{"startOffset":242821,"endOffset":242896,"count":0}],"isBlockCoverage":false},{"functionName":"Trace_foldFrames_closure0","ranges":[{"startOffset":242929,"endOffset":242999,"count":0}],"isBlockCoverage":false},{"functionName":"Trace_toString_closure0","ranges":[{"startOffset":243030,"endOffset":243072,"count":0}],"isBlockCoverage":false},{"functionName":"Trace_toString_closure","ranges":[{"startOffset":243102,"endOffset":243170,"count":0}],"isBlockCoverage":false},{"functionName":"UnparsedFrame","ranges":[{"startOffset":243198,"endOffset":243437,"count":0}],"isBlockCoverage":false},{"functionName":"GuaranteeChannel$","ranges":[{"startOffset":243471,"endOffset":243729,"count":1}],"isBlockCoverage":true},{"functionName":"GuaranteeChannel","ranges":[{"startOffset":243753,"endOffset":243940,"count":1}],"isBlockCoverage":true},{"functionName":"GuaranteeChannel_closure","ranges":[{"startOffset":243972,"endOffset":244068,"count":1}],"isBlockCoverage":true},{"functionName":"GuaranteeChannel__closure","ranges":[{"startOffset":244101,"endOffset":244170,"count":1}],"isBlockCoverage":true},{"functionName":"_GuaranteeSink","ranges":[{"startOffset":244192,"endOffset":244487,"count":1}],"isBlockCoverage":true},{"functionName":"_GuaranteeSink_addStream_closure","ranges":[{"startOffset":244527,"endOffset":244603,"count":1}],"isBlockCoverage":true},{"functionName":"main","ranges":[{"startOffset":244615,"endOffset":244926,"count":1},{"startOffset":244690,"endOffset":244714,"count":0}],"isBlockCoverage":true},{"functionName":"_connectToServer","ranges":[{"startOffset":244950,"endOffset":245613,"count":1}],"isBlockCoverage":true},{"functionName":"_connectToIframe","ranges":[{"startOffset":245637,"endOffset":247021,"count":1}],"isBlockCoverage":true},{"functionName":"_TestRunner","ranges":[{"startOffset":247040,"endOffset":247070,"count":0}],"isBlockCoverage":false},{"functionName":"_JSApi","ranges":[{"startOffset":247084,"endOffset":247109,"count":0}],"isBlockCoverage":false},{"functionName":"main_closure","ranges":[{"startOffset":247129,"endOffset":247160,"count":1}],"isBlockCoverage":true},{"functionName":"main__closure","ranges":[{"startOffset":247181,"endOffset":247246,"count":1}],"isBlockCoverage":true},{"functionName":"main__closure0","ranges":[{"startOffset":247268,"endOffset":247334,"count":1}],"isBlockCoverage":true},{"functionName":"main__closure1","ranges":[{"startOffset":247356,"endOffset":247422,"count":1}],"isBlockCoverage":true},{"functionName":"main__closure2","ranges":[{"startOffset":247444,"endOffset":247510,"count":1}],"isBlockCoverage":true},{"functionName":"main__closure3","ranges":[{"startOffset":247532,"endOffset":247598,"count":1}],"isBlockCoverage":true},{"functionName":"main_closure0","ranges":[{"startOffset":247619,"endOffset":247651,"count":1}],"isBlockCoverage":true},{"functionName":"_connectToServer_closure","ranges":[{"startOffset":247683,"endOffset":247756,"count":1}],"isBlockCoverage":true},{"functionName":"_connectToServer_closure0","ranges":[{"startOffset":247789,"endOffset":247862,"count":1}],"isBlockCoverage":true},{"functionName":"_connectToIframe_closure","ranges":[{"startOffset":247894,"endOffset":248068,"count":1}],"isBlockCoverage":true},{"functionName":"_connectToIframe_closure0","ranges":[{"startOffset":248101,"endOffset":248175,"count":1}],"isBlockCoverage":true},{"functionName":"_connectToIframe_closure1","ranges":[{"startOffset":248208,"endOffset":248315,"count":1}],"isBlockCoverage":true},{"functionName":"_MultiChannel$","ranges":[{"startOffset":248349,"endOffset":248683,"count":1}],"isBlockCoverage":true},{"functionName":"_MultiChannel","ranges":[{"startOffset":248704,"endOffset":249002,"count":1}],"isBlockCoverage":true},{"functionName":"_MultiChannel_closure","ranges":[{"startOffset":249031,"endOffset":249119,"count":1}],"isBlockCoverage":true},{"functionName":"_MultiChannel_closure0","ranges":[{"startOffset":249149,"endOffset":249215,"count":1}],"isBlockCoverage":true},{"functionName":"_MultiChannel_closure1","ranges":[{"startOffset":249245,"endOffset":249334,"count":1}],"isBlockCoverage":true},{"functionName":"_MultiChannel__closure","ranges":[{"startOffset":249364,"endOffset":249477,"count":1}],"isBlockCoverage":true},{"functionName":"_MultiChannel_virtualChannel_closure","ranges":[{"startOffset":249521,"endOffset":249629,"count":1}],"isBlockCoverage":true},{"functionName":"_MultiChannel_virtualChannel_closure0","ranges":[{"startOffset":249674,"endOffset":249783,"count":1}],"isBlockCoverage":true},{"functionName":"VirtualChannel","ranges":[{"startOffset":249805,"endOffset":249952,"count":1}],"isBlockCoverage":true},{"functionName":"current","ranges":[{"startOffset":249967,"endOffset":250526,"count":0}],"isBlockCoverage":false},{"functionName":"StreamChannelMixin","ranges":[{"startOffset":250559,"endOffset":250596,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":250814,"endOffset":250880,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":250900,"endOffset":250978,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":250996,"endOffset":251098,"count":0}],"isBlockCoverage":false},{"functionName":"noSuchMethod$1","ranges":[{"startOffset":251120,"endOffset":251378,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":251425,"endOffset":251482,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":251502,"endOffset":251569,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":251625,"endOffset":251686,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":251704,"endOffset":251751,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":251771,"endOffset":251813,"count":0}],"isBlockCoverage":false},{"functionName":"noSuchMethod$1","ranges":[{"startOffset":251835,"endOffset":251986,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":252061,"endOffset":252103,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":252121,"endOffset":252178,"count":0}],"isBlockCoverage":false},{"functionName":"waitUntilDone$0","ranges":[{"startOffset":252201,"endOffset":252266,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":252411,"endOffset":252677,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":252695,"endOffset":252762,"count":0}],"isBlockCoverage":false},{"functionName":"add$1","ranges":[{"startOffset":252825,"endOffset":253058,"count":1},{"startOffset":252978,"endOffset":253024,"count":0}],"isBlockCoverage":true},{"functionName":"removeAt$1","ranges":[{"startOffset":253076,"endOffset":253376,"count":0}],"isBlockCoverage":false},{"functionName":"insert$2","ranges":[{"startOffset":253392,"endOffset":253775,"count":0}],"isBlockCoverage":false},{"functionName":"insertAll$2","ranges":[{"startOffset":253794,"endOffset":254419,"count":0}],"isBlockCoverage":false},{"functionName":"removeLast$0","ranges":[{"startOffset":254439,"endOffset":254691,"count":0}],"isBlockCoverage":false},{"functionName":"addAll$1","ranges":[{"startOffset":254707,"endOffset":255155,"count":0}],"isBlockCoverage":false},{"functionName":"forEach$1","ranges":[{"startOffset":255172,"endOffset":255530,"count":0}],"isBlockCoverage":false},{"functionName":"join$1","ranges":[{"startOffset":255544,"endOffset":255804,"count":0}],"isBlockCoverage":false},{"functionName":"join$0","ranges":[{"startOffset":255818,"endOffset":255886,"count":0}],"isBlockCoverage":false},{"functionName":"fold$1$2","ranges":[{"startOffset":255902,"endOffset":256434,"count":1},{"startOffset":256336,"endOffset":256400,"count":0}],"isBlockCoverage":true},{"functionName":"elementAt$1","ranges":[{"startOffset":256453,"endOffset":256606,"count":0}],"isBlockCoverage":false},{"functionName":"sublist$2","ranges":[{"startOffset":256623,"endOffset":257154,"count":0}],"isBlockCoverage":false},{"functionName":"get$first","ranges":[{"startOffset":257171,"endOffset":257321,"count":0}],"isBlockCoverage":false},{"functionName":"get$last","ranges":[{"startOffset":257337,"endOffset":257511,"count":0}],"isBlockCoverage":false},{"functionName":"setRange$4","ranges":[{"startOffset":257529,"endOffset":258508,"count":0}],"isBlockCoverage":false},{"functionName":"setRange$3","ranges":[{"startOffset":258526,"endOffset":258641,"count":0}],"isBlockCoverage":false},{"functionName":"get$isNotEmpty","ranges":[{"startOffset":258663,"endOffset":258725,"count":1}],"isBlockCoverage":true},{"functionName":"toString$0","ranges":[{"startOffset":258743,"endOffset":258839,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":258859,"endOffset":258990,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":259010,"endOffset":259088,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":259106,"endOffset":259162,"count":1}],"isBlockCoverage":true},{"functionName":"set$length","ranges":[{"startOffset":259180,"endOffset":259464,"count":1},{"startOffset":259255,"endOffset":259308,"count":0},{"startOffset":259342,"endOffset":259423,"count":0}],"isBlockCoverage":true},{"functionName":"$index","ranges":[{"startOffset":259478,"endOffset":259689,"count":1},{"startOffset":259592,"endOffset":259653,"count":0}],"isBlockCoverage":true},{"functionName":"$indexSet","ranges":[{"startOffset":259706,"endOffset":260245,"count":1},{"startOffset":259897,"endOffset":259951,"count":0},{"startOffset":260028,"endOffset":260089,"count":0},{"startOffset":260147,"endOffset":260208,"count":0}],"isBlockCoverage":true},{"functionName":"get$current","ranges":[{"startOffset":260411,"endOffset":260472,"count":0}],"isBlockCoverage":false},{"functionName":"moveNext$0","ranges":[{"startOffset":260490,"endOffset":260928,"count":0}],"isBlockCoverage":false},{"functionName":"set$__interceptors$_current","ranges":[{"startOffset":260963,"endOffset":261101,"count":0}],"isBlockCoverage":false},{"functionName":"toRadixString$1","ranges":[{"startOffset":261175,"endOffset":262041,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":262059,"endOffset":262195,"count":1},{"startOffset":262134,"endOffset":262148,"count":0}],"isBlockCoverage":true},{"functionName":"get$hashCode","ranges":[{"startOffset":262215,"endOffset":262729,"count":0}],"isBlockCoverage":false},{"functionName":"$mod","ranges":[{"startOffset":262741,"endOffset":262992,"count":0}],"isBlockCoverage":false},{"functionName":"$tdiv","ranges":[{"startOffset":263005,"endOffset":263202,"count":0}],"isBlockCoverage":false},{"functionName":"_tdivFast$1","ranges":[{"startOffset":263221,"endOffset":263355,"count":1},{"startOffset":263313,"endOffset":263348,"count":0}],"isBlockCoverage":true},{"functionName":"_tdivSlow$1","ranges":[{"startOffset":263374,"endOffset":263848,"count":0}],"isBlockCoverage":false},{"functionName":"_shrOtherPositive$1","ranges":[{"startOffset":263875,"endOffset":264112,"count":1},{"startOffset":263995,"endOffset":264089,"count":0}],"isBlockCoverage":true},{"functionName":"_shrReceiverPositive$1","ranges":[{"startOffset":264142,"endOffset":264311,"count":0}],"isBlockCoverage":false},{"functionName":"_shrBothPositive$1","ranges":[{"startOffset":264337,"endOffset":264420,"count":1},{"startOffset":264389,"endOffset":264392,"count":0}],"isBlockCoverage":true},{"functionName":"$gt","ranges":[{"startOffset":264431,"endOffset":264592,"count":0}],"isBlockCoverage":false},{"functionName":"codeUnitAt$1","ranges":[{"startOffset":264740,"endOffset":265145,"count":1},{"startOffset":264844,"endOffset":264905,"count":0},{"startOffset":264935,"endOffset":264996,"count":0},{"startOffset":265041,"endOffset":265098,"count":0}],"isBlockCoverage":true},{"functionName":"_codeUnitAt$1","ranges":[{"startOffset":265166,"endOffset":265346,"count":1},{"startOffset":265238,"endOffset":265299,"count":0}],"isBlockCoverage":true},{"functionName":"allMatches$2","ranges":[{"startOffset":265366,"endOffset":265723,"count":0}],"isBlockCoverage":false},{"functionName":"allMatches$1","ranges":[{"startOffset":265743,"endOffset":265832,"count":0}],"isBlockCoverage":false},{"functionName":"matchAsPrefix$2","ranges":[{"startOffset":265855,"endOffset":266378,"count":0}],"isBlockCoverage":false},{"functionName":"$add","ranges":[{"startOffset":266390,"endOffset":266564,"count":0}],"isBlockCoverage":false},{"functionName":"endsWith$1","ranges":[{"startOffset":266582,"endOffset":266823,"count":0}],"isBlockCoverage":false},{"functionName":"replaceFirst$2","ranges":[{"startOffset":266845,"endOffset":267026,"count":0}],"isBlockCoverage":false},{"functionName":"replaceRange$3","ranges":[{"startOffset":267048,"endOffset":267373,"count":0}],"isBlockCoverage":false},{"functionName":"startsWith$2","ranges":[{"startOffset":267393,"endOffset":268070,"count":1},{"startOffset":267526,"endOffset":267573,"count":0},{"startOffset":267619,"endOffset":267638,"count":0},{"startOffset":267695,"endOffset":267776,"count":0},{"startOffset":267911,"endOffset":267924,"count":0},{"startOffset":267996,"endOffset":268069,"count":0}],"isBlockCoverage":true},{"functionName":"startsWith$1","ranges":[{"startOffset":268090,"endOffset":268181,"count":1}],"isBlockCoverage":true},{"functionName":"substring$2","ranges":[{"startOffset":268200,"endOffset":268888,"count":1},{"startOffset":268334,"endOffset":268386,"count":0},{"startOffset":268501,"endOffset":268525,"count":0},{"startOffset":268560,"endOffset":268620,"count":0},{"startOffset":268662,"endOffset":268722,"count":0},{"startOffset":268769,"endOffset":268827,"count":0}],"isBlockCoverage":true},{"functionName":"substring$1","ranges":[{"startOffset":268907,"endOffset":269006,"count":1}],"isBlockCoverage":true},{"functionName":"trim$0","ranges":[{"startOffset":269020,"endOffset":269700,"count":0}],"isBlockCoverage":false},{"functionName":"$mul","ranges":[{"startOffset":269712,"endOffset":270191,"count":0}],"isBlockCoverage":false},{"functionName":"padRight$1","ranges":[{"startOffset":270209,"endOffset":270458,"count":0}],"isBlockCoverage":false},{"functionName":"indexOf$2","ranges":[{"startOffset":270475,"endOffset":270731,"count":1},{"startOffset":270582,"endOffset":270663,"count":0}],"isBlockCoverage":true},{"functionName":"indexOf$1","ranges":[{"startOffset":270748,"endOffset":270836,"count":1}],"isBlockCoverage":true},{"functionName":"lastIndexOf$2","ranges":[{"startOffset":270857,"endOffset":271276,"count":0}],"isBlockCoverage":false},{"functionName":"lastIndexOf$1","ranges":[{"startOffset":271297,"endOffset":271392,"count":0}],"isBlockCoverage":false},{"functionName":"contains$1","ranges":[{"startOffset":271410,"endOffset":271584,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":271602,"endOffset":271651,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":271671,"endOffset":272077,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":272095,"endOffset":272151,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":272165,"endOffset":272372,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":272459,"endOffset":272512,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":272526,"endOffset":272627,"count":0}],"isBlockCoverage":false},{"functionName":"$asEfficientLengthIterable","ranges":[{"startOffset":272661,"endOffset":272701,"count":0}],"isBlockCoverage":false},{"functionName":"$asUnmodifiableListMixin","ranges":[{"startOffset":272733,"endOffset":272773,"count":0}],"isBlockCoverage":false},{"functionName":"$asListMixin","ranges":[{"startOffset":272793,"endOffset":272833,"count":0}],"isBlockCoverage":false},{"functionName":"$asIterable","ranges":[{"startOffset":272852,"endOffset":272892,"count":0}],"isBlockCoverage":false},{"functionName":"$asList","ranges":[{"startOffset":272907,"endOffset":272947,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":273046,"endOffset":273183,"count":0}],"isBlockCoverage":false},{"functionName":"get$isEmpty","ranges":[{"startOffset":273202,"endOffset":273263,"count":0}],"isBlockCoverage":false},{"functionName":"join$1","ranges":[{"startOffset":273277,"endOffset":274216,"count":0}],"isBlockCoverage":false},{"functionName":"join$0","ranges":[{"startOffset":274230,"endOffset":274298,"count":0}],"isBlockCoverage":false},{"functionName":"fold$1$2","ranges":[{"startOffset":274314,"endOffset":274870,"count":0}],"isBlockCoverage":false},{"functionName":"toList$1$growable","ranges":[{"startOffset":274895,"endOffset":275249,"count":0}],"isBlockCoverage":false},{"functionName":"toList$0","ranges":[{"startOffset":275265,"endOffset":275346,"count":0}],"isBlockCoverage":false},{"functionName":"get$_endIndex","ranges":[{"startOffset":275405,"endOffset":275616,"count":0}],"isBlockCoverage":false},{"functionName":"get$_startIndex","ranges":[{"startOffset":275639,"endOffset":275841,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":275859,"endOffset":276224,"count":0}],"isBlockCoverage":false},{"functionName":"elementAt$1","ranges":[{"startOffset":276243,"endOffset":276692,"count":0}],"isBlockCoverage":false},{"functionName":"get$current","ranges":[{"startOffset":276746,"endOffset":276803,"count":0}],"isBlockCoverage":false},{"functionName":"moveNext$0","ranges":[{"startOffset":276821,"endOffset":277341,"count":0}],"isBlockCoverage":false},{"functionName":"set$__internal$_current","ranges":[{"startOffset":277372,"endOffset":277506,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":277583,"endOffset":277702,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":277720,"endOffset":277797,"count":0}],"isBlockCoverage":false},{"functionName":"$asIterable","ranges":[{"startOffset":277816,"endOffset":277859,"count":0}],"isBlockCoverage":false},{"functionName":"$asEfficientLengthIterable","ranges":[{"startOffset":277975,"endOffset":278018,"count":0}],"isBlockCoverage":false},{"functionName":"moveNext$0","ranges":[{"startOffset":278073,"endOffset":278314,"count":0}],"isBlockCoverage":false},{"functionName":"get$current","ranges":[{"startOffset":278333,"endOffset":278390,"count":0}],"isBlockCoverage":false},{"functionName":"set$__internal$_current","ranges":[{"startOffset":278421,"endOffset":278555,"count":0}],"isBlockCoverage":false},{"functionName":"$asIterator","ranges":[{"startOffset":278574,"endOffset":278617,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":278676,"endOffset":278740,"count":0}],"isBlockCoverage":false},{"functionName":"elementAt$1","ranges":[{"startOffset":278759,"endOffset":278853,"count":0}],"isBlockCoverage":false},{"functionName":"$asEfficientLengthIterable","ranges":[{"startOffset":278887,"endOffset":278930,"count":0}],"isBlockCoverage":false},{"functionName":"$asListIterable","ranges":[{"startOffset":278953,"endOffset":278996,"count":0}],"isBlockCoverage":false},{"functionName":"$asIterable","ranges":[{"startOffset":279015,"endOffset":279058,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":279114,"endOffset":279232,"count":0}],"isBlockCoverage":false},{"functionName":"moveNext$0","ranges":[{"startOffset":279286,"endOffset":279470,"count":0}],"isBlockCoverage":false},{"functionName":"get$current","ranges":[{"startOffset":279489,"endOffset":279550,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":279607,"endOffset":279745,"count":0}],"isBlockCoverage":false},{"functionName":"$asIterable","ranges":[{"startOffset":279764,"endOffset":279807,"count":0}],"isBlockCoverage":false},{"functionName":"get$current","ranges":[{"startOffset":279863,"endOffset":279920,"count":0}],"isBlockCoverage":false},{"functionName":"moveNext$0","ranges":[{"startOffset":279938,"endOffset":280470,"count":0}],"isBlockCoverage":false},{"functionName":"set$_currentExpansion","ranges":[{"startOffset":280499,"endOffset":280668,"count":0}],"isBlockCoverage":false},{"functionName":"set$__internal$_current","ranges":[{"startOffset":280699,"endOffset":280833,"count":0}],"isBlockCoverage":false},{"functionName":"$asIterator","ranges":[{"startOffset":280872,"endOffset":280915,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":280975,"endOffset":281097,"count":0}],"isBlockCoverage":false},{"functionName":"moveNext$0","ranges":[{"startOffset":281155,"endOffset":281440,"count":0}],"isBlockCoverage":false},{"functionName":"get$current","ranges":[{"startOffset":281459,"endOffset":281520,"count":0}],"isBlockCoverage":false},{"functionName":"moveNext$0","ranges":[{"startOffset":281574,"endOffset":281612,"count":0}],"isBlockCoverage":false},{"functionName":"get$current","ranges":[{"startOffset":281631,"endOffset":281663,"count":0}],"isBlockCoverage":false},{"functionName":"$indexSet","ranges":[{"startOffset":281785,"endOffset":282038,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":282140,"endOffset":282204,"count":0}],"isBlockCoverage":false},{"functionName":"elementAt$1","ranges":[{"startOffset":282223,"endOffset":282393,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":282442,"endOffset":282661,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":282679,"endOffset":282759,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":282770,"endOffset":282934,"count":0}],"isBlockCoverage":false},{"functionName":"get$isEmpty","ranges":[{"startOffset":283042,"endOffset":283103,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":283121,"endOffset":283182,"count":0}],"isBlockCoverage":false},{"functionName":"$indexSet","ranges":[{"startOffset":283199,"endOffset":283429,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":283502,"endOffset":283560,"count":0}],"isBlockCoverage":false},{"functionName":"containsKey$1","ranges":[{"startOffset":283581,"endOffset":283761,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":283775,"endOffset":283884,"count":0}],"isBlockCoverage":false},{"functionName":"_fetch$1","ranges":[{"startOffset":283900,"endOffset":283974,"count":0}],"isBlockCoverage":false},{"functionName":"forEach$1","ranges":[{"startOffset":283991,"endOffset":284372,"count":0}],"isBlockCoverage":false},{"functionName":"Instantiation$1","ranges":[{"startOffset":284431,"endOffset":284530,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":284548,"endOffset":284741,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":284792,"endOffset":284881,"count":0}],"isBlockCoverage":false},{"functionName":"call$4","ranges":[{"startOffset":284895,"endOffset":285000,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":285018,"endOffset":285157,"count":0}],"isBlockCoverage":false},{"functionName":"get$memberName","ranges":[{"startOffset":285220,"endOffset":285288,"count":0}],"isBlockCoverage":false},{"functionName":"get$positionalArguments","ranges":[{"startOffset":285319,"endOffset":285850,"count":0}],"isBlockCoverage":false},{"functionName":"get$namedArguments","ranges":[{"startOffset":285876,"endOffset":286722,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":286820,"endOffset":287115,"count":0}],"isBlockCoverage":false},{"functionName":"matchTypeError$1","ranges":[{"startOffset":287198,"endOffset":287850,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":287900,"endOffset":288103,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":288163,"endOffset":288563,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":288622,"endOffset":288728,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":288838,"endOffset":289012,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":289083,"endOffset":289391,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":289461,"endOffset":289555,"count":0}],"isBlockCoverage":false},{"functionName":"get$$call","ranges":[{"startOffset":289592,"endOffset":289629,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":289793,"endOffset":289982,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":290028,"endOffset":290329,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":290349,"endOffset":290718,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":290736,"endOffset":290971,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":291035,"endOffset":291081,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":291145,"endOffset":291191,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":291244,"endOffset":291314,"count":0}],"isBlockCoverage":false},{"functionName":"get$_typeName","ranges":[{"startOffset":291366,"endOffset":291542,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":291560,"endOffset":291614,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":291634,"endOffset":291830,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":291841,"endOffset":292006,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":292062,"endOffset":292120,"count":1}],"isBlockCoverage":true},{"functionName":"get$isEmpty","ranges":[{"startOffset":292139,"endOffset":292203,"count":1}],"isBlockCoverage":true},{"functionName":"get$keys","ranges":[{"startOffset":292219,"endOffset":292325,"count":0}],"isBlockCoverage":false},{"functionName":"get$values","ranges":[{"startOffset":292343,"endOffset":292585,"count":0}],"isBlockCoverage":false},{"functionName":"containsKey$1","ranges":[{"startOffset":292606,"endOffset":293097,"count":1},{"startOffset":292682,"endOffset":292834,"count":0},{"startOffset":292963,"endOffset":292976,"count":0},{"startOffset":293038,"endOffset":293091,"count":0}],"isBlockCoverage":true},{"functionName":"internalContainsKey$1","ranges":[{"startOffset":293126,"endOffset":293341,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":293355,"endOffset":293981,"count":1},{"startOffset":293518,"endOffset":293525,"count":0},{"startOffset":293603,"endOffset":293609,"count":0},{"startOffset":293790,"endOffset":293797,"count":0},{"startOffset":293872,"endOffset":293878,"count":0},{"startOffset":293930,"endOffset":293975,"count":0}],"isBlockCoverage":true},{"functionName":"internalGet$1","ranges":[{"startOffset":294002,"endOffset":294339,"count":0}],"isBlockCoverage":false},{"functionName":"$indexSet","ranges":[{"startOffset":294356,"endOffset":295711,"count":1},{"startOffset":295102,"endOffset":295705,"count":0}],"isBlockCoverage":true},{"functionName":"putIfAbsent$2","ranges":[{"startOffset":295732,"endOffset":296105,"count":1},{"startOffset":296009,"endOffset":296104,"count":0}],"isBlockCoverage":true},{"functionName":"remove$1","ranges":[{"startOffset":296121,"endOffset":296430,"count":0}],"isBlockCoverage":false},{"functionName":"internalRemove$1","ranges":[{"startOffset":296454,"endOffset":296861,"count":0}],"isBlockCoverage":false},{"functionName":"clear$0","ranges":[{"startOffset":296876,"endOffset":297150,"count":0}],"isBlockCoverage":false},{"functionName":"forEach$1","ranges":[{"startOffset":297167,"endOffset":297681,"count":1},{"startOffset":297580,"endOffset":297640,"count":0}],"isBlockCoverage":true},{"functionName":"_addHashTableEntry$3","ranges":[{"startOffset":297709,"endOffset":298113,"count":1},{"startOffset":298057,"endOffset":298107,"count":0}],"isBlockCoverage":true},{"functionName":"_removeHashTableEntry$2","ranges":[{"startOffset":298144,"endOffset":298428,"count":0}],"isBlockCoverage":false},{"functionName":"_modified$0","ranges":[{"startOffset":298447,"endOffset":298529,"count":1}],"isBlockCoverage":true},{"functionName":"_newLinkedCell$2","ranges":[{"startOffset":298553,"endOffset":299085,"count":1}],"isBlockCoverage":true},{"functionName":"_unlinkCell$1","ranges":[{"startOffset":299106,"endOffset":299471,"count":0}],"isBlockCoverage":false},{"functionName":"internalFindBucketIndex$2","ranges":[{"startOffset":299504,"endOffset":299755,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":299773,"endOffset":299834,"count":0}],"isBlockCoverage":false},{"functionName":"_getTableCell$2","ranges":[{"startOffset":299857,"endOffset":299910,"count":1}],"isBlockCoverage":true},{"functionName":"_getTableBucket$2","ranges":[{"startOffset":299935,"endOffset":299988,"count":0}],"isBlockCoverage":false},{"functionName":"_setTableEntry$3","ranges":[{"startOffset":300012,"endOffset":300073,"count":1}],"isBlockCoverage":true},{"functionName":"_deleteTableEntry$2","ranges":[{"startOffset":300100,"endOffset":300153,"count":1}],"isBlockCoverage":true},{"functionName":"_containsTableEntry$2","ranges":[{"startOffset":300182,"endOffset":300265,"count":1}],"isBlockCoverage":true},{"functionName":"_newHashTable$0","ranges":[{"startOffset":300288,"endOffset":300495,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":300587,"endOffset":300732,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":300750,"endOffset":300898,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":301001,"endOffset":301076,"count":0}],"isBlockCoverage":false},{"functionName":"get$isEmpty","ranges":[{"startOffset":301095,"endOffset":301176,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":301196,"endOffset":301388,"count":0}],"isBlockCoverage":false},{"functionName":"get$current","ranges":[{"startOffset":301454,"endOffset":301512,"count":0}],"isBlockCoverage":false},{"functionName":"moveNext$0","ranges":[{"startOffset":301530,"endOffset":302000,"count":0}],"isBlockCoverage":false},{"functionName":"set$__js_helper$_current","ranges":[{"startOffset":302032,"endOffset":302167,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":302241,"endOffset":302289,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":302363,"endOffset":302428,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":302503,"endOffset":302583,"count":1}],"isBlockCoverage":true},{"functionName":"toString$0","ranges":[{"startOffset":302658,"endOffset":302722,"count":0}],"isBlockCoverage":false},{"functionName":"get$_nativeGlobalVersion","ranges":[{"startOffset":302754,"endOffset":303029,"count":0}],"isBlockCoverage":false},{"functionName":"get$_nativeAnchoredVersion","ranges":[{"startOffset":303063,"endOffset":303350,"count":0}],"isBlockCoverage":false},{"functionName":"firstMatch$1","ranges":[{"startOffset":303370,"endOffset":303626,"count":0}],"isBlockCoverage":false},{"functionName":"allMatches$2","ranges":[{"startOffset":303646,"endOffset":303862,"count":0}],"isBlockCoverage":false},{"functionName":"allMatches$1","ranges":[{"startOffset":303882,"endOffset":303971,"count":0}],"isBlockCoverage":false},{"functionName":"_execGlobal$2","ranges":[{"startOffset":303992,"endOffset":304252,"count":0}],"isBlockCoverage":false},{"functionName":"_execAnchored$2","ranges":[{"startOffset":304275,"endOffset":304648,"count":0}],"isBlockCoverage":false},{"functionName":"matchAsPrefix$2","ranges":[{"startOffset":304671,"endOffset":304954,"count":0}],"isBlockCoverage":false},{"functionName":"get$start","ranges":[{"startOffset":305051,"endOffset":305102,"count":0}],"isBlockCoverage":false},{"functionName":"get$end","ranges":[{"startOffset":305117,"endOffset":305201,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":305215,"endOffset":305397,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":305476,"endOffset":305584,"count":0}],"isBlockCoverage":false},{"functionName":"$asIterable","ranges":[{"startOffset":305603,"endOffset":305645,"count":0}],"isBlockCoverage":false},{"functionName":"get$current","ranges":[{"startOffset":305706,"endOffset":305764,"count":0}],"isBlockCoverage":false},{"functionName":"moveNext$0","ranges":[{"startOffset":305782,"endOffset":306369,"count":0}],"isBlockCoverage":false},{"functionName":"$asIterator","ranges":[{"startOffset":306408,"endOffset":306450,"count":0}],"isBlockCoverage":false},{"functionName":"get$end","ranges":[{"startOffset":306499,"endOffset":306643,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":306657,"endOffset":306806,"count":0}],"isBlockCoverage":false},{"functionName":"get$start","ranges":[{"startOffset":306840,"endOffset":306891,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":306959,"endOffset":307077,"count":0}],"isBlockCoverage":false},{"functionName":"$asIterable","ranges":[{"startOffset":307096,"endOffset":307138,"count":0}],"isBlockCoverage":false},{"functionName":"moveNext$0","ranges":[{"startOffset":307204,"endOffset":307851,"count":0}],"isBlockCoverage":false},{"functionName":"get$current","ranges":[{"startOffset":307870,"endOffset":307928,"count":0}],"isBlockCoverage":false},{"functionName":"$asIterator","ranges":[{"startOffset":307967,"endOffset":308009,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":308182,"endOffset":308238,"count":0}],"isBlockCoverage":false},{"functionName":"$asJavaScriptIndexingBehavior","ranges":[{"startOffset":308313,"endOffset":308331,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":308392,"endOffset":308544,"count":0}],"isBlockCoverage":false},{"functionName":"$indexSet","ranges":[{"startOffset":308561,"endOffset":308753,"count":0}],"isBlockCoverage":false},{"functionName":"$asEfficientLengthIterable","ranges":[{"startOffset":308822,"endOffset":308865,"count":0}],"isBlockCoverage":false},{"functionName":"$asFixedLengthListMixin","ranges":[{"startOffset":308896,"endOffset":308939,"count":0}],"isBlockCoverage":false},{"functionName":"$asListMixin","ranges":[{"startOffset":308959,"endOffset":309002,"count":0}],"isBlockCoverage":false},{"functionName":"$asIterable","ranges":[{"startOffset":309041,"endOffset":309084,"count":0}],"isBlockCoverage":false},{"functionName":"$asList","ranges":[{"startOffset":309115,"endOffset":309158,"count":0}],"isBlockCoverage":false},{"functionName":"$indexSet","ranges":[{"startOffset":309219,"endOffset":309408,"count":1}],"isBlockCoverage":true},{"functionName":"$asEfficientLengthIterable","ranges":[{"startOffset":309477,"endOffset":309517,"count":0}],"isBlockCoverage":false},{"functionName":"$asFixedLengthListMixin","ranges":[{"startOffset":309548,"endOffset":309588,"count":0}],"isBlockCoverage":false},{"functionName":"$asListMixin","ranges":[{"startOffset":309608,"endOffset":309648,"count":1}],"isBlockCoverage":true},{"functionName":"$asIterable","ranges":[{"startOffset":309687,"endOffset":309727,"count":0}],"isBlockCoverage":false},{"functionName":"$asList","ranges":[{"startOffset":309758,"endOffset":309798,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":309850,"endOffset":310002,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":310054,"endOffset":310206,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":310257,"endOffset":310409,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":310462,"endOffset":310614,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":310667,"endOffset":310819,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":310882,"endOffset":310938,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":310952,"endOffset":311104,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":311160,"endOffset":311216,"count":1}],"isBlockCoverage":true},{"functionName":"$index","ranges":[{"startOffset":311230,"endOffset":311382,"count":0}],"isBlockCoverage":false},{"functionName":"sublist$2","ranges":[{"startOffset":311399,"endOffset":311541,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":312009,"endOffset":312148,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":312250,"endOffset":312486,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":312598,"endOffset":312646,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":312812,"endOffset":312860,"count":0}],"isBlockCoverage":false},{"functionName":"_TimerImpl$2","ranges":[{"startOffset":312981,"endOffset":313267,"count":0}],"isBlockCoverage":false},{"functionName":"_TimerImpl$periodic$2","ranges":[{"startOffset":313296,"endOffset":313599,"count":1},{"startOffset":313511,"endOffset":313593,"count":0}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":313680,"endOffset":313756,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":313888,"endOffset":314241,"count":0}],"isBlockCoverage":false},{"functionName":"complete$1","ranges":[{"startOffset":314370,"endOffset":314852,"count":1},{"startOffset":314559,"endOffset":314846,"count":0}],"isBlockCoverage":true},{"functionName":"completeError$2","ranges":[{"startOffset":314875,"endOffset":315072,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":315167,"endOffset":315240,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":315387,"endOffset":315467,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":315594,"endOffset":315668,"count":1}],"isBlockCoverage":true},{"functionName":"call$2","ranges":[{"startOffset":315747,"endOffset":315907,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":316044,"endOffset":316137,"count":1}],"isBlockCoverage":true},{"functionName":"completeError$2","ranges":[{"startOffset":316289,"endOffset":316893,"count":0}],"isBlockCoverage":false},{"functionName":"completeError$1","ranges":[{"startOffset":316916,"endOffset":316987,"count":0}],"isBlockCoverage":false},{"functionName":"complete$1","ranges":[{"startOffset":317064,"endOffset":317349,"count":1},{"startOffset":317244,"endOffset":317309,"count":0}],"isBlockCoverage":true},{"functionName":"complete$0","ranges":[{"startOffset":317367,"endOffset":317441,"count":1}],"isBlockCoverage":true},{"functionName":"_completeError$2","ranges":[{"startOffset":317465,"endOffset":317560,"count":0}],"isBlockCoverage":false},{"functionName":"complete$1","ranges":[{"startOffset":317615,"endOffset":317895,"count":1},{"startOffset":317795,"endOffset":317860,"count":0}],"isBlockCoverage":true},{"functionName":"complete$0","ranges":[{"startOffset":317913,"endOffset":317987,"count":0}],"isBlockCoverage":false},{"functionName":"_completeError$2","ranges":[{"startOffset":318011,"endOffset":318101,"count":0}],"isBlockCoverage":false},{"functionName":"matchesErrorTest$1","ranges":[{"startOffset":318165,"endOffset":318401,"count":0}],"isBlockCoverage":false},{"functionName":"handleError$1","ranges":[{"startOffset":318422,"endOffset":319026,"count":0}],"isBlockCoverage":false},{"functionName":"then$1$2$onError","ranges":[{"startOffset":319080,"endOffset":319598,"count":1},{"startOffset":319465,"endOffset":319521,"count":0}],"isBlockCoverage":true},{"functionName":"then$1$1","ranges":[{"startOffset":319614,"endOffset":319686,"count":1}],"isBlockCoverage":true},{"functionName":"_thenNoZoneRegistration$1$2","ranges":[{"startOffset":319721,"endOffset":320105,"count":1}],"isBlockCoverage":true},{"functionName":"whenComplete$1","ranges":[{"startOffset":320127,"endOffset":320534,"count":0}],"isBlockCoverage":false},{"functionName":"_addListener$1","ranges":[{"startOffset":320556,"endOffset":321250,"count":1},{"startOffset":320829,"endOffset":321144,"count":0}],"isBlockCoverage":true},{"functionName":"_prependListeners$1","ranges":[{"startOffset":321277,"endOffset":322404,"count":0}],"isBlockCoverage":false},{"functionName":"_removeListeners$0","ranges":[{"startOffset":322430,"endOffset":322625,"count":1}],"isBlockCoverage":true},{"functionName":"_reverseListeners$1","ranges":[{"startOffset":322652,"endOffset":322909,"count":1}],"isBlockCoverage":true},{"functionName":"_complete$1","ranges":[{"startOffset":322928,"endOffset":323583,"count":1},{"startOffset":323168,"endOffset":323336,"count":0}],"isBlockCoverage":true},{"functionName":"_completeError$2","ranges":[{"startOffset":323607,"endOffset":323915,"count":0}],"isBlockCoverage":false},{"functionName":"_completeError$1","ranges":[{"startOffset":323939,"endOffset":324011,"count":0}],"isBlockCoverage":false},{"functionName":"_asyncComplete$1","ranges":[{"startOffset":324035,"endOffset":324387,"count":1},{"startOffset":324208,"endOffset":324269,"count":0}],"isBlockCoverage":true},{"functionName":"_chainFuture$1","ranges":[{"startOffset":324409,"endOffset":324868,"count":0}],"isBlockCoverage":false},{"functionName":"_asyncCompleteError$2","ranges":[{"startOffset":324897,"endOffset":325120,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":325203,"endOffset":325287,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":325425,"endOffset":325517,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":325657,"endOffset":325758,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":325850,"endOffset":325999,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":326013,"endOffset":326075,"count":0}],"isBlockCoverage":false},{"functionName":"$defaultValues","ranges":[{"startOffset":326120,"endOffset":326159,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":326252,"endOffset":326322,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":326457,"endOffset":326765,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":326898,"endOffset":326974,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":327114,"endOffset":327196,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":327357,"endOffset":328955,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":329075,"endOffset":329128,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":329234,"endOffset":329953,"count":1},{"startOffset":329710,"endOffset":329947,"count":0}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":330050,"endOffset":330966,"count":0}],"isBlockCoverage":false},{"functionName":"pipe$1","ranges":[{"startOffset":331068,"endOffset":331333,"count":1}],"isBlockCoverage":true},{"functionName":"get$length","ranges":[{"startOffset":331351,"endOffset":331673,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":331729,"endOffset":331793,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":331871,"endOffset":332007,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":332025,"endOffset":332139,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":332198,"endOffset":332266,"count":0}],"isBlockCoverage":false},{"functionName":"get$_pendingEvents","ranges":[{"startOffset":332504,"endOffset":332877,"count":1},{"startOffset":332650,"endOffset":332876,"count":0}],"isBlockCoverage":true},{"functionName":"_ensurePendingEvents$0","ranges":[{"startOffset":332907,"endOffset":333600,"count":0}],"isBlockCoverage":false},{"functionName":"get$_subscription","ranges":[{"startOffset":333625,"endOffset":334046,"count":1},{"startOffset":333673,"endOffset":333925,"count":0}],"isBlockCoverage":true},{"functionName":"_badEventState$0","ranges":[{"startOffset":334070,"endOffset":334263,"count":0}],"isBlockCoverage":false},{"functionName":"_ensureDoneFuture$0","ranges":[{"startOffset":334290,"endOffset":334533,"count":0}],"isBlockCoverage":false},{"functionName":"add$1","ranges":[{"startOffset":334546,"endOffset":334760,"count":1},{"startOffset":334681,"endOffset":334728,"count":0}],"isBlockCoverage":true},{"functionName":"addError$2","ranges":[{"startOffset":334778,"endOffset":335358,"count":0}],"isBlockCoverage":false},{"functionName":"addError$1","ranges":[{"startOffset":335376,"endOffset":335442,"count":0}],"isBlockCoverage":false},{"functionName":"close$0","ranges":[{"startOffset":335457,"endOffset":335879,"count":0}],"isBlockCoverage":false},{"functionName":"_add$1","ranges":[{"startOffset":335893,"endOffset":336207,"count":1},{"startOffset":336085,"endOffset":336201,"count":0}],"isBlockCoverage":true},{"functionName":"_async$_addError$2","ranges":[{"startOffset":336233,"endOffset":336487,"count":0}],"isBlockCoverage":false},{"functionName":"_subscribe$4","ranges":[{"startOffset":336507,"endOffset":337709,"count":1},{"startOffset":336834,"endOffset":336911,"count":0},{"startOffset":336965,"endOffset":336968,"count":0},{"startOffset":337264,"endOffset":337491,"count":0}],"isBlockCoverage":true},{"functionName":"_recordCancel$1","ranges":[{"startOffset":337732,"endOffset":338892,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":339105,"endOffset":339165,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":339261,"endOffset":339394,"count":0}],"isBlockCoverage":false},{"functionName":"_sendData$1","ranges":[{"startOffset":339533,"endOffset":339677,"count":1}],"isBlockCoverage":true},{"functionName":"_sendError$2","ranges":[{"startOffset":339697,"endOffset":339802,"count":0}],"isBlockCoverage":false},{"functionName":"_sendDone$0","ranges":[{"startOffset":339821,"endOffset":339882,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":339984,"endOffset":340083,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":340094,"endOffset":340307,"count":0}],"isBlockCoverage":false},{"functionName":"_onCancel$0","ranges":[{"startOffset":340372,"endOffset":340443,"count":0}],"isBlockCoverage":false},{"functionName":"_onPause$0","ranges":[{"startOffset":340461,"endOffset":340868,"count":0}],"isBlockCoverage":false},{"functionName":"_onResume$0","ranges":[{"startOffset":340887,"endOffset":341296,"count":0}],"isBlockCoverage":false},{"functionName":"add$1","ranges":[{"startOffset":341350,"endOffset":341482,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":341597,"endOffset":341672,"count":0}],"isBlockCoverage":false},{"functionName":"_BufferingStreamSubscription$4","ranges":[{"startOffset":341780,"endOffset":343046,"count":1},{"startOffset":342069,"endOffset":342106,"count":0},{"startOffset":342501,"endOffset":342838,"count":0}],"isBlockCoverage":true},{"functionName":"_setPendingEvents$1","ranges":[{"startOffset":343073,"endOffset":343490,"count":1},{"startOffset":343296,"endOffset":343484,"count":0}],"isBlockCoverage":true},{"functionName":"cancel$0","ranges":[{"startOffset":343506,"endOffset":343740,"count":0}],"isBlockCoverage":false},{"functionName":"_cancel$0","ranges":[{"startOffset":343757,"endOffset":344079,"count":0}],"isBlockCoverage":false},{"functionName":"_add$1","ranges":[{"startOffset":344093,"endOffset":344445,"count":1},{"startOffset":344310,"endOffset":344317,"count":0},{"startOffset":344368,"endOffset":344439,"count":0}],"isBlockCoverage":true},{"functionName":"_async$_addError$2","ranges":[{"startOffset":344471,"endOffset":344720,"count":0}],"isBlockCoverage":false},{"functionName":"_close$0","ranges":[{"startOffset":344736,"endOffset":344979,"count":0}],"isBlockCoverage":false},{"functionName":"_onPause$0","ranges":[{"startOffset":344997,"endOffset":345015,"count":0}],"isBlockCoverage":false},{"functionName":"_onResume$0","ranges":[{"startOffset":345034,"endOffset":345052,"count":0}],"isBlockCoverage":false},{"functionName":"_onCancel$0","ranges":[{"startOffset":345071,"endOffset":345103,"count":0}],"isBlockCoverage":false},{"functionName":"_addPending$1","ranges":[{"startOffset":345124,"endOffset":345687,"count":0}],"isBlockCoverage":false},{"functionName":"_sendData$1","ranges":[{"startOffset":345706,"endOffset":346096,"count":1}],"isBlockCoverage":true},{"functionName":"_sendError$2","ranges":[{"startOffset":346116,"endOffset":346631,"count":0}],"isBlockCoverage":false},{"functionName":"_sendDone$0","ranges":[{"startOffset":346650,"endOffset":346982,"count":0}],"isBlockCoverage":false},{"functionName":"_guardCallback$1","ranges":[{"startOffset":347006,"endOffset":347285,"count":1}],"isBlockCoverage":true},{"functionName":"_checkState$1","ranges":[{"startOffset":347306,"endOffset":348403,"count":1},{"startOffset":347416,"endOffset":347457,"count":0},{"startOffset":347459,"endOffset":347850,"count":0},{"startOffset":347932,"endOffset":347996,"count":0},{"startOffset":348099,"endOffset":348318,"count":0},{"startOffset":348345,"endOffset":348356,"count":0},{"startOffset":348366,"endOffset":348397,"count":0}],"isBlockCoverage":true},{"functionName":"set$_async$_onData","ranges":[{"startOffset":348429,"endOffset":348607,"count":1}],"isBlockCoverage":true},{"functionName":"set$_onDone","ranges":[{"startOffset":348626,"endOffset":348722,"count":1}],"isBlockCoverage":true},{"functionName":"set$_pending","ranges":[{"startOffset":348742,"endOffset":348928,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":349070,"endOffset":349703,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":349855,"endOffset":350105,"count":0}],"isBlockCoverage":false},{"functionName":"listen$4$cancelOnError$onDone$onError","ranges":[{"startOffset":350252,"endOffset":350638,"count":1}],"isBlockCoverage":true},{"functionName":"listen$1","ranges":[{"startOffset":350654,"endOffset":350761,"count":1}],"isBlockCoverage":true},{"functionName":"listen$3$onDone$onError","ranges":[{"startOffset":350792,"endOffset":350921,"count":1}],"isBlockCoverage":true},{"functionName":"listen$2$onDone","ranges":[{"startOffset":350944,"endOffset":351061,"count":1}],"isBlockCoverage":true},{"functionName":"set$next","ranges":[{"startOffset":351113,"endOffset":351203,"count":0}],"isBlockCoverage":false},{"functionName":"get$next","ranges":[{"startOffset":351219,"endOffset":351261,"count":0}],"isBlockCoverage":false},{"functionName":"perform$1","ranges":[{"startOffset":351313,"endOffset":351448,"count":0}],"isBlockCoverage":false},{"functionName":"perform$1","ranges":[{"startOffset":351501,"endOffset":351585,"count":0}],"isBlockCoverage":false},{"functionName":"$as_DelayedEvent","ranges":[{"startOffset":351609,"endOffset":351627,"count":0}],"isBlockCoverage":false},{"functionName":"perform$1","ranges":[{"startOffset":351679,"endOffset":351735,"count":0}],"isBlockCoverage":false},{"functionName":"get$next","ranges":[{"startOffset":351751,"endOffset":351783,"count":0}],"isBlockCoverage":false},{"functionName":"set$next","ranges":[{"startOffset":351799,"endOffset":351889,"count":0}],"isBlockCoverage":false},{"functionName":"$as_DelayedEvent","ranges":[{"startOffset":351938,"endOffset":351956,"count":0}],"isBlockCoverage":false},{"functionName":"schedule$1","ranges":[{"startOffset":352011,"endOffset":352371,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":352439,"endOffset":352917,"count":0}],"isBlockCoverage":false},{"functionName":"add$1","ranges":[{"startOffset":353038,"endOffset":353300,"count":0}],"isBlockCoverage":false},{"functionName":"_schedule$0","ranges":[{"startOffset":353365,"endOffset":353539,"count":0}],"isBlockCoverage":false},{"functionName":"cancel$0","ranges":[{"startOffset":353555,"endOffset":353615,"count":0}],"isBlockCoverage":false},{"functionName":"_sendDone$0","ranges":[{"startOffset":353634,"endOffset":353880,"count":0}],"isBlockCoverage":false},{"functionName":"listen$4$cancelOnError$onDone$onError","ranges":[{"startOffset":354026,"endOffset":354367,"count":0}],"isBlockCoverage":false},{"functionName":"listen$1","ranges":[{"startOffset":354383,"endOffset":354490,"count":0}],"isBlockCoverage":false},{"functionName":"listen$3$onDone$onError","ranges":[{"startOffset":354521,"endOffset":354650,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":354727,"endOffset":354776,"count":0}],"isBlockCoverage":false},{"functionName":"handleUncaughtError$3","ranges":[{"startOffset":355050,"endOffset":355408,"count":0}],"isBlockCoverage":false},{"functionName":"get$_delegate","ranges":[{"startOffset":355523,"endOffset":355705,"count":0}],"isBlockCoverage":false},{"functionName":"get$errorZone","ranges":[{"startOffset":355726,"endOffset":355789,"count":1}],"isBlockCoverage":true},{"functionName":"runGuarded$1","ranges":[{"startOffset":355809,"endOffset":356114,"count":1},{"startOffset":355949,"endOffset":356108,"count":0}],"isBlockCoverage":true},{"functionName":"runUnaryGuarded$1$2","ranges":[{"startOffset":356141,"endOffset":356526,"count":1},{"startOffset":356361,"endOffset":356520,"count":0}],"isBlockCoverage":true},{"functionName":"runBinaryGuarded$2$3","ranges":[{"startOffset":356554,"endOffset":357013,"count":0}],"isBlockCoverage":false},{"functionName":"bindCallback$1$1","ranges":[{"startOffset":357037,"endOffset":357198,"count":0}],"isBlockCoverage":false},{"functionName":"bindUnaryCallback$2$1","ranges":[{"startOffset":357227,"endOffset":357422,"count":1}],"isBlockCoverage":true},{"functionName":"bindCallbackGuarded$1","ranges":[{"startOffset":357451,"endOffset":357611,"count":1}],"isBlockCoverage":true},{"functionName":"bindUnaryCallbackGuarded$1$1","ranges":[{"startOffset":357647,"endOffset":357841,"count":1}],"isBlockCoverage":true},{"functionName":"$index","ranges":[{"startOffset":357855,"endOffset":358169,"count":0}],"isBlockCoverage":false},{"functionName":"handleUncaughtError$2","ranges":[{"startOffset":358198,"endOffset":358557,"count":0}],"isBlockCoverage":false},{"functionName":"fork$2$specification$zoneValues","ranges":[{"startOffset":358596,"endOffset":358897,"count":0}],"isBlockCoverage":false},{"functionName":"run$1$1","ranges":[{"startOffset":358912,"endOffset":359343,"count":1}],"isBlockCoverage":true},{"functionName":"runUnary$2$2","ranges":[{"startOffset":359363,"endOffset":359898,"count":1}],"isBlockCoverage":true},{"functionName":"runBinary$3$3","ranges":[{"startOffset":359919,"endOffset":360544,"count":0}],"isBlockCoverage":false},{"functionName":"registerCallback$1$1","ranges":[{"startOffset":360572,"endOffset":361053,"count":1}],"isBlockCoverage":true},{"functionName":"registerUnaryCallback$2$1","ranges":[{"startOffset":361086,"endOffset":361624,"count":1}],"isBlockCoverage":true},{"functionName":"registerBinaryCallback$3$1","ranges":[{"startOffset":361658,"endOffset":362225,"count":1}],"isBlockCoverage":true},{"functionName":"errorCallback$2","ranges":[{"startOffset":362248,"endOffset":362670,"count":0}],"isBlockCoverage":false},{"functionName":"scheduleMicrotask$1","ranges":[{"startOffset":362697,"endOffset":363013,"count":1}],"isBlockCoverage":true},{"functionName":"createPeriodicTimer$2","ranges":[{"startOffset":363042,"endOffset":363397,"count":1}],"isBlockCoverage":true},{"functionName":"print$1","ranges":[{"startOffset":363412,"endOffset":363675,"count":0}],"isBlockCoverage":false},{"functionName":"set$_run","ranges":[{"startOffset":363691,"endOffset":363808,"count":1}],"isBlockCoverage":true},{"functionName":"set$_runUnary","ranges":[{"startOffset":363829,"endOffset":363961,"count":1}],"isBlockCoverage":true},{"functionName":"set$_runBinary","ranges":[{"startOffset":363983,"endOffset":364118,"count":1}],"isBlockCoverage":true},{"functionName":"set$_registerCallback","ranges":[{"startOffset":364147,"endOffset":364303,"count":1}],"isBlockCoverage":true},{"functionName":"set$_registerUnaryCallback","ranges":[{"startOffset":364337,"endOffset":364508,"count":1}],"isBlockCoverage":true},{"functionName":"set$_registerBinaryCallback","ranges":[{"startOffset":364543,"endOffset":364717,"count":1}],"isBlockCoverage":true},{"functionName":"set$_errorCallback","ranges":[{"startOffset":364743,"endOffset":364972,"count":1}],"isBlockCoverage":true},{"functionName":"set$_scheduleMicrotask","ranges":[{"startOffset":365002,"endOffset":365229,"count":1}],"isBlockCoverage":true},{"functionName":"set$_createTimer","ranges":[{"startOffset":365253,"endOffset":365479,"count":1}],"isBlockCoverage":true},{"functionName":"set$_createPeriodicTimer","ranges":[{"startOffset":365511,"endOffset":365778,"count":1}],"isBlockCoverage":true},{"functionName":"set$_print","ranges":[{"startOffset":365796,"endOffset":365977,"count":1}],"isBlockCoverage":true},{"functionName":"set$_fork","ranges":[{"startOffset":365994,"endOffset":366199,"count":1}],"isBlockCoverage":true},{"functionName":"set$_handleUncaughtError","ranges":[{"startOffset":366231,"endOffset":366468,"count":1}],"isBlockCoverage":true},{"functionName":"get$_run","ranges":[{"startOffset":366484,"endOffset":366526,"count":0}],"isBlockCoverage":false},{"functionName":"get$_runUnary","ranges":[{"startOffset":366547,"endOffset":366594,"count":0}],"isBlockCoverage":false},{"functionName":"get$_runBinary","ranges":[{"startOffset":366616,"endOffset":366664,"count":0}],"isBlockCoverage":false},{"functionName":"get$_registerCallback","ranges":[{"startOffset":366693,"endOffset":366748,"count":0}],"isBlockCoverage":false},{"functionName":"get$_registerUnaryCallback","ranges":[{"startOffset":366782,"endOffset":366842,"count":0}],"isBlockCoverage":false},{"functionName":"get$_registerBinaryCallback","ranges":[{"startOffset":366877,"endOffset":366938,"count":0}],"isBlockCoverage":false},{"functionName":"get$_errorCallback","ranges":[{"startOffset":366964,"endOffset":367016,"count":0}],"isBlockCoverage":false},{"functionName":"get$_scheduleMicrotask","ranges":[{"startOffset":367046,"endOffset":367102,"count":0}],"isBlockCoverage":false},{"functionName":"get$_createTimer","ranges":[{"startOffset":367126,"endOffset":367176,"count":0}],"isBlockCoverage":false},{"functionName":"get$_createPeriodicTimer","ranges":[{"startOffset":367208,"endOffset":367266,"count":0}],"isBlockCoverage":false},{"functionName":"get$_print","ranges":[{"startOffset":367284,"endOffset":367328,"count":0}],"isBlockCoverage":false},{"functionName":"get$_fork","ranges":[{"startOffset":367345,"endOffset":367388,"count":0}],"isBlockCoverage":false},{"functionName":"get$_handleUncaughtError","ranges":[{"startOffset":367420,"endOffset":367478,"count":0}],"isBlockCoverage":false},{"functionName":"get$parent","ranges":[{"startOffset":367496,"endOffset":367548,"count":0}],"isBlockCoverage":false},{"functionName":"get$_async$_map","ranges":[{"startOffset":367571,"endOffset":367620,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":367689,"endOffset":367765,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":367783,"endOffset":367838,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":367912,"endOffset":368062,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":368080,"endOffset":368151,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":368227,"endOffset":368300,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":368449,"endOffset":368598,"count":1}],"isBlockCoverage":true},{"functionName":"$signature","ranges":[{"startOffset":368616,"endOffset":368683,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":368752,"endOffset":369158,"count":0}],"isBlockCoverage":false},{"functionName":"get$_run","ranges":[{"startOffset":369225,"endOffset":369292,"count":1}],"isBlockCoverage":true},{"functionName":"get$_runUnary","ranges":[{"startOffset":369313,"endOffset":369385,"count":1}],"isBlockCoverage":true},{"functionName":"get$_runBinary","ranges":[{"startOffset":369407,"endOffset":369480,"count":1}],"isBlockCoverage":true},{"functionName":"get$_registerCallback","ranges":[{"startOffset":369509,"endOffset":369589,"count":1}],"isBlockCoverage":true},{"functionName":"get$_registerUnaryCallback","ranges":[{"startOffset":369623,"endOffset":369675,"count":1}],"isBlockCoverage":true},{"functionName":"get$_registerBinaryCallback","ranges":[{"startOffset":369710,"endOffset":369762,"count":1}],"isBlockCoverage":true},{"functionName":"get$_errorCallback","ranges":[{"startOffset":369788,"endOffset":369865,"count":1}],"isBlockCoverage":true},{"functionName":"get$_scheduleMicrotask","ranges":[{"startOffset":369895,"endOffset":369976,"count":1}],"isBlockCoverage":true},{"functionName":"get$_createTimer","ranges":[{"startOffset":370000,"endOffset":370075,"count":1}],"isBlockCoverage":true},{"functionName":"get$_createPeriodicTimer","ranges":[{"startOffset":370107,"endOffset":370159,"count":1}],"isBlockCoverage":true},{"functionName":"get$_print","ranges":[{"startOffset":370177,"endOffset":370246,"count":1}],"isBlockCoverage":true},{"functionName":"get$_fork","ranges":[{"startOffset":370263,"endOffset":370331,"count":1}],"isBlockCoverage":true},{"functionName":"get$_handleUncaughtError","ranges":[{"startOffset":370363,"endOffset":370415,"count":0}],"isBlockCoverage":false},{"functionName":"get$parent","ranges":[{"startOffset":370433,"endOffset":370466,"count":1}],"isBlockCoverage":true},{"functionName":"get$_async$_map","ranges":[{"startOffset":370489,"endOffset":370549,"count":1}],"isBlockCoverage":true},{"functionName":"get$_delegate","ranges":[{"startOffset":370570,"endOffset":370764,"count":0}],"isBlockCoverage":false},{"functionName":"get$errorZone","ranges":[{"startOffset":370785,"endOffset":370822,"count":1}],"isBlockCoverage":true},{"functionName":"runGuarded$1","ranges":[{"startOffset":370842,"endOffset":371321,"count":0}],"isBlockCoverage":false},{"functionName":"runUnaryGuarded$1$2","ranges":[{"startOffset":371348,"endOffset":371910,"count":0}],"isBlockCoverage":false},{"functionName":"runBinaryGuarded$2$3","ranges":[{"startOffset":371938,"endOffset":372581,"count":0}],"isBlockCoverage":false},{"functionName":"bindCallback$1$1","ranges":[{"startOffset":372605,"endOffset":372733,"count":0}],"isBlockCoverage":false},{"functionName":"bindCallbackGuarded$1","ranges":[{"startOffset":372762,"endOffset":372889,"count":0}],"isBlockCoverage":false},{"functionName":"bindUnaryCallbackGuarded$1$1","ranges":[{"startOffset":372925,"endOffset":373077,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":373091,"endOffset":373129,"count":0}],"isBlockCoverage":false},{"functionName":"handleUncaughtError$2","ranges":[{"startOffset":373158,"endOffset":373305,"count":0}],"isBlockCoverage":false},{"functionName":"fork$2$specification$zoneValues","ranges":[{"startOffset":373344,"endOffset":373458,"count":1}],"isBlockCoverage":true},{"functionName":"run$1$1","ranges":[{"startOffset":373473,"endOffset":373668,"count":0}],"isBlockCoverage":false},{"functionName":"runUnary$2$2","ranges":[{"startOffset":373688,"endOffset":373966,"count":0}],"isBlockCoverage":false},{"functionName":"runBinary$3$3","ranges":[{"startOffset":373987,"endOffset":374346,"count":0}],"isBlockCoverage":false},{"functionName":"registerCallback$1$1","ranges":[{"startOffset":374374,"endOffset":374454,"count":0}],"isBlockCoverage":false},{"functionName":"registerUnaryCallback$2$1","ranges":[{"startOffset":374487,"endOffset":374583,"count":0}],"isBlockCoverage":false},{"functionName":"registerBinaryCallback$3$1","ranges":[{"startOffset":374617,"endOffset":374721,"count":0}],"isBlockCoverage":false},{"functionName":"errorCallback$2","ranges":[{"startOffset":374744,"endOffset":374793,"count":0}],"isBlockCoverage":false},{"functionName":"scheduleMicrotask$1","ranges":[{"startOffset":374820,"endOffset":374933,"count":0}],"isBlockCoverage":false},{"functionName":"createPeriodicTimer$2","ranges":[{"startOffset":374962,"endOffset":375105,"count":0}],"isBlockCoverage":false},{"functionName":"print$1","ranges":[{"startOffset":375120,"endOffset":375172,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":375239,"endOffset":375306,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":375324,"endOffset":375379,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":375453,"endOffset":375517,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":375664,"endOffset":375804,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":375822,"endOffset":375889,"count":0}],"isBlockCoverage":false},{"functionName":"call$5","ranges":[{"startOffset":375942,"endOffset":376743,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":376812,"endOffset":376870,"count":0}],"isBlockCoverage":false},{"functionName":"get$isEmpty","ranges":[{"startOffset":376889,"endOffset":376953,"count":0}],"isBlockCoverage":false},{"functionName":"get$keys","ranges":[{"startOffset":376969,"endOffset":377070,"count":0}],"isBlockCoverage":false},{"functionName":"containsKey$1","ranges":[{"startOffset":377091,"endOffset":377529,"count":0}],"isBlockCoverage":false},{"functionName":"_containsKey$1","ranges":[{"startOffset":377551,"endOffset":377737,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":377751,"endOffset":378258,"count":0}],"isBlockCoverage":false},{"functionName":"_get$1","ranges":[{"startOffset":378272,"endOffset":378549,"count":0}],"isBlockCoverage":false},{"functionName":"$indexSet","ranges":[{"startOffset":378566,"endOffset":379433,"count":0}],"isBlockCoverage":false},{"functionName":"_set$2","ranges":[{"startOffset":379447,"endOffset":380330,"count":0}],"isBlockCoverage":false},{"functionName":"forEach$1","ranges":[{"startOffset":380347,"endOffset":380898,"count":0}],"isBlockCoverage":false},{"functionName":"_collection$_computeKeys$0","ranges":[{"startOffset":380932,"endOffset":382221,"count":0}],"isBlockCoverage":false},{"functionName":"_collection$_addHashTableEntry$3","ranges":[{"startOffset":382261,"endOffset":382617,"count":0}],"isBlockCoverage":false},{"functionName":"_computeHashCode$1","ranges":[{"startOffset":382643,"endOffset":382712,"count":0}],"isBlockCoverage":false},{"functionName":"_getBucket$2","ranges":[{"startOffset":382732,"endOffset":382810,"count":0}],"isBlockCoverage":false},{"functionName":"_findBucketIndex$2","ranges":[{"startOffset":382836,"endOffset":383075,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":383135,"endOffset":383198,"count":0}],"isBlockCoverage":false},{"functionName":"get$isEmpty","ranges":[{"startOffset":383217,"endOffset":383286,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":383306,"endOffset":383438,"count":0}],"isBlockCoverage":false},{"functionName":"get$current","ranges":[{"startOffset":383499,"endOffset":383557,"count":0}],"isBlockCoverage":false},{"functionName":"moveNext$0","ranges":[{"startOffset":383575,"endOffset":384056,"count":0}],"isBlockCoverage":false},{"functionName":"set$_collection$_current","ranges":[{"startOffset":384088,"endOffset":384223,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":384300,"endOffset":384484,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":384502,"endOffset":384560,"count":0}],"isBlockCoverage":false},{"functionName":"contains$1","ranges":[{"startOffset":384578,"endOffset":385195,"count":1},{"startOffset":384662,"endOffset":384687,"count":0},{"startOffset":384689,"endOffset":384885,"count":0},{"startOffset":385049,"endOffset":385189,"count":0}],"isBlockCoverage":true},{"functionName":"_contains$1","ranges":[{"startOffset":385214,"endOffset":385409,"count":0}],"isBlockCoverage":false},{"functionName":"add$1","ranges":[{"startOffset":385422,"endOffset":386268,"count":0}],"isBlockCoverage":false},{"functionName":"_collection$_add$1","ranges":[{"startOffset":386294,"endOffset":386943,"count":0}],"isBlockCoverage":false},{"functionName":"remove$1","ranges":[{"startOffset":386959,"endOffset":387360,"count":1},{"startOffset":387018,"endOffset":387043,"count":0},{"startOffset":387053,"endOffset":387136,"count":0},{"startOffset":387304,"endOffset":387354,"count":0}],"isBlockCoverage":true},{"functionName":"_remove$1","ranges":[{"startOffset":387377,"endOffset":387746,"count":0}],"isBlockCoverage":false},{"functionName":"_collection$_addHashTableEntry$2","ranges":[{"startOffset":387786,"endOffset":388089,"count":0}],"isBlockCoverage":false},{"functionName":"_collection$_removeHashTableEntry$2","ranges":[{"startOffset":388132,"endOffset":388443,"count":1},{"startOffset":388221,"endOffset":388442,"count":0}],"isBlockCoverage":true},{"functionName":"_collection$_modified$0","ranges":[{"startOffset":388474,"endOffset":388582,"count":0}],"isBlockCoverage":false},{"functionName":"_collection$_newLinkedCell$1","ranges":[{"startOffset":388618,"endOffset":389176,"count":0}],"isBlockCoverage":false},{"functionName":"_collection$_unlinkCell$1","ranges":[{"startOffset":389209,"endOffset":389658,"count":0}],"isBlockCoverage":false},{"functionName":"_computeHashCode$1","ranges":[{"startOffset":389684,"endOffset":389761,"count":0}],"isBlockCoverage":false},{"functionName":"_getBucket$2","ranges":[{"startOffset":389781,"endOffset":389867,"count":0}],"isBlockCoverage":false},{"functionName":"_findBucketIndex$2","ranges":[{"startOffset":389893,"endOffset":390203,"count":0}],"isBlockCoverage":false},{"functionName":"get$current","ranges":[{"startOffset":390306,"endOffset":390364,"count":0}],"isBlockCoverage":false},{"functionName":"moveNext$0","ranges":[{"startOffset":390382,"endOffset":390971,"count":0}],"isBlockCoverage":false},{"functionName":"set$_collection$_current","ranges":[{"startOffset":391003,"endOffset":391138,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":391329,"endOffset":391499,"count":0}],"isBlockCoverage":false},{"functionName":"elementAt$1","ranges":[{"startOffset":391518,"endOffset":391594,"count":0}],"isBlockCoverage":false},{"functionName":"get$isEmpty","ranges":[{"startOffset":391613,"endOffset":391685,"count":0}],"isBlockCoverage":false},{"functionName":"get$isNotEmpty","ranges":[{"startOffset":391707,"endOffset":391775,"count":0}],"isBlockCoverage":false},{"functionName":"fillRange$3","ranges":[{"startOffset":391794,"endOffset":392116,"count":1}],"isBlockCoverage":true},{"functionName":"toString$0","ranges":[{"startOffset":392134,"endOffset":392230,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":392322,"endOffset":392591,"count":0}],"isBlockCoverage":false},{"functionName":"forEach$1","ranges":[{"startOffset":392659,"endOffset":393030,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":393048,"endOffset":393131,"count":0}],"isBlockCoverage":false},{"functionName":"get$isEmpty","ranges":[{"startOffset":393150,"endOffset":393234,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":393252,"endOffset":393313,"count":0}],"isBlockCoverage":false},{"functionName":"$indexSet","ranges":[{"startOffset":393389,"endOffset":393708,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":393752,"endOffset":393815,"count":1}],"isBlockCoverage":true},{"functionName":"$indexSet","ranges":[{"startOffset":393832,"endOffset":394035,"count":0}],"isBlockCoverage":false},{"functionName":"forEach$1","ranges":[{"startOffset":394052,"endOffset":394236,"count":0}],"isBlockCoverage":false},{"functionName":"get$isEmpty","ranges":[{"startOffset":394255,"endOffset":394333,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":394351,"endOffset":394428,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":394446,"endOffset":394504,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":394608,"endOffset":394693,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":394926,"endOffset":395244,"count":1},{"startOffset":395025,"endOffset":395058,"count":0},{"startOffset":395107,"endOffset":395114,"count":0},{"startOffset":395221,"endOffset":395229,"count":0}],"isBlockCoverage":true},{"functionName":"get$length","ranges":[{"startOffset":395262,"endOffset":395383,"count":0}],"isBlockCoverage":false},{"functionName":"get$isEmpty","ranges":[{"startOffset":395402,"endOffset":395463,"count":0}],"isBlockCoverage":false},{"functionName":"get$keys","ranges":[{"startOffset":395479,"endOffset":395703,"count":0}],"isBlockCoverage":false},{"functionName":"$indexSet","ranges":[{"startOffset":395720,"endOffset":396180,"count":0}],"isBlockCoverage":false},{"functionName":"containsKey$1","ranges":[{"startOffset":396201,"endOffset":396375,"count":0}],"isBlockCoverage":false},{"functionName":"forEach$1","ranges":[{"startOffset":396392,"endOffset":397032,"count":1},{"startOffset":396553,"endOffset":396587,"count":0},{"startOffset":396958,"endOffset":397018,"count":0}],"isBlockCoverage":true},{"functionName":"_computeKeys$0","ranges":[{"startOffset":397054,"endOffset":397276,"count":1}],"isBlockCoverage":true},{"functionName":"_upgrade$0","ranges":[{"startOffset":397294,"endOffset":397882,"count":0}],"isBlockCoverage":false},{"functionName":"_process$1","ranges":[{"startOffset":397900,"endOffset":398131,"count":1},{"startOffset":398012,"endOffset":398019,"count":0}],"isBlockCoverage":true},{"functionName":"$asMapMixin","ranges":[{"startOffset":398150,"endOffset":398199,"count":0}],"isBlockCoverage":false},{"functionName":"$asMap","ranges":[{"startOffset":398213,"endOffset":398262,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":398322,"endOffset":398411,"count":0}],"isBlockCoverage":false},{"functionName":"elementAt$1","ranges":[{"startOffset":398430,"endOffset":398755,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":398775,"endOffset":399090,"count":0}],"isBlockCoverage":false},{"functionName":"$asEfficientLengthIterable","ranges":[{"startOffset":399124,"endOffset":399167,"count":0}],"isBlockCoverage":false},{"functionName":"$asListIterable","ranges":[{"startOffset":399190,"endOffset":399233,"count":0}],"isBlockCoverage":false},{"functionName":"$asIterable","ranges":[{"startOffset":399252,"endOffset":399295,"count":0}],"isBlockCoverage":false},{"functionName":"encode$1","ranges":[{"startOffset":399344,"endOffset":399419,"count":0}],"isBlockCoverage":false},{"functionName":"convert$1","ranges":[{"startOffset":399480,"endOffset":400124,"count":0}],"isBlockCoverage":false},{"functionName":"$asStreamTransformer","ranges":[{"startOffset":400152,"endOffset":400212,"count":0}],"isBlockCoverage":false},{"functionName":"$asConverter","ranges":[{"startOffset":400232,"endOffset":400292,"count":0}],"isBlockCoverage":false},{"functionName":"normalize$3","ranges":[{"startOffset":400378,"endOffset":404030,"count":0}],"isBlockCoverage":false},{"functionName":"$asCodec","ranges":[{"startOffset":404046,"endOffset":404106,"count":0}],"isBlockCoverage":false},{"functionName":"$asStreamTransformer","ranges":[{"startOffset":404170,"endOffset":404230,"count":0}],"isBlockCoverage":false},{"functionName":"$asConverter","ranges":[{"startOffset":404250,"endOffset":404310,"count":0}],"isBlockCoverage":false},{"functionName":"$asCodec","ranges":[{"startOffset":404386,"endOffset":404437,"count":0}],"isBlockCoverage":false},{"functionName":"$asCodec","ranges":[{"startOffset":404514,"endOffset":404574,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":404641,"endOffset":404894,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":404950,"endOffset":405016,"count":0}],"isBlockCoverage":false},{"functionName":"decode$2$reviver","ranges":[{"startOffset":405072,"endOffset":405191,"count":1}],"isBlockCoverage":true},{"functionName":"encode$2$toEncodable","ranges":[{"startOffset":405219,"endOffset":405389,"count":1}],"isBlockCoverage":true},{"functionName":"get$encoder","ranges":[{"startOffset":405408,"endOffset":405464,"count":1}],"isBlockCoverage":true},{"functionName":"get$decoder","ranges":[{"startOffset":405483,"endOffset":405534,"count":1}],"isBlockCoverage":true},{"functionName":"$asCodec","ranges":[{"startOffset":405550,"endOffset":405603,"count":0}],"isBlockCoverage":false},{"functionName":"$asStreamTransformer","ranges":[{"startOffset":405665,"endOffset":405718,"count":0}],"isBlockCoverage":false},{"functionName":"$asConverter","ranges":[{"startOffset":405738,"endOffset":405791,"count":0}],"isBlockCoverage":false},{"functionName":"$asStreamTransformer","ranges":[{"startOffset":405853,"endOffset":405906,"count":0}],"isBlockCoverage":false},{"functionName":"$asConverter","ranges":[{"startOffset":405926,"endOffset":405979,"count":0}],"isBlockCoverage":false},{"functionName":"writeStringContent$1","ranges":[{"startOffset":406046,"endOffset":407693,"count":1},{"startOffset":406329,"endOffset":407300,"count":0},{"startOffset":407346,"endOffset":407538,"count":0},{"startOffset":407601,"endOffset":407687,"count":0}],"isBlockCoverage":true},{"functionName":"_checkCycle$1","ranges":[{"startOffset":407714,"endOffset":408027,"count":1},{"startOffset":407871,"endOffset":407883,"count":0},{"startOffset":407911,"endOffset":407970,"count":0}],"isBlockCoverage":true},{"functionName":"writeObject$1","ranges":[{"startOffset":408048,"endOffset":408754,"count":1},{"startOffset":408163,"endOffset":408748,"count":0}],"isBlockCoverage":true},{"functionName":"writeJsonValue$1","ranges":[{"startOffset":408778,"endOffset":410030,"count":1},{"startOffset":408901,"endOffset":408914,"count":0},{"startOffset":409006,"endOffset":409072,"count":0},{"startOffset":409100,"endOffset":409167,"count":0},{"startOffset":409655,"endOffset":409678,"count":0},{"startOffset":409908,"endOffset":409931,"count":0},{"startOffset":409987,"endOffset":410016,"count":0}],"isBlockCoverage":true},{"functionName":"writeList$1","ranges":[{"startOffset":410049,"endOffset":410429,"count":1}],"isBlockCoverage":true},{"functionName":"writeMap$1","ranges":[{"startOffset":410447,"endOffset":411384,"count":1},{"startOffset":410929,"endOffset":410942,"count":0},{"startOffset":411241,"endOffset":411274,"count":0}],"isBlockCoverage":true},{"functionName":"call$2","ranges":[{"startOffset":411454,"endOffset":411738,"count":1},{"startOffset":411538,"endOffset":411572,"count":0}],"isBlockCoverage":true},{"functionName":"get$_partialResult","ranges":[{"startOffset":411829,"endOffset":411944,"count":0}],"isBlockCoverage":false},{"functionName":"writeNumber$1","ranges":[{"startOffset":411965,"endOffset":412063,"count":1}],"isBlockCoverage":true},{"functionName":"writeString$1","ranges":[{"startOffset":412084,"endOffset":412151,"count":1}],"isBlockCoverage":true},{"functionName":"writeStringSlice$3","ranges":[{"startOffset":412177,"endOffset":412285,"count":0}],"isBlockCoverage":false},{"functionName":"writeCharCode$1","ranges":[{"startOffset":412308,"endOffset":412387,"count":0}],"isBlockCoverage":false},{"functionName":"get$encoder","ranges":[{"startOffset":412438,"endOffset":412486,"count":0}],"isBlockCoverage":false},{"functionName":"convert$1","ranges":[{"startOffset":412537,"endOffset":413070,"count":0}],"isBlockCoverage":false},{"functionName":"$asStreamTransformer","ranges":[{"startOffset":413098,"endOffset":413158,"count":0}],"isBlockCoverage":false},{"functionName":"$asConverter","ranges":[{"startOffset":413178,"endOffset":413238,"count":0}],"isBlockCoverage":false},{"functionName":"_writeSurrogate$2","ranges":[{"startOffset":413298,"endOffset":414650,"count":0}],"isBlockCoverage":false},{"functionName":"_fillBuffer$3","ranges":[{"startOffset":414671,"endOffset":416478,"count":0}],"isBlockCoverage":false},{"functionName":"convert$1","ranges":[{"startOffset":416529,"endOffset":417119,"count":1},{"startOffset":416771,"endOffset":416785,"count":0},{"startOffset":417103,"endOffset":417107,"count":0}],"isBlockCoverage":true},{"functionName":"$asStreamTransformer","ranges":[{"startOffset":417147,"endOffset":417207,"count":0}],"isBlockCoverage":false},{"functionName":"$asConverter","ranges":[{"startOffset":417227,"endOffset":417287,"count":0}],"isBlockCoverage":false},{"functionName":"flush$2","ranges":[{"startOffset":417337,"endOffset":417609,"count":1},{"startOffset":417475,"endOffset":417603,"count":0}],"isBlockCoverage":true},{"functionName":"convert$3","ranges":[{"startOffset":417626,"endOffset":421538,"count":1},{"startOffset":418311,"endOffset":419809,"count":0},{"startOffset":420150,"endOffset":421331,"count":0},{"startOffset":421410,"endOffset":421532,"count":0}],"isBlockCoverage":true},{"functionName":"call$2","ranges":[{"startOffset":421610,"endOffset":421735,"count":1}],"isBlockCoverage":true},{"functionName":"call$2","ranges":[{"startOffset":421826,"endOffset":422161,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":422248,"endOffset":422415,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":422435,"endOffset":422566,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":422584,"endOffset":423195,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":423264,"endOffset":423417,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":423437,"endOffset":423515,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":423533,"endOffset":424155,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":424219,"endOffset":424494,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":424578,"endOffset":424661,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":424763,"endOffset":424813,"count":0}],"isBlockCoverage":false},{"functionName":"get$_errorName","ranges":[{"startOffset":424871,"endOffset":424955,"count":0}],"isBlockCoverage":false},{"functionName":"get$_errorExplanation","ranges":[{"startOffset":424984,"endOffset":425019,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":425037,"endOffset":425551,"count":0}],"isBlockCoverage":false},{"functionName":"get$_errorName","ranges":[{"startOffset":425606,"endOffset":425651,"count":0}],"isBlockCoverage":false},{"functionName":"get$_errorExplanation","ranges":[{"startOffset":425680,"endOffset":426274,"count":0}],"isBlockCoverage":false},{"functionName":"get$_errorName","ranges":[{"startOffset":426329,"endOffset":426374,"count":0}],"isBlockCoverage":false},{"functionName":"get$_errorExplanation","ranges":[{"startOffset":426403,"endOffset":426799,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":426817,"endOffset":426869,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":426927,"endOffset":427772,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":427829,"endOffset":427903,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":427962,"endOffset":428088,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":428139,"endOffset":428201,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":428269,"endOffset":428498,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":428555,"endOffset":428604,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":428680,"endOffset":428730,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":428813,"endOffset":429012,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":429063,"endOffset":429125,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":429181,"endOffset":431814,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":431916,"endOffset":432069,"count":0}],"isBlockCoverage":false},{"functionName":"get$isEmpty","ranges":[{"startOffset":432088,"endOffset":432159,"count":0}],"isBlockCoverage":false},{"functionName":"skipWhile$1","ranges":[{"startOffset":432178,"endOffset":432378,"count":0}],"isBlockCoverage":false},{"functionName":"get$first","ranges":[{"startOffset":432395,"endOffset":432580,"count":0}],"isBlockCoverage":false},{"functionName":"get$last","ranges":[{"startOffset":432596,"endOffset":432864,"count":0}],"isBlockCoverage":false},{"functionName":"elementAt$1","ranges":[{"startOffset":432883,"endOffset":433294,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":433312,"endOffset":433398,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":433568,"endOffset":433650,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":433668,"endOffset":433708,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":433808,"endOffset":433863,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":433883,"endOffset":433950,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":433968,"endOffset":434059,"count":0}],"isBlockCoverage":false},{"functionName":"noSuchMethod$1","ranges":[{"startOffset":434081,"endOffset":434328,"count":0}],"isBlockCoverage":false},{"functionName":"toString","ranges":[{"startOffset":434344,"endOffset":434398,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":434513,"endOffset":434563,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":434678,"endOffset":434733,"count":0}],"isBlockCoverage":false},{"functionName":"write$1","ranges":[{"startOffset":434748,"endOffset":434803,"count":1}],"isBlockCoverage":true},{"functionName":"writeCharCode$1","ranges":[{"startOffset":434826,"endOffset":434919,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":434937,"endOffset":435033,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":435148,"endOffset":435892,"count":1},{"startOffset":435410,"endOffset":435547,"count":0}],"isBlockCoverage":true},{"functionName":"call$2","ranges":[{"startOffset":435976,"endOffset":436109,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":436192,"endOffset":436325,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":436339,"endOffset":436397,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":436483,"endOffset":436948,"count":0}],"isBlockCoverage":false},{"functionName":"get$userInfo","ranges":[{"startOffset":437015,"endOffset":437062,"count":0}],"isBlockCoverage":false},{"functionName":"get$host","ranges":[{"startOffset":437078,"endOffset":437303,"count":0}],"isBlockCoverage":false},{"functionName":"get$port","ranges":[{"startOffset":437319,"endOffset":437453,"count":0}],"isBlockCoverage":false},{"functionName":"get$query","ranges":[{"startOffset":437470,"endOffset":437551,"count":0}],"isBlockCoverage":false},{"functionName":"get$fragment","ranges":[{"startOffset":437571,"endOffset":437655,"count":0}],"isBlockCoverage":false},{"functionName":"get$pathSegments","ranges":[{"startOffset":437679,"endOffset":438447,"count":0}],"isBlockCoverage":false},{"functionName":"get$queryParameters","ranges":[{"startOffset":438474,"endOffset":438764,"count":1},{"startOffset":438691,"endOffset":438695,"count":0}],"isBlockCoverage":true},{"functionName":"_mergePaths$2","ranges":[{"startOffset":438785,"endOffset":439869,"count":0}],"isBlockCoverage":false},{"functionName":"resolve$1","ranges":[{"startOffset":439886,"endOffset":439969,"count":0}],"isBlockCoverage":false},{"functionName":"resolveUri$1","ranges":[{"startOffset":439989,"endOffset":442823,"count":0}],"isBlockCoverage":false},{"functionName":"get$hasAuthority","ranges":[{"startOffset":442847,"endOffset":442898,"count":0}],"isBlockCoverage":false},{"functionName":"get$hasPort","ranges":[{"startOffset":442917,"endOffset":442968,"count":0}],"isBlockCoverage":false},{"functionName":"get$hasQuery","ranges":[{"startOffset":442988,"endOffset":443040,"count":0}],"isBlockCoverage":false},{"functionName":"get$hasFragment","ranges":[{"startOffset":443063,"endOffset":443118,"count":0}],"isBlockCoverage":false},{"functionName":"get$hasAbsolutePath","ranges":[{"startOffset":443145,"endOffset":443210,"count":0}],"isBlockCoverage":false},{"functionName":"toFilePath$0","ranges":[{"startOffset":443230,"endOffset":444436,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":444454,"endOffset":445288,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":445299,"endOffset":446881,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":446901,"endOffset":447105,"count":0}],"isBlockCoverage":false},{"functionName":"set$_pathSegments","ranges":[{"startOffset":447130,"endOffset":447254,"count":0}],"isBlockCoverage":false},{"functionName":"set$_queryParameters","ranges":[{"startOffset":447282,"endOffset":447436,"count":1}],"isBlockCoverage":true},{"functionName":"get$scheme","ranges":[{"startOffset":447469,"endOffset":447513,"count":0}],"isBlockCoverage":false},{"functionName":"get$path","ranges":[{"startOffset":447529,"endOffset":447579,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":447643,"endOffset":447836,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":447944,"endOffset":448269,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":448348,"endOffset":448460,"count":0}],"isBlockCoverage":false},{"functionName":"get$uri","ranges":[{"startOffset":448525,"endOffset":449212,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":449230,"endOffset":449434,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":449492,"endOffset":449544,"count":1}],"isBlockCoverage":true},{"functionName":"call$2","ranges":[{"startOffset":449620,"endOffset":449847,"count":1},{"startOffset":449723,"endOffset":449749,"count":0}],"isBlockCoverage":true},{"functionName":"call$3","ranges":[{"startOffset":449926,"endOffset":450216,"count":1},{"startOffset":450142,"endOffset":450169,"count":0}],"isBlockCoverage":true},{"functionName":"call$3","ranges":[{"startOffset":450275,"endOffset":450601,"count":1},{"startOffset":450527,"endOffset":450554,"count":0}],"isBlockCoverage":true},{"functionName":"get$hasAuthority","ranges":[{"startOffset":450658,"endOffset":450710,"count":0}],"isBlockCoverage":false},{"functionName":"get$hasPort","ranges":[{"startOffset":450729,"endOffset":451079,"count":0}],"isBlockCoverage":false},{"functionName":"get$hasQuery","ranges":[{"startOffset":451099,"endOffset":451337,"count":0}],"isBlockCoverage":false},{"functionName":"get$hasFragment","ranges":[{"startOffset":451360,"endOffset":451538,"count":0}],"isBlockCoverage":false},{"functionName":"get$_isFile","ranges":[{"startOffset":451557,"endOffset":451650,"count":0}],"isBlockCoverage":false},{"functionName":"get$_isHttp","ranges":[{"startOffset":451669,"endOffset":451762,"count":0}],"isBlockCoverage":false},{"functionName":"get$_isHttps","ranges":[{"startOffset":451782,"endOffset":451876,"count":0}],"isBlockCoverage":false},{"functionName":"get$hasAbsolutePath","ranges":[{"startOffset":451903,"endOffset":451985,"count":0}],"isBlockCoverage":false},{"functionName":"get$scheme","ranges":[{"startOffset":452003,"endOffset":452773,"count":0}],"isBlockCoverage":false},{"functionName":"get$userInfo","ranges":[{"startOffset":452793,"endOffset":453028,"count":0}],"isBlockCoverage":false},{"functionName":"get$host","ranges":[{"startOffset":453044,"endOffset":453171,"count":0}],"isBlockCoverage":false},{"functionName":"get$port","ranges":[{"startOffset":453187,"endOffset":453563,"count":0}],"isBlockCoverage":false},{"functionName":"get$path","ranges":[{"startOffset":453579,"endOffset":453674,"count":0}],"isBlockCoverage":false},{"functionName":"get$query","ranges":[{"startOffset":453691,"endOffset":453975,"count":0}],"isBlockCoverage":false},{"functionName":"get$fragment","ranges":[{"startOffset":453995,"endOffset":454227,"count":0}],"isBlockCoverage":false},{"functionName":"get$pathSegments","ranges":[{"startOffset":454251,"endOffset":455219,"count":0}],"isBlockCoverage":false},{"functionName":"get$queryParameters","ranges":[{"startOffset":455246,"endOffset":455623,"count":0}],"isBlockCoverage":false},{"functionName":"_isPort$1","ranges":[{"startOffset":455640,"endOffset":455927,"count":0}],"isBlockCoverage":false},{"functionName":"removeFragment$0","ranges":[{"startOffset":455951,"endOffset":456335,"count":0}],"isBlockCoverage":false},{"functionName":"resolve$1","ranges":[{"startOffset":456352,"endOffset":456435,"count":0}],"isBlockCoverage":false},{"functionName":"resolveUri$1","ranges":[{"startOffset":456455,"endOffset":456640,"count":0}],"isBlockCoverage":false},{"functionName":"_simpleMerge$2","ranges":[{"startOffset":456662,"endOffset":462688,"count":0}],"isBlockCoverage":false},{"functionName":"toFilePath$0","ranges":[{"startOffset":462708,"endOffset":463987,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":464007,"endOffset":464186,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":464197,"endOffset":464401,"count":0}],"isBlockCoverage":false},{"functionName":"_toNonSimple$0","ranges":[{"startOffset":464423,"endOffset":465061,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":465079,"endOffset":465122,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":465252,"endOffset":465309,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":465361,"endOffset":465418,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":465507,"endOffset":465563,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":465616,"endOffset":465673,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":465726,"endOffset":465782,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":465830,"endOffset":465889,"count":0}],"isBlockCoverage":false},{"functionName":"get$onClick","ranges":[{"startOffset":465908,"endOffset":466020,"count":0}],"isBlockCoverage":false},{"functionName":"addEventListener$3","ranges":[{"startOffset":466136,"endOffset":466350,"count":1}],"isBlockCoverage":true},{"functionName":"_addEventListener$3","ranges":[{"startOffset":466377,"endOffset":466569,"count":1}],"isBlockCoverage":true},{"functionName":"_removeEventListener$3","ranges":[{"startOffset":466599,"endOffset":466794,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":466904,"endOffset":466960,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":467015,"endOffset":467071,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":467085,"endOffset":467319,"count":0}],"isBlockCoverage":false},{"functionName":"$indexSet","ranges":[{"startOffset":467336,"endOffset":467547,"count":0}],"isBlockCoverage":false},{"functionName":"elementAt$1","ranges":[{"startOffset":467566,"endOffset":467719,"count":0}],"isBlockCoverage":false},{"functionName":"$asEfficientLengthIterable","ranges":[{"startOffset":467788,"endOffset":467829,"count":0}],"isBlockCoverage":false},{"functionName":"$asJavaScriptIndexingBehavior","ranges":[{"startOffset":467904,"endOffset":467945,"count":0}],"isBlockCoverage":false},{"functionName":"$asListMixin","ranges":[{"startOffset":467965,"endOffset":468006,"count":0}],"isBlockCoverage":false},{"functionName":"$asIterable","ranges":[{"startOffset":468045,"endOffset":468086,"count":0}],"isBlockCoverage":false},{"functionName":"$asList","ranges":[{"startOffset":468117,"endOffset":468158,"count":0}],"isBlockCoverage":false},{"functionName":"$asImmutableListMixin","ranges":[{"startOffset":468187,"endOffset":468228,"count":0}],"isBlockCoverage":false},{"functionName":"get$origin","ranges":[{"startOffset":468330,"endOffset":468485,"count":1},{"startOffset":468414,"endOffset":468484,"count":0}],"isBlockCoverage":true},{"functionName":"toString$0","ranges":[{"startOffset":468503,"endOffset":468560,"count":0}],"isBlockCoverage":false},{"functionName":"addEventListener$3","ranges":[{"startOffset":468671,"endOffset":468926,"count":1}],"isBlockCoverage":true},{"functionName":"postMessage$1","ranges":[{"startOffset":468947,"endOffset":469079,"count":1}],"isBlockCoverage":true},{"functionName":"toString$0","ranges":[{"startOffset":469194,"endOffset":469338,"count":0}],"isBlockCoverage":false},{"functionName":"_removeChild$1","ranges":[{"startOffset":469360,"endOffset":469435,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":469505,"endOffset":469561,"count":0}],"isBlockCoverage":false},{"functionName":"get$location","ranges":[{"startOffset":469638,"endOffset":469696,"count":1}],"isBlockCoverage":true},{"functionName":"postMessage$3","ranges":[{"startOffset":469717,"endOffset":469975,"count":0}],"isBlockCoverage":false},{"functionName":"_postMessage_1$3","ranges":[{"startOffset":469999,"endOffset":470177,"count":0}],"isBlockCoverage":false},{"functionName":"listen$4$cancelOnError$onDone$onError","ranges":[{"startOffset":470279,"endOffset":470605,"count":0}],"isBlockCoverage":false},{"functionName":"listen$1","ranges":[{"startOffset":470621,"endOffset":470728,"count":0}],"isBlockCoverage":false},{"functionName":"listen$3$onDone$onError","ranges":[{"startOffset":470759,"endOffset":470888,"count":0}],"isBlockCoverage":false},{"functionName":"cancel$0","ranges":[{"startOffset":470995,"endOffset":471170,"count":0}],"isBlockCoverage":false},{"functionName":"_tryResume$0","ranges":[{"startOffset":471190,"endOffset":471364,"count":1}],"isBlockCoverage":true},{"functionName":"_unlisten$0","ranges":[{"startOffset":471383,"endOffset":471696,"count":0}],"isBlockCoverage":false},{"functionName":"set$_onData","ranges":[{"startOffset":471715,"endOffset":471819,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":471888,"endOffset":471979,"count":1}],"isBlockCoverage":true},{"functionName":"get$iterator","ranges":[{"startOffset":472060,"endOffset":472239,"count":0}],"isBlockCoverage":false},{"functionName":"moveNext$0","ranges":[{"startOffset":472301,"endOffset":472764,"count":0}],"isBlockCoverage":false},{"functionName":"get$current","ranges":[{"startOffset":472783,"endOffset":472829,"count":0}],"isBlockCoverage":false},{"functionName":"set$_current","ranges":[{"startOffset":472849,"endOffset":472972,"count":0}],"isBlockCoverage":false},{"functionName":"postMessage$3","ranges":[{"startOffset":473056,"endOffset":473227,"count":1}],"isBlockCoverage":true},{"functionName":"findSlot$1","ranges":[{"startOffset":473464,"endOffset":473763,"count":1},{"startOffset":473634,"endOffset":473643,"count":0}],"isBlockCoverage":true},{"functionName":"walk$1","ranges":[{"startOffset":473777,"endOffset":475247,"count":1},{"startOffset":474098,"endOffset":474130,"count":0},{"startOffset":474165,"endOffset":474240,"count":0},{"startOffset":474273,"endOffset":474282,"count":0},{"startOffset":474315,"endOffset":474324,"count":0},{"startOffset":474419,"endOffset":474428,"count":0},{"startOffset":474556,"endOffset":474581,"count":0},{"startOffset":474667,"endOffset":474679,"count":0},{"startOffset":475007,"endOffset":475032,"count":0},{"startOffset":475094,"endOffset":475106,"count":0},{"startOffset":475155,"endOffset":475246,"count":0}],"isBlockCoverage":true},{"functionName":"copyList$2","ranges":[{"startOffset":475265,"endOffset":475616,"count":1}],"isBlockCoverage":true},{"functionName":"call$2","ranges":[{"startOffset":475682,"endOffset":475766,"count":1}],"isBlockCoverage":true},{"functionName":"findSlot$1","ranges":[{"startOffset":475849,"endOffset":476208,"count":1},{"startOffset":476029,"endOffset":476044,"count":0},{"startOffset":476071,"endOffset":476080,"count":0}],"isBlockCoverage":true},{"functionName":"walk$1","ranges":[{"startOffset":476222,"endOffset":478314,"count":1},{"startOffset":476555,"endOffset":476884,"count":0},{"startOffset":476924,"endOffset":476999,"count":0},{"startOffset":477073,"endOffset":477118,"count":0},{"startOffset":477319,"endOffset":477344,"count":0},{"startOffset":477434,"endOffset":477446,"count":0},{"startOffset":477849,"endOffset":477874,"count":0},{"startOffset":477936,"endOffset":477948,"count":0},{"startOffset":478073,"endOffset":478076,"count":0},{"startOffset":478292,"endOffset":478313,"count":0}],"isBlockCoverage":true},{"functionName":"convertNativeToDart_AcceptStructuredClone$2$mustCopy","ranges":[{"startOffset":478374,"endOffset":478470,"count":1}],"isBlockCoverage":true},{"functionName":"call$2","ranges":[{"startOffset":478542,"endOffset":478706,"count":1}],"isBlockCoverage":true},{"functionName":"forEachJsField$2","ranges":[{"startOffset":478846,"endOffset":479184,"count":1},{"startOffset":479052,"endOffset":479098,"count":0}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":479261,"endOffset":479336,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":479433,"endOffset":479510,"count":0}],"isBlockCoverage":false},{"functionName":"get$onClick","ranges":[{"startOffset":479581,"endOffset":479693,"count":1}],"isBlockCoverage":true},{"functionName":"$asEfficientLengthIterable","ranges":[{"startOffset":479789,"endOffset":479829,"count":0}],"isBlockCoverage":false},{"functionName":"$asIterable","ranges":[{"startOffset":479868,"endOffset":479908,"count":0}],"isBlockCoverage":false},{"functionName":"$asList","ranges":[{"startOffset":479939,"endOffset":479979,"count":0}],"isBlockCoverage":false},{"functionName":"addStream$1","ranges":[{"startOffset":480035,"endOffset":480478,"count":0}],"isBlockCoverage":false},{"functionName":"_checkEventAllowed$0","ranges":[{"startOffset":480506,"endOffset":480767,"count":0}],"isBlockCoverage":false},{"functionName":"close$0","ranges":[{"startOffset":480782,"endOffset":480870,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":480987,"endOffset":481045,"count":0}],"isBlockCoverage":false},{"functionName":"absolute$7","ranges":[{"startOffset":481161,"endOffset":481639,"count":0}],"isBlockCoverage":false},{"functionName":"absolute$1","ranges":[{"startOffset":481657,"endOffset":481775,"count":0}],"isBlockCoverage":false},{"functionName":"join$8","ranges":[{"startOffset":481789,"endOffset":482229,"count":0}],"isBlockCoverage":false},{"functionName":"join$2","ranges":[{"startOffset":482243,"endOffset":482371,"count":0}],"isBlockCoverage":false},{"functionName":"joinAll$1","ranges":[{"startOffset":482388,"endOffset":483822,"count":0}],"isBlockCoverage":false},{"functionName":"split$1","ranges":[{"startOffset":483837,"endOffset":484322,"count":0}],"isBlockCoverage":false},{"functionName":"normalize$1","ranges":[{"startOffset":484341,"endOffset":484574,"count":0}],"isBlockCoverage":false},{"functionName":"_needsNormalization$1","ranges":[{"startOffset":484603,"endOffset":486114,"count":0}],"isBlockCoverage":false},{"functionName":"relative$1","ranges":[{"startOffset":486132,"endOffset":488870,"count":0}],"isBlockCoverage":false},{"functionName":"toUri$1","ranges":[{"startOffset":488885,"endOffset":489181,"count":0}],"isBlockCoverage":false},{"functionName":"prettyUri$1","ranges":[{"startOffset":489200,"endOffset":489763,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":489820,"endOffset":489888,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":489967,"endOffset":490034,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":490111,"endOffset":490184,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":490264,"endOffset":490368,"count":0}],"isBlockCoverage":false},{"functionName":"getRoot$1","ranges":[{"startOffset":490441,"endOffset":490777,"count":0}],"isBlockCoverage":false},{"functionName":"relativePathToUri$1","ranges":[{"startOffset":490804,"endOffset":491061,"count":0}],"isBlockCoverage":false},{"functionName":"pathsEqual$2","ranges":[{"startOffset":491081,"endOffset":491140,"count":0}],"isBlockCoverage":false},{"functionName":"get$hasTrailingSeparator","ranges":[{"startOffset":491205,"endOffset":491442,"count":0}],"isBlockCoverage":false},{"functionName":"removeTrailingSeparators$0","ranges":[{"startOffset":491476,"endOffset":491891,"count":0}],"isBlockCoverage":false},{"functionName":"normalize$0","ranges":[{"startOffset":491910,"endOffset":493391,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":493409,"endOffset":493905,"count":0}],"isBlockCoverage":false},{"functionName":"set$parts","ranges":[{"startOffset":493922,"endOffset":494022,"count":0}],"isBlockCoverage":false},{"functionName":"set$separators","ranges":[{"startOffset":494044,"endOffset":494159,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":494224,"endOffset":494290,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":494364,"endOffset":494430,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":494476,"endOffset":494529,"count":0}],"isBlockCoverage":false},{"functionName":"containsSeparator$1","ranges":[{"startOffset":494589,"endOffset":494666,"count":0}],"isBlockCoverage":false},{"functionName":"isSeparator$1","ranges":[{"startOffset":494687,"endOffset":494743,"count":0}],"isBlockCoverage":false},{"functionName":"needsSeparator$1","ranges":[{"startOffset":494767,"endOffset":494881,"count":0}],"isBlockCoverage":false},{"functionName":"rootLength$2$withDrive","ranges":[{"startOffset":494911,"endOffset":495044,"count":0}],"isBlockCoverage":false},{"functionName":"rootLength$1","ranges":[{"startOffset":495064,"endOffset":495141,"count":0}],"isBlockCoverage":false},{"functionName":"isRootRelative$1","ranges":[{"startOffset":495165,"endOffset":495207,"count":0}],"isBlockCoverage":false},{"functionName":"pathFromUri$1","ranges":[{"startOffset":495228,"endOffset":495555,"count":0}],"isBlockCoverage":false},{"functionName":"absolutePathToUri$1","ranges":[{"startOffset":495582,"endOffset":495981,"count":0}],"isBlockCoverage":false},{"functionName":"get$name","ranges":[{"startOffset":495997,"endOffset":496047,"count":0}],"isBlockCoverage":false},{"functionName":"get$separator","ranges":[{"startOffset":496068,"endOffset":496115,"count":0}],"isBlockCoverage":false},{"functionName":"containsSeparator$1","ranges":[{"startOffset":496173,"endOffset":496250,"count":0}],"isBlockCoverage":false},{"functionName":"isSeparator$1","ranges":[{"startOffset":496271,"endOffset":496327,"count":0}],"isBlockCoverage":false},{"functionName":"needsSeparator$1","ranges":[{"startOffset":496351,"endOffset":496625,"count":0}],"isBlockCoverage":false},{"functionName":"rootLength$2$withDrive","ranges":[{"startOffset":496655,"endOffset":497605,"count":0}],"isBlockCoverage":false},{"functionName":"rootLength$1","ranges":[{"startOffset":497625,"endOffset":497702,"count":0}],"isBlockCoverage":false},{"functionName":"isRootRelative$1","ranges":[{"startOffset":497726,"endOffset":497817,"count":0}],"isBlockCoverage":false},{"functionName":"pathFromUri$1","ranges":[{"startOffset":497838,"endOffset":497892,"count":0}],"isBlockCoverage":false},{"functionName":"relativePathToUri$1","ranges":[{"startOffset":497919,"endOffset":497973,"count":0}],"isBlockCoverage":false},{"functionName":"absolutePathToUri$1","ranges":[{"startOffset":498000,"endOffset":498054,"count":0}],"isBlockCoverage":false},{"functionName":"get$name","ranges":[{"startOffset":498070,"endOffset":498120,"count":0}],"isBlockCoverage":false},{"functionName":"get$separator","ranges":[{"startOffset":498141,"endOffset":498188,"count":0}],"isBlockCoverage":false},{"functionName":"containsSeparator$1","ranges":[{"startOffset":498250,"endOffset":498327,"count":0}],"isBlockCoverage":false},{"functionName":"isSeparator$1","ranges":[{"startOffset":498348,"endOffset":498423,"count":0}],"isBlockCoverage":false},{"functionName":"needsSeparator$1","ranges":[{"startOffset":498447,"endOffset":498622,"count":0}],"isBlockCoverage":false},{"functionName":"rootLength$2$withDrive","ranges":[{"startOffset":498652,"endOffset":499519,"count":0}],"isBlockCoverage":false},{"functionName":"rootLength$1","ranges":[{"startOffset":499539,"endOffset":499616,"count":0}],"isBlockCoverage":false},{"functionName":"isRootRelative$1","ranges":[{"startOffset":499640,"endOffset":499706,"count":0}],"isBlockCoverage":false},{"functionName":"pathFromUri$1","ranges":[{"startOffset":499727,"endOffset":500380,"count":0}],"isBlockCoverage":false},{"functionName":"absolutePathToUri$1","ranges":[{"startOffset":500407,"endOffset":501556,"count":0}],"isBlockCoverage":false},{"functionName":"codeUnitsEqual$2","ranges":[{"startOffset":501580,"endOffset":501969,"count":0}],"isBlockCoverage":false},{"functionName":"pathsEqual$2","ranges":[{"startOffset":501989,"endOffset":502379,"count":0}],"isBlockCoverage":false},{"functionName":"get$name","ranges":[{"startOffset":502395,"endOffset":502445,"count":0}],"isBlockCoverage":false},{"functionName":"get$separator","ranges":[{"startOffset":502466,"endOffset":502513,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":502588,"endOffset":502655,"count":0}],"isBlockCoverage":false},{"functionName":"toTrace$0","ranges":[{"startOffset":502719,"endOffset":503068,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":503086,"endOffset":503628,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":503712,"endOffset":503885,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":503968,"endOffset":504053,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":504131,"endOffset":504223,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":504303,"endOffset":504679,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":504760,"endOffset":504879,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":504958,"endOffset":505296,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":505376,"endOffset":505558,"count":0}],"isBlockCoverage":false},{"functionName":"get$isCore","ranges":[{"startOffset":505624,"endOffset":505689,"count":0}],"isBlockCoverage":false},{"functionName":"get$library","ranges":[{"startOffset":505708,"endOffset":505863,"count":0}],"isBlockCoverage":false},{"functionName":"get$$package","ranges":[{"startOffset":505883,"endOffset":506053,"count":0}],"isBlockCoverage":false},{"functionName":"get$location","ranges":[{"startOffset":506073,"endOffset":506361,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":506379,"endOffset":506469,"count":0}],"isBlockCoverage":false},{"functionName":"get$uri","ranges":[{"startOffset":506484,"endOffset":506525,"count":0}],"isBlockCoverage":false},{"functionName":"get$line","ranges":[{"startOffset":506541,"endOffset":506583,"count":0}],"isBlockCoverage":false},{"functionName":"get$column","ranges":[{"startOffset":506601,"endOffset":506645,"count":0}],"isBlockCoverage":false},{"functionName":"get$member","ranges":[{"startOffset":506663,"endOffset":506707,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":506771,"endOffset":507825,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":507908,"endOffset":508742,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":508839,"endOffset":509859,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":509948,"endOffset":511172,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":511261,"endOffset":512805,"count":0}],"isBlockCoverage":false},{"functionName":"get$_trace","ranges":[{"startOffset":512874,"endOffset":513090,"count":0}],"isBlockCoverage":false},{"functionName":"get$frames","ranges":[{"startOffset":513108,"endOffset":513171,"count":0}],"isBlockCoverage":false},{"functionName":"get$terse","ranges":[{"startOffset":513188,"endOffset":513273,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":513291,"endOffset":513357,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":513456,"endOffset":513524,"count":0}],"isBlockCoverage":false},{"functionName":"get$terse","ranges":[{"startOffset":513589,"endOffset":513680,"count":0}],"isBlockCoverage":false},{"functionName":"foldFrames$2$terse","ranges":[{"startOffset":513706,"endOffset":515185,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":515203,"endOffset":515689,"count":0}],"isBlockCoverage":false},{"functionName":"get$frames","ranges":[{"startOffset":515729,"endOffset":515773,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":515834,"endOffset":515912,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":515991,"endOffset":516074,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":516151,"endOffset":516253,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":516331,"endOffset":516414,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":516495,"endOffset":516567,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":516649,"endOffset":516732,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":516814,"endOffset":516927,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":517010,"endOffset":517098,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":517181,"endOffset":517269,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":517353,"endOffset":517442,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":517517,"endOffset":517556,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":517637,"endOffset":517967,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":518049,"endOffset":518442,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":518522,"endOffset":518641,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":518720,"endOffset":518989,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":519063,"endOffset":519108,"count":0}],"isBlockCoverage":false},{"functionName":"get$uri","ranges":[{"startOffset":519140,"endOffset":519181,"count":0}],"isBlockCoverage":false},{"functionName":"get$line","ranges":[{"startOffset":519197,"endOffset":519239,"count":0}],"isBlockCoverage":false},{"functionName":"get$column","ranges":[{"startOffset":519257,"endOffset":519301,"count":0}],"isBlockCoverage":false},{"functionName":"get$isCore","ranges":[{"startOffset":519319,"endOffset":519363,"count":0}],"isBlockCoverage":false},{"functionName":"get$library","ranges":[{"startOffset":519382,"endOffset":519427,"count":0}],"isBlockCoverage":false},{"functionName":"get$$package","ranges":[{"startOffset":519447,"endOffset":519493,"count":0}],"isBlockCoverage":false},{"functionName":"get$location","ranges":[{"startOffset":519513,"endOffset":519567,"count":0}],"isBlockCoverage":false},{"functionName":"get$member","ranges":[{"startOffset":519585,"endOffset":519629,"count":0}],"isBlockCoverage":false},{"functionName":"GuaranteeChannel$3$allowSinkErrors","ranges":[{"startOffset":519710,"endOffset":520046,"count":1}],"isBlockCoverage":true},{"functionName":"_onSinkDisconnected$0","ranges":[{"startOffset":520075,"endOffset":520266,"count":0}],"isBlockCoverage":false},{"functionName":"set$_sink","ranges":[{"startOffset":520283,"endOffset":520401,"count":1}],"isBlockCoverage":true},{"functionName":"set$_streamController","ranges":[{"startOffset":520430,"endOffset":520588,"count":1}],"isBlockCoverage":true},{"functionName":"set$_guarantee_channel$_subscription","ranges":[{"startOffset":520632,"endOffset":520801,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":520862,"endOffset":521185,"count":1},{"startOffset":520956,"endOffset":520963,"count":0}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":521266,"endOffset":521392,"count":0}],"isBlockCoverage":false},{"functionName":"add$1","ranges":[{"startOffset":521510,"endOffset":522038,"count":1},{"startOffset":521653,"endOffset":521725,"count":0},{"startOffset":521781,"endOffset":521859,"count":0},{"startOffset":521898,"endOffset":521905,"count":0}],"isBlockCoverage":true},{"functionName":"addError$2","ranges":[{"startOffset":522056,"endOffset":522478,"count":0}],"isBlockCoverage":false},{"functionName":"addError$1","ranges":[{"startOffset":522496,"endOffset":522562,"count":0}],"isBlockCoverage":false},{"functionName":"_addError$2","ranges":[{"startOffset":522581,"endOffset":522735,"count":0}],"isBlockCoverage":false},{"functionName":"_addError$1","ranges":[{"startOffset":522754,"endOffset":522821,"count":0}],"isBlockCoverage":false},{"functionName":"addStream$1","ranges":[{"startOffset":522840,"endOffset":523722,"count":1},{"startOffset":522976,"endOffset":523049,"count":0},{"startOffset":523105,"endOffset":523184,"count":0},{"startOffset":523215,"endOffset":523334,"count":0}],"isBlockCoverage":true},{"functionName":"close$0","ranges":[{"startOffset":523737,"endOffset":524196,"count":0}],"isBlockCoverage":false},{"functionName":"_onStreamDisconnected$0","ranges":[{"startOffset":524227,"endOffset":524597,"count":0}],"isBlockCoverage":false},{"functionName":"set$_addStreamSubscription","ranges":[{"startOffset":524631,"endOffset":524808,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":524925,"endOffset":525051,"count":0}],"isBlockCoverage":false},{"functionName":"_MultiChannel$1","ranges":[{"startOffset":525129,"endOffset":525778,"count":1}],"isBlockCoverage":true},{"functionName":"virtualChannel$1","ranges":[{"startOffset":525802,"endOffset":527448,"count":1},{"startOffset":526029,"endOffset":526206,"count":0},{"startOffset":526253,"endOffset":526477,"count":0},{"startOffset":526530,"endOffset":526575,"count":0},{"startOffset":526702,"endOffset":526803,"count":0}],"isBlockCoverage":true},{"functionName":"_closeChannel$2","ranges":[{"startOffset":527471,"endOffset":527872,"count":0}],"isBlockCoverage":false},{"functionName":"_closeInnerChannel$0","ranges":[{"startOffset":527900,"endOffset":528350,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":528432,"endOffset":528620,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":528638,"endOffset":528705,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":528764,"endOffset":528829,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":528956,"endOffset":529518,"count":1},{"startOffset":529164,"endOffset":529171,"count":0},{"startOffset":529457,"endOffset":529512,"count":0}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":529596,"endOffset":529733,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":529751,"endOffset":529835,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":529908,"endOffset":530159,"count":1}],"isBlockCoverage":true},{"functionName":"$signature","ranges":[{"startOffset":530177,"endOffset":530277,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":530351,"endOffset":530463,"count":0}],"isBlockCoverage":false},{"functionName":"get$local","ranges":[{"startOffset":530647,"endOffset":530691,"count":0}],"isBlockCoverage":false},{"functionName":"set$_local","ranges":[{"startOffset":530709,"endOffset":530828,"count":1}],"isBlockCoverage":true},{"functionName":"set$_foreign","ranges":[{"startOffset":530848,"endOffset":530973,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":531139,"endOffset":532002,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":532120,"endOffset":533385,"count":1},{"startOffset":532816,"endOffset":533379,"count":0}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":533455,"endOffset":533696,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":533767,"endOffset":534167,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":534238,"endOffset":534587,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":534706,"endOffset":534887,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":535005,"endOffset":535323,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":535453,"endOffset":535766,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":535848,"endOffset":535966,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":536046,"endOffset":537326,"count":1},{"startOffset":536265,"endOffset":536272,"count":0},{"startOffset":536472,"endOffset":536479,"count":0},{"startOffset":536965,"endOffset":537320,"count":0}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":537408,"endOffset":537676,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":537758,"endOffset":538685,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":537952,"endOffset":538612,"count":1},{"startOffset":538042,"endOffset":538098,"count":0}],"isBlockCoverage":true},{"functionName":"aliases","ranges":[{"startOffset":538714,"endOffset":539149,"count":1}],"isBlockCoverage":true},{"functionName":"installTearOffs","ranges":[{"startOffset":539157,"endOffset":544148,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":540050,"endOffset":540089,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":540135,"endOffset":540205,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":540496,"endOffset":540593,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":540702,"endOffset":540820,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":540931,"endOffset":541070,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":541195,"endOffset":541305,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":541440,"endOffset":541561,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":541698,"endOffset":541826,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":542583,"endOffset":542622,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":542757,"endOffset":542796,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":542921,"endOffset":542960,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":543161,"endOffset":543200,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":543660,"endOffset":543699,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":543800,"endOffset":543839,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":544079,"endOffset":544134,"count":0}],"isBlockCoverage":false},{"functionName":"inheritance","ranges":[{"startOffset":544156,"endOffset":556574,"count":1}],"isBlockCoverage":true},{"functionName":"constants","ranges":[{"startOffset":556582,"endOffset":566012,"count":1}],"isBlockCoverage":true},{"functionName":"getTagFallback","ranges":[{"startOffset":557622,"endOffset":557736,"count":0}],"isBlockCoverage":false},{"functionName":"C.C_JS_CONST0","ranges":[{"startOffset":557758,"endOffset":558873,"count":1},{"startOffset":558781,"endOffset":558796,"count":0}],"isBlockCoverage":true},{"functionName":"getTag","ranges":[{"startOffset":557825,"endOffset":557928,"count":0}],"isBlockCoverage":false},{"functionName":"getUnknownTag","ranges":[{"startOffset":557931,"endOffset":558148,"count":0}],"isBlockCoverage":false},{"functionName":"getUnknownTagGenericBrowser","ranges":[{"startOffset":558151,"endOffset":558326,"count":0}],"isBlockCoverage":false},{"functionName":"prototypeForTag","ranges":[{"startOffset":558329,"endOffset":558595,"count":1},{"startOffset":558399,"endOffset":558411,"count":0},{"startOffset":558545,"endOffset":558557,"count":0}],"isBlockCoverage":true},{"functionName":"discriminator","ranges":[{"startOffset":558598,"endOffset":558642,"count":0}],"isBlockCoverage":false},{"functionName":"C.C_JS_CONST6","ranges":[{"startOffset":558895,"endOffset":559359,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":558931,"endOffset":559356,"count":1},{"startOffset":558987,"endOffset":559000,"count":0},{"startOffset":559078,"endOffset":559091,"count":0},{"startOffset":559317,"endOffset":559355,"count":0}],"isBlockCoverage":true},{"functionName":"confirm","ranges":[{"startOffset":559135,"endOffset":559242,"count":1}],"isBlockCoverage":true},{"functionName":"C.C_JS_CONST1","ranges":[{"startOffset":559381,"endOffset":559530,"count":1},{"startOffset":559468,"endOffset":559529,"count":0}],"isBlockCoverage":true},{"functionName":"C.C_JS_CONST2","ranges":[{"startOffset":559552,"endOffset":560025,"count":1}],"isBlockCoverage":true},{"functionName":"getTagFixed","ranges":[{"startOffset":559648,"endOffset":559829,"count":0}],"isBlockCoverage":false},{"functionName":"prototypeForTagFixed","ranges":[{"startOffset":559832,"endOffset":559945,"count":1}],"isBlockCoverage":true},{"functionName":"C.C_JS_CONST5","ranges":[{"startOffset":560047,"endOffset":560577,"count":1},{"startOffset":560134,"endOffset":560138,"count":0},{"startOffset":560195,"endOffset":560576,"count":0}],"isBlockCoverage":true},{"functionName":"getTagFirefox","ranges":[{"startOffset":560454,"endOffset":560543,"count":0}],"isBlockCoverage":false},{"functionName":"C.C_JS_CONST4","ranges":[{"startOffset":560599,"endOffset":561481,"count":1},{"startOffset":560686,"endOffset":560690,"count":0},{"startOffset":560748,"endOffset":561480,"count":0}],"isBlockCoverage":true},{"functionName":"getTagIE","ranges":[{"startOffset":561013,"endOffset":561256,"count":0}],"isBlockCoverage":false},{"functionName":"prototypeForTagIE","ranges":[{"startOffset":561259,"endOffset":561407,"count":0}],"isBlockCoverage":false},{"functionName":"C.C_JS_CONST3","ranges":[{"startOffset":561503,"endOffset":561536,"count":1}],"isBlockCoverage":true},{"functionName":"staticFields","ranges":[{"startOffset":566020,"endOffset":566720,"count":1}],"isBlockCoverage":true},{"functionName":"lazyInitializers","ranges":[{"startOffset":566728,"endOffset":575683,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":566870,"endOffset":566948,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":567029,"endOffset":567098,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":567199,"endOffset":567387,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":567484,"endOffset":567687,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":567780,"endOffset":567891,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":567998,"endOffset":568249,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":568352,"endOffset":568465,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":568582,"endOffset":568837,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":568938,"endOffset":569053,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":569168,"endOffset":569357,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":569468,"endOffset":569585,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":569710,"endOffset":569903,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":570002,"endOffset":570077,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":570142,"endOffset":570223,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":570288,"endOffset":570350,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":570413,"endOffset":570448,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":570517,"endOffset":570578,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":570669,"endOffset":571283,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":571354,"endOffset":571512,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":571583,"endOffset":571664,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":571721,"endOffset":571771,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":571814,"endOffset":571888,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":571931,"endOffset":572008,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":572059,"endOffset":572220,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":572275,"endOffset":572548,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":572595,"endOffset":572849,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":572906,"endOffset":572966,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":573011,"endOffset":573116,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":573161,"endOffset":573279,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":573336,"endOffset":573422,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":573481,"endOffset":573591,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":573658,"endOffset":573797,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":573854,"endOffset":573959,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":574008,"endOffset":574107,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":574158,"endOffset":574221,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":574282,"endOffset":574368,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":574437,"endOffset":574524,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":574577,"endOffset":574658,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":574703,"endOffset":574773,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":574826,"endOffset":574893,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":574960,"endOffset":575064,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":575121,"endOffset":575225,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":575270,"endOffset":575364,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":575421,"endOffset":575534,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":575585,"endOffset":575677,"count":1}],"isBlockCoverage":true},{"functionName":"nativeSupport","ranges":[{"startOffset":579591,"endOffset":596530,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":579623,"endOffset":580408,"count":1},{"startOffset":580311,"endOffset":580407,"count":0}],"isBlockCoverage":true},{"functionName":"intern","ranges":[{"startOffset":579655,"endOffset":579781,"count":1}],"isBlockCoverage":true},{"functionName":"init.getIsolateTag","ranges":[{"startOffset":579810,"endOffset":579894,"count":1}],"isBlockCoverage":true},{"functionName":"Function.call$0","ranges":[{"startOffset":596565,"endOffset":596600,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$1","ranges":[{"startOffset":596632,"endOffset":596669,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$2","ranges":[{"startOffset":596701,"endOffset":596744,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$3","ranges":[{"startOffset":596776,"endOffset":596825,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$4","ranges":[{"startOffset":596857,"endOffset":596912,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$1$1","ranges":[{"startOffset":596946,"endOffset":596983,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$3$1","ranges":[{"startOffset":597017,"endOffset":597054,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$3$3","ranges":[{"startOffset":597088,"endOffset":597137,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$2$2","ranges":[{"startOffset":597171,"endOffset":597214,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$2$1","ranges":[{"startOffset":597248,"endOffset":597285,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$2$3","ranges":[{"startOffset":597319,"endOffset":597368,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$1$2","ranges":[{"startOffset":597402,"endOffset":597445,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$5","ranges":[{"startOffset":597477,"endOffset":597538,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$3$4","ranges":[{"startOffset":597572,"endOffset":597627,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$2$4","ranges":[{"startOffset":597661,"endOffset":597716,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$1$4","ranges":[{"startOffset":597750,"endOffset":597805,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$3$6","ranges":[{"startOffset":597839,"endOffset":597906,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$2$5","ranges":[{"startOffset":597940,"endOffset":598001,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":598067,"endOffset":598606,"count":1},{"startOffset":598129,"endOffset":598227,"count":0},{"startOffset":598282,"endOffset":598605,"count":0}],"isBlockCoverage":true},{"functionName":"onLoad","ranges":[{"startOffset":598329,"endOffset":598499,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":598608,"endOffset":598784,"count":1},{"startOffset":598726,"endOffset":598753,"count":0}],"isBlockCoverage":true}]},{"scriptId":"6","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":276,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":275,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff_completeError$20","ranges":[{"startOffset":82,"endOffset":273,"count":0}],"isBlockCoverage":false}]},{"scriptId":"7","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":282,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":281,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff_complete$11","ranges":[{"startOffset":82,"endOffset":279,"count":1}],"isBlockCoverage":true}]},{"scriptId":"8","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":277,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":276,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff__completeError$22","ranges":[{"startOffset":82,"endOffset":274,"count":0}],"isBlockCoverage":false}]},{"scriptId":"9","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":277,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":276,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff_add$13","ranges":[{"startOffset":82,"endOffset":274,"count":1}],"isBlockCoverage":true}]},{"scriptId":"10","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":271,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":270,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff_addError$24","ranges":[{"startOffset":82,"endOffset":268,"count":1}],"isBlockCoverage":true}]},{"scriptId":"11","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":277,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":276,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff_add$15","ranges":[{"startOffset":82,"endOffset":274,"count":1}],"isBlockCoverage":true}]},{"scriptId":"12","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":272,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":271,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff__sendDone$06","ranges":[{"startOffset":82,"endOffset":269,"count":0}],"isBlockCoverage":false}]},{"scriptId":"13","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":271,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":270,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff_addError$27","ranges":[{"startOffset":82,"endOffset":268,"count":1}],"isBlockCoverage":true}]},{"scriptId":"14","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":272,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":271,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff__addError$28","ranges":[{"startOffset":82,"endOffset":269,"count":1}],"isBlockCoverage":true}]},{"scriptId":"15","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":281,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":280,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff__closeInnerChannel$09","ranges":[{"startOffset":82,"endOffset":278,"count":1}],"isBlockCoverage":true}]},{"scriptId":"16","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":62,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":61,"count":1}],"isBlockCoverage":true}]},{"scriptId":"17","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":92,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":91,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":32,"endOffset":89,"count":1},{"startOffset":87,"endOffset":88,"count":0}],"isBlockCoverage":true}]},{"scriptId":"18","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":62,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":61,"count":1}],"isBlockCoverage":true}]},{"scriptId":"19","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":86,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":85,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":32,"endOffset":83,"count":0}],"isBlockCoverage":false}]},{"scriptId":"20","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":62,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":61,"count":1}],"isBlockCoverage":true}]},{"scriptId":"21","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":106,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":105,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":32,"endOffset":103,"count":0}],"isBlockCoverage":false}]},{"scriptId":"22","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":62,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":61,"count":1}],"isBlockCoverage":true}]},{"scriptId":"23","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":86,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":85,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":32,"endOffset":83,"count":0}],"isBlockCoverage":false}]},{"scriptId":"24","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":62,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":61,"count":1}],"isBlockCoverage":true}]},{"scriptId":"25","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":92,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":91,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":32,"endOffset":89,"count":1},{"startOffset":87,"endOffset":88,"count":0}],"isBlockCoverage":true}]},{"scriptId":"26","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":64,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":63,"count":1}],"isBlockCoverage":true}]},{"scriptId":"27","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":98,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":97,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":32,"endOffset":95,"count":0}],"isBlockCoverage":false}]},{"scriptId":"28","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":64,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":63,"count":1}],"isBlockCoverage":true}]},{"scriptId":"29","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":89,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":88,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":32,"endOffset":86,"count":0}],"isBlockCoverage":false}]},{"scriptId":"30","url":"http://localhost:33587/JvrQonmMf3ATS3rRCO76ZTlBfGvy%2Fj69/test/packages/test/dart.js","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":2011,"count":1}],"isBlockCoverage":true},{"functionName":"window.onload","ranges":[{"startOffset":384,"endOffset":2009,"count":1},{"startOffset":1295,"endOffset":1442,"count":0},{"startOffset":1491,"endOffset":1629,"count":0}],"isBlockCoverage":true},{"functionName":"sendLoadException","ranges":[{"startOffset":560,"endOffset":762,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":875,"endOffset":921,"count":0}],"isBlockCoverage":false},{"functionName":"script.onerror","ranges":[{"startOffset":1747,"endOffset":1907,"count":0}],"isBlockCoverage":false}]},{"scriptId":"31","url":"http://localhost:33587/JvrQonmMf3ATS3rRCO76ZTlBfGvy%2Fj69/test/main_test.dart.browser_test.dart.js","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":1081547,"count":1}],"isBlockCoverage":true},{"functionName":"dartProgram","ranges":[{"startOffset":1051,"endOffset":1081480,"count":1}],"isBlockCoverage":true},{"functionName":"copyProperties","ranges":[{"startOffset":1078,"endOffset":1253,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1288,"endOffset":1858,"count":1},{"startOffset":1469,"endOffset":1482,"count":0},{"startOffset":1645,"endOffset":1707,"count":0},{"startOffset":1709,"endOffset":1812,"count":0},{"startOffset":1818,"endOffset":1857,"count":0}],"isBlockCoverage":true},{"functionName":"cls","ranges":[{"startOffset":1315,"endOffset":1333,"count":1}],"isBlockCoverage":true},{"functionName":"setFunctionNamesIfNecessary","ranges":[{"startOffset":1864,"endOffset":2287,"count":1},{"startOffset":1991,"endOffset":2283,"count":0}],"isBlockCoverage":true},{"functionName":"t","ranges":[{"startOffset":1916,"endOffset":1936,"count":0}],"isBlockCoverage":false},{"functionName":"inherit","ranges":[{"startOffset":2290,"endOffset":2685,"count":1},{"startOffset":2533,"endOffset":2681,"count":0}],"isBlockCoverage":true},{"functionName":"inheritMany","ranges":[{"startOffset":2688,"endOffset":2805,"count":1}],"isBlockCoverage":true},{"functionName":"mixin","ranges":[{"startOffset":2808,"endOffset":2929,"count":1}],"isBlockCoverage":true},{"functionName":"lazy","ranges":[{"startOffset":2932,"endOffset":3681,"count":1}],"isBlockCoverage":true},{"functionName":"holder.<computed>","ranges":[{"startOffset":3094,"endOffset":3676,"count":1},{"startOffset":3429,"endOffset":3467,"count":0},{"startOffset":3539,"endOffset":3559,"count":0}],"isBlockCoverage":true},{"functionName":"holder.<computed>","ranges":[{"startOffset":3134,"endOffset":3187,"count":0}],"isBlockCoverage":false},{"functionName":"holder.<computed>","ranges":[{"startOffset":3589,"endOffset":3640,"count":1}],"isBlockCoverage":true},{"functionName":"makeConstList","ranges":[{"startOffset":3684,"endOffset":3799,"count":1}],"isBlockCoverage":true},{"functionName":"convertToFastObject","ranges":[{"startOffset":3802,"endOffset":3939,"count":1}],"isBlockCoverage":true},{"functionName":"t","ranges":[{"startOffset":3849,"endOffset":3869,"count":1}],"isBlockCoverage":true},{"functionName":"convertAllToFastObject","ranges":[{"startOffset":3942,"endOffset":4093,"count":1}],"isBlockCoverage":true},{"functionName":"tearOffGetter","ranges":[{"startOffset":4123,"endOffset":5038,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff","ranges":[{"startOffset":5041,"endOffset":5449,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":5180,"endOffset":5362,"count":1}],"isBlockCoverage":true},{"functionName":"installTearOff","ranges":[{"startOffset":5475,"endOffset":6389,"count":1}],"isBlockCoverage":true},{"functionName":"installStaticTearOff","ranges":[{"startOffset":6392,"endOffset":6715,"count":1}],"isBlockCoverage":true},{"functionName":"installInstanceTearOff","ranges":[{"startOffset":6718,"endOffset":7067,"count":1}],"isBlockCoverage":true},{"functionName":"setOrUpdateInterceptorsByTag","ranges":[{"startOffset":7070,"endOffset":7273,"count":1},{"startOffset":7234,"endOffset":7272,"count":0}],"isBlockCoverage":true},{"functionName":"setOrUpdateLeafTags","ranges":[{"startOffset":7276,"endOffset":7452,"count":1},{"startOffset":7413,"endOffset":7451,"count":0}],"isBlockCoverage":true},{"functionName":"updateTypes","ranges":[{"startOffset":7455,"endOffset":7608,"count":0}],"isBlockCoverage":false},{"functionName":"updateHolder","ranges":[{"startOffset":7611,"endOffset":7715,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":7736,"endOffset":9400,"count":1}],"isBlockCoverage":true},{"functionName":"mkInstance","ranges":[{"startOffset":7770,"endOffset":8132,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":7890,"endOffset":8123,"count":1}],"isBlockCoverage":true},{"functionName":"mkStatic","ranges":[{"startOffset":8151,"endOffset":8481,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":8256,"endOffset":8472,"count":1}],"isBlockCoverage":true},{"functionName":"initializeDeferredHunk","ranges":[{"startOffset":9406,"endOffset":9527,"count":0}],"isBlockCoverage":false},{"functionName":"getGlobalFromName","ranges":[{"startOffset":9530,"endOffset":9727,"count":0}],"isBlockCoverage":false},{"functionName":"JS_CONST","ranges":[{"startOffset":9759,"endOffset":9786,"count":0}],"isBlockCoverage":false},{"functionName":"CastIterable_CastIterable","ranges":[{"startOffset":9819,"endOffset":10153,"count":1},{"startOffset":10045,"endOffset":10152,"count":0}],"isBlockCoverage":true},{"functionName":"hexDigitValue","ranges":[{"startOffset":10174,"endOffset":10439,"count":0}],"isBlockCoverage":false},{"functionName":"SubListIterable$","ranges":[{"startOffset":10463,"endOffset":10899,"count":0}],"isBlockCoverage":false},{"functionName":"MappedIterable_MappedIterable","ranges":[{"startOffset":10936,"endOffset":11314,"count":0}],"isBlockCoverage":false},{"functionName":"IterableElementError_noElement","ranges":[{"startOffset":11352,"endOffset":11415,"count":0}],"isBlockCoverage":false},{"functionName":"IterableElementError_tooMany","ranges":[{"startOffset":11451,"endOffset":11521,"count":0}],"isBlockCoverage":false},{"functionName":"IterableElementError_tooFew","ranges":[{"startOffset":11556,"endOffset":11625,"count":0}],"isBlockCoverage":false},{"functionName":"_CastIterableBase","ranges":[{"startOffset":11650,"endOffset":11686,"count":0}],"isBlockCoverage":false},{"functionName":"CastIterator","ranges":[{"startOffset":11706,"endOffset":11789,"count":1}],"isBlockCoverage":true},{"functionName":"CastIterable","ranges":[{"startOffset":11809,"endOffset":11892,"count":0}],"isBlockCoverage":false},{"functionName":"_EfficientLengthCastIterable","ranges":[{"startOffset":11928,"endOffset":12027,"count":1}],"isBlockCoverage":true},{"functionName":"CastMap","ranges":[{"startOffset":12042,"endOffset":12120,"count":1}],"isBlockCoverage":true},{"functionName":"CastMap_forEach_closure","ranges":[{"startOffset":12151,"endOffset":12241,"count":0}],"isBlockCoverage":false},{"functionName":"CodeUnits","ranges":[{"startOffset":12258,"endOffset":12313,"count":0}],"isBlockCoverage":false},{"functionName":"EfficientLengthIterable","ranges":[{"startOffset":12344,"endOffset":12386,"count":0}],"isBlockCoverage":false},{"functionName":"ListIterable","ranges":[{"startOffset":12406,"endOffset":12437,"count":0}],"isBlockCoverage":false},{"functionName":"SubListIterable","ranges":[{"startOffset":12460,"endOffset":12640,"count":0}],"isBlockCoverage":false},{"functionName":"ListIterator","ranges":[{"startOffset":12660,"endOffset":12874,"count":1}],"isBlockCoverage":true},{"functionName":"MappedIterable","ranges":[{"startOffset":12896,"endOffset":13018,"count":1}],"isBlockCoverage":true},{"functionName":"EfficientLengthMappedIterable","ranges":[{"startOffset":13055,"endOffset":13192,"count":0}],"isBlockCoverage":false},{"functionName":"MappedIterator","ranges":[{"startOffset":13214,"endOffset":13372,"count":1}],"isBlockCoverage":true},{"functionName":"MappedListIterable","ranges":[{"startOffset":13398,"endOffset":13511,"count":1}],"isBlockCoverage":true},{"functionName":"WhereIterable","ranges":[{"startOffset":13532,"endOffset":13653,"count":1}],"isBlockCoverage":true},{"functionName":"WhereIterator","ranges":[{"startOffset":13674,"endOffset":13784,"count":1}],"isBlockCoverage":true},{"functionName":"ExpandIterable","ranges":[{"startOffset":13806,"endOffset":13928,"count":0}],"isBlockCoverage":false},{"functionName":"ExpandIterator","ranges":[{"startOffset":13950,"endOffset":14144,"count":0}],"isBlockCoverage":false},{"functionName":"SkipWhileIterable","ranges":[{"startOffset":14169,"endOffset":14294,"count":0}],"isBlockCoverage":false},{"functionName":"SkipWhileIterator","ranges":[{"startOffset":14319,"endOffset":14473,"count":0}],"isBlockCoverage":false},{"functionName":"EmptyIterator","ranges":[{"startOffset":14494,"endOffset":14549,"count":1}],"isBlockCoverage":true},{"functionName":"FixedLengthListMixin","ranges":[{"startOffset":14577,"endOffset":14616,"count":0}],"isBlockCoverage":false},{"functionName":"UnmodifiableListMixin","ranges":[{"startOffset":14645,"endOffset":14685,"count":0}],"isBlockCoverage":false},{"functionName":"UnmodifiableListBase","ranges":[{"startOffset":14713,"endOffset":14752,"count":0}],"isBlockCoverage":false},{"functionName":"ReversedListIterable","ranges":[{"startOffset":14780,"endOffset":14871,"count":1}],"isBlockCoverage":true},{"functionName":"Symbol","ranges":[{"startOffset":14885,"endOffset":14946,"count":1}],"isBlockCoverage":true},{"functionName":"ConstantMap__throwUnmodifiable","ranges":[{"startOffset":14984,"endOffset":15086,"count":0}],"isBlockCoverage":false},{"functionName":"instantiate1","ranges":[{"startOffset":15106,"endOffset":15248,"count":0}],"isBlockCoverage":false},{"functionName":"unminifyOrTag","ranges":[{"startOffset":15269,"endOffset":15468,"count":0}],"isBlockCoverage":false},{"functionName":"isJsIndexable","ranges":[{"startOffset":15489,"endOffset":15722,"count":0}],"isBlockCoverage":false},{"functionName":"S","ranges":[{"startOffset":15731,"endOffset":16230,"count":1},{"startOffset":15821,"endOffset":16229,"count":0}],"isBlockCoverage":true},{"functionName":"Primitives_objectHashCode","ranges":[{"startOffset":16263,"endOffset":16463,"count":1}],"isBlockCoverage":true},{"functionName":"Primitives_parseInt","ranges":[{"startOffset":16490,"endOffset":17741,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_objectTypeName","ranges":[{"startOffset":17774,"endOffset":17874,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives__objectTypeNameNewRti","ranges":[{"startOffset":17914,"endOffset":18695,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives__saneNativeClassName","ranges":[{"startOffset":18734,"endOffset":18825,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_dateNow","ranges":[{"startOffset":18851,"endOffset":18894,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_initTicker","ranges":[{"startOffset":18923,"endOffset":19555,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_currentUri","ranges":[{"startOffset":19584,"endOffset":19683,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives__fromCharCodeApply","ranges":[{"startOffset":19720,"endOffset":20112,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_stringFromCodePoints","ranges":[{"startOffset":20151,"endOffset":20858,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_stringFromCharCodes","ranges":[{"startOffset":20896,"endOffset":21417,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_stringFromNativeUint8List","ranges":[{"startOffset":21461,"endOffset":21888,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_stringFromCharCode","ranges":[{"startOffset":21925,"endOffset":22438,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_lazyAsJsDate","ranges":[{"startOffset":22469,"endOffset":22610,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_getYear","ranges":[{"startOffset":22636,"endOffset":22752,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_getMonth","ranges":[{"startOffset":22779,"endOffset":22892,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_getDay","ranges":[{"startOffset":22917,"endOffset":23029,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_getHours","ranges":[{"startOffset":23056,"endOffset":23169,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_getMinutes","ranges":[{"startOffset":23198,"endOffset":23313,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_getSeconds","ranges":[{"startOffset":23342,"endOffset":23457,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_getMilliseconds","ranges":[{"startOffset":23491,"endOffset":23611,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_getProperty","ranges":[{"startOffset":23641,"endOffset":23862,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_setProperty","ranges":[{"startOffset":23892,"endOffset":24121,"count":0}],"isBlockCoverage":false},{"functionName":"iae","ranges":[{"startOffset":24132,"endOffset":24219,"count":0}],"isBlockCoverage":false},{"functionName":"ioore","ranges":[{"startOffset":24232,"endOffset":24397,"count":0}],"isBlockCoverage":false},{"functionName":"diagnoseIndexError","ranges":[{"startOffset":24423,"endOffset":24943,"count":0}],"isBlockCoverage":false},{"functionName":"diagnoseRangeError","ranges":[{"startOffset":24969,"endOffset":25354,"count":0}],"isBlockCoverage":false},{"functionName":"argumentErrorValue","ranges":[{"startOffset":25380,"endOffset":25464,"count":0}],"isBlockCoverage":false},{"functionName":"checkNum","ranges":[{"startOffset":25480,"endOffset":25619,"count":0}],"isBlockCoverage":false},{"functionName":"wrapException","ranges":[{"startOffset":25640,"endOffset":26027,"count":0}],"isBlockCoverage":false},{"functionName":"toStringWrapper","ranges":[{"startOffset":26050,"endOffset":26116,"count":0}],"isBlockCoverage":false},{"functionName":"throwExpression","ranges":[{"startOffset":26139,"endOffset":26192,"count":0}],"isBlockCoverage":false},{"functionName":"throwConcurrentModificationError","ranges":[{"startOffset":26232,"endOffset":26333,"count":0}],"isBlockCoverage":false},{"functionName":"TypeErrorDecoder_extractPattern","ranges":[{"startOffset":26372,"endOffset":27376,"count":0}],"isBlockCoverage":false},{"functionName":"TypeErrorDecoder_provokeCallErrorOn","ranges":[{"startOffset":27419,"endOffset":27663,"count":0}],"isBlockCoverage":false},{"functionName":"TypeErrorDecoder_provokePropertyErrorOn","ranges":[{"startOffset":27710,"endOffset":27892,"count":0}],"isBlockCoverage":false},{"functionName":"NullError$","ranges":[{"startOffset":27910,"endOffset":28020,"count":0}],"isBlockCoverage":false},{"functionName":"JsNoSuchMethodError$","ranges":[{"startOffset":28048,"endOffset":28232,"count":0}],"isBlockCoverage":false},{"functionName":"unwrapException","ranges":[{"startOffset":28255,"endOffset":32748,"count":0}],"isBlockCoverage":false},{"functionName":"getTraceFromException","ranges":[{"startOffset":32777,"endOffset":33142,"count":1},{"startOffset":32881,"endOffset":32909,"count":0},{"startOffset":32947,"endOffset":32983,"count":0},{"startOffset":33055,"endOffset":33068,"count":0}],"isBlockCoverage":true},{"functionName":"objectHashCode","ranges":[{"startOffset":33164,"endOffset":33346,"count":1}],"isBlockCoverage":true},{"functionName":"fillLiteralMap","ranges":[{"startOffset":33368,"endOffset":33829,"count":1}],"isBlockCoverage":true},{"functionName":"fillLiteralSet","ranges":[{"startOffset":33851,"endOffset":34149,"count":1}],"isBlockCoverage":true},{"functionName":"invokeClosure","ranges":[{"startOffset":34170,"endOffset":34749,"count":1},{"startOffset":34441,"endOffset":34493,"count":0},{"startOffset":34502,"endOffset":34560,"count":0},{"startOffset":34569,"endOffset":34633,"count":0},{"startOffset":34641,"endOffset":34748,"count":0}],"isBlockCoverage":true},{"functionName":"convertDartClosureToJS","ranges":[{"startOffset":34779,"endOffset":35232,"count":1},{"startOffset":34862,"endOffset":34874,"count":0}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":34979,"endOffset":35131,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":35029,"endOffset":35122,"count":1}],"isBlockCoverage":true},{"functionName":"Closure_fromTearOff","ranges":[{"startOffset":35259,"endOffset":37399,"count":1},{"startOffset":36000,"endOffset":36017,"count":0},{"startOffset":37093,"endOffset":37187,"count":0}],"isBlockCoverage":true},{"functionName":"static_tear_off","ranges":[{"startOffset":35831,"endOffset":35899,"count":0}],"isBlockCoverage":false},{"functionName":"Closure__computeSignatureFunctionNewRti","ranges":[{"startOffset":37446,"endOffset":38243,"count":1},{"startOffset":37726,"endOffset":38242,"count":0}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":37580,"endOffset":37686,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":37620,"endOffset":37675,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":37997,"endOffset":38133,"count":0}],"isBlockCoverage":false},{"functionName":"Closure_cspForwardCall","ranges":[{"startOffset":38273,"endOffset":39658,"count":1},{"startOffset":38399,"endOffset":38406,"count":0},{"startOffset":38418,"endOffset":38573,"count":0},{"startOffset":38582,"endOffset":38739,"count":0},{"startOffset":38748,"endOffset":38911,"count":0},{"startOffset":38920,"endOffset":39089,"count":0},{"startOffset":39098,"endOffset":39273,"count":0},{"startOffset":39282,"endOffset":39463,"count":0}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":38443,"endOffset":38553,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":38607,"endOffset":38719,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":38773,"endOffset":38891,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":38945,"endOffset":39069,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":39123,"endOffset":39253,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":39307,"endOffset":39443,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":39498,"endOffset":39623,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":39534,"endOffset":39610,"count":0}],"isBlockCoverage":false},{"functionName":"Closure_forwardCallTo","ranges":[{"startOffset":39687,"endOffset":41342,"count":1},{"startOffset":40050,"endOffset":40076,"count":0},{"startOffset":40341,"endOffset":40358,"count":0},{"startOffset":40594,"endOffset":40672,"count":0},{"startOffset":40960,"endOffset":40977,"count":0},{"startOffset":41199,"endOffset":41277,"count":0}],"isBlockCoverage":true},{"functionName":"Closure_cspForwardInterceptedCall","ranges":[{"startOffset":41383,"endOffset":43149,"count":0}],"isBlockCoverage":false},{"functionName":"Closure_forwardInterceptedCallTo","ranges":[{"startOffset":43189,"endOffset":44760,"count":1},{"startOffset":43766,"endOffset":43792,"count":0},{"startOffset":43880,"endOffset":43956,"count":0},{"startOffset":44175,"endOffset":44192,"count":0},{"startOffset":44651,"endOffset":44668,"count":0}],"isBlockCoverage":true},{"functionName":"closureFromTearOff","ranges":[{"startOffset":44786,"endOffset":45024,"count":1}],"isBlockCoverage":true},{"functionName":"BoundClosure_evalRecipe","ranges":[{"startOffset":45055,"endOffset":45190,"count":0}],"isBlockCoverage":false},{"functionName":"BoundClosure_evalRecipeIntercepted","ranges":[{"startOffset":45232,"endOffset":45371,"count":0}],"isBlockCoverage":false},{"functionName":"BoundClosure_selfOf","ranges":[{"startOffset":45398,"endOffset":45451,"count":0}],"isBlockCoverage":false},{"functionName":"BoundClosure_receiverOf","ranges":[{"startOffset":45482,"endOffset":45539,"count":0}],"isBlockCoverage":false},{"functionName":"BoundClosure_computeFieldNamed","ranges":[{"startOffset":45577,"endOffset":45937,"count":1}],"isBlockCoverage":true},{"functionName":"boolConversionCheck","ranges":[{"startOffset":45964,"endOffset":46094,"count":1},{"startOffset":46015,"endOffset":46068,"count":0}],"isBlockCoverage":true},{"functionName":"extractFunctionTypeObjectFromInternal","ranges":[{"startOffset":46139,"endOffset":46420,"count":0}],"isBlockCoverage":false},{"functionName":"TypeErrorImplementation$","ranges":[{"startOffset":46452,"endOffset":46662,"count":0}],"isBlockCoverage":false},{"functionName":"_typeDescription","ranges":[{"startOffset":46686,"endOffset":47058,"count":0}],"isBlockCoverage":false},{"functionName":"assertTest","ranges":[{"startOffset":47076,"endOffset":47290,"count":1},{"startOffset":47149,"endOffset":47289,"count":0}],"isBlockCoverage":true},{"functionName":"assertThrow","ranges":[{"startOffset":47309,"endOffset":47395,"count":0}],"isBlockCoverage":false},{"functionName":"assertHelper","ranges":[{"startOffset":47415,"endOffset":47533,"count":1},{"startOffset":47480,"endOffset":47527,"count":0}],"isBlockCoverage":true},{"functionName":"throwCyclicInit","ranges":[{"startOffset":47556,"endOffset":47658,"count":0}],"isBlockCoverage":false},{"functionName":"RuntimeError$","ranges":[{"startOffset":47679,"endOffset":47746,"count":0}],"isBlockCoverage":false},{"functionName":"getIsolateAffinityTag","ranges":[{"startOffset":47775,"endOffset":47838,"count":0}],"isBlockCoverage":false},{"functionName":"setRuntimeTypeInfo","ranges":[{"startOffset":47864,"endOffset":47973,"count":1}],"isBlockCoverage":true},{"functionName":"getRuntimeTypeInfo","ranges":[{"startOffset":47999,"endOffset":48095,"count":0}],"isBlockCoverage":false},{"functionName":"getRuntimeTypeArguments","ranges":[{"startOffset":48126,"endOffset":48282,"count":0}],"isBlockCoverage":false},{"functionName":"runtimeTypeToString","ranges":[{"startOffset":48309,"endOffset":48378,"count":0}],"isBlockCoverage":false},{"functionName":"_runtimeTypeToString","ranges":[{"startOffset":48406,"endOffset":49897,"count":0}],"isBlockCoverage":false},{"functionName":"_functionRtiToString0","ranges":[{"startOffset":49926,"endOffset":52750,"count":0}],"isBlockCoverage":false},{"functionName":"_joinArguments","ranges":[{"startOffset":52772,"endOffset":53457,"count":0}],"isBlockCoverage":false},{"functionName":"getRuntimeType","ranges":[{"startOffset":53479,"endOffset":53665,"count":0}],"isBlockCoverage":false},{"functionName":"substitute","ranges":[{"startOffset":53683,"endOffset":54227,"count":0}],"isBlockCoverage":false},{"functionName":"computeSignature","ranges":[{"startOffset":54251,"endOffset":54444,"count":0}],"isBlockCoverage":false},{"functionName":"invokeOn","ranges":[{"startOffset":54460,"endOffset":54686,"count":0}],"isBlockCoverage":false},{"functionName":"defineProperty","ranges":[{"startOffset":54708,"endOffset":54861,"count":0}],"isBlockCoverage":false},{"functionName":"lookupAndCacheInterceptor","ranges":[{"startOffset":54894,"endOffset":57451,"count":0}],"isBlockCoverage":false},{"functionName":"patchInteriorProto","ranges":[{"startOffset":57477,"endOffset":57764,"count":0}],"isBlockCoverage":false},{"functionName":"makeLeafDispatchRecord","ranges":[{"startOffset":57794,"endOffset":57929,"count":1}],"isBlockCoverage":true},{"functionName":"makeDefaultDispatchRecord","ranges":[{"startOffset":57962,"endOffset":58233,"count":1}],"isBlockCoverage":true},{"functionName":"initNativeDispatch","ranges":[{"startOffset":58259,"endOffset":58415,"count":1},{"startOffset":58325,"endOffset":58332,"count":0}],"isBlockCoverage":true},{"functionName":"initNativeDispatchContinue","ranges":[{"startOffset":58449,"endOffset":59729,"count":1}],"isBlockCoverage":true},{"functionName":"fun","ranges":[{"startOffset":58828,"endOffset":58850,"count":0}],"isBlockCoverage":false},{"functionName":"initHooks","ranges":[{"startOffset":59746,"endOffset":61000,"count":1},{"startOffset":60255,"endOffset":60668,"count":0}],"isBlockCoverage":true},{"functionName":"applyHooksTransformer","ranges":[{"startOffset":61029,"endOffset":61107,"count":1}],"isBlockCoverage":true},{"functionName":"JSSyntaxRegExp_makeNative","ranges":[{"startOffset":61140,"endOffset":61765,"count":0}],"isBlockCoverage":false},{"functionName":"_MatchImplementation$","ranges":[{"startOffset":61794,"endOffset":61977,"count":0}],"isBlockCoverage":false},{"functionName":"stringContainsUnchecked","ranges":[{"startOffset":62008,"endOffset":62496,"count":0}],"isBlockCoverage":false},{"functionName":"escapeReplacement","ranges":[{"startOffset":62521,"endOffset":62671,"count":0}],"isBlockCoverage":false},{"functionName":"stringReplaceFirstRE","ranges":[{"startOffset":62699,"endOffset":62974,"count":0}],"isBlockCoverage":false},{"functionName":"quoteStringForRegExp","ranges":[{"startOffset":63002,"endOffset":63154,"count":0}],"isBlockCoverage":false},{"functionName":"stringReplaceAllUnchecked","ranges":[{"startOffset":63187,"endOffset":63770,"count":0}],"isBlockCoverage":false},{"functionName":"stringReplaceAllUncheckedString","ranges":[{"startOffset":63809,"endOffset":64503,"count":0}],"isBlockCoverage":false},{"functionName":"_stringIdentity","ranges":[{"startOffset":64526,"endOffset":64571,"count":0}],"isBlockCoverage":false},{"functionName":"stringReplaceAllFuncUnchecked","ranges":[{"startOffset":64608,"endOffset":65417,"count":0}],"isBlockCoverage":false},{"functionName":"stringReplaceFirstUnchecked","ranges":[{"startOffset":65452,"endOffset":66440,"count":0}],"isBlockCoverage":false},{"functionName":"stringReplaceRangeUnchecked","ranges":[{"startOffset":66475,"endOffset":66661,"count":0}],"isBlockCoverage":false},{"functionName":"ConstantMap","ranges":[{"startOffset":66680,"endOffset":66710,"count":0}],"isBlockCoverage":false},{"functionName":"ConstantMap_map_closure","ranges":[{"startOffset":66741,"endOffset":66867,"count":0}],"isBlockCoverage":false},{"functionName":"ConstantStringMap","ranges":[{"startOffset":66892,"endOffset":67070,"count":1}],"isBlockCoverage":true},{"functionName":"_ConstantMapKeyIterable","ranges":[{"startOffset":67101,"endOffset":67204,"count":0}],"isBlockCoverage":false},{"functionName":"Instantiation","ranges":[{"startOffset":67225,"endOffset":67257,"count":0}],"isBlockCoverage":false},{"functionName":"Instantiation1","ranges":[{"startOffset":67279,"endOffset":67372,"count":0}],"isBlockCoverage":false},{"functionName":"Primitives_initTicker_closure","ranges":[{"startOffset":67409,"endOffset":67488,"count":0}],"isBlockCoverage":false},{"functionName":"TypeErrorDecoder","ranges":[{"startOffset":67512,"endOffset":67732,"count":0}],"isBlockCoverage":false},{"functionName":"NullError","ranges":[{"startOffset":67749,"endOffset":67846,"count":0}],"isBlockCoverage":false},{"functionName":"JsNoSuchMethodError","ranges":[{"startOffset":67873,"endOffset":68011,"count":0}],"isBlockCoverage":false},{"functionName":"UnknownJsTypeError","ranges":[{"startOffset":68037,"endOffset":68114,"count":0}],"isBlockCoverage":false},{"functionName":"ExceptionAndStackTrace","ranges":[{"startOffset":68144,"endOffset":68250,"count":0}],"isBlockCoverage":true},{"functionName":"unwrapException_saveStackTrace","ranges":[{"startOffset":68288,"endOffset":68359,"count":0}],"isBlockCoverage":false},{"functionName":"_StackTrace","ranges":[{"startOffset":68378,"endOffset":68464,"count":1}],"isBlockCoverage":true},{"functionName":"Closure","ranges":[{"startOffset":68479,"endOffset":68505,"count":0}],"isBlockCoverage":true},{"functionName":"TearOffClosure","ranges":[{"startOffset":68527,"endOffset":68560,"count":0}],"isBlockCoverage":false},{"functionName":"StaticClosure","ranges":[{"startOffset":68581,"endOffset":68613,"count":1}],"isBlockCoverage":true},{"functionName":"BoundClosure","ranges":[{"startOffset":68633,"endOffset":68784,"count":1}],"isBlockCoverage":true},{"functionName":"TypeErrorImplementation","ranges":[{"startOffset":68815,"endOffset":68884,"count":0}],"isBlockCoverage":false},{"functionName":"RuntimeError","ranges":[{"startOffset":68904,"endOffset":68962,"count":0}],"isBlockCoverage":false},{"functionName":"_AssertionError","ranges":[{"startOffset":68985,"endOffset":69046,"count":0}],"isBlockCoverage":false},{"functionName":"JsLinkedHashMap","ranges":[{"startOffset":69069,"endOffset":69306,"count":1}],"isBlockCoverage":true},{"functionName":"JsLinkedHashMap_values_closure","ranges":[{"startOffset":69344,"endOffset":69418,"count":0}],"isBlockCoverage":false},{"functionName":"JsLinkedHashMap_addAll_closure","ranges":[{"startOffset":69456,"endOffset":69530,"count":0}],"isBlockCoverage":false},{"functionName":"LinkedHashMapCell","ranges":[{"startOffset":69555,"endOffset":69713,"count":1}],"isBlockCoverage":true},{"functionName":"LinkedHashMapKeyIterable","ranges":[{"startOffset":69745,"endOffset":69849,"count":1}],"isBlockCoverage":true},{"functionName":"LinkedHashMapKeyIterator","ranges":[{"startOffset":69881,"endOffset":70079,"count":1}],"isBlockCoverage":true},{"functionName":"initHooks_closure","ranges":[{"startOffset":70104,"endOffset":70166,"count":1}],"isBlockCoverage":true},{"functionName":"initHooks_closure0","ranges":[{"startOffset":70192,"endOffset":70262,"count":1}],"isBlockCoverage":true},{"functionName":"initHooks_closure1","ranges":[{"startOffset":70288,"endOffset":70360,"count":1}],"isBlockCoverage":true},{"functionName":"JSSyntaxRegExp","ranges":[{"startOffset":70382,"endOffset":70553,"count":0}],"isBlockCoverage":false},{"functionName":"_MatchImplementation","ranges":[{"startOffset":70581,"endOffset":70646,"count":0}],"isBlockCoverage":false},{"functionName":"_AllMatchesIterable","ranges":[{"startOffset":70673,"endOffset":70803,"count":0}],"isBlockCoverage":false},{"functionName":"_AllMatchesIterator","ranges":[{"startOffset":70830,"endOffset":71016,"count":0}],"isBlockCoverage":false},{"functionName":"StringMatch","ranges":[{"startOffset":71035,"endOffset":71119,"count":0}],"isBlockCoverage":false},{"functionName":"_StringAllMatchesIterable","ranges":[{"startOffset":71152,"endOffset":71292,"count":0}],"isBlockCoverage":false},{"functionName":"_StringAllMatchesIterator","ranges":[{"startOffset":71325,"endOffset":71513,"count":0}],"isBlockCoverage":false},{"functionName":"_ensureNativeList","ranges":[{"startOffset":71538,"endOffset":71579,"count":0}],"isBlockCoverage":false},{"functionName":"NativeInt8List__create1","ranges":[{"startOffset":71610,"endOffset":71664,"count":0}],"isBlockCoverage":false},{"functionName":"_checkValidIndex","ranges":[{"startOffset":71688,"endOffset":71845,"count":1},{"startOffset":71782,"endOffset":71839,"count":0}],"isBlockCoverage":true},{"functionName":"_checkValidRange","ranges":[{"startOffset":71869,"endOffset":72275,"count":0}],"isBlockCoverage":false},{"functionName":"NativeByteBuffer","ranges":[{"startOffset":72299,"endOffset":72334,"count":0}],"isBlockCoverage":false},{"functionName":"NativeTypedData","ranges":[{"startOffset":72357,"endOffset":72391,"count":0}],"isBlockCoverage":false},{"functionName":"NativeByteData","ranges":[{"startOffset":72413,"endOffset":72446,"count":0}],"isBlockCoverage":false},{"functionName":"NativeTypedArray","ranges":[{"startOffset":72470,"endOffset":72505,"count":0}],"isBlockCoverage":false},{"functionName":"NativeTypedArrayOfDouble","ranges":[{"startOffset":72537,"endOffset":72580,"count":0}],"isBlockCoverage":false},{"functionName":"NativeTypedArrayOfInt","ranges":[{"startOffset":72609,"endOffset":72649,"count":0}],"isBlockCoverage":false},{"functionName":"NativeFloat32List","ranges":[{"startOffset":72674,"endOffset":72710,"count":0}],"isBlockCoverage":false},{"functionName":"NativeFloat64List","ranges":[{"startOffset":72735,"endOffset":72771,"count":0}],"isBlockCoverage":false},{"functionName":"NativeInt16List","ranges":[{"startOffset":72794,"endOffset":72828,"count":0}],"isBlockCoverage":false},{"functionName":"NativeInt32List","ranges":[{"startOffset":72851,"endOffset":72885,"count":0}],"isBlockCoverage":false},{"functionName":"NativeInt8List","ranges":[{"startOffset":72907,"endOffset":72940,"count":0}],"isBlockCoverage":false},{"functionName":"NativeUint16List","ranges":[{"startOffset":72964,"endOffset":72999,"count":0}],"isBlockCoverage":false},{"functionName":"NativeUint32List","ranges":[{"startOffset":73023,"endOffset":73058,"count":0}],"isBlockCoverage":false},{"functionName":"NativeUint8ClampedList","ranges":[{"startOffset":73088,"endOffset":73129,"count":0}],"isBlockCoverage":false},{"functionName":"NativeUint8List","ranges":[{"startOffset":73152,"endOffset":73186,"count":0}],"isBlockCoverage":false},{"functionName":"_NativeTypedArrayOfDouble_NativeTypedArray_ListMixin","ranges":[{"startOffset":73246,"endOffset":73317,"count":0}],"isBlockCoverage":false},{"functionName":"_NativeTypedArrayOfDouble_NativeTypedArray_ListMixin_FixedLengthListMixin","ranges":[{"startOffset":73398,"endOffset":73490,"count":0}],"isBlockCoverage":false},{"functionName":"_NativeTypedArrayOfInt_NativeTypedArray_ListMixin","ranges":[{"startOffset":73547,"endOffset":73615,"count":0}],"isBlockCoverage":false},{"functionName":"_NativeTypedArrayOfInt_NativeTypedArray_ListMixin_FixedLengthListMixin","ranges":[{"startOffset":73693,"endOffset":73782,"count":0}],"isBlockCoverage":false},{"functionName":"Rti__getFutureFromFutureOr","ranges":[{"startOffset":73816,"endOffset":74142,"count":0}],"isBlockCoverage":false},{"functionName":"Rti__isUnionOfFunctionType","ranges":[{"startOffset":74176,"endOffset":74375,"count":1}],"isBlockCoverage":true},{"functionName":"Rti__getInterfaceTypeArguments","ranges":[{"startOffset":74413,"endOffset":74497,"count":1}],"isBlockCoverage":true},{"functionName":"Rti__getBindingArguments","ranges":[{"startOffset":74529,"endOffset":74614,"count":1}],"isBlockCoverage":true},{"functionName":"Rti__getFunctionParameters","ranges":[{"startOffset":74648,"endOffset":74733,"count":1}],"isBlockCoverage":true},{"functionName":"Rti__getGenericFunctionBounds","ranges":[{"startOffset":74770,"endOffset":74855,"count":1}],"isBlockCoverage":true},{"functionName":"Rti__getCanonicalRecipe","ranges":[{"startOffset":74886,"endOffset":75056,"count":0}],"isBlockCoverage":false},{"functionName":"findType","ranges":[{"startOffset":75072,"endOffset":75154,"count":1}],"isBlockCoverage":true},{"functionName":"instantiatedGenericFunctionType","ranges":[{"startOffset":75193,"endOffset":76127,"count":0}],"isBlockCoverage":false},{"functionName":"_instantiate","ranges":[{"startOffset":76147,"endOffset":80529,"count":0}],"isBlockCoverage":false},{"functionName":"_instantiateArray","ranges":[{"startOffset":80554,"endOffset":81024,"count":0}],"isBlockCoverage":false},{"functionName":"_instantiateNamed","ranges":[{"startOffset":81049,"endOffset":81640,"count":0}],"isBlockCoverage":false},{"functionName":"_instantiateFunctionParameters","ranges":[{"startOffset":81678,"endOffset":82753,"count":0}],"isBlockCoverage":false},{"functionName":"closureFunctionType","ranges":[{"startOffset":82780,"endOffset":83037,"count":1},{"startOffset":83012,"endOffset":83036,"count":0}],"isBlockCoverage":true},{"functionName":"instanceOrFunctionType","ranges":[{"startOffset":83067,"endOffset":83352,"count":1}],"isBlockCoverage":true},{"functionName":"instanceType","ranges":[{"startOffset":83372,"endOffset":83710,"count":1},{"startOffset":83505,"endOffset":83545,"count":0}],"isBlockCoverage":true},{"functionName":"_arrayInstanceType","ranges":[{"startOffset":83736,"endOffset":83981,"count":1},{"startOffset":83939,"endOffset":83957,"count":0}],"isBlockCoverage":true},{"functionName":"_instanceType","ranges":[{"startOffset":84002,"endOffset":84127,"count":1},{"startOffset":84080,"endOffset":84120,"count":0}],"isBlockCoverage":true},{"functionName":"_instanceTypeFromConstructor","ranges":[{"startOffset":84163,"endOffset":84394,"count":1}],"isBlockCoverage":true},{"functionName":"_instanceTypeFromConstructorMiss","ranges":[{"startOffset":84434,"endOffset":84736,"count":1},{"startOffset":84532,"endOffset":84574,"count":0}],"isBlockCoverage":true},{"functionName":"getTypeFromTypesTable","ranges":[{"startOffset":84765,"endOffset":85054,"count":1}],"isBlockCoverage":true},{"functionName":"createRuntimeType","ranges":[{"startOffset":85079,"endOffset":85242,"count":1},{"startOffset":85168,"endOffset":85180,"count":0}],"isBlockCoverage":true},{"functionName":"typeLiteral","ranges":[{"startOffset":85261,"endOffset":85364,"count":1}],"isBlockCoverage":true},{"functionName":"_installSpecializedIsTest","ranges":[{"startOffset":85397,"endOffset":86499,"count":1},{"startOffset":85764,"endOffset":85806,"count":0},{"startOffset":85923,"endOffset":85939,"count":0}],"isBlockCoverage":true},{"functionName":"_generalIsTestImplementation","ranges":[{"startOffset":86535,"endOffset":86701,"count":1}],"isBlockCoverage":true},{"functionName":"_isTestViaProperty","ranges":[{"startOffset":86727,"endOffset":86913,"count":1}],"isBlockCoverage":true},{"functionName":"_generalAsCheckImplementation","ranges":[{"startOffset":86950,"endOffset":87273,"count":1},{"startOffset":87022,"endOffset":87036,"count":0},{"startOffset":87112,"endOffset":87272,"count":0}],"isBlockCoverage":true},{"functionName":"_generalTypeCheckImplementation","ranges":[{"startOffset":87312,"endOffset":87635,"count":1},{"startOffset":87474,"endOffset":87634,"count":0}],"isBlockCoverage":true},{"functionName":"checkTypeBound","ranges":[{"startOffset":87657,"endOffset":88102,"count":0}],"isBlockCoverage":false},{"functionName":"_Error_compose","ranges":[{"startOffset":88124,"endOffset":88496,"count":0}],"isBlockCoverage":false},{"functionName":"_CastError$fromMessage","ranges":[{"startOffset":88526,"endOffset":88607,"count":0}],"isBlockCoverage":false},{"functionName":"_CastError__CastError$forType","ranges":[{"startOffset":88644,"endOffset":88759,"count":0}],"isBlockCoverage":false},{"functionName":"_TypeError$fromMessage","ranges":[{"startOffset":88789,"endOffset":88870,"count":0}],"isBlockCoverage":false},{"functionName":"_TypeError__TypeError$forType","ranges":[{"startOffset":88907,"endOffset":89022,"count":0}],"isBlockCoverage":false},{"functionName":"_isTop","ranges":[{"startOffset":89036,"endOffset":89079,"count":1}],"isBlockCoverage":true},{"functionName":"_asTop","ranges":[{"startOffset":89093,"endOffset":89138,"count":1}],"isBlockCoverage":true},{"functionName":"_isBool","ranges":[{"startOffset":89153,"endOffset":89227,"count":1}],"isBlockCoverage":true},{"functionName":"_asBoolNullable","ranges":[{"startOffset":89250,"endOffset":89471,"count":1},{"startOffset":89387,"endOffset":89470,"count":0}],"isBlockCoverage":true},{"functionName":"_checkBoolNullable","ranges":[{"startOffset":89497,"endOffset":89718,"count":1},{"startOffset":89634,"endOffset":89717,"count":0}],"isBlockCoverage":true},{"functionName":"_asDoubleNullable","ranges":[{"startOffset":89743,"endOffset":89956,"count":0}],"isBlockCoverage":false},{"functionName":"_checkDoubleNullable","ranges":[{"startOffset":89984,"endOffset":90197,"count":0}],"isBlockCoverage":false},{"functionName":"_isInt","ranges":[{"startOffset":90211,"endOffset":90308,"count":1}],"isBlockCoverage":true},{"functionName":"_asIntNullable","ranges":[{"startOffset":90330,"endOffset":90573,"count":1},{"startOffset":90490,"endOffset":90572,"count":0}],"isBlockCoverage":true},{"functionName":"_checkIntNullable","ranges":[{"startOffset":90598,"endOffset":90841,"count":1},{"startOffset":90709,"endOffset":90840,"count":0}],"isBlockCoverage":true},{"functionName":"_isNum","ranges":[{"startOffset":90855,"endOffset":90919,"count":1}],"isBlockCoverage":true},{"functionName":"_asNumNullable","ranges":[{"startOffset":90941,"endOffset":91151,"count":1},{"startOffset":91019,"endOffset":91150,"count":0}],"isBlockCoverage":true},{"functionName":"_checkNumNullable","ranges":[{"startOffset":91176,"endOffset":91386,"count":0}],"isBlockCoverage":false},{"functionName":"_isString","ranges":[{"startOffset":91403,"endOffset":91467,"count":1}],"isBlockCoverage":true},{"functionName":"_asStringNullable","ranges":[{"startOffset":91492,"endOffset":91705,"count":1},{"startOffset":91619,"endOffset":91704,"count":0}],"isBlockCoverage":true},{"functionName":"_checkStringNullable","ranges":[{"startOffset":91733,"endOffset":91946,"count":1},{"startOffset":91811,"endOffset":91945,"count":0}],"isBlockCoverage":true},{"functionName":"_rtiArrayToString","ranges":[{"startOffset":91971,"endOffset":92203,"count":0}],"isBlockCoverage":false},{"functionName":"_functionRtiToString","ranges":[{"startOffset":92231,"endOffset":95348,"count":0}],"isBlockCoverage":false},{"functionName":"_rtiToString","ranges":[{"startOffset":95368,"endOffset":96985,"count":0}],"isBlockCoverage":false},{"functionName":"_unminifyOrTag","ranges":[{"startOffset":97007,"endOffset":97195,"count":0}],"isBlockCoverage":false},{"functionName":"_Universe_findRule","ranges":[{"startOffset":97221,"endOffset":97393,"count":1},{"startOffset":97343,"endOffset":97368,"count":0}],"isBlockCoverage":true},{"functionName":"_Universe_findErasedType","ranges":[{"startOffset":97425,"endOffset":98058,"count":1},{"startOffset":97640,"endOffset":98052,"count":0}],"isBlockCoverage":true},{"functionName":"_Universe_addRules","ranges":[{"startOffset":98084,"endOffset":98173,"count":1}],"isBlockCoverage":true},{"functionName":"_Universe_addErasedTypes","ranges":[{"startOffset":98205,"endOffset":98294,"count":1}],"isBlockCoverage":true},{"functionName":"_Universe_eval","ranges":[{"startOffset":98316,"endOffset":98586,"count":1}],"isBlockCoverage":true},{"functionName":"_Universe_evalInEnvironment","ranges":[{"startOffset":98621,"endOffset":99004,"count":1}],"isBlockCoverage":true},{"functionName":"_Universe_bind","ranges":[{"startOffset":99026,"endOffset":99702,"count":1},{"startOffset":99328,"endOffset":99370,"count":0},{"startOffset":99578,"endOffset":99620,"count":0}],"isBlockCoverage":true},{"functionName":"_Universe__parseRecipe","ranges":[{"startOffset":99732,"endOffset":99879,"count":1}],"isBlockCoverage":true},{"functionName":"_Universe__finishRti","ranges":[{"startOffset":99907,"endOffset":100268,"count":1},{"startOffset":100023,"endOffset":100065,"count":0}],"isBlockCoverage":true},{"functionName":"_Universe__lookupTerminalRti","ranges":[{"startOffset":100304,"endOffset":100628,"count":1}],"isBlockCoverage":true},{"functionName":"_Universe__lookupUnaryRti","ranges":[{"startOffset":100661,"endOffset":101026,"count":1}],"isBlockCoverage":true},{"functionName":"_Universe__lookupGenericFunctionParameterRti","ranges":[{"startOffset":101078,"endOffset":101456,"count":1}],"isBlockCoverage":true},{"functionName":"_Universe__canonicalRecipeJoin","ranges":[{"startOffset":101494,"endOffset":101845,"count":1},{"startOffset":101750,"endOffset":101792,"count":0}],"isBlockCoverage":true},{"functionName":"_Universe__canonicalRecipeJoinNamed","ranges":[{"startOffset":101888,"endOffset":102332,"count":0}],"isBlockCoverage":false},{"functionName":"_Universe__lookupInterfaceRti","ranges":[{"startOffset":102369,"endOffset":102971,"count":1}],"isBlockCoverage":true},{"functionName":"_Universe__lookupBindingRti","ranges":[{"startOffset":103006,"endOffset":103877,"count":1},{"startOffset":103457,"endOffset":103499,"count":0}],"isBlockCoverage":true},{"functionName":"_Universe__lookupFunctionRti","ranges":[{"startOffset":103913,"endOffset":105417,"count":1},{"startOffset":104216,"endOffset":104258,"count":0},{"startOffset":104965,"endOffset":105084,"count":0}],"isBlockCoverage":true},{"functionName":"_Universe__lookupGenericFunctionRti","ranges":[{"startOffset":105460,"endOffset":106050,"count":1},{"startOffset":105635,"endOffset":105677,"count":0},{"startOffset":105817,"endOffset":105830,"count":0}],"isBlockCoverage":true},{"functionName":"_Parser_create","ranges":[{"startOffset":106072,"endOffset":106187,"count":1}],"isBlockCoverage":true},{"functionName":"_Parser_parse","ranges":[{"startOffset":106208,"endOffset":111999,"count":1},{"startOffset":106817,"endOffset":106880,"count":0},{"startOffset":106989,"endOffset":107018,"count":0},{"startOffset":107031,"endOffset":107137,"count":0},{"startOffset":107388,"endOffset":107493,"count":0},{"startOffset":108690,"endOffset":108784,"count":0},{"startOffset":108797,"endOffset":109122,"count":0},{"startOffset":109135,"endOffset":109460,"count":0},{"startOffset":109682,"endOffset":109703,"count":0},{"startOffset":110356,"endOffset":110440,"count":0},{"startOffset":111456,"endOffset":111561,"count":0},{"startOffset":111574,"endOffset":111816,"count":0},{"startOffset":111829,"endOffset":111880,"count":0}],"isBlockCoverage":true},{"functionName":"_Parser_handleDigit","ranges":[{"startOffset":112026,"endOffset":112337,"count":1},{"startOffset":112242,"endOffset":112290,"count":0}],"isBlockCoverage":true},{"functionName":"_Parser_handleIdentifier","ranges":[{"startOffset":112369,"endOffset":113633,"count":1},{"startOffset":112644,"endOffset":112650,"count":0},{"startOffset":113401,"endOffset":113494,"count":0}],"isBlockCoverage":true},{"functionName":"_Parser_handleExtendedOperations","ranges":[{"startOffset":113673,"endOffset":114066,"count":0}],"isBlockCoverage":false},{"functionName":"_Parser_toType","ranges":[{"startOffset":114088,"endOffset":114385,"count":1}],"isBlockCoverage":true},{"functionName":"_Parser_toTypes","ranges":[{"startOffset":114408,"endOffset":114605,"count":1}],"isBlockCoverage":true},{"functionName":"_Parser_toTypesNamed","ranges":[{"startOffset":114633,"endOffset":114876,"count":0}],"isBlockCoverage":false},{"functionName":"_Parser_indexToType","ranges":[{"startOffset":114903,"endOffset":115904,"count":1},{"startOffset":115075,"endOffset":115162,"count":0},{"startOffset":115556,"endOffset":115639,"count":0},{"startOffset":115790,"endOffset":115903,"count":0}],"isBlockCoverage":true},{"functionName":"_isSubtype","ranges":[{"startOffset":115922,"endOffset":118887,"count":1},{"startOffset":116182,"endOffset":116194,"count":0},{"startOffset":116235,"endOffset":116248,"count":0},{"startOffset":116365,"endOffset":116512,"count":0},{"startOffset":116574,"endOffset":116694,"count":0},{"startOffset":116718,"endOffset":116850,"count":0},{"startOffset":116874,"endOffset":117119,"count":0},{"startOffset":117143,"endOffset":117280,"count":0},{"startOffset":117431,"endOffset":117542,"count":0},{"startOffset":117566,"endOffset":117698,"count":0},{"startOffset":117735,"endOffset":117748,"count":0},{"startOffset":117932,"endOffset":117944,"count":0},{"startOffset":117981,"endOffset":117994,"count":0},{"startOffset":118164,"endOffset":118177,"count":0},{"startOffset":118216,"endOffset":118238,"count":0},{"startOffset":118278,"endOffset":118300,"count":0},{"startOffset":118576,"endOffset":118588,"count":0},{"startOffset":118615,"endOffset":118628,"count":0},{"startOffset":118768,"endOffset":118781,"count":0},{"startOffset":118861,"endOffset":118886,"count":0}],"isBlockCoverage":true},{"functionName":"_isFunctionSubtype","ranges":[{"startOffset":118913,"endOffset":121867,"count":1},{"startOffset":119567,"endOffset":119580,"count":0},{"startOffset":120006,"endOffset":120019,"count":0},{"startOffset":120482,"endOffset":120495,"count":0},{"startOffset":120682,"endOffset":120695,"count":0},{"startOffset":120916,"endOffset":120929,"count":0},{"startOffset":120992,"endOffset":121171,"count":0},{"startOffset":121437,"endOffset":121842,"count":0}],"isBlockCoverage":true},{"functionName":"_isInterfaceSubtype","ranges":[{"startOffset":121894,"endOffset":123121,"count":1},{"startOffset":122175,"endOffset":122584,"count":0},{"startOffset":122669,"endOffset":122682,"count":0},{"startOffset":123083,"endOffset":123096,"count":0}],"isBlockCoverage":true},{"functionName":"typeEqual","ranges":[{"startOffset":123138,"endOffset":124947,"count":1},{"startOffset":123229,"endOffset":123426,"count":0},{"startOffset":123435,"endOffset":123442,"count":0},{"startOffset":123451,"endOffset":123518,"count":0},{"startOffset":123527,"endOffset":123808,"count":0},{"startOffset":123817,"endOffset":124067,"count":0},{"startOffset":124076,"endOffset":124623,"count":0},{"startOffset":124632,"endOffset":124892,"count":0},{"startOffset":124901,"endOffset":124933,"count":0}],"isBlockCoverage":true},{"functionName":"typesEqual","ranges":[{"startOffset":124965,"endOffset":125245,"count":1},{"startOffset":125093,"endOffset":125106,"count":0},{"startOffset":125207,"endOffset":125220,"count":0}],"isBlockCoverage":true},{"functionName":"namedTypesEqual","ranges":[{"startOffset":125268,"endOffset":125761,"count":0}],"isBlockCoverage":false},{"functionName":"isLegacyTopType","ranges":[{"startOffset":125784,"endOffset":125838,"count":1}],"isBlockCoverage":true},{"functionName":"isTopType","ranges":[{"startOffset":125855,"endOffset":126428,"count":1},{"startOffset":126261,"endOffset":126341,"count":0}],"isBlockCoverage":true},{"functionName":"_Utils_objectAssign","ranges":[{"startOffset":126455,"endOffset":126663,"count":1}],"isBlockCoverage":true},{"functionName":"Rti","ranges":[{"startOffset":126674,"endOffset":126970,"count":1}],"isBlockCoverage":true},{"functionName":"_FunctionParameters","ranges":[{"startOffset":126997,"endOffset":127123,"count":1}],"isBlockCoverage":true},{"functionName":"_Type","ranges":[{"startOffset":127136,"endOffset":127213,"count":1}],"isBlockCoverage":true},{"functionName":"_Error","ranges":[{"startOffset":127227,"endOffset":127252,"count":0}],"isBlockCoverage":false},{"functionName":"_CastError","ranges":[{"startOffset":127270,"endOffset":127327,"count":0}],"isBlockCoverage":false},{"functionName":"_TypeError","ranges":[{"startOffset":127345,"endOffset":127402,"count":0}],"isBlockCoverage":false},{"functionName":"extractKeys","ranges":[{"startOffset":127421,"endOffset":127537,"count":0}],"isBlockCoverage":false},{"functionName":"unmangleGlobalNameIfPreservedAnyways","ranges":[{"startOffset":127581,"endOffset":127649,"count":0}],"isBlockCoverage":false},{"functionName":"printString","ranges":[{"startOffset":127668,"endOffset":128115,"count":0}],"isBlockCoverage":false},{"functionName":"makeDispatchRecord","ranges":[{"startOffset":128153,"endOffset":128286,"count":1}],"isBlockCoverage":true},{"functionName":"getNativeInterceptor","ranges":[{"startOffset":128314,"endOffset":129994,"count":1},{"startOffset":128762,"endOffset":128776,"count":0},{"startOffset":128891,"endOffset":129041,"count":0},{"startOffset":129049,"endOffset":129138,"count":0},{"startOffset":129139,"endOffset":129190,"count":0},{"startOffset":129231,"endOffset":129993,"count":0}],"isBlockCoverage":true},{"functionName":"JSArray_JSArray$fixed","ranges":[{"startOffset":130023,"endOffset":130380,"count":0}],"isBlockCoverage":false},{"functionName":"JSArray_JSArray$markFixed","ranges":[{"startOffset":130413,"endOffset":130543,"count":0}],"isBlockCoverage":false},{"functionName":"JSArray_markFixedList","ranges":[{"startOffset":130572,"endOffset":130646,"count":1}],"isBlockCoverage":true},{"functionName":"JSString__isWhitespace","ranges":[{"startOffset":130676,"endOffset":131431,"count":0}],"isBlockCoverage":false},{"functionName":"JSString__skipLeadingWhitespace","ranges":[{"startOffset":131470,"endOffset":131788,"count":0}],"isBlockCoverage":false},{"functionName":"JSString__skipTrailingWhitespace","ranges":[{"startOffset":131828,"endOffset":132157,"count":0}],"isBlockCoverage":false},{"functionName":"getInterceptor$","ranges":[{"startOffset":132180,"endOffset":132943,"count":1},{"startOffset":132240,"endOffset":132368,"count":0},{"startOffset":132699,"endOffset":132825,"count":0}],"isBlockCoverage":true},{"functionName":"getInterceptor$ansx","ranges":[{"startOffset":132970,"endOffset":133556,"count":0}],"isBlockCoverage":false},{"functionName":"getInterceptor$asx","ranges":[{"startOffset":133582,"endOffset":134092,"count":1},{"startOffset":133715,"endOffset":133731,"count":0},{"startOffset":133848,"endOffset":133974,"count":0},{"startOffset":134039,"endOffset":134091,"count":0}],"isBlockCoverage":true},{"functionName":"getInterceptor$ax","ranges":[{"startOffset":134117,"endOffset":134551,"count":1},{"startOffset":134174,"endOffset":134190,"count":0},{"startOffset":134307,"endOffset":134433,"count":0}],"isBlockCoverage":true},{"functionName":"getInterceptor$n","ranges":[{"startOffset":134575,"endOffset":134848,"count":0}],"isBlockCoverage":false},{"functionName":"getInterceptor$s","ranges":[{"startOffset":134872,"endOffset":135145,"count":1},{"startOffset":134968,"endOffset":135144,"count":0}],"isBlockCoverage":true},{"functionName":"getInterceptor$x","ranges":[{"startOffset":135169,"endOffset":135526,"count":1},{"startOffset":135226,"endOffset":135242,"count":0},{"startOffset":135282,"endOffset":135408,"count":0},{"startOffset":135457,"endOffset":135473,"count":0}],"isBlockCoverage":true},{"functionName":"get$first$ax","ranges":[{"startOffset":135546,"endOffset":135636,"count":1}],"isBlockCoverage":true},{"functionName":"get$hashCode$","ranges":[{"startOffset":135657,"endOffset":135748,"count":1}],"isBlockCoverage":true},{"functionName":"get$isEmpty$asx","ranges":[{"startOffset":135771,"endOffset":135864,"count":1}],"isBlockCoverage":true},{"functionName":"get$iterator$ax","ranges":[{"startOffset":135887,"endOffset":135980,"count":1}],"isBlockCoverage":true},{"functionName":"get$last$ax","ranges":[{"startOffset":135999,"endOffset":136088,"count":0}],"isBlockCoverage":false},{"functionName":"get$length$asx","ranges":[{"startOffset":136110,"endOffset":136202,"count":1}],"isBlockCoverage":true},{"functionName":"get$message$x","ranges":[{"startOffset":136223,"endOffset":136314,"count":0}],"isBlockCoverage":false},{"functionName":"get$runtimeType$","ranges":[{"startOffset":136338,"endOffset":136432,"count":0}],"isBlockCoverage":false},{"functionName":"get$startsWith$s","ranges":[{"startOffset":136456,"endOffset":136550,"count":0}],"isBlockCoverage":false},{"functionName":"$add$ansx","ranges":[{"startOffset":136567,"endOffset":136756,"count":0}],"isBlockCoverage":false},{"functionName":"$eq$","ranges":[{"startOffset":136768,"endOffset":136998,"count":1}],"isBlockCoverage":true},{"functionName":"$index$asx","ranges":[{"startOffset":137016,"endOffset":137374,"count":0}],"isBlockCoverage":false},{"functionName":"$indexSet$ax","ranges":[{"startOffset":137394,"endOffset":137500,"count":1}],"isBlockCoverage":true},{"functionName":"_codeUnitAt$1$s","ranges":[{"startOffset":137523,"endOffset":137624,"count":1}],"isBlockCoverage":true},{"functionName":"_removeEventListener$3$x","ranges":[{"startOffset":137656,"endOffset":137782,"count":1}],"isBlockCoverage":true},{"functionName":"addEventListener$3$x","ranges":[{"startOffset":137810,"endOffset":137932,"count":1}],"isBlockCoverage":true},{"functionName":"allMatches$1$s","ranges":[{"startOffset":137954,"endOffset":138054,"count":0}],"isBlockCoverage":false},{"functionName":"allMatches$2$s","ranges":[{"startOffset":138076,"endOffset":138184,"count":0}],"isBlockCoverage":false},{"functionName":"codeUnitAt$1$s","ranges":[{"startOffset":138206,"endOffset":138306,"count":0}],"isBlockCoverage":false},{"functionName":"contains$1$asx","ranges":[{"startOffset":138328,"endOffset":138428,"count":0}],"isBlockCoverage":false},{"functionName":"elementAt$1$ax","ranges":[{"startOffset":138450,"endOffset":138550,"count":1}],"isBlockCoverage":true},{"functionName":"endsWith$1$s","ranges":[{"startOffset":138570,"endOffset":138668,"count":0}],"isBlockCoverage":false},{"functionName":"fillRange$3$ax","ranges":[{"startOffset":138690,"endOffset":138806,"count":1}],"isBlockCoverage":true},{"functionName":"map$1$1$ax","ranges":[{"startOffset":138824,"endOffset":138930,"count":0}],"isBlockCoverage":false},{"functionName":"matchAsPrefix$2$s","ranges":[{"startOffset":138955,"endOffset":139066,"count":0}],"isBlockCoverage":false},{"functionName":"padRight$1$s","ranges":[{"startOffset":139086,"endOffset":139184,"count":0}],"isBlockCoverage":false},{"functionName":"replaceRange$3$asx","ranges":[{"startOffset":139210,"endOffset":139330,"count":0}],"isBlockCoverage":false},{"functionName":"startsWith$1$s","ranges":[{"startOffset":139352,"endOffset":139452,"count":0}],"isBlockCoverage":false},{"functionName":"startsWith$2$s","ranges":[{"startOffset":139474,"endOffset":139582,"count":1}],"isBlockCoverage":true},{"functionName":"substring$1$s","ranges":[{"startOffset":139603,"endOffset":139702,"count":0}],"isBlockCoverage":false},{"functionName":"substring$2$s","ranges":[{"startOffset":139723,"endOffset":139830,"count":0}],"isBlockCoverage":false},{"functionName":"toRadixString$1$n","ranges":[{"startOffset":139855,"endOffset":139958,"count":0}],"isBlockCoverage":false},{"functionName":"toSet$0$ax","ranges":[{"startOffset":139976,"endOffset":140064,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0$","ranges":[{"startOffset":140083,"endOffset":140172,"count":0}],"isBlockCoverage":false},{"functionName":"trim$0$s","ranges":[{"startOffset":140188,"endOffset":140274,"count":0}],"isBlockCoverage":false},{"functionName":"Interceptor","ranges":[{"startOffset":140293,"endOffset":140323,"count":0}],"isBlockCoverage":false},{"functionName":"JSBool","ranges":[{"startOffset":140337,"endOffset":140362,"count":0}],"isBlockCoverage":false},{"functionName":"JSNull","ranges":[{"startOffset":140376,"endOffset":140401,"count":0}],"isBlockCoverage":false},{"functionName":"JSObject","ranges":[{"startOffset":140417,"endOffset":140444,"count":0}],"isBlockCoverage":false},{"functionName":"JavaScriptObject","ranges":[{"startOffset":140468,"endOffset":140503,"count":0}],"isBlockCoverage":false},{"functionName":"PlainJavaScriptObject","ranges":[{"startOffset":140532,"endOffset":140572,"count":0}],"isBlockCoverage":false},{"functionName":"UnknownJavaScriptObject","ranges":[{"startOffset":140603,"endOffset":140645,"count":0}],"isBlockCoverage":false},{"functionName":"JavaScriptFunction","ranges":[{"startOffset":140671,"endOffset":140708,"count":0}],"isBlockCoverage":false},{"functionName":"JSArray","ranges":[{"startOffset":140723,"endOffset":140772,"count":0}],"isBlockCoverage":true},{"functionName":"JSUnmodifiableArray","ranges":[{"startOffset":140799,"endOffset":140860,"count":0}],"isBlockCoverage":false},{"functionName":"ArrayIterator","ranges":[{"startOffset":140881,"endOffset":141052,"count":1}],"isBlockCoverage":true},{"functionName":"JSNumber","ranges":[{"startOffset":141068,"endOffset":141095,"count":0}],"isBlockCoverage":false},{"functionName":"JSInt","ranges":[{"startOffset":141108,"endOffset":141132,"count":0}],"isBlockCoverage":false},{"functionName":"JSDouble","ranges":[{"startOffset":141148,"endOffset":141175,"count":0}],"isBlockCoverage":false},{"functionName":"JSString","ranges":[{"startOffset":141191,"endOffset":141218,"count":0}],"isBlockCoverage":true},{"functionName":"_AsyncRun__initializeScheduleImmediate","ranges":[{"startOffset":141276,"endOffset":142083,"count":1},{"startOffset":141369,"endOffset":141433,"count":0},{"startOffset":141892,"endOffset":142082,"count":0}],"isBlockCoverage":true},{"functionName":"_AsyncRun__scheduleImmediateJsOverride","ranges":[{"startOffset":142129,"endOffset":142315,"count":0}],"isBlockCoverage":false},{"functionName":"_AsyncRun__scheduleImmediateWithSetImmediate","ranges":[{"startOffset":142367,"endOffset":142554,"count":0}],"isBlockCoverage":false},{"functionName":"_AsyncRun__scheduleImmediateWithTimer","ranges":[{"startOffset":142599,"endOffset":142705,"count":0}],"isBlockCoverage":false},{"functionName":"Timer__createTimer","ranges":[{"startOffset":142731,"endOffset":142922,"count":1},{"startOffset":142886,"endOffset":142889,"count":0}],"isBlockCoverage":true},{"functionName":"_TimerImpl$","ranges":[{"startOffset":142941,"endOffset":143084,"count":1}],"isBlockCoverage":true},{"functionName":"_TimerImpl$periodic","ranges":[{"startOffset":143111,"endOffset":143264,"count":0}],"isBlockCoverage":false},{"functionName":"_makeAsyncAwaitCompleter","ranges":[{"startOffset":143296,"endOffset":143454,"count":1}],"isBlockCoverage":true},{"functionName":"_asyncStartSync","ranges":[{"startOffset":143477,"endOffset":143617,"count":1}],"isBlockCoverage":true},{"functionName":"_asyncAwait","ranges":[{"startOffset":143636,"endOffset":143720,"count":1}],"isBlockCoverage":true},{"functionName":"_asyncReturn","ranges":[{"startOffset":143740,"endOffset":143811,"count":1}],"isBlockCoverage":true},{"functionName":"_asyncRethrow","ranges":[{"startOffset":143832,"endOffset":143960,"count":0}],"isBlockCoverage":false},{"functionName":"_awaitOnObject","ranges":[{"startOffset":143982,"endOffset":144686,"count":1},{"startOffset":144384,"endOffset":144441,"count":0}],"isBlockCoverage":true},{"functionName":"_wrapJsFunctionForAsync","ranges":[{"startOffset":144717,"endOffset":145220,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":144762,"endOffset":145053,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":144799,"endOffset":145044,"count":1},{"startOffset":144941,"endOffset":145034,"count":0}],"isBlockCoverage":true},{"functionName":"Future_Future","ranges":[{"startOffset":145241,"endOffset":145457,"count":1}],"isBlockCoverage":true},{"functionName":"Future_Future$microtask","ranges":[{"startOffset":145488,"endOffset":145706,"count":0}],"isBlockCoverage":false},{"functionName":"Future_Future$sync","ranges":[{"startOffset":145732,"endOffset":146777,"count":1},{"startOffset":145947,"endOffset":145961,"count":0},{"startOffset":146185,"endOffset":146771,"count":0}],"isBlockCoverage":true},{"functionName":"Future_Future$error","ranges":[{"startOffset":146804,"endOffset":147339,"count":0}],"isBlockCoverage":false},{"functionName":"Future_wait","ranges":[{"startOffset":147358,"endOffset":148702,"count":0}],"isBlockCoverage":false},{"functionName":"Future_forEach","ranges":[{"startOffset":148724,"endOffset":148925,"count":1}],"isBlockCoverage":true},{"functionName":"Future__kTrue","ranges":[{"startOffset":148946,"endOffset":148984,"count":0}],"isBlockCoverage":false},{"functionName":"Future_doWhile","ranges":[{"startOffset":149006,"endOffset":149408,"count":1}],"isBlockCoverage":true},{"functionName":"_completeWithErrorCallback","ranges":[{"startOffset":149442,"endOffset":149802,"count":0}],"isBlockCoverage":false},{"functionName":"_Future$zoneValue","ranges":[{"startOffset":149827,"endOffset":150023,"count":1}],"isBlockCoverage":true},{"functionName":"_Future__chainForeignFuture","ranges":[{"startOffset":150058,"endOffset":150653,"count":0}],"isBlockCoverage":false},{"functionName":"_Future__chainCoreFuture","ranges":[{"startOffset":150685,"endOffset":151411,"count":1},{"startOffset":150866,"endOffset":150958,"count":0},{"startOffset":150978,"endOffset":151135,"count":0}],"isBlockCoverage":true},{"functionName":"_Future__propagateToListeners","ranges":[{"startOffset":151448,"endOffset":155442,"count":1},{"startOffset":151952,"endOffset":152109,"count":0},{"startOffset":152235,"endOffset":152357,"count":0},{"startOffset":152661,"endOffset":152687,"count":0},{"startOffset":152790,"endOffset":152910,"count":0},{"startOffset":152958,"endOffset":153223,"count":0},{"startOffset":153845,"endOffset":153967,"count":0},{"startOffset":154108,"endOffset":154697,"count":0},{"startOffset":155231,"endOffset":155375,"count":0}],"isBlockCoverage":true},{"functionName":"_registerErrorHandler","ranges":[{"startOffset":155471,"endOffset":156025,"count":0}],"isBlockCoverage":false},{"functionName":"_microtaskLoop","ranges":[{"startOffset":156047,"endOffset":156321,"count":1}],"isBlockCoverage":true},{"functionName":"_startMicrotaskLoop","ranges":[{"startOffset":156348,"endOffset":156683,"count":1},{"startOffset":156577,"endOffset":156669,"count":0}],"isBlockCoverage":true},{"functionName":"_scheduleAsyncCallback","ranges":[{"startOffset":156713,"endOffset":157097,"count":1}],"isBlockCoverage":true},{"functionName":"_schedulePriorityAsyncCallback","ranges":[{"startOffset":157135,"endOffset":157721,"count":0}],"isBlockCoverage":false},{"functionName":"scheduleMicrotask","ranges":[{"startOffset":157746,"endOffset":158408,"count":1},{"startOffset":157973,"endOffset":158407,"count":0}],"isBlockCoverage":true},{"functionName":"Stream_Stream$fromFuture","ranges":[{"startOffset":158440,"endOffset":158865,"count":0}],"isBlockCoverage":false},{"functionName":"Stream_Stream$fromIterable","ranges":[{"startOffset":158899,"endOffset":159065,"count":1}],"isBlockCoverage":true},{"functionName":"StreamIterator_StreamIterator","ranges":[{"startOffset":159102,"endOffset":159288,"count":0}],"isBlockCoverage":false},{"functionName":"StreamController_StreamController","ranges":[{"startOffset":159329,"endOffset":159628,"count":1},{"startOffset":159516,"endOffset":159621,"count":0}],"isBlockCoverage":true},{"functionName":"_runGuarded","ranges":[{"startOffset":159647,"endOffset":159995,"count":1},{"startOffset":159819,"endOffset":159989,"count":0}],"isBlockCoverage":true},{"functionName":"_AddStreamState_makeErrorHandler","ranges":[{"startOffset":160035,"endOffset":160136,"count":0}],"isBlockCoverage":false},{"functionName":"_BufferingStreamSubscription$","ranges":[{"startOffset":160173,"endOffset":160505,"count":1},{"startOffset":160287,"endOffset":160290,"count":0}],"isBlockCoverage":true},{"functionName":"_nullDataHandler","ranges":[{"startOffset":160529,"endOffset":160552,"count":0}],"isBlockCoverage":false},{"functionName":"_nullErrorHandler","ranges":[{"startOffset":160577,"endOffset":160719,"count":0}],"isBlockCoverage":false},{"functionName":"_nullDoneHandler","ranges":[{"startOffset":160743,"endOffset":160761,"count":0}],"isBlockCoverage":false},{"functionName":"_runUserCode","ranges":[{"startOffset":160781,"endOffset":161431,"count":1},{"startOffset":160958,"endOffset":161425,"count":0}],"isBlockCoverage":true},{"functionName":"_cancelAndError","ranges":[{"startOffset":161454,"endOffset":161799,"count":0}],"isBlockCoverage":false},{"functionName":"_cancelAndErrorClosure","ranges":[{"startOffset":161829,"endOffset":161940,"count":1}],"isBlockCoverage":true},{"functionName":"_cancelAndValue","ranges":[{"startOffset":161963,"endOffset":162267,"count":1}],"isBlockCoverage":true},{"functionName":"Timer_Timer","ranges":[{"startOffset":162286,"endOffset":162516,"count":1},{"startOffset":162389,"endOffset":162433,"count":0}],"isBlockCoverage":true},{"functionName":"_ZoneSpecification$","ranges":[{"startOffset":162543,"endOffset":162986,"count":1}],"isBlockCoverage":true},{"functionName":"Zone__enter","ranges":[{"startOffset":163005,"endOffset":163218,"count":1}],"isBlockCoverage":true},{"functionName":"_parentDelegate","ranges":[{"startOffset":163241,"endOffset":163377,"count":1}],"isBlockCoverage":true},{"functionName":"_rootHandleUncaughtError","ranges":[{"startOffset":163409,"endOffset":163630,"count":0}],"isBlockCoverage":false},{"functionName":"_rootRun","ranges":[{"startOffset":163646,"endOffset":164117,"count":1},{"startOffset":164009,"endOffset":164010,"count":0}],"isBlockCoverage":true},{"functionName":"_rootRunUnary","ranges":[{"startOffset":164138,"endOffset":164675,"count":1},{"startOffset":164567,"endOffset":164568,"count":0}],"isBlockCoverage":true},{"functionName":"_rootRunBinary","ranges":[{"startOffset":164697,"endOffset":165297,"count":0}],"isBlockCoverage":false},{"functionName":"_rootRegisterCallback","ranges":[{"startOffset":165326,"endOffset":165413,"count":1}],"isBlockCoverage":true},{"functionName":"_rootRegisterUnaryCallback","ranges":[{"startOffset":165447,"endOffset":165567,"count":1}],"isBlockCoverage":true},{"functionName":"_rootRegisterBinaryCallback","ranges":[{"startOffset":165602,"endOffset":165740,"count":1}],"isBlockCoverage":true},{"functionName":"_rootErrorCallback","ranges":[{"startOffset":165766,"endOffset":165885,"count":0}],"isBlockCoverage":false},{"functionName":"_rootScheduleMicrotask","ranges":[{"startOffset":165915,"endOffset":166240,"count":1},{"startOffset":166160,"endOffset":166198,"count":0}],"isBlockCoverage":true},{"functionName":"_rootCreateTimer","ranges":[{"startOffset":166264,"endOffset":166506,"count":1}],"isBlockCoverage":true},{"functionName":"_rootCreatePeriodicTimer","ranges":[{"startOffset":166538,"endOffset":166935,"count":0}],"isBlockCoverage":false},{"functionName":"_rootPrint","ranges":[{"startOffset":166953,"endOffset":167048,"count":0}],"isBlockCoverage":false},{"functionName":"_printToZone","ranges":[{"startOffset":167068,"endOffset":167130,"count":0}],"isBlockCoverage":false},{"functionName":"_rootFork","ranges":[{"startOffset":167147,"endOffset":169398,"count":1}],"isBlockCoverage":true},{"functionName":"runZoned","ranges":[{"startOffset":169414,"endOffset":171320,"count":1},{"startOffset":169842,"endOffset":170101,"count":0},{"startOffset":170196,"endOffset":170336,"count":0},{"startOffset":170963,"endOffset":171319,"count":0}],"isBlockCoverage":true},{"functionName":"_runZoned","ranges":[{"startOffset":171337,"endOffset":171497,"count":1}],"isBlockCoverage":true},{"functionName":"_AsyncRun__initializeScheduleImmediate_internalCallback","ranges":[{"startOffset":171560,"endOffset":171660,"count":1}],"isBlockCoverage":true},{"functionName":"_AsyncRun__initializeScheduleImmediate_closure","ranges":[{"startOffset":171714,"endOffset":171856,"count":1}],"isBlockCoverage":true},{"functionName":"_AsyncRun__scheduleImmediateJsOverride_internalCallback","ranges":[{"startOffset":171919,"endOffset":172021,"count":0}],"isBlockCoverage":false},{"functionName":"_AsyncRun__scheduleImmediateWithSetImmediate_internalCallback","ranges":[{"startOffset":172090,"endOffset":172198,"count":0}],"isBlockCoverage":false},{"functionName":"_TimerImpl","ranges":[{"startOffset":172216,"endOffset":172319,"count":1}],"isBlockCoverage":true},{"functionName":"_TimerImpl_internalCallback","ranges":[{"startOffset":172354,"endOffset":172455,"count":1}],"isBlockCoverage":true},{"functionName":"_TimerImpl$periodic_closure","ranges":[{"startOffset":172490,"endOffset":172660,"count":0}],"isBlockCoverage":false},{"functionName":"_AsyncAwaitCompleter","ranges":[{"startOffset":172688,"endOffset":172806,"count":1}],"isBlockCoverage":true},{"functionName":"_awaitOnObject_closure","ranges":[{"startOffset":172836,"endOffset":172909,"count":1}],"isBlockCoverage":true},{"functionName":"_awaitOnObject_closure0","ranges":[{"startOffset":172940,"endOffset":173014,"count":1}],"isBlockCoverage":true},{"functionName":"_wrapJsFunctionForAsync_closure","ranges":[{"startOffset":173053,"endOffset":173133,"count":1}],"isBlockCoverage":true},{"functionName":"_BroadcastStream","ranges":[{"startOffset":173157,"endOffset":173248,"count":1}],"isBlockCoverage":true},{"functionName":"_BroadcastSubscription","ranges":[{"startOffset":173278,"endOffset":173605,"count":1}],"isBlockCoverage":true},{"functionName":"_BroadcastStreamController","ranges":[{"startOffset":173639,"endOffset":173684,"count":0}],"isBlockCoverage":false},{"functionName":"_SyncBroadcastStreamController","ranges":[{"startOffset":173722,"endOffset":173978,"count":1}],"isBlockCoverage":true},{"functionName":"_SyncBroadcastStreamController__sendData_closure","ranges":[{"startOffset":174034,"endOffset":174152,"count":0}],"isBlockCoverage":false},{"functionName":"_SyncBroadcastStreamController__sendError_closure","ranges":[{"startOffset":174209,"endOffset":174361,"count":0}],"isBlockCoverage":false},{"functionName":"_SyncBroadcastStreamController__sendDone_closure","ranges":[{"startOffset":174417,"endOffset":174509,"count":0}],"isBlockCoverage":false},{"functionName":"_AsyncBroadcastStreamController","ranges":[{"startOffset":174548,"endOffset":174805,"count":0}],"isBlockCoverage":false},{"functionName":"Future","ranges":[{"startOffset":174819,"endOffset":174844,"count":0}],"isBlockCoverage":false},{"functionName":"Future_Future_closure","ranges":[{"startOffset":174873,"endOffset":174972,"count":1}],"isBlockCoverage":true},{"functionName":"Future_Future$microtask_closure","ranges":[{"startOffset":175011,"endOffset":175120,"count":0}],"isBlockCoverage":false},{"functionName":"Future_wait_handleError","ranges":[{"startOffset":175151,"endOffset":175316,"count":0}],"isBlockCoverage":false},{"functionName":"Future_wait_closure","ranges":[{"startOffset":175343,"endOffset":175546,"count":0}],"isBlockCoverage":false},{"functionName":"Future_forEach_closure","ranges":[{"startOffset":175576,"endOffset":175673,"count":1}],"isBlockCoverage":true},{"functionName":"Future_doWhile_closure","ranges":[{"startOffset":175703,"endOffset":175830,"count":1}],"isBlockCoverage":true},{"functionName":"TimeoutException","ranges":[{"startOffset":175854,"endOffset":175946,"count":0}],"isBlockCoverage":false},{"functionName":"Completer","ranges":[{"startOffset":175963,"endOffset":175991,"count":0}],"isBlockCoverage":false},{"functionName":"_Completer","ranges":[{"startOffset":176009,"endOffset":176038,"count":0}],"isBlockCoverage":false},{"functionName":"_AsyncCompleter","ranges":[{"startOffset":176061,"endOffset":176146,"count":1}],"isBlockCoverage":true},{"functionName":"_SyncCompleter","ranges":[{"startOffset":176168,"endOffset":176252,"count":1}],"isBlockCoverage":true},{"functionName":"_FutureListener","ranges":[{"startOffset":176275,"endOffset":176487,"count":1}],"isBlockCoverage":true},{"functionName":"_Future","ranges":[{"startOffset":176502,"endOffset":176647,"count":1}],"isBlockCoverage":true},{"functionName":"_Future__addListener_closure","ranges":[{"startOffset":176683,"endOffset":176785,"count":1}],"isBlockCoverage":true},{"functionName":"_Future__prependListeners_closure","ranges":[{"startOffset":176826,"endOffset":176931,"count":0}],"isBlockCoverage":false},{"functionName":"_Future__chainForeignFuture_closure","ranges":[{"startOffset":176974,"endOffset":177054,"count":0}],"isBlockCoverage":false},{"functionName":"_Future__chainForeignFuture_closure0","ranges":[{"startOffset":177098,"endOffset":177179,"count":0}],"isBlockCoverage":false},{"functionName":"_Future__chainForeignFuture_closure1","ranges":[{"startOffset":177223,"endOffset":177350,"count":0}],"isBlockCoverage":false},{"functionName":"_Future__asyncComplete_closure","ranges":[{"startOffset":177388,"endOffset":177489,"count":1}],"isBlockCoverage":true},{"functionName":"_Future__chainFuture_closure","ranges":[{"startOffset":177525,"endOffset":177624,"count":0}],"isBlockCoverage":false},{"functionName":"_Future__asyncCompleteError_closure","ranges":[{"startOffset":177667,"endOffset":177805,"count":0}],"isBlockCoverage":false},{"functionName":"_Future__propagateToListeners_handleWhenCompleteCallback","ranges":[{"startOffset":177869,"endOffset":178066,"count":1}],"isBlockCoverage":true},{"functionName":"_Future__propagateToListeners_handleWhenCompleteCallback_closure","ranges":[{"startOffset":178138,"endOffset":178255,"count":0}],"isBlockCoverage":false},{"functionName":"_Future__propagateToListeners_handleValueCallback","ranges":[{"startOffset":178312,"endOffset":178470,"count":1}],"isBlockCoverage":true},{"functionName":"_Future__propagateToListeners_handleError","ranges":[{"startOffset":178519,"endOffset":178663,"count":0}],"isBlockCoverage":false},{"functionName":"_AsyncCallbackEntry","ranges":[{"startOffset":178690,"endOffset":178780,"count":1}],"isBlockCoverage":true},{"functionName":"Stream","ranges":[{"startOffset":178794,"endOffset":178819,"count":0}],"isBlockCoverage":false},{"functionName":"Stream_Stream$fromFuture_closure","ranges":[{"startOffset":178859,"endOffset":178963,"count":0}],"isBlockCoverage":false},{"functionName":"Stream_Stream$fromFuture_closure0","ranges":[{"startOffset":179004,"endOffset":179086,"count":0}],"isBlockCoverage":false},{"functionName":"Stream_Stream$fromIterable_closure","ranges":[{"startOffset":179128,"endOffset":179232,"count":1}],"isBlockCoverage":true},{"functionName":"Stream_pipe_closure","ranges":[{"startOffset":179259,"endOffset":179331,"count":1}],"isBlockCoverage":true},{"functionName":"Stream_length_closure","ranges":[{"startOffset":179360,"endOffset":179453,"count":0}],"isBlockCoverage":false},{"functionName":"Stream_length_closure0","ranges":[{"startOffset":179483,"endOffset":179578,"count":0}],"isBlockCoverage":false},{"functionName":"Stream_first_closure","ranges":[{"startOffset":179606,"endOffset":179726,"count":1}],"isBlockCoverage":true},{"functionName":"Stream_first_closure0","ranges":[{"startOffset":179755,"endOffset":179821,"count":1}],"isBlockCoverage":true},{"functionName":"Stream_last_closure","ranges":[{"startOffset":179848,"endOffset":179939,"count":0}],"isBlockCoverage":false},{"functionName":"Stream_last_closure0","ranges":[{"startOffset":179967,"endOffset":180060,"count":0}],"isBlockCoverage":false},{"functionName":"Stream_firstWhere_closure","ranges":[{"startOffset":180093,"endOffset":180252,"count":1}],"isBlockCoverage":true},{"functionName":"Stream_firstWhere__closure","ranges":[{"startOffset":180286,"endOffset":180382,"count":1}],"isBlockCoverage":true},{"functionName":"Stream_firstWhere__closure0","ranges":[{"startOffset":180417,"endOffset":180544,"count":1}],"isBlockCoverage":true},{"functionName":"Stream_firstWhere_closure0","ranges":[{"startOffset":180578,"endOffset":180704,"count":1}],"isBlockCoverage":true},{"functionName":"StreamSubscription","ranges":[{"startOffset":180730,"endOffset":180767,"count":0}],"isBlockCoverage":false},{"functionName":"StreamTransformerBase","ranges":[{"startOffset":180796,"endOffset":180836,"count":0}],"isBlockCoverage":false},{"functionName":"_StreamController","ranges":[{"startOffset":180861,"endOffset":180897,"count":0}],"isBlockCoverage":false},{"functionName":"_StreamController__subscribe_closure","ranges":[{"startOffset":180941,"endOffset":181021,"count":1}],"isBlockCoverage":true},{"functionName":"_StreamController__recordCancel_complete","ranges":[{"startOffset":181069,"endOffset":181153,"count":1}],"isBlockCoverage":true},{"functionName":"_SyncStreamControllerDispatch","ranges":[{"startOffset":181190,"endOffset":181238,"count":0}],"isBlockCoverage":false},{"functionName":"_AsyncStreamControllerDispatch","ranges":[{"startOffset":181276,"endOffset":181325,"count":0}],"isBlockCoverage":false},{"functionName":"_AsyncStreamController","ranges":[{"startOffset":181355,"endOffset":181616,"count":0}],"isBlockCoverage":false},{"functionName":"_SyncStreamController","ranges":[{"startOffset":181645,"endOffset":181905,"count":1}],"isBlockCoverage":true},{"functionName":"_ControllerStream","ranges":[{"startOffset":181930,"endOffset":182022,"count":1}],"isBlockCoverage":true},{"functionName":"_ControllerSubscription","ranges":[{"startOffset":182053,"endOffset":182306,"count":1}],"isBlockCoverage":true},{"functionName":"_StreamSinkWrapper","ranges":[{"startOffset":182332,"endOffset":182428,"count":1}],"isBlockCoverage":true},{"functionName":"_AddStreamState","ranges":[{"startOffset":182451,"endOffset":182485,"count":0}],"isBlockCoverage":false},{"functionName":"_AddStreamState_makeErrorHandler_closure","ranges":[{"startOffset":182533,"endOffset":182622,"count":0}],"isBlockCoverage":false},{"functionName":"_AddStreamState_cancel_closure","ranges":[{"startOffset":182660,"endOffset":182734,"count":1}],"isBlockCoverage":true},{"functionName":"_StreamControllerAddStreamState","ranges":[{"startOffset":182773,"endOffset":182957,"count":1}],"isBlockCoverage":true},{"functionName":"_BufferingStreamSubscription","ranges":[{"startOffset":182993,"endOffset":183221,"count":1}],"isBlockCoverage":true},{"functionName":"_BufferingStreamSubscription__sendError_sendError","ranges":[{"startOffset":183278,"endOffset":183430,"count":0}],"isBlockCoverage":false},{"functionName":"_BufferingStreamSubscription__sendDone_sendDone","ranges":[{"startOffset":183485,"endOffset":183576,"count":0}],"isBlockCoverage":false},{"functionName":"_StreamImpl","ranges":[{"startOffset":183595,"endOffset":183625,"count":0}],"isBlockCoverage":false},{"functionName":"_GeneratedStreamImpl","ranges":[{"startOffset":183653,"endOffset":183773,"count":1}],"isBlockCoverage":true},{"functionName":"_IterablePendingEvents","ranges":[{"startOffset":183803,"endOffset":183928,"count":1}],"isBlockCoverage":true},{"functionName":"_DelayedEvent","ranges":[{"startOffset":183949,"endOffset":183981,"count":0}],"isBlockCoverage":false},{"functionName":"_DelayedData","ranges":[{"startOffset":184001,"endOffset":184106,"count":0}],"isBlockCoverage":false},{"functionName":"_DelayedError","ranges":[{"startOffset":184127,"endOffset":184240,"count":0}],"isBlockCoverage":false},{"functionName":"_DelayedDone","ranges":[{"startOffset":184260,"endOffset":184291,"count":1}],"isBlockCoverage":true},{"functionName":"_PendingEvents","ranges":[{"startOffset":184313,"endOffset":184346,"count":0}],"isBlockCoverage":false},{"functionName":"_PendingEvents_schedule_closure","ranges":[{"startOffset":184385,"endOffset":184490,"count":1}],"isBlockCoverage":true},{"functionName":"_StreamImplEvents","ranges":[{"startOffset":184515,"endOffset":184666,"count":0}],"isBlockCoverage":false},{"functionName":"_DoneStreamSubscription","ranges":[{"startOffset":184697,"endOffset":184849,"count":0}],"isBlockCoverage":false},{"functionName":"_StreamIterator","ranges":[{"startOffset":184872,"endOffset":184929,"count":0}],"isBlockCoverage":false},{"functionName":"_EmptyStream","ranges":[{"startOffset":184949,"endOffset":185003,"count":0}],"isBlockCoverage":false},{"functionName":"_cancelAndError_closure","ranges":[{"startOffset":185034,"endOffset":185161,"count":0}],"isBlockCoverage":false},{"functionName":"_cancelAndErrorClosure_closure","ranges":[{"startOffset":185199,"endOffset":185308,"count":1}],"isBlockCoverage":true},{"functionName":"_cancelAndValue_closure","ranges":[{"startOffset":185339,"endOffset":185434,"count":1}],"isBlockCoverage":true},{"functionName":"Timer","ranges":[{"startOffset":185447,"endOffset":185471,"count":0}],"isBlockCoverage":false},{"functionName":"AsyncError","ranges":[{"startOffset":185489,"endOffset":185575,"count":0}],"isBlockCoverage":false},{"functionName":"_ZoneFunction","ranges":[{"startOffset":185596,"endOffset":185708,"count":1}],"isBlockCoverage":true},{"functionName":"ZoneSpecification","ranges":[{"startOffset":185733,"endOffset":185769,"count":0}],"isBlockCoverage":false},{"functionName":"_ZoneSpecification","ranges":[{"startOffset":185795,"endOffset":186270,"count":1}],"isBlockCoverage":true},{"functionName":"ZoneDelegate","ranges":[{"startOffset":186290,"endOffset":186321,"count":0}],"isBlockCoverage":false},{"functionName":"Zone","ranges":[{"startOffset":186333,"endOffset":186356,"count":0}],"isBlockCoverage":false},{"functionName":"_ZoneDelegate","ranges":[{"startOffset":186377,"endOffset":186446,"count":1}],"isBlockCoverage":true},{"functionName":"_Zone","ranges":[{"startOffset":186459,"endOffset":186483,"count":0}],"isBlockCoverage":false},{"functionName":"_CustomZone","ranges":[{"startOffset":186502,"endOffset":186881,"count":1}],"isBlockCoverage":true},{"functionName":"_CustomZone_bindCallback_closure","ranges":[{"startOffset":186921,"endOffset":187052,"count":1}],"isBlockCoverage":true},{"functionName":"_CustomZone_bindUnaryCallback_closure","ranges":[{"startOffset":187097,"endOffset":187264,"count":0}],"isBlockCoverage":false},{"functionName":"_CustomZone_bindCallbackGuarded_closure","ranges":[{"startOffset":187311,"endOffset":187426,"count":1}],"isBlockCoverage":true},{"functionName":"_CustomZone_bindUnaryCallbackGuarded_closure","ranges":[{"startOffset":187478,"endOffset":187621,"count":1}],"isBlockCoverage":true},{"functionName":"_rootHandleUncaughtError_closure","ranges":[{"startOffset":187661,"endOffset":187770,"count":0}],"isBlockCoverage":false},{"functionName":"_RootZone","ranges":[{"startOffset":187787,"endOffset":187815,"count":1}],"isBlockCoverage":true},{"functionName":"_RootZone_bindCallback_closure","ranges":[{"startOffset":187853,"endOffset":187973,"count":0}],"isBlockCoverage":false},{"functionName":"_RootZone_bindCallbackGuarded_closure","ranges":[{"startOffset":188018,"endOffset":188122,"count":0}],"isBlockCoverage":false},{"functionName":"_RootZone_bindUnaryCallbackGuarded_closure","ranges":[{"startOffset":188172,"endOffset":188304,"count":0}],"isBlockCoverage":false},{"functionName":"runZoned_closure","ranges":[{"startOffset":188328,"endOffset":188389,"count":1}],"isBlockCoverage":true},{"functionName":"HashMap_HashMap","ranges":[{"startOffset":188412,"endOffset":188522,"count":1}],"isBlockCoverage":true},{"functionName":"_HashMap__getTableEntry","ranges":[{"startOffset":188553,"endOffset":188656,"count":0}],"isBlockCoverage":false},{"functionName":"_HashMap__setTableEntry","ranges":[{"startOffset":188687,"endOffset":188814,"count":1},{"startOffset":188750,"endOffset":188769,"count":0}],"isBlockCoverage":true},{"functionName":"_HashMap__newHashTable","ranges":[{"startOffset":188844,"endOffset":189036,"count":1}],"isBlockCoverage":true},{"functionName":"LinkedHashMap_LinkedHashMap","ranges":[{"startOffset":189071,"endOffset":189195,"count":1}],"isBlockCoverage":true},{"functionName":"LinkedHashMap_LinkedHashMap$_literal","ranges":[{"startOffset":189239,"endOffset":189480,"count":1}],"isBlockCoverage":true},{"functionName":"LinkedHashMap_LinkedHashMap$_empty","ranges":[{"startOffset":189522,"endOffset":189646,"count":1}],"isBlockCoverage":true},{"functionName":"LinkedHashSet_LinkedHashSet","ranges":[{"startOffset":189681,"endOffset":189769,"count":1}],"isBlockCoverage":true},{"functionName":"LinkedHashSet_LinkedHashSet$_empty","ranges":[{"startOffset":189811,"endOffset":189899,"count":1}],"isBlockCoverage":true},{"functionName":"LinkedHashSet_LinkedHashSet$_literal","ranges":[{"startOffset":189943,"endOffset":190104,"count":1}],"isBlockCoverage":true},{"functionName":"_LinkedHashSet__newHashTable","ranges":[{"startOffset":190140,"endOffset":190343,"count":1}],"isBlockCoverage":true},{"functionName":"_LinkedHashSetIterator$","ranges":[{"startOffset":190374,"endOffset":190595,"count":1}],"isBlockCoverage":true},{"functionName":"HashMap_HashMap$from","ranges":[{"startOffset":190623,"endOffset":190799,"count":1}],"isBlockCoverage":true},{"functionName":"IterableBase_iterableToShortString","ranges":[{"startOffset":190841,"endOffset":191704,"count":0}],"isBlockCoverage":false},{"functionName":"IterableBase_iterableToFullString","ranges":[{"startOffset":191745,"endOffset":192506,"count":0}],"isBlockCoverage":false},{"functionName":"_isToStringVisiting","ranges":[{"startOffset":192533,"endOffset":192718,"count":0}],"isBlockCoverage":false},{"functionName":"_iterablePartsToStrings","ranges":[{"startOffset":192749,"endOffset":195409,"count":0}],"isBlockCoverage":false},{"functionName":"LinkedHashMap_LinkedHashMap$from","ranges":[{"startOffset":195449,"endOffset":195649,"count":1}],"isBlockCoverage":true},{"functionName":"LinkedHashSet_LinkedHashSet$from","ranges":[{"startOffset":195689,"endOffset":195923,"count":1}],"isBlockCoverage":true},{"functionName":"MapBase_mapToString","ranges":[{"startOffset":195950,"endOffset":196637,"count":0}],"isBlockCoverage":false},{"functionName":"ListQueue$","ranges":[{"startOffset":196655,"endOffset":196883,"count":1}],"isBlockCoverage":true},{"functionName":"_ListQueueIterator$","ranges":[{"startOffset":196910,"endOffset":197072,"count":0}],"isBlockCoverage":false},{"functionName":"_HashMap","ranges":[{"startOffset":197088,"endOffset":197255,"count":1}],"isBlockCoverage":true},{"functionName":"_IdentityHashMap","ranges":[{"startOffset":197279,"endOffset":197454,"count":1}],"isBlockCoverage":true},{"functionName":"_HashMapKeyIterable","ranges":[{"startOffset":197481,"endOffset":197568,"count":0}],"isBlockCoverage":false},{"functionName":"_HashMapKeyIterator","ranges":[{"startOffset":197595,"endOffset":197778,"count":0}],"isBlockCoverage":false},{"functionName":"_LinkedHashSet","ranges":[{"startOffset":197800,"endOffset":198048,"count":1}],"isBlockCoverage":true},{"functionName":"_LinkedHashSetCell","ranges":[{"startOffset":198074,"endOffset":198205,"count":1}],"isBlockCoverage":true},{"functionName":"_LinkedHashSetIterator","ranges":[{"startOffset":198235,"endOffset":198443,"count":1}],"isBlockCoverage":true},{"functionName":"UnmodifiableListView","ranges":[{"startOffset":198471,"endOffset":198574,"count":0}],"isBlockCoverage":false},{"functionName":"HashMap_HashMap$from_closure","ranges":[{"startOffset":198610,"endOffset":198729,"count":1}],"isBlockCoverage":true},{"functionName":"IterableBase","ranges":[{"startOffset":198749,"endOffset":198780,"count":0}],"isBlockCoverage":false},{"functionName":"LinkedHashMap_LinkedHashMap$from_closure","ranges":[{"startOffset":198828,"endOffset":198959,"count":1}],"isBlockCoverage":true},{"functionName":"ListBase","ranges":[{"startOffset":198975,"endOffset":199002,"count":0}],"isBlockCoverage":false},{"functionName":"ListMixin","ranges":[{"startOffset":199019,"endOffset":199047,"count":0}],"isBlockCoverage":false},{"functionName":"MapBase","ranges":[{"startOffset":199062,"endOffset":199088,"count":0}],"isBlockCoverage":false},{"functionName":"MapBase_mapToString_closure","ranges":[{"startOffset":199123,"endOffset":199223,"count":0}],"isBlockCoverage":false},{"functionName":"MapMixin","ranges":[{"startOffset":199239,"endOffset":199266,"count":0}],"isBlockCoverage":false},{"functionName":"_UnmodifiableMapMixin","ranges":[{"startOffset":199295,"endOffset":199335,"count":0}],"isBlockCoverage":false},{"functionName":"MapView","ranges":[{"startOffset":199350,"endOffset":199376,"count":0}],"isBlockCoverage":false},{"functionName":"UnmodifiableMapView","ranges":[{"startOffset":199403,"endOffset":199490,"count":1}],"isBlockCoverage":true},{"functionName":"ListQueue","ranges":[{"startOffset":199507,"endOffset":199650,"count":1}],"isBlockCoverage":true},{"functionName":"_ListQueueIterator","ranges":[{"startOffset":199676,"endOffset":199903,"count":0}],"isBlockCoverage":false},{"functionName":"SetMixin","ranges":[{"startOffset":199919,"endOffset":199946,"count":0}],"isBlockCoverage":false},{"functionName":"SetBase","ranges":[{"startOffset":199961,"endOffset":199987,"count":0}],"isBlockCoverage":false},{"functionName":"_SetBase","ranges":[{"startOffset":200003,"endOffset":200030,"count":0}],"isBlockCoverage":false},{"functionName":"_ListBase_Object_ListMixin","ranges":[{"startOffset":200064,"endOffset":200109,"count":0}],"isBlockCoverage":false},{"functionName":"_SetBase_Object_SetMixin","ranges":[{"startOffset":200141,"endOffset":200184,"count":0}],"isBlockCoverage":false},{"functionName":"_UnmodifiableMapView_MapView__UnmodifiableMapMixin","ranges":[{"startOffset":200242,"endOffset":200311,"count":0}],"isBlockCoverage":false},{"functionName":"_parseJson","ranges":[{"startOffset":200329,"endOffset":200797,"count":0}],"isBlockCoverage":false},{"functionName":"_convertJsonToDartLazy","ranges":[{"startOffset":200827,"endOffset":201212,"count":0}],"isBlockCoverage":false},{"functionName":"Utf8Decoder__convertIntercepted","ranges":[{"startOffset":201251,"endOffset":201457,"count":0}],"isBlockCoverage":false},{"functionName":"Utf8Decoder__convertInterceptedUint8List","ranges":[{"startOffset":201505,"endOffset":202094,"count":0}],"isBlockCoverage":false},{"functionName":"Utf8Decoder__useTextDecoderChecked","ranges":[{"startOffset":202136,"endOffset":202310,"count":0}],"isBlockCoverage":false},{"functionName":"Utf8Decoder__useTextDecoderUnchecked","ranges":[{"startOffset":202354,"endOffset":202579,"count":0}],"isBlockCoverage":false},{"functionName":"Utf8Decoder__unsafe","ranges":[{"startOffset":202606,"endOffset":202845,"count":0}],"isBlockCoverage":false},{"functionName":"Utf8Decoder__makeDecoder","ranges":[{"startOffset":202877,"endOffset":203098,"count":0}],"isBlockCoverage":false},{"functionName":"_scanOneByteCharacters","ranges":[{"startOffset":203128,"endOffset":203470,"count":0}],"isBlockCoverage":false},{"functionName":"Base64Codec__checkPadding","ranges":[{"startOffset":203503,"endOffset":204114,"count":0}],"isBlockCoverage":false},{"functionName":"_JsonMap","ranges":[{"startOffset":204130,"endOffset":204243,"count":0}],"isBlockCoverage":false},{"functionName":"_JsonMapKeyIterable","ranges":[{"startOffset":204270,"endOffset":204335,"count":0}],"isBlockCoverage":false},{"functionName":"AsciiCodec","ranges":[{"startOffset":204353,"endOffset":204382,"count":1}],"isBlockCoverage":true},{"functionName":"_UnicodeSubsetEncoder","ranges":[{"startOffset":204411,"endOffset":204451,"count":0}],"isBlockCoverage":false},{"functionName":"AsciiEncoder","ranges":[{"startOffset":204471,"endOffset":204533,"count":1}],"isBlockCoverage":true},{"functionName":"Base64Codec","ranges":[{"startOffset":204552,"endOffset":204582,"count":1}],"isBlockCoverage":true},{"functionName":"Base64Encoder","ranges":[{"startOffset":204603,"endOffset":204635,"count":1}],"isBlockCoverage":true},{"functionName":"Codec","ranges":[{"startOffset":204648,"endOffset":204672,"count":0}],"isBlockCoverage":false},{"functionName":"_FusedCodec","ranges":[{"startOffset":204691,"endOffset":204810,"count":0}],"isBlockCoverage":false},{"functionName":"Converter","ranges":[{"startOffset":204827,"endOffset":204855,"count":0}],"isBlockCoverage":false},{"functionName":"Encoding","ranges":[{"startOffset":204871,"endOffset":204898,"count":0}],"isBlockCoverage":false},{"functionName":"JsonCodec","ranges":[{"startOffset":204915,"endOffset":204943,"count":1}],"isBlockCoverage":true},{"functionName":"JsonDecoder","ranges":[{"startOffset":204962,"endOffset":205020,"count":1}],"isBlockCoverage":true},{"functionName":"Utf8Codec","ranges":[{"startOffset":205037,"endOffset":205065,"count":1}],"isBlockCoverage":true},{"functionName":"Utf8Encoder","ranges":[{"startOffset":205084,"endOffset":205114,"count":1}],"isBlockCoverage":true},{"functionName":"_Utf8Encoder","ranges":[{"startOffset":205134,"endOffset":205235,"count":0}],"isBlockCoverage":false},{"functionName":"Utf8Decoder","ranges":[{"startOffset":205254,"endOffset":205319,"count":0}],"isBlockCoverage":false},{"functionName":"_Utf8Decoder","ranges":[{"startOffset":205339,"endOffset":205550,"count":0}],"isBlockCoverage":false},{"functionName":"int_parse","ranges":[{"startOffset":205567,"endOffset":205845,"count":0}],"isBlockCoverage":false},{"functionName":"Error__objectToString","ranges":[{"startOffset":205874,"endOffset":206053,"count":0}],"isBlockCoverage":false},{"functionName":"List_List$filled","ranges":[{"startOffset":206077,"endOffset":206334,"count":0}],"isBlockCoverage":false},{"functionName":"List_List$from","ranges":[{"startOffset":206356,"endOffset":206723,"count":1}],"isBlockCoverage":true},{"functionName":"List_List$unmodifiable","ranges":[{"startOffset":206753,"endOffset":206964,"count":1}],"isBlockCoverage":true},{"functionName":"String_String$fromCharCodes","ranges":[{"startOffset":206999,"endOffset":207622,"count":0}],"isBlockCoverage":false},{"functionName":"String_String$fromCharCode","ranges":[{"startOffset":207656,"endOffset":207738,"count":0}],"isBlockCoverage":false},{"functionName":"String__stringFromIterable","ranges":[{"startOffset":207772,"endOffset":208694,"count":0}],"isBlockCoverage":false},{"functionName":"RegExp_RegExp","ranges":[{"startOffset":208715,"endOffset":208868,"count":0}],"isBlockCoverage":false},{"functionName":"StringBuffer__writeAll","ranges":[{"startOffset":208898,"endOffset":209382,"count":0}],"isBlockCoverage":false},{"functionName":"Uri_base","ranges":[{"startOffset":209398,"endOffset":209596,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__uriEncode","ranges":[{"startOffset":209619,"endOffset":210718,"count":0}],"isBlockCoverage":false},{"functionName":"StackTrace_current","ranges":[{"startOffset":210744,"endOffset":211119,"count":1},{"startOffset":210908,"endOffset":211113,"count":0}],"isBlockCoverage":true},{"functionName":"DateTime__fourDigits","ranges":[{"startOffset":211147,"endOffset":211424,"count":0}],"isBlockCoverage":false},{"functionName":"DateTime__threeDigits","ranges":[{"startOffset":211453,"endOffset":211581,"count":0}],"isBlockCoverage":false},{"functionName":"DateTime__twoDigits","ranges":[{"startOffset":211608,"endOffset":211691,"count":0}],"isBlockCoverage":false},{"functionName":"Duration$","ranges":[{"startOffset":211708,"endOffset":211891,"count":1},{"startOffset":211794,"endOffset":211821,"count":0}],"isBlockCoverage":true},{"functionName":"Error_safeToString","ranges":[{"startOffset":211917,"endOffset":212177,"count":0}],"isBlockCoverage":false},{"functionName":"AssertionError$","ranges":[{"startOffset":212200,"endOffset":212269,"count":0}],"isBlockCoverage":false},{"functionName":"ArgumentError$","ranges":[{"startOffset":212291,"endOffset":212378,"count":0}],"isBlockCoverage":false},{"functionName":"ArgumentError$value","ranges":[{"startOffset":212405,"endOffset":212507,"count":0}],"isBlockCoverage":false},{"functionName":"ArgumentError$notNull","ranges":[{"startOffset":212536,"endOffset":212633,"count":0}],"isBlockCoverage":false},{"functionName":"RangeError$","ranges":[{"startOffset":212652,"endOffset":212776,"count":0}],"isBlockCoverage":false},{"functionName":"RangeError$value","ranges":[{"startOffset":212800,"endOffset":212915,"count":0}],"isBlockCoverage":false},{"functionName":"RangeError$range","ranges":[{"startOffset":212939,"endOffset":213100,"count":0}],"isBlockCoverage":false},{"functionName":"RangeError_checkValueInInterval","ranges":[{"startOffset":213139,"endOffset":213328,"count":0}],"isBlockCoverage":false},{"functionName":"RangeError_checkValidRange","ranges":[{"startOffset":213362,"endOffset":213728,"count":1},{"startOffset":213442,"endOffset":213518,"count":0},{"startOffset":213596,"endOffset":213672,"count":0},{"startOffset":213700,"endOffset":213727,"count":0}],"isBlockCoverage":true},{"functionName":"RangeError_checkNotNegative","ranges":[{"startOffset":213763,"endOffset":213959,"count":0}],"isBlockCoverage":false},{"functionName":"IndexError$","ranges":[{"startOffset":213978,"endOffset":214221,"count":0}],"isBlockCoverage":false},{"functionName":"UnsupportedError$","ranges":[{"startOffset":214246,"endOffset":214317,"count":0}],"isBlockCoverage":false},{"functionName":"UnimplementedError$","ranges":[{"startOffset":214344,"endOffset":214417,"count":0}],"isBlockCoverage":false},{"functionName":"StateError$","ranges":[{"startOffset":214436,"endOffset":214501,"count":0}],"isBlockCoverage":false},{"functionName":"ConcurrentModificationError$","ranges":[{"startOffset":214537,"endOffset":214633,"count":0}],"isBlockCoverage":false},{"functionName":"FormatException$","ranges":[{"startOffset":214657,"endOffset":214759,"count":0}],"isBlockCoverage":false},{"functionName":"List_List$generate","ranges":[{"startOffset":214785,"endOffset":215096,"count":1}],"isBlockCoverage":true},{"functionName":"Map_castFrom","ranges":[{"startOffset":215116,"endOffset":215276,"count":1}],"isBlockCoverage":true},{"functionName":"print","ranges":[{"startOffset":215289,"endOffset":215458,"count":0}],"isBlockCoverage":false},{"functionName":"_combineSurrogatePair","ranges":[{"startOffset":215487,"endOffset":215575,"count":0}],"isBlockCoverage":false},{"functionName":"Uri_parse","ranges":[{"startOffset":215592,"endOffset":222061,"count":1},{"startOffset":216121,"endOffset":216228,"count":0},{"startOffset":216270,"endOffset":216359,"count":0},{"startOffset":216950,"endOffset":216995,"count":0},{"startOffset":217075,"endOffset":217098,"count":0},{"startOffset":217195,"endOffset":217218,"count":0},{"startOffset":217284,"endOffset":217301,"count":0},{"startOffset":217506,"endOffset":217533,"count":0},{"startOffset":217584,"endOffset":217609,"count":0},{"startOffset":217656,"endOffset":217683,"count":0},{"startOffset":217733,"endOffset":217756,"count":0},{"startOffset":217798,"endOffset":217821,"count":0},{"startOffset":217869,"endOffset":217895,"count":0},{"startOffset":217945,"endOffset":217968,"count":0},{"startOffset":218399,"endOffset":218415,"count":0},{"startOffset":218500,"endOffset":218565,"count":0},{"startOffset":218652,"endOffset":218723,"count":0},{"startOffset":218766,"endOffset":218797,"count":0},{"startOffset":218798,"endOffset":218839,"count":0},{"startOffset":218936,"endOffset":218978,"count":0},{"startOffset":218999,"endOffset":219076,"count":0},{"startOffset":219213,"endOffset":219911,"count":0},{"startOffset":219947,"endOffset":220222,"count":0},{"startOffset":220275,"endOffset":221412,"count":0},{"startOffset":221479,"endOffset":221514,"count":0},{"startOffset":221584,"endOffset":221802,"count":0},{"startOffset":221927,"endOffset":222060,"count":0}],"isBlockCoverage":true},{"functionName":"Uri_decodeComponent","ranges":[{"startOffset":222088,"endOffset":222270,"count":0}],"isBlockCoverage":false},{"functionName":"Uri__parseIPv4Address","ranges":[{"startOffset":222299,"endOffset":223833,"count":0}],"isBlockCoverage":false},{"functionName":"Uri_parseIPv6Address","ranges":[{"startOffset":223861,"endOffset":226795,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__Uri$notSimple","ranges":[{"startOffset":226822,"endOffset":228163,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__Uri","ranges":[{"startOffset":228180,"endOffset":229390,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__defaultPort","ranges":[{"startOffset":229415,"endOffset":229553,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__fail","ranges":[{"startOffset":229571,"endOffset":229678,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__Uri$file","ranges":[{"startOffset":229700,"endOffset":229830,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__checkNonWindowsPathReservedCharacters","ranges":[{"startOffset":229881,"endOffset":230033,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__checkWindowsPathReservedCharacters","ranges":[{"startOffset":230081,"endOffset":230721,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__checkWindowsDriveLetter","ranges":[{"startOffset":230758,"endOffset":231242,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__makeFileUri","ranges":[{"startOffset":231267,"endOffset":231594,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__makeWindowsFileUrl","ranges":[{"startOffset":231626,"endOffset":234062,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__makePort","ranges":[{"startOffset":234084,"endOffset":234218,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__makeHost","ranges":[{"startOffset":234240,"endOffset":235817,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__checkZoneID","ranges":[{"startOffset":235842,"endOffset":236000,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__normalizeZoneID","ranges":[{"startOffset":236029,"endOffset":238805,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__normalizeRegName","ranges":[{"startOffset":238835,"endOffset":242233,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__makeScheme","ranges":[{"startOffset":242257,"endOffset":243253,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__canonicalizeScheme","ranges":[{"startOffset":243285,"endOffset":243546,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__makeUserInfo","ranges":[{"startOffset":243572,"endOffset":243741,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__makePath","ranges":[{"startOffset":243763,"endOffset":244818,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__normalizePath","ranges":[{"startOffset":244845,"endOffset":245122,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__makeQuery","ranges":[{"startOffset":245145,"endOffset":245323,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__makeFragment","ranges":[{"startOffset":245349,"endOffset":245519,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__normalizeEscape","ranges":[{"startOffset":245548,"endOffset":246720,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__escapeChar","ranges":[{"startOffset":246744,"endOffset":248292,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__normalizeOrSubstring","ranges":[{"startOffset":248326,"endOffset":248566,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__normalize","ranges":[{"startOffset":248589,"endOffset":251311,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__mayContainDotSegments","ranges":[{"startOffset":251346,"endOffset":251505,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__removeDotSegments","ranges":[{"startOffset":251536,"endOffset":252526,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__normalizeRelativePath","ranges":[{"startOffset":252561,"endOffset":254222,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__escapeScheme","ranges":[{"startOffset":254248,"endOffset":254933,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__toWindowsFilePath","ranges":[{"startOffset":254964,"endOffset":255945,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__hexCharPairToByte","ranges":[{"startOffset":255976,"endOffset":256491,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__uriDecode","ranges":[{"startOffset":256514,"endOffset":258126,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__isAlphabeticCharacter","ranges":[{"startOffset":258161,"endOffset":258274,"count":0}],"isBlockCoverage":false},{"functionName":"UriData__writeUri","ranges":[{"startOffset":258299,"endOffset":258967,"count":0}],"isBlockCoverage":false},{"functionName":"UriData__validateMimeType","ranges":[{"startOffset":259000,"endOffset":259351,"count":0}],"isBlockCoverage":false},{"functionName":"UriData__parse","ranges":[{"startOffset":259373,"endOffset":261418,"count":0}],"isBlockCoverage":false},{"functionName":"UriData__uriEncodeBytes","ranges":[{"startOffset":261449,"endOffset":262927,"count":0}],"isBlockCoverage":false},{"functionName":"_createTables","ranges":[{"startOffset":262948,"endOffset":267507,"count":1}],"isBlockCoverage":true},{"functionName":"_scan","ranges":[{"startOffset":267520,"endOffset":268208,"count":1},{"startOffset":267816,"endOffset":267846,"count":0},{"startOffset":267957,"endOffset":267967,"count":0},{"startOffset":268012,"endOffset":268040,"count":0}],"isBlockCoverage":true},{"functionName":"bool","ranges":[{"startOffset":268220,"endOffset":268243,"count":0}],"isBlockCoverage":false},{"functionName":"DateTime","ranges":[{"startOffset":268259,"endOffset":268339,"count":0}],"isBlockCoverage":false},{"functionName":"double","ranges":[{"startOffset":268353,"endOffset":268378,"count":0}],"isBlockCoverage":false},{"functionName":"Duration","ranges":[{"startOffset":268394,"endOffset":268450,"count":1}],"isBlockCoverage":true},{"functionName":"Duration_toString_sixDigits","ranges":[{"startOffset":268485,"endOffset":268531,"count":0}],"isBlockCoverage":false},{"functionName":"Duration_toString_twoDigits","ranges":[{"startOffset":268566,"endOffset":268612,"count":0}],"isBlockCoverage":false},{"functionName":"Error","ranges":[{"startOffset":268625,"endOffset":268649,"count":0}],"isBlockCoverage":false},{"functionName":"AssertionError","ranges":[{"startOffset":268671,"endOffset":268731,"count":0}],"isBlockCoverage":false},{"functionName":"NullThrownError","ranges":[{"startOffset":268754,"endOffset":268788,"count":0}],"isBlockCoverage":false},{"functionName":"ArgumentError","ranges":[{"startOffset":268809,"endOffset":268967,"count":0}],"isBlockCoverage":false},{"functionName":"RangeError","ranges":[{"startOffset":268985,"endOffset":269186,"count":0}],"isBlockCoverage":false},{"functionName":"IndexError","ranges":[{"startOffset":269204,"endOffset":269384,"count":0}],"isBlockCoverage":false},{"functionName":"UnsupportedError","ranges":[{"startOffset":269408,"endOffset":269470,"count":0}],"isBlockCoverage":false},{"functionName":"UnimplementedError","ranges":[{"startOffset":269496,"endOffset":269560,"count":0}],"isBlockCoverage":false},{"functionName":"StateError","ranges":[{"startOffset":269578,"endOffset":269634,"count":0}],"isBlockCoverage":false},{"functionName":"ConcurrentModificationError","ranges":[{"startOffset":269669,"endOffset":269749,"count":0}],"isBlockCoverage":false},{"functionName":"OutOfMemoryError","ranges":[{"startOffset":269773,"endOffset":269808,"count":1}],"isBlockCoverage":true},{"functionName":"StackOverflowError","ranges":[{"startOffset":269834,"endOffset":269871,"count":0}],"isBlockCoverage":false},{"functionName":"CyclicInitializationError","ranges":[{"startOffset":269904,"endOffset":269980,"count":0}],"isBlockCoverage":false},{"functionName":"_Exception","ranges":[{"startOffset":269998,"endOffset":270054,"count":0}],"isBlockCoverage":false},{"functionName":"FormatException","ranges":[{"startOffset":270077,"endOffset":270194,"count":0}],"isBlockCoverage":false},{"functionName":"Expando","ranges":[{"startOffset":270209,"endOffset":270321,"count":1}],"isBlockCoverage":true},{"functionName":"Function","ranges":[{"startOffset":270337,"endOffset":270364,"count":0}],"isBlockCoverage":false},{"functionName":"int","ranges":[{"startOffset":270375,"endOffset":270397,"count":0}],"isBlockCoverage":false},{"functionName":"Iterable","ranges":[{"startOffset":270413,"endOffset":270440,"count":0}],"isBlockCoverage":false},{"functionName":"Iterator","ranges":[{"startOffset":270456,"endOffset":270483,"count":0}],"isBlockCoverage":false},{"functionName":"List","ranges":[{"startOffset":270495,"endOffset":270518,"count":0}],"isBlockCoverage":false},{"functionName":"Map","ranges":[{"startOffset":270529,"endOffset":270551,"count":0}],"isBlockCoverage":false},{"functionName":"MapEntry","ranges":[{"startOffset":270567,"endOffset":270669,"count":1}],"isBlockCoverage":true},{"functionName":"Null","ranges":[{"startOffset":270681,"endOffset":270704,"count":0}],"isBlockCoverage":false},{"functionName":"num","ranges":[{"startOffset":270715,"endOffset":270737,"count":0}],"isBlockCoverage":false},{"functionName":"Object","ranges":[{"startOffset":270751,"endOffset":270776,"count":1}],"isBlockCoverage":true},{"functionName":"Pattern","ranges":[{"startOffset":270791,"endOffset":270817,"count":0}],"isBlockCoverage":false},{"functionName":"Match","ranges":[{"startOffset":270830,"endOffset":270854,"count":0}],"isBlockCoverage":false},{"functionName":"RegExpMatch","ranges":[{"startOffset":270873,"endOffset":270903,"count":0}],"isBlockCoverage":false},{"functionName":"Set","ranges":[{"startOffset":270914,"endOffset":270936,"count":0}],"isBlockCoverage":false},{"functionName":"StackTrace","ranges":[{"startOffset":270954,"endOffset":270983,"count":0}],"isBlockCoverage":false},{"functionName":"_StringStackTrace","ranges":[{"startOffset":271008,"endOffset":271075,"count":0}],"isBlockCoverage":false},{"functionName":"Stopwatch","ranges":[{"startOffset":271092,"endOffset":271162,"count":0}],"isBlockCoverage":false},{"functionName":"String","ranges":[{"startOffset":271176,"endOffset":271201,"count":0}],"isBlockCoverage":false},{"functionName":"Runes","ranges":[{"startOffset":271214,"endOffset":271264,"count":0}],"isBlockCoverage":false},{"functionName":"RuneIterator","ranges":[{"startOffset":271284,"endOffset":271439,"count":0}],"isBlockCoverage":false},{"functionName":"StringBuffer","ranges":[{"startOffset":271459,"endOffset":271519,"count":0}],"isBlockCoverage":false},{"functionName":"Uri","ranges":[{"startOffset":271530,"endOffset":271552,"count":0}],"isBlockCoverage":false},{"functionName":"Uri__parseIPv4Address_error","ranges":[{"startOffset":271587,"endOffset":271657,"count":0}],"isBlockCoverage":false},{"functionName":"Uri_parseIPv6Address_error","ranges":[{"startOffset":271691,"endOffset":271760,"count":0}],"isBlockCoverage":false},{"functionName":"Uri_parseIPv6Address_parseHex","ranges":[{"startOffset":271797,"endOffset":271896,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri","ranges":[{"startOffset":271908,"endOffset":272185,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__Uri$notSimple_closure","ranges":[{"startOffset":272220,"endOffset":272320,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__checkNonWindowsPathReservedCharacters_closure","ranges":[{"startOffset":272379,"endOffset":272482,"count":0}],"isBlockCoverage":false},{"functionName":"_Uri__makePath_closure","ranges":[{"startOffset":272512,"endOffset":272553,"count":0}],"isBlockCoverage":false},{"functionName":"UriData","ranges":[{"startOffset":272568,"endOffset":272689,"count":0}],"isBlockCoverage":false},{"functionName":"_createTables_closure","ranges":[{"startOffset":272718,"endOffset":272758,"count":1}],"isBlockCoverage":true},{"functionName":"_createTables_build","ranges":[{"startOffset":272785,"endOffset":272849,"count":1}],"isBlockCoverage":true},{"functionName":"_createTables_setChars","ranges":[{"startOffset":272879,"endOffset":272920,"count":1}],"isBlockCoverage":true},{"functionName":"_createTables_setRange","ranges":[{"startOffset":272950,"endOffset":272991,"count":1}],"isBlockCoverage":true},{"functionName":"_SimpleUri","ranges":[{"startOffset":273009,"endOffset":273320,"count":1}],"isBlockCoverage":true},{"functionName":"_DataUri","ranges":[{"startOffset":273336,"endOffset":273617,"count":0}],"isBlockCoverage":false},{"functionName":"_StructuredClone","ranges":[{"startOffset":273641,"endOffset":273676,"count":0}],"isBlockCoverage":false},{"functionName":"_StructuredClone_walk_closure","ranges":[{"startOffset":273713,"endOffset":273814,"count":1}],"isBlockCoverage":true},{"functionName":"_StructuredClone_walk_closure0","ranges":[{"startOffset":273852,"endOffset":273954,"count":0}],"isBlockCoverage":false},{"functionName":"_AcceptStructuredClone","ranges":[{"startOffset":273984,"endOffset":274025,"count":0}],"isBlockCoverage":false},{"functionName":"_AcceptStructuredClone_walk_closure","ranges":[{"startOffset":274068,"endOffset":274175,"count":1}],"isBlockCoverage":true},{"functionName":"_StructuredCloneDart2Js","ranges":[{"startOffset":274206,"endOffset":274302,"count":1}],"isBlockCoverage":true},{"functionName":"_AcceptStructuredCloneDart2Js","ranges":[{"startOffset":274339,"endOffset":274470,"count":1}],"isBlockCoverage":true},{"functionName":"_convertDataTree","ranges":[{"startOffset":274494,"endOffset":274639,"count":1}],"isBlockCoverage":true},{"functionName":"promiseToFuture","ranges":[{"startOffset":274662,"endOffset":275033,"count":0}],"isBlockCoverage":false},{"functionName":"_convertDataTree__convert","ranges":[{"startOffset":275066,"endOffset":275147,"count":1}],"isBlockCoverage":true},{"functionName":"promiseToFuture_closure","ranges":[{"startOffset":275178,"endOffset":275272,"count":0}],"isBlockCoverage":false},{"functionName":"promiseToFuture_closure0","ranges":[{"startOffset":275304,"endOffset":275376,"count":0}],"isBlockCoverage":false},{"functionName":"ByteBuffer","ranges":[{"startOffset":275394,"endOffset":275423,"count":0}],"isBlockCoverage":false},{"functionName":"ByteData","ranges":[{"startOffset":275439,"endOffset":275466,"count":0}],"isBlockCoverage":false},{"functionName":"Int8List","ranges":[{"startOffset":275482,"endOffset":275509,"count":0}],"isBlockCoverage":false},{"functionName":"Uint8List","ranges":[{"startOffset":275526,"endOffset":275554,"count":0}],"isBlockCoverage":false},{"functionName":"Uint8ClampedList","ranges":[{"startOffset":275578,"endOffset":275613,"count":0}],"isBlockCoverage":false},{"functionName":"Int16List","ranges":[{"startOffset":275630,"endOffset":275658,"count":0}],"isBlockCoverage":false},{"functionName":"Uint16List","ranges":[{"startOffset":275676,"endOffset":275705,"count":0}],"isBlockCoverage":false},{"functionName":"Int32List","ranges":[{"startOffset":275722,"endOffset":275750,"count":0}],"isBlockCoverage":false},{"functionName":"Uint32List","ranges":[{"startOffset":275768,"endOffset":275797,"count":0}],"isBlockCoverage":false},{"functionName":"Float32List","ranges":[{"startOffset":275816,"endOffset":275846,"count":0}],"isBlockCoverage":false},{"functionName":"Float64List","ranges":[{"startOffset":275865,"endOffset":275895,"count":0}],"isBlockCoverage":false},{"functionName":"SqlError","ranges":[{"startOffset":275911,"endOffset":275938,"count":0}],"isBlockCoverage":false},{"functionName":"max","ranges":[{"startOffset":275949,"endOffset":276119,"count":0}],"isBlockCoverage":false},{"functionName":"pow","ranges":[{"startOffset":276130,"endOffset":276195,"count":0}],"isBlockCoverage":false},{"functionName":"_EventStreamSubscription$","ranges":[{"startOffset":276240,"endOffset":276575,"count":1},{"startOffset":276327,"endOffset":276333,"count":0}],"isBlockCoverage":true},{"functionName":"_wrapZone","ranges":[{"startOffset":276592,"endOffset":276771,"count":1},{"startOffset":276705,"endOffset":276770,"count":0}],"isBlockCoverage":true},{"functionName":"ApplicationCacheErrorEvent","ranges":[{"startOffset":276805,"endOffset":276850,"count":0}],"isBlockCoverage":false},{"functionName":"Blob","ranges":[{"startOffset":276862,"endOffset":276885,"count":0}],"isBlockCoverage":false},{"functionName":"DomError","ranges":[{"startOffset":276901,"endOffset":276928,"count":0}],"isBlockCoverage":false},{"functionName":"DomException","ranges":[{"startOffset":276948,"endOffset":276979,"count":0}],"isBlockCoverage":false},{"functionName":"ErrorEvent","ranges":[{"startOffset":276997,"endOffset":277026,"count":0}],"isBlockCoverage":false},{"functionName":"Event","ranges":[{"startOffset":277039,"endOffset":277063,"count":0}],"isBlockCoverage":false},{"functionName":"EventTarget","ranges":[{"startOffset":277082,"endOffset":277112,"count":0}],"isBlockCoverage":false},{"functionName":"File","ranges":[{"startOffset":277124,"endOffset":277147,"count":0}],"isBlockCoverage":false},{"functionName":"Location","ranges":[{"startOffset":277163,"endOffset":277190,"count":0}],"isBlockCoverage":false},{"functionName":"MediaError","ranges":[{"startOffset":277208,"endOffset":277237,"count":0}],"isBlockCoverage":false},{"functionName":"MediaKeyMessageEvent","ranges":[{"startOffset":277265,"endOffset":277304,"count":0}],"isBlockCoverage":false},{"functionName":"MessageEvent","ranges":[{"startOffset":277324,"endOffset":277355,"count":0}],"isBlockCoverage":false},{"functionName":"MessagePort","ranges":[{"startOffset":277374,"endOffset":277404,"count":0}],"isBlockCoverage":false},{"functionName":"NavigatorUserMediaError","ranges":[{"startOffset":277435,"endOffset":277477,"count":0}],"isBlockCoverage":false},{"functionName":"OverconstrainedError","ranges":[{"startOffset":277505,"endOffset":277544,"count":0}],"isBlockCoverage":false},{"functionName":"PositionError","ranges":[{"startOffset":277565,"endOffset":277597,"count":0}],"isBlockCoverage":false},{"functionName":"PresentationConnectionCloseEvent","ranges":[{"startOffset":277637,"endOffset":277688,"count":0}],"isBlockCoverage":false},{"functionName":"SpeechRecognitionError","ranges":[{"startOffset":277718,"endOffset":277759,"count":0}],"isBlockCoverage":false},{"functionName":"EventStreamProvider","ranges":[{"startOffset":277786,"endOffset":277847,"count":0}],"isBlockCoverage":false},{"functionName":"_EventStream","ranges":[{"startOffset":277867,"endOffset":278029,"count":1}],"isBlockCoverage":true},{"functionName":"_EventStreamSubscription","ranges":[{"startOffset":278061,"endOffset":278292,"count":1}],"isBlockCoverage":true},{"functionName":"_EventStreamSubscription_closure","ranges":[{"startOffset":278332,"endOffset":278409,"count":1}],"isBlockCoverage":true},{"functionName":"AsyncMemoizer","ranges":[{"startOffset":278437,"endOffset":278540,"count":0}],"isBlockCoverage":false},{"functionName":"NullStreamSink","ranges":[{"startOffset":278558,"endOffset":278715,"count":0}],"isBlockCoverage":false},{"functionName":"NullStreamSink_addStream_closure","ranges":[{"startOffset":278751,"endOffset":278827,"count":0}],"isBlockCoverage":false},{"functionName":"Validator","ranges":[{"startOffset":278840,"endOffset":278898,"count":0}],"isBlockCoverage":false},{"functionName":"SpanScanner$","ranges":[{"startOffset":278918,"endOffset":279265,"count":0}],"isBlockCoverage":false},{"functionName":"SpanScanner","ranges":[{"startOffset":279284,"endOffset":279530,"count":0}],"isBlockCoverage":false},{"functionName":"_SpanScannerState","ranges":[{"startOffset":279555,"endOffset":279663,"count":0}],"isBlockCoverage":false},{"functionName":"RemoteListener_start","ranges":[{"startOffset":279691,"endOffset":280824,"count":1}],"isBlockCoverage":true},{"functionName":"RemoteListener__deserializeSet","ranges":[{"startOffset":280862,"endOffset":281054,"count":1},{"startOffset":280911,"endOffset":280923,"count":0},{"startOffset":280979,"endOffset":281053,"count":0}],"isBlockCoverage":true},{"functionName":"RemoteListener__sendLoadException","ranges":[{"startOffset":281095,"endOffset":281308,"count":0}],"isBlockCoverage":false},{"functionName":"RemoteListener__sendError","ranges":[{"startOffset":281341,"endOffset":281720,"count":0}],"isBlockCoverage":false},{"functionName":"RemoteListener","ranges":[{"startOffset":281742,"endOffset":281833,"count":1}],"isBlockCoverage":true},{"functionName":"RemoteListener_start_closure","ranges":[{"startOffset":281869,"endOffset":281974,"count":1}],"isBlockCoverage":true},{"functionName":"RemoteListener_start_closure0","ranges":[{"startOffset":282011,"endOffset":282059,"count":1}],"isBlockCoverage":true},{"functionName":"RemoteListener_start_closure1","ranges":[{"startOffset":282096,"endOffset":282348,"count":1}],"isBlockCoverage":true},{"functionName":"RemoteListener_start__closure","ranges":[{"startOffset":282385,"endOffset":282637,"count":1}],"isBlockCoverage":true},{"functionName":"RemoteListener_start___closure","ranges":[{"startOffset":282675,"endOffset":282905,"count":1}],"isBlockCoverage":true},{"functionName":"RemoteListener_start____closure","ranges":[{"startOffset":282944,"endOffset":283053,"count":1}],"isBlockCoverage":true},{"functionName":"RemoteListener_start____closure0","ranges":[{"startOffset":283093,"endOffset":283229,"count":1}],"isBlockCoverage":true},{"functionName":"RemoteListener_start_____closure","ranges":[{"startOffset":283269,"endOffset":283405,"count":1}],"isBlockCoverage":true},{"functionName":"RemoteListener_start___closure0","ranges":[{"startOffset":283444,"endOffset":283549,"count":1}],"isBlockCoverage":true},{"functionName":"RemoteListener__serializeGroup_closure","ranges":[{"startOffset":283595,"endOffset":283734,"count":1}],"isBlockCoverage":true},{"functionName":"RemoteListener__serializeTest_closure","ranges":[{"startOffset":283779,"endOffset":283951,"count":1}],"isBlockCoverage":true},{"functionName":"RemoteListener__runLiveTest_closure","ranges":[{"startOffset":283994,"endOffset":284076,"count":1}],"isBlockCoverage":true},{"functionName":"RemoteListener__runLiveTest_closure0","ranges":[{"startOffset":284120,"endOffset":284202,"count":1}],"isBlockCoverage":true},{"functionName":"RemoteListener__runLiveTest_closure1","ranges":[{"startOffset":284246,"endOffset":284358,"count":1}],"isBlockCoverage":true},{"functionName":"RemoteListener__runLiveTest_closure2","ranges":[{"startOffset":284402,"endOffset":284511,"count":1}],"isBlockCoverage":true},{"functionName":"RemoteListener__runLiveTest_closure3","ranges":[{"startOffset":284555,"endOffset":284667,"count":1}],"isBlockCoverage":true},{"functionName":"RemoteListener__runLiveTest__closure","ranges":[{"startOffset":284711,"endOffset":284793,"count":1}],"isBlockCoverage":true},{"functionName":"DelegatingSink","ranges":[{"startOffset":284822,"endOffset":284911,"count":0}],"isBlockCoverage":false},{"functionName":"None","ranges":[{"startOffset":284919,"endOffset":284942,"count":1}],"isBlockCoverage":true},{"functionName":"Scanner","ranges":[{"startOffset":284953,"endOffset":285079,"count":0}],"isBlockCoverage":false},{"functionName":"EmptyUnmodifiableSet","ranges":[{"startOffset":285103,"endOffset":285165,"count":1}],"isBlockCoverage":true},{"functionName":"Style__getPlatformStyle","ranges":[{"startOffset":285196,"endOffset":285573,"count":0}],"isBlockCoverage":false},{"functionName":"Style","ranges":[{"startOffset":285586,"endOffset":285610,"count":0}],"isBlockCoverage":false},{"functionName":"Pool$","ranges":[{"startOffset":285623,"endOffset":286231,"count":0}],"isBlockCoverage":false},{"functionName":"Pool","ranges":[{"startOffset":286243,"endOffset":286547,"count":0}],"isBlockCoverage":false},{"functionName":"Pool_close_closure","ranges":[{"startOffset":286573,"endOffset":286635,"count":0}],"isBlockCoverage":false},{"functionName":"Pool__onResourceReleaseAllowed_closure","ranges":[{"startOffset":286681,"endOffset":286794,"count":0}],"isBlockCoverage":false},{"functionName":"Pool__runOnRelease_closure","ranges":[{"startOffset":286828,"endOffset":286898,"count":0}],"isBlockCoverage":false},{"functionName":"Pool__runOnRelease_closure0","ranges":[{"startOffset":286933,"endOffset":287004,"count":0}],"isBlockCoverage":false},{"functionName":"PoolResource","ranges":[{"startOffset":287024,"endOffset":287110,"count":0}],"isBlockCoverage":false},{"functionName":"mapStackTrace","ranges":[{"startOffset":287131,"endOffset":288220,"count":0}],"isBlockCoverage":false},{"functionName":"_prettifyMember","ranges":[{"startOffset":288243,"endOffset":289263,"count":0}],"isBlockCoverage":false},{"functionName":"mapStackTrace_closure","ranges":[{"startOffset":289292,"endOffset":289456,"count":0}],"isBlockCoverage":false},{"functionName":"mapStackTrace_closure0","ranges":[{"startOffset":289486,"endOffset":289676,"count":0}],"isBlockCoverage":false},{"functionName":"mapStackTrace_closure1","ranges":[{"startOffset":289706,"endOffset":289747,"count":0}],"isBlockCoverage":false},{"functionName":"_prettifyMember_closure","ranges":[{"startOffset":289778,"endOffset":289820,"count":0}],"isBlockCoverage":false},{"functionName":"_prettifyMember_closure0","ranges":[{"startOffset":289852,"endOffset":289895,"count":0}],"isBlockCoverage":false},{"functionName":"StackZoneSpecification","ranges":[{"startOffset":289925,"endOffset":290121,"count":1}],"isBlockCoverage":true},{"functionName":"StackZoneSpecification_chainFor_closure","ranges":[{"startOffset":290168,"endOffset":290252,"count":0}],"isBlockCoverage":false},{"functionName":"StackZoneSpecification_chainFor_closure0","ranges":[{"startOffset":290300,"endOffset":290414,"count":0}],"isBlockCoverage":false},{"functionName":"StackZoneSpecification__registerCallback_closure","ranges":[{"startOffset":290470,"endOffset":290642,"count":1}],"isBlockCoverage":true},{"functionName":"StackZoneSpecification__registerUnaryCallback_closure","ranges":[{"startOffset":290703,"endOffset":290900,"count":1}],"isBlockCoverage":true},{"functionName":"StackZoneSpecification__registerUnaryCallback__closure","ranges":[{"startOffset":290962,"endOffset":291104,"count":1}],"isBlockCoverage":true},{"functionName":"StackZoneSpecification__registerBinaryCallback_closure","ranges":[{"startOffset":291166,"endOffset":291386,"count":1}],"isBlockCoverage":true},{"functionName":"StackZoneSpecification__registerBinaryCallback__closure","ranges":[{"startOffset":291449,"endOffset":291627,"count":1}],"isBlockCoverage":true},{"functionName":"StackZoneSpecification__currentTrace_closure","ranges":[{"startOffset":291679,"endOffset":291827,"count":1}],"isBlockCoverage":true},{"functionName":"_Node","ranges":[{"startOffset":291840,"endOffset":291919,"count":1}],"isBlockCoverage":true},{"functionName":"Group$","ranges":[{"startOffset":291933,"endOffset":292150,"count":1}],"isBlockCoverage":true},{"functionName":"Group","ranges":[{"startOffset":292163,"endOffset":292362,"count":1}],"isBlockCoverage":true},{"functionName":"Group_forPlatform_closure","ranges":[{"startOffset":292395,"endOffset":292467,"count":1}],"isBlockCoverage":true},{"functionName":"Group__map_closure","ranges":[{"startOffset":292493,"endOffset":292558,"count":1}],"isBlockCoverage":true},{"functionName":"Group__map_closure0","ranges":[{"startOffset":292585,"endOffset":292623,"count":1}],"isBlockCoverage":true},{"functionName":"Metadata__parseOnPlatform","ranges":[{"startOffset":292656,"endOffset":292775,"count":1}],"isBlockCoverage":true},{"functionName":"Metadata__parseTags","ranges":[{"startOffset":292802,"endOffset":292889,"count":1}],"isBlockCoverage":true},{"functionName":"Metadata_Metadata","ranges":[{"startOffset":292914,"endOffset":293928,"count":1},{"startOffset":293321,"endOffset":293340,"count":0},{"startOffset":293880,"endOffset":293927,"count":0}],"isBlockCoverage":true},{"functionName":"Metadata$_","ranges":[{"startOffset":293946,"endOffset":294846,"count":1},{"startOffset":294749,"endOffset":294795,"count":0}],"isBlockCoverage":true},{"functionName":"Metadata$parse","ranges":[{"startOffset":294868,"endOffset":295398,"count":1},{"startOffset":294999,"endOffset":295008,"count":0},{"startOffset":295061,"endOffset":295067,"count":0},{"startOffset":295301,"endOffset":295347,"count":0}],"isBlockCoverage":true},{"functionName":"Metadata$deserialize","ranges":[{"startOffset":295426,"endOffset":296886,"count":1},{"startOffset":295595,"endOffset":295675,"count":0},{"startOffset":296451,"endOffset":296672,"count":0}],"isBlockCoverage":true},{"functionName":"Metadata__deserializeTimeout","ranges":[{"startOffset":296922,"endOffset":297350,"count":1},{"startOffset":297058,"endOffset":297085,"count":0},{"startOffset":297241,"endOffset":297349,"count":0}],"isBlockCoverage":true},{"functionName":"Metadata","ranges":[{"startOffset":297366,"endOffset":297685,"count":1}],"isBlockCoverage":true},{"functionName":"Metadata_Metadata__unresolved","ranges":[{"startOffset":297722,"endOffset":298035,"count":1}],"isBlockCoverage":true},{"functionName":"Metadata_Metadata_closure","ranges":[{"startOffset":298068,"endOffset":298138,"count":1}],"isBlockCoverage":true},{"functionName":"Metadata$deserialize_closure","ranges":[{"startOffset":298174,"endOffset":298221,"count":1}],"isBlockCoverage":true},{"functionName":"Metadata__validateTags_closure","ranges":[{"startOffset":298259,"endOffset":298308,"count":1}],"isBlockCoverage":true},{"functionName":"Metadata__validateTags_closure0","ranges":[{"startOffset":298347,"endOffset":298397,"count":1}],"isBlockCoverage":true},{"functionName":"Metadata_validatePlatformSelectors_closure","ranges":[{"startOffset":298447,"endOffset":298542,"count":1}],"isBlockCoverage":true},{"functionName":"Metadata_merge_closure","ranges":[{"startOffset":298572,"endOffset":298613,"count":1}],"isBlockCoverage":true},{"functionName":"Metadata_merge_closure0","ranges":[{"startOffset":298644,"endOffset":298686,"count":1}],"isBlockCoverage":true},{"functionName":"Metadata_forPlatform_closure","ranges":[{"startOffset":298722,"endOffset":298825,"count":0}],"isBlockCoverage":false},{"functionName":"Metadata_serialize_closure","ranges":[{"startOffset":298859,"endOffset":298944,"count":1}],"isBlockCoverage":true},{"functionName":"Metadata_serialize_closure0","ranges":[{"startOffset":298979,"endOffset":299025,"count":1}],"isBlockCoverage":true},{"functionName":"IterableSet","ranges":[{"startOffset":299044,"endOffset":299138,"count":0}],"isBlockCoverage":false},{"functionName":"_IterableSet_SetMixin_UnmodifiableSetMixin","ranges":[{"startOffset":299188,"endOffset":299249,"count":0}],"isBlockCoverage":false},{"functionName":"Engine$","ranges":[{"startOffset":299264,"endOffset":300874,"count":0}],"isBlockCoverage":false},{"functionName":"Engine","ranges":[{"startOffset":300888,"endOffset":301558,"count":0}],"isBlockCoverage":false},{"functionName":"Engine_success_closure","ranges":[{"startOffset":301588,"endOffset":301629,"count":0}],"isBlockCoverage":false},{"functionName":"Engine_closure","ranges":[{"startOffset":301651,"endOffset":301709,"count":0}],"isBlockCoverage":false},{"functionName":"Engine_closure0","ranges":[{"startOffset":301732,"endOffset":301766,"count":0}],"isBlockCoverage":false},{"functionName":"Engine_run_closure","ranges":[{"startOffset":301792,"endOffset":301854,"count":0}],"isBlockCoverage":false},{"functionName":"Engine_run__closure","ranges":[{"startOffset":301881,"endOffset":301971,"count":0}],"isBlockCoverage":false},{"functionName":"Engine_run___closure","ranges":[{"startOffset":301999,"endOffset":302125,"count":0}],"isBlockCoverage":false},{"functionName":"Engine_run____closure","ranges":[{"startOffset":302154,"endOffset":302220,"count":0}],"isBlockCoverage":false},{"functionName":"Engine_run_closure0","ranges":[{"startOffset":302247,"endOffset":302338,"count":0}],"isBlockCoverage":false},{"functionName":"Engine__runLiveTest_closure","ranges":[{"startOffset":302373,"endOffset":302474,"count":0}],"isBlockCoverage":false},{"functionName":"Engine__runLiveTest_closure0","ranges":[{"startOffset":302510,"endOffset":302610,"count":0}],"isBlockCoverage":false},{"functionName":"Engine__runLiveTest_closure1","ranges":[{"startOffset":302646,"endOffset":302693,"count":0}],"isBlockCoverage":false},{"functionName":"Engine__runSkippedTest_closure","ranges":[{"startOffset":302731,"endOffset":302780,"count":0}],"isBlockCoverage":false},{"functionName":"Engine__runSkippedTest_closure0","ranges":[{"startOffset":302819,"endOffset":302924,"count":0}],"isBlockCoverage":false},{"functionName":"Engine__runSkippedTest_closure1","ranges":[{"startOffset":302963,"endOffset":303013,"count":0}],"isBlockCoverage":false},{"functionName":"binarySearch","ranges":[{"startOffset":303033,"endOffset":303712,"count":0}],"isBlockCoverage":false},{"functionName":"DelegatingStreamSubscription","ranges":[{"startOffset":303755,"endOffset":303802,"count":0}],"isBlockCoverage":false},{"functionName":"StreamCompleter","ranges":[{"startOffset":303821,"endOffset":303907,"count":1}],"isBlockCoverage":true},{"functionName":"_CompleterStream","ranges":[{"startOffset":303927,"endOffset":304055,"count":1}],"isBlockCoverage":true},{"functionName":"BooleanSelectorImpl","ranges":[{"startOffset":304078,"endOffset":304145,"count":0}],"isBlockCoverage":false},{"functionName":"mapMap","ranges":[{"startOffset":304159,"endOffset":304498,"count":1}],"isBlockCoverage":true},{"functionName":"mergeMaps","ranges":[{"startOffset":304515,"endOffset":304721,"count":1}],"isBlockCoverage":true},{"functionName":"mapMap_closure","ranges":[{"startOffset":304743,"endOffset":304846,"count":1}],"isBlockCoverage":true},{"functionName":"mapMap_closure0","ranges":[{"startOffset":304869,"endOffset":305013,"count":1}],"isBlockCoverage":true},{"functionName":"mergeMaps_closure","ranges":[{"startOffset":305038,"endOffset":305181,"count":1}],"isBlockCoverage":true},{"functionName":"UnionSetController$","ranges":[{"startOffset":305208,"endOffset":305497,"count":0}],"isBlockCoverage":false},{"functionName":"UnionSetController","ranges":[{"startOffset":305523,"endOffset":305678,"count":0}],"isBlockCoverage":false},{"functionName":"_IsTrue","ranges":[{"startOffset":305693,"endOffset":305719,"count":1}],"isBlockCoverage":true},{"functionName":"_Predicate","ranges":[{"startOffset":305737,"endOffset":305868,"count":0}],"isBlockCoverage":false},{"functionName":"FileLocation$_","ranges":[{"startOffset":305890,"endOffset":306294,"count":0}],"isBlockCoverage":false},{"functionName":"_FileSpan$","ranges":[{"startOffset":306312,"endOffset":306850,"count":0}],"isBlockCoverage":false},{"functionName":"SourceFile","ranges":[{"startOffset":306868,"endOffset":307027,"count":0}],"isBlockCoverage":false},{"functionName":"FileLocation","ranges":[{"startOffset":307047,"endOffset":307130,"count":0}],"isBlockCoverage":false},{"functionName":"_FileSpan","ranges":[{"startOffset":307147,"endOffset":307265,"count":0}],"isBlockCoverage":false},{"functionName":"SourceSpanMixin","ranges":[{"startOffset":307288,"endOffset":307322,"count":0}],"isBlockCoverage":false},{"functionName":"Trace_Trace$current","ranges":[{"startOffset":307349,"endOffset":307488,"count":0}],"isBlockCoverage":false},{"functionName":"Trace_Trace$from","ranges":[{"startOffset":307512,"endOffset":307838,"count":1},{"startOffset":307563,"endOffset":307639,"count":0},{"startOffset":307695,"endOffset":307837,"count":0}],"isBlockCoverage":true},{"functionName":"Trace_Trace$parse","ranges":[{"startOffset":307863,"endOffset":309377,"count":0}],"isBlockCoverage":false},{"functionName":"Trace__parseVM","ranges":[{"startOffset":309399,"endOffset":310090,"count":0}],"isBlockCoverage":false},{"functionName":"Trace$parseV8","ranges":[{"startOffset":310111,"endOffset":310662,"count":0}],"isBlockCoverage":false},{"functionName":"Trace$parseJSCore","ranges":[{"startOffset":310687,"endOffset":311118,"count":0}],"isBlockCoverage":false},{"functionName":"Trace$parseFirefox","ranges":[{"startOffset":311144,"endOffset":311604,"count":0}],"isBlockCoverage":false},{"functionName":"Trace$parseFriendly","ranges":[{"startOffset":311631,"endOffset":312181,"count":0}],"isBlockCoverage":false},{"functionName":"Trace","ranges":[{"startOffset":312194,"endOffset":312274,"count":0}],"isBlockCoverage":false},{"functionName":"Trace_Trace$current_closure","ranges":[{"startOffset":312309,"endOffset":312407,"count":0}],"isBlockCoverage":false},{"functionName":"Trace_Trace$from_closure","ranges":[{"startOffset":312439,"endOffset":312507,"count":0}],"isBlockCoverage":false},{"functionName":"Trace__parseVM_closure","ranges":[{"startOffset":312537,"endOffset":312578,"count":0}],"isBlockCoverage":false},{"functionName":"Trace$parseV8_closure","ranges":[{"startOffset":312607,"endOffset":312647,"count":0}],"isBlockCoverage":false},{"functionName":"Trace$parseV8_closure0","ranges":[{"startOffset":312677,"endOffset":312718,"count":0}],"isBlockCoverage":false},{"functionName":"Trace$parseJSCore_closure","ranges":[{"startOffset":312751,"endOffset":312795,"count":0}],"isBlockCoverage":false},{"functionName":"Trace$parseJSCore_closure0","ranges":[{"startOffset":312829,"endOffset":312874,"count":0}],"isBlockCoverage":false},{"functionName":"Trace$parseFirefox_closure","ranges":[{"startOffset":312908,"endOffset":312953,"count":0}],"isBlockCoverage":false},{"functionName":"Trace$parseFirefox_closure0","ranges":[{"startOffset":312988,"endOffset":313034,"count":0}],"isBlockCoverage":false},{"functionName":"Trace$parseFriendly_closure","ranges":[{"startOffset":313069,"endOffset":313115,"count":0}],"isBlockCoverage":false},{"functionName":"Trace$parseFriendly_closure0","ranges":[{"startOffset":313151,"endOffset":313198,"count":0}],"isBlockCoverage":false},{"functionName":"Trace_foldFrames_closure","ranges":[{"startOffset":313230,"endOffset":313305,"count":0}],"isBlockCoverage":false},{"functionName":"Trace_foldFrames_closure0","ranges":[{"startOffset":313338,"endOffset":313408,"count":0}],"isBlockCoverage":false},{"functionName":"Trace_toString_closure0","ranges":[{"startOffset":313439,"endOffset":313481,"count":0}],"isBlockCoverage":false},{"functionName":"Trace_toString_closure","ranges":[{"startOffset":313511,"endOffset":313579,"count":0}],"isBlockCoverage":false},{"functionName":"RunnerSuite","ranges":[{"startOffset":313598,"endOffset":313764,"count":0}],"isBlockCoverage":false},{"functionName":"RunnerSuiteController","ranges":[{"startOffset":313793,"endOffset":314020,"count":0}],"isBlockCoverage":false},{"functionName":"RunnerSuiteController__close_closure","ranges":[{"startOffset":314064,"endOffset":314144,"count":0}],"isBlockCoverage":false},{"functionName":"FutureGroup","ranges":[{"startOffset":314170,"endOffset":314384,"count":0}],"isBlockCoverage":false},{"functionName":"FutureGroup_add_closure","ranges":[{"startOffset":314411,"endOffset":314505,"count":0}],"isBlockCoverage":false},{"functionName":"FutureGroup_add_closure0","ranges":[{"startOffset":314533,"endOffset":314601,"count":0}],"isBlockCoverage":false},{"functionName":"ValueResult","ranges":[{"startOffset":314616,"endOffset":314696,"count":1}],"isBlockCoverage":true},{"functionName":"PackageConfigResolver__normalizeMap","ranges":[{"startOffset":314739,"endOffset":314975,"count":1}],"isBlockCoverage":true},{"functionName":"PackageConfigResolver","ranges":[{"startOffset":315004,"endOffset":315080,"count":1}],"isBlockCoverage":true},{"functionName":"PackageConfigResolver__normalizeMap_closure","ranges":[{"startOffset":315131,"endOffset":315193,"count":1}],"isBlockCoverage":true},{"functionName":"UrlStyle","ranges":[{"startOffset":315209,"endOffset":315397,"count":0}],"isBlockCoverage":false},{"functionName":"ErrorResult","ranges":[{"startOffset":315423,"endOffset":315510,"count":0}],"isBlockCoverage":false},{"functionName":"SourceLocation$","ranges":[{"startOffset":315533,"endOffset":316255,"count":0}],"isBlockCoverage":false},{"functionName":"SourceLocation","ranges":[{"startOffset":316277,"endOffset":316429,"count":0}],"isBlockCoverage":false},{"functionName":"SourceSpan","ranges":[{"startOffset":316447,"endOffset":316476,"count":0}],"isBlockCoverage":false},{"functionName":"SourceSpanBase","ranges":[{"startOffset":316498,"endOffset":316531,"count":0}],"isBlockCoverage":false},{"functionName":"GroupEntry","ranges":[{"startOffset":316549,"endOffset":316578,"count":0}],"isBlockCoverage":false},{"functionName":"LiveTestController$","ranges":[{"startOffset":316605,"endOffset":317396,"count":1}],"isBlockCoverage":true},{"functionName":"_LiveTest","ranges":[{"startOffset":317413,"endOffset":317494,"count":1}],"isBlockCoverage":true},{"functionName":"LiveTestController","ranges":[{"startOffset":317520,"endOffset":318000,"count":1}],"isBlockCoverage":true},{"functionName":"Test","ranges":[{"startOffset":318012,"endOffset":318035,"count":0}],"isBlockCoverage":false},{"functionName":"errorsDontStopTest","ranges":[{"startOffset":318061,"endOffset":318525,"count":0}],"isBlockCoverage":false},{"functionName":"errorsDontStopTest_closure","ranges":[{"startOffset":318559,"endOffset":318659,"count":0}],"isBlockCoverage":false},{"functionName":"errorsDontStopTest_closure0","ranges":[{"startOffset":318694,"endOffset":318740,"count":0}],"isBlockCoverage":false},{"functionName":"Result","ranges":[{"startOffset":318761,"endOffset":318786,"count":0}],"isBlockCoverage":false},{"functionName":"StringDescription","ranges":[{"startOffset":318807,"endOffset":318867,"count":0}],"isBlockCoverage":false},{"functionName":"FeatureMatcher","ranges":[{"startOffset":318885,"endOffset":318918,"count":0}],"isBlockCoverage":false},{"functionName":"PosixStyle","ranges":[{"startOffset":318932,"endOffset":319073,"count":0}],"isBlockCoverage":false},{"functionName":"StringScannerException$","ranges":[{"startOffset":319104,"endOffset":319201,"count":0}],"isBlockCoverage":false},{"functionName":"StringScannerException","ranges":[{"startOffset":319231,"endOffset":319359,"count":0}],"isBlockCoverage":false},{"functionName":"PlatformSelector$parse","ranges":[{"startOffset":319389,"endOffset":319570,"count":0}],"isBlockCoverage":false},{"functionName":"PlatformSelector__wrapFormatException","ranges":[{"startOffset":319615,"endOffset":319694,"count":0}],"isBlockCoverage":false},{"functionName":"PlatformSelector","ranges":[{"startOffset":319718,"endOffset":319798,"count":1}],"isBlockCoverage":true},{"functionName":"PlatformSelector$parse_closure","ranges":[{"startOffset":319836,"endOffset":319913,"count":0}],"isBlockCoverage":false},{"functionName":"PlatformSelector_validate_closure","ranges":[{"startOffset":319954,"endOffset":320067,"count":0}],"isBlockCoverage":false},{"functionName":"PlatformSelector_validate__closure","ranges":[{"startOffset":320109,"endOffset":320196,"count":0}],"isBlockCoverage":false},{"functionName":"PlatformSelector_evaluate_closure","ranges":[{"startOffset":320237,"endOffset":320317,"count":1}],"isBlockCoverage":true},{"functionName":"SuitePlatform$","ranges":[{"startOffset":320339,"endOffset":320703,"count":1},{"startOffset":320429,"endOffset":320433,"count":0},{"startOffset":320533,"endOffset":320640,"count":0}],"isBlockCoverage":true},{"functionName":"SuitePlatform","ranges":[{"startOffset":320724,"endOffset":320837,"count":1}],"isBlockCoverage":true},{"functionName":"StackTraceMapper","ranges":[{"startOffset":320861,"endOffset":320896,"count":0}],"isBlockCoverage":false},{"functionName":"LiveSuite","ranges":[{"startOffset":320913,"endOffset":320941,"count":0}],"isBlockCoverage":false},{"functionName":"JSStackTraceMapper_deserialize","ranges":[{"startOffset":320979,"endOffset":321921,"count":1},{"startOffset":321375,"endOffset":321508,"count":0}],"isBlockCoverage":true},{"functionName":"JSStackTraceMapper__deserializePackageConfigMap","ranges":[{"startOffset":321976,"endOffset":322130,"count":1}],"isBlockCoverage":true},{"functionName":"JSStackTraceMapper","ranges":[{"startOffset":322156,"endOffset":322355,"count":1}],"isBlockCoverage":true},{"functionName":"JSStackTraceMapper__deserializePackageConfigMap_closure","ranges":[{"startOffset":322418,"endOffset":322492,"count":1}],"isBlockCoverage":true},{"functionName":"StreamGroup","ranges":[{"startOffset":322518,"endOffset":322755,"count":0}],"isBlockCoverage":false},{"functionName":"StreamGroup_add_closure","ranges":[{"startOffset":322782,"endOffset":322824,"count":0}],"isBlockCoverage":false},{"functionName":"StreamGroup_add_closure0","ranges":[{"startOffset":322852,"endOffset":322948,"count":0}],"isBlockCoverage":false},{"functionName":"StreamGroup__onListen_closure","ranges":[{"startOffset":322981,"endOffset":323054,"count":0}],"isBlockCoverage":false},{"functionName":"StreamGroup__onCancelBroadcast_closure","ranges":[{"startOffset":323096,"endOffset":323178,"count":0}],"isBlockCoverage":false},{"functionName":"StreamGroup__listenToStream_closure","ranges":[{"startOffset":323217,"endOffset":323324,"count":0}],"isBlockCoverage":false},{"functionName":"_StreamGroupState","ranges":[{"startOffset":323345,"endOffset":323405,"count":1}],"isBlockCoverage":true},{"functionName":"Token","ranges":[{"startOffset":323414,"endOffset":323488,"count":0}],"isBlockCoverage":false},{"functionName":"IdentifierToken","ranges":[{"startOffset":323507,"endOffset":323591,"count":0}],"isBlockCoverage":false},{"functionName":"TokenType","ranges":[{"startOffset":323604,"endOffset":323656,"count":1}],"isBlockCoverage":true},{"functionName":"UnmodifiableSetView$","ranges":[{"startOffset":323684,"endOffset":323800,"count":0}],"isBlockCoverage":false},{"functionName":"UnmodifiableSetView","ranges":[{"startOffset":323827,"endOffset":323915,"count":1}],"isBlockCoverage":true},{"functionName":"UnmodifiableSetMixin","ranges":[{"startOffset":323943,"endOffset":323982,"count":0}],"isBlockCoverage":false},{"functionName":"_UnmodifiableSetView_DelegatingSet_UnmodifiableSetMixin","ranges":[{"startOffset":324045,"endOffset":324119,"count":0}],"isBlockCoverage":false},{"functionName":"WindowsStyle","ranges":[{"startOffset":324139,"endOffset":324331,"count":0}],"isBlockCoverage":false},{"functionName":"WindowsStyle_absolutePathToUri_closure","ranges":[{"startOffset":324377,"endOffset":324434,"count":0}],"isBlockCoverage":false},{"functionName":"decodeVlq","ranges":[{"startOffset":324451,"endOffset":325682,"count":0}],"isBlockCoverage":false},{"functionName":"closure","ranges":[{"startOffset":325697,"endOffset":325723,"count":0}],"isBlockCoverage":false},{"functionName":"internalBootstrapBrowserTest","ranges":[{"startOffset":325759,"endOffset":326211,"count":1}],"isBlockCoverage":true},{"functionName":"internalBootstrapBrowserTest_closure","ranges":[{"startOffset":326255,"endOffset":326310,"count":1}],"isBlockCoverage":true},{"functionName":"StreamQueue","ranges":[{"startOffset":326336,"endOffset":326620,"count":1}],"isBlockCoverage":true},{"functionName":"StreamQueue__ensureListening_closure","ranges":[{"startOffset":326660,"endOffset":326740,"count":1}],"isBlockCoverage":true},{"functionName":"StreamQueue__ensureListening_closure1","ranges":[{"startOffset":326781,"endOffset":326862,"count":1}],"isBlockCoverage":true},{"functionName":"StreamQueue__ensureListening_closure0","ranges":[{"startOffset":326903,"endOffset":326984,"count":1}],"isBlockCoverage":true},{"functionName":"_EventRequest","ranges":[{"startOffset":327001,"endOffset":327033,"count":0}],"isBlockCoverage":false},{"functionName":"_NextRequest","ranges":[{"startOffset":327049,"endOffset":327135,"count":1}],"isBlockCoverage":true},{"functionName":"_RestRequest","ranges":[{"startOffset":327151,"endOffset":327271,"count":1}],"isBlockCoverage":true},{"functionName":"Parser","ranges":[{"startOffset":327281,"endOffset":327343,"count":0}],"isBlockCoverage":false},{"functionName":"Matcher","ranges":[{"startOffset":327354,"endOffset":327380,"count":0}],"isBlockCoverage":false},{"functionName":"SourceMapSpan","ranges":[{"startOffset":327397,"endOffset":327547,"count":0}],"isBlockCoverage":false},{"functionName":"SourceSpanFormatException$","ranges":[{"startOffset":327581,"endOffset":327682,"count":0}],"isBlockCoverage":false},{"functionName":"SourceSpanException","ranges":[{"startOffset":327709,"endOffset":327747,"count":0}],"isBlockCoverage":false},{"functionName":"SourceSpanFormatException","ranges":[{"startOffset":327780,"endOffset":327911,"count":0}],"isBlockCoverage":false},{"functionName":"State","ranges":[{"startOffset":327924,"endOffset":328002,"count":1}],"isBlockCoverage":true},{"functionName":"Status","ranges":[{"startOffset":328016,"endOffset":328065,"count":1}],"isBlockCoverage":true},{"functionName":"Result0","ranges":[{"startOffset":328080,"endOffset":328130,"count":1}],"isBlockCoverage":true},{"functionName":"expect","ranges":[{"startOffset":328144,"endOffset":328244,"count":1}],"isBlockCoverage":true},{"functionName":"_expect","ranges":[{"startOffset":328259,"endOffset":329408,"count":1},{"startOffset":328467,"endOffset":328550,"count":0},{"startOffset":328759,"endOffset":328803,"count":0},{"startOffset":329097,"endOffset":329407,"count":0}],"isBlockCoverage":true},{"functionName":"fail","ranges":[{"startOffset":329420,"endOffset":329505,"count":0}],"isBlockCoverage":false},{"functionName":"formatFailure","ranges":[{"startOffset":329526,"endOffset":330135,"count":0}],"isBlockCoverage":false},{"functionName":"TestFailure","ranges":[{"startOffset":330154,"endOffset":330211,"count":0}],"isBlockCoverage":false},{"functionName":"_expect_closure0","ranges":[{"startOffset":330235,"endOffset":330270,"count":0}],"isBlockCoverage":false},{"functionName":"_expect_closure","ranges":[{"startOffset":330293,"endOffset":330327,"count":1}],"isBlockCoverage":true},{"functionName":"method1","ranges":[{"startOffset":330342,"endOffset":330388,"count":1}],"isBlockCoverage":true},{"functionName":"method2","ranges":[{"startOffset":330403,"endOffset":330449,"count":0}],"isBlockCoverage":false},{"functionName":"main0","ranges":[{"startOffset":330462,"endOffset":330529,"count":1}],"isBlockCoverage":true},{"functionName":"main_closure0","ranges":[{"startOffset":330550,"endOffset":330582,"count":1}],"isBlockCoverage":true},{"functionName":"main__closure","ranges":[{"startOffset":330603,"endOffset":330635,"count":1}],"isBlockCoverage":true},{"functionName":"StreamSinkCompleter","ranges":[{"startOffset":330669,"endOffset":330756,"count":1}],"isBlockCoverage":true},{"functionName":"_CompleterSink","ranges":[{"startOffset":330774,"endOffset":330961,"count":1}],"isBlockCoverage":true},{"functionName":"_CompleterSink__setDestinationSink_closure","ranges":[{"startOffset":331007,"endOffset":331068,"count":0}],"isBlockCoverage":false},{"functionName":"SubscriptionStream","ranges":[{"startOffset":331090,"endOffset":331200,"count":1}],"isBlockCoverage":true},{"functionName":"_CancelOnErrorSubscriptionWrapper","ranges":[{"startOffset":331237,"endOffset":331362,"count":0}],"isBlockCoverage":false},{"functionName":"_CancelOnErrorSubscriptionWrapper_onError_closure","ranges":[{"startOffset":331415,"endOffset":331541,"count":0}],"isBlockCoverage":false},{"functionName":"_CancelOnErrorSubscriptionWrapper_onError__closure","ranges":[{"startOffset":331595,"endOffset":331754,"count":0}],"isBlockCoverage":false},{"functionName":"Evaluator","ranges":[{"startOffset":331767,"endOffset":331825,"count":0}],"isBlockCoverage":false},{"functionName":"parseJsonExtended","ranges":[{"startOffset":331850,"endOffset":332085,"count":0}],"isBlockCoverage":false},{"functionName":"parseJson","ranges":[{"startOffset":332102,"endOffset":332830,"count":0}],"isBlockCoverage":false},{"functionName":"MultiSectionMapping$fromJson","ranges":[{"startOffset":332866,"endOffset":333186,"count":0}],"isBlockCoverage":false},{"functionName":"MappingBundle$fromJson","ranges":[{"startOffset":333216,"endOffset":333428,"count":0}],"isBlockCoverage":false},{"functionName":"SingleMapping$fromJson","ranges":[{"startOffset":333458,"endOffset":334453,"count":0}],"isBlockCoverage":false},{"functionName":"Mapping","ranges":[{"startOffset":334468,"endOffset":334494,"count":0}],"isBlockCoverage":false},{"functionName":"MultiSectionMapping","ranges":[{"startOffset":334521,"endOffset":334650,"count":0}],"isBlockCoverage":false},{"functionName":"MappingBundle","ranges":[{"startOffset":334671,"endOffset":334732,"count":0}],"isBlockCoverage":false},{"functionName":"SingleMapping","ranges":[{"startOffset":334753,"endOffset":335018,"count":0}],"isBlockCoverage":false},{"functionName":"SingleMapping$fromJson_closure","ranges":[{"startOffset":335056,"endOffset":335130,"count":0}],"isBlockCoverage":false},{"functionName":"SingleMapping__findLine_closure","ranges":[{"startOffset":335169,"endOffset":335243,"count":0}],"isBlockCoverage":false},{"functionName":"SingleMapping__findColumn_closure","ranges":[{"startOffset":335284,"endOffset":335362,"count":0}],"isBlockCoverage":false},{"functionName":"TargetLineEntry","ranges":[{"startOffset":335385,"endOffset":335472,"count":0}],"isBlockCoverage":false},{"functionName":"TargetEntry","ranges":[{"startOffset":335491,"endOffset":335685,"count":0}],"isBlockCoverage":false},{"functionName":"_MappingTokenizer","ranges":[{"startOffset":335710,"endOffset":335835,"count":0}],"isBlockCoverage":false},{"functionName":"_TokenKind","ranges":[{"startOffset":335853,"endOffset":335972,"count":1}],"isBlockCoverage":true},{"functionName":"LazyTrace","ranges":[{"startOffset":335989,"endOffset":336093,"count":1}],"isBlockCoverage":true},{"functionName":"LazyTrace_foldFrames_closure","ranges":[{"startOffset":336129,"endOffset":336259,"count":0}],"isBlockCoverage":false},{"functionName":"RuntimeSelection","ranges":[{"startOffset":336283,"endOffset":336318,"count":0}],"isBlockCoverage":false},{"functionName":"BooleanSelector","ranges":[{"startOffset":336348,"endOffset":336382,"count":0}],"isBlockCoverage":false},{"functionName":"All","ranges":[{"startOffset":336389,"endOffset":336411,"count":1}],"isBlockCoverage":true},{"functionName":"ParsedPath_ParsedPath$parse","ranges":[{"startOffset":336446,"endOffset":337648,"count":0}],"isBlockCoverage":false},{"functionName":"ParsedPath","ranges":[{"startOffset":337666,"endOffset":337813,"count":0}],"isBlockCoverage":false},{"functionName":"ParsedPath_normalize_closure","ranges":[{"startOffset":337849,"endOffset":337921,"count":0}],"isBlockCoverage":false},{"functionName":"PathException$","ranges":[{"startOffset":337943,"endOffset":338011,"count":0}],"isBlockCoverage":false},{"functionName":"PathException","ranges":[{"startOffset":338032,"endOffset":338091,"count":0}],"isBlockCoverage":false},{"functionName":"SourceSpanWithContext$","ranges":[{"startOffset":338121,"endOffset":338709,"count":0}],"isBlockCoverage":false},{"functionName":"SourceSpanWithContext","ranges":[{"startOffset":338738,"endOffset":338892,"count":0}],"isBlockCoverage":false},{"functionName":"LazyChain","ranges":[{"startOffset":338909,"endOffset":339001,"count":0}],"isBlockCoverage":false},{"functionName":"LazyChain_foldFrames_closure","ranges":[{"startOffset":339037,"endOffset":339167,"count":0}],"isBlockCoverage":false},{"functionName":"LazyChain_toTrace_closure","ranges":[{"startOffset":339200,"endOffset":339269,"count":0}],"isBlockCoverage":false},{"functionName":"StringScanner","ranges":[{"startOffset":339290,"endOffset":339322,"count":0}],"isBlockCoverage":false},{"functionName":"Declarer$","ranges":[{"startOffset":339339,"endOffset":340044,"count":1},{"startOffset":339457,"endOffset":339548,"count":0},{"startOffset":339600,"endOffset":339626,"count":0}],"isBlockCoverage":true},{"functionName":"Declarer","ranges":[{"startOffset":340060,"endOffset":340568,"count":1}],"isBlockCoverage":true},{"functionName":"Declarer_test_closure","ranges":[{"startOffset":340597,"endOffset":340688,"count":1}],"isBlockCoverage":true},{"functionName":"Declarer_test__closure","ranges":[{"startOffset":340718,"endOffset":340810,"count":1}],"isBlockCoverage":true},{"functionName":"Declarer_test___closure","ranges":[{"startOffset":340841,"endOffset":340934,"count":1}],"isBlockCoverage":true},{"functionName":"Declarer_group_closure","ranges":[{"startOffset":340964,"endOffset":341029,"count":1}],"isBlockCoverage":true},{"functionName":"Declarer_build_closure","ranges":[{"startOffset":341059,"endOffset":341125,"count":1}],"isBlockCoverage":true},{"functionName":"Declarer__runSetUps_closure","ranges":[{"startOffset":341160,"endOffset":341206,"count":1}],"isBlockCoverage":true},{"functionName":"Declarer__tearDownAll_closure","ranges":[{"startOffset":341243,"endOffset":341316,"count":0}],"isBlockCoverage":false},{"functionName":"Declarer__tearDownAll__closure","ranges":[{"startOffset":341354,"endOffset":341428,"count":0}],"isBlockCoverage":false},{"functionName":"Declarer__tearDownAll___closure","ranges":[{"startOffset":341467,"endOffset":341542,"count":0}],"isBlockCoverage":false},{"functionName":"PrintSink","ranges":[{"startOffset":341559,"endOffset":341626,"count":0}],"isBlockCoverage":false},{"functionName":"_expandSafe","ranges":[{"startOffset":341657,"endOffset":341839,"count":0}],"isBlockCoverage":false},{"functionName":"VariableNode","ranges":[{"startOffset":341859,"endOffset":341940,"count":0}],"isBlockCoverage":false},{"functionName":"NotNode","ranges":[{"startOffset":341955,"endOffset":342032,"count":0}],"isBlockCoverage":false},{"functionName":"OrNode","ranges":[{"startOffset":342046,"endOffset":342122,"count":0}],"isBlockCoverage":false},{"functionName":"AndNode","ranges":[{"startOffset":342137,"endOffset":342214,"count":0}],"isBlockCoverage":false},{"functionName":"ConditionalNode","ranges":[{"startOffset":342237,"endOffset":342361,"count":0}],"isBlockCoverage":false},{"functionName":"Highlighter__normalizeNewlines","ranges":[{"startOffset":342399,"endOffset":343195,"count":0}],"isBlockCoverage":false},{"functionName":"Highlighter__normalizeTrailingNewline","ranges":[{"startOffset":343240,"endOffset":344711,"count":0}],"isBlockCoverage":false},{"functionName":"Highlighter__normalizeEndOfLine","ranges":[{"startOffset":344750,"endOffset":345414,"count":0}],"isBlockCoverage":false},{"functionName":"Highlighter__lastLineLength","ranges":[{"startOffset":345449,"endOffset":345775,"count":0}],"isBlockCoverage":false},{"functionName":"Highlighter","ranges":[{"startOffset":345794,"endOffset":345999,"count":0}],"isBlockCoverage":false},{"functionName":"Highlighter__writeFirstLine_closure","ranges":[{"startOffset":346042,"endOffset":346147,"count":0}],"isBlockCoverage":false},{"functionName":"Highlighter__writeFirstLine_closure0","ranges":[{"startOffset":346191,"endOffset":346303,"count":0}],"isBlockCoverage":false},{"functionName":"Highlighter__writeFirstLine_closure1","ranges":[{"startOffset":346347,"endOffset":346455,"count":0}],"isBlockCoverage":false},{"functionName":"Highlighter__writeFirstLine_closure2","ranges":[{"startOffset":346499,"endOffset":346607,"count":0}],"isBlockCoverage":false},{"functionName":"Highlighter__writeIntermediateLines_closure","ranges":[{"startOffset":346658,"endOffset":346771,"count":0}],"isBlockCoverage":false},{"functionName":"Highlighter__writeLastLine_closure","ranges":[{"startOffset":346813,"endOffset":346917,"count":0}],"isBlockCoverage":false},{"functionName":"Highlighter__writeLastLine_closure0","ranges":[{"startOffset":346960,"endOffset":347071,"count":0}],"isBlockCoverage":false},{"functionName":"Highlighter__writeLastLine_closure1","ranges":[{"startOffset":347114,"endOffset":347221,"count":0}],"isBlockCoverage":false},{"functionName":"Highlighter__writeSidebar_closure","ranges":[{"startOffset":347262,"endOffset":347390,"count":0}],"isBlockCoverage":false},{"functionName":"Chain_capture","ranges":[{"startOffset":347411,"endOffset":348428,"count":1},{"startOffset":347512,"endOffset":347565,"count":0},{"startOffset":347633,"endOffset":347760,"count":0}],"isBlockCoverage":true},{"functionName":"Chain_Chain$current","ranges":[{"startOffset":348455,"endOffset":348942,"count":0}],"isBlockCoverage":false},{"functionName":"Chain_Chain$forTrace","ranges":[{"startOffset":348970,"endOffset":349524,"count":0}],"isBlockCoverage":false},{"functionName":"Chain_Chain$parse","ranges":[{"startOffset":349549,"endOffset":350621,"count":0}],"isBlockCoverage":false},{"functionName":"Chain","ranges":[{"startOffset":350634,"endOffset":350684,"count":0}],"isBlockCoverage":false},{"functionName":"Chain_capture_closure","ranges":[{"startOffset":350713,"endOffset":350804,"count":1}],"isBlockCoverage":true},{"functionName":"Chain_Chain$current_closure","ranges":[{"startOffset":350839,"endOffset":350937,"count":0}],"isBlockCoverage":false},{"functionName":"Chain_Chain$forTrace_closure","ranges":[{"startOffset":350973,"endOffset":351045,"count":0}],"isBlockCoverage":false},{"functionName":"Chain_Chain$parse_closure","ranges":[{"startOffset":351078,"endOffset":351122,"count":0}],"isBlockCoverage":false},{"functionName":"Chain_Chain$parse_closure0","ranges":[{"startOffset":351156,"endOffset":351201,"count":0}],"isBlockCoverage":false},{"functionName":"Chain_foldFrames_closure","ranges":[{"startOffset":351233,"endOffset":351332,"count":0}],"isBlockCoverage":false},{"functionName":"Chain_foldFrames_closure0","ranges":[{"startOffset":351365,"endOffset":351434,"count":0}],"isBlockCoverage":false},{"functionName":"Chain_toTrace_closure","ranges":[{"startOffset":351463,"endOffset":351503,"count":0}],"isBlockCoverage":false},{"functionName":"Chain_toString_closure0","ranges":[{"startOffset":351534,"endOffset":351576,"count":0}],"isBlockCoverage":false},{"functionName":"Chain_toString__closure0","ranges":[{"startOffset":351608,"endOffset":351651,"count":0}],"isBlockCoverage":false},{"functionName":"Chain_toString_closure","ranges":[{"startOffset":351681,"endOffset":351749,"count":0}],"isBlockCoverage":false},{"functionName":"Chain_toString__closure","ranges":[{"startOffset":351780,"endOffset":351849,"count":0}],"isBlockCoverage":false},{"functionName":"Invoker_guard","ranges":[{"startOffset":351870,"endOffset":352115,"count":1}],"isBlockCoverage":true},{"functionName":"LocalTest","ranges":[{"startOffset":352132,"endOffset":352335,"count":1}],"isBlockCoverage":true},{"functionName":"Invoker","ranges":[{"startOffset":352350,"endOffset":352742,"count":1}],"isBlockCoverage":true},{"functionName":"Invoker_guard_closure","ranges":[{"startOffset":352771,"endOffset":352811,"count":1}],"isBlockCoverage":true},{"functionName":"Invoker_guard__closure","ranges":[{"startOffset":352841,"endOffset":353002,"count":0}],"isBlockCoverage":false},{"functionName":"Invoker_waitForOutstandingCallbacks_closure","ranges":[{"startOffset":353053,"endOffset":353229,"count":1}],"isBlockCoverage":true},{"functionName":"Invoker_waitForOutstandingCallbacks_closure0","ranges":[{"startOffset":353281,"endOffset":353397,"count":1}],"isBlockCoverage":true},{"functionName":"Invoker_heartbeat_message","ranges":[{"startOffset":353430,"endOffset":353501,"count":1}],"isBlockCoverage":true},{"functionName":"Invoker_heartbeat_closure","ranges":[{"startOffset":353534,"endOffset":353661,"count":1}],"isBlockCoverage":true},{"functionName":"Invoker_heartbeat__closure","ranges":[{"startOffset":353695,"endOffset":353823,"count":0}],"isBlockCoverage":false},{"functionName":"Invoker__handleError_closure","ranges":[{"startOffset":353859,"endOffset":353932,"count":0}],"isBlockCoverage":false},{"functionName":"Invoker__handleError_closure0","ranges":[{"startOffset":353969,"endOffset":354042,"count":0}],"isBlockCoverage":false},{"functionName":"Invoker__onRun_closure","ranges":[{"startOffset":354072,"endOffset":354187,"count":1}],"isBlockCoverage":true},{"functionName":"Invoker__onRun__closure","ranges":[{"startOffset":354218,"endOffset":354334,"count":1}],"isBlockCoverage":true},{"functionName":"Invoker__onRun___closure","ranges":[{"startOffset":354366,"endOffset":354434,"count":1}],"isBlockCoverage":true},{"functionName":"Invoker__onRun____closure","ranges":[{"startOffset":354467,"endOffset":354536,"count":1}],"isBlockCoverage":true},{"functionName":"Invoker__onRun___closure0","ranges":[{"startOffset":354569,"endOffset":354638,"count":1}],"isBlockCoverage":true},{"functionName":"_AsyncCounter","ranges":[{"startOffset":354659,"endOffset":354753,"count":1}],"isBlockCoverage":true},{"functionName":"StackTraceFormatter","ranges":[{"startOffset":354780,"endOffset":354899,"count":1}],"isBlockCoverage":true},{"functionName":"StackTraceFormatter_formatStackTrace_closure","ranges":[{"startOffset":354951,"endOffset":355039,"count":0}],"isBlockCoverage":false},{"functionName":"Suite__filterGroup","ranges":[{"startOffset":355065,"endOffset":355410,"count":1},{"startOffset":355223,"endOffset":355409,"count":0}],"isBlockCoverage":true},{"functionName":"Suite","ranges":[{"startOffset":355423,"endOffset":355528,"count":1}],"isBlockCoverage":true},{"functionName":"SuiteConfiguration__list","ranges":[{"startOffset":355560,"endOffset":355606,"count":0}],"isBlockCoverage":false},{"functionName":"SuiteConfiguration__map","ranges":[{"startOffset":355637,"endOffset":355695,"count":0}],"isBlockCoverage":false},{"functionName":"SuiteConfiguration","ranges":[{"startOffset":355721,"endOffset":355758,"count":0}],"isBlockCoverage":false},{"functionName":"RemoteException_serialize","ranges":[{"startOffset":355791,"endOffset":356552,"count":0}],"isBlockCoverage":false},{"functionName":"IntersectionSelector","ranges":[{"startOffset":356587,"endOffset":356688,"count":0}],"isBlockCoverage":false},{"functionName":"StreamChannel","ranges":[{"startOffset":356705,"endOffset":356737,"count":0}],"isBlockCoverage":false},{"functionName":"_StreamChannel","ranges":[{"startOffset":356755,"endOffset":356865,"count":1}],"isBlockCoverage":true},{"functionName":"StreamChannelMixin","ranges":[{"startOffset":356887,"endOffset":356924,"count":0}],"isBlockCoverage":false},{"functionName":"Timeout","ranges":[{"startOffset":356935,"endOffset":357022,"count":1}],"isBlockCoverage":true},{"functionName":"ExpandedReporter","ranges":[{"startOffset":357042,"endOffset":357603,"count":0}],"isBlockCoverage":false},{"functionName":"ExpandedReporter__onTestStarted_closure","ranges":[{"startOffset":357646,"endOffset":357759,"count":0}],"isBlockCoverage":false},{"functionName":"ExpandedReporter__onTestStarted_closure0","ranges":[{"startOffset":357803,"endOffset":357917,"count":0}],"isBlockCoverage":false},{"functionName":"ExpandedReporter__onTestStarted_closure1","ranges":[{"startOffset":357961,"endOffset":358075,"count":0}],"isBlockCoverage":false},{"functionName":"_declarer","ranges":[{"startOffset":358092,"endOffset":358479,"count":1},{"startOffset":358251,"endOffset":358478,"count":0}],"isBlockCoverage":true},{"functionName":"test","ranges":[{"startOffset":358491,"endOffset":358707,"count":1}],"isBlockCoverage":true},{"functionName":"group","ranges":[{"startOffset":358720,"endOffset":358937,"count":1}],"isBlockCoverage":true},{"functionName":"_declarer_closure","ranges":[{"startOffset":358962,"endOffset":358998,"count":0}],"isBlockCoverage":false},{"functionName":"_declarer__closure","ranges":[{"startOffset":359024,"endOffset":359087,"count":0}],"isBlockCoverage":false},{"functionName":"main","ranges":[{"startOffset":359099,"endOffset":359177,"count":1}],"isBlockCoverage":true},{"functionName":"main_closure","ranges":[{"startOffset":359197,"endOffset":359228,"count":1}],"isBlockCoverage":true},{"functionName":"RecursiveVisitor","ranges":[{"startOffset":359259,"endOffset":359294,"count":0}],"isBlockCoverage":false},{"functionName":"InternalStyle","ranges":[{"startOffset":359311,"endOffset":359343,"count":0}],"isBlockCoverage":false},{"functionName":"StreamChannelController$","ranges":[{"startOffset":359375,"endOffset":360324,"count":1}],"isBlockCoverage":true},{"functionName":"StreamChannelController","ranges":[{"startOffset":360355,"endOffset":360462,"count":1}],"isBlockCoverage":true},{"functionName":"Runtime_Runtime$deserialize","ranges":[{"startOffset":360497,"endOffset":361558,"count":1},{"startOffset":360735,"endOffset":361557,"count":0}],"isBlockCoverage":true},{"functionName":"Runtime","ranges":[{"startOffset":361573,"endOffset":361827,"count":1}],"isBlockCoverage":true},{"functionName":"Runtime_Runtime$deserialize_closure","ranges":[{"startOffset":361870,"endOffset":361954,"count":1}],"isBlockCoverage":true},{"functionName":"indent","ranges":[{"startOffset":361968,"endOffset":362129,"count":0}],"isBlockCoverage":false},{"functionName":"toSentence","ranges":[{"startOffset":362147,"endOffset":362529,"count":0}],"isBlockCoverage":false},{"functionName":"pluralize","ranges":[{"startOffset":362546,"endOffset":362649,"count":0}],"isBlockCoverage":false},{"functionName":"prefixLines","ranges":[{"startOffset":362668,"endOffset":363386,"count":0}],"isBlockCoverage":false},{"functionName":"closure0","ranges":[{"startOffset":363402,"endOffset":363429,"count":0}],"isBlockCoverage":false},{"functionName":"LiveSuiteController$","ranges":[{"startOffset":363457,"endOffset":364346,"count":0}],"isBlockCoverage":false},{"functionName":"_LiveSuite","ranges":[{"startOffset":364364,"endOffset":364447,"count":0}],"isBlockCoverage":false},{"functionName":"LiveSuiteController","ranges":[{"startOffset":364474,"endOffset":364920,"count":0}],"isBlockCoverage":false},{"functionName":"LiveSuiteController_closure","ranges":[{"startOffset":364955,"endOffset":365026,"count":0}],"isBlockCoverage":false},{"functionName":"LiveSuiteController_closure0","ranges":[{"startOffset":365062,"endOffset":365109,"count":0}],"isBlockCoverage":false},{"functionName":"LiveSuiteController_reportLiveTest_closure","ranges":[{"startOffset":365159,"endOffset":365309,"count":0}],"isBlockCoverage":false},{"functionName":"LiveSuiteController_close_closure","ranges":[{"startOffset":365350,"endOffset":365427,"count":0}],"isBlockCoverage":false},{"functionName":"asUri","ranges":[{"startOffset":365440,"endOffset":365612,"count":0}],"isBlockCoverage":false},{"functionName":"ensureTrailingSlash","ranges":[{"startOffset":365639,"endOffset":366120,"count":1},{"startOffset":365724,"endOffset":365758,"count":0},{"startOffset":365898,"endOffset":366119,"count":0}],"isBlockCoverage":true},{"functionName":"isAlphabetic","ranges":[{"startOffset":366140,"endOffset":366302,"count":0}],"isBlockCoverage":false},{"functionName":"isDriveLetter","ranges":[{"startOffset":366323,"endOffset":366734,"count":0}],"isBlockCoverage":false},{"functionName":"countCodeUnits","ranges":[{"startOffset":366756,"endOffset":367071,"count":0}],"isBlockCoverage":false},{"functionName":"findLineStart","ranges":[{"startOffset":367092,"endOffset":367938,"count":0}],"isBlockCoverage":false},{"functionName":"validateErrorArgs","ranges":[{"startOffset":367963,"endOffset":368466,"count":0}],"isBlockCoverage":false},{"functionName":"QueueList$","ranges":[{"startOffset":368496,"endOffset":368736,"count":1}],"isBlockCoverage":true},{"functionName":"QueueList__nextPowerOf2","ranges":[{"startOffset":368767,"endOffset":369042,"count":0}],"isBlockCoverage":false},{"functionName":"QueueList","ranges":[{"startOffset":369059,"endOffset":369215,"count":1}],"isBlockCoverage":true},{"functionName":"_QueueList_Object_ListMixin","ranges":[{"startOffset":369250,"endOffset":369296,"count":0}],"isBlockCoverage":false},{"functionName":"UnionSet","ranges":[{"startOffset":369319,"endOffset":369427,"count":0}],"isBlockCoverage":false},{"functionName":"UnionSet_length_closure","ranges":[{"startOffset":369454,"endOffset":369521,"count":0}],"isBlockCoverage":false},{"functionName":"UnionSet__iterable_closure","ranges":[{"startOffset":369551,"endOffset":369621,"count":0}],"isBlockCoverage":false},{"functionName":"_UnionSet_SetBase_UnmodifiableSetMixin","ranges":[{"startOffset":369663,"endOffset":369720,"count":0}],"isBlockCoverage":false},{"functionName":"_DelegatingIterableBase","ranges":[{"startOffset":369747,"endOffset":369789,"count":0}],"isBlockCoverage":false},{"functionName":"DelegatingIterable","ranges":[{"startOffset":369811,"endOffset":369848,"count":0}],"isBlockCoverage":false},{"functionName":"DelegatingSet","ranges":[{"startOffset":369865,"endOffset":369947,"count":0}],"isBlockCoverage":false},{"functionName":"TypeMatcher","ranges":[{"startOffset":369962,"endOffset":369992,"count":0}],"isBlockCoverage":false},{"functionName":"wrapMatcher","ranges":[{"startOffset":370011,"endOffset":370493,"count":1},{"startOffset":370116,"endOffset":370487,"count":0}],"isBlockCoverage":true},{"functionName":"escape","ranges":[{"startOffset":370507,"endOffset":370736,"count":0}],"isBlockCoverage":false},{"functionName":"_getHexLiteral","ranges":[{"startOffset":370758,"endOffset":371247,"count":0}],"isBlockCoverage":false},{"functionName":"wrapMatcher_closure","ranges":[{"startOffset":371274,"endOffset":371333,"count":0}],"isBlockCoverage":false},{"functionName":"escape_closure","ranges":[{"startOffset":371355,"endOffset":371388,"count":0}],"isBlockCoverage":false},{"functionName":"Context_Context","ranges":[{"startOffset":371411,"endOffset":371599,"count":0}],"isBlockCoverage":false},{"functionName":"_parseUri","ranges":[{"startOffset":371616,"endOffset":371786,"count":0}],"isBlockCoverage":false},{"functionName":"_validateArgList","ranges":[{"startOffset":371810,"endOffset":372805,"count":0}],"isBlockCoverage":false},{"functionName":"Context","ranges":[{"startOffset":372820,"endOffset":372910,"count":0}],"isBlockCoverage":false},{"functionName":"Context_join_closure","ranges":[{"startOffset":372938,"endOffset":372977,"count":0}],"isBlockCoverage":false},{"functionName":"Context_joinAll_closure","ranges":[{"startOffset":373008,"endOffset":373050,"count":0}],"isBlockCoverage":false},{"functionName":"Context_split_closure","ranges":[{"startOffset":373079,"endOffset":373119,"count":0}],"isBlockCoverage":false},{"functionName":"_validateArgList_closure","ranges":[{"startOffset":373151,"endOffset":373194,"count":0}],"isBlockCoverage":false},{"functionName":"_PathDirection","ranges":[{"startOffset":373216,"endOffset":373273,"count":1}],"isBlockCoverage":true},{"functionName":"_PathRelation","ranges":[{"startOffset":373294,"endOffset":373350,"count":1}],"isBlockCoverage":true},{"functionName":"_StringEqualsMatcher__writeLeading","ranges":[{"startOffset":373404,"endOffset":373714,"count":0}],"isBlockCoverage":false},{"functionName":"_StringEqualsMatcher__writeTrailing","ranges":[{"startOffset":373757,"endOffset":374094,"count":0}],"isBlockCoverage":false},{"functionName":"_StringEqualsMatcher","ranges":[{"startOffset":374122,"endOffset":374203,"count":0}],"isBlockCoverage":false},{"functionName":"_DeepMatcher","ranges":[{"startOffset":374223,"endOffset":374311,"count":0}],"isBlockCoverage":false},{"functionName":"_DeepMatcher__compareSets_closure","ranges":[{"startOffset":374352,"endOffset":374533,"count":0}],"isBlockCoverage":false},{"functionName":"PackageRootResolver","ranges":[{"startOffset":374560,"endOffset":374629,"count":0}],"isBlockCoverage":false},{"functionName":"SourceLocationMixin","ranges":[{"startOffset":374656,"endOffset":374694,"count":0}],"isBlockCoverage":false},{"functionName":"_MultiChannel$","ranges":[{"startOffset":374716,"endOffset":375095,"count":1}],"isBlockCoverage":true},{"functionName":"_MultiChannel","ranges":[{"startOffset":375116,"endOffset":375414,"count":1}],"isBlockCoverage":true},{"functionName":"_MultiChannel_closure","ranges":[{"startOffset":375443,"endOffset":375531,"count":1}],"isBlockCoverage":true},{"functionName":"_MultiChannel_closure0","ranges":[{"startOffset":375561,"endOffset":375627,"count":1}],"isBlockCoverage":true},{"functionName":"_MultiChannel_closure1","ranges":[{"startOffset":375657,"endOffset":375746,"count":1}],"isBlockCoverage":true},{"functionName":"_MultiChannel__closure","ranges":[{"startOffset":375776,"endOffset":375889,"count":1}],"isBlockCoverage":true},{"functionName":"_MultiChannel_virtualChannel_closure","ranges":[{"startOffset":375933,"endOffset":376041,"count":1}],"isBlockCoverage":true},{"functionName":"_MultiChannel_virtualChannel_closure0","ranges":[{"startOffset":376086,"endOffset":376195,"count":1}],"isBlockCoverage":true},{"functionName":"VirtualChannel","ranges":[{"startOffset":376217,"endOffset":376400,"count":1}],"isBlockCoverage":true},{"functionName":"Message","ranges":[{"startOffset":376415,"endOffset":376491,"count":0}],"isBlockCoverage":false},{"functionName":"MessageType","ranges":[{"startOffset":376510,"endOffset":376564,"count":1}],"isBlockCoverage":true},{"functionName":"current","ranges":[{"startOffset":376579,"endOffset":377522,"count":0}],"isBlockCoverage":false},{"functionName":"prettyPrint","ranges":[{"startOffset":377553,"endOffset":377748,"count":0}],"isBlockCoverage":false},{"functionName":"_typeName","ranges":[{"startOffset":377765,"endOffset":377994,"count":0}],"isBlockCoverage":false},{"functionName":"_escapeString","ranges":[{"startOffset":378015,"endOffset":378154,"count":0}],"isBlockCoverage":false},{"functionName":"prettyPrint__prettyPrint","ranges":[{"startOffset":378186,"endOffset":378292,"count":0}],"isBlockCoverage":false},{"functionName":"prettyPrint__prettyPrint_pp","ranges":[{"startOffset":378327,"endOffset":378461,"count":0}],"isBlockCoverage":false},{"functionName":"prettyPrint__prettyPrint_closure","ranges":[{"startOffset":378501,"endOffset":378578,"count":0}],"isBlockCoverage":false},{"functionName":"prettyPrint__prettyPrint_closure0","ranges":[{"startOffset":378619,"endOffset":378721,"count":0}],"isBlockCoverage":false},{"functionName":"prettyPrint__prettyPrint_closure1","ranges":[{"startOffset":378762,"endOffset":378840,"count":0}],"isBlockCoverage":false},{"functionName":"LiveTest","ranges":[{"startOffset":378856,"endOffset":378883,"count":0}],"isBlockCoverage":false},{"functionName":"Frame_Frame$parseVM","ranges":[{"startOffset":378922,"endOffset":379038,"count":0}],"isBlockCoverage":false},{"functionName":"Frame_Frame$parseV8","ranges":[{"startOffset":379065,"endOffset":379181,"count":0}],"isBlockCoverage":false},{"functionName":"Frame_Frame$parseFirefox","ranges":[{"startOffset":379213,"endOffset":379334,"count":0}],"isBlockCoverage":false},{"functionName":"Frame_Frame$parseFriendly","ranges":[{"startOffset":379367,"endOffset":379489,"count":0}],"isBlockCoverage":false},{"functionName":"Frame__uriOrPathToUri","ranges":[{"startOffset":379518,"endOffset":380076,"count":0}],"isBlockCoverage":false},{"functionName":"Frame__catchFormatException","ranges":[{"startOffset":380111,"endOffset":380455,"count":0}],"isBlockCoverage":false},{"functionName":"Frame","ranges":[{"startOffset":380468,"endOffset":380605,"count":0}],"isBlockCoverage":false},{"functionName":"Frame_Frame$parseVM_closure","ranges":[{"startOffset":380640,"endOffset":380711,"count":0}],"isBlockCoverage":false},{"functionName":"Frame_Frame$parseV8_closure","ranges":[{"startOffset":380746,"endOffset":380817,"count":0}],"isBlockCoverage":false},{"functionName":"Frame_Frame$parseV8_closure_parseLocation","ranges":[{"startOffset":380866,"endOffset":380951,"count":0}],"isBlockCoverage":false},{"functionName":"Frame_Frame$parseFirefox_closure","ranges":[{"startOffset":380991,"endOffset":381067,"count":0}],"isBlockCoverage":false},{"functionName":"Frame_Frame$parseFriendly_closure","ranges":[{"startOffset":381108,"endOffset":381185,"count":0}],"isBlockCoverage":false},{"functionName":"AsciiGlyphSet","ranges":[{"startOffset":381206,"endOffset":381238,"count":1}],"isBlockCoverage":true},{"functionName":"UnparsedFrame","ranges":[{"startOffset":381266,"endOffset":381349,"count":0}],"isBlockCoverage":false},{"functionName":"StreamChannelCompleter","ranges":[{"startOffset":381375,"endOffset":381623,"count":1}],"isBlockCoverage":true},{"functionName":"postMessageChannel","ranges":[{"startOffset":381649,"endOffset":382274,"count":1}],"isBlockCoverage":true},{"functionName":"postMessageChannel_closure","ranges":[{"startOffset":382308,"endOffset":382353,"count":1}],"isBlockCoverage":true},{"functionName":"postMessageChannel_closure0","ranges":[{"startOffset":382388,"endOffset":382464,"count":1}],"isBlockCoverage":true},{"functionName":"postMessageChannel__closure","ranges":[{"startOffset":382499,"endOffset":382575,"count":1}],"isBlockCoverage":true},{"functionName":"postMessageChannel__closure0","ranges":[{"startOffset":382611,"endOffset":382682,"count":1}],"isBlockCoverage":true},{"functionName":"postMessageChannel__closure1","ranges":[{"startOffset":382718,"endOffset":382827,"count":1}],"isBlockCoverage":true},{"functionName":"OperatingSystem_find","ranges":[{"startOffset":382855,"endOffset":383034,"count":1}],"isBlockCoverage":true},{"functionName":"OperatingSystem","ranges":[{"startOffset":383057,"endOffset":383147,"count":1}],"isBlockCoverage":true},{"functionName":"OperatingSystem_find_closure","ranges":[{"startOffset":383183,"endOffset":383260,"count":1}],"isBlockCoverage":true},{"functionName":"OperatingSystem_find_closure0","ranges":[{"startOffset":383297,"endOffset":383345,"count":1}],"isBlockCoverage":true},{"functionName":"SuiteChannelManager","ranges":[{"startOffset":383372,"endOffset":383520,"count":1}],"isBlockCoverage":true},{"functionName":"GuaranteeChannel$","ranges":[{"startOffset":383557,"endOffset":383845,"count":1}],"isBlockCoverage":true},{"functionName":"GuaranteeChannel","ranges":[{"startOffset":383869,"endOffset":384037,"count":1}],"isBlockCoverage":true},{"functionName":"GuaranteeChannel_closure","ranges":[{"startOffset":384069,"endOffset":384165,"count":1}],"isBlockCoverage":true},{"functionName":"GuaranteeChannel__closure","ranges":[{"startOffset":384198,"endOffset":384267,"count":1}],"isBlockCoverage":true},{"functionName":"_GuaranteeSink","ranges":[{"startOffset":384289,"endOffset":384584,"count":1}],"isBlockCoverage":true},{"functionName":"_GuaranteeSink__addError_closure","ranges":[{"startOffset":384624,"endOffset":384675,"count":0}],"isBlockCoverage":false},{"functionName":"_GuaranteeSink_addStream_closure","ranges":[{"startOffset":384715,"endOffset":384791,"count":1}],"isBlockCoverage":true},{"functionName":"UnicodeGlyphSet","ranges":[{"startOffset":384814,"endOffset":384848,"count":1}],"isBlockCoverage":true},{"functionName":"ClosedException$","ranges":[{"startOffset":384872,"endOffset":384928,"count":0}],"isBlockCoverage":false},{"functionName":"ClosedException","ranges":[{"startOffset":384951,"endOffset":384985,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":385218,"endOffset":385284,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":385304,"endOffset":385382,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":385400,"endOffset":385507,"count":0}],"isBlockCoverage":false},{"functionName":"get$runtimeType","ranges":[{"startOffset":385530,"endOffset":385597,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":385644,"endOffset":385701,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":385721,"endOffset":385788,"count":1},{"startOffset":385773,"endOffset":385781,"count":0}],"isBlockCoverage":true},{"functionName":"get$runtimeType","ranges":[{"startOffset":385811,"endOffset":385867,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":385923,"endOffset":385984,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":386002,"endOffset":386049,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":386069,"endOffset":386111,"count":0}],"isBlockCoverage":false},{"functionName":"get$runtimeType","ranges":[{"startOffset":386134,"endOffset":386190,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":386294,"endOffset":386336,"count":0}],"isBlockCoverage":false},{"functionName":"get$runtimeType","ranges":[{"startOffset":386359,"endOffset":386419,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":386437,"endOffset":386494,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":386659,"endOffset":386925,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":386943,"endOffset":387010,"count":0}],"isBlockCoverage":false},{"functionName":"add$1","ranges":[{"startOffset":387073,"endOffset":387290,"count":1},{"startOffset":387210,"endOffset":387256,"count":0}],"isBlockCoverage":true},{"functionName":"removeAt$1","ranges":[{"startOffset":387308,"endOffset":387608,"count":0}],"isBlockCoverage":false},{"functionName":"insert$2","ranges":[{"startOffset":387624,"endOffset":387991,"count":0}],"isBlockCoverage":false},{"functionName":"insertAll$2","ranges":[{"startOffset":388010,"endOffset":388615,"count":0}],"isBlockCoverage":false},{"functionName":"removeLast$0","ranges":[{"startOffset":388635,"endOffset":388887,"count":0}],"isBlockCoverage":false},{"functionName":"remove$1","ranges":[{"startOffset":388903,"endOffset":389218,"count":1},{"startOffset":388989,"endOffset":389038,"count":0},{"startOffset":389192,"endOffset":389217,"count":0}],"isBlockCoverage":true},{"functionName":"addAll$1","ranges":[{"startOffset":389234,"endOffset":389764,"count":0}],"isBlockCoverage":false},{"functionName":"forEach$1","ranges":[{"startOffset":389781,"endOffset":390106,"count":0}],"isBlockCoverage":false},{"functionName":"map$1$1","ranges":[{"startOffset":390121,"endOffset":390359,"count":0}],"isBlockCoverage":false},{"functionName":"join$1","ranges":[{"startOffset":390373,"endOffset":390629,"count":0}],"isBlockCoverage":false},{"functionName":"join$0","ranges":[{"startOffset":390643,"endOffset":390711,"count":0}],"isBlockCoverage":false},{"functionName":"fold$1$2","ranges":[{"startOffset":390727,"endOffset":391213,"count":1},{"startOffset":391010,"endOffset":391187,"count":0}],"isBlockCoverage":true},{"functionName":"firstWhere$2$orElse","ranges":[{"startOffset":391240,"endOffset":391854,"count":1},{"startOffset":391653,"endOffset":391717,"count":0},{"startOffset":391783,"endOffset":391853,"count":0}],"isBlockCoverage":true},{"functionName":"firstWhere$1","ranges":[{"startOffset":391874,"endOffset":391969,"count":1}],"isBlockCoverage":true},{"functionName":"elementAt$1","ranges":[{"startOffset":391988,"endOffset":392141,"count":1},{"startOffset":392073,"endOffset":392105,"count":0}],"isBlockCoverage":true},{"functionName":"sublist$2","ranges":[{"startOffset":392158,"endOffset":392671,"count":0}],"isBlockCoverage":false},{"functionName":"get$first","ranges":[{"startOffset":392688,"endOffset":392838,"count":1},{"startOffset":392767,"endOffset":392837,"count":0}],"isBlockCoverage":true},{"functionName":"get$last","ranges":[{"startOffset":392854,"endOffset":393028,"count":1},{"startOffset":392957,"endOffset":393027,"count":0}],"isBlockCoverage":true},{"functionName":"get$single","ranges":[{"startOffset":393046,"endOffset":393372,"count":0}],"isBlockCoverage":false},{"functionName":"setRange$4","ranges":[{"startOffset":393390,"endOffset":394326,"count":0}],"isBlockCoverage":false},{"functionName":"setRange$3","ranges":[{"startOffset":394344,"endOffset":394459,"count":0}],"isBlockCoverage":false},{"functionName":"fillRange$3","ranges":[{"startOffset":394478,"endOffset":394843,"count":0}],"isBlockCoverage":false},{"functionName":"replaceRange$3","ranges":[{"startOffset":394865,"endOffset":395890,"count":0}],"isBlockCoverage":false},{"functionName":"contains$1","ranges":[{"startOffset":395908,"endOffset":396081,"count":0}],"isBlockCoverage":false},{"functionName":"get$isEmpty","ranges":[{"startOffset":396100,"endOffset":396162,"count":1}],"isBlockCoverage":true},{"functionName":"toString$0","ranges":[{"startOffset":396180,"endOffset":396276,"count":0}],"isBlockCoverage":false},{"functionName":"toSet$0","ranges":[{"startOffset":396291,"endOffset":396422,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":396442,"endOffset":396589,"count":1}],"isBlockCoverage":true},{"functionName":"get$hashCode","ranges":[{"startOffset":396609,"endOffset":396687,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":396705,"endOffset":396761,"count":1}],"isBlockCoverage":true},{"functionName":"set$length","ranges":[{"startOffset":396779,"endOffset":397195,"count":1},{"startOffset":396884,"endOffset":396937,"count":0},{"startOffset":396978,"endOffset":397046,"count":0},{"startOffset":397080,"endOffset":397154,"count":0}],"isBlockCoverage":true},{"functionName":"$index","ranges":[{"startOffset":397209,"endOffset":397523,"count":1},{"startOffset":397307,"endOffset":397368,"count":0},{"startOffset":397426,"endOffset":397487,"count":0}],"isBlockCoverage":true},{"functionName":"$indexSet","ranges":[{"startOffset":397540,"endOffset":398028,"count":1},{"startOffset":397720,"endOffset":397774,"count":0},{"startOffset":397811,"endOffset":397872,"count":0},{"startOffset":397930,"endOffset":397991,"count":0}],"isBlockCoverage":true},{"functionName":"get$current","ranges":[{"startOffset":398194,"endOffset":398240,"count":1}],"isBlockCoverage":true},{"functionName":"moveNext$0","ranges":[{"startOffset":398258,"endOffset":398662,"count":1},{"startOffset":398403,"endOffset":398465,"count":0}],"isBlockCoverage":true},{"functionName":"set$_current","ranges":[{"startOffset":398682,"endOffset":398771,"count":1}],"isBlockCoverage":true},{"functionName":"floor$0","ranges":[{"startOffset":398837,"endOffset":399285,"count":0}],"isBlockCoverage":false},{"functionName":"round$0","ranges":[{"startOffset":399300,"endOffset":399582,"count":1},{"startOffset":399425,"endOffset":399581,"count":0}],"isBlockCoverage":true},{"functionName":"toRadixString$1","ranges":[{"startOffset":399605,"endOffset":400471,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":400489,"endOffset":400625,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":400645,"endOffset":401151,"count":0}],"isBlockCoverage":false},{"functionName":"$mod","ranges":[{"startOffset":401163,"endOffset":401414,"count":0}],"isBlockCoverage":false},{"functionName":"$tdiv","ranges":[{"startOffset":401427,"endOffset":401624,"count":0}],"isBlockCoverage":false},{"functionName":"_tdivFast$1","ranges":[{"startOffset":401643,"endOffset":401777,"count":1},{"startOffset":401735,"endOffset":401770,"count":0}],"isBlockCoverage":true},{"functionName":"_tdivSlow$1","ranges":[{"startOffset":401796,"endOffset":402270,"count":0}],"isBlockCoverage":false},{"functionName":"_shlPositive$1","ranges":[{"startOffset":402292,"endOffset":402380,"count":0}],"isBlockCoverage":false},{"functionName":"_shrOtherPositive$1","ranges":[{"startOffset":402407,"endOffset":402644,"count":0}],"isBlockCoverage":false},{"functionName":"_shrReceiverPositive$1","ranges":[{"startOffset":402674,"endOffset":402843,"count":0}],"isBlockCoverage":false},{"functionName":"_shrBothPositive$1","ranges":[{"startOffset":402869,"endOffset":402952,"count":0}],"isBlockCoverage":false},{"functionName":"get$runtimeType","ranges":[{"startOffset":402975,"endOffset":403030,"count":0}],"isBlockCoverage":false},{"functionName":"get$runtimeType","ranges":[{"startOffset":403114,"endOffset":403169,"count":0}],"isBlockCoverage":false},{"functionName":"get$runtimeType","ranges":[{"startOffset":403238,"endOffset":403296,"count":0}],"isBlockCoverage":false},{"functionName":"codeUnitAt$1","ranges":[{"startOffset":403347,"endOffset":403614,"count":1},{"startOffset":403404,"endOffset":403465,"count":0},{"startOffset":403510,"endOffset":403567,"count":0}],"isBlockCoverage":true},{"functionName":"_codeUnitAt$1","ranges":[{"startOffset":403635,"endOffset":403815,"count":1},{"startOffset":403707,"endOffset":403768,"count":0}],"isBlockCoverage":true},{"functionName":"allMatches$2","ranges":[{"startOffset":403835,"endOffset":404180,"count":0}],"isBlockCoverage":false},{"functionName":"allMatches$1","ranges":[{"startOffset":404200,"endOffset":404289,"count":0}],"isBlockCoverage":false},{"functionName":"matchAsPrefix$2","ranges":[{"startOffset":404312,"endOffset":404833,"count":0}],"isBlockCoverage":false},{"functionName":"$add","ranges":[{"startOffset":404845,"endOffset":405018,"count":0}],"isBlockCoverage":false},{"functionName":"endsWith$1","ranges":[{"startOffset":405036,"endOffset":405256,"count":0}],"isBlockCoverage":false},{"functionName":"splitMapJoin$2$onMatch","ranges":[{"startOffset":405286,"endOffset":405477,"count":0}],"isBlockCoverage":false},{"functionName":"replaceFirst$2","ranges":[{"startOffset":405499,"endOffset":405680,"count":0}],"isBlockCoverage":false},{"functionName":"replaceRange$3","ranges":[{"startOffset":405702,"endOffset":405903,"count":0}],"isBlockCoverage":false},{"functionName":"startsWith$2","ranges":[{"startOffset":405923,"endOffset":406447,"count":1},{"startOffset":406073,"endOffset":406154,"count":0},{"startOffset":406288,"endOffset":406301,"count":0},{"startOffset":406373,"endOffset":406446,"count":0}],"isBlockCoverage":true},{"functionName":"startsWith$1","ranges":[{"startOffset":406467,"endOffset":406558,"count":0}],"isBlockCoverage":false},{"functionName":"substring$2","ranges":[{"startOffset":406577,"endOffset":407046,"count":1},{"startOffset":406656,"endOffset":406683,"count":0},{"startOffset":406718,"endOffset":406778,"count":0},{"startOffset":406820,"endOffset":406880,"count":0},{"startOffset":406927,"endOffset":406985,"count":0}],"isBlockCoverage":true},{"functionName":"substring$1","ranges":[{"startOffset":407065,"endOffset":407164,"count":0}],"isBlockCoverage":false},{"functionName":"trim$0","ranges":[{"startOffset":407178,"endOffset":407844,"count":0}],"isBlockCoverage":false},{"functionName":"$mul","ranges":[{"startOffset":407856,"endOffset":408335,"count":0}],"isBlockCoverage":false},{"functionName":"padLeft$2","ranges":[{"startOffset":408352,"endOffset":408535,"count":0}],"isBlockCoverage":false},{"functionName":"padRight$1","ranges":[{"startOffset":408553,"endOffset":408802,"count":0}],"isBlockCoverage":false},{"functionName":"indexOf$2","ranges":[{"startOffset":408819,"endOffset":409075,"count":0}],"isBlockCoverage":false},{"functionName":"indexOf$1","ranges":[{"startOffset":409092,"endOffset":409180,"count":0}],"isBlockCoverage":false},{"functionName":"lastIndexOf$2","ranges":[{"startOffset":409201,"endOffset":409620,"count":0}],"isBlockCoverage":false},{"functionName":"lastIndexOf$1","ranges":[{"startOffset":409641,"endOffset":409736,"count":0}],"isBlockCoverage":false},{"functionName":"contains$1","ranges":[{"startOffset":409754,"endOffset":409928,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":409946,"endOffset":409995,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":410015,"endOffset":410421,"count":1}],"isBlockCoverage":true},{"functionName":"get$runtimeType","ranges":[{"startOffset":410444,"endOffset":410502,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":410520,"endOffset":410576,"count":1}],"isBlockCoverage":true},{"functionName":"$index","ranges":[{"startOffset":410590,"endOffset":410806,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":410903,"endOffset":411111,"count":1}],"isBlockCoverage":true},{"functionName":"get$length","ranges":[{"startOffset":411129,"endOffset":411209,"count":0}],"isBlockCoverage":false},{"functionName":"get$isEmpty","ranges":[{"startOffset":411228,"endOffset":411309,"count":0}],"isBlockCoverage":false},{"functionName":"get$first","ranges":[{"startOffset":411326,"endOffset":411441,"count":0}],"isBlockCoverage":false},{"functionName":"get$last","ranges":[{"startOffset":411457,"endOffset":411571,"count":0}],"isBlockCoverage":false},{"functionName":"contains$1","ranges":[{"startOffset":411589,"endOffset":411663,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":411681,"endOffset":411741,"count":0}],"isBlockCoverage":false},{"functionName":"moveNext$0","ranges":[{"startOffset":411794,"endOffset":411852,"count":1}],"isBlockCoverage":true},{"functionName":"get$current","ranges":[{"startOffset":411871,"endOffset":411953,"count":1}],"isBlockCoverage":true},{"functionName":"cast$2$0","ranges":[{"startOffset":412130,"endOffset":412317,"count":0}],"isBlockCoverage":false},{"functionName":"containsKey$1","ranges":[{"startOffset":412338,"endOffset":412405,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":412419,"endOffset":412508,"count":1}],"isBlockCoverage":true},{"functionName":"remove$1","ranges":[{"startOffset":412524,"endOffset":412615,"count":0}],"isBlockCoverage":false},{"functionName":"forEach$1","ranges":[{"startOffset":412632,"endOffset":412762,"count":0}],"isBlockCoverage":false},{"functionName":"get$keys","ranges":[{"startOffset":412778,"endOffset":412919,"count":1}],"isBlockCoverage":true},{"functionName":"get$length","ranges":[{"startOffset":412937,"endOffset":413017,"count":0}],"isBlockCoverage":false},{"functionName":"get$isEmpty","ranges":[{"startOffset":413036,"endOffset":413117,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":413177,"endOffset":413372,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":413390,"endOffset":413458,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":413508,"endOffset":413561,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":413575,"endOffset":413681,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":413780,"endOffset":413952,"count":1}],"isBlockCoverage":true},{"functionName":"get$isEmpty","ranges":[{"startOffset":413971,"endOffset":414032,"count":0}],"isBlockCoverage":false},{"functionName":"get$first","ranges":[{"startOffset":414049,"endOffset":414211,"count":0}],"isBlockCoverage":false},{"functionName":"get$last","ranges":[{"startOffset":414227,"endOffset":414442,"count":0}],"isBlockCoverage":false},{"functionName":"contains$1","ranges":[{"startOffset":414460,"endOffset":414822,"count":0}],"isBlockCoverage":false},{"functionName":"join$1","ranges":[{"startOffset":414836,"endOffset":415796,"count":0}],"isBlockCoverage":false},{"functionName":"join$0","ranges":[{"startOffset":415810,"endOffset":415878,"count":0}],"isBlockCoverage":false},{"functionName":"map$1$1","ranges":[{"startOffset":415893,"endOffset":416137,"count":0}],"isBlockCoverage":false},{"functionName":"fold$1$2","ranges":[{"startOffset":416153,"endOffset":416676,"count":0}],"isBlockCoverage":false},{"functionName":"toList$1$growable","ranges":[{"startOffset":416701,"endOffset":417074,"count":1}],"isBlockCoverage":true},{"functionName":"toList$0","ranges":[{"startOffset":417090,"endOffset":417171,"count":1}],"isBlockCoverage":true},{"functionName":"toSet$0","ranges":[{"startOffset":417186,"endOffset":417453,"count":0}],"isBlockCoverage":false},{"functionName":"get$_endIndex","ranges":[{"startOffset":417512,"endOffset":417706,"count":0}],"isBlockCoverage":false},{"functionName":"get$_startIndex","ranges":[{"startOffset":417729,"endOffset":417914,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":417932,"endOffset":418288,"count":0}],"isBlockCoverage":false},{"functionName":"elementAt$1","ranges":[{"startOffset":418307,"endOffset":418765,"count":0}],"isBlockCoverage":false},{"functionName":"take$1","ranges":[{"startOffset":418779,"endOffset":419284,"count":0}],"isBlockCoverage":false},{"functionName":"get$current","ranges":[{"startOffset":419338,"endOffset":419395,"count":1}],"isBlockCoverage":true},{"functionName":"moveNext$0","ranges":[{"startOffset":419413,"endOffset":419942,"count":1},{"startOffset":419627,"endOffset":419685,"count":0}],"isBlockCoverage":true},{"functionName":"set$__internal$_current","ranges":[{"startOffset":419973,"endOffset":420073,"count":1}],"isBlockCoverage":true},{"functionName":"get$iterator","ranges":[{"startOffset":420150,"endOffset":420369,"count":1}],"isBlockCoverage":true},{"functionName":"get$length","ranges":[{"startOffset":420387,"endOffset":420464,"count":0}],"isBlockCoverage":false},{"functionName":"get$isEmpty","ranges":[{"startOffset":420483,"endOffset":420561,"count":0}],"isBlockCoverage":false},{"functionName":"get$first","ranges":[{"startOffset":420578,"endOffset":420669,"count":0}],"isBlockCoverage":false},{"functionName":"get$last","ranges":[{"startOffset":420685,"endOffset":420775,"count":0}],"isBlockCoverage":false},{"functionName":"moveNext$0","ranges":[{"startOffset":420909,"endOffset":421176,"count":1},{"startOffset":421003,"endOffset":421107,"count":0}],"isBlockCoverage":true},{"functionName":"get$current","ranges":[{"startOffset":421195,"endOffset":421252,"count":0}],"isBlockCoverage":false},{"functionName":"set$__internal$_current","ranges":[{"startOffset":421283,"endOffset":421378,"count":1}],"isBlockCoverage":true},{"functionName":"get$length","ranges":[{"startOffset":421437,"endOffset":421501,"count":1}],"isBlockCoverage":true},{"functionName":"elementAt$1","ranges":[{"startOffset":421520,"endOffset":421614,"count":1}],"isBlockCoverage":true},{"functionName":"get$iterator","ranges":[{"startOffset":421670,"endOffset":421816,"count":1}],"isBlockCoverage":true},{"functionName":"map$1$1","ranges":[{"startOffset":421831,"endOffset":422028,"count":0}],"isBlockCoverage":false},{"functionName":"moveNext$0","ranges":[{"startOffset":422082,"endOffset":422289,"count":1}],"isBlockCoverage":true},{"functionName":"get$current","ranges":[{"startOffset":422308,"endOffset":422369,"count":1}],"isBlockCoverage":true},{"functionName":"get$iterator","ranges":[{"startOffset":422426,"endOffset":422651,"count":0}],"isBlockCoverage":false},{"functionName":"get$current","ranges":[{"startOffset":422707,"endOffset":422764,"count":0}],"isBlockCoverage":false},{"functionName":"moveNext$0","ranges":[{"startOffset":422782,"endOffset":423337,"count":0}],"isBlockCoverage":false},{"functionName":"set$_currentExpansion","ranges":[{"startOffset":423366,"endOffset":423491,"count":0}],"isBlockCoverage":false},{"functionName":"set$__internal$_current","ranges":[{"startOffset":423522,"endOffset":423617,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":423697,"endOffset":423851,"count":0}],"isBlockCoverage":false},{"functionName":"moveNext$0","ranges":[{"startOffset":423909,"endOffset":424236,"count":0}],"isBlockCoverage":false},{"functionName":"get$current","ranges":[{"startOffset":424255,"endOffset":424316,"count":0}],"isBlockCoverage":false},{"functionName":"moveNext$0","ranges":[{"startOffset":424370,"endOffset":424408,"count":0}],"isBlockCoverage":false},{"functionName":"get$current","ranges":[{"startOffset":424427,"endOffset":424464,"count":0}],"isBlockCoverage":false},{"functionName":"set$length","ranges":[{"startOffset":424545,"endOffset":424683,"count":0}],"isBlockCoverage":false},{"functionName":"$indexSet","ranges":[{"startOffset":424744,"endOffset":424977,"count":0}],"isBlockCoverage":false},{"functionName":"set$length","ranges":[{"startOffset":424995,"endOffset":425127,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":425229,"endOffset":425293,"count":1}],"isBlockCoverage":true},{"functionName":"elementAt$1","ranges":[{"startOffset":425312,"endOffset":425470,"count":1}],"isBlockCoverage":true},{"functionName":"get$hashCode","ranges":[{"startOffset":425519,"endOffset":425738,"count":1}],"isBlockCoverage":true},{"functionName":"toString$0","ranges":[{"startOffset":425756,"endOffset":425836,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":425847,"endOffset":426011,"count":1},{"startOffset":425901,"endOffset":425914,"count":0}],"isBlockCoverage":true},{"functionName":"cast$2$0","ranges":[{"startOffset":426061,"endOffset":426200,"count":0}],"isBlockCoverage":false},{"functionName":"get$isEmpty","ranges":[{"startOffset":426219,"endOffset":426280,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":426298,"endOffset":426359,"count":0}],"isBlockCoverage":false},{"functionName":"remove$1","ranges":[{"startOffset":426375,"endOffset":426448,"count":0}],"isBlockCoverage":false},{"functionName":"map$2$1","ranges":[{"startOffset":426463,"endOffset":426752,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":426827,"endOffset":427051,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":427069,"endOffset":427150,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":427208,"endOffset":427266,"count":0}],"isBlockCoverage":false},{"functionName":"containsKey$1","ranges":[{"startOffset":427287,"endOffset":427466,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":427480,"endOffset":427594,"count":0}],"isBlockCoverage":false},{"functionName":"_fetch$1","ranges":[{"startOffset":427610,"endOffset":427689,"count":0}],"isBlockCoverage":false},{"functionName":"forEach$1","ranges":[{"startOffset":427706,"endOffset":428021,"count":1},{"startOffset":427929,"endOffset":428015,"count":0}],"isBlockCoverage":true},{"functionName":"get$keys","ranges":[{"startOffset":428037,"endOffset":428166,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":428232,"endOffset":428410,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":428428,"endOffset":428508,"count":0}],"isBlockCoverage":false},{"functionName":"Instantiation$1","ranges":[{"startOffset":428567,"endOffset":428666,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":428684,"endOffset":428871,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":428922,"endOffset":429017,"count":0}],"isBlockCoverage":false},{"functionName":"call$4","ranges":[{"startOffset":429031,"endOffset":429142,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":429160,"endOffset":429281,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":429347,"endOffset":429437,"count":0}],"isBlockCoverage":false},{"functionName":"matchTypeError$1","ranges":[{"startOffset":429520,"endOffset":430192,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":430242,"endOffset":430457,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":430546,"endOffset":430987,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":431075,"endOffset":431193,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":431303,"endOffset":431464,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":431536,"endOffset":431793,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":431863,"endOffset":432075,"count":0}],"isBlockCoverage":false},{"functionName":"get$$call","ranges":[{"startOffset":432112,"endOffset":432149,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":432313,"endOffset":432502,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":432548,"endOffset":432877,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":432897,"endOffset":433264,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":433282,"endOffset":433522,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":433586,"endOffset":433632,"count":0}],"isBlockCoverage":false},{"functionName":"get$message","ranges":[{"startOffset":433651,"endOffset":433704,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":433757,"endOffset":433827,"count":0}],"isBlockCoverage":false},{"functionName":"get$message","ranges":[{"startOffset":433846,"endOffset":433899,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":433955,"endOffset":434046,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":434102,"endOffset":434160,"count":0}],"isBlockCoverage":false},{"functionName":"get$isEmpty","ranges":[{"startOffset":434179,"endOffset":434243,"count":1}],"isBlockCoverage":true},{"functionName":"get$keys","ranges":[{"startOffset":434259,"endOffset":434390,"count":1}],"isBlockCoverage":true},{"functionName":"get$values","ranges":[{"startOffset":434408,"endOffset":434602,"count":0}],"isBlockCoverage":false},{"functionName":"containsKey$1","ranges":[{"startOffset":434623,"endOffset":435155,"count":1},{"startOffset":435019,"endOffset":435032,"count":0},{"startOffset":435095,"endOffset":435149,"count":0}],"isBlockCoverage":true},{"functionName":"internalContainsKey$1","ranges":[{"startOffset":435184,"endOffset":435440,"count":0}],"isBlockCoverage":false},{"functionName":"addAll$1","ranges":[{"startOffset":435456,"endOffset":435602,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":435616,"endOffset":436311,"count":1},{"startOffset":435819,"endOffset":435832,"count":0},{"startOffset":435911,"endOffset":435918,"count":0},{"startOffset":436111,"endOffset":436124,"count":0},{"startOffset":436200,"endOffset":436207,"count":0},{"startOffset":436259,"endOffset":436305,"count":0}],"isBlockCoverage":true},{"functionName":"internalGet$1","ranges":[{"startOffset":436332,"endOffset":436708,"count":0}],"isBlockCoverage":false},{"functionName":"$indexSet","ranges":[{"startOffset":436725,"endOffset":437424,"count":1}],"isBlockCoverage":true},{"functionName":"internalSet$2","ranges":[{"startOffset":437445,"endOffset":438198,"count":1},{"startOffset":437963,"endOffset":438192,"count":0}],"isBlockCoverage":true},{"functionName":"putIfAbsent$2","ranges":[{"startOffset":438219,"endOffset":438560,"count":1},{"startOffset":438463,"endOffset":438559,"count":0}],"isBlockCoverage":true},{"functionName":"remove$1","ranges":[{"startOffset":438576,"endOffset":438960,"count":1},{"startOffset":438743,"endOffset":438954,"count":0}],"isBlockCoverage":true},{"functionName":"internalRemove$1","ranges":[{"startOffset":438984,"endOffset":439546,"count":0}],"isBlockCoverage":false},{"functionName":"clear$0","ranges":[{"startOffset":439561,"endOffset":439847,"count":0}],"isBlockCoverage":false},{"functionName":"forEach$1","ranges":[{"startOffset":439864,"endOffset":440326,"count":1},{"startOffset":440224,"endOffset":440285,"count":0}],"isBlockCoverage":true},{"functionName":"__js_helper$_addHashTableEntry$3","ranges":[{"startOffset":440366,"endOffset":440739,"count":1},{"startOffset":440683,"endOffset":440733,"count":0}],"isBlockCoverage":true},{"functionName":"__js_helper$_removeHashTableEntry$2","ranges":[{"startOffset":440782,"endOffset":441088,"count":1},{"startOffset":440854,"endOffset":440866,"count":0},{"startOffset":440946,"endOffset":440958,"count":0}],"isBlockCoverage":true},{"functionName":"_modified$0","ranges":[{"startOffset":441107,"endOffset":441189,"count":1}],"isBlockCoverage":true},{"functionName":"_newLinkedCell$2","ranges":[{"startOffset":441213,"endOffset":441682,"count":1}],"isBlockCoverage":true},{"functionName":"__js_helper$_unlinkCell$1","ranges":[{"startOffset":441715,"endOffset":442185,"count":1},{"startOffset":441930,"endOffset":441966,"count":0},{"startOffset":442077,"endOffset":442117,"count":0}],"isBlockCoverage":true},{"functionName":"internalComputeHashCode$1","ranges":[{"startOffset":442218,"endOffset":442286,"count":1}],"isBlockCoverage":true},{"functionName":"internalFindBucketIndex$2","ranges":[{"startOffset":442319,"endOffset":442570,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":442588,"endOffset":442649,"count":0}],"isBlockCoverage":false},{"functionName":"_getTableCell$2","ranges":[{"startOffset":442672,"endOffset":442725,"count":1}],"isBlockCoverage":true},{"functionName":"_getTableBucket$2","ranges":[{"startOffset":442750,"endOffset":442803,"count":1}],"isBlockCoverage":true},{"functionName":"_setTableEntry$3","ranges":[{"startOffset":442827,"endOffset":442925,"count":1}],"isBlockCoverage":true},{"functionName":"_deleteTableEntry$2","ranges":[{"startOffset":442952,"endOffset":443005,"count":1}],"isBlockCoverage":true},{"functionName":"_containsTableEntry$2","ranges":[{"startOffset":443034,"endOffset":443117,"count":1}],"isBlockCoverage":true},{"functionName":"_newHashTable$0","ranges":[{"startOffset":443140,"endOffset":443353,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":443445,"endOffset":443569,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":443587,"endOffset":443663,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":443730,"endOffset":443899,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":443917,"endOffset":443998,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":444101,"endOffset":444176,"count":0}],"isBlockCoverage":false},{"functionName":"get$isEmpty","ranges":[{"startOffset":444195,"endOffset":444276,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":444296,"endOffset":444515,"count":1}],"isBlockCoverage":true},{"functionName":"contains$1","ranges":[{"startOffset":444533,"endOffset":444620,"count":0}],"isBlockCoverage":false},{"functionName":"get$current","ranges":[{"startOffset":444686,"endOffset":444744,"count":1}],"isBlockCoverage":true},{"functionName":"moveNext$0","ranges":[{"startOffset":444762,"endOffset":445261,"count":1},{"startOffset":444898,"endOffset":444956,"count":0}],"isBlockCoverage":true},{"functionName":"set$__js_helper$_current","ranges":[{"startOffset":445293,"endOffset":445394,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":445468,"endOffset":445516,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":445591,"endOffset":445656,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":445732,"endOffset":445817,"count":1}],"isBlockCoverage":true},{"functionName":"toString$0","ranges":[{"startOffset":445892,"endOffset":445983,"count":0}],"isBlockCoverage":false},{"functionName":"get$_nativeGlobalVersion","ranges":[{"startOffset":446015,"endOffset":446314,"count":0}],"isBlockCoverage":false},{"functionName":"get$_nativeAnchoredVersion","ranges":[{"startOffset":446348,"endOffset":446659,"count":0}],"isBlockCoverage":false},{"functionName":"firstMatch$1","ranges":[{"startOffset":446679,"endOffset":446942,"count":0}],"isBlockCoverage":false},{"functionName":"allMatches$2","ranges":[{"startOffset":446962,"endOffset":447186,"count":0}],"isBlockCoverage":false},{"functionName":"allMatches$1","ranges":[{"startOffset":447206,"endOffset":447295,"count":0}],"isBlockCoverage":false},{"functionName":"_execGlobal$2","ranges":[{"startOffset":447316,"endOffset":447578,"count":0}],"isBlockCoverage":false},{"functionName":"_execAnchored$2","ranges":[{"startOffset":447601,"endOffset":447981,"count":0}],"isBlockCoverage":false},{"functionName":"matchAsPrefix$2","ranges":[{"startOffset":448004,"endOffset":448222,"count":0}],"isBlockCoverage":false},{"functionName":"get$start","ranges":[{"startOffset":448319,"endOffset":448369,"count":0}],"isBlockCoverage":false},{"functionName":"get$end","ranges":[{"startOffset":448384,"endOffset":448468,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":448482,"endOffset":448669,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":448771,"endOffset":448879,"count":0}],"isBlockCoverage":false},{"functionName":"get$current","ranges":[{"startOffset":448940,"endOffset":448998,"count":0}],"isBlockCoverage":false},{"functionName":"moveNext$0","ranges":[{"startOffset":449016,"endOffset":450272,"count":0}],"isBlockCoverage":false},{"functionName":"get$end","ranges":[{"startOffset":450341,"endOffset":450406,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":450420,"endOffset":450574,"count":0}],"isBlockCoverage":false},{"functionName":"get$start","ranges":[{"startOffset":450608,"endOffset":450651,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":450719,"endOffset":450837,"count":0}],"isBlockCoverage":false},{"functionName":"get$first","ranges":[{"startOffset":450854,"endOffset":451101,"count":0}],"isBlockCoverage":false},{"functionName":"moveNext$0","ranges":[{"startOffset":451167,"endOffset":451827,"count":0}],"isBlockCoverage":false},{"functionName":"get$current","ranges":[{"startOffset":451846,"endOffset":451904,"count":0}],"isBlockCoverage":false},{"functionName":"get$runtimeType","ranges":[{"startOffset":451986,"endOffset":452048,"count":0}],"isBlockCoverage":false},{"functionName":"get$runtimeType","ranges":[{"startOffset":452215,"endOffset":452275,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":452332,"endOffset":452388,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":452487,"endOffset":452644,"count":0}],"isBlockCoverage":false},{"functionName":"$indexSet","ranges":[{"startOffset":452661,"endOffset":452863,"count":0}],"isBlockCoverage":false},{"functionName":"$indexSet","ranges":[{"startOffset":452995,"endOffset":453194,"count":1}],"isBlockCoverage":true},{"functionName":"get$runtimeType","ranges":[{"startOffset":453328,"endOffset":453391,"count":0}],"isBlockCoverage":false},{"functionName":"get$runtimeType","ranges":[{"startOffset":453454,"endOffset":453517,"count":0}],"isBlockCoverage":false},{"functionName":"get$runtimeType","ranges":[{"startOffset":453578,"endOffset":453639,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":453653,"endOffset":453810,"count":0}],"isBlockCoverage":false},{"functionName":"get$runtimeType","ranges":[{"startOffset":453871,"endOffset":453932,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":453946,"endOffset":454103,"count":0}],"isBlockCoverage":false},{"functionName":"get$runtimeType","ranges":[{"startOffset":454163,"endOffset":454223,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":454237,"endOffset":454394,"count":0}],"isBlockCoverage":false},{"functionName":"get$runtimeType","ranges":[{"startOffset":454456,"endOffset":454518,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":454532,"endOffset":454689,"count":0}],"isBlockCoverage":false},{"functionName":"get$runtimeType","ranges":[{"startOffset":454751,"endOffset":454813,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":454827,"endOffset":454984,"count":0}],"isBlockCoverage":false},{"functionName":"sublist$2","ranges":[{"startOffset":455001,"endOffset":455144,"count":0}],"isBlockCoverage":false},{"functionName":"get$runtimeType","ranges":[{"startOffset":455234,"endOffset":455302,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":455320,"endOffset":455376,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":455390,"endOffset":455547,"count":0}],"isBlockCoverage":false},{"functionName":"get$runtimeType","ranges":[{"startOffset":455608,"endOffset":455669,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":455687,"endOffset":455743,"count":1}],"isBlockCoverage":true},{"functionName":"$index","ranges":[{"startOffset":455757,"endOffset":455914,"count":0}],"isBlockCoverage":false},{"functionName":"sublist$2","ranges":[{"startOffset":455931,"endOffset":456073,"count":0}],"isBlockCoverage":false},{"functionName":"_eval$1","ranges":[{"startOffset":456490,"endOffset":456591,"count":1}],"isBlockCoverage":true},{"functionName":"_bind$1","ranges":[{"startOffset":456606,"endOffset":456704,"count":1}],"isBlockCoverage":true},{"functionName":"get$hashCode","ranges":[{"startOffset":456792,"endOffset":457109,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":457120,"endOffset":457259,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":457277,"endOffset":457342,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":457405,"endOffset":457452,"count":0}],"isBlockCoverage":false},{"functionName":"get$message","ranges":[{"startOffset":457535,"endOffset":457582,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":457674,"endOffset":457802,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":457904,"endOffset":458207,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":458319,"endOffset":458367,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":458484,"endOffset":458532,"count":0}],"isBlockCoverage":false},{"functionName":"_TimerImpl$2","ranges":[{"startOffset":458604,"endOffset":458905,"count":1},{"startOffset":458807,"endOffset":458899,"count":0}],"isBlockCoverage":true},{"functionName":"_TimerImpl$periodic$2","ranges":[{"startOffset":458934,"endOffset":459252,"count":0}],"isBlockCoverage":false},{"functionName":"cancel$0","ranges":[{"startOffset":459268,"endOffset":459616,"count":1},{"startOffset":459383,"endOffset":459390,"count":0},{"startOffset":459447,"endOffset":459494,"count":0},{"startOffset":459531,"endOffset":459610,"count":0}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":459697,"endOffset":459817,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":459900,"endOffset":460263,"count":0}],"isBlockCoverage":false},{"functionName":"complete$1","ranges":[{"startOffset":460343,"endOffset":460659,"count":1}],"isBlockCoverage":true},{"functionName":"completeError$2","ranges":[{"startOffset":460682,"endOffset":460845,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":460925,"endOffset":460999,"count":1}],"isBlockCoverage":true},{"functionName":"call$2","ranges":[{"startOffset":461079,"endOffset":461223,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":461310,"endOffset":461408,"count":1}],"isBlockCoverage":true},{"functionName":"get$isBroadcast","ranges":[{"startOffset":461490,"endOffset":461527,"count":0}],"isBlockCoverage":false},{"functionName":"_onPause$0","ranges":[{"startOffset":461590,"endOffset":461608,"count":0}],"isBlockCoverage":false},{"functionName":"_onResume$0","ranges":[{"startOffset":461627,"endOffset":461645,"count":0}],"isBlockCoverage":false},{"functionName":"set$_async$_next","ranges":[{"startOffset":461669,"endOffset":461742,"count":1}],"isBlockCoverage":true},{"functionName":"set$_async$_previous","ranges":[{"startOffset":461770,"endOffset":461855,"count":1}],"isBlockCoverage":true},{"functionName":"get$_mayAddEvent","ranges":[{"startOffset":461928,"endOffset":461976,"count":1}],"isBlockCoverage":true},{"functionName":"_ensureDoneFuture$0","ranges":[{"startOffset":462003,"endOffset":462182,"count":0}],"isBlockCoverage":false},{"functionName":"_removeListener$1","ranges":[{"startOffset":462207,"endOffset":462934,"count":0}],"isBlockCoverage":false},{"functionName":"_subscribe$4","ranges":[{"startOffset":462954,"endOffset":464472,"count":1},{"startOffset":463220,"endOffset":463469,"count":0},{"startOffset":463523,"endOffset":463526,"count":0},{"startOffset":464278,"endOffset":464337,"count":0}],"isBlockCoverage":true},{"functionName":"_recordCancel$1","ranges":[{"startOffset":464495,"endOffset":465046,"count":0}],"isBlockCoverage":false},{"functionName":"_recordPause$1","ranges":[{"startOffset":465068,"endOffset":465181,"count":0}],"isBlockCoverage":false},{"functionName":"_recordResume$1","ranges":[{"startOffset":465204,"endOffset":465317,"count":0}],"isBlockCoverage":false},{"functionName":"_addEventError$0","ranges":[{"startOffset":465341,"endOffset":465610,"count":0}],"isBlockCoverage":false},{"functionName":"add$1","ranges":[{"startOffset":465623,"endOffset":465854,"count":1},{"startOffset":465769,"endOffset":465817,"count":0}],"isBlockCoverage":true},{"functionName":"addError$2","ranges":[{"startOffset":465872,"endOffset":466438,"count":0}],"isBlockCoverage":false},{"functionName":"addError$1","ranges":[{"startOffset":466456,"endOffset":466522,"count":0}],"isBlockCoverage":false},{"functionName":"close$0","ranges":[{"startOffset":466537,"endOffset":466942,"count":0}],"isBlockCoverage":false},{"functionName":"_async$_addError$2","ranges":[{"startOffset":466968,"endOffset":467072,"count":0}],"isBlockCoverage":false},{"functionName":"_close$0","ranges":[{"startOffset":467088,"endOffset":467356,"count":0}],"isBlockCoverage":false},{"functionName":"_forEachListener$1","ranges":[{"startOffset":467382,"endOffset":468483,"count":0}],"isBlockCoverage":false},{"functionName":"_callOnCancel$0","ranges":[{"startOffset":468506,"endOffset":468761,"count":0}],"isBlockCoverage":false},{"functionName":"set$_firstSubscription","ranges":[{"startOffset":468791,"endOffset":468946,"count":1}],"isBlockCoverage":true},{"functionName":"set$_lastSubscription","ranges":[{"startOffset":468975,"endOffset":469127,"count":1}],"isBlockCoverage":true},{"functionName":"set$_addStreamState","ranges":[{"startOffset":469154,"endOffset":469293,"count":0}],"isBlockCoverage":false},{"functionName":"get$_mayAddEvent","ranges":[{"startOffset":469547,"endOffset":469673,"count":1}],"isBlockCoverage":true},{"functionName":"_addEventError$0","ranges":[{"startOffset":469697,"endOffset":469916,"count":0}],"isBlockCoverage":false},{"functionName":"_sendData$1","ranges":[{"startOffset":469935,"endOffset":470463,"count":1},{"startOffset":470076,"endOffset":470083,"count":0},{"startOffset":470308,"endOffset":470332,"count":0},{"startOffset":470356,"endOffset":470462,"count":0}],"isBlockCoverage":true},{"functionName":"_sendError$2","ranges":[{"startOffset":470483,"endOffset":470690,"count":0}],"isBlockCoverage":false},{"functionName":"_sendDone$0","ranges":[{"startOffset":470709,"endOffset":471070,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":471155,"endOffset":471289,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":471307,"endOffset":471403,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":471489,"endOffset":471653,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":471671,"endOffset":471767,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":471852,"endOffset":471979,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":471997,"endOffset":472093,"count":0}],"isBlockCoverage":false},{"functionName":"_sendData$1","ranges":[{"startOffset":472166,"endOffset":472489,"count":0}],"isBlockCoverage":false},{"functionName":"_sendError$2","ranges":[{"startOffset":472509,"endOffset":472759,"count":0}],"isBlockCoverage":false},{"functionName":"_sendDone$0","ranges":[{"startOffset":472778,"endOffset":473214,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":473299,"endOffset":473599,"count":1},{"startOffset":473419,"endOffset":473593,"count":0}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":473686,"endOffset":473986,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":474065,"endOffset":474620,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":474695,"endOffset":475141,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":475159,"endOffset":475217,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":475276,"endOffset":475578,"count":1},{"startOffset":475384,"endOffset":475577,"count":0}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":475657,"endOffset":476933,"count":1},{"startOffset":475992,"endOffset":476655,"count":0},{"startOffset":476684,"endOffset":476827,"count":0}],"isBlockCoverage":true},{"functionName":"toString$0","ranges":[{"startOffset":477010,"endOffset":477201,"count":0}],"isBlockCoverage":false},{"functionName":"get$message","ranges":[{"startOffset":477241,"endOffset":477294,"count":0}],"isBlockCoverage":false},{"functionName":"completeError$2","ranges":[{"startOffset":477380,"endOffset":477925,"count":0}],"isBlockCoverage":false},{"functionName":"completeError$1","ranges":[{"startOffset":477948,"endOffset":478019,"count":0}],"isBlockCoverage":false},{"functionName":"complete$1","ranges":[{"startOffset":478096,"endOffset":478336,"count":1},{"startOffset":478231,"endOffset":478296,"count":0}],"isBlockCoverage":true},{"functionName":"complete$0","ranges":[{"startOffset":478354,"endOffset":478408,"count":1}],"isBlockCoverage":true},{"functionName":"_completeError$2","ranges":[{"startOffset":478432,"endOffset":478527,"count":0}],"isBlockCoverage":false},{"functionName":"complete$1","ranges":[{"startOffset":478582,"endOffset":478817,"count":0}],"isBlockCoverage":false},{"functionName":"complete$0","ranges":[{"startOffset":478835,"endOffset":478889,"count":0}],"isBlockCoverage":false},{"functionName":"_completeError$2","ranges":[{"startOffset":478913,"endOffset":479003,"count":0}],"isBlockCoverage":false},{"functionName":"matchesErrorTest$1","ranges":[{"startOffset":479067,"endOffset":479290,"count":0}],"isBlockCoverage":false},{"functionName":"handleError$1","ranges":[{"startOffset":479311,"endOffset":480110,"count":0}],"isBlockCoverage":false},{"functionName":"then$1$2$onError","ranges":[{"startOffset":480164,"endOffset":480845,"count":1},{"startOffset":480507,"endOffset":480563,"count":0},{"startOffset":480676,"endOffset":480679,"count":0}],"isBlockCoverage":true},{"functionName":"then$1$1","ranges":[{"startOffset":480861,"endOffset":480933,"count":1}],"isBlockCoverage":true},{"functionName":"_thenAwait$1$2","ranges":[{"startOffset":480955,"endOffset":481337,"count":1}],"isBlockCoverage":true},{"functionName":"catchError$1","ranges":[{"startOffset":481357,"endOffset":481806,"count":0}],"isBlockCoverage":false},{"functionName":"whenComplete$1","ranges":[{"startOffset":481828,"endOffset":482281,"count":1}],"isBlockCoverage":true},{"functionName":"_cloneResult$1","ranges":[{"startOffset":482303,"endOffset":482502,"count":0}],"isBlockCoverage":false},{"functionName":"_addListener$1","ranges":[{"startOffset":482524,"endOffset":483257,"count":1},{"startOffset":482868,"endOffset":483106,"count":0}],"isBlockCoverage":true},{"functionName":"_prependListeners$1","ranges":[{"startOffset":483284,"endOffset":484374,"count":1},{"startOffset":483471,"endOffset":484368,"count":0}],"isBlockCoverage":true},{"functionName":"_removeListeners$0","ranges":[{"startOffset":484400,"endOffset":484667,"count":1}],"isBlockCoverage":true},{"functionName":"_reverseListeners$1","ranges":[{"startOffset":484694,"endOffset":484951,"count":1}],"isBlockCoverage":true},{"functionName":"_complete$1","ranges":[{"startOffset":484970,"endOffset":485601,"count":1},{"startOffset":485249,"endOffset":485317,"count":0}],"isBlockCoverage":true},{"functionName":"_completeWithValue$1","ranges":[{"startOffset":485629,"endOffset":486055,"count":1}],"isBlockCoverage":true},{"functionName":"_completeError$2","ranges":[{"startOffset":486079,"endOffset":486469,"count":0}],"isBlockCoverage":false},{"functionName":"_completeError$1","ranges":[{"startOffset":486493,"endOffset":486565,"count":0}],"isBlockCoverage":false},{"functionName":"_asyncComplete$1","ranges":[{"startOffset":486589,"endOffset":487004,"count":1},{"startOffset":486779,"endOffset":486841,"count":0}],"isBlockCoverage":true},{"functionName":"_chainFuture$1","ranges":[{"startOffset":487026,"endOffset":487512,"count":0}],"isBlockCoverage":false},{"functionName":"_asyncCompleteError$2","ranges":[{"startOffset":487541,"endOffset":487857,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":487940,"endOffset":488024,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":488113,"endOffset":488205,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":488296,"endOffset":488475,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":488567,"endOffset":488768,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":488782,"endOffset":488844,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":488937,"endOffset":489007,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":489093,"endOffset":489210,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":489294,"endOffset":489370,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":489461,"endOffset":489543,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":489655,"endOffset":491612,"count":1},{"startOffset":490115,"endOffset":490871,"count":0},{"startOffset":491050,"endOffset":491298,"count":0},{"startOffset":491326,"endOffset":491606,"count":0}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":491732,"endOffset":491785,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":491891,"endOffset":492537,"count":1},{"startOffset":492293,"endOffset":492531,"count":0}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":492634,"endOffset":493916,"count":0}],"isBlockCoverage":false},{"functionName":"get$isBroadcast","ranges":[{"startOffset":494027,"endOffset":494065,"count":1}],"isBlockCoverage":true},{"functionName":"pipe$1","ranges":[{"startOffset":494079,"endOffset":494313,"count":1}],"isBlockCoverage":true},{"functionName":"get$length","ranges":[{"startOffset":494331,"endOffset":494644,"count":0}],"isBlockCoverage":false},{"functionName":"get$first","ranges":[{"startOffset":494661,"endOffset":495037,"count":1}],"isBlockCoverage":true},{"functionName":"get$last","ranges":[{"startOffset":495053,"endOffset":495429,"count":0}],"isBlockCoverage":false},{"functionName":"firstWhere$1","ranges":[{"startOffset":495449,"endOffset":495994,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":496063,"endOffset":496187,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":496205,"endOffset":496263,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":496333,"endOffset":496503,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":496593,"endOffset":496811,"count":1}],"isBlockCoverage":true},{"functionName":"$signature","ranges":[{"startOffset":496829,"endOffset":496907,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":496963,"endOffset":497027,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":497105,"endOffset":497216,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":497234,"endOffset":497320,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":497379,"endOffset":497447,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":497523,"endOffset":497686,"count":1}],"isBlockCoverage":true},{"functionName":"$signature","ranges":[{"startOffset":497704,"endOffset":497790,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":497848,"endOffset":498176,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":498251,"endOffset":498435,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":498453,"endOffset":498539,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":498596,"endOffset":499042,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":499123,"endOffset":499482,"count":1}],"isBlockCoverage":true},{"functionName":"$signature","ranges":[{"startOffset":499500,"endOffset":499586,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":499649,"endOffset":499710,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":499794,"endOffset":499961,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":500044,"endOffset":500372,"count":0}],"isBlockCoverage":false},{"functionName":"get$_pendingEvents","ranges":[{"startOffset":500561,"endOffset":500951,"count":1},{"startOffset":500776,"endOffset":500950,"count":0}],"isBlockCoverage":true},{"functionName":"_ensurePendingEvents$0","ranges":[{"startOffset":500981,"endOffset":501700,"count":0}],"isBlockCoverage":false},{"functionName":"get$_async$_subscription","ranges":[{"startOffset":501732,"endOffset":502152,"count":1}],"isBlockCoverage":true},{"functionName":"_badEventState$0","ranges":[{"startOffset":502176,"endOffset":502426,"count":0}],"isBlockCoverage":false},{"functionName":"addStream$2$cancelOnError","ranges":[{"startOffset":502459,"endOffset":503511,"count":1},{"startOffset":502668,"endOffset":502716,"count":0},{"startOffset":502743,"endOffset":502874,"count":0},{"startOffset":503017,"endOffset":503060,"count":0},{"startOffset":503300,"endOffset":503316,"count":0},{"startOffset":503326,"endOffset":503339,"count":0}],"isBlockCoverage":true},{"functionName":"_ensureDoneFuture$0","ranges":[{"startOffset":503538,"endOffset":503771,"count":1},{"startOffset":503692,"endOffset":503747,"count":0}],"isBlockCoverage":true},{"functionName":"add$1","ranges":[{"startOffset":503784,"endOffset":504005,"count":1},{"startOffset":503924,"endOffset":503972,"count":0}],"isBlockCoverage":true},{"functionName":"addError$2","ranges":[{"startOffset":504023,"endOffset":504587,"count":0}],"isBlockCoverage":false},{"functionName":"addError$1","ranges":[{"startOffset":504605,"endOffset":504671,"count":0}],"isBlockCoverage":false},{"functionName":"close$0","ranges":[{"startOffset":504686,"endOffset":504977,"count":1},{"startOffset":504785,"endOffset":504820,"count":0},{"startOffset":504848,"endOffset":504896,"count":0}],"isBlockCoverage":true},{"functionName":"_closeUnchecked$0","ranges":[{"startOffset":505002,"endOffset":505204,"count":1},{"startOffset":505082,"endOffset":505101,"count":0},{"startOffset":505141,"endOffset":505198,"count":0}],"isBlockCoverage":true},{"functionName":"_add$1","ranges":[{"startOffset":505218,"endOffset":505567,"count":1},{"startOffset":505423,"endOffset":505561,"count":0}],"isBlockCoverage":true},{"functionName":"_async$_addError$2","ranges":[{"startOffset":505593,"endOffset":505900,"count":0}],"isBlockCoverage":false},{"functionName":"_close$0","ranges":[{"startOffset":505916,"endOffset":506256,"count":0}],"isBlockCoverage":false},{"functionName":"_subscribe$4","ranges":[{"startOffset":506276,"endOffset":507433,"count":1},{"startOffset":506562,"endOffset":506639,"count":0},{"startOffset":507026,"endOffset":507213,"count":0}],"isBlockCoverage":true},{"functionName":"_recordCancel$1","ranges":[{"startOffset":507456,"endOffset":508586,"count":1},{"startOffset":507936,"endOffset":508391,"count":0}],"isBlockCoverage":true},{"functionName":"_recordPause$1","ranges":[{"startOffset":508608,"endOffset":508942,"count":1},{"startOffset":508802,"endOffset":508900,"count":0}],"isBlockCoverage":true},{"functionName":"_recordResume$1","ranges":[{"startOffset":508965,"endOffset":509301,"count":1},{"startOffset":509159,"endOffset":509258,"count":0}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":509551,"endOffset":509611,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":509707,"endOffset":509840,"count":1},{"startOffset":509780,"endOffset":509798,"count":0},{"startOffset":509808,"endOffset":509834,"count":0}],"isBlockCoverage":true},{"functionName":"_sendData$1","ranges":[{"startOffset":509930,"endOffset":510047,"count":1}],"isBlockCoverage":true},{"functionName":"_sendError$2","ranges":[{"startOffset":510067,"endOffset":510179,"count":0}],"isBlockCoverage":false},{"functionName":"_sendDone$0","ranges":[{"startOffset":510198,"endOffset":510266,"count":0}],"isBlockCoverage":false},{"functionName":"_sendData$1","ranges":[{"startOffset":510338,"endOffset":510532,"count":0}],"isBlockCoverage":false},{"functionName":"_sendError$2","ranges":[{"startOffset":510552,"endOffset":510680,"count":0}],"isBlockCoverage":false},{"functionName":"_sendDone$0","ranges":[{"startOffset":510699,"endOffset":510788,"count":0}],"isBlockCoverage":false},{"functionName":"_createSubscription$4","ranges":[{"startOffset":510942,"endOffset":511156,"count":1}],"isBlockCoverage":true},{"functionName":"get$hashCode","ranges":[{"startOffset":511176,"endOffset":511275,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":511286,"endOffset":511499,"count":0}],"isBlockCoverage":false},{"functionName":"_onCancel$0","ranges":[{"startOffset":511564,"endOffset":511635,"count":1}],"isBlockCoverage":true},{"functionName":"_onPause$0","ranges":[{"startOffset":511653,"endOffset":511716,"count":1}],"isBlockCoverage":true},{"functionName":"_onResume$0","ranges":[{"startOffset":511735,"endOffset":511799,"count":1}],"isBlockCoverage":true},{"functionName":"add$1","ranges":[{"startOffset":511853,"endOffset":511951,"count":1}],"isBlockCoverage":true},{"functionName":"cancel$0","ranges":[{"startOffset":512090,"endOffset":512350,"count":1},{"startOffset":512181,"endOffset":512264,"count":0}],"isBlockCoverage":true},{"functionName":"call$2","ranges":[{"startOffset":512427,"endOffset":512562,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":512648,"endOffset":512723,"count":1}],"isBlockCoverage":true},{"functionName":"_BufferingStreamSubscription$4","ranges":[{"startOffset":512883,"endOffset":513035,"count":1}],"isBlockCoverage":true},{"functionName":"_setPendingEvents$1","ranges":[{"startOffset":513062,"endOffset":513518,"count":1}],"isBlockCoverage":true},{"functionName":"onData$1","ranges":[{"startOffset":513534,"endOffset":513897,"count":1}],"isBlockCoverage":true},{"functionName":"onError$1","ranges":[{"startOffset":513914,"endOffset":514590,"count":1},{"startOffset":514246,"endOffset":514584,"count":0}],"isBlockCoverage":true},{"functionName":"onDone$1","ranges":[{"startOffset":514606,"endOffset":514849,"count":1}],"isBlockCoverage":true},{"functionName":"pause$1","ranges":[{"startOffset":514864,"endOffset":515291,"count":1},{"startOffset":514982,"endOffset":514989,"count":0},{"startOffset":515094,"endOffset":515186,"count":0},{"startOffset":515240,"endOffset":515285,"count":0}],"isBlockCoverage":true},{"functionName":"pause$0","ranges":[{"startOffset":515306,"endOffset":515357,"count":1}],"isBlockCoverage":true},{"functionName":"resume$0","ranges":[{"startOffset":515373,"endOffset":516055,"count":1},{"startOffset":515471,"endOffset":515478,"count":0},{"startOffset":515591,"endOffset":515675,"count":0},{"startOffset":515735,"endOffset":515768,"count":0}],"isBlockCoverage":true},{"functionName":"cancel$0","ranges":[{"startOffset":516071,"endOffset":516331,"count":1}],"isBlockCoverage":true},{"functionName":"get$_mayResumeInput","ranges":[{"startOffset":516358,"endOffset":516536,"count":1},{"startOffset":516458,"endOffset":516479,"count":0},{"startOffset":516488,"endOffset":516513,"count":0}],"isBlockCoverage":true},{"functionName":"get$isPaused","ranges":[{"startOffset":516556,"endOffset":516607,"count":1}],"isBlockCoverage":true},{"functionName":"_cancel$0","ranges":[{"startOffset":516624,"endOffset":516954,"count":1}],"isBlockCoverage":true},{"functionName":"_add$1","ranges":[{"startOffset":516968,"endOffset":517413,"count":1},{"startOffset":517222,"endOffset":517229,"count":0},{"startOffset":517281,"endOffset":517407,"count":0}],"isBlockCoverage":true},{"functionName":"_async$_addError$2","ranges":[{"startOffset":517439,"endOffset":517688,"count":0}],"isBlockCoverage":false},{"functionName":"_close$0","ranges":[{"startOffset":517704,"endOffset":518023,"count":0}],"isBlockCoverage":false},{"functionName":"_onPause$0","ranges":[{"startOffset":518041,"endOffset":518106,"count":0}],"isBlockCoverage":false},{"functionName":"_onResume$0","ranges":[{"startOffset":518125,"endOffset":518190,"count":0}],"isBlockCoverage":false},{"functionName":"_onCancel$0","ranges":[{"startOffset":518209,"endOffset":518293,"count":1}],"isBlockCoverage":true},{"functionName":"_addPending$1","ranges":[{"startOffset":518314,"endOffset":518843,"count":0}],"isBlockCoverage":false},{"functionName":"_sendData$1","ranges":[{"startOffset":518862,"endOffset":519379,"count":1}],"isBlockCoverage":true},{"functionName":"_sendError$2","ranges":[{"startOffset":519399,"endOffset":520116,"count":0}],"isBlockCoverage":false},{"functionName":"_sendDone$0","ranges":[{"startOffset":520135,"endOffset":520625,"count":0}],"isBlockCoverage":false},{"functionName":"_guardCallback$1","ranges":[{"startOffset":520649,"endOffset":520983,"count":1}],"isBlockCoverage":true},{"functionName":"_checkState$1","ranges":[{"startOffset":521004,"endOffset":522070,"count":1},{"startOffset":521160,"endOffset":521231,"count":0},{"startOffset":521271,"endOffset":521474,"count":0},{"startOffset":521848,"endOffset":521892,"count":0},{"startOffset":522010,"endOffset":522021,"count":0},{"startOffset":522031,"endOffset":522064,"count":0}],"isBlockCoverage":true},{"functionName":"set$_onData","ranges":[{"startOffset":522089,"endOffset":522219,"count":1}],"isBlockCoverage":true},{"functionName":"set$_onDone","ranges":[{"startOffset":522238,"endOffset":522321,"count":1}],"isBlockCoverage":true},{"functionName":"set$_pending","ranges":[{"startOffset":522341,"endOffset":522487,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":522629,"endOffset":523285,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":523388,"endOffset":523626,"count":0}],"isBlockCoverage":false},{"functionName":"listen$4$cancelOnError$onDone$onError","ranges":[{"startOffset":523724,"endOffset":523966,"count":1}],"isBlockCoverage":true},{"functionName":"listen$2$onDone","ranges":[{"startOffset":523989,"endOffset":524106,"count":1}],"isBlockCoverage":true},{"functionName":"listen$3$onDone$onError","ranges":[{"startOffset":524137,"endOffset":524266,"count":1}],"isBlockCoverage":true},{"functionName":"listen$1","ranges":[{"startOffset":524282,"endOffset":524389,"count":1}],"isBlockCoverage":true},{"functionName":"_createSubscription$4","ranges":[{"startOffset":524418,"endOffset":524671,"count":0}],"isBlockCoverage":false},{"functionName":"_createSubscription$4","ranges":[{"startOffset":524743,"endOffset":525243,"count":1},{"startOffset":524958,"endOffset":525035,"count":0}],"isBlockCoverage":true},{"functionName":"get$isEmpty","ranges":[{"startOffset":525307,"endOffset":525370,"count":1}],"isBlockCoverage":true},{"functionName":"handleNext$1","ranges":[{"startOffset":525390,"endOffset":526251,"count":0}],"isBlockCoverage":false},{"functionName":"set$_async$_iterator","ranges":[{"startOffset":526279,"endOffset":526387,"count":0}],"isBlockCoverage":false},{"functionName":"set$next","ranges":[{"startOffset":526439,"endOffset":526521,"count":0}],"isBlockCoverage":false},{"functionName":"get$next","ranges":[{"startOffset":526537,"endOffset":526579,"count":0}],"isBlockCoverage":false},{"functionName":"perform$1","ranges":[{"startOffset":526631,"endOffset":526743,"count":0}],"isBlockCoverage":false},{"functionName":"perform$1","ranges":[{"startOffset":526796,"endOffset":526880,"count":0}],"isBlockCoverage":false},{"functionName":"perform$1","ranges":[{"startOffset":526932,"endOffset":526988,"count":0}],"isBlockCoverage":false},{"functionName":"get$next","ranges":[{"startOffset":527004,"endOffset":527041,"count":0}],"isBlockCoverage":false},{"functionName":"set$next","ranges":[{"startOffset":527057,"endOffset":527147,"count":0}],"isBlockCoverage":false},{"functionName":"schedule$1","ranges":[{"startOffset":527227,"endOffset":527689,"count":1},{"startOffset":527390,"endOffset":527397,"count":0},{"startOffset":527491,"endOffset":527576,"count":0}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":527757,"endOffset":527933,"count":1},{"startOffset":527889,"endOffset":527932,"count":0}],"isBlockCoverage":true},{"functionName":"get$isEmpty","ranges":[{"startOffset":528011,"endOffset":528074,"count":0}],"isBlockCoverage":false},{"functionName":"add$1","ranges":[{"startOffset":528087,"endOffset":528355,"count":0}],"isBlockCoverage":false},{"functionName":"handleNext$1","ranges":[{"startOffset":528375,"endOffset":528743,"count":0}],"isBlockCoverage":false},{"functionName":"get$isPaused","ranges":[{"startOffset":528809,"endOffset":528858,"count":0}],"isBlockCoverage":false},{"functionName":"_schedule$0","ranges":[{"startOffset":528877,"endOffset":529080,"count":0}],"isBlockCoverage":false},{"functionName":"onData$1","ranges":[{"startOffset":529096,"endOffset":529175,"count":0}],"isBlockCoverage":false},{"functionName":"onError$1","ranges":[{"startOffset":529192,"endOffset":529224,"count":0}],"isBlockCoverage":false},{"functionName":"onDone$1","ranges":[{"startOffset":529240,"endOffset":529332,"count":0}],"isBlockCoverage":false},{"functionName":"pause$1","ranges":[{"startOffset":529347,"endOffset":529401,"count":0}],"isBlockCoverage":false},{"functionName":"pause$0","ranges":[{"startOffset":529416,"endOffset":529467,"count":0}],"isBlockCoverage":false},{"functionName":"resume$0","ranges":[{"startOffset":529483,"endOffset":529661,"count":0}],"isBlockCoverage":false},{"functionName":"cancel$0","ranges":[{"startOffset":529677,"endOffset":529737,"count":0}],"isBlockCoverage":false},{"functionName":"_sendDone$0","ranges":[{"startOffset":529756,"endOffset":530019,"count":0}],"isBlockCoverage":false},{"functionName":"set$_onDone","ranges":[{"startOffset":530038,"endOffset":530121,"count":0}],"isBlockCoverage":false},{"functionName":"get$isBroadcast","ranges":[{"startOffset":530245,"endOffset":530282,"count":0}],"isBlockCoverage":false},{"functionName":"listen$4$cancelOnError$onDone$onError","ranges":[{"startOffset":530327,"endOffset":530684,"count":0}],"isBlockCoverage":false},{"functionName":"listen$3$onDone$onError","ranges":[{"startOffset":530715,"endOffset":530844,"count":0}],"isBlockCoverage":false},{"functionName":"listen$1","ranges":[{"startOffset":530860,"endOffset":530967,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":531027,"endOffset":531117,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":531203,"endOffset":531339,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":531418,"endOffset":531486,"count":1}],"isBlockCoverage":true},{"functionName":"toString$0","ranges":[{"startOffset":531582,"endOffset":531631,"count":0}],"isBlockCoverage":false},{"functionName":"handleUncaughtError$3","ranges":[{"startOffset":531905,"endOffset":532247,"count":0}],"isBlockCoverage":false},{"functionName":"registerCallback$1$2","ranges":[{"startOffset":532275,"endOffset":532668,"count":1}],"isBlockCoverage":true},{"functionName":"registerUnaryCallback$2$2","ranges":[{"startOffset":532701,"endOffset":533146,"count":1}],"isBlockCoverage":true},{"functionName":"registerBinaryCallback$3$2","ranges":[{"startOffset":533180,"endOffset":533670,"count":1}],"isBlockCoverage":true},{"functionName":"errorCallback$3","ranges":[{"startOffset":533693,"endOffset":534015,"count":0}],"isBlockCoverage":false},{"functionName":"get$_delegate","ranges":[{"startOffset":534130,"endOffset":534287,"count":1}],"isBlockCoverage":true},{"functionName":"get$errorZone","ranges":[{"startOffset":534308,"endOffset":534371,"count":1}],"isBlockCoverage":true},{"functionName":"runGuarded$1","ranges":[{"startOffset":534391,"endOffset":534691,"count":1},{"startOffset":534526,"endOffset":534685,"count":0}],"isBlockCoverage":true},{"functionName":"runUnaryGuarded$1$2","ranges":[{"startOffset":534718,"endOffset":535062,"count":1},{"startOffset":534897,"endOffset":535056,"count":0}],"isBlockCoverage":true},{"functionName":"runBinaryGuarded$2$3","ranges":[{"startOffset":535090,"endOffset":535511,"count":0}],"isBlockCoverage":false},{"functionName":"bindCallback$1$1","ranges":[{"startOffset":535535,"endOffset":535681,"count":1}],"isBlockCoverage":true},{"functionName":"bindUnaryCallback$2$1","ranges":[{"startOffset":535710,"endOffset":535907,"count":0}],"isBlockCoverage":false},{"functionName":"bindCallbackGuarded$1","ranges":[{"startOffset":535936,"endOffset":536091,"count":1}],"isBlockCoverage":true},{"functionName":"bindUnaryCallbackGuarded$1$1","ranges":[{"startOffset":536127,"endOffset":536303,"count":1}],"isBlockCoverage":true},{"functionName":"$index","ranges":[{"startOffset":536317,"endOffset":536623,"count":1}],"isBlockCoverage":true},{"functionName":"handleUncaughtError$2","ranges":[{"startOffset":536652,"endOffset":537041,"count":0}],"isBlockCoverage":false},{"functionName":"fork$2$specification$zoneValues","ranges":[{"startOffset":537080,"endOffset":537413,"count":1}],"isBlockCoverage":true},{"functionName":"run$1$1","ranges":[{"startOffset":537428,"endOffset":537846,"count":1}],"isBlockCoverage":true},{"functionName":"runUnary$2$2","ranges":[{"startOffset":537866,"endOffset":538372,"count":1}],"isBlockCoverage":true},{"functionName":"runBinary$3$3","ranges":[{"startOffset":538393,"endOffset":538980,"count":0}],"isBlockCoverage":false},{"functionName":"registerCallback$1$1","ranges":[{"startOffset":539008,"endOffset":539469,"count":1}],"isBlockCoverage":true},{"functionName":"registerUnaryCallback$2$1","ranges":[{"startOffset":539502,"endOffset":540015,"count":1}],"isBlockCoverage":true},{"functionName":"registerBinaryCallback$3$1","ranges":[{"startOffset":540049,"endOffset":540607,"count":1}],"isBlockCoverage":true},{"functionName":"errorCallback$2","ranges":[{"startOffset":540630,"endOffset":541146,"count":0}],"isBlockCoverage":false},{"functionName":"scheduleMicrotask$1","ranges":[{"startOffset":541173,"endOffset":541522,"count":1}],"isBlockCoverage":true},{"functionName":"createTimer$2","ranges":[{"startOffset":541543,"endOffset":541906,"count":1}],"isBlockCoverage":true},{"functionName":"print$1","ranges":[{"startOffset":541921,"endOffset":542216,"count":0}],"isBlockCoverage":false},{"functionName":"set$_run","ranges":[{"startOffset":542232,"endOffset":542315,"count":1}],"isBlockCoverage":true},{"functionName":"set$_runUnary","ranges":[{"startOffset":542336,"endOffset":542434,"count":1}],"isBlockCoverage":true},{"functionName":"set$_runBinary","ranges":[{"startOffset":542456,"endOffset":542557,"count":1}],"isBlockCoverage":true},{"functionName":"set$_registerCallback","ranges":[{"startOffset":542586,"endOffset":542708,"count":1}],"isBlockCoverage":true},{"functionName":"set$_registerUnaryCallback","ranges":[{"startOffset":542742,"endOffset":542879,"count":1}],"isBlockCoverage":true},{"functionName":"set$_registerBinaryCallback","ranges":[{"startOffset":542914,"endOffset":543054,"count":1}],"isBlockCoverage":true},{"functionName":"set$_errorCallback","ranges":[{"startOffset":543080,"endOffset":543248,"count":1}],"isBlockCoverage":true},{"functionName":"set$_scheduleMicrotask","ranges":[{"startOffset":543278,"endOffset":543462,"count":1}],"isBlockCoverage":true},{"functionName":"set$_createTimer","ranges":[{"startOffset":543486,"endOffset":543666,"count":1}],"isBlockCoverage":true},{"functionName":"set$_createPeriodicTimer","ranges":[{"startOffset":543698,"endOffset":543908,"count":1}],"isBlockCoverage":true},{"functionName":"set$_print","ranges":[{"startOffset":543926,"endOffset":544053,"count":1}],"isBlockCoverage":true},{"functionName":"set$_fork","ranges":[{"startOffset":544070,"endOffset":544243,"count":1}],"isBlockCoverage":true},{"functionName":"set$_handleUncaughtError","ranges":[{"startOffset":544275,"endOffset":544455,"count":1}],"isBlockCoverage":true},{"functionName":"get$_run","ranges":[{"startOffset":544471,"endOffset":544513,"count":1}],"isBlockCoverage":true},{"functionName":"get$_runUnary","ranges":[{"startOffset":544534,"endOffset":544581,"count":1}],"isBlockCoverage":true},{"functionName":"get$_runBinary","ranges":[{"startOffset":544603,"endOffset":544651,"count":1}],"isBlockCoverage":true},{"functionName":"get$_registerCallback","ranges":[{"startOffset":544680,"endOffset":544735,"count":1}],"isBlockCoverage":true},{"functionName":"get$_registerUnaryCallback","ranges":[{"startOffset":544769,"endOffset":544829,"count":1}],"isBlockCoverage":true},{"functionName":"get$_registerBinaryCallback","ranges":[{"startOffset":544864,"endOffset":544925,"count":1}],"isBlockCoverage":true},{"functionName":"get$_errorCallback","ranges":[{"startOffset":544951,"endOffset":545003,"count":1}],"isBlockCoverage":true},{"functionName":"get$_scheduleMicrotask","ranges":[{"startOffset":545033,"endOffset":545089,"count":1}],"isBlockCoverage":true},{"functionName":"get$_createTimer","ranges":[{"startOffset":545113,"endOffset":545163,"count":1}],"isBlockCoverage":true},{"functionName":"get$_createPeriodicTimer","ranges":[{"startOffset":545195,"endOffset":545253,"count":1}],"isBlockCoverage":true},{"functionName":"get$_print","ranges":[{"startOffset":545271,"endOffset":545315,"count":1}],"isBlockCoverage":true},{"functionName":"get$_fork","ranges":[{"startOffset":545332,"endOffset":545375,"count":1}],"isBlockCoverage":true},{"functionName":"get$_handleUncaughtError","ranges":[{"startOffset":545407,"endOffset":545465,"count":1}],"isBlockCoverage":true},{"functionName":"get$parent","ranges":[{"startOffset":545483,"endOffset":545535,"count":1}],"isBlockCoverage":true},{"functionName":"get$_async$_map","ranges":[{"startOffset":545558,"endOffset":545607,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":545676,"endOffset":545752,"count":1}],"isBlockCoverage":true},{"functionName":"$signature","ranges":[{"startOffset":545770,"endOffset":545824,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":545898,"endOffset":546051,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":546069,"endOffset":546156,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":546232,"endOffset":546305,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":546405,"endOffset":546531,"count":1}],"isBlockCoverage":true},{"functionName":"$signature","ranges":[{"startOffset":546549,"endOffset":546604,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":546673,"endOffset":546999,"count":0}],"isBlockCoverage":false},{"functionName":"get$_run","ranges":[{"startOffset":547066,"endOffset":547133,"count":1}],"isBlockCoverage":true},{"functionName":"get$_runUnary","ranges":[{"startOffset":547154,"endOffset":547226,"count":1}],"isBlockCoverage":true},{"functionName":"get$_runBinary","ranges":[{"startOffset":547248,"endOffset":547321,"count":1}],"isBlockCoverage":true},{"functionName":"get$_registerCallback","ranges":[{"startOffset":547350,"endOffset":547430,"count":1}],"isBlockCoverage":true},{"functionName":"get$_registerUnaryCallback","ranges":[{"startOffset":547464,"endOffset":547516,"count":1}],"isBlockCoverage":true},{"functionName":"get$_registerBinaryCallback","ranges":[{"startOffset":547551,"endOffset":547603,"count":1}],"isBlockCoverage":true},{"functionName":"get$_errorCallback","ranges":[{"startOffset":547629,"endOffset":547706,"count":1}],"isBlockCoverage":true},{"functionName":"get$_scheduleMicrotask","ranges":[{"startOffset":547736,"endOffset":547817,"count":1}],"isBlockCoverage":true},{"functionName":"get$_createTimer","ranges":[{"startOffset":547841,"endOffset":547916,"count":1}],"isBlockCoverage":true},{"functionName":"get$_createPeriodicTimer","ranges":[{"startOffset":547948,"endOffset":548000,"count":1}],"isBlockCoverage":true},{"functionName":"get$_print","ranges":[{"startOffset":548018,"endOffset":548087,"count":1}],"isBlockCoverage":true},{"functionName":"get$_fork","ranges":[{"startOffset":548104,"endOffset":548172,"count":1}],"isBlockCoverage":true},{"functionName":"get$_handleUncaughtError","ranges":[{"startOffset":548204,"endOffset":548256,"count":1}],"isBlockCoverage":true},{"functionName":"get$parent","ranges":[{"startOffset":548274,"endOffset":548312,"count":1}],"isBlockCoverage":true},{"functionName":"get$_async$_map","ranges":[{"startOffset":548335,"endOffset":548395,"count":0}],"isBlockCoverage":false},{"functionName":"get$_delegate","ranges":[{"startOffset":548416,"endOffset":548585,"count":0}],"isBlockCoverage":false},{"functionName":"get$errorZone","ranges":[{"startOffset":548606,"endOffset":548643,"count":1}],"isBlockCoverage":true},{"functionName":"runGuarded$1","ranges":[{"startOffset":548663,"endOffset":549139,"count":0}],"isBlockCoverage":false},{"functionName":"runUnaryGuarded$1$2","ranges":[{"startOffset":549166,"endOffset":549689,"count":1},{"startOffset":549479,"endOffset":549683,"count":0}],"isBlockCoverage":true},{"functionName":"runBinaryGuarded$2$3","ranges":[{"startOffset":549717,"endOffset":550324,"count":0}],"isBlockCoverage":false},{"functionName":"bindCallback$1$1","ranges":[{"startOffset":550348,"endOffset":550461,"count":0}],"isBlockCoverage":false},{"functionName":"bindCallbackGuarded$1","ranges":[{"startOffset":550490,"endOffset":550604,"count":0}],"isBlockCoverage":false},{"functionName":"bindUnaryCallbackGuarded$1$1","ranges":[{"startOffset":550640,"endOffset":550766,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":550780,"endOffset":550823,"count":0}],"isBlockCoverage":false},{"functionName":"handleUncaughtError$2","ranges":[{"startOffset":550852,"endOffset":550983,"count":0}],"isBlockCoverage":false},{"functionName":"fork$2$specification$zoneValues","ranges":[{"startOffset":551022,"endOffset":551136,"count":1}],"isBlockCoverage":true},{"functionName":"run$1$1","ranges":[{"startOffset":551151,"endOffset":551331,"count":0}],"isBlockCoverage":false},{"functionName":"runUnary$2$2","ranges":[{"startOffset":551351,"endOffset":551608,"count":1},{"startOffset":551538,"endOffset":551607,"count":0}],"isBlockCoverage":true},{"functionName":"runBinary$3$3","ranges":[{"startOffset":551629,"endOffset":551954,"count":0}],"isBlockCoverage":false},{"functionName":"registerCallback$1$1","ranges":[{"startOffset":551982,"endOffset":552047,"count":1}],"isBlockCoverage":true},{"functionName":"registerUnaryCallback$2$1","ranges":[{"startOffset":552080,"endOffset":552178,"count":1}],"isBlockCoverage":true},{"functionName":"registerBinaryCallback$3$1","ranges":[{"startOffset":552212,"endOffset":552328,"count":1}],"isBlockCoverage":true},{"functionName":"errorCallback$2","ranges":[{"startOffset":552351,"endOffset":552448,"count":0}],"isBlockCoverage":false},{"functionName":"scheduleMicrotask$1","ranges":[{"startOffset":552475,"endOffset":552575,"count":1}],"isBlockCoverage":true},{"functionName":"createTimer$2","ranges":[{"startOffset":552596,"endOffset":552701,"count":0}],"isBlockCoverage":false},{"functionName":"print$1","ranges":[{"startOffset":552716,"endOffset":552768,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":552835,"endOffset":552902,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":552920,"endOffset":552974,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":553048,"endOffset":553112,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":553210,"endOffset":553327,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":553345,"endOffset":553400,"count":0}],"isBlockCoverage":false},{"functionName":"call$5","ranges":[{"startOffset":553453,"endOffset":554320,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":554389,"endOffset":554447,"count":0}],"isBlockCoverage":false},{"functionName":"get$isEmpty","ranges":[{"startOffset":554466,"endOffset":554530,"count":0}],"isBlockCoverage":false},{"functionName":"get$keys","ranges":[{"startOffset":554546,"endOffset":554667,"count":0}],"isBlockCoverage":false},{"functionName":"containsKey$1","ranges":[{"startOffset":554688,"endOffset":555100,"count":1},{"startOffset":554860,"endOffset":554882,"count":0},{"startOffset":554924,"endOffset":554953,"count":0},{"startOffset":554955,"endOffset":555048,"count":0}],"isBlockCoverage":true},{"functionName":"_containsKey$1","ranges":[{"startOffset":555122,"endOffset":555308,"count":1}],"isBlockCoverage":true},{"functionName":"$index","ranges":[{"startOffset":555322,"endOffset":555803,"count":1},{"startOffset":555403,"endOffset":555425,"count":0},{"startOffset":555427,"endOffset":555567,"count":0},{"startOffset":555600,"endOffset":555629,"count":0},{"startOffset":555631,"endOffset":555759,"count":0}],"isBlockCoverage":true},{"functionName":"_get$1","ranges":[{"startOffset":555817,"endOffset":556095,"count":1},{"startOffset":555929,"endOffset":555941,"count":0}],"isBlockCoverage":true},{"functionName":"$indexSet","ranges":[{"startOffset":556112,"endOffset":556762,"count":1},{"startOffset":556316,"endOffset":556338,"count":0},{"startOffset":556340,"endOffset":556504,"count":0},{"startOffset":556537,"endOffset":556566,"count":0},{"startOffset":556568,"endOffset":556717,"count":0}],"isBlockCoverage":true},{"functionName":"_set$2","ranges":[{"startOffset":556776,"endOffset":557585,"count":1},{"startOffset":557442,"endOffset":557571,"count":0}],"isBlockCoverage":true},{"functionName":"remove$1","ranges":[{"startOffset":557601,"endOffset":557678,"count":0}],"isBlockCoverage":false},{"functionName":"_remove$1","ranges":[{"startOffset":557695,"endOffset":558203,"count":0}],"isBlockCoverage":false},{"functionName":"forEach$1","ranges":[{"startOffset":558220,"endOffset":558693,"count":0}],"isBlockCoverage":false},{"functionName":"_computeKeys$0","ranges":[{"startOffset":558715,"endOffset":560019,"count":0}],"isBlockCoverage":false},{"functionName":"_addHashTableEntry$3","ranges":[{"startOffset":560047,"endOffset":560344,"count":0}],"isBlockCoverage":false},{"functionName":"_computeHashCode$1","ranges":[{"startOffset":560370,"endOffset":560439,"count":1}],"isBlockCoverage":true},{"functionName":"_getBucket$2","ranges":[{"startOffset":560459,"endOffset":560537,"count":1}],"isBlockCoverage":true},{"functionName":"_findBucketIndex$2","ranges":[{"startOffset":560563,"endOffset":560802,"count":1},{"startOffset":560779,"endOffset":560801,"count":0}],"isBlockCoverage":true},{"functionName":"_computeHashCode$1","ranges":[{"startOffset":560867,"endOffset":560937,"count":1}],"isBlockCoverage":true},{"functionName":"_findBucketIndex$2","ranges":[{"startOffset":560963,"endOffset":561255,"count":1},{"startOffset":561057,"endOffset":561254,"count":0}],"isBlockCoverage":true},{"functionName":"get$length","ranges":[{"startOffset":561315,"endOffset":561378,"count":0}],"isBlockCoverage":false},{"functionName":"get$isEmpty","ranges":[{"startOffset":561397,"endOffset":561466,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":561486,"endOffset":561640,"count":0}],"isBlockCoverage":false},{"functionName":"contains$1","ranges":[{"startOffset":561658,"endOffset":561733,"count":0}],"isBlockCoverage":false},{"functionName":"get$current","ranges":[{"startOffset":561794,"endOffset":561852,"count":0}],"isBlockCoverage":false},{"functionName":"moveNext$0","ranges":[{"startOffset":561870,"endOffset":562335,"count":0}],"isBlockCoverage":false},{"functionName":"set$_collection$_current","ranges":[{"startOffset":562367,"endOffset":562468,"count":0}],"isBlockCoverage":false},{"functionName":"_newSet$0","ranges":[{"startOffset":562542,"endOffset":562647,"count":1}],"isBlockCoverage":true},{"functionName":"get$iterator","ranges":[{"startOffset":562667,"endOffset":562927,"count":1}],"isBlockCoverage":true},{"functionName":"get$length","ranges":[{"startOffset":562945,"endOffset":563003,"count":0}],"isBlockCoverage":false},{"functionName":"get$isEmpty","ranges":[{"startOffset":563022,"endOffset":563086,"count":0}],"isBlockCoverage":false},{"functionName":"contains$1","ranges":[{"startOffset":563104,"endOffset":563663,"count":1},{"startOffset":563301,"endOffset":563382,"count":0},{"startOffset":563533,"endOffset":563657,"count":0}],"isBlockCoverage":true},{"functionName":"_contains$1","ranges":[{"startOffset":563682,"endOffset":563883,"count":0}],"isBlockCoverage":false},{"functionName":"get$first","ranges":[{"startOffset":563900,"endOffset":564112,"count":0}],"isBlockCoverage":false},{"functionName":"get$last","ranges":[{"startOffset":564128,"endOffset":564339,"count":0}],"isBlockCoverage":false},{"functionName":"add$1","ranges":[{"startOffset":564352,"endOffset":565009,"count":1},{"startOffset":564713,"endOffset":565003,"count":0}],"isBlockCoverage":true},{"functionName":"_collection$_add$1","ranges":[{"startOffset":565035,"endOffset":565721,"count":0}],"isBlockCoverage":false},{"functionName":"remove$1","ranges":[{"startOffset":565737,"endOffset":566117,"count":1},{"startOffset":565819,"endOffset":565844,"count":0},{"startOffset":565854,"endOffset":565915,"count":0},{"startOffset":566060,"endOffset":566111,"count":0}],"isBlockCoverage":true},{"functionName":"_remove$1","ranges":[{"startOffset":566134,"endOffset":566619,"count":0}],"isBlockCoverage":false},{"functionName":"_addHashTableEntry$2","ranges":[{"startOffset":566647,"endOffset":566913,"count":1},{"startOffset":566808,"endOffset":566821,"count":0}],"isBlockCoverage":true},{"functionName":"_removeHashTableEntry$2","ranges":[{"startOffset":566944,"endOffset":567227,"count":1},{"startOffset":567033,"endOffset":567226,"count":0}],"isBlockCoverage":true},{"functionName":"_collection$_modified$0","ranges":[{"startOffset":567258,"endOffset":567366,"count":1}],"isBlockCoverage":true},{"functionName":"_collection$_newLinkedCell$1","ranges":[{"startOffset":567402,"endOffset":567925,"count":1}],"isBlockCoverage":true},{"functionName":"_unlinkCell$1","ranges":[{"startOffset":567946,"endOffset":568524,"count":0}],"isBlockCoverage":false},{"functionName":"_computeHashCode$1","ranges":[{"startOffset":568550,"endOffset":568627,"count":0}],"isBlockCoverage":false},{"functionName":"_findBucketIndex$2","ranges":[{"startOffset":568653,"endOffset":568906,"count":0}],"isBlockCoverage":false},{"functionName":"get$current","ranges":[{"startOffset":569034,"endOffset":569092,"count":0}],"isBlockCoverage":false},{"functionName":"moveNext$0","ranges":[{"startOffset":569110,"endOffset":569695,"count":1},{"startOffset":569258,"endOffset":569316,"count":0},{"startOffset":569475,"endOffset":569681,"count":0}],"isBlockCoverage":true},{"functionName":"set$_collection$_current","ranges":[{"startOffset":569727,"endOffset":569828,"count":1}],"isBlockCoverage":true},{"functionName":"get$length","ranges":[{"startOffset":569909,"endOffset":570001,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":570015,"endOffset":570118,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":570183,"endOffset":570273,"count":1}],"isBlockCoverage":true},{"functionName":"call$2","ranges":[{"startOffset":570402,"endOffset":570492,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":570649,"endOffset":570808,"count":0}],"isBlockCoverage":false},{"functionName":"elementAt$1","ranges":[{"startOffset":570827,"endOffset":570903,"count":0}],"isBlockCoverage":false},{"functionName":"get$isEmpty","ranges":[{"startOffset":570922,"endOffset":570994,"count":0}],"isBlockCoverage":false},{"functionName":"get$first","ranges":[{"startOffset":571011,"endOffset":571186,"count":0}],"isBlockCoverage":false},{"functionName":"get$last","ranges":[{"startOffset":571202,"endOffset":571405,"count":0}],"isBlockCoverage":false},{"functionName":"map$1$1","ranges":[{"startOffset":571420,"endOffset":571672,"count":0}],"isBlockCoverage":false},{"functionName":"toList$1$growable","ranges":[{"startOffset":571697,"endOffset":572067,"count":0}],"isBlockCoverage":false},{"functionName":"toList$0","ranges":[{"startOffset":572083,"endOffset":572164,"count":0}],"isBlockCoverage":false},{"functionName":"toSet$0","ranges":[{"startOffset":572179,"endOffset":572441,"count":0}],"isBlockCoverage":false},{"functionName":"remove$1","ranges":[{"startOffset":572457,"endOffset":572717,"count":0}],"isBlockCoverage":false},{"functionName":"_closeGap$2","ranges":[{"startOffset":572736,"endOffset":573112,"count":0}],"isBlockCoverage":false},{"functionName":"fillRange$3","ranges":[{"startOffset":573131,"endOffset":573410,"count":1}],"isBlockCoverage":true},{"functionName":"toString$0","ranges":[{"startOffset":573428,"endOffset":573524,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":573616,"endOffset":573883,"count":0}],"isBlockCoverage":false},{"functionName":"cast$2$0","ranges":[{"startOffset":573949,"endOffset":574109,"count":1}],"isBlockCoverage":true},{"functionName":"forEach$1","ranges":[{"startOffset":574126,"endOffset":574420,"count":0}],"isBlockCoverage":false},{"functionName":"map$2$1","ranges":[{"startOffset":574435,"endOffset":574940,"count":1}],"isBlockCoverage":true},{"functionName":"containsKey$1","ranges":[{"startOffset":574961,"endOffset":575031,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":575049,"endOffset":575132,"count":0}],"isBlockCoverage":false},{"functionName":"get$isEmpty","ranges":[{"startOffset":575151,"endOffset":575235,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":575253,"endOffset":575314,"count":0}],"isBlockCoverage":false},{"functionName":"remove$1","ranges":[{"startOffset":575389,"endOffset":575497,"count":0}],"isBlockCoverage":false},{"functionName":"cast$2$0","ranges":[{"startOffset":575543,"endOffset":575614,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":575628,"endOffset":575691,"count":0}],"isBlockCoverage":false},{"functionName":"containsKey$1","ranges":[{"startOffset":575712,"endOffset":575776,"count":0}],"isBlockCoverage":false},{"functionName":"forEach$1","ranges":[{"startOffset":575793,"endOffset":575906,"count":1}],"isBlockCoverage":true},{"functionName":"get$isEmpty","ranges":[{"startOffset":575925,"endOffset":576003,"count":1}],"isBlockCoverage":true},{"functionName":"get$length","ranges":[{"startOffset":576021,"endOffset":576098,"count":0}],"isBlockCoverage":false},{"functionName":"get$keys","ranges":[{"startOffset":576114,"endOffset":576167,"count":0}],"isBlockCoverage":false},{"functionName":"remove$1","ranges":[{"startOffset":576183,"endOffset":576248,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":576266,"endOffset":576323,"count":0}],"isBlockCoverage":false},{"functionName":"map$2$1","ranges":[{"startOffset":576338,"endOffset":576514,"count":1}],"isBlockCoverage":true},{"functionName":"cast$2$0","ranges":[{"startOffset":576587,"endOffset":576753,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":576805,"endOffset":576990,"count":0}],"isBlockCoverage":false},{"functionName":"get$isEmpty","ranges":[{"startOffset":577009,"endOffset":577068,"count":1}],"isBlockCoverage":true},{"functionName":"get$length","ranges":[{"startOffset":577086,"endOffset":577176,"count":0}],"isBlockCoverage":false},{"functionName":"get$first","ranges":[{"startOffset":577193,"endOffset":577451,"count":0}],"isBlockCoverage":false},{"functionName":"get$last","ranges":[{"startOffset":577467,"endOffset":577803,"count":0}],"isBlockCoverage":false},{"functionName":"elementAt$1","ranges":[{"startOffset":577822,"endOffset":578227,"count":0}],"isBlockCoverage":false},{"functionName":"clear$0","ranges":[{"startOffset":578242,"endOffset":578565,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":578583,"endOffset":578668,"count":0}],"isBlockCoverage":false},{"functionName":"removeFirst$0","ranges":[{"startOffset":578689,"endOffset":579148,"count":1},{"startOffset":578802,"endOffset":578860,"count":0},{"startOffset":578955,"endOffset":578978,"count":0}],"isBlockCoverage":true},{"functionName":"_collection$_add$1","ranges":[{"startOffset":579174,"endOffset":580057,"count":1},{"startOffset":579524,"endOffset":580017,"count":0}],"isBlockCoverage":true},{"functionName":"set$_table","ranges":[{"startOffset":580075,"endOffset":580163,"count":1}],"isBlockCoverage":true},{"functionName":"get$current","ranges":[{"startOffset":580240,"endOffset":580298,"count":0}],"isBlockCoverage":false},{"functionName":"moveNext$0","ranges":[{"startOffset":580316,"endOffset":580875,"count":0}],"isBlockCoverage":false},{"functionName":"set$_collection$_current","ranges":[{"startOffset":580907,"endOffset":581008,"count":0}],"isBlockCoverage":false},{"functionName":"get$isEmpty","ranges":[{"startOffset":581078,"endOffset":581139,"count":0}],"isBlockCoverage":false},{"functionName":"map$1$1","ranges":[{"startOffset":581154,"endOffset":581394,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":581412,"endOffset":581497,"count":0}],"isBlockCoverage":false},{"functionName":"every$1","ranges":[{"startOffset":581512,"endOffset":581772,"count":0}],"isBlockCoverage":false},{"functionName":"get$first","ranges":[{"startOffset":581789,"endOffset":581974,"count":0}],"isBlockCoverage":false},{"functionName":"get$last","ranges":[{"startOffset":581990,"endOffset":582256,"count":0}],"isBlockCoverage":false},{"functionName":"toSet$0","ranges":[{"startOffset":582456,"endOffset":582553,"count":1}],"isBlockCoverage":true},{"functionName":"get$isEmpty","ranges":[{"startOffset":582572,"endOffset":582636,"count":0}],"isBlockCoverage":false},{"functionName":"addAll$1","ranges":[{"startOffset":582652,"endOffset":582872,"count":1},{"startOffset":582834,"endOffset":582866,"count":0}],"isBlockCoverage":true},{"functionName":"union$1","ranges":[{"startOffset":582887,"endOffset":583059,"count":1}],"isBlockCoverage":true},{"functionName":"toList$1$growable","ranges":[{"startOffset":583084,"endOffset":583579,"count":1},{"startOffset":583450,"endOffset":583552,"count":0}],"isBlockCoverage":true},{"functionName":"toList$0","ranges":[{"startOffset":583595,"endOffset":583676,"count":1}],"isBlockCoverage":true},{"functionName":"map$1$1","ranges":[{"startOffset":583691,"endOffset":583931,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":583949,"endOffset":584034,"count":0}],"isBlockCoverage":false},{"functionName":"where$1","ranges":[{"startOffset":584049,"endOffset":584214,"count":1}],"isBlockCoverage":true},{"functionName":"fold$1$2","ranges":[{"startOffset":584230,"endOffset":584642,"count":0}],"isBlockCoverage":false},{"functionName":"every$1","ranges":[{"startOffset":584657,"endOffset":584988,"count":0}],"isBlockCoverage":false},{"functionName":"any$1","ranges":[{"startOffset":585001,"endOffset":585340,"count":0}],"isBlockCoverage":false},{"functionName":"get$first","ranges":[{"startOffset":585357,"endOffset":585627,"count":0}],"isBlockCoverage":false},{"functionName":"get$last","ranges":[{"startOffset":585643,"endOffset":585994,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":586272,"endOffset":586605,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":586623,"endOffset":586845,"count":0}],"isBlockCoverage":false},{"functionName":"get$isEmpty","ranges":[{"startOffset":586864,"endOffset":586925,"count":0}],"isBlockCoverage":false},{"functionName":"get$keys","ranges":[{"startOffset":586941,"endOffset":587091,"count":0}],"isBlockCoverage":false},{"functionName":"containsKey$1","ranges":[{"startOffset":587112,"endOffset":587355,"count":0}],"isBlockCoverage":false},{"functionName":"remove$1","ranges":[{"startOffset":587371,"endOffset":587528,"count":0}],"isBlockCoverage":false},{"functionName":"forEach$1","ranges":[{"startOffset":587545,"endOffset":588211,"count":0}],"isBlockCoverage":false},{"functionName":"get$_upgradedMap","ranges":[{"startOffset":588235,"endOffset":588325,"count":0}],"isBlockCoverage":false},{"functionName":"_convert$_computeKeys$0","ranges":[{"startOffset":588356,"endOffset":588651,"count":0}],"isBlockCoverage":false},{"functionName":"_upgrade$0","ranges":[{"startOffset":588669,"endOffset":589287,"count":0}],"isBlockCoverage":false},{"functionName":"_process$1","ranges":[{"startOffset":589305,"endOffset":589541,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":589601,"endOffset":589681,"count":0}],"isBlockCoverage":false},{"functionName":"elementAt$1","ranges":[{"startOffset":589700,"endOffset":590025,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":590045,"endOffset":590376,"count":0}],"isBlockCoverage":false},{"functionName":"contains$1","ranges":[{"startOffset":590394,"endOffset":590464,"count":0}],"isBlockCoverage":false},{"functionName":"encode$1","ranges":[{"startOffset":590513,"endOffset":590588,"count":0}],"isBlockCoverage":false},{"functionName":"convert$1","ranges":[{"startOffset":590649,"endOffset":591298,"count":0}],"isBlockCoverage":false},{"functionName":"normalize$3","ranges":[{"startOffset":591384,"endOffset":595104,"count":0}],"isBlockCoverage":false},{"functionName":"decode$2$reviver","ranges":[{"startOffset":595311,"endOffset":595497,"count":0}],"isBlockCoverage":false},{"functionName":"get$decoder","ranges":[{"startOffset":595516,"endOffset":595567,"count":0}],"isBlockCoverage":false},{"functionName":"get$encoder","ranges":[{"startOffset":595650,"endOffset":595698,"count":0}],"isBlockCoverage":false},{"functionName":"convert$1","ranges":[{"startOffset":595749,"endOffset":596529,"count":0}],"isBlockCoverage":false},{"functionName":"_writeSurrogate$2","ranges":[{"startOffset":596589,"endOffset":598037,"count":0}],"isBlockCoverage":false},{"functionName":"_fillBuffer$3","ranges":[{"startOffset":598058,"endOffset":599908,"count":0}],"isBlockCoverage":false},{"functionName":"convert$1","ranges":[{"startOffset":599959,"endOffset":601081,"count":0}],"isBlockCoverage":false},{"functionName":"flush$2","ranges":[{"startOffset":601131,"endOffset":601378,"count":0}],"isBlockCoverage":false},{"functionName":"convert$3","ranges":[{"startOffset":601395,"endOffset":605325,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":605392,"endOffset":605547,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":605567,"endOffset":605692,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":605710,"endOffset":606328,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":606397,"endOffset":606550,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":606570,"endOffset":606648,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":606666,"endOffset":607284,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":607348,"endOffset":607623,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":607707,"endOffset":607790,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":607891,"endOffset":608058,"count":0}],"isBlockCoverage":false},{"functionName":"get$message","ranges":[{"startOffset":608077,"endOffset":608130,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":608186,"endOffset":608236,"count":0}],"isBlockCoverage":false},{"functionName":"get$_errorName","ranges":[{"startOffset":608294,"endOffset":608378,"count":0}],"isBlockCoverage":false},{"functionName":"get$_errorExplanation","ranges":[{"startOffset":608407,"endOffset":608442,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":608460,"endOffset":608982,"count":0}],"isBlockCoverage":false},{"functionName":"get$message","ranges":[{"startOffset":609001,"endOffset":609054,"count":0}],"isBlockCoverage":false},{"functionName":"get$_errorName","ranges":[{"startOffset":609109,"endOffset":609154,"count":0}],"isBlockCoverage":false},{"functionName":"get$_errorExplanation","ranges":[{"startOffset":609183,"endOffset":609833,"count":0}],"isBlockCoverage":false},{"functionName":"get$_errorName","ranges":[{"startOffset":609888,"endOffset":609933,"count":0}],"isBlockCoverage":false},{"functionName":"get$_errorExplanation","ranges":[{"startOffset":609962,"endOffset":610401,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":610419,"endOffset":610471,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":610528,"endOffset":610602,"count":0}],"isBlockCoverage":false},{"functionName":"get$message","ranges":[{"startOffset":610621,"endOffset":610674,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":610733,"endOffset":610859,"count":0}],"isBlockCoverage":false},{"functionName":"get$message","ranges":[{"startOffset":610878,"endOffset":610931,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":610982,"endOffset":611044,"count":0}],"isBlockCoverage":false},{"functionName":"get$message","ranges":[{"startOffset":611063,"endOffset":611116,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":611184,"endOffset":611413,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":611470,"endOffset":611519,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":611595,"endOffset":611645,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":611728,"endOffset":611927,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":611978,"endOffset":612040,"count":0}],"isBlockCoverage":false},{"functionName":"get$message","ranges":[{"startOffset":612080,"endOffset":612133,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":612189,"endOffset":614795,"count":0}],"isBlockCoverage":false},{"functionName":"get$message","ranges":[{"startOffset":614835,"endOffset":614888,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":614932,"endOffset":615559,"count":0}],"isBlockCoverage":false},{"functionName":"$indexSet","ranges":[{"startOffset":615576,"endOffset":616073,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":616091,"endOffset":616147,"count":0}],"isBlockCoverage":false},{"functionName":"map$1$1","ranges":[{"startOffset":616246,"endOffset":616443,"count":0}],"isBlockCoverage":false},{"functionName":"where$1","ranges":[{"startOffset":616458,"endOffset":616647,"count":1}],"isBlockCoverage":true},{"functionName":"contains$1","ranges":[{"startOffset":616665,"endOffset":616856,"count":0}],"isBlockCoverage":false},{"functionName":"join$1","ranges":[{"startOffset":616870,"endOffset":617364,"count":0}],"isBlockCoverage":false},{"functionName":"join$0","ranges":[{"startOffset":617378,"endOffset":617446,"count":0}],"isBlockCoverage":false},{"functionName":"toList$1$growable","ranges":[{"startOffset":617471,"endOffset":617588,"count":0}],"isBlockCoverage":false},{"functionName":"toList$0","ranges":[{"startOffset":617604,"endOffset":617685,"count":0}],"isBlockCoverage":false},{"functionName":"toSet$0","ranges":[{"startOffset":617700,"endOffset":617819,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":617837,"endOffset":618062,"count":0}],"isBlockCoverage":false},{"functionName":"get$isEmpty","ranges":[{"startOffset":618081,"endOffset":618152,"count":0}],"isBlockCoverage":false},{"functionName":"skipWhile$1","ranges":[{"startOffset":618171,"endOffset":618368,"count":0}],"isBlockCoverage":false},{"functionName":"get$first","ranges":[{"startOffset":618385,"endOffset":618570,"count":0}],"isBlockCoverage":false},{"functionName":"get$last","ranges":[{"startOffset":618586,"endOffset":618852,"count":0}],"isBlockCoverage":false},{"functionName":"elementAt$1","ranges":[{"startOffset":618871,"endOffset":619282,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":619300,"endOffset":619386,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":619558,"endOffset":619650,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":619697,"endOffset":619779,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":619797,"endOffset":619837,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":619937,"endOffset":619992,"count":1}],"isBlockCoverage":true},{"functionName":"get$hashCode","ranges":[{"startOffset":620012,"endOffset":620079,"count":1}],"isBlockCoverage":true},{"functionName":"toString$0","ranges":[{"startOffset":620097,"endOffset":620193,"count":0}],"isBlockCoverage":false},{"functionName":"get$runtimeType","ranges":[{"startOffset":620216,"endOffset":620272,"count":0}],"isBlockCoverage":false},{"functionName":"toString","ranges":[{"startOffset":620288,"endOffset":620342,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":620552,"endOffset":620602,"count":0}],"isBlockCoverage":false},{"functionName":"get$elapsedMicroseconds","ranges":[{"startOffset":620687,"endOffset":621099,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":621187,"endOffset":621252,"count":0}],"isBlockCoverage":false},{"functionName":"get$last","ranges":[{"startOffset":621268,"endOffset":621758,"count":0}],"isBlockCoverage":false},{"functionName":"get$current","ranges":[{"startOffset":621812,"endOffset":621867,"count":0}],"isBlockCoverage":false},{"functionName":"moveNext$0","ranges":[{"startOffset":621885,"endOffset":622720,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":622793,"endOffset":622848,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":622866,"endOffset":622962,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":623072,"endOffset":623205,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":623288,"endOffset":623421,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":623435,"endOffset":623493,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":623579,"endOffset":624044,"count":0}],"isBlockCoverage":false},{"functionName":"get$userInfo","ranges":[{"startOffset":624111,"endOffset":624158,"count":0}],"isBlockCoverage":false},{"functionName":"get$host","ranges":[{"startOffset":624174,"endOffset":624399,"count":0}],"isBlockCoverage":false},{"functionName":"get$port","ranges":[{"startOffset":624415,"endOffset":624549,"count":0}],"isBlockCoverage":false},{"functionName":"get$query","ranges":[{"startOffset":624566,"endOffset":624647,"count":0}],"isBlockCoverage":false},{"functionName":"get$fragment","ranges":[{"startOffset":624667,"endOffset":624751,"count":0}],"isBlockCoverage":false},{"functionName":"replace$2$path$pathSegments","ranges":[{"startOffset":624786,"endOffset":625788,"count":0}],"isBlockCoverage":false},{"functionName":"replace$1$path","ranges":[{"startOffset":625810,"endOffset":625913,"count":0}],"isBlockCoverage":false},{"functionName":"replace$1$pathSegments","ranges":[{"startOffset":625943,"endOffset":626062,"count":0}],"isBlockCoverage":false},{"functionName":"get$pathSegments","ranges":[{"startOffset":626086,"endOffset":626770,"count":0}],"isBlockCoverage":false},{"functionName":"_mergePaths$2","ranges":[{"startOffset":626791,"endOffset":627849,"count":0}],"isBlockCoverage":false},{"functionName":"resolve$1","ranges":[{"startOffset":627866,"endOffset":627949,"count":0}],"isBlockCoverage":false},{"functionName":"resolveUri$1","ranges":[{"startOffset":627969,"endOffset":630843,"count":0}],"isBlockCoverage":false},{"functionName":"get$hasAuthority","ranges":[{"startOffset":630867,"endOffset":630918,"count":0}],"isBlockCoverage":false},{"functionName":"get$hasPort","ranges":[{"startOffset":630937,"endOffset":630988,"count":0}],"isBlockCoverage":false},{"functionName":"get$hasQuery","ranges":[{"startOffset":631008,"endOffset":631060,"count":0}],"isBlockCoverage":false},{"functionName":"get$hasFragment","ranges":[{"startOffset":631083,"endOffset":631138,"count":0}],"isBlockCoverage":false},{"functionName":"get$hasAbsolutePath","ranges":[{"startOffset":631165,"endOffset":631245,"count":0}],"isBlockCoverage":false},{"functionName":"toFilePath$0","ranges":[{"startOffset":631265,"endOffset":632530,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":632548,"endOffset":633376,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":633387,"endOffset":634982,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":635002,"endOffset":635163,"count":0}],"isBlockCoverage":false},{"functionName":"set$_pathSegments","ranges":[{"startOffset":635188,"endOffset":635287,"count":0}],"isBlockCoverage":false},{"functionName":"get$scheme","ranges":[{"startOffset":635320,"endOffset":635364,"count":0}],"isBlockCoverage":false},{"functionName":"get$path","ranges":[{"startOffset":635380,"endOffset":635430,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":635494,"endOffset":635608,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":635716,"endOffset":636051,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":636130,"endOffset":636243,"count":0}],"isBlockCoverage":false},{"functionName":"get$uri","ranges":[{"startOffset":636307,"endOffset":637019,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":637037,"endOffset":637234,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":637292,"endOffset":637344,"count":1}],"isBlockCoverage":true},{"functionName":"call$2","ranges":[{"startOffset":637420,"endOffset":637648,"count":1},{"startOffset":637523,"endOffset":637549,"count":0}],"isBlockCoverage":true},{"functionName":"call$3","ranges":[{"startOffset":637727,"endOffset":638030,"count":1},{"startOffset":637956,"endOffset":637983,"count":0}],"isBlockCoverage":true},{"functionName":"call$3","ranges":[{"startOffset":638109,"endOffset":638448,"count":1},{"startOffset":638374,"endOffset":638401,"count":0}],"isBlockCoverage":true},{"functionName":"get$hasAuthority","ranges":[{"startOffset":638525,"endOffset":638577,"count":0}],"isBlockCoverage":false},{"functionName":"get$hasPort","ranges":[{"startOffset":638596,"endOffset":638689,"count":0}],"isBlockCoverage":false},{"functionName":"get$hasQuery","ranges":[{"startOffset":638709,"endOffset":638780,"count":0}],"isBlockCoverage":false},{"functionName":"get$hasFragment","ranges":[{"startOffset":638803,"endOffset":638874,"count":0}],"isBlockCoverage":false},{"functionName":"get$_isFile","ranges":[{"startOffset":638893,"endOffset":639001,"count":0}],"isBlockCoverage":false},{"functionName":"get$_isHttp","ranges":[{"startOffset":639020,"endOffset":639128,"count":0}],"isBlockCoverage":false},{"functionName":"get$_isHttps","ranges":[{"startOffset":639148,"endOffset":639257,"count":0}],"isBlockCoverage":false},{"functionName":"get$hasAbsolutePath","ranges":[{"startOffset":639284,"endOffset":639381,"count":0}],"isBlockCoverage":false},{"functionName":"get$scheme","ranges":[{"startOffset":639399,"endOffset":640155,"count":0}],"isBlockCoverage":false},{"functionName":"get$userInfo","ranges":[{"startOffset":640175,"endOffset":640342,"count":0}],"isBlockCoverage":false},{"functionName":"get$host","ranges":[{"startOffset":640358,"endOffset":640500,"count":0}],"isBlockCoverage":false},{"functionName":"get$port","ranges":[{"startOffset":640516,"endOffset":640832,"count":0}],"isBlockCoverage":false},{"functionName":"get$path","ranges":[{"startOffset":640848,"endOffset":640958,"count":0}],"isBlockCoverage":false},{"functionName":"get$query","ranges":[{"startOffset":640975,"endOffset":641143,"count":0}],"isBlockCoverage":false},{"functionName":"get$fragment","ranges":[{"startOffset":641163,"endOffset":641320,"count":0}],"isBlockCoverage":false},{"functionName":"get$pathSegments","ranges":[{"startOffset":641344,"endOffset":642029,"count":1},{"startOffset":641575,"endOffset":641595,"count":0}],"isBlockCoverage":true},{"functionName":"_isPort$1","ranges":[{"startOffset":642046,"endOffset":642247,"count":0}],"isBlockCoverage":false},{"functionName":"removeFragment$0","ranges":[{"startOffset":642271,"endOffset":642611,"count":0}],"isBlockCoverage":false},{"functionName":"replace$2$path$pathSegments","ranges":[{"startOffset":642646,"endOffset":644260,"count":0}],"isBlockCoverage":false},{"functionName":"replace$1$path","ranges":[{"startOffset":644282,"endOffset":644385,"count":0}],"isBlockCoverage":false},{"functionName":"replace$1$pathSegments","ranges":[{"startOffset":644415,"endOffset":644534,"count":0}],"isBlockCoverage":false},{"functionName":"resolve$1","ranges":[{"startOffset":644551,"endOffset":644634,"count":0}],"isBlockCoverage":false},{"functionName":"resolveUri$1","ranges":[{"startOffset":644654,"endOffset":644839,"count":0}],"isBlockCoverage":false},{"functionName":"_simpleMerge$2","ranges":[{"startOffset":644861,"endOffset":648814,"count":0}],"isBlockCoverage":false},{"functionName":"toFilePath$0","ranges":[{"startOffset":648834,"endOffset":649861,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":649881,"endOffset":650033,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":650044,"endOffset":650236,"count":0}],"isBlockCoverage":false},{"functionName":"_toNonSimple$0","ranges":[{"startOffset":650258,"endOffset":650822,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":650840,"endOffset":650883,"count":0}],"isBlockCoverage":false},{"functionName":"get$message","ranges":[{"startOffset":650995,"endOffset":651052,"count":0}],"isBlockCoverage":false},{"functionName":"get$message","ranges":[{"startOffset":651137,"endOffset":651194,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":651247,"endOffset":651304,"count":0}],"isBlockCoverage":false},{"functionName":"get$message","ranges":[{"startOffset":651323,"endOffset":651380,"count":0}],"isBlockCoverage":false},{"functionName":"get$message","ranges":[{"startOffset":651432,"endOffset":651489,"count":0}],"isBlockCoverage":false},{"functionName":"addEventListener$3","ranges":[{"startOffset":651586,"endOffset":651788,"count":1}],"isBlockCoverage":true},{"functionName":"_addEventListener$3","ranges":[{"startOffset":651815,"endOffset":651995,"count":1}],"isBlockCoverage":true},{"functionName":"_removeEventListener$3","ranges":[{"startOffset":652025,"endOffset":652208,"count":1}],"isBlockCoverage":true},{"functionName":"get$origin","ranges":[{"startOffset":652315,"endOffset":652470,"count":1},{"startOffset":652399,"endOffset":652469,"count":0}],"isBlockCoverage":true},{"functionName":"toString$0","ranges":[{"startOffset":652488,"endOffset":652545,"count":0}],"isBlockCoverage":false},{"functionName":"get$message","ranges":[{"startOffset":652597,"endOffset":652654,"count":0}],"isBlockCoverage":false},{"functionName":"get$message","ranges":[{"startOffset":652716,"endOffset":652773,"count":0}],"isBlockCoverage":false},{"functionName":"addEventListener$3","ranges":[{"startOffset":652884,"endOffset":653127,"count":1}],"isBlockCoverage":true},{"functionName":"postMessage$1","ranges":[{"startOffset":653148,"endOffset":653318,"count":1}],"isBlockCoverage":true},{"functionName":"get$message","ranges":[{"startOffset":653406,"endOffset":653463,"count":0}],"isBlockCoverage":false},{"functionName":"get$message","ranges":[{"startOffset":653525,"endOffset":653582,"count":0}],"isBlockCoverage":false},{"functionName":"get$message","ranges":[{"startOffset":653637,"endOffset":653694,"count":0}],"isBlockCoverage":false},{"functionName":"get$message","ranges":[{"startOffset":653768,"endOffset":653825,"count":0}],"isBlockCoverage":false},{"functionName":"get$message","ranges":[{"startOffset":653889,"endOffset":653946,"count":0}],"isBlockCoverage":false},{"functionName":"get$isBroadcast","ranges":[{"startOffset":654044,"endOffset":654081,"count":0}],"isBlockCoverage":false},{"functionName":"listen$4$cancelOnError$onDone$onError","ranges":[{"startOffset":654126,"endOffset":654445,"count":1}],"isBlockCoverage":true},{"functionName":"listen$3$onDone$onError","ranges":[{"startOffset":654476,"endOffset":654605,"count":0}],"isBlockCoverage":false},{"functionName":"listen$1","ranges":[{"startOffset":654621,"endOffset":654728,"count":0}],"isBlockCoverage":false},{"functionName":"cancel$0","ranges":[{"startOffset":654791,"endOffset":655010,"count":1},{"startOffset":654875,"endOffset":654887,"count":0}],"isBlockCoverage":true},{"functionName":"pause$1","ranges":[{"startOffset":655025,"endOffset":655161,"count":0}],"isBlockCoverage":false},{"functionName":"pause$0","ranges":[{"startOffset":655176,"endOffset":655227,"count":0}],"isBlockCoverage":false},{"functionName":"resume$0","ranges":[{"startOffset":655243,"endOffset":655421,"count":0}],"isBlockCoverage":false},{"functionName":"_tryResume$0","ranges":[{"startOffset":655441,"endOffset":655647,"count":1}],"isBlockCoverage":true},{"functionName":"_unlisten$0","ranges":[{"startOffset":655666,"endOffset":655969,"count":1}],"isBlockCoverage":true},{"functionName":"set$_html$_onData","ranges":[{"startOffset":655994,"endOffset":656092,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":656161,"endOffset":656236,"count":1}],"isBlockCoverage":true},{"functionName":"findSlot$1","ranges":[{"startOffset":656313,"endOffset":656603,"count":1},{"startOffset":656474,"endOffset":656483,"count":0}],"isBlockCoverage":true},{"functionName":"walk$1","ranges":[{"startOffset":656617,"endOffset":658566,"count":1},{"startOffset":656751,"endOffset":656760,"count":0},{"startOffset":656904,"endOffset":656930,"count":0},{"startOffset":656970,"endOffset":657045,"count":0},{"startOffset":657083,"endOffset":657092,"count":0},{"startOffset":657130,"endOffset":657139,"count":0},{"startOffset":657249,"endOffset":657258,"count":0},{"startOffset":657409,"endOffset":657434,"count":0},{"startOffset":657506,"endOffset":657518,"count":0},{"startOffset":657862,"endOffset":657887,"count":0},{"startOffset":657949,"endOffset":657961,"count":0},{"startOffset":658011,"endOffset":658565,"count":0}],"isBlockCoverage":true},{"functionName":"copyList$2","ranges":[{"startOffset":658584,"endOffset":658922,"count":1}],"isBlockCoverage":true},{"functionName":"call$2","ranges":[{"startOffset":658988,"endOffset":659072,"count":1}],"isBlockCoverage":true},{"functionName":"call$2","ranges":[{"startOffset":659158,"endOffset":659242,"count":0}],"isBlockCoverage":false},{"functionName":"findSlot$1","ranges":[{"startOffset":659324,"endOffset":659614,"count":1},{"startOffset":659485,"endOffset":659494,"count":0}],"isBlockCoverage":true},{"functionName":"walk$1","ranges":[{"startOffset":659628,"endOffset":661744,"count":1},{"startOffset":659949,"endOffset":660278,"count":0},{"startOffset":660318,"endOffset":660393,"count":0},{"startOffset":660467,"endOffset":660510,"count":0},{"startOffset":660713,"endOffset":660738,"count":0},{"startOffset":660814,"endOffset":660826,"count":0},{"startOffset":661277,"endOffset":661302,"count":0},{"startOffset":661364,"endOffset":661376,"count":0},{"startOffset":661502,"endOffset":661505,"count":0},{"startOffset":661722,"endOffset":661743,"count":0}],"isBlockCoverage":true},{"functionName":"convertNativeToDart_AcceptStructuredClone$2$mustCopy","ranges":[{"startOffset":661804,"endOffset":661900,"count":1}],"isBlockCoverage":true},{"functionName":"call$2","ranges":[{"startOffset":661972,"endOffset":662124,"count":1}],"isBlockCoverage":true},{"functionName":"forEachObjectKey$2","ranges":[{"startOffset":662216,"endOffset":662485,"count":0}],"isBlockCoverage":false},{"functionName":"forEachJsField$2","ranges":[{"startOffset":662561,"endOffset":662902,"count":1},{"startOffset":662770,"endOffset":662816,"count":0}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":662964,"endOffset":663725,"count":1},{"startOffset":663098,"endOffset":663121,"count":0},{"startOffset":663497,"endOffset":663696,"count":0}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":663805,"endOffset":663896,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":663977,"endOffset":664044,"count":0}],"isBlockCoverage":false},{"functionName":"get$message","ranges":[{"startOffset":664969,"endOffset":665026,"count":0}],"isBlockCoverage":false},{"functionName":"runOnce$1","ranges":[{"startOffset":665079,"endOffset":665381,"count":0}],"isBlockCoverage":false},{"functionName":"onData$1","ranges":[{"startOffset":665493,"endOffset":665616,"count":0}],"isBlockCoverage":false},{"functionName":"onError$1","ranges":[{"startOffset":665633,"endOffset":665732,"count":0}],"isBlockCoverage":false},{"functionName":"onDone$1","ranges":[{"startOffset":665748,"endOffset":665866,"count":0}],"isBlockCoverage":false},{"functionName":"pause$1","ranges":[{"startOffset":665881,"endOffset":665974,"count":0}],"isBlockCoverage":false},{"functionName":"pause$0","ranges":[{"startOffset":665989,"endOffset":666040,"count":0}],"isBlockCoverage":false},{"functionName":"resume$0","ranges":[{"startOffset":666056,"endOffset":666126,"count":0}],"isBlockCoverage":false},{"functionName":"cancel$0","ranges":[{"startOffset":666142,"endOffset":666219,"count":0}],"isBlockCoverage":false},{"functionName":"add$1","ranges":[{"startOffset":666296,"endOffset":666782,"count":0}],"isBlockCoverage":false},{"functionName":"close$0","ranges":[{"startOffset":666797,"endOffset":667077,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":667153,"endOffset":667619,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":667637,"endOffset":667703,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":667764,"endOffset":667976,"count":0}],"isBlockCoverage":false},{"functionName":"add$1","ranges":[{"startOffset":668045,"endOffset":668148,"count":0}],"isBlockCoverage":false},{"functionName":"addStream$1","ranges":[{"startOffset":668167,"endOffset":668625,"count":0}],"isBlockCoverage":false},{"functionName":"_checkEventAllowed$0","ranges":[{"startOffset":668653,"endOffset":668914,"count":0}],"isBlockCoverage":false},{"functionName":"close$0","ranges":[{"startOffset":668929,"endOffset":669017,"count":0}],"isBlockCoverage":false},{"functionName":"get$done","ranges":[{"startOffset":669118,"endOffset":669160,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":669229,"endOffset":669287,"count":0}],"isBlockCoverage":false},{"functionName":"complete$1","ranges":[{"startOffset":669358,"endOffset":669447,"count":0}],"isBlockCoverage":false},{"functionName":"addTo$1","ranges":[{"startOffset":669462,"endOffset":669536,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":669556,"endOffset":669672,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":669683,"endOffset":669875,"count":0}],"isBlockCoverage":false},{"functionName":"complete$1","ranges":[{"startOffset":669972,"endOffset":670080,"count":1}],"isBlockCoverage":true},{"functionName":"addTo$1","ranges":[{"startOffset":670095,"endOffset":670191,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":670211,"endOffset":670292,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":670303,"endOffset":670456,"count":0}],"isBlockCoverage":false},{"functionName":"setSourceStream$1","ranges":[{"startOffset":670537,"endOffset":670945,"count":1},{"startOffset":670703,"endOffset":670769,"count":0}],"isBlockCoverage":true},{"functionName":"listen$4$cancelOnError$onDone$onError","ranges":[{"startOffset":671029,"endOffset":671873,"count":1},{"startOffset":671585,"endOffset":671619,"count":0}],"isBlockCoverage":true},{"functionName":"listen$3$onDone$onError","ranges":[{"startOffset":671904,"endOffset":672033,"count":0}],"isBlockCoverage":false},{"functionName":"listen$1","ranges":[{"startOffset":672049,"endOffset":672156,"count":1}],"isBlockCoverage":true},{"functionName":"_linkStreamToController$0","ranges":[{"startOffset":672189,"endOffset":672550,"count":1}],"isBlockCoverage":true},{"functionName":"_createController$0","ranges":[{"startOffset":672577,"endOffset":672786,"count":1}],"isBlockCoverage":true},{"functionName":"set$_stream_completer$_controller","ranges":[{"startOffset":672827,"endOffset":672960,"count":1}],"isBlockCoverage":true},{"functionName":"set$_sourceStream","ranges":[{"startOffset":672985,"endOffset":673096,"count":1}],"isBlockCoverage":true},{"functionName":"add$1","ranges":[{"startOffset":673143,"endOffset":673811,"count":0}],"isBlockCoverage":false},{"functionName":"_onListen$0","ranges":[{"startOffset":673830,"endOffset":674010,"count":0}],"isBlockCoverage":false},{"functionName":"_onCancelBroadcast$0","ranges":[{"startOffset":674038,"endOffset":674225,"count":0}],"isBlockCoverage":false},{"functionName":"_listenToStream$1","ranges":[{"startOffset":674250,"endOffset":674687,"count":0}],"isBlockCoverage":false},{"functionName":"close$0","ranges":[{"startOffset":674702,"endOffset":675097,"count":0}],"isBlockCoverage":false},{"functionName":"set$_stream_group$_controller","ranges":[{"startOffset":675134,"endOffset":675263,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":675339,"endOffset":675376,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":675456,"endOffset":675530,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":675548,"endOffset":675630,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":675696,"endOffset":676010,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":676028,"endOffset":676124,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":676199,"endOffset":676545,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":676563,"endOffset":676659,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":676731,"endOffset":677110,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":677188,"endOffset":677231,"count":0}],"isBlockCoverage":false},{"functionName":"get$next","ranges":[{"startOffset":677281,"endOffset":677676,"count":1},{"startOffset":677618,"endOffset":677675,"count":0}],"isBlockCoverage":true},{"functionName":"_updateRequests$0","ranges":[{"startOffset":677701,"endOffset":678244,"count":1},{"startOffset":677901,"endOffset":677955,"count":0},{"startOffset":678019,"endOffset":678042,"count":0},{"startOffset":678120,"endOffset":678151,"count":0}],"isBlockCoverage":true},{"functionName":"_extractStream$0","ranges":[{"startOffset":678268,"endOffset":678938,"count":1},{"startOffset":678406,"endOffset":678470,"count":0},{"startOffset":678575,"endOffset":678610,"count":0}],"isBlockCoverage":true},{"functionName":"_ensureListening$0","ranges":[{"startOffset":678964,"endOffset":679408,"count":1},{"startOffset":679038,"endOffset":679045,"count":0},{"startOffset":679368,"endOffset":679402,"count":0}],"isBlockCoverage":true},{"functionName":"_addResult$1","ranges":[{"startOffset":679428,"endOffset":679693,"count":1}],"isBlockCoverage":true},{"functionName":"_failClosed$0","ranges":[{"startOffset":679714,"endOffset":679784,"count":0}],"isBlockCoverage":false},{"functionName":"_addRequest$1","ranges":[{"startOffset":679805,"endOffset":680179,"count":1}],"isBlockCoverage":true},{"functionName":"set$_stream_queue$_subscription","ranges":[{"startOffset":680218,"endOffset":680355,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":680428,"endOffset":680601,"count":1}],"isBlockCoverage":true},{"functionName":"$signature","ranges":[{"startOffset":680619,"endOffset":680685,"count":1}],"isBlockCoverage":true},{"functionName":"call$2","ranges":[{"startOffset":680759,"endOffset":680888,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":680981,"endOffset":681129,"count":0}],"isBlockCoverage":false},{"functionName":"update$2","ranges":[{"startOffset":681233,"endOffset":681629,"count":1},{"startOffset":681475,"endOffset":681603,"count":0}],"isBlockCoverage":true},{"functionName":"update$2","ranges":[{"startOffset":681705,"endOffset":683204,"count":1},{"startOffset":681986,"endOffset":682524,"count":0},{"startOffset":682592,"endOffset":683179,"count":0}],"isBlockCoverage":true},{"functionName":"get$_canSendDirectly","ranges":[{"startOffset":683334,"endOffset":683447,"count":0}],"isBlockCoverage":false},{"functionName":"get$done","ranges":[{"startOffset":683463,"endOffset":683878,"count":0}],"isBlockCoverage":false},{"functionName":"addStream$1","ranges":[{"startOffset":683897,"endOffset":684228,"count":0}],"isBlockCoverage":false},{"functionName":"close$0","ranges":[{"startOffset":684243,"endOffset":684519,"count":0}],"isBlockCoverage":false},{"functionName":"_ensureController$0","ranges":[{"startOffset":684546,"endOffset":684755,"count":0}],"isBlockCoverage":false},{"functionName":"_setDestinationSink$1","ranges":[{"startOffset":684784,"endOffset":685386,"count":1},{"startOffset":685061,"endOffset":685262,"count":0},{"startOffset":685349,"endOffset":685380,"count":0}],"isBlockCoverage":true},{"functionName":"set$_stream_sink_completer$_controller","ranges":[{"startOffset":685432,"endOffset":685570,"count":0}],"isBlockCoverage":false},{"functionName":"set$_destinationSink","ranges":[{"startOffset":685598,"endOffset":685722,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":685886,"endOffset":685905,"count":0}],"isBlockCoverage":false},{"functionName":"listen$4$cancelOnError$onDone$onError","ranges":[{"startOffset":686010,"endOffset":686754,"count":1},{"startOffset":686321,"endOffset":686398,"count":0},{"startOffset":686489,"endOffset":686590,"count":0}],"isBlockCoverage":true},{"functionName":"listen$3$onDone$onError","ranges":[{"startOffset":686785,"endOffset":686914,"count":0}],"isBlockCoverage":false},{"functionName":"listen$1","ranges":[{"startOffset":686930,"endOffset":687037,"count":0}],"isBlockCoverage":false},{"functionName":"set$_subscription_stream$_source","ranges":[{"startOffset":687077,"endOffset":687203,"count":1}],"isBlockCoverage":true},{"functionName":"onError$1","ranges":[{"startOffset":687276,"endOffset":687442,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":687528,"endOffset":688068,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":688174,"endOffset":688382,"count":0}],"isBlockCoverage":false},{"functionName":"evaluate$1","ranges":[{"startOffset":688481,"endOffset":688527,"count":1}],"isBlockCoverage":true},{"functionName":"intersection$1","ranges":[{"startOffset":688549,"endOffset":688592,"count":0}],"isBlockCoverage":false},{"functionName":"validate$1","ranges":[{"startOffset":688610,"endOffset":688689,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":688707,"endOffset":688748,"count":0}],"isBlockCoverage":false},{"functionName":"accept$1","ranges":[{"startOffset":688826,"endOffset":688895,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":688913,"endOffset":688956,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":688967,"endOffset":689113,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":689133,"endOffset":689193,"count":0}],"isBlockCoverage":false},{"functionName":"get$span","ranges":[{"startOffset":689225,"endOffset":689267,"count":0}],"isBlockCoverage":false},{"functionName":"accept$1","ranges":[{"startOffset":689313,"endOffset":689377,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":689395,"endOffset":689568,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":689579,"endOffset":689727,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":689747,"endOffset":689834,"count":0}],"isBlockCoverage":false},{"functionName":"get$span","ranges":[{"startOffset":689866,"endOffset":689908,"count":0}],"isBlockCoverage":false},{"functionName":"get$span","ranges":[{"startOffset":689953,"endOffset":690044,"count":0}],"isBlockCoverage":false},{"functionName":"accept$1","ranges":[{"startOffset":690060,"endOffset":690123,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":690141,"endOffset":690553,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":690564,"endOffset":690743,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":690763,"endOffset":690897,"count":0}],"isBlockCoverage":false},{"functionName":"get$span","ranges":[{"startOffset":690959,"endOffset":691050,"count":0}],"isBlockCoverage":false},{"functionName":"accept$1","ranges":[{"startOffset":691066,"endOffset":691130,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":691148,"endOffset":691558,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":691569,"endOffset":691749,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":691769,"endOffset":691903,"count":0}],"isBlockCoverage":false},{"functionName":"get$span","ranges":[{"startOffset":691973,"endOffset":692073,"count":0}],"isBlockCoverage":false},{"functionName":"accept$1","ranges":[{"startOffset":692089,"endOffset":692161,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":692179,"endOffset":692631,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":692642,"endOffset":692888,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":692908,"endOffset":693101,"count":0}],"isBlockCoverage":false},{"functionName":"visitVariable$1","ranges":[{"startOffset":693172,"endOffset":693242,"count":0}],"isBlockCoverage":false},{"functionName":"visitNot$1","ranges":[{"startOffset":693260,"endOffset":693346,"count":0}],"isBlockCoverage":false},{"functionName":"visitOr$1","ranges":[{"startOffset":693363,"endOffset":693499,"count":0}],"isBlockCoverage":false},{"functionName":"visitAnd$1","ranges":[{"startOffset":693517,"endOffset":693653,"count":0}],"isBlockCoverage":false},{"functionName":"visitConditional$1","ranges":[{"startOffset":693679,"endOffset":693831,"count":0}],"isBlockCoverage":false},{"functionName":"evaluate$1","ranges":[{"startOffset":693910,"endOffset":694228,"count":0}],"isBlockCoverage":false},{"functionName":"intersection$1","ranges":[{"startOffset":694250,"endOffset":694597,"count":0}],"isBlockCoverage":false},{"functionName":"validate$1","ranges":[{"startOffset":694615,"endOffset":694736,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":694754,"endOffset":694816,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":694827,"endOffset":694995,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":695015,"endOffset":695099,"count":0}],"isBlockCoverage":false},{"functionName":"evaluate$1","ranges":[{"startOffset":695187,"endOffset":695353,"count":0}],"isBlockCoverage":false},{"functionName":"intersection$1","ranges":[{"startOffset":695375,"endOffset":695452,"count":0}],"isBlockCoverage":false},{"functionName":"validate$1","ranges":[{"startOffset":695470,"endOffset":695639,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":695657,"endOffset":695766,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":695777,"endOffset":695993,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":696013,"endOffset":696141,"count":0}],"isBlockCoverage":false},{"functionName":"evaluate$1","ranges":[{"startOffset":696213,"endOffset":696260,"count":0}],"isBlockCoverage":false},{"functionName":"intersection$1","ranges":[{"startOffset":696282,"endOffset":696324,"count":0}],"isBlockCoverage":false},{"functionName":"validate$1","ranges":[{"startOffset":696342,"endOffset":696421,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":696439,"endOffset":696481,"count":0}],"isBlockCoverage":false},{"functionName":"parse$0","ranges":[{"startOffset":696552,"endOffset":696864,"count":0}],"isBlockCoverage":false},{"functionName":"_conditional$0","ranges":[{"startOffset":696886,"endOffset":697347,"count":0}],"isBlockCoverage":false},{"functionName":"_or$0","ranges":[{"startOffset":697360,"endOffset":697536,"count":0}],"isBlockCoverage":false},{"functionName":"_and$0","ranges":[{"startOffset":697550,"endOffset":697742,"count":0}],"isBlockCoverage":false},{"functionName":"_simpleExpression$0","ranges":[{"startOffset":697769,"endOffset":698600,"count":0}],"isBlockCoverage":false},{"functionName":"peek$0","ranges":[{"startOffset":698644,"endOffset":698770,"count":0}],"isBlockCoverage":false},{"functionName":"next$0","ranges":[{"startOffset":698784,"endOffset":699055,"count":0}],"isBlockCoverage":false},{"functionName":"scan$1","ranges":[{"startOffset":699069,"endOffset":699219,"count":0}],"isBlockCoverage":false},{"functionName":"_getNext$0","ranges":[{"startOffset":699237,"endOffset":700677,"count":0}],"isBlockCoverage":false},{"functionName":"_scanOperator$1","ranges":[{"startOffset":700700,"endOffset":701057,"count":0}],"isBlockCoverage":false},{"functionName":"_consumeWhitespace$0","ranges":[{"startOffset":701085,"endOffset":701439,"count":0}],"isBlockCoverage":false},{"functionName":"_multiLineComment$0","ranges":[{"startOffset":701466,"endOffset":701903,"count":0}],"isBlockCoverage":false},{"functionName":"get$type","ranges":[{"startOffset":701947,"endOffset":701997,"count":0}],"isBlockCoverage":false},{"functionName":"get$span","ranges":[{"startOffset":702013,"endOffset":702055,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":702111,"endOffset":702182,"count":0}],"isBlockCoverage":false},{"functionName":"get$type","ranges":[{"startOffset":702215,"endOffset":702270,"count":0}],"isBlockCoverage":false},{"functionName":"get$span","ranges":[{"startOffset":702286,"endOffset":702328,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":702378,"endOffset":702421,"count":0}],"isBlockCoverage":false},{"functionName":"visitVariable$1","ranges":[{"startOffset":702476,"endOffset":702681,"count":0}],"isBlockCoverage":false},{"functionName":"visitNot$1","ranges":[{"startOffset":702738,"endOffset":702793,"count":0}],"isBlockCoverage":false},{"functionName":"visitOr$1","ranges":[{"startOffset":702810,"endOffset":702897,"count":0}],"isBlockCoverage":false},{"functionName":"visitAnd$1","ranges":[{"startOffset":702915,"endOffset":703002,"count":0}],"isBlockCoverage":false},{"functionName":"visitConditional$1","ranges":[{"startOffset":703028,"endOffset":703160,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":703242,"endOffset":703293,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":703311,"endOffset":703346,"count":0}],"isBlockCoverage":false},{"functionName":"contains$1","ranges":[{"startOffset":703364,"endOffset":703412,"count":0}],"isBlockCoverage":false},{"functionName":"toSet$0","ranges":[{"startOffset":703427,"endOffset":703514,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":703615,"endOffset":703731,"count":1}],"isBlockCoverage":true},{"functionName":"$signature","ranges":[{"startOffset":703749,"endOffset":703857,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":703909,"endOffset":704161,"count":1}],"isBlockCoverage":true},{"functionName":"$signature","ranges":[{"startOffset":704179,"endOffset":704273,"count":1}],"isBlockCoverage":true},{"functionName":"call$2","ranges":[{"startOffset":704327,"endOffset":704582,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":704600,"endOffset":704692,"count":1}],"isBlockCoverage":true},{"functionName":"toString$0","ranges":[{"startOffset":704742,"endOffset":704827,"count":0}],"isBlockCoverage":false},{"functionName":"removeFirst$0","ranges":[{"startOffset":704848,"endOffset":705338,"count":1},{"startOffset":704985,"endOffset":705036,"count":0},{"startOffset":705109,"endOffset":705132,"count":0}],"isBlockCoverage":true},{"functionName":"get$length","ranges":[{"startOffset":705356,"endOffset":705482,"count":1}],"isBlockCoverage":true},{"functionName":"set$length","ranges":[{"startOffset":705500,"endOffset":706426,"count":0}],"isBlockCoverage":false},{"functionName":"$index","ranges":[{"startOffset":706440,"endOffset":706924,"count":0}],"isBlockCoverage":false},{"functionName":"$indexSet","ranges":[{"startOffset":706941,"endOffset":707471,"count":0}],"isBlockCoverage":false},{"functionName":"_queue_list$_add$1","ranges":[{"startOffset":707497,"endOffset":708514,"count":1},{"startOffset":707919,"endOffset":708508,"count":0}],"isBlockCoverage":true},{"functionName":"_writeToList$1","ranges":[{"startOffset":708536,"endOffset":709305,"count":0}],"isBlockCoverage":false},{"functionName":"_preGrow$1","ranges":[{"startOffset":709323,"endOffset":709960,"count":0}],"isBlockCoverage":false},{"functionName":"set$_queue_list$_table","ranges":[{"startOffset":709990,"endOffset":710090,"count":1}],"isBlockCoverage":true},{"functionName":"get$length","ranges":[{"startOffset":710275,"endOffset":710401,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":710421,"endOffset":710522,"count":0}],"isBlockCoverage":false},{"functionName":"get$_union_set$_iterable","ranges":[{"startOffset":710554,"endOffset":710878,"count":0}],"isBlockCoverage":false},{"functionName":"toSet$0","ranges":[{"startOffset":710893,"endOffset":711220,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":711280,"endOffset":711601,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":711619,"endOffset":711693,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":711756,"endOffset":711836,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":711854,"endOffset":711927,"count":0}],"isBlockCoverage":false},{"functionName":"set$_union_set_controller$_set","ranges":[{"startOffset":712065,"endOffset":712173,"count":0}],"isBlockCoverage":false},{"functionName":"contains$1","ranges":[{"startOffset":712394,"endOffset":712470,"count":0}],"isBlockCoverage":false},{"functionName":"every$1","ranges":[{"startOffset":712485,"endOffset":712601,"count":0}],"isBlockCoverage":false},{"functionName":"get$first","ranges":[{"startOffset":712618,"endOffset":712695,"count":0}],"isBlockCoverage":false},{"functionName":"get$isEmpty","ranges":[{"startOffset":712714,"endOffset":712793,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":712813,"endOffset":712893,"count":0}],"isBlockCoverage":false},{"functionName":"get$last","ranges":[{"startOffset":712909,"endOffset":712985,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":713003,"endOffset":713081,"count":0}],"isBlockCoverage":false},{"functionName":"map$1$1","ranges":[{"startOffset":713096,"endOffset":713223,"count":0}],"isBlockCoverage":false},{"functionName":"toList$1$growable","ranges":[{"startOffset":713248,"endOffset":713329,"count":1}],"isBlockCoverage":true},{"functionName":"toList$0","ranges":[{"startOffset":713345,"endOffset":713426,"count":1}],"isBlockCoverage":true},{"functionName":"toSet$0","ranges":[{"startOffset":713441,"endOffset":713496,"count":0}],"isBlockCoverage":false},{"functionName":"where$1","ranges":[{"startOffset":713511,"endOffset":713627,"count":1}],"isBlockCoverage":true},{"functionName":"toString$0","ranges":[{"startOffset":713645,"endOffset":713703,"count":0}],"isBlockCoverage":false},{"functionName":"union$1","ranges":[{"startOffset":713813,"endOffset":713967,"count":1}],"isBlockCoverage":true},{"functionName":"toSet$0","ranges":[{"startOffset":713982,"endOffset":714157,"count":0}],"isBlockCoverage":false},{"functionName":"matches$2","ranges":[{"startOffset":714254,"endOffset":714324,"count":1}],"isBlockCoverage":true},{"functionName":"describe$1","ranges":[{"startOffset":714342,"endOffset":714441,"count":0}],"isBlockCoverage":false},{"functionName":"typedMatches$2","ranges":[{"startOffset":714496,"endOffset":714602,"count":0}],"isBlockCoverage":false},{"functionName":"describe$1","ranges":[{"startOffset":714620,"endOffset":714745,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":714803,"endOffset":714863,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":714881,"endOffset":714982,"count":0}],"isBlockCoverage":false},{"functionName":"addDescriptionOf$1","ranges":[{"startOffset":715008,"endOffset":715192,"count":0}],"isBlockCoverage":false},{"functionName":"typedMatches$2","ranges":[{"startOffset":715280,"endOffset":715389,"count":0}],"isBlockCoverage":false},{"functionName":"describe$1","ranges":[{"startOffset":715407,"endOffset":715510,"count":0}],"isBlockCoverage":false},{"functionName":"describeTypedMismatch$4","ranges":[{"startOffset":715541,"endOffset":717567,"count":0}],"isBlockCoverage":false},{"functionName":"_compareIterables$5","ranges":[{"startOffset":717629,"endOffset":718839,"count":0}],"isBlockCoverage":false},{"functionName":"_compareSets$5","ranges":[{"startOffset":718861,"endOffset":720203,"count":0}],"isBlockCoverage":false},{"functionName":"_recursiveMatch$4","ranges":[{"startOffset":720228,"endOffset":723384,"count":0}],"isBlockCoverage":false},{"functionName":"_equals_matcher$_match$3","ranges":[{"startOffset":723416,"endOffset":724262,"count":0}],"isBlockCoverage":false},{"functionName":"matches$2","ranges":[{"startOffset":724279,"endOffset":724402,"count":0}],"isBlockCoverage":false},{"functionName":"describe$1","ranges":[{"startOffset":724420,"endOffset":724510,"count":0}],"isBlockCoverage":false},{"functionName":"describeMismatch$4","ranges":[{"startOffset":724536,"endOffset":725070,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":725140,"endOffset":725305,"count":0}],"isBlockCoverage":false},{"functionName":"matches$2","ranges":[{"startOffset":725378,"endOffset":725603,"count":0}],"isBlockCoverage":false},{"functionName":"describeMismatch$4","ranges":[{"startOffset":725629,"endOffset":725977,"count":0}],"isBlockCoverage":false},{"functionName":"describeTypedMismatch$4","ranges":[{"startOffset":726008,"endOffset":726176,"count":0}],"isBlockCoverage":false},{"functionName":"describeMismatch$4","ranges":[{"startOffset":726232,"endOffset":726330,"count":0}],"isBlockCoverage":false},{"functionName":"call$4","ranges":[{"startOffset":726391,"endOffset":730032,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":730116,"endOffset":730227,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":730316,"endOffset":730510,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":730599,"endOffset":730730,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":730820,"endOffset":731014,"count":0}],"isBlockCoverage":false},{"functionName":"describe$1","ranges":[{"startOffset":731085,"endOffset":731450,"count":0}],"isBlockCoverage":false},{"functionName":"matches$2","ranges":[{"startOffset":731467,"endOffset":731575,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":731631,"endOffset":731703,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":731773,"endOffset":731958,"count":0}],"isBlockCoverage":false},{"functionName":"get$packageRoot","ranges":[{"startOffset":732071,"endOffset":732108,"count":0}],"isBlockCoverage":false},{"functionName":"get$packageConfigMap","ranges":[{"startOffset":732136,"endOffset":732190,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":732270,"endOffset":732353,"count":1}],"isBlockCoverage":true},{"functionName":"get$packageConfigMap","ranges":[{"startOffset":732469,"endOffset":732506,"count":0}],"isBlockCoverage":false},{"functionName":"get$packageRoot","ranges":[{"startOffset":732529,"endOffset":732578,"count":0}],"isBlockCoverage":false},{"functionName":"absolute$7","ranges":[{"startOffset":732626,"endOffset":733114,"count":0}],"isBlockCoverage":false},{"functionName":"absolute$1","ranges":[{"startOffset":733132,"endOffset":733250,"count":0}],"isBlockCoverage":false},{"functionName":"join$8","ranges":[{"startOffset":733264,"endOffset":733650,"count":0}],"isBlockCoverage":false},{"functionName":"join$2","ranges":[{"startOffset":733664,"endOffset":733792,"count":0}],"isBlockCoverage":false},{"functionName":"joinAll$1","ranges":[{"startOffset":733809,"endOffset":735362,"count":0}],"isBlockCoverage":false},{"functionName":"split$1","ranges":[{"startOffset":735377,"endOffset":735875,"count":0}],"isBlockCoverage":false},{"functionName":"normalize$1","ranges":[{"startOffset":735894,"endOffset":736127,"count":0}],"isBlockCoverage":false},{"functionName":"_needsNormalization$1","ranges":[{"startOffset":736156,"endOffset":737652,"count":0}],"isBlockCoverage":false},{"functionName":"relative$2$from","ranges":[{"startOffset":737675,"endOffset":741067,"count":0}],"isBlockCoverage":false},{"functionName":"relative$1","ranges":[{"startOffset":741085,"endOffset":741154,"count":0}],"isBlockCoverage":false},{"functionName":"_isWithinOrEquals$2","ranges":[{"startOffset":741181,"endOffset":743129,"count":0}],"isBlockCoverage":false},{"functionName":"_isWithinOrEqualsFast$2","ranges":[{"startOffset":743160,"endOffset":747690,"count":0}],"isBlockCoverage":false},{"functionName":"_pathDirection$2","ranges":[{"startOffset":747714,"endOffset":748939,"count":0}],"isBlockCoverage":false},{"functionName":"toUri$1","ranges":[{"startOffset":748954,"endOffset":749248,"count":0}],"isBlockCoverage":false},{"functionName":"prettyUri$1","ranges":[{"startOffset":749267,"endOffset":749843,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":749900,"endOffset":749973,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":750052,"endOffset":750124,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":750201,"endOffset":750279,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":750359,"endOffset":750468,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":750542,"endOffset":750585,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":750639,"endOffset":750682,"count":0}],"isBlockCoverage":false},{"functionName":"getRoot$1","ranges":[{"startOffset":750735,"endOffset":751064,"count":0}],"isBlockCoverage":false},{"functionName":"relativePathToUri$1","ranges":[{"startOffset":751091,"endOffset":751348,"count":0}],"isBlockCoverage":false},{"functionName":"codeUnitsEqual$2","ranges":[{"startOffset":751372,"endOffset":751448,"count":0}],"isBlockCoverage":false},{"functionName":"pathsEqual$2","ranges":[{"startOffset":751468,"endOffset":751527,"count":0}],"isBlockCoverage":false},{"functionName":"get$hasTrailingSeparator","ranges":[{"startOffset":751592,"endOffset":751829,"count":0}],"isBlockCoverage":false},{"functionName":"removeTrailingSeparators$0","ranges":[{"startOffset":751863,"endOffset":752298,"count":0}],"isBlockCoverage":false},{"functionName":"normalize$0","ranges":[{"startOffset":752317,"endOffset":753935,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":753953,"endOffset":754466,"count":0}],"isBlockCoverage":false},{"functionName":"set$parts","ranges":[{"startOffset":754483,"endOffset":754558,"count":0}],"isBlockCoverage":false},{"functionName":"set$separators","ranges":[{"startOffset":754580,"endOffset":754670,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":754735,"endOffset":754801,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":754875,"endOffset":754941,"count":0}],"isBlockCoverage":false},{"functionName":"get$message","ranges":[{"startOffset":754981,"endOffset":755034,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":755080,"endOffset":755133,"count":0}],"isBlockCoverage":false},{"functionName":"containsSeparator$1","ranges":[{"startOffset":755193,"endOffset":755270,"count":0}],"isBlockCoverage":false},{"functionName":"isSeparator$1","ranges":[{"startOffset":755291,"endOffset":755347,"count":0}],"isBlockCoverage":false},{"functionName":"needsSeparator$1","ranges":[{"startOffset":755371,"endOffset":755500,"count":0}],"isBlockCoverage":false},{"functionName":"rootLength$2$withDrive","ranges":[{"startOffset":755530,"endOffset":755678,"count":0}],"isBlockCoverage":false},{"functionName":"rootLength$1","ranges":[{"startOffset":755698,"endOffset":755775,"count":0}],"isBlockCoverage":false},{"functionName":"isRootRelative$1","ranges":[{"startOffset":755799,"endOffset":755841,"count":0}],"isBlockCoverage":false},{"functionName":"pathFromUri$1","ranges":[{"startOffset":755862,"endOffset":756185,"count":0}],"isBlockCoverage":false},{"functionName":"absolutePathToUri$1","ranges":[{"startOffset":756212,"endOffset":756605,"count":0}],"isBlockCoverage":false},{"functionName":"get$name","ranges":[{"startOffset":756621,"endOffset":756661,"count":0}],"isBlockCoverage":false},{"functionName":"get$separator","ranges":[{"startOffset":756682,"endOffset":756718,"count":0}],"isBlockCoverage":false},{"functionName":"containsSeparator$1","ranges":[{"startOffset":756776,"endOffset":756853,"count":0}],"isBlockCoverage":false},{"functionName":"isSeparator$1","ranges":[{"startOffset":756874,"endOffset":756930,"count":0}],"isBlockCoverage":false},{"functionName":"needsSeparator$1","ranges":[{"startOffset":756954,"endOffset":757222,"count":0}],"isBlockCoverage":false},{"functionName":"rootLength$2$withDrive","ranges":[{"startOffset":757252,"endOffset":758194,"count":0}],"isBlockCoverage":false},{"functionName":"rootLength$1","ranges":[{"startOffset":758214,"endOffset":758291,"count":0}],"isBlockCoverage":false},{"functionName":"isRootRelative$1","ranges":[{"startOffset":758315,"endOffset":758421,"count":0}],"isBlockCoverage":false},{"functionName":"pathFromUri$1","ranges":[{"startOffset":758442,"endOffset":758496,"count":0}],"isBlockCoverage":false},{"functionName":"relativePathToUri$1","ranges":[{"startOffset":758523,"endOffset":758577,"count":0}],"isBlockCoverage":false},{"functionName":"absolutePathToUri$1","ranges":[{"startOffset":758604,"endOffset":758658,"count":0}],"isBlockCoverage":false},{"functionName":"get$name","ranges":[{"startOffset":758674,"endOffset":758712,"count":0}],"isBlockCoverage":false},{"functionName":"get$separator","ranges":[{"startOffset":758733,"endOffset":758769,"count":0}],"isBlockCoverage":false},{"functionName":"containsSeparator$1","ranges":[{"startOffset":758831,"endOffset":758908,"count":0}],"isBlockCoverage":false},{"functionName":"isSeparator$1","ranges":[{"startOffset":758929,"endOffset":759004,"count":0}],"isBlockCoverage":false},{"functionName":"needsSeparator$1","ranges":[{"startOffset":759028,"endOffset":759218,"count":0}],"isBlockCoverage":false},{"functionName":"rootLength$2$withDrive","ranges":[{"startOffset":759248,"endOffset":760107,"count":0}],"isBlockCoverage":false},{"functionName":"rootLength$1","ranges":[{"startOffset":760127,"endOffset":760204,"count":0}],"isBlockCoverage":false},{"functionName":"isRootRelative$1","ranges":[{"startOffset":760228,"endOffset":760294,"count":0}],"isBlockCoverage":false},{"functionName":"pathFromUri$1","ranges":[{"startOffset":760315,"endOffset":760968,"count":0}],"isBlockCoverage":false},{"functionName":"absolutePathToUri$1","ranges":[{"startOffset":760995,"endOffset":762083,"count":0}],"isBlockCoverage":false},{"functionName":"codeUnitsEqual$2","ranges":[{"startOffset":762107,"endOffset":762496,"count":0}],"isBlockCoverage":false},{"functionName":"pathsEqual$2","ranges":[{"startOffset":762516,"endOffset":762906,"count":0}],"isBlockCoverage":false},{"functionName":"get$name","ranges":[{"startOffset":762922,"endOffset":762964,"count":0}],"isBlockCoverage":false},{"functionName":"get$separator","ranges":[{"startOffset":762985,"endOffset":763022,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":763097,"endOffset":763169,"count":0}],"isBlockCoverage":false},{"functionName":"request$0","ranges":[{"startOffset":763232,"endOffset":764213,"count":0}],"isBlockCoverage":false},{"functionName":"withResource$1$1","ranges":[{"startOffset":764237,"endOffset":764370,"count":0}],"isBlockCoverage":false},{"functionName":"withResource$body$Pool","ranges":[{"startOffset":764400,"endOffset":766633,"count":0}],"isBlockCoverage":false},{"functionName":"close$0","ranges":[{"startOffset":766648,"endOffset":766745,"count":0}],"isBlockCoverage":false},{"functionName":"_onResourceReleaseAllowed$1","ranges":[{"startOffset":766780,"endOffset":767623,"count":0}],"isBlockCoverage":false},{"functionName":"_runOnRelease$1","ranges":[{"startOffset":767646,"endOffset":768136,"count":0}],"isBlockCoverage":false},{"functionName":"_resetTimer$0","ranges":[{"startOffset":768157,"endOffset":768543,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":768598,"endOffset":769521,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":769616,"endOffset":769695,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":769777,"endOffset":769909,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":769992,"endOffset":770160,"count":0}],"isBlockCoverage":false},{"functionName":"release$0","ranges":[{"startOffset":770231,"endOffset":770780,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":770838,"endOffset":771040,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":771119,"endOffset":773479,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":773558,"endOffset":773629,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":773709,"endOffset":773806,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":773887,"endOffset":773961,"count":0}],"isBlockCoverage":false},{"functionName":"MultiSectionMapping$fromJson$3$mapUrl","ranges":[{"startOffset":774096,"endOffset":775955,"count":0}],"isBlockCoverage":false},{"functionName":"_indexFor$2","ranges":[{"startOffset":775974,"endOffset":776437,"count":0}],"isBlockCoverage":false},{"functionName":"spanFor$4$files$uri","ranges":[{"startOffset":776464,"endOffset":777052,"count":0}],"isBlockCoverage":false},{"functionName":"spanFor$3$uri","ranges":[{"startOffset":777073,"endOffset":777172,"count":0}],"isBlockCoverage":false},{"functionName":"spanFor$3$files","ranges":[{"startOffset":777195,"endOffset":777298,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":777316,"endOffset":777847,"count":0}],"isBlockCoverage":false},{"functionName":"MappingBundle$fromJson$2$mapUrl","ranges":[{"startOffset":777922,"endOffset":778250,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":778268,"endOffset":778496,"count":0}],"isBlockCoverage":false},{"functionName":"spanFor$4$files$uri","ranges":[{"startOffset":778523,"endOffset":779530,"count":0}],"isBlockCoverage":false},{"functionName":"spanFor$3$uri","ranges":[{"startOffset":779551,"endOffset":779650,"count":0}],"isBlockCoverage":false},{"functionName":"SingleMapping$fromJson$2$mapUrl","ranges":[{"startOffset":779725,"endOffset":783823,"count":0}],"isBlockCoverage":false},{"functionName":"_segmentError$2","ranges":[{"startOffset":783846,"endOffset":784041,"count":0}],"isBlockCoverage":false},{"functionName":"_findLine$1","ranges":[{"startOffset":784060,"endOffset":784406,"count":0}],"isBlockCoverage":false},{"functionName":"_findColumn$3","ranges":[{"startOffset":784427,"endOffset":785004,"count":0}],"isBlockCoverage":false},{"functionName":"spanFor$4$files$uri","ranges":[{"startOffset":785031,"endOffset":786224,"count":0}],"isBlockCoverage":false},{"functionName":"spanFor$3$uri","ranges":[{"startOffset":786245,"endOffset":786344,"count":0}],"isBlockCoverage":false},{"functionName":"spanFor$3$files","ranges":[{"startOffset":786367,"endOffset":786470,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":786488,"endOffset":786852,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":786919,"endOffset":787072,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":787159,"endOffset":787217,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":787306,"endOffset":787368,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":787443,"endOffset":787558,"count":0}],"isBlockCoverage":false},{"functionName":"get$line","ranges":[{"startOffset":787574,"endOffset":787616,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":787668,"endOffset":787921,"count":0}],"isBlockCoverage":false},{"functionName":"get$column","ranges":[{"startOffset":787939,"endOffset":787983,"count":0}],"isBlockCoverage":false},{"functionName":"moveNext$0","ranges":[{"startOffset":788041,"endOffset":788109,"count":0}],"isBlockCoverage":false},{"functionName":"get$current","ranges":[{"startOffset":788128,"endOffset":788407,"count":0}],"isBlockCoverage":false},{"functionName":"get$hasTokens","ranges":[{"startOffset":788428,"endOffset":788527,"count":0}],"isBlockCoverage":false},{"functionName":"get$nextKind","ranges":[{"startOffset":788547,"endOffset":788997,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":789015,"endOffset":789583,"count":0}],"isBlockCoverage":false},{"functionName":"get$isIdentifier","ranges":[{"startOffset":789694,"endOffset":789744,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":789788,"endOffset":790045,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":790116,"endOffset":790175,"count":0}],"isBlockCoverage":false},{"functionName":"get$lines","ranges":[{"startOffset":790192,"endOffset":790248,"count":0}],"isBlockCoverage":false},{"functionName":"SourceFile$decoded$2$url","ranges":[{"startOffset":790280,"endOffset":790792,"count":0}],"isBlockCoverage":false},{"functionName":"span$2","ranges":[{"startOffset":790806,"endOffset":790879,"count":0}],"isBlockCoverage":false},{"functionName":"getLine$1","ranges":[{"startOffset":790896,"endOffset":791616,"count":0}],"isBlockCoverage":false},{"functionName":"_isNearCachedLine$1","ranges":[{"startOffset":791643,"endOffset":792548,"count":0}],"isBlockCoverage":false},{"functionName":"_binarySearch$1","ranges":[{"startOffset":792571,"endOffset":792981,"count":0}],"isBlockCoverage":false},{"functionName":"getColumn$1","ranges":[{"startOffset":793000,"endOffset":793683,"count":0}],"isBlockCoverage":false},{"functionName":"getOffset$2","ranges":[{"startOffset":793702,"endOffset":794481,"count":0}],"isBlockCoverage":false},{"functionName":"getOffset$1","ranges":[{"startOffset":794500,"endOffset":794565,"count":0}],"isBlockCoverage":false},{"functionName":"get$sourceUrl","ranges":[{"startOffset":794621,"endOffset":794667,"count":0}],"isBlockCoverage":false},{"functionName":"get$line","ranges":[{"startOffset":794683,"endOffset":794748,"count":0}],"isBlockCoverage":false},{"functionName":"get$column","ranges":[{"startOffset":794766,"endOffset":794833,"count":0}],"isBlockCoverage":false},{"functionName":"get$offset","ranges":[{"startOffset":794851,"endOffset":794903,"count":0}],"isBlockCoverage":false},{"functionName":"get$sourceUrl","ranges":[{"startOffset":794956,"endOffset":795002,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":795020,"endOffset":795089,"count":0}],"isBlockCoverage":false},{"functionName":"get$start","ranges":[{"startOffset":795106,"endOffset":795185,"count":0}],"isBlockCoverage":false},{"functionName":"get$end","ranges":[{"startOffset":795200,"endOffset":795277,"count":0}],"isBlockCoverage":false},{"functionName":"get$text","ranges":[{"startOffset":795293,"endOffset":795463,"count":0}],"isBlockCoverage":false},{"functionName":"get$context","ranges":[{"startOffset":795482,"endOffset":796567,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":796578,"endOffset":797060,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":797080,"endOffset":797171,"count":0}],"isBlockCoverage":false},{"functionName":"expand$1","ranges":[{"startOffset":797187,"endOffset":797617,"count":0}],"isBlockCoverage":false},{"functionName":"highlight$0","ranges":[{"startOffset":797723,"endOffset":800062,"count":0}],"isBlockCoverage":false},{"functionName":"_writeFirstLine$1","ranges":[{"startOffset":800087,"endOffset":801960,"count":0}],"isBlockCoverage":false},{"functionName":"_writeIntermediateLines$1","ranges":[{"startOffset":801993,"endOffset":802716,"count":0}],"isBlockCoverage":false},{"functionName":"_writeLastLine$1","ranges":[{"startOffset":802740,"endOffset":803867,"count":0}],"isBlockCoverage":false},{"functionName":"_writeTrailingLines$1","ranges":[{"startOffset":803896,"endOffset":804584,"count":0}],"isBlockCoverage":false},{"functionName":"_writeText$1","ranges":[{"startOffset":804604,"endOffset":805084,"count":0}],"isBlockCoverage":false},{"functionName":"_writeSidebar$2$end$line","ranges":[{"startOffset":805116,"endOffset":805243,"count":0}],"isBlockCoverage":false},{"functionName":"_writeSidebar$1$end","ranges":[{"startOffset":805270,"endOffset":805346,"count":0}],"isBlockCoverage":false},{"functionName":"_writeSidebar$1$line","ranges":[{"startOffset":805374,"endOffset":805452,"count":0}],"isBlockCoverage":false},{"functionName":"_writeSidebar$0","ranges":[{"startOffset":805475,"endOffset":805549,"count":0}],"isBlockCoverage":false},{"functionName":"_countTabs$1","ranges":[{"startOffset":805569,"endOffset":805863,"count":0}],"isBlockCoverage":false},{"functionName":"_isOnlyWhitespace$1","ranges":[{"startOffset":805890,"endOffset":806214,"count":0}],"isBlockCoverage":false},{"functionName":"_colorize$2$color","ranges":[{"startOffset":806239,"endOffset":806594,"count":0}],"isBlockCoverage":false},{"functionName":"_colorize$1","ranges":[{"startOffset":806613,"endOffset":806692,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":806764,"endOffset":806982,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":807074,"endOffset":807147,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":807239,"endOffset":807514,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":807606,"endOffset":807796,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":807895,"endOffset":808102,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":808192,"endOffset":808411,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":808502,"endOffset":808715,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":808806,"endOffset":809078,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":809167,"endOffset":809588,"count":0}],"isBlockCoverage":false},{"functionName":"distance$1","ranges":[{"startOffset":809662,"endOffset":809961,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":809972,"endOffset":810183,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":810203,"endOffset":810282,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":810300,"endOffset":810590,"count":0}],"isBlockCoverage":false},{"functionName":"get$sourceUrl","ranges":[{"startOffset":810611,"endOffset":810658,"count":0}],"isBlockCoverage":false},{"functionName":"get$offset","ranges":[{"startOffset":810676,"endOffset":810728,"count":0}],"isBlockCoverage":false},{"functionName":"get$line","ranges":[{"startOffset":810744,"endOffset":810786,"count":0}],"isBlockCoverage":false},{"functionName":"get$column","ranges":[{"startOffset":810804,"endOffset":810848,"count":0}],"isBlockCoverage":false},{"functionName":"distance$1","ranges":[{"startOffset":810908,"endOffset":811205,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":811216,"endOffset":811426,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":811446,"endOffset":811524,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":811542,"endOffset":811946,"count":0}],"isBlockCoverage":false},{"functionName":"SourceSpanBase$3","ranges":[{"startOffset":812064,"endOffset":812766,"count":0}],"isBlockCoverage":false},{"functionName":"get$start","ranges":[{"startOffset":812783,"endOffset":812826,"count":0}],"isBlockCoverage":false},{"functionName":"get$end","ranges":[{"startOffset":812841,"endOffset":812882,"count":0}],"isBlockCoverage":false},{"functionName":"get$text","ranges":[{"startOffset":812898,"endOffset":812940,"count":0}],"isBlockCoverage":false},{"functionName":"get$message","ranges":[{"startOffset":813001,"endOffset":813064,"count":0}],"isBlockCoverage":false},{"functionName":"toString$1$color","ranges":[{"startOffset":813088,"endOffset":813313,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":813331,"endOffset":813411,"count":0}],"isBlockCoverage":false},{"functionName":"get$sourceUrl","ranges":[{"startOffset":813558,"endOffset":813623,"count":0}],"isBlockCoverage":false},{"functionName":"get$length","ranges":[{"startOffset":813641,"endOffset":813799,"count":0}],"isBlockCoverage":false},{"functionName":"message$2$color","ranges":[{"startOffset":813822,"endOffset":814454,"count":0}],"isBlockCoverage":false},{"functionName":"message$1","ranges":[{"startOffset":814471,"endOffset":814568,"count":0}],"isBlockCoverage":false},{"functionName":"highlight$1$color","ranges":[{"startOffset":814593,"endOffset":815709,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":815720,"endOffset":815923,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":815943,"endOffset":816110,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":816128,"endOffset":816349,"count":0}],"isBlockCoverage":false},{"functionName":"get$context","ranges":[{"startOffset":816434,"endOffset":816480,"count":0}],"isBlockCoverage":false},{"functionName":"foldFrames$2$terse","ranges":[{"startOffset":816534,"endOffset":817349,"count":0}],"isBlockCoverage":false},{"functionName":"toTrace$0","ranges":[{"startOffset":817366,"endOffset":817684,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":817702,"endOffset":818222,"count":0}],"isBlockCoverage":false},{"functionName":"get$traces","ranges":[{"startOffset":818262,"endOffset":818306,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":818364,"endOffset":818720,"count":1},{"startOffset":818496,"endOffset":818714,"count":0}],"isBlockCoverage":true},{"functionName":"$signature","ranges":[{"startOffset":818738,"endOffset":818792,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":818856,"endOffset":819515,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":819600,"endOffset":819679,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":819761,"endOffset":819943,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":820026,"endOffset":820116,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":820197,"endOffset":820307,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":820389,"endOffset":820699,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":820777,"endOffset":820853,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":820933,"endOffset":821283,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":821364,"endOffset":821467,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":821546,"endOffset":821837,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":821917,"endOffset":822083,"count":0}],"isBlockCoverage":false},{"functionName":"get$isCore","ranges":[{"startOffset":822149,"endOffset":822214,"count":0}],"isBlockCoverage":false},{"functionName":"get$library","ranges":[{"startOffset":822233,"endOffset":822388,"count":0}],"isBlockCoverage":false},{"functionName":"get$$package","ranges":[{"startOffset":822408,"endOffset":822583,"count":0}],"isBlockCoverage":false},{"functionName":"get$location","ranges":[{"startOffset":822603,"endOffset":822908,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":822926,"endOffset":823016,"count":0}],"isBlockCoverage":false},{"functionName":"get$uri","ranges":[{"startOffset":823031,"endOffset":823072,"count":0}],"isBlockCoverage":false},{"functionName":"get$line","ranges":[{"startOffset":823088,"endOffset":823130,"count":0}],"isBlockCoverage":false},{"functionName":"get$column","ranges":[{"startOffset":823148,"endOffset":823192,"count":0}],"isBlockCoverage":false},{"functionName":"get$member","ranges":[{"startOffset":823210,"endOffset":823254,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":823318,"endOffset":824399,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":824483,"endOffset":825317,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":825415,"endOffset":826447,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":826536,"endOffset":827780,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":827870,"endOffset":829445,"count":0}],"isBlockCoverage":false},{"functionName":"get$_chain","ranges":[{"startOffset":829515,"endOffset":829701,"count":0}],"isBlockCoverage":false},{"functionName":"get$traces","ranges":[{"startOffset":829719,"endOffset":829782,"count":0}],"isBlockCoverage":false},{"functionName":"foldFrames$2$terse","ranges":[{"startOffset":829808,"endOffset":829965,"count":0}],"isBlockCoverage":false},{"functionName":"toTrace$0","ranges":[{"startOffset":829982,"endOffset":830069,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":830087,"endOffset":830153,"count":0}],"isBlockCoverage":false},{"functionName":"set$_lazy_chain$_inner","ranges":[{"startOffset":830183,"endOffset":830267,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":830371,"endOffset":830474,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":830556,"endOffset":830624,"count":0}],"isBlockCoverage":false},{"functionName":"get$_lazy_trace$_trace","ranges":[{"startOffset":830705,"endOffset":830903,"count":0}],"isBlockCoverage":false},{"functionName":"get$frames","ranges":[{"startOffset":830921,"endOffset":830996,"count":0}],"isBlockCoverage":false},{"functionName":"get$original","ranges":[{"startOffset":831016,"endOffset":831093,"count":0}],"isBlockCoverage":false},{"functionName":"foldFrames$2$terse","ranges":[{"startOffset":831119,"endOffset":831276,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":831294,"endOffset":831372,"count":0}],"isBlockCoverage":false},{"functionName":"set$_lazy_trace$_inner","ranges":[{"startOffset":831402,"endOffset":831486,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":831590,"endOffset":831705,"count":0}],"isBlockCoverage":false},{"functionName":"chainFor$1","ranges":[{"startOffset":831787,"endOffset":832653,"count":0}],"isBlockCoverage":false},{"functionName":"_stack_zone_specification$_registerCallback$1$4","ranges":[{"startOffset":832708,"endOffset":833201,"count":1},{"startOffset":832917,"endOffset":832966,"count":0}],"isBlockCoverage":true},{"functionName":"_stack_zone_specification$_registerCallback$4","ranges":[{"startOffset":833254,"endOffset":833402,"count":0}],"isBlockCoverage":false},{"functionName":"_stack_zone_specification$_registerUnaryCallback$2$4","ranges":[{"startOffset":833462,"endOffset":834015,"count":1},{"startOffset":833704,"endOffset":833762,"count":0}],"isBlockCoverage":true},{"functionName":"_stack_zone_specification$_registerUnaryCallback$4","ranges":[{"startOffset":834073,"endOffset":834241,"count":0}],"isBlockCoverage":false},{"functionName":"_stack_zone_specification$_registerBinaryCallback$3$4","ranges":[{"startOffset":834302,"endOffset":834911,"count":1},{"startOffset":834516,"endOffset":834648,"count":0}],"isBlockCoverage":true},{"functionName":"_stack_zone_specification$_registerBinaryCallback$4","ranges":[{"startOffset":834970,"endOffset":835154,"count":0}],"isBlockCoverage":false},{"functionName":"_stack_zone_specification$_errorCallback$5","ranges":[{"startOffset":835204,"endOffset":836108,"count":0}],"isBlockCoverage":false},{"functionName":"_stack_zone_specification$_run$1$2","ranges":[{"startOffset":836150,"endOffset":836761,"count":1},{"startOffset":836415,"endOffset":836692,"count":0}],"isBlockCoverage":true},{"functionName":"_currentTrace$1","ranges":[{"startOffset":836784,"endOffset":836966,"count":1}],"isBlockCoverage":true},{"functionName":"_trimVMChain$1","ranges":[{"startOffset":836988,"endOffset":837222,"count":0}],"isBlockCoverage":false},{"functionName":"set$_currentNode","ranges":[{"startOffset":837246,"endOffset":837336,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":837412,"endOffset":837498,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":837595,"endOffset":837689,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":837793,"endOffset":837926,"count":1}],"isBlockCoverage":true},{"functionName":"$signature","ranges":[{"startOffset":837944,"endOffset":837998,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":838088,"endOffset":838328,"count":1}],"isBlockCoverage":true},{"functionName":"$signature","ranges":[{"startOffset":838346,"endOffset":838433,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":838524,"endOffset":838580,"count":1}],"isBlockCoverage":true},{"functionName":"$signature","ranges":[{"startOffset":838598,"endOffset":838652,"count":1}],"isBlockCoverage":true},{"functionName":"call$2","ranges":[{"startOffset":838743,"endOffset":839016,"count":1}],"isBlockCoverage":true},{"functionName":"$signature","ranges":[{"startOffset":839034,"endOffset":839141,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":839233,"endOffset":839344,"count":1}],"isBlockCoverage":true},{"functionName":"$signature","ranges":[{"startOffset":839362,"endOffset":839416,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":839497,"endOffset":839889,"count":0}],"isBlockCoverage":false},{"functionName":"toChain$0","ranges":[{"startOffset":839953,"endOffset":840253,"count":0}],"isBlockCoverage":false},{"functionName":"foldFrames$2$terse","ranges":[{"startOffset":840307,"endOffset":841859,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":841877,"endOffset":842341,"count":0}],"isBlockCoverage":false},{"functionName":"get$frames","ranges":[{"startOffset":842381,"endOffset":842425,"count":0}],"isBlockCoverage":false},{"functionName":"get$original","ranges":[{"startOffset":842445,"endOffset":842491,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":842555,"endOffset":842867,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":842947,"endOffset":843025,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":843103,"endOffset":843191,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":843269,"endOffset":843376,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":843454,"endOffset":843542,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":843624,"endOffset":843701,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":843783,"endOffset":843871,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":843954,"endOffset":844072,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":844155,"endOffset":844248,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":844332,"endOffset":844425,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":844509,"endOffset":844603,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":844684,"endOffset":845037,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":845119,"endOffset":845519,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":845599,"endOffset":845702,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":845781,"endOffset":846034,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":846108,"endOffset":846153,"count":0}],"isBlockCoverage":false},{"functionName":"get$uri","ranges":[{"startOffset":846185,"endOffset":846226,"count":0}],"isBlockCoverage":false},{"functionName":"get$line","ranges":[{"startOffset":846242,"endOffset":846279,"count":0}],"isBlockCoverage":false},{"functionName":"get$column","ranges":[{"startOffset":846297,"endOffset":846334,"count":0}],"isBlockCoverage":false},{"functionName":"get$isCore","ranges":[{"startOffset":846352,"endOffset":846390,"count":0}],"isBlockCoverage":false},{"functionName":"get$library","ranges":[{"startOffset":846409,"endOffset":846452,"count":0}],"isBlockCoverage":false},{"functionName":"get$$package","ranges":[{"startOffset":846472,"endOffset":846509,"count":0}],"isBlockCoverage":false},{"functionName":"get$location","ranges":[{"startOffset":846529,"endOffset":846572,"count":0}],"isBlockCoverage":false},{"functionName":"get$member","ranges":[{"startOffset":846590,"endOffset":846634,"count":0}],"isBlockCoverage":false},{"functionName":"get$stream","ranges":[{"startOffset":846691,"endOffset":846863,"count":1}],"isBlockCoverage":true},{"functionName":"get$sink","ranges":[{"startOffset":846879,"endOffset":846922,"count":1}],"isBlockCoverage":true},{"functionName":"GuaranteeChannel$3$allowSinkErrors","ranges":[{"startOffset":846964,"endOffset":847401,"count":1}],"isBlockCoverage":true},{"functionName":"_onSinkDisconnected$0","ranges":[{"startOffset":847430,"endOffset":847602,"count":0}],"isBlockCoverage":false},{"functionName":"set$_sink","ranges":[{"startOffset":847619,"endOffset":847714,"count":1}],"isBlockCoverage":true},{"functionName":"set$_streamController","ranges":[{"startOffset":847743,"endOffset":847876,"count":1}],"isBlockCoverage":true},{"functionName":"set$_subscription","ranges":[{"startOffset":847901,"endOffset":848024,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":848085,"endOffset":848387,"count":1},{"startOffset":848177,"endOffset":848184,"count":0}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":848468,"endOffset":848594,"count":0}],"isBlockCoverage":false},{"functionName":"get$done","ranges":[{"startOffset":848666,"endOffset":848725,"count":0}],"isBlockCoverage":false},{"functionName":"add$1","ranges":[{"startOffset":848738,"endOffset":849217,"count":1},{"startOffset":848863,"endOffset":848935,"count":0},{"startOffset":848992,"endOffset":849070,"count":0},{"startOffset":849110,"endOffset":849117,"count":0}],"isBlockCoverage":true},{"functionName":"addError$2","ranges":[{"startOffset":849235,"endOffset":849669,"count":0}],"isBlockCoverage":false},{"functionName":"addError$1","ranges":[{"startOffset":849687,"endOffset":849753,"count":0}],"isBlockCoverage":false},{"functionName":"_addError$2","ranges":[{"startOffset":849772,"endOffset":850246,"count":0}],"isBlockCoverage":false},{"functionName":"_addError$1","ranges":[{"startOffset":850265,"endOffset":850332,"count":0}],"isBlockCoverage":false},{"functionName":"addStream$1","ranges":[{"startOffset":850351,"endOffset":851289,"count":1},{"startOffset":850488,"endOffset":850561,"count":0},{"startOffset":850618,"endOffset":850697,"count":0},{"startOffset":850729,"endOffset":850857,"count":0}],"isBlockCoverage":true},{"functionName":"close$0","ranges":[{"startOffset":851304,"endOffset":851793,"count":0}],"isBlockCoverage":false},{"functionName":"_onStreamDisconnected$0","ranges":[{"startOffset":851824,"endOffset":852220,"count":0}],"isBlockCoverage":false},{"functionName":"set$_addStreamSubscription","ranges":[{"startOffset":852254,"endOffset":852404,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":852558,"endOffset":852577,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":852665,"endOffset":852791,"count":0}],"isBlockCoverage":false},{"functionName":"_MultiChannel$1","ranges":[{"startOffset":852869,"endOffset":853574,"count":1}],"isBlockCoverage":true},{"functionName":"virtualChannel$1","ranges":[{"startOffset":853598,"endOffset":855403,"count":1},{"startOffset":854008,"endOffset":854335,"count":0},{"startOffset":854389,"endOffset":854435,"count":0},{"startOffset":854564,"endOffset":854665,"count":0}],"isBlockCoverage":true},{"functionName":"virtualChannel$0","ranges":[{"startOffset":855427,"endOffset":855487,"count":1}],"isBlockCoverage":true},{"functionName":"_closeChannel$2","ranges":[{"startOffset":855510,"endOffset":855929,"count":0}],"isBlockCoverage":false},{"functionName":"_closeInnerChannel$0","ranges":[{"startOffset":855957,"endOffset":856432,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":856514,"endOffset":856645,"count":1}],"isBlockCoverage":true},{"functionName":"$signature","ranges":[{"startOffset":856663,"endOffset":856718,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":856777,"endOffset":856842,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":856920,"endOffset":857524,"count":1},{"startOffset":857122,"endOffset":857129,"count":0},{"startOffset":857353,"endOffset":857369,"count":0},{"startOffset":857463,"endOffset":857518,"count":0}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":857602,"endOffset":857750,"count":0}],"isBlockCoverage":false},{"functionName":"$signature","ranges":[{"startOffset":857768,"endOffset":857847,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":857920,"endOffset":858103,"count":1}],"isBlockCoverage":true},{"functionName":"$signature","ranges":[{"startOffset":858121,"endOffset":858184,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":858258,"endOffset":858370,"count":0}],"isBlockCoverage":false},{"functionName":"get$stream","ranges":[{"startOffset":858463,"endOffset":858515,"count":0}],"isBlockCoverage":false},{"functionName":"set$_stream_channel_completer$_channel","ranges":[{"startOffset":858606,"endOffset":858735,"count":1}],"isBlockCoverage":true},{"functionName":"get$local","ranges":[{"startOffset":858798,"endOffset":858842,"count":0}],"isBlockCoverage":false},{"functionName":"set$_local","ranges":[{"startOffset":858860,"endOffset":858957,"count":1}],"isBlockCoverage":true},{"functionName":"set$_foreign","ranges":[{"startOffset":858977,"endOffset":859080,"count":1}],"isBlockCoverage":true},{"functionName":"get$stream","ranges":[{"startOffset":859169,"endOffset":859221,"count":1}],"isBlockCoverage":true},{"functionName":"spanFrom$1","ranges":[{"startOffset":859374,"endOffset":859530,"count":0}],"isBlockCoverage":false},{"functionName":"matches$1","ranges":[{"startOffset":859547,"endOffset":859856,"count":0}],"isBlockCoverage":false},{"functionName":"error$3$length$position","ranges":[{"startOffset":859887,"endOffset":860142,"count":0}],"isBlockCoverage":false},{"functionName":"get$lastMatch","ranges":[{"startOffset":860259,"endOffset":860437,"count":0}],"isBlockCoverage":false},{"functionName":"peekChar$0","ranges":[{"startOffset":860455,"endOffset":860647,"count":0}],"isBlockCoverage":false},{"functionName":"scan$1","ranges":[{"startOffset":860661,"endOffset":860895,"count":0}],"isBlockCoverage":false},{"functionName":"expect$2$name","ranges":[{"startOffset":860916,"endOffset":861423,"count":0}],"isBlockCoverage":false},{"functionName":"expect$1","ranges":[{"startOffset":861439,"endOffset":861512,"count":0}],"isBlockCoverage":false},{"functionName":"matches$1","ranges":[{"startOffset":861529,"endOffset":861791,"count":0}],"isBlockCoverage":false},{"functionName":"glyphOrAscii$2","ranges":[{"startOffset":861849,"endOffset":861911,"count":0}],"isBlockCoverage":false},{"functionName":"get$horizontalLine","ranges":[{"startOffset":861937,"endOffset":861973,"count":0}],"isBlockCoverage":false},{"functionName":"get$verticalLine","ranges":[{"startOffset":861997,"endOffset":862033,"count":0}],"isBlockCoverage":false},{"functionName":"get$topLeftCorner","ranges":[{"startOffset":862058,"endOffset":862094,"count":0}],"isBlockCoverage":false},{"functionName":"get$bottomLeftCorner","ranges":[{"startOffset":862122,"endOffset":862158,"count":0}],"isBlockCoverage":false},{"functionName":"get$upEnd","ranges":[{"startOffset":862175,"endOffset":862211,"count":0}],"isBlockCoverage":false},{"functionName":"get$downEnd","ranges":[{"startOffset":862230,"endOffset":862266,"count":0}],"isBlockCoverage":false},{"functionName":"glyphOrAscii$2","ranges":[{"startOffset":862326,"endOffset":862382,"count":0}],"isBlockCoverage":false},{"functionName":"get$horizontalLine","ranges":[{"startOffset":862408,"endOffset":862449,"count":0}],"isBlockCoverage":false},{"functionName":"get$verticalLine","ranges":[{"startOffset":862473,"endOffset":862514,"count":0}],"isBlockCoverage":false},{"functionName":"get$topLeftCorner","ranges":[{"startOffset":862539,"endOffset":862580,"count":0}],"isBlockCoverage":false},{"functionName":"get$bottomLeftCorner","ranges":[{"startOffset":862608,"endOffset":862649,"count":0}],"isBlockCoverage":false},{"functionName":"get$upEnd","ranges":[{"startOffset":862666,"endOffset":862707,"count":0}],"isBlockCoverage":false},{"functionName":"get$downEnd","ranges":[{"startOffset":862726,"endOffset":862767,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":862840,"endOffset":864682,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":863077,"endOffset":864609,"count":1},{"startOffset":863167,"endOffset":863223,"count":0},{"startOffset":863485,"endOffset":863577,"count":0},{"startOffset":863993,"endOffset":864097,"count":0},{"startOffset":864323,"endOffset":864422,"count":0}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":864764,"endOffset":865103,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":865187,"endOffset":865869,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":865953,"endOffset":866183,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":866268,"endOffset":866429,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":866513,"endOffset":866721,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":866796,"endOffset":866858,"count":0}],"isBlockCoverage":false},{"functionName":"test$9$onPlatform$retry$skip$solo$tags$testOn$timeout","ranges":[{"startOffset":866971,"endOffset":867811,"count":1},{"startOffset":867323,"endOffset":867326,"count":0},{"startOffset":867550,"endOffset":867557,"count":0},{"startOffset":867633,"endOffset":867659,"count":0}],"isBlockCoverage":true},{"functionName":"group$9$onPlatform$retry$skip$solo$tags$testOn$timeout","ranges":[{"startOffset":867873,"endOffset":869608,"count":1},{"startOffset":868325,"endOffset":868328,"count":0},{"startOffset":868584,"endOffset":868610,"count":0},{"startOffset":868684,"endOffset":868702,"count":0},{"startOffset":869525,"endOffset":869602,"count":0}],"isBlockCoverage":true},{"functionName":"build$0","ranges":[{"startOffset":869623,"endOffset":870102,"count":1}],"isBlockCoverage":true},{"functionName":"_checkNotBuilt$1","ranges":[{"startOffset":870126,"endOffset":870294,"count":1},{"startOffset":870183,"endOffset":870293,"count":0}],"isBlockCoverage":true},{"functionName":"_runSetUps$0","ranges":[{"startOffset":870314,"endOffset":871575,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":870514,"endOffset":871496,"count":1},{"startOffset":870604,"endOffset":870660,"count":0}],"isBlockCoverage":true},{"functionName":"get$_setUpAll","ranges":[{"startOffset":871596,"endOffset":871633,"count":1}],"isBlockCoverage":true},{"functionName":"get$_tearDownAll","ranges":[{"startOffset":871657,"endOffset":872027,"count":1},{"startOffset":871775,"endOffset":871849,"count":0},{"startOffset":871850,"endOffset":871873,"count":0}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":872085,"endOffset":874867,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":872360,"endOffset":874794,"count":1},{"startOffset":872450,"endOffset":872506,"count":0},{"startOffset":873288,"endOffset":874287,"count":0}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":874945,"endOffset":875120,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":875200,"endOffset":876169,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":875387,"endOffset":876096,"count":1},{"startOffset":875477,"endOffset":875533,"count":0}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":876247,"endOffset":876413,"count":1},{"startOffset":876332,"endOffset":876412,"count":0}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":876491,"endOffset":876827,"count":1},{"startOffset":876626,"endOffset":876669,"count":0},{"startOffset":876670,"endOffset":876812,"count":0}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":876911,"endOffset":876963,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":877049,"endOffset":877288,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":877374,"endOffset":877550,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":877637,"endOffset":879068,"count":0}],"isBlockCoverage":false},{"functionName":"forPlatform$1","ranges":[{"startOffset":879136,"endOffset":879644,"count":1},{"startOffset":879307,"endOffset":879319,"count":0},{"startOffset":879481,"endOffset":879510,"count":0},{"startOffset":879520,"endOffset":879532,"count":0}],"isBlockCoverage":true},{"functionName":"_group$_map$1","ranges":[{"startOffset":879665,"endOffset":880149,"count":1}],"isBlockCoverage":true},{"functionName":"get$name","ranges":[{"startOffset":880187,"endOffset":880237,"count":0}],"isBlockCoverage":false},{"functionName":"get$metadata","ranges":[{"startOffset":880257,"endOffset":880303,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":880365,"endOffset":880437,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":880512,"endOffset":880602,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":880678,"endOffset":880754,"count":1}],"isBlockCoverage":true},{"functionName":"load$2$groups","ranges":[{"startOffset":880858,"endOffset":881479,"count":1}],"isBlockCoverage":true},{"functionName":"forPlatform$1","ranges":[{"startOffset":881500,"endOffset":881799,"count":1},{"startOffset":881648,"endOffset":881660,"count":0}],"isBlockCoverage":true},{"functionName":"get$name","ranges":[{"startOffset":881815,"endOffset":881865,"count":0}],"isBlockCoverage":false},{"functionName":"get$metadata","ranges":[{"startOffset":881885,"endOffset":881931,"count":0}],"isBlockCoverage":false},{"functionName":"get$_outstandingCallbacks","ranges":[{"startOffset":881994,"endOffset":882266,"count":1},{"startOffset":882147,"endOffset":882265,"count":0}],"isBlockCoverage":true},{"functionName":"addOutstandingCallback$0","ranges":[{"startOffset":882298,"endOffset":882562,"count":0}],"isBlockCoverage":false},{"functionName":"waitForOutstandingCallbacks$1","ranges":[{"startOffset":882599,"endOffset":883243,"count":1}],"isBlockCoverage":true},{"functionName":"unclosable$1$1","ranges":[{"startOffset":883265,"endOffset":883512,"count":1}],"isBlockCoverage":true},{"functionName":"heartbeat$0","ranges":[{"startOffset":883531,"endOffset":884164,"count":1},{"startOffset":883729,"endOffset":883736,"count":0},{"startOffset":883989,"endOffset":883996,"count":0}],"isBlockCoverage":true},{"functionName":"_handleError$3","ranges":[{"startOffset":884186,"endOffset":885992,"count":0}],"isBlockCoverage":false},{"functionName":"_handleError$2","ranges":[{"startOffset":886014,"endOffset":886096,"count":0}],"isBlockCoverage":false},{"functionName":"_invoker$_onRun$0","ranges":[{"startOffset":886121,"endOffset":886628,"count":1}],"isBlockCoverage":true},{"functionName":"_runTearDowns$0","ranges":[{"startOffset":886651,"endOffset":888109,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":886875,"endOffset":888027,"count":1},{"startOffset":886965,"endOffset":887021,"count":0},{"startOffset":887385,"endOffset":887694,"count":0},{"startOffset":887707,"endOffset":887841,"count":0}],"isBlockCoverage":true},{"functionName":"call$5","ranges":[{"startOffset":888167,"endOffset":888558,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":888637,"endOffset":888765,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":888865,"endOffset":889886,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":889058,"endOffset":889813,"count":1},{"startOffset":889148,"endOffset":889204,"count":0}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":889986,"endOffset":890094,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":890175,"endOffset":890978,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":891060,"endOffset":891255,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":891337,"endOffset":891638,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":891722,"endOffset":891930,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":892015,"endOffset":892186,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":892264,"endOffset":892515,"count":1},{"startOffset":892445,"endOffset":892477,"count":0}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":892594,"endOffset":893102,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":893182,"endOffset":895232,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":893413,"endOffset":895159,"count":1},{"startOffset":893503,"endOffset":893559,"count":0},{"startOffset":894440,"endOffset":894592,"count":0},{"startOffset":894648,"endOffset":894893,"count":0}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":895313,"endOffset":896507,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":895504,"endOffset":896434,"count":1},{"startOffset":895594,"endOffset":895650,"count":0}],"isBlockCoverage":true},{"functionName":"call$4","ranges":[{"startOffset":896588,"endOffset":896759,"count":0}],"isBlockCoverage":false},{"functionName":"decrement$0","ranges":[{"startOffset":896834,"endOffset":897013,"count":1},{"startOffset":896886,"endOffset":896893,"count":0},{"startOffset":896977,"endOffset":896984,"count":0}],"isBlockCoverage":true},{"functionName":"run$0","ranges":[{"startOffset":897087,"endOffset":897565,"count":0}],"isBlockCoverage":false},{"functionName":"addError$2","ranges":[{"startOffset":897624,"endOffset":897936,"count":0}],"isBlockCoverage":false},{"functionName":"setState$1","ranges":[{"startOffset":897954,"endOffset":898264,"count":1},{"startOffset":898062,"endOffset":898069,"count":0},{"startOffset":898141,"endOffset":898148,"count":0}],"isBlockCoverage":true},{"functionName":"message$1","ranges":[{"startOffset":898281,"endOffset":898470,"count":0}],"isBlockCoverage":false},{"functionName":"_live_test_controller$_run$0","ranges":[{"startOffset":898506,"endOffset":898976,"count":1},{"startOffset":898579,"endOffset":898668,"count":0},{"startOffset":898737,"endOffset":898829,"count":0}],"isBlockCoverage":true},{"functionName":"_live_test_controller$_close$0","ranges":[{"startOffset":899014,"endOffset":899384,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":899464,"endOffset":899507,"count":0}],"isBlockCoverage":false},{"functionName":"_validateTags$0","ranges":[{"startOffset":899561,"endOffset":900156,"count":1},{"startOffset":899966,"endOffset":900155,"count":0}],"isBlockCoverage":true},{"functionName":"validatePlatformSelectors$1","ranges":[{"startOffset":900191,"endOffset":900418,"count":1}],"isBlockCoverage":true},{"functionName":"merge$1","ranges":[{"startOffset":900433,"endOffset":901393,"count":1}],"isBlockCoverage":true},{"functionName":"change$4$onPlatform$skip$skipReason$timeout","ranges":[{"startOffset":901444,"endOffset":902100,"count":0}],"isBlockCoverage":false},{"functionName":"change$1$onPlatform","ranges":[{"startOffset":902127,"endOffset":902248,"count":0}],"isBlockCoverage":false},{"functionName":"change$1$timeout","ranges":[{"startOffset":902272,"endOffset":902387,"count":0}],"isBlockCoverage":false},{"functionName":"change$2$skip$skipReason","ranges":[{"startOffset":902419,"endOffset":902546,"count":0}],"isBlockCoverage":false},{"functionName":"forPlatform$1","ranges":[{"startOffset":902567,"endOffset":902916,"count":1},{"startOffset":902687,"endOffset":902915,"count":0}],"isBlockCoverage":true},{"functionName":"serialize$0","ranges":[{"startOffset":902935,"endOffset":903762,"count":1},{"startOffset":903242,"endOffset":903261,"count":0}],"isBlockCoverage":true},{"functionName":"_serializeTimeout$1","ranges":[{"startOffset":903789,"endOffset":904104,"count":1},{"startOffset":903878,"endOffset":903892,"count":0},{"startOffset":903951,"endOffset":903965,"count":0}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":904170,"endOffset":904437,"count":1}],"isBlockCoverage":true},{"functionName":"call$2","ranges":[{"startOffset":904519,"endOffset":904859,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":904944,"endOffset":905183,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":905270,"endOffset":905391,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":905478,"endOffset":905558,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":905656,"endOffset":905903,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":905982,"endOffset":906116,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":906196,"endOffset":906330,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":906415,"endOffset":906760,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":906843,"endOffset":907050,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":907134,"endOffset":907382,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":907458,"endOffset":907501,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":907566,"endOffset":907676,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":907762,"endOffset":907799,"count":1}],"isBlockCoverage":true},{"functionName":"validate$1","ranges":[{"startOffset":907875,"endOffset":908141,"count":1},{"startOffset":908007,"endOffset":908140,"count":0}],"isBlockCoverage":true},{"functionName":"evaluate$1","ranges":[{"startOffset":908159,"endOffset":908292,"count":1}],"isBlockCoverage":true},{"functionName":"intersection$1","ranges":[{"startOffset":908314,"endOffset":908542,"count":1},{"startOffset":908448,"endOffset":908541,"count":0}],"isBlockCoverage":true},{"functionName":"toString$0","ranges":[{"startOffset":908560,"endOffset":908639,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":908650,"endOffset":908848,"count":0}],"isBlockCoverage":false},{"functionName":"get$hashCode","ranges":[{"startOffset":908868,"endOffset":908949,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":909016,"endOffset":909144,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":909234,"endOffset":909377,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":909467,"endOffset":909603,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":909692,"endOffset":910518,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":910585,"endOffset":910628,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":910700,"endOffset":910802,"count":1}],"isBlockCoverage":true},{"functionName":"configure$3$except$mapper$only","ranges":[{"startOffset":910902,"endOffset":911192,"count":1},{"startOffset":911107,"endOffset":911132,"count":0},{"startOffset":911165,"endOffset":911186,"count":0}],"isBlockCoverage":true},{"functionName":"configure$2$except$only","ranges":[{"startOffset":911223,"endOffset":911323,"count":1}],"isBlockCoverage":true},{"functionName":"configure$1$mapper","ranges":[{"startOffset":911349,"endOffset":911443,"count":1}],"isBlockCoverage":true},{"functionName":"formatStackTrace$2$verbose","ranges":[{"startOffset":911477,"endOffset":912169,"count":0}],"isBlockCoverage":false},{"functionName":"set$_except","ranges":[{"startOffset":912188,"endOffset":912268,"count":0}],"isBlockCoverage":false},{"functionName":"set$_only","ranges":[{"startOffset":912285,"endOffset":912359,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":912440,"endOffset":912670,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":912729,"endOffset":912905,"count":1},{"startOffset":912783,"endOffset":912796,"count":0},{"startOffset":912867,"endOffset":912898,"count":0}],"isBlockCoverage":true},{"functionName":"get$hashCode","ranges":[{"startOffset":912925,"endOffset":913054,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":913072,"endOffset":913383,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":913430,"endOffset":913473,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":913521,"endOffset":913564,"count":0}],"isBlockCoverage":false},{"functionName":"toString$0","ranges":[{"startOffset":913717,"endOffset":913763,"count":0}],"isBlockCoverage":false},{"functionName":"get$message","ranges":[{"startOffset":913782,"endOffset":913835,"count":0}],"isBlockCoverage":false},{"functionName":"call$5","ranges":[{"startOffset":913888,"endOffset":914188,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":914260,"endOffset":914278,"count":1}],"isBlockCoverage":true},{"functionName":"merge$1","ranges":[{"startOffset":914342,"endOffset":915081,"count":1},{"startOffset":914467,"endOffset":914494,"count":0},{"startOffset":914552,"endOffset":914583,"count":0},{"startOffset":914632,"endOffset":914853,"count":0},{"startOffset":914955,"endOffset":914972,"count":0},{"startOffset":915015,"endOffset":915032,"count":0}],"isBlockCoverage":true},{"functionName":"apply$1","ranges":[{"startOffset":915096,"endOffset":915445,"count":1},{"startOffset":915179,"endOffset":915191,"count":0},{"startOffset":915319,"endOffset":915336,"count":0}],"isBlockCoverage":true},{"functionName":"get$hashCode","ranges":[{"startOffset":915465,"endOffset":915577,"count":0}],"isBlockCoverage":false},{"functionName":"$eq","ranges":[{"startOffset":915588,"endOffset":915784,"count":1},{"startOffset":915642,"endOffset":915655,"count":0}],"isBlockCoverage":true},{"functionName":"toString$0","ranges":[{"startOffset":915802,"endOffset":916008,"count":0}],"isBlockCoverage":false},{"functionName":"_serializeGroup$3","ranges":[{"startOffset":916070,"endOffset":917084,"count":1},{"startOffset":916473,"endOffset":916517,"count":0}],"isBlockCoverage":true},{"functionName":"_serializeTest$3","ranges":[{"startOffset":917108,"endOffset":917764,"count":1},{"startOffset":917540,"endOffset":917584,"count":0}],"isBlockCoverage":true},{"functionName":"_runLiveTest$2","ranges":[{"startOffset":917786,"endOffset":918752,"count":1}],"isBlockCoverage":true},{"functionName":"call$4","ranges":[{"startOffset":918817,"endOffset":919145,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":919231,"endOffset":919250,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":919335,"endOffset":919891,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":919976,"endOffset":920289,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":920375,"endOffset":925739,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":920701,"endOffset":925666,"count":1},{"startOffset":920791,"endOffset":920847,"count":0},{"startOffset":921070,"endOffset":921774,"count":0},{"startOffset":921820,"endOffset":922042,"count":0},{"startOffset":922087,"endOffset":922311,"count":0},{"startOffset":923050,"endOffset":923091,"count":0},{"startOffset":923567,"endOffset":923597,"count":0}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":925826,"endOffset":927365,"count":1},{"startOffset":925967,"endOffset":926041,"count":0},{"startOffset":926601,"endOffset":926671,"count":0},{"startOffset":927004,"endOffset":927069,"count":0},{"startOffset":927115,"endOffset":927359,"count":0}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":927453,"endOffset":927588,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":927676,"endOffset":928035,"count":1}],"isBlockCoverage":true},{"functionName":"call$2","ranges":[{"startOffset":928122,"endOffset":928276,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":928370,"endOffset":928663,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":928757,"endOffset":929103,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":929194,"endOffset":929380,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":929472,"endOffset":929733,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":929826,"endOffset":930378,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":930471,"endOffset":930825,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":930918,"endOffset":931101,"count":1}],"isBlockCoverage":true},{"functionName":"call$1","ranges":[{"startOffset":931193,"endOffset":931352,"count":1}],"isBlockCoverage":true},{"functionName":"connectOut$1","ranges":[{"startOffset":931434,"endOffset":932439,"count":1},{"startOffset":931560,"endOffset":931587,"count":0},{"startOffset":931674,"endOffset":931767,"count":0}],"isBlockCoverage":true},{"functionName":"get$length","ranges":[{"startOffset":932491,"endOffset":932603,"count":0}],"isBlockCoverage":false},{"functionName":"get$iterator","ranges":[{"startOffset":932623,"endOffset":932784,"count":0}],"isBlockCoverage":false},{"functionName":"toSet$0","ranges":[{"startOffset":932799,"endOffset":932888,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":933051,"endOffset":933169,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":933252,"endOffset":933441,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":933506,"endOffset":933888,"count":0}],"isBlockCoverage":false},{"functionName":"get$_onUnpaused","ranges":[{"startOffset":933961,"endOffset":934099,"count":0}],"isBlockCoverage":false},{"functionName":"get$success","ranges":[{"startOffset":934118,"endOffset":935569,"count":0}],"isBlockCoverage":false},{"functionName":"get$liveTests","ranges":[{"startOffset":935590,"endOffset":936069,"count":0}],"isBlockCoverage":false},{"functionName":"Engine$3$concurrency$coverage$maxSuites","ranges":[{"startOffset":936116,"endOffset":936304,"count":0}],"isBlockCoverage":false},{"functionName":"run$0","ranges":[{"startOffset":936317,"endOffset":936943,"count":0}],"isBlockCoverage":false},{"functionName":"_runGroup$3","ranges":[{"startOffset":936962,"endOffset":937125,"count":0}],"isBlockCoverage":false},{"functionName":"_runGroup$body$Engine","ranges":[{"startOffset":937154,"endOffset":945098,"count":0}],"isBlockCoverage":false},{"functionName":"_engine$_runLiveTest$3$countSuccess","ranges":[{"startOffset":945141,"endOffset":945283,"count":0}],"isBlockCoverage":false},{"functionName":"_engine$_runLiveTest$2","ranges":[{"startOffset":945313,"endOffset":945444,"count":0}],"isBlockCoverage":false},{"functionName":"_runLiveTest$body$Engine","ranges":[{"startOffset":945476,"endOffset":948266,"count":0}],"isBlockCoverage":false},{"functionName":"_runSkippedTest$3","ranges":[{"startOffset":948291,"endOffset":948443,"count":0}],"isBlockCoverage":false},{"functionName":"_runSkippedTest$body$Engine","ranges":[{"startOffset":948478,"endOffset":950257,"count":0}],"isBlockCoverage":false},{"functionName":"_addLiveSuite$1","ranges":[{"startOffset":950280,"endOffset":951177,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":951236,"endOffset":951499,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":951570,"endOffset":951828,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":951900,"endOffset":951919,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":951993,"endOffset":952254,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":952330,"endOffset":952400,"count":0}],"isBlockCoverage":false},{"functionName":"$call$body$Engine_run__closure","ranges":[{"startOffset":952438,"endOffset":953809,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":953885,"endOffset":955623,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":955700,"endOffset":955766,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":955842,"endOffset":956062,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":956145,"endOffset":956558,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":956643,"endOffset":956740,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":956824,"endOffset":956842,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":956928,"endOffset":956946,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":957033,"endOffset":957502,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":957589,"endOffset":957607,"count":0}],"isBlockCoverage":false},{"functionName":"LiveSuiteController$1","ranges":[{"startOffset":957758,"endOffset":958027,"count":0}],"isBlockCoverage":false},{"functionName":"reportLiveTest$2$countSuccess","ranges":[{"startOffset":958064,"endOffset":958889,"count":0}],"isBlockCoverage":false},{"functionName":"close$0","ranges":[{"startOffset":958904,"endOffset":959033,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":959097,"endOffset":959152,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":959237,"endOffset":959256,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":959354,"endOffset":959967,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":960057,"endOffset":961699,"count":0}],"isBlockCoverage":false},{"functionName":"_onTestStarted$1","ranges":[{"startOffset":961781,"endOffset":963251,"count":0}],"isBlockCoverage":false},{"functionName":"_onStateChange$2","ranges":[{"startOffset":963275,"endOffset":963683,"count":0}],"isBlockCoverage":false},{"functionName":"_expanded$_onError$3","ranges":[{"startOffset":963711,"endOffset":964186,"count":0}],"isBlockCoverage":false},{"functionName":"_expanded$_onDone$1","ranges":[{"startOffset":964213,"endOffset":965237,"count":0}],"isBlockCoverage":false},{"functionName":"_progressLine$3$color$suffix","ranges":[{"startOffset":965273,"endOffset":967686,"count":0}],"isBlockCoverage":false},{"functionName":"_progressLine$2$suffix","ranges":[{"startOffset":967716,"endOffset":967820,"count":0}],"isBlockCoverage":false},{"functionName":"_progressLine$2$color","ranges":[{"startOffset":967849,"endOffset":967951,"count":0}],"isBlockCoverage":false},{"functionName":"_progressLine$1","ranges":[{"startOffset":967974,"endOffset":968068,"count":0}],"isBlockCoverage":false},{"functionName":"_description$1","ranges":[{"startOffset":968090,"endOffset":968203,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":968279,"endOffset":968386,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":968484,"endOffset":968637,"count":0}],"isBlockCoverage":false},{"functionName":"call$1","ranges":[{"startOffset":968735,"endOffset":969071,"count":0}],"isBlockCoverage":false},{"functionName":"_runner_suite$_close$0","ranges":[{"startOffset":969197,"endOffset":969305,"count":0}],"isBlockCoverage":false},{"functionName":"set$_runner_suite$_suite","ranges":[{"startOffset":969337,"endOffset":969408,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":969481,"endOffset":970301,"count":0}],"isBlockCoverage":false},{"functionName":"writeln$1","ranges":[{"startOffset":970445,"endOffset":970545,"count":0}],"isBlockCoverage":false},{"functionName":"_flush$0","ranges":[{"startOffset":970561,"endOffset":970743,"count":0}],"isBlockCoverage":false},{"functionName":"call$2","ranges":[{"startOffset":970896,"endOffset":971053,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":971128,"endOffset":974564,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":974638,"endOffset":974728,"count":0}],"isBlockCoverage":false},{"functionName":"call$0","ranges":[{"startOffset":974798,"endOffset":974868,"count":1}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":974937,"endOffset":975688,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":975109,"endOffset":975615,"count":1},{"startOffset":975199,"endOffset":975255,"count":0},{"startOffset":975440,"endOffset":975452,"count":0}],"isBlockCoverage":true},{"functionName":"call$0","ranges":[{"startOffset":975756,"endOffset":975816,"count":1}],"isBlockCoverage":true},{"functionName":"aliases","ranges":[{"startOffset":975846,"endOffset":976773,"count":1}],"isBlockCoverage":true},{"functionName":"installTearOffs","ranges":[{"startOffset":976781,"endOffset":984996,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":978155,"endOffset":978225,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":978518,"endOffset":978624,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":978734,"endOffset":978870,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":979096,"endOffset":979215,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":979350,"endOffset":979489,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":979626,"endOffset":979781,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":984923,"endOffset":984982,"count":0}],"isBlockCoverage":false},{"functionName":"inheritance","ranges":[{"startOffset":985004,"endOffset":1007745,"count":1}],"isBlockCoverage":true},{"functionName":"rtii","ranges":[{"startOffset":1029633,"endOffset":1042848,"count":1},{"startOffset":1042844,"endOffset":1042847,"count":0}],"isBlockCoverage":true},{"functionName":"constants","ranges":[{"startOffset":1042856,"endOffset":1058765,"count":1}],"isBlockCoverage":true},{"functionName":"getTagFallback","ranges":[{"startOffset":1044143,"endOffset":1044257,"count":0}],"isBlockCoverage":false},{"functionName":"C.C_JS_CONST0","ranges":[{"startOffset":1044279,"endOffset":1045394,"count":1},{"startOffset":1045302,"endOffset":1045317,"count":0}],"isBlockCoverage":true},{"functionName":"getTag","ranges":[{"startOffset":1044346,"endOffset":1044449,"count":0}],"isBlockCoverage":false},{"functionName":"getUnknownTag","ranges":[{"startOffset":1044452,"endOffset":1044669,"count":0}],"isBlockCoverage":false},{"functionName":"getUnknownTagGenericBrowser","ranges":[{"startOffset":1044672,"endOffset":1044847,"count":0}],"isBlockCoverage":false},{"functionName":"prototypeForTag","ranges":[{"startOffset":1044850,"endOffset":1045116,"count":1},{"startOffset":1044920,"endOffset":1044932,"count":0},{"startOffset":1045066,"endOffset":1045078,"count":0}],"isBlockCoverage":true},{"functionName":"discriminator","ranges":[{"startOffset":1045119,"endOffset":1045163,"count":0}],"isBlockCoverage":false},{"functionName":"C.C_JS_CONST6","ranges":[{"startOffset":1045416,"endOffset":1045880,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1045452,"endOffset":1045877,"count":1},{"startOffset":1045508,"endOffset":1045521,"count":0},{"startOffset":1045599,"endOffset":1045612,"count":0},{"startOffset":1045838,"endOffset":1045876,"count":0}],"isBlockCoverage":true},{"functionName":"confirm","ranges":[{"startOffset":1045656,"endOffset":1045763,"count":1}],"isBlockCoverage":true},{"functionName":"C.C_JS_CONST1","ranges":[{"startOffset":1045902,"endOffset":1046051,"count":1},{"startOffset":1045989,"endOffset":1046050,"count":0}],"isBlockCoverage":true},{"functionName":"C.C_JS_CONST2","ranges":[{"startOffset":1046073,"endOffset":1046546,"count":1}],"isBlockCoverage":true},{"functionName":"getTagFixed","ranges":[{"startOffset":1046169,"endOffset":1046350,"count":0}],"isBlockCoverage":false},{"functionName":"prototypeForTagFixed","ranges":[{"startOffset":1046353,"endOffset":1046466,"count":1},{"startOffset":1046417,"endOffset":1046429,"count":0}],"isBlockCoverage":true},{"functionName":"C.C_JS_CONST5","ranges":[{"startOffset":1046568,"endOffset":1047098,"count":1},{"startOffset":1046655,"endOffset":1046659,"count":0},{"startOffset":1046716,"endOffset":1047097,"count":0}],"isBlockCoverage":true},{"functionName":"getTagFirefox","ranges":[{"startOffset":1046975,"endOffset":1047064,"count":0}],"isBlockCoverage":false},{"functionName":"C.C_JS_CONST4","ranges":[{"startOffset":1047120,"endOffset":1048002,"count":1},{"startOffset":1047207,"endOffset":1047211,"count":0},{"startOffset":1047269,"endOffset":1048001,"count":0}],"isBlockCoverage":true},{"functionName":"getTagIE","ranges":[{"startOffset":1047534,"endOffset":1047777,"count":0}],"isBlockCoverage":false},{"functionName":"prototypeForTagIE","ranges":[{"startOffset":1047780,"endOffset":1047928,"count":0}],"isBlockCoverage":false},{"functionName":"C.C_JS_CONST3","ranges":[{"startOffset":1048024,"endOffset":1048057,"count":1}],"isBlockCoverage":true},{"functionName":"staticFields","ranges":[{"startOffset":1058773,"endOffset":1059835,"count":1}],"isBlockCoverage":true},{"functionName":"lazyInitializers","ranges":[{"startOffset":1059843,"endOffset":1071865,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1059985,"endOffset":1060063,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1060144,"endOffset":1060213,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1060314,"endOffset":1060502,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1060599,"endOffset":1060802,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1060895,"endOffset":1061006,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1061113,"endOffset":1061364,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1061467,"endOffset":1061580,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1061697,"endOffset":1061952,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1062053,"endOffset":1062168,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1062283,"endOffset":1062472,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1062583,"endOffset":1062700,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1062825,"endOffset":1063018,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1063117,"endOffset":1063192,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1063257,"endOffset":1063342,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1063407,"endOffset":1063495,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1063564,"endOffset":1063625,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1063716,"endOffset":1064340,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1064411,"endOffset":1064569,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1064640,"endOffset":1064721,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1064794,"endOffset":1064854,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1064911,"endOffset":1064961,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1065054,"endOffset":1065143,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1065214,"endOffset":1065295,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1065367,"endOffset":1065450,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1065513,"endOffset":1065593,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1065648,"endOffset":1065830,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1065873,"endOffset":1065947,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1065982,"endOffset":1066052,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1066095,"endOffset":1066172,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1066223,"endOffset":1066364,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1066419,"endOffset":1066666,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1066713,"endOffset":1066941,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1066998,"endOffset":1067058,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1067101,"endOffset":1067158,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1067205,"endOffset":1067275,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1067322,"endOffset":1067389,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1067434,"endOffset":1067481,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1067526,"endOffset":1067631,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1067676,"endOffset":1067794,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1067851,"endOffset":1067937,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1067996,"endOffset":1068106,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1068173,"endOffset":1068312,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1068369,"endOffset":1068474,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1068523,"endOffset":1068622,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1068673,"endOffset":1068736,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1068797,"endOffset":1068883,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1068952,"endOffset":1069039,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1069134,"endOffset":1069181,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1069234,"endOffset":1069315,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1069360,"endOffset":1069430,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1069483,"endOffset":1069550,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1069617,"endOffset":1069721,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1069778,"endOffset":1069882,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1069939,"endOffset":1070078,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1070155,"endOffset":1070594,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1070646,"endOffset":1070693,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1070745,"endOffset":1070792,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1070849,"endOffset":1070907,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1070979,"endOffset":1071062,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1071147,"endOffset":1071254,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1071331,"endOffset":1071859,"count":0}],"isBlockCoverage":false},{"functionName":"nativeSupport","ranges":[{"startOffset":1071873,"endOffset":1079153,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1071905,"endOffset":1072690,"count":1},{"startOffset":1072593,"endOffset":1072689,"count":0}],"isBlockCoverage":true},{"functionName":"intern","ranges":[{"startOffset":1071937,"endOffset":1072063,"count":1}],"isBlockCoverage":true},{"functionName":"init.getIsolateTag","ranges":[{"startOffset":1072092,"endOffset":1072176,"count":1}],"isBlockCoverage":true},{"functionName":"Function.call$0","ranges":[{"startOffset":1079188,"endOffset":1079223,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$1","ranges":[{"startOffset":1079255,"endOffset":1079292,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$2","ranges":[{"startOffset":1079324,"endOffset":1079367,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$3$3","ranges":[{"startOffset":1079401,"endOffset":1079450,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$2$2","ranges":[{"startOffset":1079484,"endOffset":1079527,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$1$1","ranges":[{"startOffset":1079561,"endOffset":1079598,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$2$1","ranges":[{"startOffset":1079632,"endOffset":1079669,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$3","ranges":[{"startOffset":1079701,"endOffset":1079750,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$4","ranges":[{"startOffset":1079782,"endOffset":1079837,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$3$1","ranges":[{"startOffset":1079871,"endOffset":1079908,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$2$3","ranges":[{"startOffset":1079942,"endOffset":1079991,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$1$2","ranges":[{"startOffset":1080025,"endOffset":1080068,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$5","ranges":[{"startOffset":1080100,"endOffset":1080161,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$3$4","ranges":[{"startOffset":1080195,"endOffset":1080250,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$2$4","ranges":[{"startOffset":1080284,"endOffset":1080339,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$1$4","ranges":[{"startOffset":1080373,"endOffset":1080428,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$3$6","ranges":[{"startOffset":1080462,"endOffset":1080529,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$2$5","ranges":[{"startOffset":1080563,"endOffset":1080624,"count":0}],"isBlockCoverage":false},{"functionName":"Function.call$2$0","ranges":[{"startOffset":1080658,"endOffset":1080693,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1080759,"endOffset":1081298,"count":1},{"startOffset":1080821,"endOffset":1080919,"count":0},{"startOffset":1080974,"endOffset":1081297,"count":0}],"isBlockCoverage":true},{"functionName":"onLoad","ranges":[{"startOffset":1081021,"endOffset":1081191,"count":0}],"isBlockCoverage":false},{"functionName":"","ranges":[{"startOffset":1081300,"endOffset":1081476,"count":1},{"startOffset":1081418,"endOffset":1081445,"count":0}],"isBlockCoverage":true}]},{"scriptId":"32","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":284,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":283,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff_startsWith$20","ranges":[{"startOffset":82,"endOffset":281,"count":0}],"isBlockCoverage":false}]},{"scriptId":"33","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":271,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":270,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff__onPause$01","ranges":[{"startOffset":82,"endOffset":268,"count":0}],"isBlockCoverage":false}]},{"scriptId":"34","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":272,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":271,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff__onResume$02","ranges":[{"startOffset":82,"endOffset":269,"count":0}],"isBlockCoverage":false}]},{"scriptId":"35","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":277,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":276,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff_add$13","ranges":[{"startOffset":82,"endOffset":274,"count":0}],"isBlockCoverage":false}]},{"scriptId":"36","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":271,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":270,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff_addError$24","ranges":[{"startOffset":82,"endOffset":268,"count":0}],"isBlockCoverage":false}]},{"scriptId":"37","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":271,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":270,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff_complete$15","ranges":[{"startOffset":82,"endOffset":268,"count":1}],"isBlockCoverage":true}]},{"scriptId":"38","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":271,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":270,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff_complete$16","ranges":[{"startOffset":82,"endOffset":268,"count":1}],"isBlockCoverage":true}]},{"scriptId":"39","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":277,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":276,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff__completeError$27","ranges":[{"startOffset":82,"endOffset":274,"count":1}],"isBlockCoverage":true}]},{"scriptId":"40","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":277,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":276,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff_add$18","ranges":[{"startOffset":82,"endOffset":274,"count":1}],"isBlockCoverage":true}]},{"scriptId":"41","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":271,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":270,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff_addError$29","ranges":[{"startOffset":82,"endOffset":268,"count":1}],"isBlockCoverage":true}]},{"scriptId":"42","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":280,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":279,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff_close$010","ranges":[{"startOffset":82,"endOffset":277,"count":1}],"isBlockCoverage":true}]},{"scriptId":"43","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":268,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":267,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff__add$111","ranges":[{"startOffset":82,"endOffset":265,"count":1}],"isBlockCoverage":true}]},{"scriptId":"44","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":280,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":279,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff__async$_addError$212","ranges":[{"startOffset":82,"endOffset":277,"count":1}],"isBlockCoverage":true}]},{"scriptId":"45","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":270,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":269,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff__close$013","ranges":[{"startOffset":82,"endOffset":267,"count":1}],"isBlockCoverage":true}]},{"scriptId":"46","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":272,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":271,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff__onPause$014","ranges":[{"startOffset":82,"endOffset":269,"count":0}],"isBlockCoverage":false}]},{"scriptId":"47","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":273,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":272,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff__onResume$015","ranges":[{"startOffset":82,"endOffset":270,"count":1}],"isBlockCoverage":true}]},{"scriptId":"48","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":278,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":277,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff_add$116","ranges":[{"startOffset":82,"endOffset":275,"count":1}],"isBlockCoverage":true}]},{"scriptId":"49","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":272,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":271,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff__onPause$017","ranges":[{"startOffset":82,"endOffset":269,"count":0}],"isBlockCoverage":false}]},{"scriptId":"50","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":273,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":272,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff__onResume$018","ranges":[{"startOffset":82,"endOffset":270,"count":0}],"isBlockCoverage":false}]},{"scriptId":"51","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":273,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":272,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff__sendDone$019","ranges":[{"startOffset":82,"endOffset":270,"count":0}],"isBlockCoverage":false}]},{"scriptId":"52","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":283,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":282,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff_contains$120","ranges":[{"startOffset":82,"endOffset":280,"count":0}],"isBlockCoverage":false}]},{"scriptId":"53","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":280,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":279,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff_close$021","ranges":[{"startOffset":82,"endOffset":277,"count":0}],"isBlockCoverage":false}]},{"scriptId":"54","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":273,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":272,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff__onListen$022","ranges":[{"startOffset":82,"endOffset":270,"count":0}],"isBlockCoverage":false}]},{"scriptId":"55","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":282,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":281,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff__onCancelBroadcast$023","ranges":[{"startOffset":82,"endOffset":279,"count":0}],"isBlockCoverage":false}]},{"scriptId":"56","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":283,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":282,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff_contains$124","ranges":[{"startOffset":82,"endOffset":280,"count":0}],"isBlockCoverage":false}]},{"scriptId":"57","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":279,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":278,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff__recursiveMatch$425","ranges":[{"startOffset":82,"endOffset":276,"count":0}],"isBlockCoverage":false}]},{"scriptId":"58","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":288,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":287,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff_message$2$color26","ranges":[{"startOffset":82,"endOffset":285,"count":0}],"isBlockCoverage":false}]},{"scriptId":"59","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":309,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":308,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff__stack_zone_specification$_registerCallback$1$427","ranges":[{"startOffset":82,"endOffset":306,"count":1}],"isBlockCoverage":true}]},{"scriptId":"60","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":314,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":313,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff__stack_zone_specification$_registerUnaryCallback$2$428","ranges":[{"startOffset":82,"endOffset":311,"count":1}],"isBlockCoverage":true}]},{"scriptId":"61","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":315,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":314,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff__stack_zone_specification$_registerBinaryCallback$3$429","ranges":[{"startOffset":82,"endOffset":312,"count":1}],"isBlockCoverage":true}]},{"scriptId":"62","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":304,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":303,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff__stack_zone_specification$_errorCallback$530","ranges":[{"startOffset":82,"endOffset":301,"count":1}],"isBlockCoverage":true}]},{"scriptId":"63","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":272,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":271,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff_addError$231","ranges":[{"startOffset":82,"endOffset":269,"count":1}],"isBlockCoverage":true}]},{"scriptId":"64","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":273,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":272,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff__addError$232","ranges":[{"startOffset":82,"endOffset":270,"count":1}],"isBlockCoverage":true}]},{"scriptId":"65","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":280,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":279,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff_close$033","ranges":[{"startOffset":82,"endOffset":277,"count":0}],"isBlockCoverage":false}]},{"scriptId":"66","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":282,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":281,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff__closeInnerChannel$034","ranges":[{"startOffset":82,"endOffset":279,"count":1}],"isBlockCoverage":true}]},{"scriptId":"67","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":279,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":278,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff__invoker$_onRun$035","ranges":[{"startOffset":82,"endOffset":276,"count":1}],"isBlockCoverage":true}]},{"scriptId":"68","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":277,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":276,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff__runTearDowns$036","ranges":[{"startOffset":82,"endOffset":274,"count":1}],"isBlockCoverage":true}]},{"scriptId":"69","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":267,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":266,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff_run$037","ranges":[{"startOffset":82,"endOffset":264,"count":0}],"isBlockCoverage":false}]},{"scriptId":"70","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":282,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":281,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff_message$138","ranges":[{"startOffset":82,"endOffset":279,"count":0}],"isBlockCoverage":false}]},{"scriptId":"71","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":267,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":266,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff_run$039","ranges":[{"startOffset":82,"endOffset":264,"count":0}],"isBlockCoverage":false}]},{"scriptId":"72","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":278,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":277,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff__onTestStarted$140","ranges":[{"startOffset":82,"endOffset":275,"count":0}],"isBlockCoverage":false}]},{"scriptId":"73","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":281,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":280,"count":1}],"isBlockCoverage":true},{"functionName":"tearOff__expanded$_onDone$141","ranges":[{"startOffset":82,"endOffset":278,"count":0}],"isBlockCoverage":false}]},{"scriptId":"74","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":62,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":61,"count":1}],"isBlockCoverage":true}]},{"scriptId":"75","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":92,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":91,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":32,"endOffset":89,"count":1},{"startOffset":87,"endOffset":88,"count":0}],"isBlockCoverage":true}]},{"scriptId":"76","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":62,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":61,"count":1}],"isBlockCoverage":true}]},{"scriptId":"77","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":86,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":85,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":32,"endOffset":83,"count":0}],"isBlockCoverage":false}]},{"scriptId":"78","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":62,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":61,"count":1}],"isBlockCoverage":true}]},{"scriptId":"79","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":106,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":105,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":32,"endOffset":103,"count":0}],"isBlockCoverage":false}]},{"scriptId":"80","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":62,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":61,"count":1}],"isBlockCoverage":true}]},{"scriptId":"81","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":86,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":85,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":32,"endOffset":83,"count":0}],"isBlockCoverage":false}]},{"scriptId":"82","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":62,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":61,"count":1}],"isBlockCoverage":true}]},{"scriptId":"83","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":92,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":91,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":32,"endOffset":89,"count":0}],"isBlockCoverage":false}]},{"scriptId":"84","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":64,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":63,"count":1}],"isBlockCoverage":true}]},{"scriptId":"85","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":93,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":92,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":32,"endOffset":90,"count":1},{"startOffset":87,"endOffset":89,"count":0}],"isBlockCoverage":true}]},{"scriptId":"86","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":64,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":63,"count":1}],"isBlockCoverage":true}]},{"scriptId":"87","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":84,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":83,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":32,"endOffset":81,"count":0}],"isBlockCoverage":false}]},{"scriptId":"88","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":64,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":63,"count":1}],"isBlockCoverage":true}]},{"scriptId":"89","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":89,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":88,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":32,"endOffset":86,"count":0}],"isBlockCoverage":false}]},{"scriptId":"90","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":64,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":63,"count":1}],"isBlockCoverage":true}]},{"scriptId":"91","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":99,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":98,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":32,"endOffset":96,"count":1}],"isBlockCoverage":true}]},{"scriptId":"92","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":64,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":63,"count":1}],"isBlockCoverage":true}]},{"scriptId":"93","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":96,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":95,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":32,"endOffset":93,"count":0}],"isBlockCoverage":false}]},{"scriptId":"94","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":64,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":63,"count":1}],"isBlockCoverage":true}]},{"scriptId":"95","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":80,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":79,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":32,"endOffset":77,"count":1}],"isBlockCoverage":true}]},{"scriptId":"96","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":64,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":63,"count":1}],"isBlockCoverage":true}]},{"scriptId":"97","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":96,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":95,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":32,"endOffset":93,"count":0}],"isBlockCoverage":false}]},{"scriptId":"98","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":64,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":63,"count":1}],"isBlockCoverage":true}]},{"scriptId":"99","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":91,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":90,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":32,"endOffset":88,"count":1},{"startOffset":85,"endOffset":87,"count":0}],"isBlockCoverage":true}]},{"scriptId":"100","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":64,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":63,"count":1}],"isBlockCoverage":true}]},{"scriptId":"101","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":105,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":104,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":32,"endOffset":102,"count":1}],"isBlockCoverage":true}]},{"scriptId":"102","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":64,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":63,"count":1}],"isBlockCoverage":true}]},{"scriptId":"103","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":84,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":83,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":32,"endOffset":81,"count":0}],"isBlockCoverage":false}]},{"scriptId":"104","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":64,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":63,"count":1}],"isBlockCoverage":true}]},{"scriptId":"105","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":132,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":131,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":32,"endOffset":129,"count":0}],"isBlockCoverage":false}]},{"scriptId":"106","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":64,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":63,"count":1}],"isBlockCoverage":true}]},{"scriptId":"107","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":151,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":150,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":32,"endOffset":148,"count":1}],"isBlockCoverage":true}]},{"scriptId":"108","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":64,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":63,"count":1}],"isBlockCoverage":true}]},{"scriptId":"109","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":137,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":136,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":32,"endOffset":134,"count":1}],"isBlockCoverage":true}]},{"scriptId":"110","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":64,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":63,"count":1}],"isBlockCoverage":true}]},{"scriptId":"111","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":146,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":145,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":32,"endOffset":143,"count":1}],"isBlockCoverage":true}]},{"scriptId":"112","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":64,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":63,"count":1}],"isBlockCoverage":true}]},{"scriptId":"113","url":"","functions":[{"functionName":"","ranges":[{"startOffset":0,"endOffset":103,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":1,"endOffset":102,"count":1}],"isBlockCoverage":true},{"functionName":"","ranges":[{"startOffset":32,"endOffset":100,"count":1}],"isBlockCoverage":true}]}]
\ No newline at end of file
diff --git a/pkgs/coverage/test/test_files/function_coverage_app.dart b/pkgs/coverage/test/test_files/function_coverage_app.dart
new file mode 100644
index 0000000..c4868f9
--- /dev/null
+++ b/pkgs/coverage/test/test_files/function_coverage_app.dart
@@ -0,0 +1,58 @@
+// Copyright (c) 2022, 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 'test_library.dart';
+
+int normalFunction() {
+ return 123;
+}
+
+abstract class BaseClass {
+ int abstractMethod();
+}
+
+class SomeClass extends BaseClass {
+ SomeClass() : x = 123;
+
+ // Creates an implicit getter and setter that should be ignored.
+ int x;
+
+ int normalMethod() {
+ return 123;
+ }
+
+ static int staticMethod() {
+ return 123;
+ }
+
+ @override
+ int abstractMethod() {
+ return 123;
+ }
+}
+
+extension SomeExtension on SomeClass {
+ int extensionMethod() {
+ return 123;
+ }
+}
+
+class OtherClass {
+ int otherMethod() {
+ return 123;
+ }
+}
+
+void main() {
+ print(normalFunction());
+ print(SomeClass().normalMethod());
+ print(SomeClass.staticMethod());
+ print(SomeClass().extensionMethod());
+ print(SomeClass().abstractMethod());
+ print(OtherClass().otherMethod());
+ print(libraryFunction());
+ print(otherLibraryFunction());
+}
+
+// ignore_for_file: unreachable_from_main
diff --git a/pkgs/coverage/test/test_files/main_test.js b/pkgs/coverage/test/test_files/main_test.js
new file mode 100644
index 0000000..4c4fb3e
--- /dev/null
+++ b/pkgs/coverage/test/test_files/main_test.js
@@ -0,0 +1,26570 @@
+// Generated by dart2js (fast startup emitter, strong), the Dart to JavaScript compiler version: 2.8.0-292505767.
+// The code supports the following hooks:
+// dartPrint(message):
+// if this function is defined it is called instead of the Dart [print]
+// method.
+//
+// dartMainRunner(main, args):
+// if this function is defined, the Dart [main] method will not be invoked
+// directly. Instead, a closure that will invoke [main], and its arguments
+// [args] is passed to [dartMainRunner].
+//
+// dartDeferredLibraryLoader(uri, successCallback, errorCallback):
+// if this function is defined, it will be called when a deferred library
+// is loaded. It should load and eval the javascript of `uri`, and call
+// successCallback. If it fails to do so, it should call errorCallback with
+// an error.
+//
+// dartCallInstrumentation(id, qualifiedName):
+// if this function is defined, it will be called at each entry of a
+// method or constructor. Used only when compiling programs with
+// --experiment-call-instrumentation.
+(function dartProgram() {
+ function copyProperties(from, to) {
+ var keys = Object.keys(from);
+ for (var i = 0; i < keys.length; i++) {
+ var key = keys[i];
+ to[key] = from[key];
+ }
+ }
+ var supportsDirectProtoAccess = function() {
+ var cls = function() {
+ };
+ cls.prototype = {p: {}};
+ var object = new cls();
+ if (!(object.__proto__ && object.__proto__.p === cls.prototype.p))
+ return false;
+ try {
+ if (typeof navigator != "undefined" && typeof navigator.userAgent == "string" && navigator.userAgent.indexOf("Chrome/") >= 0)
+ return true;
+ if (typeof version == "function" && version.length == 0) {
+ var v = version();
+ if (/^\d+\.\d+\.\d+\.\d+$/.test(v))
+ return true;
+ }
+ } catch (_) {
+ }
+ return false;
+ }();
+ function setFunctionNamesIfNecessary(holders) {
+ function t() {
+ }
+ ;
+ if (typeof t.name == "string")
+ return;
+ for (var i = 0; i < holders.length; i++) {
+ var holder = holders[i];
+ var keys = Object.keys(holder);
+ for (var j = 0; j < keys.length; j++) {
+ var key = keys[j];
+ var f = holder[key];
+ if (typeof f == 'function')
+ f.name = key;
+ }
+ }
+ }
+ function inherit(cls, sup) {
+ cls.prototype.constructor = cls;
+ cls.prototype["$is" + cls.name] = cls;
+ if (sup != null) {
+ if (supportsDirectProtoAccess) {
+ cls.prototype.__proto__ = sup.prototype;
+ return;
+ }
+ var clsPrototype = Object.create(sup.prototype);
+ copyProperties(cls.prototype, clsPrototype);
+ cls.prototype = clsPrototype;
+ }
+ }
+ function inheritMany(sup, classes) {
+ for (var i = 0; i < classes.length; i++)
+ inherit(classes[i], sup);
+ }
+ function mixin(cls, mixin) {
+ copyProperties(mixin.prototype, cls.prototype);
+ cls.prototype.constructor = cls;
+ }
+ function lazy(holder, name, getterName, initializer) {
+ var uninitializedSentinel = holder;
+ holder[name] = uninitializedSentinel;
+ holder[getterName] = function() {
+ holder[getterName] = function() {
+ H.throwCyclicInit(name);
+ };
+ var result;
+ var sentinelInProgress = initializer;
+ try {
+ if (holder[name] === uninitializedSentinel) {
+ result = holder[name] = sentinelInProgress;
+ result = holder[name] = initializer();
+ } else
+ result = holder[name];
+ } finally {
+ if (result === sentinelInProgress)
+ holder[name] = null;
+ holder[getterName] = function() {
+ return this[name];
+ };
+ }
+ return result;
+ };
+ }
+ function makeConstList(list) {
+ list.immutable$list = Array;
+ list.fixed$length = Array;
+ return list;
+ }
+ function convertToFastObject(properties) {
+ function t() {
+ }
+ t.prototype = properties;
+ new t();
+ return properties;
+ }
+ function convertAllToFastObject(arrayOfObjects) {
+ for (var i = 0; i < arrayOfObjects.length; ++i)
+ convertToFastObject(arrayOfObjects[i]);
+ }
+ var functionCounter = 0;
+ function tearOffGetter(funcs, applyTrampolineIndex, reflectionInfo, name, isIntercepted) {
+ return isIntercepted ? new Function("funcs", "applyTrampolineIndex", "reflectionInfo", "name", "H", "c", "return function tearOff_" + name + functionCounter++ + "(receiver) {" + "if (c === null) c = " + "H.closureFromTearOff" + "(" + "this, funcs, applyTrampolineIndex, reflectionInfo, false, true, name);" + "return new c(this, funcs[0], receiver, name);" + "}")(funcs, applyTrampolineIndex, reflectionInfo, name, H, null) : new Function("funcs", "applyTrampolineIndex", "reflectionInfo", "name", "H", "c", "return function tearOff_" + name + functionCounter++ + "() {" + "if (c === null) c = " + "H.closureFromTearOff" + "(" + "this, funcs, applyTrampolineIndex, reflectionInfo, false, false, name);" + "return new c(this, funcs[0], null, name);" + "}")(funcs, applyTrampolineIndex, reflectionInfo, name, H, null);
+ }
+ function tearOff(funcs, applyTrampolineIndex, reflectionInfo, isStatic, name, isIntercepted) {
+ var cache = null;
+ return isStatic ? function() {
+ if (cache === null)
+ cache = H.closureFromTearOff(this, funcs, applyTrampolineIndex, reflectionInfo, true, false, name).prototype;
+ return cache;
+ } : tearOffGetter(funcs, applyTrampolineIndex, reflectionInfo, name, isIntercepted);
+ }
+ var typesOffset = 0;
+ function installTearOff(container, getterName, isStatic, isIntercepted, requiredParameterCount, optionalParameterDefaultValues, callNames, funsOrNames, funType, applyIndex) {
+ var funs = [];
+ for (var i = 0; i < funsOrNames.length; i++) {
+ var fun = funsOrNames[i];
+ if (typeof fun == 'string')
+ fun = container[fun];
+ fun.$callName = callNames[i];
+ funs.push(fun);
+ }
+ var fun = funs[0];
+ fun.$requiredArgCount = requiredParameterCount;
+ fun.$defaultValues = optionalParameterDefaultValues;
+ var reflectionInfo = funType;
+ if (typeof reflectionInfo == "number")
+ reflectionInfo += typesOffset;
+ var name = funsOrNames[0];
+ fun.$stubName = name;
+ var getterFunction = tearOff(funs, applyIndex || 0, reflectionInfo, isStatic, name, isIntercepted);
+ container[getterName] = getterFunction;
+ if (isStatic)
+ fun.$tearOff = getterFunction;
+ }
+ function installStaticTearOff(container, getterName, requiredParameterCount, optionalParameterDefaultValues, callNames, funsOrNames, funType, applyIndex) {
+ return installTearOff(container, getterName, true, false, requiredParameterCount, optionalParameterDefaultValues, callNames, funsOrNames, funType, applyIndex);
+ }
+ function installInstanceTearOff(container, getterName, isIntercepted, requiredParameterCount, optionalParameterDefaultValues, callNames, funsOrNames, funType, applyIndex) {
+ return installTearOff(container, getterName, false, isIntercepted, requiredParameterCount, optionalParameterDefaultValues, callNames, funsOrNames, funType, applyIndex);
+ }
+ function setOrUpdateInterceptorsByTag(newTags) {
+ var tags = init.interceptorsByTag;
+ if (!tags) {
+ init.interceptorsByTag = newTags;
+ return;
+ }
+ copyProperties(newTags, tags);
+ }
+ function setOrUpdateLeafTags(newTags) {
+ var tags = init.leafTags;
+ if (!tags) {
+ init.leafTags = newTags;
+ return;
+ }
+ copyProperties(newTags, tags);
+ }
+ function updateTypes(newTypes) {
+ var types = init.types;
+ var length = types.length;
+ types.push.apply(types, newTypes);
+ return length;
+ }
+ function updateHolder(holder, newHolder) {
+ copyProperties(newHolder, holder);
+ return holder;
+ }
+ var hunkHelpers = function() {
+ var mkInstance = function(isIntercepted, requiredParameterCount, optionalParameterDefaultValues, callNames, applyIndex) {
+ return function(container, getterName, name, funType) {
+ return installInstanceTearOff(container, getterName, isIntercepted, requiredParameterCount, optionalParameterDefaultValues, callNames, [name], funType, applyIndex);
+ };
+ },
+ mkStatic = function(requiredParameterCount, optionalParameterDefaultValues, callNames, applyIndex) {
+ return function(container, getterName, name, funType) {
+ return installStaticTearOff(container, getterName, requiredParameterCount, optionalParameterDefaultValues, callNames, [name], funType, applyIndex);
+ };
+ };
+ return {inherit: inherit, inheritMany: inheritMany, mixin: mixin, installStaticTearOff: installStaticTearOff, installInstanceTearOff: installInstanceTearOff, _instance_0u: mkInstance(0, 0, null, ["call$0"], 0), _instance_1u: mkInstance(0, 1, null, ["call$1"], 0), _instance_2u: mkInstance(0, 2, null, ["call$2"], 0), _instance_0i: mkInstance(1, 0, null, ["call$0"], 0), _instance_1i: mkInstance(1, 1, null, ["call$1"], 0), _instance_2i: mkInstance(1, 2, null, ["call$2"], 0), _static_0: mkStatic(0, null, ["call$0"], 0), _static_1: mkStatic(1, null, ["call$1"], 0), _static_2: mkStatic(2, null, ["call$2"], 0), makeConstList: makeConstList, lazy: lazy, updateHolder: updateHolder, convertToFastObject: convertToFastObject, setFunctionNamesIfNecessary: setFunctionNamesIfNecessary, updateTypes: updateTypes, setOrUpdateInterceptorsByTag: setOrUpdateInterceptorsByTag, setOrUpdateLeafTags: setOrUpdateLeafTags};
+ }();
+ function initializeDeferredHunk(hunk) {
+ typesOffset = init.types.length;
+ hunk(hunkHelpers, init, holders, $);
+ }
+ function getGlobalFromName(name) {
+ for (var i = 0; i < holders.length; i++) {
+ if (holders[i] == C)
+ continue;
+ if (holders[i][name])
+ return holders[i][name];
+ }
+ }
+ var C = {},
+ H = {JS_CONST: function JS_CONST() {
+ },
+ CastIterable_CastIterable: function(source, $S, $T) {
+ if ($S._eval$1("EfficientLengthIterable<0>")._is(source))
+ return new H._EfficientLengthCastIterable(source, $S._eval$1("@<0>")._bind$1($T)._eval$1("_EfficientLengthCastIterable<1,2>"));
+ return new H.CastIterable(source, $S._eval$1("@<0>")._bind$1($T)._eval$1("CastIterable<1,2>"));
+ },
+ hexDigitValue: function(char) {
+ var digit, letter;
+ H.assertHelper(char <= 65535);
+ digit = char ^ 48;
+ if (digit <= 9)
+ return digit;
+ letter = char | 32;
+ if (97 <= letter && letter <= 102)
+ return letter - 87;
+ return -1;
+ },
+ SubListIterable$: function(_iterable, _start, _endOrLength, $E) {
+ P.RangeError_checkNotNegative(_start, "start");
+ if (_endOrLength != null) {
+ P.RangeError_checkNotNegative(_endOrLength, "end");
+ if (_start > _endOrLength)
+ H.throwExpression(P.RangeError$range(_start, 0, _endOrLength, "start", null));
+ }
+ return new H.SubListIterable(_iterable, _start, _endOrLength, $E._eval$1("SubListIterable<0>"));
+ },
+ MappedIterable_MappedIterable: function(iterable, $function, $S, $T) {
+ if (type$.EfficientLengthIterable_dynamic._is(iterable))
+ return new H.EfficientLengthMappedIterable(iterable, $function, $S._eval$1("@<0>")._bind$1($T)._eval$1("EfficientLengthMappedIterable<1,2>"));
+ return new H.MappedIterable(iterable, $function, $S._eval$1("@<0>")._bind$1($T)._eval$1("MappedIterable<1,2>"));
+ },
+ IterableElementError_noElement: function() {
+ return new P.StateError("No element");
+ },
+ IterableElementError_tooMany: function() {
+ return new P.StateError("Too many elements");
+ },
+ IterableElementError_tooFew: function() {
+ return new P.StateError("Too few elements");
+ },
+ _CastIterableBase: function _CastIterableBase() {
+ },
+ CastIterator: function CastIterator(t0, t1) {
+ this._source = t0;
+ this.$ti = t1;
+ },
+ CastIterable: function CastIterable(t0, t1) {
+ this._source = t0;
+ this.$ti = t1;
+ },
+ _EfficientLengthCastIterable: function _EfficientLengthCastIterable(t0, t1) {
+ this._source = t0;
+ this.$ti = t1;
+ },
+ CastMap: function CastMap(t0, t1) {
+ this._source = t0;
+ this.$ti = t1;
+ },
+ CastMap_forEach_closure: function CastMap_forEach_closure(t0, t1) {
+ this.$this = t0;
+ this.f = t1;
+ },
+ CodeUnits: function CodeUnits(t0) {
+ this._string = t0;
+ },
+ EfficientLengthIterable: function EfficientLengthIterable() {
+ },
+ ListIterable: function ListIterable() {
+ },
+ SubListIterable: function SubListIterable(t0, t1, t2, t3) {
+ var _ = this;
+ _.__internal$_iterable = t0;
+ _.__internal$_start = t1;
+ _._endOrLength = t2;
+ _.$ti = t3;
+ },
+ ListIterator: function ListIterator(t0, t1, t2) {
+ var _ = this;
+ _.__internal$_iterable = t0;
+ _.__internal$_length = t1;
+ _.__internal$_index = 0;
+ _.__internal$_current = null;
+ _.$ti = t2;
+ },
+ MappedIterable: function MappedIterable(t0, t1, t2) {
+ this.__internal$_iterable = t0;
+ this._f = t1;
+ this.$ti = t2;
+ },
+ EfficientLengthMappedIterable: function EfficientLengthMappedIterable(t0, t1, t2) {
+ this.__internal$_iterable = t0;
+ this._f = t1;
+ this.$ti = t2;
+ },
+ MappedIterator: function MappedIterator(t0, t1, t2) {
+ var _ = this;
+ _.__internal$_current = null;
+ _._iterator = t0;
+ _._f = t1;
+ _.$ti = t2;
+ },
+ MappedListIterable: function MappedListIterable(t0, t1, t2) {
+ this._source = t0;
+ this._f = t1;
+ this.$ti = t2;
+ },
+ WhereIterable: function WhereIterable(t0, t1, t2) {
+ this.__internal$_iterable = t0;
+ this._f = t1;
+ this.$ti = t2;
+ },
+ WhereIterator: function WhereIterator(t0, t1, t2) {
+ this._iterator = t0;
+ this._f = t1;
+ this.$ti = t2;
+ },
+ ExpandIterable: function ExpandIterable(t0, t1, t2) {
+ this.__internal$_iterable = t0;
+ this._f = t1;
+ this.$ti = t2;
+ },
+ ExpandIterator: function ExpandIterator(t0, t1, t2, t3) {
+ var _ = this;
+ _._iterator = t0;
+ _._f = t1;
+ _._currentExpansion = t2;
+ _.__internal$_current = null;
+ _.$ti = t3;
+ },
+ SkipWhileIterable: function SkipWhileIterable(t0, t1, t2) {
+ this.__internal$_iterable = t0;
+ this._f = t1;
+ this.$ti = t2;
+ },
+ SkipWhileIterator: function SkipWhileIterator(t0, t1, t2) {
+ var _ = this;
+ _._iterator = t0;
+ _._f = t1;
+ _._hasSkipped = false;
+ _.$ti = t2;
+ },
+ EmptyIterator: function EmptyIterator(t0) {
+ this.$ti = t0;
+ },
+ FixedLengthListMixin: function FixedLengthListMixin() {
+ },
+ UnmodifiableListMixin: function UnmodifiableListMixin() {
+ },
+ UnmodifiableListBase: function UnmodifiableListBase() {
+ },
+ ReversedListIterable: function ReversedListIterable(t0, t1) {
+ this._source = t0;
+ this.$ti = t1;
+ },
+ Symbol: function Symbol(t0) {
+ this.__internal$_name = t0;
+ },
+ ConstantMap__throwUnmodifiable: function() {
+ throw H.wrapException(P.UnsupportedError$("Cannot modify unmodifiable Map"));
+ },
+ instantiate1: function(f, T1) {
+ var t1 = new H.Instantiation1(f, T1._eval$1("Instantiation1<0>"));
+ t1.Instantiation$1(f);
+ return t1;
+ },
+ unminifyOrTag: function(rawClassName) {
+ var preserved = H.unmangleGlobalNameIfPreservedAnyways(rawClassName);
+ if (typeof preserved == "string")
+ return preserved;
+ return rawClassName;
+ },
+ isJsIndexable: function(object, record) {
+ var result;
+ if (record != null) {
+ result = record.x;
+ if (result != null)
+ return result;
+ }
+ return type$.JavaScriptIndexingBehavior_dynamic._is(object);
+ },
+ S: function(value) {
+ var res;
+ if (typeof value == "string")
+ return value;
+ if (typeof value == "number") {
+ if (value !== 0)
+ return "" + value;
+ } else if (true === value)
+ return "true";
+ else if (false === value)
+ return "false";
+ else if (value == null)
+ return "null";
+ res = J.toString$0$(value);
+ if (typeof res != "string")
+ throw H.wrapException(H.argumentErrorValue(value));
+ return res;
+ },
+ Primitives_objectHashCode: function(object) {
+ var hash = object.$identityHash;
+ if (hash == null) {
+ hash = Math.random() * 0x3fffffff | 0;
+ object.$identityHash = hash;
+ }
+ return hash;
+ },
+ Primitives_parseInt: function(source, radix) {
+ var match, decimalMatch, maxCharCode, digitsPart, t1, i, _null = null;
+ if (typeof source != "string")
+ H.throwExpression(H.argumentErrorValue(source));
+ match = /^\s*[+-]?((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$/i.exec(source);
+ if (match == null)
+ return _null;
+ if (3 >= match.length)
+ return H.ioore(match, 3);
+ decimalMatch = H._checkStringNullable(match[3]);
+ if (radix == null) {
+ if (decimalMatch != null)
+ return parseInt(source, 10);
+ if (match[2] != null)
+ return parseInt(source, 16);
+ return _null;
+ }
+ if (radix < 2 || radix > 36)
+ throw H.wrapException(P.RangeError$range(radix, 2, 36, "radix", _null));
+ if (radix === 10 && decimalMatch != null)
+ return parseInt(source, 10);
+ if (radix < 10 || decimalMatch == null) {
+ maxCharCode = radix <= 10 ? 47 + radix : 86 + radix;
+ H.assertHelper(typeof match[1] == "string");
+ digitsPart = match[1];
+ for (t1 = digitsPart.length, i = 0; i < t1; ++i)
+ if ((C.JSString_methods._codeUnitAt$1(digitsPart, i) | 32) > maxCharCode)
+ return _null;
+ }
+ return parseInt(source, radix);
+ },
+ Primitives_objectTypeName: function(object) {
+ var t1 = H.Primitives__objectTypeNameNewRti(object);
+ return t1;
+ },
+ Primitives__objectTypeNameNewRti: function(object) {
+ var dispatchName, $constructor, constructorName;
+ if (object instanceof P.Object)
+ return H._rtiToString(H.instanceType(object), null);
+ if (J.getInterceptor$(object) === C.Interceptor_methods || type$.UnknownJavaScriptObject._is(object)) {
+ dispatchName = C.C_JS_CONST(object);
+ if (H.Primitives__saneNativeClassName(dispatchName))
+ return dispatchName;
+ $constructor = object.constructor;
+ if (typeof $constructor == "function") {
+ constructorName = $constructor.name;
+ if (typeof constructorName == "string" && H.Primitives__saneNativeClassName(constructorName))
+ return constructorName;
+ }
+ }
+ return H._rtiToString(H.instanceType(object), null);
+ },
+ Primitives__saneNativeClassName: function($name) {
+ var t1 = $name !== "Object" && $name !== "";
+ return t1;
+ },
+ Primitives_dateNow: function() {
+ return Date.now();
+ },
+ Primitives_initTicker: function() {
+ var $window, performance;
+ if ($.Primitives_timerFrequency != null)
+ return;
+ $.Primitives_timerFrequency = 1000;
+ $.Primitives_timerTicks = H._js_helper_Primitives_dateNow$closure();
+ if (typeof window == "undefined")
+ return;
+ $window = window;
+ if ($window == null)
+ return;
+ performance = $window.performance;
+ if (performance == null)
+ return;
+ if (typeof performance.now != "function")
+ return;
+ $.Primitives_timerFrequency = 1000000;
+ $.Primitives_timerTicks = new H.Primitives_initTicker_closure(performance);
+ },
+ Primitives_currentUri: function() {
+ if (!!self.location)
+ return self.location.href;
+ return null;
+ },
+ Primitives__fromCharCodeApply: function(array) {
+ var result, i, i0, chunkEnd,
+ end = J.get$length$asx(array);
+ if (end <= 500)
+ return String.fromCharCode.apply(null, array);
+ for (result = "", i = 0; i < end; i = i0) {
+ i0 = i + 500;
+ chunkEnd = i0 < end ? i0 : end;
+ result += String.fromCharCode.apply(null, array.slice(i, chunkEnd));
+ }
+ return result;
+ },
+ Primitives_stringFromCodePoints: function(codePoints) {
+ var t1, i,
+ a = H.setRuntimeTypeInfo([], type$.JSArray_int);
+ for (t1 = J.get$iterator$ax(type$.Iterable_dynamic._check(codePoints)); t1.moveNext$0();) {
+ i = t1.get$current();
+ if (!H._isInt(i))
+ throw H.wrapException(H.argumentErrorValue(i));
+ if (i <= 65535)
+ C.JSArray_methods.add$1(a, i);
+ else if (i <= 1114111) {
+ C.JSArray_methods.add$1(a, 55296 + (C.JSInt_methods._shrOtherPositive$1(i - 65536, 10) & 1023));
+ C.JSArray_methods.add$1(a, 56320 + (i & 1023));
+ } else
+ throw H.wrapException(H.argumentErrorValue(i));
+ }
+ return H.Primitives__fromCharCodeApply(a);
+ },
+ Primitives_stringFromCharCodes: function(charCodes) {
+ var t1, i;
+ for (type$.Iterable_dynamic._check(charCodes), t1 = J.get$iterator$ax(charCodes); t1.moveNext$0();) {
+ i = t1.get$current();
+ if (!H._isInt(i))
+ throw H.wrapException(H.argumentErrorValue(i));
+ if (i < 0)
+ throw H.wrapException(H.argumentErrorValue(i));
+ if (i > 65535)
+ return H.Primitives_stringFromCodePoints(charCodes);
+ }
+ return H.Primitives__fromCharCodeApply(type$.List_dynamic._check(charCodes));
+ },
+ Primitives_stringFromNativeUint8List: function(charCodes, start, end) {
+ var i, result, i0, chunkEnd;
+ if (end <= 500 && start === 0 && end === charCodes.length)
+ return String.fromCharCode.apply(null, charCodes);
+ for (i = start, result = ""; i < end; i = i0) {
+ i0 = i + 500;
+ chunkEnd = i0 < end ? i0 : end;
+ result += String.fromCharCode.apply(null, charCodes.subarray(i, chunkEnd));
+ }
+ return result;
+ },
+ Primitives_stringFromCharCode: function(charCode) {
+ var bits;
+ if (typeof charCode !== "number")
+ return H.iae(charCode);
+ if (0 <= charCode) {
+ if (charCode <= 65535)
+ return String.fromCharCode(charCode);
+ if (charCode <= 1114111) {
+ bits = charCode - 65536;
+ return String.fromCharCode((55296 | C.JSInt_methods._shrOtherPositive$1(bits, 10)) >>> 0, 56320 | bits & 1023);
+ }
+ }
+ throw H.wrapException(P.RangeError$range(charCode, 0, 1114111, null, null));
+ },
+ Primitives_lazyAsJsDate: function(receiver) {
+ if (receiver.date === void 0)
+ receiver.date = new Date(receiver._value);
+ return receiver.date;
+ },
+ Primitives_getYear: function(receiver) {
+ var t1 = H.Primitives_lazyAsJsDate(receiver).getUTCFullYear() + 0;
+ return t1;
+ },
+ Primitives_getMonth: function(receiver) {
+ var t1 = H.Primitives_lazyAsJsDate(receiver).getUTCMonth() + 1;
+ return t1;
+ },
+ Primitives_getDay: function(receiver) {
+ var t1 = H.Primitives_lazyAsJsDate(receiver).getUTCDate() + 0;
+ return t1;
+ },
+ Primitives_getHours: function(receiver) {
+ var t1 = H.Primitives_lazyAsJsDate(receiver).getUTCHours() + 0;
+ return t1;
+ },
+ Primitives_getMinutes: function(receiver) {
+ var t1 = H.Primitives_lazyAsJsDate(receiver).getUTCMinutes() + 0;
+ return t1;
+ },
+ Primitives_getSeconds: function(receiver) {
+ var t1 = H.Primitives_lazyAsJsDate(receiver).getUTCSeconds() + 0;
+ return t1;
+ },
+ Primitives_getMilliseconds: function(receiver) {
+ var t1 = H.Primitives_lazyAsJsDate(receiver).getUTCMilliseconds() + 0;
+ return t1;
+ },
+ Primitives_getProperty: function(object, key) {
+ if (object == null || H._isBool(object) || typeof object == "number" || typeof object == "string")
+ throw H.wrapException(H.argumentErrorValue(object));
+ return object[key];
+ },
+ Primitives_setProperty: function(object, key, value) {
+ if (object == null || H._isBool(object) || typeof object == "number" || typeof object == "string")
+ throw H.wrapException(H.argumentErrorValue(object));
+ object[key] = value;
+ },
+ iae: function(argument) {
+ throw H.wrapException(H.argumentErrorValue(argument));
+ },
+ ioore: function(receiver, index) {
+ if (receiver == null)
+ J.get$length$asx(receiver);
+ throw H.wrapException(H.diagnoseIndexError(receiver, index));
+ },
+ diagnoseIndexError: function(indexable, index) {
+ var $length, t1, _s5_ = "index";
+ if (!H._isInt(index))
+ return new P.ArgumentError(true, index, _s5_, null);
+ $length = H._checkIntNullable(J.get$length$asx(indexable));
+ if (!(index < 0)) {
+ if (typeof $length !== "number")
+ return H.iae($length);
+ t1 = index >= $length;
+ } else
+ t1 = true;
+ if (t1)
+ return P.IndexError$(index, indexable, _s5_, null, $length);
+ return P.RangeError$value(index, _s5_);
+ },
+ diagnoseRangeError: function(start, end, $length) {
+ var _s13_ = "Invalid value";
+ if (start < 0 || start > $length)
+ return new P.RangeError(0, $length, true, start, "start", _s13_);
+ if (end != null)
+ if (end < start || end > $length)
+ return new P.RangeError(start, $length, true, end, "end", _s13_);
+ return new P.ArgumentError(true, end, "end", null);
+ },
+ argumentErrorValue: function(object) {
+ return new P.ArgumentError(true, object, null, null);
+ },
+ checkNum: function(value) {
+ if (typeof value != "number")
+ throw H.wrapException(H.argumentErrorValue(value));
+ return value;
+ },
+ wrapException: function(ex) {
+ var wrapper;
+ if (ex == null)
+ ex = new P.NullThrownError();
+ wrapper = new Error();
+ wrapper.dartException = ex;
+ if ("defineProperty" in Object) {
+ Object.defineProperty(wrapper, "message", {get: H.toStringWrapper});
+ wrapper.name = "";
+ } else
+ wrapper.toString = H.toStringWrapper;
+ return wrapper;
+ },
+ toStringWrapper: function() {
+ return J.toString$0$(this.dartException);
+ },
+ throwExpression: function(ex) {
+ throw H.wrapException(ex);
+ },
+ throwConcurrentModificationError: function(collection) {
+ throw H.wrapException(P.ConcurrentModificationError$(collection));
+ },
+ TypeErrorDecoder_extractPattern: function(message) {
+ var match, $arguments, argumentsExpr, expr, method, receiver;
+ message = H.quoteStringForRegExp(message.replace(String({}), '$receiver$'));
+ match = message.match(/\\\$[a-zA-Z]+\\\$/g);
+ if (match == null)
+ match = H.setRuntimeTypeInfo([], type$.JSArray_String);
+ $arguments = match.indexOf("\\$arguments\\$");
+ argumentsExpr = match.indexOf("\\$argumentsExpr\\$");
+ expr = match.indexOf("\\$expr\\$");
+ method = match.indexOf("\\$method\\$");
+ receiver = match.indexOf("\\$receiver\\$");
+ return new H.TypeErrorDecoder(message.replace(new RegExp('\\\\\\$arguments\\\\\\$', 'g'), '((?:x|[^x])*)').replace(new RegExp('\\\\\\$argumentsExpr\\\\\\$', 'g'), '((?:x|[^x])*)').replace(new RegExp('\\\\\\$expr\\\\\\$', 'g'), '((?:x|[^x])*)').replace(new RegExp('\\\\\\$method\\\\\\$', 'g'), '((?:x|[^x])*)').replace(new RegExp('\\\\\\$receiver\\\\\\$', 'g'), '((?:x|[^x])*)'), $arguments, argumentsExpr, expr, method, receiver);
+ },
+ TypeErrorDecoder_provokeCallErrorOn: function(expression) {
+ return function($expr$) {
+ var $argumentsExpr$ = '$arguments$';
+ try {
+ $expr$.$method$($argumentsExpr$);
+ } catch (e) {
+ return e.message;
+ }
+ }(expression);
+ },
+ TypeErrorDecoder_provokePropertyErrorOn: function(expression) {
+ return function($expr$) {
+ try {
+ $expr$.$method$;
+ } catch (e) {
+ return e.message;
+ }
+ }(expression);
+ },
+ NullError$: function(_message, match) {
+ return new H.NullError(_message, match == null ? null : match.method);
+ },
+ JsNoSuchMethodError$: function(_message, match) {
+ var t1 = match == null,
+ t2 = t1 ? null : match.method;
+ return new H.JsNoSuchMethodError(_message, t2, t1 ? null : match.receiver);
+ },
+ unwrapException: function(ex) {
+ var message, number, ieErrorCode, nsme, notClosure, nullCall, nullLiteralCall, undefCall, undefLiteralCall, nullProperty, undefProperty, undefLiteralProperty, match, t2, _null = null,
+ t1 = new H.unwrapException_saveStackTrace(ex);
+ if (ex == null)
+ return _null;
+ if (ex instanceof H.ExceptionAndStackTrace)
+ return t1.call$1(ex.dartException);
+ if (typeof ex !== "object")
+ return ex;
+ if ("dartException" in ex)
+ return t1.call$1(ex.dartException);
+ else if (!("message" in ex))
+ return ex;
+ message = ex.message;
+ if ("number" in ex && typeof ex.number == "number") {
+ number = ex.number;
+ ieErrorCode = number & 65535;
+ if ((C.JSInt_methods._shrOtherPositive$1(number, 16) & 8191) === 10)
+ switch (ieErrorCode) {
+ case 438:
+ return t1.call$1(H.JsNoSuchMethodError$(H.S(message) + " (Error " + ieErrorCode + ")", _null));
+ case 445:
+ case 5007:
+ return t1.call$1(H.NullError$(H.S(message) + " (Error " + ieErrorCode + ")", _null));
+ }
+ }
+ if (ex instanceof TypeError) {
+ nsme = $.$get$TypeErrorDecoder_noSuchMethodPattern();
+ notClosure = $.$get$TypeErrorDecoder_notClosurePattern();
+ nullCall = $.$get$TypeErrorDecoder_nullCallPattern();
+ nullLiteralCall = $.$get$TypeErrorDecoder_nullLiteralCallPattern();
+ undefCall = $.$get$TypeErrorDecoder_undefinedCallPattern();
+ undefLiteralCall = $.$get$TypeErrorDecoder_undefinedLiteralCallPattern();
+ nullProperty = $.$get$TypeErrorDecoder_nullPropertyPattern();
+ $.$get$TypeErrorDecoder_nullLiteralPropertyPattern();
+ undefProperty = $.$get$TypeErrorDecoder_undefinedPropertyPattern();
+ undefLiteralProperty = $.$get$TypeErrorDecoder_undefinedLiteralPropertyPattern();
+ match = nsme.matchTypeError$1(message);
+ if (match != null)
+ return t1.call$1(H.JsNoSuchMethodError$(H._checkStringNullable(message), match));
+ else {
+ match = notClosure.matchTypeError$1(message);
+ if (match != null) {
+ match.method = "call";
+ return t1.call$1(H.JsNoSuchMethodError$(H._checkStringNullable(message), match));
+ } else {
+ match = nullCall.matchTypeError$1(message);
+ if (match == null) {
+ match = nullLiteralCall.matchTypeError$1(message);
+ if (match == null) {
+ match = undefCall.matchTypeError$1(message);
+ if (match == null) {
+ match = undefLiteralCall.matchTypeError$1(message);
+ if (match == null) {
+ match = nullProperty.matchTypeError$1(message);
+ if (match == null) {
+ match = nullLiteralCall.matchTypeError$1(message);
+ if (match == null) {
+ match = undefProperty.matchTypeError$1(message);
+ if (match == null) {
+ match = undefLiteralProperty.matchTypeError$1(message);
+ t2 = match != null;
+ } else
+ t2 = true;
+ } else
+ t2 = true;
+ } else
+ t2 = true;
+ } else
+ t2 = true;
+ } else
+ t2 = true;
+ } else
+ t2 = true;
+ } else
+ t2 = true;
+ if (t2)
+ return t1.call$1(H.NullError$(H._checkStringNullable(message), match));
+ }
+ }
+ return t1.call$1(new H.UnknownJsTypeError(typeof message == "string" ? message : ""));
+ }
+ if (ex instanceof RangeError) {
+ if (typeof message == "string" && message.indexOf("call stack") !== -1)
+ return new P.StackOverflowError();
+ message = function(ex) {
+ try {
+ return String(ex);
+ } catch (e) {
+ }
+ return null;
+ }(ex);
+ return t1.call$1(new P.ArgumentError(false, _null, _null, typeof message == "string" ? message.replace(/^RangeError:\s*/, "") : message));
+ }
+ if (typeof InternalError == "function" && ex instanceof InternalError)
+ if (typeof message == "string" && message === "too much recursion")
+ return new P.StackOverflowError();
+ return ex;
+ },
+ getTraceFromException: function(exception) {
+ var trace;
+ if (exception instanceof H.ExceptionAndStackTrace)
+ return exception.stackTrace;
+ if (exception == null)
+ return new H._StackTrace(exception);
+ trace = exception.$cachedTrace;
+ if (trace != null)
+ return trace;
+ return exception.$cachedTrace = new H._StackTrace(exception);
+ },
+ objectHashCode: function(object) {
+ if (object == null || typeof object != 'object')
+ return J.get$hashCode$(object);
+ else
+ return H.Primitives_objectHashCode(object);
+ },
+ fillLiteralMap: function(keyValuePairs, result) {
+ var $length, index, index0, key,
+ t1 = Array.isArray(keyValuePairs);
+ H.assertHelper(t1);
+ $length = keyValuePairs.length;
+ for (index = 0; index < $length;) {
+ index0 = index + 1;
+ H.assertHelper(t1);
+ key = keyValuePairs[index];
+ index = index0 + 1;
+ H.assertHelper(t1);
+ result.$indexSet(0, key, keyValuePairs[index0]);
+ }
+ return result;
+ },
+ fillLiteralSet: function(values, result) {
+ var $length, index,
+ t1 = Array.isArray(values);
+ H.assertHelper(t1);
+ $length = values.length;
+ for (index = 0; index < $length; ++index) {
+ H.assertHelper(t1);
+ result.add$1(0, values[index]);
+ }
+ return result;
+ },
+ invokeClosure: function(closure, numberOfArguments, arg1, arg2, arg3, arg4) {
+ type$.Function._check(closure);
+ switch (H._checkIntNullable(numberOfArguments)) {
+ case 0:
+ return closure.call$0();
+ case 1:
+ return closure.call$1(arg1);
+ case 2:
+ return closure.call$2(arg1, arg2);
+ case 3:
+ return closure.call$3(arg1, arg2, arg3);
+ case 4:
+ return closure.call$4(arg1, arg2, arg3, arg4);
+ }
+ throw H.wrapException(new P._Exception("Unsupported number of arguments for wrapped closure"));
+ },
+ convertDartClosureToJS: function(closure, arity) {
+ var $function;
+ if (closure == null)
+ return null;
+ $function = closure.$identity;
+ if (!!$function)
+ return $function;
+ $function = function(closure, arity, invoke) {
+ return function(a1, a2, a3, a4) {
+ return invoke(closure, arity, a1, a2, a3, a4);
+ };
+ }(closure, arity, H.invokeClosure);
+ closure.$identity = $function;
+ return $function;
+ },
+ Closure_fromTearOff: function(receiver, functions, applyTrampolineIndex, reflectionInfo, isStatic, isIntercepted, propertyName) {
+ var $constructor, t1, trampoline, signatureFunction, applyTrampoline, i, stub, stubCallName, _null = null,
+ $function = functions[0],
+ callName = $function.$callName,
+ $prototype = isStatic ? Object.create(new H.StaticClosure().constructor.prototype) : Object.create(new H.BoundClosure(_null, _null, _null, _null).constructor.prototype);
+ $prototype.$initialize = $prototype.constructor;
+ if (isStatic)
+ $constructor = function static_tear_off() {
+ this.$initialize();
+ };
+ else {
+ t1 = $.Closure_functionCounter;
+ if (typeof t1 !== "number")
+ return t1.$add();
+ $.Closure_functionCounter = t1 + 1;
+ t1 = new Function("a,b,c,d" + t1, "this.$initialize(a,b,c,d" + t1 + ")");
+ $constructor = t1;
+ }
+ $prototype.constructor = $constructor;
+ $constructor.prototype = $prototype;
+ if (!isStatic) {
+ trampoline = H.Closure_forwardCallTo(receiver, $function, isIntercepted);
+ trampoline.$reflectionInfo = reflectionInfo;
+ } else {
+ $prototype.$static_name = propertyName;
+ trampoline = $function;
+ }
+ signatureFunction = H.Closure__computeSignatureFunctionNewRti(reflectionInfo, isStatic, isIntercepted);
+ $prototype.$signature = signatureFunction;
+ $prototype[callName] = trampoline;
+ for (applyTrampoline = trampoline, i = 1; i < functions.length; ++i) {
+ stub = functions[i];
+ stubCallName = stub.$callName;
+ if (stubCallName != null) {
+ stub = isStatic ? stub : H.Closure_forwardCallTo(receiver, stub, isIntercepted);
+ $prototype[stubCallName] = stub;
+ }
+ if (i === applyTrampolineIndex) {
+ stub.$reflectionInfo = reflectionInfo;
+ applyTrampoline = stub;
+ }
+ }
+ $prototype["call*"] = applyTrampoline;
+ $prototype.$requiredArgCount = $function.$requiredArgCount;
+ $prototype.$defaultValues = $function.$defaultValues;
+ return $constructor;
+ },
+ Closure__computeSignatureFunctionNewRti: function(functionType, isStatic, isIntercepted) {
+ var typeEvalMethod;
+ if (typeof functionType == "number")
+ return function(getType, t) {
+ return function() {
+ return getType(t);
+ };
+ }(H.getTypeFromTypesTable, functionType);
+ if (typeof functionType == "string") {
+ if (isStatic)
+ throw H.wrapException("Cannot compute signature for static tearoff.");
+ typeEvalMethod = isIntercepted ? H.BoundClosure_evalRecipeIntercepted : H.BoundClosure_evalRecipe;
+ return function(recipe, evalOnReceiver) {
+ return function() {
+ return evalOnReceiver(this, recipe);
+ };
+ }(functionType, typeEvalMethod);
+ }
+ throw H.wrapException("Error in functionType of tearoff");
+ },
+ Closure_cspForwardCall: function(arity, isSuperCall, stubName, $function) {
+ var getSelf = H.BoundClosure_selfOf;
+ switch (isSuperCall ? -1 : arity) {
+ case 0:
+ return function(n, S) {
+ return function() {
+ return S(this)[n]();
+ };
+ }(stubName, getSelf);
+ case 1:
+ return function(n, S) {
+ return function(a) {
+ return S(this)[n](a);
+ };
+ }(stubName, getSelf);
+ case 2:
+ return function(n, S) {
+ return function(a, b) {
+ return S(this)[n](a, b);
+ };
+ }(stubName, getSelf);
+ case 3:
+ return function(n, S) {
+ return function(a, b, c) {
+ return S(this)[n](a, b, c);
+ };
+ }(stubName, getSelf);
+ case 4:
+ return function(n, S) {
+ return function(a, b, c, d) {
+ return S(this)[n](a, b, c, d);
+ };
+ }(stubName, getSelf);
+ case 5:
+ return function(n, S) {
+ return function(a, b, c, d, e) {
+ return S(this)[n](a, b, c, d, e);
+ };
+ }(stubName, getSelf);
+ default:
+ return function(f, s) {
+ return function() {
+ return f.apply(s(this), arguments);
+ };
+ }($function, getSelf);
+ }
+ },
+ Closure_forwardCallTo: function(receiver, $function, isIntercepted) {
+ var stubName, arity, lookedUpFunction, t1, t2, selfName, $arguments;
+ if (isIntercepted)
+ return H.Closure_forwardInterceptedCallTo(receiver, $function);
+ stubName = $function.$stubName;
+ arity = $function.length;
+ lookedUpFunction = receiver[stubName];
+ t1 = $function == null ? lookedUpFunction == null : $function === lookedUpFunction;
+ t2 = !t1 || arity >= 27;
+ if (t2)
+ return H.Closure_cspForwardCall(arity, !t1, stubName, $function);
+ if (arity === 0) {
+ t1 = $.Closure_functionCounter;
+ if (typeof t1 !== "number")
+ return t1.$add();
+ $.Closure_functionCounter = t1 + 1;
+ selfName = "self" + t1;
+ t1 = "return function(){var " + selfName + " = this.";
+ t2 = $.BoundClosure_selfFieldNameCache;
+ return new Function(t1 + H.S(t2 == null ? $.BoundClosure_selfFieldNameCache = H.BoundClosure_computeFieldNamed("self") : t2) + ";return " + selfName + "." + H.S(stubName) + "();}")();
+ }
+ H.assertHelper(1 <= arity && arity < 27);
+ $arguments = "abcdefghijklmnopqrstuvwxyz".split("").splice(0, arity).join(",");
+ t1 = $.Closure_functionCounter;
+ if (typeof t1 !== "number")
+ return t1.$add();
+ $.Closure_functionCounter = t1 + 1;
+ $arguments += t1;
+ t1 = "return function(" + $arguments + "){return this.";
+ t2 = $.BoundClosure_selfFieldNameCache;
+ return new Function(t1 + H.S(t2 == null ? $.BoundClosure_selfFieldNameCache = H.BoundClosure_computeFieldNamed("self") : t2) + "." + H.S(stubName) + "(" + $arguments + ");}")();
+ },
+ Closure_cspForwardInterceptedCall: function(arity, isSuperCall, $name, $function) {
+ var getSelf = H.BoundClosure_selfOf,
+ getReceiver = H.BoundClosure_receiverOf;
+ switch (isSuperCall ? -1 : arity) {
+ case 0:
+ throw H.wrapException(H.RuntimeError$("Intercepted function with no arguments."));
+ case 1:
+ return function(n, s, r) {
+ return function() {
+ return s(this)[n](r(this));
+ };
+ }($name, getSelf, getReceiver);
+ case 2:
+ return function(n, s, r) {
+ return function(a) {
+ return s(this)[n](r(this), a);
+ };
+ }($name, getSelf, getReceiver);
+ case 3:
+ return function(n, s, r) {
+ return function(a, b) {
+ return s(this)[n](r(this), a, b);
+ };
+ }($name, getSelf, getReceiver);
+ case 4:
+ return function(n, s, r) {
+ return function(a, b, c) {
+ return s(this)[n](r(this), a, b, c);
+ };
+ }($name, getSelf, getReceiver);
+ case 5:
+ return function(n, s, r) {
+ return function(a, b, c, d) {
+ return s(this)[n](r(this), a, b, c, d);
+ };
+ }($name, getSelf, getReceiver);
+ case 6:
+ return function(n, s, r) {
+ return function(a, b, c, d, e) {
+ return s(this)[n](r(this), a, b, c, d, e);
+ };
+ }($name, getSelf, getReceiver);
+ default:
+ return function(f, s, r, a) {
+ return function() {
+ a = [r(this)];
+ Array.prototype.push.apply(a, arguments);
+ return f.apply(s(this), a);
+ };
+ }($function, getSelf, getReceiver);
+ }
+ },
+ Closure_forwardInterceptedCallTo: function(receiver, $function) {
+ var t2, stubName, arity, lookedUpFunction, t3, t4, $arguments,
+ t1 = $.BoundClosure_selfFieldNameCache;
+ if (t1 == null)
+ t1 = $.BoundClosure_selfFieldNameCache = H.BoundClosure_computeFieldNamed("self");
+ t2 = $.BoundClosure_receiverFieldNameCache;
+ if (t2 == null)
+ t2 = $.BoundClosure_receiverFieldNameCache = H.BoundClosure_computeFieldNamed("receiver");
+ stubName = $function.$stubName;
+ arity = $function.length;
+ lookedUpFunction = receiver[stubName];
+ t3 = $function == null ? lookedUpFunction == null : $function === lookedUpFunction;
+ t4 = !t3 || arity >= 28;
+ if (t4)
+ return H.Closure_cspForwardInterceptedCall(arity, !t3, stubName, $function);
+ if (arity === 1) {
+ t1 = "return function(){return this." + H.S(t1) + "." + H.S(stubName) + "(this." + H.S(t2) + ");";
+ t2 = $.Closure_functionCounter;
+ if (typeof t2 !== "number")
+ return t2.$add();
+ $.Closure_functionCounter = t2 + 1;
+ return new Function(t1 + t2 + "}")();
+ }
+ H.assertHelper(1 < arity && arity < 28);
+ $arguments = "abcdefghijklmnopqrstuvwxyz".split("").splice(0, arity - 1).join(",");
+ t1 = "return function(" + $arguments + "){return this." + H.S(t1) + "." + H.S(stubName) + "(this." + H.S(t2) + ", " + $arguments + ");";
+ t2 = $.Closure_functionCounter;
+ if (typeof t2 !== "number")
+ return t2.$add();
+ $.Closure_functionCounter = t2 + 1;
+ return new Function(t1 + t2 + "}")();
+ },
+ closureFromTearOff: function(receiver, functions, applyTrampolineIndex, reflectionInfo, isStatic, isIntercepted, $name) {
+ return H.Closure_fromTearOff(receiver, functions, applyTrampolineIndex, reflectionInfo, !!isStatic, !!isIntercepted, $name);
+ },
+ BoundClosure_evalRecipe: function(closure, recipe) {
+ return H._Universe_evalInEnvironment(init.typeUniverse, H.instanceType(closure._self), recipe);
+ },
+ BoundClosure_evalRecipeIntercepted: function(closure, recipe) {
+ return H._Universe_evalInEnvironment(init.typeUniverse, H.instanceType(closure._receiver), recipe);
+ },
+ BoundClosure_selfOf: function(closure) {
+ return closure._self;
+ },
+ BoundClosure_receiverOf: function(closure) {
+ return closure._receiver;
+ },
+ BoundClosure_computeFieldNamed: function(fieldName) {
+ var t1, i, $name,
+ template = new H.BoundClosure("self", "target", "receiver", "name"),
+ names = J.JSArray_markFixedList(Object.getOwnPropertyNames(template));
+ for (t1 = names.length, i = 0; i < t1; ++i) {
+ $name = names[i];
+ if (template[$name] === fieldName)
+ return $name;
+ }
+ },
+ boolConversionCheck: function(value) {
+ if (value == null)
+ H.assertThrow("boolean expression must not be null");
+ return value;
+ },
+ extractFunctionTypeObjectFromInternal: function(o) {
+ var signature;
+ if ("$signature" in o) {
+ signature = o.$signature;
+ if (typeof signature == "number")
+ return init.types[H._checkIntNullable(signature)];
+ else
+ return o.$signature();
+ }
+ return null;
+ },
+ TypeErrorImplementation$: function(value, type) {
+ return new H.TypeErrorImplementation("TypeError: " + P.Error_safeToString(value) + ": type '" + H.S(H._typeDescription(value)) + "' is not a subtype of type '" + type + "'");
+ },
+ _typeDescription: function(value) {
+ var functionTypeObject;
+ if (value instanceof H.Closure) {
+ functionTypeObject = H.extractFunctionTypeObjectFromInternal(J.getInterceptor$(value));
+ if (functionTypeObject != null)
+ return H.runtimeTypeToString(functionTypeObject);
+ return "Closure";
+ }
+ return H.Primitives_objectTypeName(value);
+ },
+ assertTest: function(condition) {
+ if (true === condition)
+ return false;
+ if (H._isBool(condition))
+ return !condition;
+ throw H.wrapException(H.TypeErrorImplementation$(condition, "bool"));
+ },
+ assertThrow: function(message) {
+ throw H.wrapException(new H._AssertionError(message));
+ },
+ assertHelper: function(condition) {
+ if (H.assertTest(condition))
+ throw H.wrapException(P.AssertionError$(null));
+ },
+ throwCyclicInit: function(staticName) {
+ throw H.wrapException(new P.CyclicInitializationError(staticName));
+ },
+ RuntimeError$: function(message) {
+ return new H.RuntimeError(message);
+ },
+ getIsolateAffinityTag: function($name) {
+ return init.getIsolateTag($name);
+ },
+ setRuntimeTypeInfo: function(target, rti) {
+ H.assertHelper(rti != null);
+ target.$ti = rti;
+ return target;
+ },
+ getRuntimeTypeInfo: function(target) {
+ if (target == null)
+ return null;
+ return target.$ti;
+ },
+ getRuntimeTypeArguments: function(interceptor, object, substitutionName) {
+ return H.substitute(interceptor["$as" + H.S(substitutionName)], H.getRuntimeTypeInfo(object));
+ },
+ runtimeTypeToString: function(rti) {
+ return H._runtimeTypeToString(rti, null);
+ },
+ _runtimeTypeToString: function(rti, genericContext) {
+ var t1, t2;
+ if (rti == null)
+ return "dynamic";
+ if (rti === -1)
+ return "void";
+ if (Array.isArray(rti))
+ return H.unminifyOrTag(rti[0].name) + H._joinArguments(rti, 1, genericContext);
+ if (typeof rti == "function")
+ return H.unminifyOrTag(rti.name);
+ if (rti === -2)
+ return "dynamic";
+ H.assertHelper(!(rti === -1));
+ if (typeof rti == "number") {
+ H._checkIntNullable(rti);
+ if (genericContext == null || rti < 0 || rti >= genericContext.length)
+ return "unexpected-generic-index:" + rti;
+ t1 = genericContext.length;
+ t2 = t1 - rti - 1;
+ if (t2 < 0 || t2 >= t1)
+ return H.ioore(genericContext, t2);
+ return H.S(genericContext[t2]);
+ }
+ t1 = rti != null;
+ if (t1)
+ t2 = typeof rti == "string";
+ else
+ t2 = true;
+ H.assertHelper(!t2);
+ if ('func' in rti)
+ return H._functionRtiToString0(rti, genericContext);
+ if (t1)
+ t2 = typeof rti == "string";
+ else
+ t2 = true;
+ H.assertHelper(!t2);
+ if ('futureOr' in rti) {
+ if (t1)
+ t1 = typeof rti == "string";
+ else
+ t1 = true;
+ H.assertHelper(!t1);
+ H.assertHelper('futureOr' in rti);
+ return "FutureOr<" + H._runtimeTypeToString("type" in rti ? rti.type : null, genericContext) + ">";
+ }
+ return "unknown-reified-type";
+ },
+ _functionRtiToString0: function(rti, genericContext) {
+ var boundsRti, outerContextLength, offset, i, i0, typeParameters, typeSep, t1, t2, boundRti, returnTypeText, $arguments, argumentsText, sep, _i, argument, optionalArguments, namedArguments, $name, _s2_ = ", ";
+ if ("bounds" in rti) {
+ boundsRti = rti.bounds;
+ if (genericContext == null) {
+ genericContext = H.setRuntimeTypeInfo([], type$.JSArray_String);
+ outerContextLength = null;
+ } else
+ outerContextLength = genericContext.length;
+ offset = genericContext.length;
+ for (i = boundsRti.length, i0 = i; i0 > 0; --i0)
+ C.JSArray_methods.add$1(genericContext, "T" + (offset + i0));
+ for (typeParameters = "<", typeSep = "", i0 = 0; i0 < i; ++i0, typeSep = _s2_) {
+ typeParameters += typeSep;
+ t1 = genericContext.length;
+ t2 = t1 - i0 - 1;
+ if (t2 < 0)
+ return H.ioore(genericContext, t2);
+ typeParameters = C.JSString_methods.$add(typeParameters, genericContext[t2]);
+ boundRti = boundsRti[i0];
+ if (boundRti != null && boundRti !== P.Object)
+ typeParameters += " extends " + H._runtimeTypeToString(boundRti, genericContext);
+ }
+ typeParameters += ">";
+ } else {
+ typeParameters = "";
+ outerContextLength = null;
+ }
+ returnTypeText = !!rti.v ? "void" : H._runtimeTypeToString(rti.ret, genericContext);
+ if ("args" in rti) {
+ $arguments = rti.args;
+ for (t1 = $arguments.length, argumentsText = "", sep = "", _i = 0; _i < t1; ++_i, sep = _s2_) {
+ argument = $arguments[_i];
+ argumentsText = argumentsText + sep + H._runtimeTypeToString(argument, genericContext);
+ }
+ } else {
+ argumentsText = "";
+ sep = "";
+ }
+ if ("opt" in rti) {
+ optionalArguments = rti.opt;
+ argumentsText += sep + "[";
+ for (t1 = optionalArguments.length, sep = "", _i = 0; _i < t1; ++_i, sep = _s2_) {
+ argument = optionalArguments[_i];
+ argumentsText = argumentsText + sep + H._runtimeTypeToString(argument, genericContext);
+ }
+ argumentsText += "]";
+ }
+ if ("named" in rti) {
+ namedArguments = rti.named;
+ argumentsText += sep + "{";
+ for (t1 = H.extractKeys(namedArguments), t2 = t1.length, sep = "", _i = 0; _i < t2; ++_i, sep = _s2_) {
+ $name = H._checkStringNullable(t1[_i]);
+ argumentsText = argumentsText + sep + H._runtimeTypeToString(namedArguments[$name], genericContext) + (" " + H.S($name));
+ }
+ argumentsText += "}";
+ }
+ if (outerContextLength != null)
+ genericContext.length = outerContextLength;
+ return typeParameters + "(" + argumentsText + ") => " + returnTypeText;
+ },
+ _joinArguments: function(types, startIndex, genericContext) {
+ var t1, buffer, index, separator, allDynamic, argument;
+ if (types == null)
+ return "";
+ t1 = Array.isArray(types);
+ H.assertHelper(t1);
+ buffer = new P.StringBuffer("");
+ for (index = startIndex, separator = "", allDynamic = true; H.assertHelper(t1), index < types.length; ++index, separator = ", ") {
+ buffer._contents += separator;
+ H.assertHelper(t1);
+ argument = types[index];
+ if (argument != null)
+ allDynamic = false;
+ buffer._contents += H._runtimeTypeToString(argument, genericContext);
+ }
+ return "<" + buffer.toString$0(0) + ">";
+ },
+ getRuntimeType: function(object) {
+ var rti = object instanceof H.Closure ? H.closureFunctionType(object) : null;
+ return H.createRuntimeType(rti == null ? H.instanceType(object) : rti);
+ },
+ substitute: function(substitution, $arguments) {
+ if (substitution == null)
+ return $arguments;
+ H.assertHelper(typeof substitution == "function");
+ H.assertHelper($arguments == null || Array.isArray($arguments));
+ substitution = H.invokeOn(substitution, null, $arguments);
+ if (substitution == null)
+ return null;
+ if (Array.isArray(substitution))
+ return substitution;
+ if (typeof substitution == "function")
+ return H.invokeOn(substitution, null, $arguments);
+ return $arguments;
+ },
+ computeSignature: function(signature, context, contextName) {
+ return H.invokeOn(signature, context, H.substitute(J.getInterceptor$(context)["$as" + H.S(contextName)], H.getRuntimeTypeInfo(context)));
+ },
+ invokeOn: function($function, receiver, $arguments) {
+ H.assertHelper(typeof $function == "function");
+ H.assertHelper($arguments == null || Array.isArray($arguments));
+ return $function.apply(receiver, $arguments);
+ },
+ defineProperty: function(obj, property, value) {
+ Object.defineProperty(obj, property, {value: value, enumerable: false, writable: true, configurable: true});
+ },
+ lookupAndCacheInterceptor: function(obj) {
+ var tag, record, interceptor, interceptorClass, mark, t1;
+ H.assertHelper(!(obj instanceof P.Object));
+ tag = H._checkStringNullable($.getTagFunction.call$1(obj));
+ record = $.dispatchRecordsForInstanceTags[tag];
+ if (record != null) {
+ Object.defineProperty(obj, init.dispatchPropertyName, {value: record, enumerable: false, writable: true, configurable: true});
+ return record.i;
+ }
+ interceptor = $.interceptorsForUncacheableTags[tag];
+ if (interceptor != null)
+ return interceptor;
+ interceptorClass = init.interceptorsByTag[tag];
+ if (interceptorClass == null) {
+ tag = H._checkStringNullable($.alternateTagFunction.call$2(obj, tag));
+ if (tag != null) {
+ record = $.dispatchRecordsForInstanceTags[tag];
+ if (record != null) {
+ Object.defineProperty(obj, init.dispatchPropertyName, {value: record, enumerable: false, writable: true, configurable: true});
+ return record.i;
+ }
+ interceptor = $.interceptorsForUncacheableTags[tag];
+ if (interceptor != null)
+ return interceptor;
+ interceptorClass = init.interceptorsByTag[tag];
+ }
+ }
+ if (interceptorClass == null)
+ return null;
+ interceptor = interceptorClass.prototype;
+ mark = tag[0];
+ if (mark === "!") {
+ record = H.makeLeafDispatchRecord(interceptor);
+ $.dispatchRecordsForInstanceTags[tag] = record;
+ Object.defineProperty(obj, init.dispatchPropertyName, {value: record, enumerable: false, writable: true, configurable: true});
+ return record.i;
+ }
+ if (mark === "~") {
+ $.interceptorsForUncacheableTags[tag] = interceptor;
+ return interceptor;
+ }
+ if (mark === "-") {
+ t1 = H.makeLeafDispatchRecord(interceptor);
+ Object.defineProperty(Object.getPrototypeOf(obj), init.dispatchPropertyName, {value: t1, enumerable: false, writable: true, configurable: true});
+ return t1.i;
+ }
+ if (mark === "+")
+ return H.patchInteriorProto(obj, interceptor);
+ if (mark === "*")
+ throw H.wrapException(P.UnimplementedError$(tag));
+ if (init.leafTags[tag] === true) {
+ t1 = H.makeLeafDispatchRecord(interceptor);
+ Object.defineProperty(Object.getPrototypeOf(obj), init.dispatchPropertyName, {value: t1, enumerable: false, writable: true, configurable: true});
+ return t1.i;
+ } else
+ return H.patchInteriorProto(obj, interceptor);
+ },
+ patchInteriorProto: function(obj, interceptor) {
+ var proto = Object.getPrototypeOf(obj);
+ Object.defineProperty(proto, init.dispatchPropertyName, {value: J.makeDispatchRecord(interceptor, proto, null, null), enumerable: false, writable: true, configurable: true});
+ return interceptor;
+ },
+ makeLeafDispatchRecord: function(interceptor) {
+ return J.makeDispatchRecord(interceptor, false, null, !!interceptor.$isJavaScriptIndexingBehavior);
+ },
+ makeDefaultDispatchRecord: function(tag, interceptorClass, proto) {
+ var interceptor = interceptorClass.prototype;
+ if (init.leafTags[tag] === true)
+ return H.makeLeafDispatchRecord(interceptor);
+ else
+ return J.makeDispatchRecord(interceptor, proto, null, null);
+ },
+ initNativeDispatch: function() {
+ if (true === $.initNativeDispatchFlag)
+ return;
+ $.initNativeDispatchFlag = true;
+ H.initNativeDispatchContinue();
+ },
+ initNativeDispatchContinue: function() {
+ var map, tags, fun, i, tag, proto, record, interceptorClass;
+ $.dispatchRecordsForInstanceTags = Object.create(null);
+ $.interceptorsForUncacheableTags = Object.create(null);
+ H.initHooks();
+ map = init.interceptorsByTag;
+ tags = Object.getOwnPropertyNames(map);
+ if (typeof window != "undefined") {
+ window;
+ fun = function() {
+ };
+ for (i = 0; i < tags.length; ++i) {
+ tag = tags[i];
+ proto = $.prototypeForTagFunction.call$1(tag);
+ if (proto != null) {
+ record = H.makeDefaultDispatchRecord(tag, map[tag], proto);
+ if (record != null) {
+ Object.defineProperty(proto, init.dispatchPropertyName, {value: record, enumerable: false, writable: true, configurable: true});
+ fun.prototype = proto;
+ }
+ }
+ }
+ }
+ for (i = 0; i < tags.length; ++i) {
+ tag = tags[i];
+ if (/^[A-Za-z_]/.test(tag)) {
+ interceptorClass = map[tag];
+ map["!" + tag] = interceptorClass;
+ map["~" + tag] = interceptorClass;
+ map["-" + tag] = interceptorClass;
+ map["+" + tag] = interceptorClass;
+ map["*" + tag] = interceptorClass;
+ }
+ }
+ },
+ initHooks: function() {
+ var transformers, i, transformer, getTag, getUnknownTag, prototypeForTag,
+ hooks = C.C_JS_CONST0();
+ hooks = H.applyHooksTransformer(C.C_JS_CONST1, H.applyHooksTransformer(C.C_JS_CONST2, H.applyHooksTransformer(C.C_JS_CONST3, H.applyHooksTransformer(C.C_JS_CONST3, H.applyHooksTransformer(C.C_JS_CONST4, H.applyHooksTransformer(C.C_JS_CONST5, H.applyHooksTransformer(C.C_JS_CONST6(C.C_JS_CONST), hooks)))))));
+ if (typeof dartNativeDispatchHooksTransformer != "undefined") {
+ transformers = dartNativeDispatchHooksTransformer;
+ if (typeof transformers == "function")
+ transformers = [transformers];
+ if (transformers.constructor == Array)
+ for (i = 0; i < transformers.length; ++i) {
+ transformer = transformers[i];
+ if (typeof transformer == "function")
+ hooks = transformer(hooks) || hooks;
+ }
+ }
+ getTag = hooks.getTag;
+ getUnknownTag = hooks.getUnknownTag;
+ prototypeForTag = hooks.prototypeForTag;
+ $.getTagFunction = new H.initHooks_closure(getTag);
+ $.alternateTagFunction = new H.initHooks_closure0(getUnknownTag);
+ $.prototypeForTagFunction = new H.initHooks_closure1(prototypeForTag);
+ },
+ applyHooksTransformer: function(transformer, hooks) {
+ return transformer(hooks) || hooks;
+ },
+ JSSyntaxRegExp_makeNative: function(source, multiLine, caseSensitive, unicode, dotAll, global) {
+ var m = multiLine ? "m" : "",
+ i = caseSensitive ? "" : "i",
+ u = unicode ? "u" : "",
+ s = dotAll ? "s" : "",
+ g = global ? "g" : "",
+ regexp = function(source, modifiers) {
+ try {
+ return new RegExp(source, modifiers);
+ } catch (e) {
+ return e;
+ }
+ }(source, m + i + u + s + g);
+ if (regexp instanceof RegExp)
+ return regexp;
+ throw H.wrapException(P.FormatException$("Illegal RegExp pattern (" + String(regexp) + ")", source, null));
+ },
+ _MatchImplementation$: function(pattern, _match) {
+ H.assertHelper(typeof _match.input == "string");
+ H.assertHelper(H._isInt(_match.index));
+ return new H._MatchImplementation(_match);
+ },
+ stringContainsUnchecked: function(receiver, other, startIndex) {
+ var t1, t2;
+ if (typeof other == "string")
+ return receiver.indexOf(other, startIndex) >= 0;
+ else if (other instanceof H.JSSyntaxRegExp) {
+ t1 = C.JSString_methods.substring$1(receiver, startIndex);
+ t2 = other._nativeRegExp;
+ return t2.test(t1);
+ } else {
+ t1 = J.allMatches$1$s(other, C.JSString_methods.substring$1(receiver, startIndex));
+ return !t1.get$isEmpty(t1);
+ }
+ },
+ escapeReplacement: function(replacement) {
+ if (replacement.indexOf("$", 0) >= 0)
+ return replacement.replace(/\$/g, "$$$$");
+ return replacement;
+ },
+ stringReplaceFirstRE: function(receiver, regexp, replacement, startIndex) {
+ var match = regexp._execGlobal$2(receiver, startIndex);
+ if (match == null)
+ return receiver;
+ return H.stringReplaceRangeUnchecked(receiver, match._match.index, match.get$end(), replacement);
+ },
+ quoteStringForRegExp: function(string) {
+ if (/[[\]{}()*+?.\\^$|]/.test(string))
+ return string.replace(/[[\]{}()*+?.\\^$|]/g, "\\$&");
+ return string;
+ },
+ stringReplaceAllUnchecked: function(receiver, pattern, replacement) {
+ var nativeRegexp;
+ if (typeof pattern == "string")
+ return H.stringReplaceAllUncheckedString(receiver, pattern, replacement);
+ if (pattern instanceof H.JSSyntaxRegExp) {
+ nativeRegexp = pattern.get$_nativeGlobalVersion();
+ nativeRegexp.lastIndex = 0;
+ return receiver.replace(nativeRegexp, H.escapeReplacement(replacement));
+ }
+ if (pattern == null)
+ H.throwExpression(H.argumentErrorValue(pattern));
+ throw H.wrapException("String.replaceAll(Pattern) UNIMPLEMENTED");
+ },
+ stringReplaceAllUncheckedString: function(receiver, pattern, replacement) {
+ var $length, t1, i, index;
+ if (pattern === "") {
+ if (receiver === "")
+ return replacement;
+ $length = receiver.length;
+ for (t1 = replacement, i = 0; i < $length; ++i)
+ t1 = t1 + receiver[i] + replacement;
+ return t1.charCodeAt(0) == 0 ? t1 : t1;
+ }
+ index = receiver.indexOf(pattern, 0);
+ if (index < 0)
+ return receiver;
+ if (receiver.length < 500 || replacement.indexOf("$", 0) >= 0)
+ return receiver.split(pattern).join(replacement);
+ return receiver.replace(new RegExp(H.quoteStringForRegExp(pattern), 'g'), H.escapeReplacement(replacement));
+ },
+ _stringIdentity: function(string) {
+ return string;
+ },
+ stringReplaceAllFuncUnchecked: function(receiver, pattern, onMatch, onNonMatch) {
+ var t1, startIndex, t2, t3, t4, t5;
+ if (!type$.Pattern._is(pattern))
+ throw H.wrapException(P.ArgumentError$value(pattern, "pattern", "is not a Pattern"));
+ for (t1 = pattern.allMatches$1(0, receiver), t1 = new H._AllMatchesIterator(t1._re, t1.__js_helper$_string, t1._start), startIndex = 0, t2 = ""; t1.moveNext$0(); t2 = t3) {
+ t3 = t1.__js_helper$_current;
+ t4 = t3._match;
+ t5 = t4.index;
+ t3 = t2 + H.S(H._stringIdentity(C.JSString_methods.substring$2(receiver, startIndex, t5))) + H.S(onMatch.call$1(t3));
+ startIndex = t5 + t4[0].length;
+ }
+ t1 = t2 + H.S(H._stringIdentity(C.JSString_methods.substring$1(receiver, startIndex)));
+ return t1.charCodeAt(0) == 0 ? t1 : t1;
+ },
+ stringReplaceFirstUnchecked: function(receiver, pattern, replacement, startIndex) {
+ var index, t1, matches, match;
+ if (typeof pattern == "string") {
+ index = receiver.indexOf(pattern, startIndex);
+ if (index < 0)
+ return receiver;
+ return H.stringReplaceRangeUnchecked(receiver, index, index + pattern.length, replacement);
+ }
+ if (pattern instanceof H.JSSyntaxRegExp)
+ return startIndex === 0 ? receiver.replace(pattern._nativeRegExp, H.escapeReplacement(replacement)) : H.stringReplaceFirstRE(receiver, pattern, replacement, startIndex);
+ if (pattern == null)
+ H.throwExpression(H.argumentErrorValue(pattern));
+ t1 = J.allMatches$2$s(pattern, receiver, startIndex);
+ matches = type$.Iterator_Match._check(t1.get$iterator(t1));
+ if (!matches.moveNext$0())
+ return receiver;
+ match = matches.get$current();
+ return C.JSString_methods.replaceRange$3(receiver, match.get$start(), match.get$end(), replacement);
+ },
+ stringReplaceRangeUnchecked: function(receiver, start, end, replacement) {
+ var prefix = receiver.substring(0, start),
+ suffix = receiver.substring(end);
+ return prefix + replacement + suffix;
+ },
+ ConstantMap: function ConstantMap() {
+ },
+ ConstantMap_map_closure: function ConstantMap_map_closure(t0, t1, t2) {
+ this.$this = t0;
+ this.transform = t1;
+ this.result = t2;
+ },
+ ConstantStringMap: function ConstantStringMap(t0, t1, t2, t3) {
+ var _ = this;
+ _.__js_helper$_length = t0;
+ _._jsObject = t1;
+ _.__js_helper$_keys = t2;
+ _.$ti = t3;
+ },
+ _ConstantMapKeyIterable: function _ConstantMapKeyIterable(t0, t1) {
+ this.__js_helper$_map = t0;
+ this.$ti = t1;
+ },
+ Instantiation: function Instantiation() {
+ },
+ Instantiation1: function Instantiation1(t0, t1) {
+ this._genericClosure = t0;
+ this.$ti = t1;
+ },
+ Primitives_initTicker_closure: function Primitives_initTicker_closure(t0) {
+ this.performance = t0;
+ },
+ TypeErrorDecoder: function TypeErrorDecoder(t0, t1, t2, t3, t4, t5) {
+ var _ = this;
+ _._pattern = t0;
+ _._arguments = t1;
+ _._argumentsExpr = t2;
+ _._expr = t3;
+ _._method = t4;
+ _._receiver = t5;
+ },
+ NullError: function NullError(t0, t1) {
+ this.__js_helper$_message = t0;
+ this._method = t1;
+ },
+ JsNoSuchMethodError: function JsNoSuchMethodError(t0, t1, t2) {
+ this.__js_helper$_message = t0;
+ this._method = t1;
+ this._receiver = t2;
+ },
+ UnknownJsTypeError: function UnknownJsTypeError(t0) {
+ this.__js_helper$_message = t0;
+ },
+ ExceptionAndStackTrace: function ExceptionAndStackTrace(t0, t1) {
+ this.dartException = t0;
+ this.stackTrace = t1;
+ },
+ unwrapException_saveStackTrace: function unwrapException_saveStackTrace(t0) {
+ this.ex = t0;
+ },
+ _StackTrace: function _StackTrace(t0) {
+ this._exception = t0;
+ this._trace = null;
+ },
+ Closure: function Closure() {
+ },
+ TearOffClosure: function TearOffClosure() {
+ },
+ StaticClosure: function StaticClosure() {
+ },
+ BoundClosure: function BoundClosure(t0, t1, t2, t3) {
+ var _ = this;
+ _._self = t0;
+ _._target = t1;
+ _._receiver = t2;
+ _._name = t3;
+ },
+ TypeErrorImplementation: function TypeErrorImplementation(t0) {
+ this.message = t0;
+ },
+ RuntimeError: function RuntimeError(t0) {
+ this.message = t0;
+ },
+ _AssertionError: function _AssertionError(t0) {
+ this.message = t0;
+ },
+ JsLinkedHashMap: function JsLinkedHashMap(t0) {
+ var _ = this;
+ _.__js_helper$_length = 0;
+ _._last = _._first = _.__js_helper$_rest = _.__js_helper$_nums = _.__js_helper$_strings = null;
+ _._modifications = 0;
+ _.$ti = t0;
+ },
+ JsLinkedHashMap_values_closure: function JsLinkedHashMap_values_closure(t0) {
+ this.$this = t0;
+ },
+ JsLinkedHashMap_addAll_closure: function JsLinkedHashMap_addAll_closure(t0) {
+ this.$this = t0;
+ },
+ LinkedHashMapCell: function LinkedHashMapCell(t0, t1) {
+ var _ = this;
+ _.hashMapCellKey = t0;
+ _.hashMapCellValue = t1;
+ _._previous = _._next = null;
+ },
+ LinkedHashMapKeyIterable: function LinkedHashMapKeyIterable(t0, t1) {
+ this.__js_helper$_map = t0;
+ this.$ti = t1;
+ },
+ LinkedHashMapKeyIterator: function LinkedHashMapKeyIterator(t0, t1, t2) {
+ var _ = this;
+ _.__js_helper$_map = t0;
+ _._modifications = t1;
+ _.__js_helper$_current = _._cell = null;
+ _.$ti = t2;
+ },
+ initHooks_closure: function initHooks_closure(t0) {
+ this.getTag = t0;
+ },
+ initHooks_closure0: function initHooks_closure0(t0) {
+ this.getUnknownTag = t0;
+ },
+ initHooks_closure1: function initHooks_closure1(t0) {
+ this.prototypeForTag = t0;
+ },
+ JSSyntaxRegExp: function JSSyntaxRegExp(t0, t1) {
+ var _ = this;
+ _.pattern = t0;
+ _._nativeRegExp = t1;
+ _._nativeAnchoredRegExp = _._nativeGlobalRegExp = null;
+ },
+ _MatchImplementation: function _MatchImplementation(t0) {
+ this._match = t0;
+ },
+ _AllMatchesIterable: function _AllMatchesIterable(t0, t1, t2) {
+ this._re = t0;
+ this.__js_helper$_string = t1;
+ this._start = t2;
+ },
+ _AllMatchesIterator: function _AllMatchesIterator(t0, t1, t2) {
+ var _ = this;
+ _._regExp = t0;
+ _.__js_helper$_string = t1;
+ _._nextIndex = t2;
+ _.__js_helper$_current = null;
+ },
+ StringMatch: function StringMatch(t0, t1) {
+ this.start = t0;
+ this.pattern = t1;
+ },
+ _StringAllMatchesIterable: function _StringAllMatchesIterable(t0, t1, t2) {
+ this._input = t0;
+ this._pattern = t1;
+ this.__js_helper$_index = t2;
+ },
+ _StringAllMatchesIterator: function _StringAllMatchesIterator(t0, t1, t2) {
+ var _ = this;
+ _._input = t0;
+ _._pattern = t1;
+ _.__js_helper$_index = t2;
+ _.__js_helper$_current = null;
+ },
+ _ensureNativeList: function(list) {
+ return list;
+ },
+ NativeInt8List__create1: function(arg) {
+ return new Int8Array(arg);
+ },
+ _checkValidIndex: function(index, list, $length) {
+ if (index >>> 0 !== index || index >= $length)
+ throw H.wrapException(H.diagnoseIndexError(list, index));
+ },
+ _checkValidRange: function(start, end, $length) {
+ var t1;
+ if (!(start >>> 0 !== start))
+ if (end == null)
+ t1 = start > $length;
+ else
+ t1 = end >>> 0 !== end || start > end || end > $length;
+ else
+ t1 = true;
+ if (t1)
+ throw H.wrapException(H.diagnoseRangeError(start, end, $length));
+ if (end == null)
+ return $length;
+ return end;
+ },
+ NativeByteBuffer: function NativeByteBuffer() {
+ },
+ NativeTypedData: function NativeTypedData() {
+ },
+ NativeByteData: function NativeByteData() {
+ },
+ NativeTypedArray: function NativeTypedArray() {
+ },
+ NativeTypedArrayOfDouble: function NativeTypedArrayOfDouble() {
+ },
+ NativeTypedArrayOfInt: function NativeTypedArrayOfInt() {
+ },
+ NativeFloat32List: function NativeFloat32List() {
+ },
+ NativeFloat64List: function NativeFloat64List() {
+ },
+ NativeInt16List: function NativeInt16List() {
+ },
+ NativeInt32List: function NativeInt32List() {
+ },
+ NativeInt8List: function NativeInt8List() {
+ },
+ NativeUint16List: function NativeUint16List() {
+ },
+ NativeUint32List: function NativeUint32List() {
+ },
+ NativeUint8ClampedList: function NativeUint8ClampedList() {
+ },
+ NativeUint8List: function NativeUint8List() {
+ },
+ _NativeTypedArrayOfDouble_NativeTypedArray_ListMixin: function _NativeTypedArrayOfDouble_NativeTypedArray_ListMixin() {
+ },
+ _NativeTypedArrayOfDouble_NativeTypedArray_ListMixin_FixedLengthListMixin: function _NativeTypedArrayOfDouble_NativeTypedArray_ListMixin_FixedLengthListMixin() {
+ },
+ _NativeTypedArrayOfInt_NativeTypedArray_ListMixin: function _NativeTypedArrayOfInt_NativeTypedArray_ListMixin() {
+ },
+ _NativeTypedArrayOfInt_NativeTypedArray_ListMixin_FixedLengthListMixin: function _NativeTypedArrayOfInt_NativeTypedArray_ListMixin_FixedLengthListMixin() {
+ },
+ Rti__getFutureFromFutureOr: function(universe, rti) {
+ var future;
+ H.assertHelper(rti._kind === 8);
+ future = rti._precomputed1;
+ if (future == null) {
+ H.assertHelper(rti._kind === 8);
+ future = rti._precomputed1 = H._Universe__lookupInterfaceRti(universe, "Future", [rti._primary]);
+ }
+ return future;
+ },
+ Rti__isUnionOfFunctionType: function(rti) {
+ var kind = rti._kind;
+ if (kind === 6 || kind === 7 || kind === 8)
+ return H.Rti__isUnionOfFunctionType(rti._primary);
+ return kind === 11 || kind === 12;
+ },
+ Rti__getInterfaceTypeArguments: function(rti) {
+ H.assertHelper(rti._kind === 9);
+ return rti._rest;
+ },
+ Rti__getBindingArguments: function(rti) {
+ H.assertHelper(rti._kind === 10);
+ return rti._rest;
+ },
+ Rti__getFunctionParameters: function(rti) {
+ H.assertHelper(rti._kind === 11);
+ return rti._rest;
+ },
+ Rti__getGenericFunctionBounds: function(rti) {
+ H.assertHelper(rti._kind === 12);
+ return rti._rest;
+ },
+ Rti__getCanonicalRecipe: function(rti) {
+ var s = rti._canonicalRecipe;
+ if (H.assertTest(typeof s == "string"))
+ H.assertThrow("Missing canonical recipe");
+ return s;
+ },
+ findType: function(recipe) {
+ return H._Universe_eval(init.typeUniverse, recipe);
+ },
+ instantiatedGenericFunctionType: function(genericFunctionRti, instantiationRti) {
+ var bounds, typeArguments, cache, s, key, probe, rti;
+ if (genericFunctionRti == null)
+ return null;
+ bounds = H.Rti__getGenericFunctionBounds(genericFunctionRti);
+ typeArguments = H.Rti__getInterfaceTypeArguments(instantiationRti);
+ H.assertHelper(bounds.length === typeArguments.length);
+ cache = genericFunctionRti._bindCache;
+ if (cache == null)
+ cache = genericFunctionRti._bindCache = new Map();
+ s = instantiationRti._canonicalRecipe;
+ if (H.assertTest(typeof s == "string"))
+ H.assertThrow("Missing canonical recipe");
+ key = s;
+ probe = cache.get(key);
+ if (probe != null)
+ return probe;
+ H.assertHelper(genericFunctionRti._kind === 12);
+ rti = H._instantiate(init.typeUniverse, genericFunctionRti._primary, typeArguments, 0);
+ cache.set(key, rti);
+ return rti;
+ },
+ _instantiate: function(universe, rti, typeArguments, depth) {
+ var baseType, instantiatedBaseType, s, interfaceTypeArguments, instantiatedInterfaceTypeArguments, base, instantiatedBase, $arguments, instantiatedArguments, returnType, instantiatedReturnType, functionParameters, instantiatedFunctionParameters, bounds, instantiatedBounds, index,
+ _s24_ = "Missing canonical recipe",
+ t1 = rti._kind,
+ kind = t1;
+ switch (kind) {
+ case 5:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ return rti;
+ case 6:
+ baseType = rti._primary;
+ instantiatedBaseType = H._instantiate(universe, baseType, typeArguments, depth);
+ if (instantiatedBaseType === baseType)
+ return rti;
+ s = instantiatedBaseType._canonicalRecipe;
+ if (H.assertTest(typeof s == "string"))
+ H.assertThrow(_s24_);
+ return H._Universe__lookupUnaryRti(universe, 6, instantiatedBaseType, s + "*");
+ case 7:
+ baseType = rti._primary;
+ instantiatedBaseType = H._instantiate(universe, baseType, typeArguments, depth);
+ if (instantiatedBaseType === baseType)
+ return rti;
+ s = instantiatedBaseType._canonicalRecipe;
+ if (H.assertTest(typeof s == "string"))
+ H.assertThrow(_s24_);
+ return H._Universe__lookupUnaryRti(universe, 7, instantiatedBaseType, s + "?");
+ case 8:
+ baseType = rti._primary;
+ instantiatedBaseType = H._instantiate(universe, baseType, typeArguments, depth);
+ if (instantiatedBaseType === baseType)
+ return rti;
+ s = instantiatedBaseType._canonicalRecipe;
+ if (H.assertTest(typeof s == "string"))
+ H.assertThrow(_s24_);
+ return H._Universe__lookupUnaryRti(universe, 8, instantiatedBaseType, s + "/");
+ case 9:
+ interfaceTypeArguments = H.Rti__getInterfaceTypeArguments(rti);
+ instantiatedInterfaceTypeArguments = H._instantiateArray(universe, interfaceTypeArguments, typeArguments, depth);
+ if (instantiatedInterfaceTypeArguments === interfaceTypeArguments)
+ return rti;
+ H.assertHelper(rti._kind === 9);
+ return H._Universe__lookupInterfaceRti(universe, rti._primary, instantiatedInterfaceTypeArguments);
+ case 10:
+ H.assertHelper(t1 === 10);
+ base = rti._primary;
+ instantiatedBase = H._instantiate(universe, base, typeArguments, depth);
+ $arguments = H.Rti__getBindingArguments(rti);
+ instantiatedArguments = H._instantiateArray(universe, $arguments, typeArguments, depth);
+ if (instantiatedBase === base && instantiatedArguments === $arguments)
+ return rti;
+ return H._Universe__lookupBindingRti(universe, instantiatedBase, instantiatedArguments);
+ case 11:
+ H.assertHelper(t1 === 11);
+ returnType = rti._primary;
+ instantiatedReturnType = H._instantiate(universe, returnType, typeArguments, depth);
+ functionParameters = H.Rti__getFunctionParameters(rti);
+ instantiatedFunctionParameters = H._instantiateFunctionParameters(universe, functionParameters, typeArguments, depth);
+ if (instantiatedReturnType === returnType && instantiatedFunctionParameters === functionParameters)
+ return rti;
+ return H._Universe__lookupFunctionRti(universe, instantiatedReturnType, instantiatedFunctionParameters);
+ case 12:
+ bounds = H.Rti__getGenericFunctionBounds(rti);
+ depth += bounds.length;
+ instantiatedBounds = H._instantiateArray(universe, bounds, typeArguments, depth);
+ H.assertHelper(rti._kind === 12);
+ base = rti._primary;
+ instantiatedBase = H._instantiate(universe, base, typeArguments, depth);
+ if (instantiatedBounds === bounds && instantiatedBase === base)
+ return rti;
+ return H._Universe__lookupGenericFunctionRti(universe, instantiatedBase, instantiatedBounds);
+ case 13:
+ H.assertHelper(t1 === 13);
+ index = rti._primary;
+ if (index < depth)
+ return null;
+ return typeArguments[index - depth];
+ default:
+ throw H.wrapException(P.AssertionError$("Attempted to instantiate unexpected RTI kind " + kind));
+ }
+ },
+ _instantiateArray: function(universe, rtiArray, typeArguments, depth) {
+ var changed, i, rti, instantiatedRti,
+ $length = rtiArray.length,
+ result = [];
+ for (changed = false, i = 0; i < $length; ++i) {
+ rti = rtiArray[i];
+ instantiatedRti = H._instantiate(universe, rti, typeArguments, depth);
+ if (instantiatedRti !== rti)
+ changed = true;
+ result.push(instantiatedRti);
+ }
+ return changed ? result : rtiArray;
+ },
+ _instantiateNamed: function(universe, namedArray, typeArguments, depth) {
+ var result, changed, i, t1, rti, instantiatedRti,
+ $length = namedArray.length;
+ H.assertHelper(($length & 1) === 0);
+ result = [];
+ for (changed = false, i = 0; i < $length; i += 2) {
+ t1 = namedArray[i];
+ rti = namedArray[i + 1];
+ instantiatedRti = H._instantiate(universe, rti, typeArguments, depth);
+ if (instantiatedRti !== rti)
+ changed = true;
+ result.push(t1);
+ result.push(instantiatedRti);
+ }
+ return changed ? result : namedArray;
+ },
+ _instantiateFunctionParameters: function(universe, functionParameters, typeArguments, depth) {
+ var result,
+ requiredPositional = functionParameters._requiredPositional,
+ instantiatedRequiredPositional = H._instantiateArray(universe, requiredPositional, typeArguments, depth),
+ optionalPositional = functionParameters._optionalPositional,
+ instantiatedOptionalPositional = H._instantiateArray(universe, optionalPositional, typeArguments, depth),
+ optionalNamed = functionParameters._optionalNamed,
+ instantiatedOptionalNamed = H._instantiateNamed(universe, optionalNamed, typeArguments, depth);
+ if (instantiatedRequiredPositional === requiredPositional && instantiatedOptionalPositional === optionalPositional && instantiatedOptionalNamed === optionalNamed)
+ return functionParameters;
+ result = new H._FunctionParameters();
+ result._requiredPositional = instantiatedRequiredPositional;
+ result._optionalPositional = instantiatedOptionalPositional;
+ result._optionalNamed = instantiatedOptionalNamed;
+ return result;
+ },
+ closureFunctionType: function(closure) {
+ var signature = closure.$signature;
+ if (signature != null) {
+ if (typeof signature == "number")
+ return H.getTypeFromTypesTable(signature);
+ return closure.$signature();
+ }
+ return null;
+ },
+ instanceOrFunctionType: function(object, testRti) {
+ var rti;
+ if (H.Rti__isUnionOfFunctionType(testRti))
+ if (object instanceof H.Closure) {
+ rti = H.closureFunctionType(object);
+ if (rti != null)
+ return rti;
+ }
+ return H.instanceType(object);
+ },
+ instanceType: function(object) {
+ var rti;
+ if (object instanceof P.Object) {
+ rti = object.$ti;
+ return rti != null ? rti : H._instanceTypeFromConstructor(object);
+ }
+ if (Array.isArray(object))
+ return H._arrayInstanceType(object);
+ return H._instanceTypeFromConstructor(J.getInterceptor$(object));
+ },
+ _arrayInstanceType: function(object) {
+ var rti = object.$ti,
+ defaultRti = type$.JSArray_dynamic;
+ if (rti == null)
+ return defaultRti;
+ if (rti.constructor !== defaultRti.constructor)
+ return defaultRti;
+ return rti;
+ },
+ _instanceType: function(object) {
+ var rti = object.$ti;
+ return rti != null ? rti : H._instanceTypeFromConstructor(object);
+ },
+ _instanceTypeFromConstructor: function(instance) {
+ var $constructor = instance.constructor,
+ probe = $constructor.$ccache;
+ if (probe != null)
+ return probe;
+ return H._instanceTypeFromConstructorMiss(instance, $constructor);
+ },
+ _instanceTypeFromConstructorMiss: function(instance, $constructor) {
+ var effectiveConstructor = instance instanceof H.Closure ? instance.__proto__.__proto__.constructor : $constructor,
+ rti = H._Universe_findErasedType(init.typeUniverse, effectiveConstructor.name);
+ $constructor.$ccache = rti;
+ return rti;
+ },
+ getTypeFromTypesTable: function(_index) {
+ var rti,
+ index = _index,
+ table = init.types,
+ type = table[index];
+ if (typeof type == "string") {
+ rti = H._Universe_eval(init.typeUniverse, type);
+ table[index] = rti;
+ return rti;
+ }
+ return type;
+ },
+ createRuntimeType: function(rti) {
+ var type = rti._cachedRuntimeType;
+ if (type != null)
+ return type;
+ return rti._cachedRuntimeType = new H._Type(rti);
+ },
+ typeLiteral: function(recipe) {
+ return H.createRuntimeType(H._Universe_eval(init.typeUniverse, recipe));
+ },
+ _installSpecializedIsTest: function(object) {
+ var s, key, testRti = this,
+ t1 = testRti._kind,
+ isFn = H._generalIsTestImplementation;
+ if (H.isTopType(testRti, true)) {
+ isFn = H._isTop;
+ testRti._check = testRti._as = H._asTop;
+ } else if (t1 === 9) {
+ s = testRti._canonicalRecipe;
+ if (H.assertTest(typeof s == "string"))
+ H.assertThrow("Missing canonical recipe");
+ key = s;
+ if ("int" === key)
+ isFn = H._isInt;
+ else if ("double" === key)
+ isFn = H._isNum;
+ else if ("num" === key)
+ isFn = H._isNum;
+ else if ("String" === key)
+ isFn = H._isString;
+ else if ("bool" === key)
+ isFn = H._isBool;
+ else {
+ H.assertHelper(testRti._kind === 9);
+ t1 = testRti._primary;
+ if (H.Rti__getInterfaceTypeArguments(testRti).every(H.isLegacyTopType)) {
+ testRti._specializedTestResource = "$is" + t1;
+ isFn = H._isTestViaProperty;
+ }
+ }
+ }
+ testRti._is = isFn;
+ return testRti._is(object);
+ },
+ _generalIsTestImplementation: function(object) {
+ var testRti = this;
+ return H._isSubtype(init.typeUniverse, H.instanceOrFunctionType(object, testRti), null, testRti, null, true);
+ },
+ _isTestViaProperty: function(object) {
+ var tag = this._specializedTestResource;
+ if (object instanceof P.Object)
+ return !!object[tag];
+ return !!J.getInterceptor$(object)[tag];
+ },
+ _generalAsCheckImplementation: function(object) {
+ var testRti;
+ if (object == null)
+ return object;
+ testRti = this;
+ if (testRti._is(object))
+ return object;
+ throw H.wrapException(H._CastError$fromMessage(H._Error_compose(object, H.instanceOrFunctionType(object, testRti), H._rtiToString(testRti, null))));
+ },
+ _generalTypeCheckImplementation: function(object) {
+ var testRti;
+ if (object == null)
+ return object;
+ testRti = this;
+ if (testRti._is(object))
+ return object;
+ throw H.wrapException(H._TypeError$fromMessage(H._Error_compose(object, H.instanceOrFunctionType(object, testRti), H._rtiToString(testRti, null))));
+ },
+ checkTypeBound: function(type, bound, variable, methodName) {
+ var _null = null;
+ if (H._isSubtype(init.typeUniverse, type, _null, bound, _null, true))
+ return type;
+ throw H.wrapException(H._TypeError$fromMessage("The type argument '" + H.S(H._rtiToString(type, _null)) + "' is not a subtype of the type variable bound '" + H.S(H._rtiToString(bound, _null)) + "' of type variable '" + variable + "' in '" + H.S(methodName) + "'."));
+ },
+ _Error_compose: function(object, objectRti, checkedTypeDescription) {
+ var objectDescription = P.Error_safeToString(object),
+ objectTypeDescription = H._rtiToString(objectRti == null ? H.instanceType(object) : objectRti, null);
+ return objectDescription + ": type '" + H.S(objectTypeDescription) + "' is not a subtype of type '" + H.S(checkedTypeDescription) + "'";
+ },
+ _CastError$fromMessage: function(message) {
+ return new H._CastError("CastError: " + message);
+ },
+ _CastError__CastError$forType: function(object, type) {
+ return new H._CastError("CastError: " + H._Error_compose(object, null, type));
+ },
+ _TypeError$fromMessage: function(message) {
+ return new H._TypeError("TypeError: " + message);
+ },
+ _TypeError__TypeError$forType: function(object, type) {
+ return new H._TypeError("TypeError: " + H._Error_compose(object, null, type));
+ },
+ _isTop: function(object) {
+ return true;
+ },
+ _asTop: function(object) {
+ return object;
+ },
+ _isBool: function(object) {
+ return true === object || false === object;
+ },
+ _asBoolNullable: function(object) {
+ if (true === object || false === object)
+ return object;
+ if (object == null)
+ return object;
+ throw H.wrapException(H._CastError__CastError$forType(object, "bool"));
+ },
+ _checkBoolNullable: function(object) {
+ if (true === object || false === object)
+ return object;
+ if (object == null)
+ return object;
+ throw H.wrapException(H._TypeError__TypeError$forType(object, "bool"));
+ },
+ _asDoubleNullable: function(object) {
+ if (typeof object == "number")
+ return object;
+ if (object == null)
+ return object;
+ throw H.wrapException(H._CastError__CastError$forType(object, "double"));
+ },
+ _checkDoubleNullable: function(object) {
+ if (typeof object == "number")
+ return object;
+ if (object == null)
+ return object;
+ throw H.wrapException(H._TypeError__TypeError$forType(object, "double"));
+ },
+ _isInt: function(object) {
+ return typeof object == "number" && Math.floor(object) === object;
+ },
+ _asIntNullable: function(object) {
+ if (typeof object == "number" && Math.floor(object) === object)
+ return object;
+ if (object == null)
+ return object;
+ throw H.wrapException(H._CastError__CastError$forType(object, "int"));
+ },
+ _checkIntNullable: function(object) {
+ if (typeof object == "number" && Math.floor(object) === object)
+ return object;
+ if (object == null)
+ return object;
+ throw H.wrapException(H._TypeError__TypeError$forType(object, "int"));
+ },
+ _isNum: function(object) {
+ return typeof object == "number";
+ },
+ _asNumNullable: function(object) {
+ if (typeof object == "number")
+ return object;
+ if (object == null)
+ return object;
+ throw H.wrapException(H._CastError__CastError$forType(object, "num"));
+ },
+ _checkNumNullable: function(object) {
+ if (typeof object == "number")
+ return object;
+ if (object == null)
+ return object;
+ throw H.wrapException(H._TypeError__TypeError$forType(object, "num"));
+ },
+ _isString: function(object) {
+ return typeof object == "string";
+ },
+ _asStringNullable: function(object) {
+ if (typeof object == "string")
+ return object;
+ if (object == null)
+ return object;
+ throw H.wrapException(H._CastError__CastError$forType(object, "String"));
+ },
+ _checkStringNullable: function(object) {
+ if (typeof object == "string")
+ return object;
+ if (object == null)
+ return object;
+ throw H.wrapException(H._TypeError__TypeError$forType(object, "String"));
+ },
+ _rtiArrayToString: function(array, genericContext) {
+ var s, sep, i;
+ for (s = "", sep = "", i = 0; i < array.length; ++i, sep = ", ")
+ s += C.JSString_methods.$add(sep, H._rtiToString(array[i], genericContext));
+ return s;
+ },
+ _functionRtiToString: function(functionType, genericContext, bounds) {
+ var boundsLength, outerContextLength, offset, i, typeParametersText, typeSep, t1, t2, boundRti, parameters, requiredPositional, requiredPositionalLength, optionalPositional, optionalPositionalLength, optionalNamed, optionalNamedLength, returnTypeText, argumentsText, sep, _s2_ = ", ";
+ if (bounds != null) {
+ boundsLength = bounds.length;
+ if (genericContext == null) {
+ genericContext = H.setRuntimeTypeInfo([], type$.JSArray_String);
+ outerContextLength = null;
+ } else
+ outerContextLength = genericContext.length;
+ offset = genericContext.length;
+ for (i = boundsLength; i > 0; --i)
+ C.JSArray_methods.add$1(genericContext, "T" + (offset + i));
+ for (typeParametersText = "<", typeSep = "", i = 0; i < boundsLength; ++i, typeSep = _s2_) {
+ typeParametersText += typeSep;
+ t1 = genericContext.length;
+ t2 = t1 - 1 - i;
+ if (t2 < 0)
+ return H.ioore(genericContext, t2);
+ typeParametersText = C.JSString_methods.$add(typeParametersText, genericContext[t2]);
+ boundRti = bounds[i];
+ if (!H.isTopType(boundRti, true))
+ typeParametersText += C.JSString_methods.$add(" extends ", H._rtiToString(boundRti, genericContext));
+ }
+ typeParametersText += ">";
+ } else {
+ typeParametersText = "";
+ outerContextLength = null;
+ }
+ H.assertHelper(functionType._kind === 11);
+ t1 = functionType._primary;
+ parameters = H.Rti__getFunctionParameters(functionType);
+ requiredPositional = parameters._requiredPositional;
+ requiredPositionalLength = requiredPositional.length;
+ optionalPositional = parameters._optionalPositional;
+ optionalPositionalLength = optionalPositional.length;
+ optionalNamed = parameters._optionalNamed;
+ optionalNamedLength = optionalNamed.length;
+ H.assertHelper(optionalPositionalLength === 0 || optionalNamedLength === 0);
+ returnTypeText = H._rtiToString(t1, genericContext);
+ for (argumentsText = "", sep = "", i = 0; i < requiredPositionalLength; ++i, sep = _s2_)
+ argumentsText += C.JSString_methods.$add(sep, H._rtiToString(requiredPositional[i], genericContext));
+ if (optionalPositionalLength > 0) {
+ argumentsText += sep + "[";
+ for (sep = "", i = 0; i < optionalPositionalLength; ++i, sep = _s2_)
+ argumentsText += C.JSString_methods.$add(sep, H._rtiToString(optionalPositional[i], genericContext));
+ argumentsText += "]";
+ }
+ if (optionalNamedLength > 0) {
+ argumentsText += sep + "{";
+ for (sep = "", i = 0; i < optionalNamedLength; i += 2, sep = _s2_)
+ argumentsText += C.JSString_methods.$add(sep, H._rtiToString(optionalNamed[i + 1], genericContext)) + " " + optionalNamed[i];
+ argumentsText += "}";
+ }
+ if (outerContextLength != null)
+ genericContext.length = outerContextLength;
+ return typeParametersText + "(" + argumentsText + ") => " + H.S(returnTypeText);
+ },
+ _rtiToString: function(rti, genericContext) {
+ var $name, $arguments, t2,
+ t1 = rti._kind,
+ kind = t1;
+ if (kind === 5)
+ return "erased";
+ if (kind === 2)
+ return "dynamic";
+ if (kind === 3)
+ return "void";
+ if (kind === 1)
+ return "Never";
+ if (kind === 4)
+ return "any";
+ if (kind === 6) {
+ H.assertHelper(t1 === 6);
+ return H.S(H._rtiToString(rti._primary, genericContext)) + "*";
+ }
+ if (kind === 7) {
+ H.assertHelper(t1 === 7);
+ return H.S(H._rtiToString(rti._primary, genericContext)) + "?";
+ }
+ if (kind === 8) {
+ H.assertHelper(t1 === 8);
+ return "FutureOr<" + H.S(H._rtiToString(rti._primary, genericContext)) + ">";
+ }
+ if (kind === 9) {
+ H.assertHelper(t1 === 9);
+ $name = H._unminifyOrTag(rti._primary);
+ $arguments = H.Rti__getInterfaceTypeArguments(rti);
+ return $arguments.length !== 0 ? $name + ("<" + H._rtiArrayToString($arguments, genericContext) + ">") : $name;
+ }
+ if (kind === 11)
+ return H._functionRtiToString(rti, genericContext, null);
+ if (kind === 12) {
+ H.assertHelper(t1 === 12);
+ return H._functionRtiToString(rti._primary, genericContext, H.Rti__getGenericFunctionBounds(rti));
+ }
+ if (kind === 13) {
+ H.assertHelper(t1 === 13);
+ t1 = rti._primary;
+ t2 = genericContext.length;
+ t1 = t2 - 1 - t1;
+ if (t1 < 0 || t1 >= t2)
+ return H.ioore(genericContext, t1);
+ return genericContext[t1];
+ }
+ return "?";
+ },
+ _unminifyOrTag: function(rawClassName) {
+ var preserved = H.unmangleGlobalNameIfPreservedAnyways(rawClassName);
+ if (preserved != null)
+ return preserved;
+ return rawClassName;
+ },
+ _Universe_findRule: function(universe, targetType) {
+ var rule = universe.tR[targetType];
+ for (; typeof rule == "string";)
+ rule = universe.tR[rule];
+ return rule;
+ },
+ _Universe_findErasedType: function(universe, cls) {
+ var $length, erased, $arguments, i, $interface,
+ metadata = universe.eT,
+ probe = metadata[cls];
+ if (probe == null)
+ return H._Universe_eval(universe, cls);
+ else if (typeof probe == "number") {
+ $length = probe;
+ erased = H._Universe__lookupTerminalRti(universe, 5, "#");
+ $arguments = [];
+ for (i = 0; i < $length; ++i)
+ $arguments.push(erased);
+ $interface = H._Universe__lookupInterfaceRti(universe, cls, $arguments);
+ metadata[cls] = $interface;
+ return $interface;
+ } else
+ return probe;
+ },
+ _Universe_addRules: function(universe, rules) {
+ return H._Utils_objectAssign(universe.tR, rules);
+ },
+ _Universe_addErasedTypes: function(universe, types) {
+ return H._Utils_objectAssign(universe.eT, types);
+ },
+ _Universe_eval: function(universe, recipe) {
+ var rti,
+ cache = universe.eC,
+ probe = cache.get(recipe);
+ if (probe != null)
+ return probe;
+ rti = H._Universe__parseRecipe(universe, null, recipe);
+ cache.set(recipe, rti);
+ return rti;
+ },
+ _Universe_evalInEnvironment: function(universe, environment, recipe) {
+ var probe, rti,
+ cache = environment._evalCache;
+ if (cache == null)
+ cache = environment._evalCache = new Map();
+ probe = cache.get(recipe);
+ if (probe != null)
+ return probe;
+ rti = H._Universe__parseRecipe(universe, environment, recipe);
+ cache.set(recipe, rti);
+ return rti;
+ },
+ _Universe_bind: function(universe, environment, argumentsRti) {
+ var s, argumentsRecipe, probe, rti,
+ cache = environment._bindCache;
+ if (cache == null)
+ cache = environment._bindCache = new Map();
+ s = argumentsRti._canonicalRecipe;
+ if (H.assertTest(typeof s == "string"))
+ H.assertThrow("Missing canonical recipe");
+ argumentsRecipe = s;
+ probe = cache.get(argumentsRecipe);
+ if (probe != null)
+ return probe;
+ rti = H._Universe__lookupBindingRti(universe, environment, argumentsRti._kind === 10 ? H.Rti__getBindingArguments(argumentsRti) : [argumentsRti]);
+ cache.set(argumentsRecipe, rti);
+ return rti;
+ },
+ _Universe__parseRecipe: function(universe, environment, recipe) {
+ var rti = H._Parser_parse(H._Parser_create(universe, environment, recipe));
+ return rti;
+ },
+ _Universe__finishRti: function(universe, rti) {
+ var s = rti._canonicalRecipe;
+ if (H.assertTest(typeof s == "string"))
+ H.assertThrow("Missing canonical recipe");
+ universe.eC.set(s, rti);
+ rti._as = H._generalAsCheckImplementation;
+ rti._check = H._generalTypeCheckImplementation;
+ rti._is = H._installSpecializedIsTest;
+ return rti;
+ },
+ _Universe__lookupTerminalRti: function(universe, kind, canonicalRecipe) {
+ var rti,
+ probe = universe.eC.get(canonicalRecipe);
+ if (probe != null)
+ return probe;
+ rti = new H.Rti(null, null, null);
+ rti._kind = kind;
+ rti._canonicalRecipe = canonicalRecipe;
+ return H._Universe__finishRti(universe, rti);
+ },
+ _Universe__lookupUnaryRti: function(universe, kind, baseType, canonicalRecipe) {
+ var rti,
+ probe = universe.eC.get(canonicalRecipe);
+ if (probe != null)
+ return probe;
+ rti = new H.Rti(null, null, null);
+ rti._kind = kind;
+ rti._primary = baseType;
+ rti._canonicalRecipe = canonicalRecipe;
+ return H._Universe__finishRti(universe, rti);
+ },
+ _Universe__lookupGenericFunctionParameterRti: function(universe, index) {
+ var rti,
+ canonicalRecipe = "" + index + "^",
+ probe = universe.eC.get(canonicalRecipe);
+ if (probe != null)
+ return probe;
+ rti = new H.Rti(null, null, null);
+ rti._kind = 13;
+ rti._primary = index;
+ rti._canonicalRecipe = canonicalRecipe;
+ return H._Universe__finishRti(universe, rti);
+ },
+ _Universe__canonicalRecipeJoin: function($arguments) {
+ var s, sep, i, s0,
+ $length = $arguments.length;
+ for (s = "", sep = "", i = 0; i < $length; ++i, sep = ",") {
+ s0 = $arguments[i]._canonicalRecipe;
+ if (H.assertTest(typeof s0 == "string"))
+ H.assertThrow("Missing canonical recipe");
+ s += sep + s0;
+ }
+ return s;
+ },
+ _Universe__canonicalRecipeJoinNamed: function($arguments) {
+ var s, sep, i, t1, s0,
+ $length = $arguments.length;
+ H.assertHelper(($length & 1) === 0);
+ for (s = "", sep = "", i = 0; i < $length; i += 2, sep = ",") {
+ t1 = $arguments[i];
+ s0 = $arguments[i + 1]._canonicalRecipe;
+ if (H.assertTest(typeof s0 == "string"))
+ H.assertThrow("Missing canonical recipe");
+ s += sep + t1 + ":" + s0;
+ }
+ return s;
+ },
+ _Universe__lookupInterfaceRti: function(universe, $name, $arguments) {
+ var s, probe, rti;
+ H.assertHelper(typeof $name == "string");
+ s = $name;
+ if ($arguments.length !== 0)
+ s += "<" + H._Universe__canonicalRecipeJoin($arguments) + ">";
+ probe = universe.eC.get(s);
+ if (probe != null)
+ return probe;
+ rti = new H.Rti(null, null, null);
+ rti._kind = 9;
+ rti._primary = $name;
+ rti._rest = $arguments;
+ if ($arguments.length > 0)
+ rti._precomputed1 = $arguments[0];
+ rti._canonicalRecipe = s;
+ return H._Universe__finishRti(universe, rti);
+ },
+ _Universe__lookupBindingRti: function(universe, base, $arguments) {
+ var newBase, newArguments, s, probe, rti,
+ t1 = base._kind;
+ if (t1 === 10) {
+ H.assertHelper(t1 === 10);
+ newBase = base._primary;
+ newArguments = H.Rti__getBindingArguments(base).concat($arguments);
+ } else {
+ newArguments = $arguments;
+ newBase = base;
+ }
+ s = newBase._canonicalRecipe;
+ if (H.assertTest(typeof s == "string"))
+ H.assertThrow("Missing canonical recipe");
+ s = s + ";" + ("<" + H._Universe__canonicalRecipeJoin(newArguments) + ">");
+ probe = universe.eC.get(s);
+ if (probe != null)
+ return probe;
+ rti = new H.Rti(null, null, null);
+ rti._kind = 10;
+ rti._primary = newBase;
+ rti._rest = newArguments;
+ rti._canonicalRecipe = s;
+ return H._Universe__finishRti(universe, rti);
+ },
+ _Universe__lookupFunctionRti: function(universe, returnType, parameters) {
+ var requiredPositional, requiredPositionalLength, optionalPositional, optionalPositionalLength, optionalNamed, optionalNamedLength, recipe, key, probe, rti,
+ s = returnType._canonicalRecipe;
+ if (H.assertTest(typeof s == "string"))
+ H.assertThrow("Missing canonical recipe");
+ requiredPositional = parameters._requiredPositional;
+ requiredPositionalLength = requiredPositional.length;
+ optionalPositional = parameters._optionalPositional;
+ optionalPositionalLength = optionalPositional.length;
+ optionalNamed = parameters._optionalNamed;
+ optionalNamedLength = optionalNamed.length;
+ H.assertHelper(optionalPositionalLength === 0 || optionalNamedLength === 0);
+ recipe = "(" + H._Universe__canonicalRecipeJoin(requiredPositional);
+ if (optionalPositionalLength > 0)
+ recipe += (requiredPositionalLength > 0 ? "," : "") + "[" + H._Universe__canonicalRecipeJoin(optionalPositional) + "]";
+ if (optionalNamedLength > 0)
+ recipe += (requiredPositionalLength > 0 ? "," : "") + "{" + H._Universe__canonicalRecipeJoinNamed(optionalNamed) + "}";
+ key = s + (recipe + ")");
+ probe = universe.eC.get(key);
+ if (probe != null)
+ return probe;
+ rti = new H.Rti(null, null, null);
+ rti._kind = 11;
+ rti._primary = returnType;
+ rti._rest = parameters;
+ rti._canonicalRecipe = key;
+ return H._Universe__finishRti(universe, rti);
+ },
+ _Universe__lookupGenericFunctionRti: function(universe, baseFunctionType, bounds) {
+ var key, probe, rti,
+ s = baseFunctionType._canonicalRecipe;
+ if (H.assertTest(typeof s == "string"))
+ H.assertThrow("Missing canonical recipe");
+ key = s + "<" + H._Universe__canonicalRecipeJoin(bounds) + ">";
+ probe = universe.eC.get(key);
+ if (probe != null)
+ return probe;
+ rti = new H.Rti(null, null, null);
+ rti._kind = 12;
+ rti._primary = baseFunctionType;
+ rti._rest = bounds;
+ rti._canonicalRecipe = key;
+ return H._Universe__finishRti(universe, rti);
+ },
+ _Parser_create: function(universe, environment, recipe) {
+ return {u: universe, e: environment, r: recipe, s: [], p: 0};
+ },
+ _Parser_parse: function(parser) {
+ var t1, i, ch, t2, t3, universe, array, head, base, u, s, parameters, optionalPositional, optionalNamed, item,
+ _s24_ = "Missing canonical recipe",
+ source = parser.r,
+ stack = parser.s;
+ for (t1 = source.length, i = 0; i < t1;) {
+ ch = source.charCodeAt(i);
+ if (ch >= 48 && ch <= 57)
+ i = H._Parser_handleDigit(i + 1, ch, source, stack);
+ else if ((((ch | 32) >>> 0) - 97 & 65535) < 26 || ch === 95 || ch === 36)
+ i = H._Parser_handleIdentifier(parser, i, source, stack, false);
+ else if (ch === 46)
+ i = H._Parser_handleIdentifier(parser, i, source, stack, true);
+ else {
+ ++i;
+ switch (ch) {
+ case 44:
+ break;
+ case 58:
+ break;
+ case 59:
+ stack.push(H._Parser_toType(parser.u, parser.e, stack.pop()));
+ break;
+ case 94:
+ t2 = parser.u;
+ t3 = stack.pop();
+ H.assertHelper(typeof t3 == "number");
+ stack.push(H._Universe__lookupGenericFunctionParameterRti(t2, t3));
+ break;
+ case 35:
+ stack.push(H._Universe__lookupTerminalRti(parser.u, 5, "#"));
+ break;
+ case 64:
+ stack.push(H._Universe__lookupTerminalRti(parser.u, 2, "@"));
+ break;
+ case 126:
+ stack.push(H._Universe__lookupTerminalRti(parser.u, 3, "~"));
+ break;
+ case 60:
+ stack.push(parser.p);
+ parser.p = stack.length;
+ break;
+ case 62:
+ universe = parser.u;
+ array = stack.splice(parser.p);
+ H._Parser_toTypes(parser.u, parser.e, array);
+ parser.p = stack.pop();
+ head = stack.pop();
+ if (typeof head == "string")
+ stack.push(H._Universe__lookupInterfaceRti(universe, head, array));
+ else {
+ base = H._Parser_toType(universe, parser.e, head);
+ switch (base._kind) {
+ case 11:
+ stack.push(H._Universe__lookupGenericFunctionRti(universe, base, array));
+ break;
+ default:
+ stack.push(H._Universe__lookupBindingRti(universe, base, array));
+ break;
+ }
+ }
+ break;
+ case 38:
+ H._Parser_handleExtendedOperations(parser, stack);
+ break;
+ case 42:
+ u = parser.u;
+ t2 = H._Parser_toType(u, parser.e, stack.pop());
+ s = t2._canonicalRecipe;
+ if (H.assertTest(typeof s == "string"))
+ H.assertThrow(_s24_);
+ stack.push(H._Universe__lookupUnaryRti(u, 6, t2, s + "*"));
+ break;
+ case 63:
+ u = parser.u;
+ t2 = H._Parser_toType(u, parser.e, stack.pop());
+ s = t2._canonicalRecipe;
+ if (H.assertTest(typeof s == "string"))
+ H.assertThrow(_s24_);
+ stack.push(H._Universe__lookupUnaryRti(u, 7, t2, s + "?"));
+ break;
+ case 47:
+ u = parser.u;
+ t2 = H._Parser_toType(u, parser.e, stack.pop());
+ s = t2._canonicalRecipe;
+ if (H.assertTest(typeof s == "string"))
+ H.assertThrow(_s24_);
+ stack.push(H._Universe__lookupUnaryRti(u, 8, t2, s + "/"));
+ break;
+ case 40:
+ stack.push(parser.p);
+ parser.p = stack.length;
+ break;
+ case 41:
+ universe = parser.u;
+ parameters = new H._FunctionParameters();
+ optionalPositional = universe.sEA;
+ optionalNamed = universe.sEA;
+ head = stack.pop();
+ if (typeof head == "number")
+ switch (head) {
+ case -1:
+ optionalPositional = stack.pop();
+ break;
+ case -2:
+ optionalNamed = stack.pop();
+ break;
+ default:
+ stack.push(head);
+ break;
+ }
+ else
+ stack.push(head);
+ array = stack.splice(parser.p);
+ H._Parser_toTypes(parser.u, parser.e, array);
+ parser.p = stack.pop();
+ parameters._requiredPositional = array;
+ parameters._optionalPositional = optionalPositional;
+ parameters._optionalNamed = optionalNamed;
+ stack.push(H._Universe__lookupFunctionRti(universe, H._Parser_toType(universe, parser.e, stack.pop()), parameters));
+ break;
+ case 91:
+ stack.push(parser.p);
+ parser.p = stack.length;
+ break;
+ case 93:
+ array = stack.splice(parser.p);
+ H._Parser_toTypes(parser.u, parser.e, array);
+ parser.p = stack.pop();
+ stack.push(array);
+ stack.push(-1);
+ break;
+ case 123:
+ stack.push(parser.p);
+ parser.p = stack.length;
+ break;
+ case 125:
+ array = stack.splice(parser.p);
+ H._Parser_toTypesNamed(parser.u, parser.e, array);
+ parser.p = stack.pop();
+ stack.push(array);
+ stack.push(-2);
+ break;
+ default:
+ throw "Bad character " + ch;
+ }
+ }
+ }
+ item = stack.pop();
+ return H._Parser_toType(parser.u, parser.e, item);
+ },
+ _Parser_handleDigit: function(i, digit, source, stack) {
+ var t1, ch,
+ value = digit - 48;
+ for (t1 = source.length; i < t1; ++i) {
+ ch = source.charCodeAt(i);
+ if (!(ch >= 48 && ch <= 57))
+ break;
+ value = value * 10 + (ch - 48);
+ }
+ stack.push(value);
+ return i;
+ },
+ _Parser_handleIdentifier: function(parser, start, source, stack, hasPeriod) {
+ var t1, ch, t2, string, environment, rule, recipe,
+ i = start + 1;
+ for (t1 = source.length; i < t1; ++i) {
+ ch = source.charCodeAt(i);
+ if (ch === 46) {
+ if (hasPeriod)
+ break;
+ hasPeriod = true;
+ } else {
+ if (!((((ch | 32) >>> 0) - 97 & 65535) < 26 || ch === 95 || ch === 36))
+ t2 = ch >= 48 && ch <= 57;
+ else
+ t2 = true;
+ if (!t2)
+ break;
+ }
+ }
+ string = source.substring(start, i);
+ if (hasPeriod) {
+ t1 = parser.u;
+ environment = parser.e;
+ t2 = environment._kind;
+ if (t2 === 10) {
+ H.assertHelper(t2 === 10);
+ environment = environment._primary;
+ }
+ H.assertHelper(environment._kind === 9);
+ rule = H._Universe_findRule(t1, environment._primary);
+ H.assertHelper(rule != null);
+ recipe = rule[string];
+ if (recipe == null)
+ H.throwExpression('No "' + string + '" in "' + H.Rti__getCanonicalRecipe(environment) + '"');
+ stack.push(H._Universe_evalInEnvironment(t1, environment, recipe));
+ } else
+ stack.push(string);
+ return i;
+ },
+ _Parser_handleExtendedOperations: function(parser, stack) {
+ var $top = stack.pop();
+ if (0 === $top) {
+ stack.push(H._Universe__lookupTerminalRti(parser.u, 1, "0&"));
+ return;
+ }
+ if (1 === $top) {
+ stack.push(H._Universe__lookupTerminalRti(parser.u, 4, "1&"));
+ return;
+ }
+ throw H.wrapException(P.AssertionError$("Unexpected extended operation " + H.S($top)));
+ },
+ _Parser_toType: function(universe, environment, item) {
+ if (typeof item == "string")
+ return H._Universe__lookupInterfaceRti(universe, item, universe.sEA);
+ else if (typeof item == "number")
+ return H._Parser_indexToType(universe, environment, item);
+ else
+ return item;
+ },
+ _Parser_toTypes: function(universe, environment, items) {
+ var i,
+ $length = items.length;
+ for (i = 0; i < $length; ++i)
+ items[i] = H._Parser_toType(universe, environment, items[i]);
+ },
+ _Parser_toTypesNamed: function(universe, environment, items) {
+ var i,
+ $length = items.length;
+ H.assertHelper(($length & 1) === 0);
+ for (i = 1; i < $length; i += 2)
+ items[i] = H._Parser_toType(universe, environment, items[i]);
+ },
+ _Parser_indexToType: function(universe, environment, index) {
+ var typeArguments, len,
+ t1 = environment._kind,
+ kind = t1;
+ if (kind === 10) {
+ if (index === 0) {
+ H.assertHelper(t1 === 10);
+ return environment._primary;
+ }
+ typeArguments = H.Rti__getBindingArguments(environment);
+ len = typeArguments.length;
+ if (index <= len)
+ return typeArguments[index - 1];
+ index -= len;
+ H.assertHelper(t1 === 10);
+ environment = environment._primary;
+ kind = environment._kind;
+ } else if (index === 0)
+ return environment;
+ if (kind !== 9)
+ throw H.wrapException(P.AssertionError$("Indexed base must be an interface type"));
+ typeArguments = H.Rti__getInterfaceTypeArguments(environment);
+ if (index <= typeArguments.length)
+ return typeArguments[index - 1];
+ throw H.wrapException(P.AssertionError$("Bad index " + index + " for " + environment.toString$0(0)));
+ },
+ _isSubtype: function(universe, s, sEnv, t, tEnv, isLegacy) {
+ var sKind, leftTypeVariable, t1, tKind, sBounds, tBounds;
+ if (s === t)
+ return true;
+ if (H.isTopType(t, true))
+ return true;
+ sKind = s._kind;
+ if (sKind === 4)
+ return true;
+ if (H.isTopType(s, true))
+ return false;
+ if (s === type$.Null)
+ return true;
+ leftTypeVariable = sKind === 13;
+ if (leftTypeVariable) {
+ H.assertHelper(s._kind === 13);
+ if (H._isSubtype(universe, sEnv[s._primary], sEnv, t, tEnv, true))
+ return true;
+ }
+ t1 = t._kind;
+ tKind = t1;
+ if (sKind === 6) {
+ H.assertHelper(s._kind === 6);
+ return H._isSubtype(universe, s._primary, sEnv, t, tEnv, true);
+ }
+ if (tKind === 6) {
+ H.assertHelper(t1 === 6);
+ t1 = t._primary;
+ return H._isSubtype(universe, s, sEnv, t1, tEnv, true);
+ }
+ if (sKind === 8) {
+ H.assertHelper(s._kind === 8);
+ if (!H._isSubtype(universe, s._primary, sEnv, t, tEnv, true))
+ return false;
+ return H._isSubtype(universe, H.Rti__getFutureFromFutureOr(universe, s), sEnv, t, tEnv, true);
+ }
+ if (sKind === 7) {
+ H.assertHelper(s._kind === 7);
+ t1 = H._isSubtype(universe, s._primary, sEnv, t, tEnv, true);
+ return t1;
+ }
+ if (tKind === 8) {
+ H.assertHelper(t1 === 8);
+ if (H._isSubtype(universe, s, sEnv, t._primary, tEnv, true))
+ return true;
+ return H._isSubtype(universe, s, sEnv, H.Rti__getFutureFromFutureOr(universe, t), tEnv, true);
+ }
+ if (tKind === 7) {
+ H.assertHelper(t1 === 7);
+ t1 = H._isSubtype(universe, s, sEnv, t._primary, tEnv, true);
+ return t1;
+ }
+ if (leftTypeVariable)
+ return false;
+ t1 = sKind !== 11;
+ if ((!t1 || sKind === 12) && t === type$.Function)
+ return true;
+ if (tKind === 12) {
+ if (s === type$.JavaScriptFunction)
+ return true;
+ if (sKind !== 12)
+ return false;
+ sBounds = H.Rti__getGenericFunctionBounds(s);
+ tBounds = H.Rti__getGenericFunctionBounds(t);
+ if (!H.typesEqual(sBounds, tBounds, true))
+ return false;
+ sEnv = sEnv == null ? sBounds : sBounds.concat(sEnv);
+ tEnv = tEnv == null ? tBounds : tBounds.concat(tEnv);
+ H.assertHelper(s._kind === 12);
+ t1 = s._primary;
+ H.assertHelper(t._kind === 12);
+ return H._isFunctionSubtype(universe, t1, sEnv, t._primary, tEnv, true);
+ }
+ if (tKind === 11) {
+ if (s === type$.JavaScriptFunction)
+ return true;
+ if (t1)
+ return false;
+ return H._isFunctionSubtype(universe, s, sEnv, t, tEnv, true);
+ }
+ if (sKind === 9) {
+ if (tKind !== 9)
+ return false;
+ return H._isInterfaceSubtype(universe, s, sEnv, t, tEnv, true);
+ }
+ return false;
+ },
+ _isFunctionSubtype: function(universe, s, sEnv, t, tEnv, isLegacy) {
+ var t1, sParameters, tParameters, sRequiredPositional, tRequiredPositional, sRequiredPositionalLength, tRequiredPositionalLength, requiredPositionalDelta, sOptionalPositional, tOptionalPositional, sOptionalPositionalLength, tOptionalPositionalLength, i, sOptionalNamed, tOptionalNamed, sOptionalNamedLength, tOptionalNamedLength, j, tName, sName;
+ H.assertHelper(s._kind === 11);
+ H.assertHelper(t._kind === 11);
+ H.assertHelper(s._kind === 11);
+ t1 = s._primary;
+ H.assertHelper(t._kind === 11);
+ if (!H._isSubtype(universe, t1, sEnv, t._primary, tEnv, true))
+ return false;
+ sParameters = H.Rti__getFunctionParameters(s);
+ tParameters = H.Rti__getFunctionParameters(t);
+ sRequiredPositional = sParameters._requiredPositional;
+ tRequiredPositional = tParameters._requiredPositional;
+ sRequiredPositionalLength = sRequiredPositional.length;
+ tRequiredPositionalLength = tRequiredPositional.length;
+ if (sRequiredPositionalLength > tRequiredPositionalLength)
+ return false;
+ requiredPositionalDelta = tRequiredPositionalLength - sRequiredPositionalLength;
+ sOptionalPositional = sParameters._optionalPositional;
+ tOptionalPositional = tParameters._optionalPositional;
+ sOptionalPositionalLength = sOptionalPositional.length;
+ tOptionalPositionalLength = tOptionalPositional.length;
+ if (sRequiredPositionalLength + sOptionalPositionalLength < tRequiredPositionalLength + tOptionalPositionalLength)
+ return false;
+ for (i = 0; i < sRequiredPositionalLength; ++i) {
+ t1 = sRequiredPositional[i];
+ if (!H._isSubtype(universe, tRequiredPositional[i], tEnv, t1, sEnv, true))
+ return false;
+ }
+ for (i = 0; i < requiredPositionalDelta; ++i) {
+ t1 = sOptionalPositional[i];
+ if (!H._isSubtype(universe, tRequiredPositional[sRequiredPositionalLength + i], tEnv, t1, sEnv, true))
+ return false;
+ }
+ for (i = 0; i < tOptionalPositionalLength; ++i) {
+ t1 = sOptionalPositional[requiredPositionalDelta + i];
+ if (!H._isSubtype(universe, tOptionalPositional[i], tEnv, t1, sEnv, true))
+ return false;
+ }
+ sOptionalNamed = sParameters._optionalNamed;
+ tOptionalNamed = tParameters._optionalNamed;
+ sOptionalNamedLength = sOptionalNamed.length;
+ tOptionalNamedLength = tOptionalNamed.length;
+ for (i = 0, j = 0; j < tOptionalNamedLength; j += 2) {
+ tName = tOptionalNamed[j];
+ do {
+ if (i >= sOptionalNamedLength)
+ return false;
+ sName = sOptionalNamed[i];
+ i += 2;
+ } while (sName < tName);
+ if (tName < sName)
+ return false;
+ t1 = sOptionalNamed[i - 1];
+ if (!H._isSubtype(universe, tOptionalNamed[j + 1], tEnv, t1, sEnv, true))
+ return false;
+ }
+ return true;
+ },
+ _isInterfaceSubtype: function(universe, s, sEnv, t, tEnv, isLegacy) {
+ var sName, tName, sArgs, tArgs, $length, i, t1, t2, rule, supertypeArgs;
+ H.assertHelper(s._kind === 9);
+ sName = s._primary;
+ H.assertHelper(t._kind === 9);
+ tName = t._primary;
+ if (sName === tName) {
+ sArgs = H.Rti__getInterfaceTypeArguments(s);
+ tArgs = H.Rti__getInterfaceTypeArguments(t);
+ $length = sArgs.length;
+ H.assertHelper($length === tArgs.length);
+ for (i = 0; i < $length; ++i) {
+ t1 = sArgs[i];
+ t2 = tArgs[i];
+ if (!H._isSubtype(universe, t1, sEnv, t2, tEnv, true))
+ return false;
+ }
+ return true;
+ }
+ rule = H._Universe_findRule(universe, sName);
+ if (rule == null)
+ return false;
+ supertypeArgs = rule[tName];
+ if (supertypeArgs == null)
+ return false;
+ $length = supertypeArgs.length;
+ tArgs = H.Rti__getInterfaceTypeArguments(t);
+ H.assertHelper($length === tArgs.length);
+ for (i = 0; i < $length; ++i)
+ if (!H._isSubtype(universe, H._Universe_evalInEnvironment(universe, s, supertypeArgs[i]), sEnv, tArgs[i], tEnv, true))
+ return false;
+ return true;
+ },
+ typeEqual: function(s, t, isLegacy) {
+ var t1, sKind, t2;
+ if (s === t)
+ return true;
+ if (H.isTopType(s, true))
+ return H.isTopType(t, true);
+ t1 = s._kind;
+ sKind = t1;
+ if (sKind !== t._kind)
+ return false;
+ switch (sKind) {
+ case 6:
+ case 7:
+ case 8:
+ return H.typeEqual(s._primary, t._primary, true);
+ case 9:
+ H.assertHelper(t1 === 9);
+ t1 = s._primary;
+ H.assertHelper(t._kind === 9);
+ if (t1 !== t._primary)
+ return false;
+ return H.typesEqual(H.Rti__getInterfaceTypeArguments(s), H.Rti__getInterfaceTypeArguments(t), true);
+ case 10:
+ H.assertHelper(t1 === 10);
+ t1 = s._primary;
+ H.assertHelper(t._kind === 10);
+ return H.typeEqual(t1, t._primary, true) && H.typesEqual(H.Rti__getBindingArguments(s), H.Rti__getBindingArguments(t), true);
+ case 11:
+ H.assertHelper(t1 === 11);
+ t1 = s._primary;
+ H.assertHelper(t._kind === 11);
+ if (H.typeEqual(t1, t._primary, true)) {
+ t1 = H.Rti__getFunctionParameters(s);
+ t2 = H.Rti__getFunctionParameters(t);
+ t1 = H.typesEqual(t1._requiredPositional, t2._requiredPositional, true) && H.typesEqual(t1._optionalPositional, t2._optionalPositional, true) && H.namedTypesEqual(t1._optionalNamed, t2._optionalNamed, true);
+ } else
+ t1 = false;
+ return t1;
+ case 12:
+ H.assertHelper(t1 === 12);
+ t1 = s._primary;
+ H.assertHelper(t._kind === 12);
+ return H.typeEqual(t1, t._primary, true) && H.typesEqual(H.Rti__getGenericFunctionBounds(s), H.Rti__getGenericFunctionBounds(t), true);
+ default:
+ return false;
+ }
+ },
+ typesEqual: function(sArray, tArray, isLegacy) {
+ var i,
+ sLength = sArray.length;
+ if (sLength !== tArray.length)
+ return false;
+ for (i = 0; i < sLength; ++i)
+ if (!H.typeEqual(sArray[i], tArray[i], true))
+ return false;
+ return true;
+ },
+ namedTypesEqual: function(sArray, tArray, isLegacy) {
+ var i, t1,
+ sLength = sArray.length,
+ tLength = tArray.length;
+ H.assertHelper((sLength & 1) === 0);
+ H.assertHelper((tLength & 1) === 0);
+ if (sLength !== tLength)
+ return false;
+ for (i = 0; i < sLength; i += 2) {
+ if (sArray[i] !== tArray[i])
+ return false;
+ t1 = i + 1;
+ if (!H.typeEqual(sArray[t1], tArray[t1], true))
+ return false;
+ }
+ return true;
+ },
+ isLegacyTopType: function(t) {
+ return H.isTopType(t, true);
+ },
+ isTopType: function(t, isLegacy) {
+ var t1, kind;
+ if (t === type$.Object)
+ return true;
+ t1 = t._kind;
+ kind = t1;
+ if (kind !== 2)
+ if (kind !== 3)
+ if (kind !== 4)
+ if (kind !== 5)
+ if (kind === 8) {
+ H.assertHelper(t1 === 8);
+ t1 = H.isTopType(t._primary, true);
+ } else
+ t1 = false;
+ else
+ t1 = true;
+ else
+ t1 = true;
+ else
+ t1 = true;
+ else
+ t1 = true;
+ return t1;
+ },
+ _Utils_objectAssign: function(o, other) {
+ var i, key,
+ keys = Object.keys(other),
+ $length = keys.length;
+ for (i = 0; i < $length; ++i) {
+ key = keys[i];
+ o[key] = other[key];
+ }
+ },
+ Rti: function Rti(t0, t1, t2) {
+ var _ = this;
+ _._as = t0;
+ _._check = t1;
+ _._is = t2;
+ _._cachedRuntimeType = _._specializedTestResource = _._precomputed1 = null;
+ _._kind = 0;
+ _._canonicalRecipe = _._bindCache = _._evalCache = _._rest = _._primary = null;
+ },
+ _FunctionParameters: function _FunctionParameters() {
+ this._optionalNamed = this._optionalPositional = this._requiredPositional = null;
+ },
+ _Type: function _Type(t0) {
+ this._rti = t0;
+ this._hashCode = null;
+ },
+ _Error: function _Error() {
+ },
+ _CastError: function _CastError(t0) {
+ this._message = t0;
+ },
+ _TypeError: function _TypeError(t0) {
+ this._message = t0;
+ },
+ extractKeys: function(victim) {
+ return J.JSArray_JSArray$markFixed(victim ? Object.keys(victim) : [], type$.dynamic);
+ },
+ unmangleGlobalNameIfPreservedAnyways: function($name) {
+ return init.mangledGlobalNames[$name];
+ },
+ printString: function(string) {
+ if (typeof dartPrint == "function") {
+ dartPrint(string);
+ return;
+ }
+ if (typeof console == "object" && typeof console.log != "undefined") {
+ console.log(string);
+ return;
+ }
+ if (typeof window == "object")
+ return;
+ if (typeof print == "function") {
+ print(string);
+ return;
+ }
+ throw "Unable to print message: " + String(string);
+ }
+ },
+ J = {
+ makeDispatchRecord: function(interceptor, proto, extension, indexability) {
+ return {i: interceptor, p: proto, e: extension, x: indexability};
+ },
+ getNativeInterceptor: function(object) {
+ var proto, objectProto, $constructor, interceptor,
+ record = object[init.dispatchPropertyName];
+ if (record == null)
+ if ($.initNativeDispatchFlag == null) {
+ H.initNativeDispatch();
+ record = object[init.dispatchPropertyName];
+ }
+ if (record != null) {
+ proto = record.p;
+ if (false === proto)
+ return record.i;
+ if (true === proto)
+ return object;
+ objectProto = Object.getPrototypeOf(object);
+ if (proto === objectProto)
+ return record.i;
+ if (record.e === objectProto)
+ throw H.wrapException(P.UnimplementedError$("Return interceptor for " + H.S(proto(object, record))));
+ }
+ $constructor = object.constructor;
+ interceptor = $constructor == null ? null : $constructor[$.$get$JS_INTEROP_INTERCEPTOR_TAG()];
+ if (interceptor != null)
+ return interceptor;
+ interceptor = H.lookupAndCacheInterceptor(object);
+ if (interceptor != null)
+ return interceptor;
+ if (typeof object == "function")
+ return C.JavaScriptFunction_methods;
+ proto = Object.getPrototypeOf(object);
+ if (proto == null)
+ return C.PlainJavaScriptObject_methods;
+ if (proto === Object.prototype)
+ return C.PlainJavaScriptObject_methods;
+ if (typeof $constructor == "function") {
+ Object.defineProperty($constructor, $.$get$JS_INTEROP_INTERCEPTOR_TAG(), {value: C.UnknownJavaScriptObject_methods, enumerable: false, writable: true, configurable: true});
+ return C.UnknownJavaScriptObject_methods;
+ }
+ return C.UnknownJavaScriptObject_methods;
+ },
+ JSArray_JSArray$fixed: function($length, $E) {
+ if (!H._isInt($length))
+ throw H.wrapException(P.ArgumentError$value($length, "length", "is not an integer"));
+ if ($length < 0 || $length > 4294967295)
+ throw H.wrapException(P.RangeError$range($length, 0, 4294967295, "length", null));
+ return J.JSArray_JSArray$markFixed(new Array($length), $E);
+ },
+ JSArray_JSArray$markFixed: function(allocation, $E) {
+ return J.JSArray_markFixedList(H.setRuntimeTypeInfo(allocation, $E._eval$1("JSArray<0>")));
+ },
+ JSArray_markFixedList: function(list) {
+ list.fixed$length = Array;
+ return list;
+ },
+ JSString__isWhitespace: function(codeUnit) {
+ if (codeUnit < 256)
+ switch (codeUnit) {
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 32:
+ case 133:
+ case 160:
+ return true;
+ default:
+ return false;
+ }
+ switch (codeUnit) {
+ case 5760:
+ case 8192:
+ case 8193:
+ case 8194:
+ case 8195:
+ case 8196:
+ case 8197:
+ case 8198:
+ case 8199:
+ case 8200:
+ case 8201:
+ case 8202:
+ case 8232:
+ case 8233:
+ case 8239:
+ case 8287:
+ case 12288:
+ case 65279:
+ return true;
+ default:
+ return false;
+ }
+ },
+ JSString__skipLeadingWhitespace: function(string, index) {
+ var t1, codeUnit;
+ for (t1 = string.length; index < t1;) {
+ codeUnit = C.JSString_methods._codeUnitAt$1(string, index);
+ if (codeUnit !== 32 && codeUnit !== 13 && !J.JSString__isWhitespace(codeUnit))
+ break;
+ ++index;
+ }
+ return index;
+ },
+ JSString__skipTrailingWhitespace: function(string, index) {
+ var index0, codeUnit;
+ for (; index > 0; index = index0) {
+ index0 = index - 1;
+ codeUnit = C.JSString_methods.codeUnitAt$1(string, index0);
+ if (codeUnit !== 32 && codeUnit !== 13 && !J.JSString__isWhitespace(codeUnit))
+ break;
+ }
+ return index;
+ },
+ getInterceptor$: function(receiver) {
+ if (typeof receiver == "number") {
+ if (Math.floor(receiver) == receiver)
+ return J.JSInt.prototype;
+ return J.JSDouble.prototype;
+ }
+ if (typeof receiver == "string")
+ return J.JSString.prototype;
+ if (receiver == null)
+ return J.JSNull.prototype;
+ if (typeof receiver == "boolean")
+ return J.JSBool.prototype;
+ if (receiver.constructor == Array)
+ return J.JSArray.prototype;
+ if (typeof receiver != "object") {
+ if (typeof receiver == "function")
+ return J.JavaScriptFunction.prototype;
+ return receiver;
+ }
+ if (receiver instanceof P.Object)
+ return receiver;
+ return J.getNativeInterceptor(receiver);
+ },
+ getInterceptor$ansx: function(receiver) {
+ if (typeof receiver == "number")
+ return J.JSNumber.prototype;
+ if (typeof receiver == "string")
+ return J.JSString.prototype;
+ if (receiver == null)
+ return receiver;
+ if (receiver.constructor == Array)
+ return J.JSArray.prototype;
+ if (typeof receiver != "object") {
+ if (typeof receiver == "function")
+ return J.JavaScriptFunction.prototype;
+ return receiver;
+ }
+ if (receiver instanceof P.Object)
+ return receiver;
+ return J.getNativeInterceptor(receiver);
+ },
+ getInterceptor$asx: function(receiver) {
+ if (typeof receiver == "string")
+ return J.JSString.prototype;
+ if (receiver == null)
+ return receiver;
+ if (receiver.constructor == Array)
+ return J.JSArray.prototype;
+ if (typeof receiver != "object") {
+ if (typeof receiver == "function")
+ return J.JavaScriptFunction.prototype;
+ return receiver;
+ }
+ if (receiver instanceof P.Object)
+ return receiver;
+ return J.getNativeInterceptor(receiver);
+ },
+ getInterceptor$ax: function(receiver) {
+ if (receiver == null)
+ return receiver;
+ if (receiver.constructor == Array)
+ return J.JSArray.prototype;
+ if (typeof receiver != "object") {
+ if (typeof receiver == "function")
+ return J.JavaScriptFunction.prototype;
+ return receiver;
+ }
+ if (receiver instanceof P.Object)
+ return receiver;
+ return J.getNativeInterceptor(receiver);
+ },
+ getInterceptor$n: function(receiver) {
+ if (typeof receiver == "number")
+ return J.JSNumber.prototype;
+ if (receiver == null)
+ return receiver;
+ if (!(receiver instanceof P.Object))
+ return J.UnknownJavaScriptObject.prototype;
+ return receiver;
+ },
+ getInterceptor$s: function(receiver) {
+ if (typeof receiver == "string")
+ return J.JSString.prototype;
+ if (receiver == null)
+ return receiver;
+ if (!(receiver instanceof P.Object))
+ return J.UnknownJavaScriptObject.prototype;
+ return receiver;
+ },
+ getInterceptor$x: function(receiver) {
+ if (receiver == null)
+ return receiver;
+ if (typeof receiver != "object") {
+ if (typeof receiver == "function")
+ return J.JavaScriptFunction.prototype;
+ return receiver;
+ }
+ if (receiver instanceof P.Object)
+ return receiver;
+ return J.getNativeInterceptor(receiver);
+ },
+ get$first$ax: function(receiver) {
+ return J.getInterceptor$ax(receiver).get$first(receiver);
+ },
+ get$hashCode$: function(receiver) {
+ return J.getInterceptor$(receiver).get$hashCode(receiver);
+ },
+ get$isEmpty$asx: function(receiver) {
+ return J.getInterceptor$asx(receiver).get$isEmpty(receiver);
+ },
+ get$iterator$ax: function(receiver) {
+ return J.getInterceptor$ax(receiver).get$iterator(receiver);
+ },
+ get$last$ax: function(receiver) {
+ return J.getInterceptor$ax(receiver).get$last(receiver);
+ },
+ get$length$asx: function(receiver) {
+ return J.getInterceptor$asx(receiver).get$length(receiver);
+ },
+ get$message$x: function(receiver) {
+ return J.getInterceptor$x(receiver).get$message(receiver);
+ },
+ get$runtimeType$: function(receiver) {
+ return J.getInterceptor$(receiver).get$runtimeType(receiver);
+ },
+ get$startsWith$s: function(receiver) {
+ return J.getInterceptor$s(receiver).get$startsWith(receiver);
+ },
+ $add$ansx: function(receiver, a0) {
+ if (typeof receiver == "number" && typeof a0 == "number")
+ return receiver + a0;
+ return J.getInterceptor$ansx(receiver).$add(receiver, a0);
+ },
+ $eq$: function(receiver, a0) {
+ if (receiver == null)
+ return a0 == null;
+ if (typeof receiver != "object")
+ return a0 != null && receiver === a0;
+ return J.getInterceptor$(receiver).$eq(receiver, a0);
+ },
+ $index$asx: function(receiver, a0) {
+ if (typeof a0 === "number")
+ if (receiver.constructor == Array || typeof receiver == "string" || H.isJsIndexable(receiver, receiver[init.dispatchPropertyName]))
+ if (a0 >>> 0 === a0 && a0 < receiver.length)
+ return receiver[a0];
+ return J.getInterceptor$asx(receiver).$index(receiver, a0);
+ },
+ $indexSet$ax: function(receiver, a0, a1) {
+ return J.getInterceptor$ax(receiver).$indexSet(receiver, a0, a1);
+ },
+ _codeUnitAt$1$s: function(receiver, a0) {
+ return J.getInterceptor$s(receiver)._codeUnitAt$1(receiver, a0);
+ },
+ _removeEventListener$3$x: function(receiver, a0, a1, a2) {
+ return J.getInterceptor$x(receiver)._removeEventListener$3(receiver, a0, a1, a2);
+ },
+ addEventListener$3$x: function(receiver, a0, a1, a2) {
+ return J.getInterceptor$x(receiver).addEventListener$3(receiver, a0, a1, a2);
+ },
+ allMatches$1$s: function(receiver, a0) {
+ return J.getInterceptor$s(receiver).allMatches$1(receiver, a0);
+ },
+ allMatches$2$s: function(receiver, a0, a1) {
+ return J.getInterceptor$s(receiver).allMatches$2(receiver, a0, a1);
+ },
+ codeUnitAt$1$s: function(receiver, a0) {
+ return J.getInterceptor$s(receiver).codeUnitAt$1(receiver, a0);
+ },
+ contains$1$asx: function(receiver, a0) {
+ return J.getInterceptor$asx(receiver).contains$1(receiver, a0);
+ },
+ elementAt$1$ax: function(receiver, a0) {
+ return J.getInterceptor$ax(receiver).elementAt$1(receiver, a0);
+ },
+ endsWith$1$s: function(receiver, a0) {
+ return J.getInterceptor$s(receiver).endsWith$1(receiver, a0);
+ },
+ fillRange$3$ax: function(receiver, a0, a1, a2) {
+ return J.getInterceptor$ax(receiver).fillRange$3(receiver, a0, a1, a2);
+ },
+ map$1$1$ax: function(receiver, a0, $T1) {
+ return J.getInterceptor$ax(receiver).map$1$1(receiver, a0, $T1);
+ },
+ matchAsPrefix$2$s: function(receiver, a0, a1) {
+ return J.getInterceptor$s(receiver).matchAsPrefix$2(receiver, a0, a1);
+ },
+ padRight$1$s: function(receiver, a0) {
+ return J.getInterceptor$s(receiver).padRight$1(receiver, a0);
+ },
+ replaceRange$3$asx: function(receiver, a0, a1, a2) {
+ return J.getInterceptor$asx(receiver).replaceRange$3(receiver, a0, a1, a2);
+ },
+ startsWith$1$s: function(receiver, a0) {
+ return J.getInterceptor$s(receiver).startsWith$1(receiver, a0);
+ },
+ startsWith$2$s: function(receiver, a0, a1) {
+ return J.getInterceptor$s(receiver).startsWith$2(receiver, a0, a1);
+ },
+ substring$1$s: function(receiver, a0) {
+ return J.getInterceptor$s(receiver).substring$1(receiver, a0);
+ },
+ substring$2$s: function(receiver, a0, a1) {
+ return J.getInterceptor$s(receiver).substring$2(receiver, a0, a1);
+ },
+ toRadixString$1$n: function(receiver, a0) {
+ return J.getInterceptor$n(receiver).toRadixString$1(receiver, a0);
+ },
+ toSet$0$ax: function(receiver) {
+ return J.getInterceptor$ax(receiver).toSet$0(receiver);
+ },
+ toString$0$: function(receiver) {
+ return J.getInterceptor$(receiver).toString$0(receiver);
+ },
+ trim$0$s: function(receiver) {
+ return J.getInterceptor$s(receiver).trim$0(receiver);
+ },
+ Interceptor: function Interceptor() {
+ },
+ JSBool: function JSBool() {
+ },
+ JSNull: function JSNull() {
+ },
+ JSObject: function JSObject() {
+ },
+ JavaScriptObject: function JavaScriptObject() {
+ },
+ PlainJavaScriptObject: function PlainJavaScriptObject() {
+ },
+ UnknownJavaScriptObject: function UnknownJavaScriptObject() {
+ },
+ JavaScriptFunction: function JavaScriptFunction() {
+ },
+ JSArray: function JSArray(t0) {
+ this.$ti = t0;
+ },
+ JSUnmodifiableArray: function JSUnmodifiableArray(t0) {
+ this.$ti = t0;
+ },
+ ArrayIterator: function ArrayIterator(t0, t1, t2) {
+ var _ = this;
+ _._iterable = t0;
+ _._length = t1;
+ _._index = 0;
+ _._current = null;
+ _.$ti = t2;
+ },
+ JSNumber: function JSNumber() {
+ },
+ JSInt: function JSInt() {
+ },
+ JSDouble: function JSDouble() {
+ },
+ JSString: function JSString() {
+ }
+ },
+ P = {
+ _AsyncRun__initializeScheduleImmediate: function() {
+ var div, span, t1 = {};
+ if (self.scheduleImmediate != null)
+ return P.async__AsyncRun__scheduleImmediateJsOverride$closure();
+ if (self.MutationObserver != null && self.document != null) {
+ div = self.document.createElement("div");
+ span = self.document.createElement("span");
+ t1.storedCallback = null;
+ new self.MutationObserver(H.convertDartClosureToJS(new P._AsyncRun__initializeScheduleImmediate_internalCallback(t1), 1)).observe(div, {childList: true});
+ return new P._AsyncRun__initializeScheduleImmediate_closure(t1, div, span);
+ } else if (self.setImmediate != null)
+ return P.async__AsyncRun__scheduleImmediateWithSetImmediate$closure();
+ return P.async__AsyncRun__scheduleImmediateWithTimer$closure();
+ },
+ _AsyncRun__scheduleImmediateJsOverride: function(callback) {
+ self.scheduleImmediate(H.convertDartClosureToJS(new P._AsyncRun__scheduleImmediateJsOverride_internalCallback(type$.void_Function._check(callback)), 0));
+ },
+ _AsyncRun__scheduleImmediateWithSetImmediate: function(callback) {
+ self.setImmediate(H.convertDartClosureToJS(new P._AsyncRun__scheduleImmediateWithSetImmediate_internalCallback(type$.void_Function._check(callback)), 0));
+ },
+ _AsyncRun__scheduleImmediateWithTimer: function(callback) {
+ P.Timer__createTimer(C.Duration_0, type$.void_Function._check(callback));
+ },
+ Timer__createTimer: function(duration, callback) {
+ var milliseconds = C.JSInt_methods._tdivFast$1(duration._duration, 1000);
+ return P._TimerImpl$(milliseconds < 0 ? 0 : milliseconds, callback);
+ },
+ _TimerImpl$: function(milliseconds, callback) {
+ var t1 = new P._TimerImpl(true);
+ t1._TimerImpl$2(milliseconds, callback);
+ return t1;
+ },
+ _TimerImpl$periodic: function(milliseconds, callback) {
+ var t1 = new P._TimerImpl(false);
+ t1._TimerImpl$periodic$2(milliseconds, callback);
+ return t1;
+ },
+ _makeAsyncAwaitCompleter: function($T) {
+ return new P._AsyncAwaitCompleter(new P._Future($.Zone__current, $T._eval$1("_Future<0>")), $T._eval$1("_AsyncAwaitCompleter<0>"));
+ },
+ _asyncStartSync: function(bodyFunction, completer) {
+ bodyFunction.call$2(0, null);
+ completer.isSync = true;
+ return completer._future;
+ },
+ _asyncAwait: function(object, bodyFunction) {
+ P._awaitOnObject(object, bodyFunction);
+ },
+ _asyncReturn: function(object, completer) {
+ completer.complete$1(object);
+ },
+ _asyncRethrow: function(object, completer) {
+ completer.completeError$2(H.unwrapException(object), H.getTraceFromException(object));
+ },
+ _awaitOnObject: function(object, bodyFunction) {
+ var t1, future,
+ thenCallback = new P._awaitOnObject_closure(bodyFunction),
+ errorCallback = new P._awaitOnObject_closure0(bodyFunction);
+ if (object instanceof P._Future)
+ object._thenAwait$1$2(thenCallback, errorCallback, type$.dynamic);
+ else {
+ t1 = type$.dynamic;
+ if (type$.Future_dynamic._is(object))
+ object.then$1$2$onError(thenCallback, errorCallback, t1);
+ else {
+ future = new P._Future($.Zone__current, type$._Future_dynamic);
+ future._state = 4;
+ future._resultOrListeners = object;
+ future._thenAwait$1$2(thenCallback, null, t1);
+ }
+ }
+ },
+ _wrapJsFunctionForAsync: function($function) {
+ var $protected = function(fn, ERROR) {
+ return function(errorCode, result) {
+ while (true)
+ try {
+ fn(errorCode, result);
+ break;
+ } catch (error) {
+ result = error;
+ errorCode = ERROR;
+ }
+ };
+ }($function, 1);
+ return $.Zone__current.registerBinaryCallback$3$1(new P._wrapJsFunctionForAsync_closure($protected), type$.Null, type$.int, type$.dynamic);
+ },
+ Future_Future: function(computation, $T) {
+ var result = new P._Future($.Zone__current, $T._eval$1("_Future<0>"));
+ P.Timer_Timer(C.Duration_0, new P.Future_Future_closure(result, computation));
+ return result;
+ },
+ Future_Future$microtask: function(computation, $T) {
+ var result = new P._Future($.Zone__current, $T._eval$1("_Future<0>"));
+ P.scheduleMicrotask(new P.Future_Future$microtask_closure(result, computation));
+ return result;
+ },
+ Future_Future$sync: function(computation, $T) {
+ var result, error, stackTrace, future, replacement, t1, t2, exception;
+ try {
+ result = computation.call$0();
+ if ($T._eval$1("Future<0>")._is(result))
+ return result;
+ else {
+ t1 = $T._check(result);
+ t2 = new P._Future($.Zone__current, $T._eval$1("_Future<0>"));
+ t2._state = 4;
+ t2._resultOrListeners = t1;
+ return t2;
+ }
+ } catch (exception) {
+ error = H.unwrapException(exception);
+ stackTrace = H.getTraceFromException(exception);
+ t1 = $.Zone__current;
+ future = new P._Future(t1, $T._eval$1("_Future<0>"));
+ replacement = t1.errorCallback$2(error, stackTrace);
+ if (replacement != null) {
+ t1 = replacement.error;
+ if (t1 == null)
+ t1 = new P.NullThrownError();
+ future._asyncCompleteError$2(t1, replacement.stackTrace);
+ } else
+ future._asyncCompleteError$2(error, stackTrace);
+ return future;
+ }
+ },
+ Future_Future$error: function(error, stackTrace, $T) {
+ var replacement,
+ t1 = $.Zone__current;
+ if (t1 !== C.C__RootZone) {
+ replacement = t1.errorCallback$2(error, stackTrace);
+ if (replacement != null) {
+ error = replacement.error;
+ if (error == null)
+ error = new P.NullThrownError();
+ stackTrace = replacement.stackTrace;
+ }
+ }
+ t1 = new P._Future($.Zone__current, $T._eval$1("_Future<0>"));
+ t1._asyncCompleteError$2(error, stackTrace);
+ return t1;
+ },
+ Future_wait: function(futures, eagerError, $T) {
+ var handleError, future, pos, e, st, t2, t3, _i, t4, exception, _box_0 = {}, cleanUp = null,
+ t1 = $T._eval$1("_Future<List<0>>"),
+ result = new P._Future($.Zone__current, t1);
+ _box_0.values = null;
+ _box_0.remaining = 0;
+ _box_0.stackTrace = _box_0.error = null;
+ handleError = new P.Future_wait_handleError(_box_0, cleanUp, true, result);
+ try {
+ for (t2 = futures.length, t3 = type$.Null, _i = 0, t4 = 0; _i < futures.length; futures.length === t2 || (0, H.throwConcurrentModificationError)(futures), ++_i) {
+ future = futures[_i];
+ pos = t4;
+ future.then$1$2$onError(new P.Future_wait_closure(_box_0, pos, result, cleanUp, true, $T), handleError, t3);
+ t4 = ++_box_0.remaining;
+ }
+ if (t4 === 0) {
+ t1 = new P._Future($.Zone__current, t1);
+ t1._asyncComplete$1(C.List_empty1);
+ return t1;
+ }
+ t1 = new Array(t4);
+ t1.fixed$length = Array;
+ _box_0.values = H.setRuntimeTypeInfo(t1, $T._eval$1("JSArray<0>"));
+ } catch (exception) {
+ e = H.unwrapException(exception);
+ st = H.getTraceFromException(exception);
+ t1 = P.Future_Future$error(e, st, $T._eval$1("List<0>"));
+ return t1;
+ }
+ return result;
+ },
+ Future_forEach: function(elements, action, $T) {
+ return P.Future_doWhile(new P.Future_forEach_closure(new J.ArrayIterator(elements, 0, H._arrayInstanceType(elements)._eval$1("ArrayIterator<1>")), action));
+ },
+ Future__kTrue: function(_) {
+ return true;
+ },
+ Future_doWhile: function(action) {
+ var nextIteration, t1 = {},
+ t2 = $.Zone__current,
+ doneSignal = new P._Future(t2, type$._Future_dynamic);
+ t1.nextIteration = null;
+ nextIteration = t2.bindUnaryCallbackGuarded$1$1(new P.Future_doWhile_closure(t1, action, doneSignal), type$.bool);
+ t1.nextIteration = nextIteration;
+ nextIteration.call$1(true);
+ return doneSignal;
+ },
+ _completeWithErrorCallback: function(result, error, stackTrace) {
+ var replacement = $.Zone__current.errorCallback$2(error, stackTrace);
+ if (replacement != null) {
+ error = replacement.error;
+ if (error == null)
+ error = new P.NullThrownError();
+ stackTrace = replacement.stackTrace;
+ }
+ result._completeError$2(error, stackTrace);
+ },
+ _Future$zoneValue: function(value, _zone, $T) {
+ var t1 = new P._Future(_zone, $T._eval$1("_Future<0>"));
+ $T._check(value);
+ t1._state = 4;
+ t1._resultOrListeners = value;
+ return t1;
+ },
+ _Future__chainForeignFuture: function(source, target) {
+ var e, s, exception;
+ H.assertHelper(target._state < 4);
+ H.assertHelper(!(source instanceof P._Future));
+ H.assertHelper(target._state === 0);
+ target._state = 1;
+ try {
+ source.then$1$2$onError(new P._Future__chainForeignFuture_closure(target), new P._Future__chainForeignFuture_closure0(target), type$.Null);
+ } catch (exception) {
+ e = H.unwrapException(exception);
+ s = H.getTraceFromException(exception);
+ P.scheduleMicrotask(new P._Future__chainForeignFuture_closure1(target, e, s));
+ }
+ },
+ _Future__chainCoreFuture: function(source, target) {
+ var t1, t2, t3, listeners;
+ H.assertHelper(target._state <= 1);
+ for (t1 = type$._Future_dynamic; t2 = source._state, t3 = t2 === 2, t3;) {
+ H.assertHelper(t3);
+ source = t1._check(source._resultOrListeners);
+ }
+ if (t2 >= 4) {
+ listeners = target._removeListeners$0();
+ target._cloneResult$1(source);
+ P._Future__propagateToListeners(target, listeners);
+ } else {
+ listeners = type$._FutureListener_dynamic_dynamic._check(target._resultOrListeners);
+ H.assertHelper(target._state <= 1);
+ target._state = 2;
+ target._resultOrListeners = source;
+ source._prependListeners$1(listeners);
+ }
+ },
+ _Future__propagateToListeners: function(source, listeners) {
+ var t2, t3, t4, _box_0, hasError, asyncError, listeners0, sourceResult, t5, t6, zone, previous, oldZone, current, result, _box_1 = {},
+ t1 = _box_1.source = source;
+ for (t2 = type$.AsyncError, t3 = type$._FutureListener_dynamic_dynamic, t4 = type$.Future_dynamic; true;) {
+ _box_0 = {};
+ H.assertHelper(t1._state >= 4);
+ t1 = _box_1.source;
+ hasError = t1._state === 8;
+ if (listeners == null) {
+ if (hasError) {
+ asyncError = t2._check(t1._resultOrListeners);
+ t1._zone.handleUncaughtError$2(asyncError.error, asyncError.stackTrace);
+ }
+ return;
+ }
+ for (; listeners0 = listeners._nextListener, listeners0 != null; listeners = listeners0) {
+ listeners._nextListener = null;
+ P._Future__propagateToListeners(_box_1.source, listeners);
+ }
+ t1 = _box_1.source;
+ sourceResult = t1._resultOrListeners;
+ _box_0.listenerHasError = hasError;
+ _box_0.listenerValueOrError = sourceResult;
+ t5 = !hasError;
+ if (t5) {
+ t6 = listeners.state;
+ t6 = (t6 & 1) !== 0 || (t6 & 15) === 8;
+ } else
+ t6 = true;
+ if (t6) {
+ t6 = listeners.result;
+ zone = t6._zone;
+ if (hasError) {
+ t1 = t1._zone;
+ t1 = !(t1 === zone || t1.get$errorZone() === zone.get$errorZone());
+ } else
+ t1 = false;
+ if (t1) {
+ t1 = _box_1.source;
+ H.assertHelper(t1._state === 8);
+ asyncError = t2._check(t1._resultOrListeners);
+ _box_1.source._zone.handleUncaughtError$2(asyncError.error, asyncError.stackTrace);
+ return;
+ }
+ t1 = $.Zone__current;
+ if (t1 !== zone) {
+ H.assertHelper(zone !== t1);
+ previous = $.Zone__current;
+ $.Zone__current = zone;
+ oldZone = previous;
+ } else
+ oldZone = null;
+ t1 = listeners.state;
+ if ((t1 & 15) === 8)
+ new P._Future__propagateToListeners_handleWhenCompleteCallback(_box_1, _box_0, listeners, hasError).call$0();
+ else if (t5) {
+ if ((t1 & 1) !== 0)
+ new P._Future__propagateToListeners_handleValueCallback(_box_0, listeners, sourceResult).call$0();
+ } else if ((t1 & 2) !== 0)
+ new P._Future__propagateToListeners_handleError(_box_1, _box_0, listeners).call$0();
+ if (oldZone != null)
+ $.Zone__current = oldZone;
+ t1 = _box_0.listenerValueOrError;
+ if (t4._is(t1)) {
+ if (t1._state >= 4) {
+ H.assertHelper(t6._state < 4);
+ current = t3._check(t6._resultOrListeners);
+ t6._resultOrListeners = null;
+ listeners = t6._reverseListeners$1(current);
+ H.assertHelper(t6._state < 4);
+ H.assertHelper(t1._state >= 4);
+ t6._state = t1._state;
+ t6._resultOrListeners = t1._resultOrListeners;
+ _box_1.source = t1;
+ continue;
+ } else
+ P._Future__chainCoreFuture(t1, t6);
+ return;
+ }
+ }
+ result = listeners.result;
+ H.assertHelper(result._state < 4);
+ current = t3._check(result._resultOrListeners);
+ result._resultOrListeners = null;
+ listeners = result._reverseListeners$1(current);
+ t1 = _box_0.listenerHasError;
+ t5 = _box_0.listenerValueOrError;
+ t6 = result._state >= 4;
+ if (!t1) {
+ result.$ti._precomputed1._check(t5);
+ H.assertHelper(!t6);
+ result._state = 4;
+ result._resultOrListeners = t5;
+ } else {
+ t2._check(t5);
+ H.assertHelper(!t6);
+ result._state = 8;
+ result._resultOrListeners = t5;
+ }
+ _box_1.source = result;
+ t1 = result;
+ }
+ },
+ _registerErrorHandler: function(errorHandler, zone) {
+ if (type$.dynamic_Function_Object_StackTrace._is(errorHandler))
+ return zone.registerBinaryCallback$3$1(errorHandler, type$.dynamic, type$.Object, type$.StackTrace);
+ if (type$.dynamic_Function_Object._is(errorHandler))
+ return zone.registerUnaryCallback$2$1(errorHandler, type$.dynamic, type$.Object);
+ throw H.wrapException(P.ArgumentError$value(errorHandler, "onError", "Error handler must accept one Object or one Object and a StackTrace as arguments, and return a a valid result"));
+ },
+ _microtaskLoop: function() {
+ var t1, t2;
+ for (; t1 = $._nextCallback, t1 != null;) {
+ $._lastPriorityCallback = null;
+ t2 = t1.next;
+ $._nextCallback = t2;
+ if (t2 == null)
+ $._lastCallback = null;
+ t1.callback.call$0();
+ }
+ },
+ _startMicrotaskLoop: function() {
+ $._isInCallbackLoop = true;
+ try {
+ P._microtaskLoop();
+ } finally {
+ $._lastPriorityCallback = null;
+ $._isInCallbackLoop = false;
+ if ($._nextCallback != null)
+ $.$get$_AsyncRun__scheduleImmediateClosure().call$1(P.async___startMicrotaskLoop$closure());
+ }
+ },
+ _scheduleAsyncCallback: function(callback) {
+ var newEntry = new P._AsyncCallbackEntry(callback);
+ if ($._nextCallback == null) {
+ $._nextCallback = $._lastCallback = newEntry;
+ if (!$._isInCallbackLoop)
+ $.$get$_AsyncRun__scheduleImmediateClosure().call$1(P.async___startMicrotaskLoop$closure());
+ } else
+ $._lastCallback = $._lastCallback.next = newEntry;
+ },
+ _schedulePriorityAsyncCallback: function(callback) {
+ var entry, t2,
+ t1 = $._nextCallback;
+ if (t1 == null) {
+ P._scheduleAsyncCallback(callback);
+ $._lastPriorityCallback = $._lastCallback;
+ return;
+ }
+ entry = new P._AsyncCallbackEntry(callback);
+ t2 = $._lastPriorityCallback;
+ if (t2 == null) {
+ entry.next = t1;
+ $._nextCallback = $._lastPriorityCallback = entry;
+ } else {
+ entry.next = t2.next;
+ $._lastPriorityCallback = t2.next = entry;
+ if (entry.next == null)
+ $._lastCallback = entry;
+ }
+ },
+ scheduleMicrotask: function(callback) {
+ var t1, _null = null,
+ currentZone = $.Zone__current;
+ if (C.C__RootZone === currentZone) {
+ P._rootScheduleMicrotask(_null, _null, C.C__RootZone, callback);
+ return;
+ }
+ if (C.C__RootZone === currentZone.get$_scheduleMicrotask().zone)
+ t1 = C.C__RootZone.get$errorZone() === currentZone.get$errorZone();
+ else
+ t1 = false;
+ if (t1) {
+ P._rootScheduleMicrotask(_null, _null, currentZone, currentZone.registerCallback$1$1(callback, type$.void));
+ return;
+ }
+ t1 = $.Zone__current;
+ t1.scheduleMicrotask$1(t1.bindCallbackGuarded$1(callback));
+ },
+ Stream_Stream$fromFuture: function(future, $T) {
+ var _null = null,
+ t1 = $T._eval$1("_SyncStreamController<0>"),
+ controller = new P._SyncStreamController(_null, _null, _null, _null, t1);
+ future.then$1$2$onError(new P.Stream_Stream$fromFuture_closure(controller, $T), new P.Stream_Stream$fromFuture_closure0(controller), type$.Null);
+ return new P._ControllerStream(controller, t1._eval$1("_ControllerStream<1>"));
+ },
+ Stream_Stream$fromIterable: function(elements, $T) {
+ return new P._GeneratedStreamImpl(new P.Stream_Stream$fromIterable_closure(elements, $T), $T._eval$1("_GeneratedStreamImpl<0>"));
+ },
+ StreamIterator_StreamIterator: function(stream, $T) {
+ if (stream == null)
+ H.throwExpression(P.ArgumentError$notNull("stream"));
+ return new P._StreamIterator($T._eval$1("_StreamIterator<0>"));
+ },
+ StreamController_StreamController: function(onCancel, onListen, sync, $T) {
+ var _null = null;
+ return sync ? new P._SyncStreamController(onListen, _null, _null, onCancel, $T._eval$1("_SyncStreamController<0>")) : new P._AsyncStreamController(onListen, _null, _null, onCancel, $T._eval$1("_AsyncStreamController<0>"));
+ },
+ _runGuarded: function(notificationHandler) {
+ var e, s, exception;
+ if (notificationHandler == null)
+ return;
+ try {
+ notificationHandler.call$0();
+ } catch (exception) {
+ e = H.unwrapException(exception);
+ s = H.getTraceFromException(exception);
+ $.Zone__current.handleUncaughtError$2(e, s);
+ }
+ },
+ _AddStreamState_makeErrorHandler: function(controller) {
+ return new P._AddStreamState_makeErrorHandler_closure(controller);
+ },
+ _BufferingStreamSubscription$: function(onData, onError, onDone, cancelOnError, $T) {
+ var t1 = $.Zone__current,
+ t2 = cancelOnError ? 1 : 0;
+ t2 = new P._BufferingStreamSubscription(t1, t2, $T._eval$1("_BufferingStreamSubscription<0>"));
+ t2._BufferingStreamSubscription$4(onData, onError, onDone, cancelOnError, $T);
+ return t2;
+ },
+ _nullDataHandler: function(value) {
+ },
+ _nullErrorHandler: function(error, stackTrace) {
+ type$.StackTrace._check(stackTrace);
+ $.Zone__current.handleUncaughtError$2(error, stackTrace);
+ },
+ _nullDoneHandler: function() {
+ },
+ _runUserCode: function(userCode, onSuccess, onError, $T) {
+ var e, s, replacement, error, stackTrace, exception, error0;
+ try {
+ onSuccess.call$1(userCode.call$0());
+ } catch (exception) {
+ e = H.unwrapException(exception);
+ s = H.getTraceFromException(exception);
+ replacement = $.Zone__current.errorCallback$2(e, s);
+ if (replacement == null)
+ onError.call$2(e, s);
+ else {
+ error0 = replacement.error;
+ error = error0 == null ? new P.NullThrownError() : error0;
+ stackTrace = replacement.stackTrace;
+ onError.call$2(error, stackTrace);
+ }
+ }
+ },
+ _cancelAndError: function(subscription, future, error, stackTrace) {
+ var cancelFuture = subscription.cancel$0();
+ if (cancelFuture != null && cancelFuture !== $.$get$Future__nullFuture())
+ cancelFuture.whenComplete$1(new P._cancelAndError_closure(future, error, stackTrace));
+ else
+ future._completeError$2(error, stackTrace);
+ },
+ _cancelAndErrorClosure: function(subscription, future) {
+ return new P._cancelAndErrorClosure_closure(subscription, future);
+ },
+ _cancelAndValue: function(subscription, future, value) {
+ var cancelFuture = subscription.cancel$0();
+ if (cancelFuture != null && cancelFuture !== $.$get$Future__nullFuture())
+ cancelFuture.whenComplete$1(new P._cancelAndValue_closure(future, value));
+ else
+ future._complete$1(value);
+ },
+ Timer_Timer: function(duration, callback) {
+ var t1 = $.Zone__current;
+ if (t1 === C.C__RootZone)
+ return t1.createTimer$2(duration, callback);
+ return t1.createTimer$2(duration, t1.bindCallbackGuarded$1(callback));
+ },
+ _ZoneSpecification$: function(createPeriodicTimer, createTimer, errorCallback, fork, handleUncaughtError, $print, registerBinaryCallback, registerCallback, registerUnaryCallback, run, runBinary, runUnary, scheduleMicrotask) {
+ return new P._ZoneSpecification(handleUncaughtError, run, runUnary, runBinary, registerCallback, registerUnaryCallback, registerBinaryCallback, errorCallback, scheduleMicrotask, createTimer, createPeriodicTimer, $print, fork);
+ },
+ Zone__enter: function(zone) {
+ var previous;
+ H.assertHelper(zone != null);
+ H.assertHelper(zone !== $.Zone__current);
+ previous = $.Zone__current;
+ $.Zone__current = zone;
+ return previous;
+ },
+ _parentDelegate: function(zone) {
+ if (zone.get$parent(zone) == null)
+ return null;
+ return zone.get$parent(zone).get$_delegate();
+ },
+ _rootHandleUncaughtError: function($self, $parent, zone, error, stackTrace) {
+ var t1 = {};
+ t1.error = error;
+ P._schedulePriorityAsyncCallback(new P._rootHandleUncaughtError_closure(t1, type$.StackTrace._check(stackTrace)));
+ },
+ _rootRun: function($self, $parent, zone, f, $R) {
+ var old,
+ t1 = type$.Zone;
+ t1._check($self);
+ type$.ZoneDelegate._check($parent);
+ t1._check(zone);
+ $R._eval$1("0()")._check(f);
+ if ($.Zone__current === zone)
+ return f.call$0();
+ old = P.Zone__enter(zone);
+ try {
+ t1 = f.call$0();
+ return t1;
+ } finally {
+ t1 = old;
+ H.assertHelper(t1 != null);
+ $.Zone__current = t1;
+ }
+ },
+ _rootRunUnary: function($self, $parent, zone, f, arg, $R, $T) {
+ var old,
+ t1 = type$.Zone;
+ t1._check($self);
+ type$.ZoneDelegate._check($parent);
+ t1._check(zone);
+ $R._eval$1("@<0>")._bind$1($T)._eval$1("1(2)")._check(f);
+ $T._check(arg);
+ if ($.Zone__current === zone)
+ return f.call$1(arg);
+ old = P.Zone__enter(zone);
+ try {
+ t1 = f.call$1(arg);
+ return t1;
+ } finally {
+ t1 = old;
+ H.assertHelper(t1 != null);
+ $.Zone__current = t1;
+ }
+ },
+ _rootRunBinary: function($self, $parent, zone, f, arg1, arg2, $R, T1, T2) {
+ var old,
+ t1 = type$.Zone;
+ t1._check($self);
+ type$.ZoneDelegate._check($parent);
+ t1._check(zone);
+ $R._eval$1("@<0>")._bind$1(T1)._bind$1(T2)._eval$1("1(2,3)")._check(f);
+ T1._check(arg1);
+ T2._check(arg2);
+ if ($.Zone__current === zone)
+ return f.call$2(arg1, arg2);
+ old = P.Zone__enter(zone);
+ try {
+ t1 = f.call$2(arg1, arg2);
+ return t1;
+ } finally {
+ t1 = old;
+ H.assertHelper(t1 != null);
+ $.Zone__current = t1;
+ }
+ },
+ _rootRegisterCallback: function($self, $parent, zone, f, $R) {
+ return $R._eval$1("0()")._check(f);
+ },
+ _rootRegisterUnaryCallback: function($self, $parent, zone, f, $R, $T) {
+ return $R._eval$1("@<0>")._bind$1($T)._eval$1("1(2)")._check(f);
+ },
+ _rootRegisterBinaryCallback: function($self, $parent, zone, f, $R, T1, T2) {
+ return $R._eval$1("@<0>")._bind$1(T1)._bind$1(T2)._eval$1("1(2,3)")._check(f);
+ },
+ _rootErrorCallback: function($self, $parent, zone, error, stackTrace) {
+ type$.StackTrace._check(stackTrace);
+ return null;
+ },
+ _rootScheduleMicrotask: function($self, $parent, zone, f) {
+ var t1;
+ type$.void_Function._check(f);
+ t1 = C.C__RootZone !== zone;
+ if (t1)
+ f = !(!t1 || C.C__RootZone.get$errorZone() === zone.get$errorZone()) ? zone.bindCallbackGuarded$1(f) : zone.bindCallback$1$1(f, type$.void);
+ P._scheduleAsyncCallback(f);
+ },
+ _rootCreateTimer: function($self, $parent, zone, duration, callback) {
+ type$.Duration._check(duration);
+ callback = zone.bindCallback$1$1(type$.void_Function._check(callback), type$.void);
+ return P.Timer__createTimer(duration, callback);
+ },
+ _rootCreatePeriodicTimer: function($self, $parent, zone, duration, callback) {
+ var milliseconds;
+ type$.Duration._check(duration);
+ callback = zone.bindUnaryCallback$2$1(type$.void_Function_Timer._check(callback), type$.dynamic, type$.Timer);
+ milliseconds = C.JSInt_methods._tdivFast$1(duration._duration, 1000);
+ return P._TimerImpl$periodic(milliseconds < 0 ? 0 : milliseconds, callback);
+ },
+ _rootPrint: function($self, $parent, zone, line) {
+ H.printString(H._checkStringNullable(line));
+ },
+ _printToZone: function(line) {
+ $.Zone__current.print$1(0, line);
+ },
+ _rootFork: function($self, $parent, zone, specification, zoneValues) {
+ var valueMap, t1, t2;
+ type$.ZoneSpecification._check(specification);
+ type$.Map_dynamic_dynamic._check(zoneValues);
+ $.printToZone = P.async___printToZone$closure();
+ if (specification == null)
+ specification = C._ZoneSpecification_ALf;
+ if (zoneValues == null)
+ valueMap = zone.get$_async$_map();
+ else {
+ t1 = type$.dynamic;
+ valueMap = P.HashMap_HashMap$from(zoneValues, t1, t1);
+ }
+ t1 = new P._CustomZone(zone, valueMap);
+ t2 = zone.get$_run();
+ t1.set$_run(t2);
+ t2 = zone.get$_runUnary();
+ t1.set$_runUnary(t2);
+ t2 = zone.get$_runBinary();
+ t1.set$_runBinary(t2);
+ t2 = specification.registerCallback;
+ t1.set$_registerCallback(t2 != null ? new P._ZoneFunction(t1, t2, type$._ZoneFunction_Function) : zone.get$_registerCallback());
+ t2 = specification.registerUnaryCallback;
+ t1.set$_registerUnaryCallback(t2 != null ? new P._ZoneFunction(t1, t2, type$._ZoneFunction_Function) : zone.get$_registerUnaryCallback());
+ t2 = specification.registerBinaryCallback;
+ t1.set$_registerBinaryCallback(t2 != null ? new P._ZoneFunction(t1, t2, type$._ZoneFunction_Function) : zone.get$_registerBinaryCallback());
+ t2 = specification.errorCallback;
+ t1.set$_errorCallback(t2 != null ? new P._ZoneFunction(t1, t2, type$._ZoneFunction_of_AsyncError_Function_Zone_ZoneDelegate_Zone_Object_StackTrace) : zone.get$_errorCallback());
+ t2 = zone.get$_scheduleMicrotask();
+ t1.set$_scheduleMicrotask(t2);
+ t2 = zone.get$_createTimer();
+ t1.set$_createTimer(t2);
+ t2 = zone.get$_createPeriodicTimer();
+ t1.set$_createPeriodicTimer(t2);
+ t2 = specification.print;
+ t1.set$_print(t2 != null ? new P._ZoneFunction(t1, t2, type$._ZoneFunction_of_void_Function_Zone_ZoneDelegate_Zone_String) : zone.get$_print());
+ t2 = zone.get$_fork();
+ t1.set$_fork(t2);
+ t2 = specification.handleUncaughtError;
+ t1.set$_handleUncaughtError(t2 != null ? new P._ZoneFunction(t1, t2, type$._ZoneFunction_of_void_Function_Zone_ZoneDelegate_Zone_Object_StackTrace) : zone.get$_handleUncaughtError());
+ return t1;
+ },
+ runZoned: function(body, onError, zoneSpecification, zoneValues, $R) {
+ var e, stackTrace, errorHandler, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, exception, _null = null, t1 = {};
+ if (onError == null)
+ return P._runZoned(body, zoneValues, zoneSpecification, $R);
+ t1.binaryOnError = t1.unaryOnError = null;
+ if (type$.void_Function_Object_StackTrace._is(onError))
+ t1.binaryOnError = onError;
+ else if (type$.void_Function_Object._is(onError))
+ t1.unaryOnError = onError;
+ else
+ throw H.wrapException(P.ArgumentError$("onError callback must take either an Object (the error), or both an Object (the error) and a StackTrace."));
+ errorHandler = new P.runZoned_closure(t1);
+ if (zoneSpecification == null)
+ zoneSpecification = P._ZoneSpecification$(_null, _null, _null, _null, errorHandler, _null, _null, _null, _null, _null, _null, _null, _null);
+ else {
+ t2 = zoneSpecification;
+ t3 = t2.run;
+ t4 = t2.runUnary;
+ t5 = t2.runBinary;
+ t6 = t2.registerCallback;
+ t7 = t2.registerUnaryCallback;
+ t8 = t2.registerBinaryCallback;
+ t9 = t2.errorCallback;
+ t10 = t2.scheduleMicrotask;
+ t11 = t2.createTimer;
+ t12 = t2.createPeriodicTimer;
+ t13 = t2.print;
+ zoneSpecification = P._ZoneSpecification$(t12, t11, t9, t2.fork, errorHandler, t13, t8, t6, t7, t3, t5, t4, t10);
+ }
+ try {
+ t2 = P._runZoned(body, zoneValues, zoneSpecification, $R);
+ return t2;
+ } catch (exception) {
+ e = H.unwrapException(exception);
+ stackTrace = H.getTraceFromException(exception);
+ t2 = t1.binaryOnError;
+ if (t2 != null)
+ t2.call$2(e, stackTrace);
+ else {
+ H.assertHelper(t1.unaryOnError != null);
+ t1.unaryOnError.call$1(e);
+ }
+ }
+ return _null;
+ },
+ _runZoned: function(body, zoneValues, specification, $R) {
+ return $.Zone__current.fork$2$specification$zoneValues(specification, zoneValues).run$1$1(body, $R);
+ },
+ _AsyncRun__initializeScheduleImmediate_internalCallback: function _AsyncRun__initializeScheduleImmediate_internalCallback(t0) {
+ this._box_0 = t0;
+ },
+ _AsyncRun__initializeScheduleImmediate_closure: function _AsyncRun__initializeScheduleImmediate_closure(t0, t1, t2) {
+ this._box_0 = t0;
+ this.div = t1;
+ this.span = t2;
+ },
+ _AsyncRun__scheduleImmediateJsOverride_internalCallback: function _AsyncRun__scheduleImmediateJsOverride_internalCallback(t0) {
+ this.callback = t0;
+ },
+ _AsyncRun__scheduleImmediateWithSetImmediate_internalCallback: function _AsyncRun__scheduleImmediateWithSetImmediate_internalCallback(t0) {
+ this.callback = t0;
+ },
+ _TimerImpl: function _TimerImpl(t0) {
+ this._once = t0;
+ this._handle = null;
+ this._tick = 0;
+ },
+ _TimerImpl_internalCallback: function _TimerImpl_internalCallback(t0, t1) {
+ this.$this = t0;
+ this.callback = t1;
+ },
+ _TimerImpl$periodic_closure: function _TimerImpl$periodic_closure(t0, t1, t2, t3) {
+ var _ = this;
+ _.$this = t0;
+ _.milliseconds = t1;
+ _.start = t2;
+ _.callback = t3;
+ },
+ _AsyncAwaitCompleter: function _AsyncAwaitCompleter(t0, t1) {
+ this._future = t0;
+ this.isSync = false;
+ this.$ti = t1;
+ },
+ _awaitOnObject_closure: function _awaitOnObject_closure(t0) {
+ this.bodyFunction = t0;
+ },
+ _awaitOnObject_closure0: function _awaitOnObject_closure0(t0) {
+ this.bodyFunction = t0;
+ },
+ _wrapJsFunctionForAsync_closure: function _wrapJsFunctionForAsync_closure(t0) {
+ this.$protected = t0;
+ },
+ _BroadcastStream: function _BroadcastStream(t0, t1) {
+ this._controller = t0;
+ this.$ti = t1;
+ },
+ _BroadcastSubscription: function _BroadcastSubscription(t0, t1, t2, t3) {
+ var _ = this;
+ _._eventState = 0;
+ _._async$_previous = _._async$_next = null;
+ _._controller = t0;
+ _._onDone = _._onError = _._onData = null;
+ _._zone = t1;
+ _._state = t2;
+ _._pending = _._cancelFuture = null;
+ _.$ti = t3;
+ },
+ _BroadcastStreamController: function _BroadcastStreamController() {
+ },
+ _SyncBroadcastStreamController: function _SyncBroadcastStreamController(t0, t1, t2) {
+ var _ = this;
+ _.onListen = t0;
+ _.onCancel = t1;
+ _._state = 0;
+ _._doneFuture = _._addStreamState = _._lastSubscription = _._firstSubscription = null;
+ _.$ti = t2;
+ },
+ _SyncBroadcastStreamController__sendData_closure: function _SyncBroadcastStreamController__sendData_closure(t0, t1) {
+ this.$this = t0;
+ this.data = t1;
+ },
+ _SyncBroadcastStreamController__sendError_closure: function _SyncBroadcastStreamController__sendError_closure(t0, t1, t2) {
+ this.$this = t0;
+ this.error = t1;
+ this.stackTrace = t2;
+ },
+ _SyncBroadcastStreamController__sendDone_closure: function _SyncBroadcastStreamController__sendDone_closure(t0) {
+ this.$this = t0;
+ },
+ _AsyncBroadcastStreamController: function _AsyncBroadcastStreamController(t0, t1, t2) {
+ var _ = this;
+ _.onListen = t0;
+ _.onCancel = t1;
+ _._state = 0;
+ _._doneFuture = _._addStreamState = _._lastSubscription = _._firstSubscription = null;
+ _.$ti = t2;
+ },
+ Future: function Future() {
+ },
+ Future_Future_closure: function Future_Future_closure(t0, t1) {
+ this.result = t0;
+ this.computation = t1;
+ },
+ Future_Future$microtask_closure: function Future_Future$microtask_closure(t0, t1) {
+ this.result = t0;
+ this.computation = t1;
+ },
+ Future_wait_handleError: function Future_wait_handleError(t0, t1, t2, t3) {
+ var _ = this;
+ _._box_0 = t0;
+ _.cleanUp = t1;
+ _.eagerError = t2;
+ _.result = t3;
+ },
+ Future_wait_closure: function Future_wait_closure(t0, t1, t2, t3, t4, t5) {
+ var _ = this;
+ _._box_0 = t0;
+ _.pos = t1;
+ _.result = t2;
+ _.cleanUp = t3;
+ _.eagerError = t4;
+ _.T = t5;
+ },
+ Future_forEach_closure: function Future_forEach_closure(t0, t1) {
+ this.iterator = t0;
+ this.action = t1;
+ },
+ Future_doWhile_closure: function Future_doWhile_closure(t0, t1, t2) {
+ this._box_0 = t0;
+ this.action = t1;
+ this.doneSignal = t2;
+ },
+ TimeoutException: function TimeoutException(t0, t1) {
+ this.message = t0;
+ this.duration = t1;
+ },
+ Completer: function Completer() {
+ },
+ _Completer: function _Completer() {
+ },
+ _AsyncCompleter: function _AsyncCompleter(t0, t1) {
+ this.future = t0;
+ this.$ti = t1;
+ },
+ _SyncCompleter: function _SyncCompleter(t0, t1) {
+ this.future = t0;
+ this.$ti = t1;
+ },
+ _FutureListener: function _FutureListener(t0, t1, t2, t3, t4) {
+ var _ = this;
+ _._nextListener = null;
+ _.result = t0;
+ _.state = t1;
+ _.callback = t2;
+ _.errorCallback = t3;
+ _.$ti = t4;
+ },
+ _Future: function _Future(t0, t1) {
+ var _ = this;
+ _._state = 0;
+ _._zone = t0;
+ _._resultOrListeners = null;
+ _.$ti = t1;
+ },
+ _Future__addListener_closure: function _Future__addListener_closure(t0, t1) {
+ this.$this = t0;
+ this.listener = t1;
+ },
+ _Future__prependListeners_closure: function _Future__prependListeners_closure(t0, t1) {
+ this._box_0 = t0;
+ this.$this = t1;
+ },
+ _Future__chainForeignFuture_closure: function _Future__chainForeignFuture_closure(t0) {
+ this.target = t0;
+ },
+ _Future__chainForeignFuture_closure0: function _Future__chainForeignFuture_closure0(t0) {
+ this.target = t0;
+ },
+ _Future__chainForeignFuture_closure1: function _Future__chainForeignFuture_closure1(t0, t1, t2) {
+ this.target = t0;
+ this.e = t1;
+ this.s = t2;
+ },
+ _Future__asyncComplete_closure: function _Future__asyncComplete_closure(t0, t1) {
+ this.$this = t0;
+ this.value = t1;
+ },
+ _Future__chainFuture_closure: function _Future__chainFuture_closure(t0, t1) {
+ this.$this = t0;
+ this.value = t1;
+ },
+ _Future__asyncCompleteError_closure: function _Future__asyncCompleteError_closure(t0, t1, t2) {
+ this.$this = t0;
+ this.error = t1;
+ this.stackTrace = t2;
+ },
+ _Future__propagateToListeners_handleWhenCompleteCallback: function _Future__propagateToListeners_handleWhenCompleteCallback(t0, t1, t2, t3) {
+ var _ = this;
+ _._box_1 = t0;
+ _._box_0 = t1;
+ _.listener = t2;
+ _.hasError = t3;
+ },
+ _Future__propagateToListeners_handleWhenCompleteCallback_closure: function _Future__propagateToListeners_handleWhenCompleteCallback_closure(t0) {
+ this.originalSource = t0;
+ },
+ _Future__propagateToListeners_handleValueCallback: function _Future__propagateToListeners_handleValueCallback(t0, t1, t2) {
+ this._box_0 = t0;
+ this.listener = t1;
+ this.sourceResult = t2;
+ },
+ _Future__propagateToListeners_handleError: function _Future__propagateToListeners_handleError(t0, t1, t2) {
+ this._box_1 = t0;
+ this._box_0 = t1;
+ this.listener = t2;
+ },
+ _AsyncCallbackEntry: function _AsyncCallbackEntry(t0) {
+ this.callback = t0;
+ this.next = null;
+ },
+ Stream: function Stream() {
+ },
+ Stream_Stream$fromFuture_closure: function Stream_Stream$fromFuture_closure(t0, t1) {
+ this.controller = t0;
+ this.T = t1;
+ },
+ Stream_Stream$fromFuture_closure0: function Stream_Stream$fromFuture_closure0(t0) {
+ this.controller = t0;
+ },
+ Stream_Stream$fromIterable_closure: function Stream_Stream$fromIterable_closure(t0, t1) {
+ this.elements = t0;
+ this.T = t1;
+ },
+ Stream_pipe_closure: function Stream_pipe_closure(t0) {
+ this.streamConsumer = t0;
+ },
+ Stream_length_closure: function Stream_length_closure(t0, t1) {
+ this._box_0 = t0;
+ this.$this = t1;
+ },
+ Stream_length_closure0: function Stream_length_closure0(t0, t1) {
+ this._box_0 = t0;
+ this.future = t1;
+ },
+ Stream_first_closure: function Stream_first_closure(t0, t1, t2) {
+ this._box_0 = t0;
+ this.$this = t1;
+ this.future = t2;
+ },
+ Stream_first_closure0: function Stream_first_closure0(t0) {
+ this.future = t0;
+ },
+ Stream_last_closure: function Stream_last_closure(t0, t1) {
+ this._box_0 = t0;
+ this.$this = t1;
+ },
+ Stream_last_closure0: function Stream_last_closure0(t0, t1) {
+ this._box_0 = t0;
+ this.future = t1;
+ },
+ Stream_firstWhere_closure: function Stream_firstWhere_closure(t0, t1, t2, t3) {
+ var _ = this;
+ _._box_0 = t0;
+ _.$this = t1;
+ _.test = t2;
+ _.future = t3;
+ },
+ Stream_firstWhere__closure: function Stream_firstWhere__closure(t0, t1) {
+ this.test = t0;
+ this.value = t1;
+ },
+ Stream_firstWhere__closure0: function Stream_firstWhere__closure0(t0, t1, t2) {
+ this._box_0 = t0;
+ this.future = t1;
+ this.value = t2;
+ },
+ Stream_firstWhere_closure0: function Stream_firstWhere_closure0(t0, t1, t2) {
+ this.$this = t0;
+ this.orElse = t1;
+ this.future = t2;
+ },
+ StreamSubscription: function StreamSubscription() {
+ },
+ StreamTransformerBase: function StreamTransformerBase() {
+ },
+ _StreamController: function _StreamController() {
+ },
+ _StreamController__subscribe_closure: function _StreamController__subscribe_closure(t0) {
+ this.$this = t0;
+ },
+ _StreamController__recordCancel_complete: function _StreamController__recordCancel_complete(t0) {
+ this.$this = t0;
+ },
+ _SyncStreamControllerDispatch: function _SyncStreamControllerDispatch() {
+ },
+ _AsyncStreamControllerDispatch: function _AsyncStreamControllerDispatch() {
+ },
+ _AsyncStreamController: function _AsyncStreamController(t0, t1, t2, t3, t4) {
+ var _ = this;
+ _._varData = null;
+ _._state = 0;
+ _._doneFuture = null;
+ _.onListen = t0;
+ _.onPause = t1;
+ _.onResume = t2;
+ _.onCancel = t3;
+ _.$ti = t4;
+ },
+ _SyncStreamController: function _SyncStreamController(t0, t1, t2, t3, t4) {
+ var _ = this;
+ _._varData = null;
+ _._state = 0;
+ _._doneFuture = null;
+ _.onListen = t0;
+ _.onPause = t1;
+ _.onResume = t2;
+ _.onCancel = t3;
+ _.$ti = t4;
+ },
+ _ControllerStream: function _ControllerStream(t0, t1) {
+ this._controller = t0;
+ this.$ti = t1;
+ },
+ _ControllerSubscription: function _ControllerSubscription(t0, t1, t2, t3) {
+ var _ = this;
+ _._controller = t0;
+ _._onDone = _._onError = _._onData = null;
+ _._zone = t1;
+ _._state = t2;
+ _._pending = _._cancelFuture = null;
+ _.$ti = t3;
+ },
+ _StreamSinkWrapper: function _StreamSinkWrapper(t0, t1) {
+ this._async$_target = t0;
+ this.$ti = t1;
+ },
+ _AddStreamState: function _AddStreamState() {
+ },
+ _AddStreamState_makeErrorHandler_closure: function _AddStreamState_makeErrorHandler_closure(t0) {
+ this.controller = t0;
+ },
+ _AddStreamState_cancel_closure: function _AddStreamState_cancel_closure(t0) {
+ this.$this = t0;
+ },
+ _StreamControllerAddStreamState: function _StreamControllerAddStreamState(t0, t1, t2, t3) {
+ var _ = this;
+ _.varData = t0;
+ _.addStreamFuture = t1;
+ _.addSubscription = t2;
+ _.$ti = t3;
+ },
+ _BufferingStreamSubscription: function _BufferingStreamSubscription(t0, t1, t2) {
+ var _ = this;
+ _._onDone = _._onError = _._onData = null;
+ _._zone = t0;
+ _._state = t1;
+ _._pending = _._cancelFuture = null;
+ _.$ti = t2;
+ },
+ _BufferingStreamSubscription__sendError_sendError: function _BufferingStreamSubscription__sendError_sendError(t0, t1, t2) {
+ this.$this = t0;
+ this.error = t1;
+ this.stackTrace = t2;
+ },
+ _BufferingStreamSubscription__sendDone_sendDone: function _BufferingStreamSubscription__sendDone_sendDone(t0) {
+ this.$this = t0;
+ },
+ _StreamImpl: function _StreamImpl() {
+ },
+ _GeneratedStreamImpl: function _GeneratedStreamImpl(t0, t1) {
+ this._pending = t0;
+ this._isUsed = false;
+ this.$ti = t1;
+ },
+ _IterablePendingEvents: function _IterablePendingEvents(t0, t1) {
+ this._async$_iterator = t0;
+ this._state = 0;
+ this.$ti = t1;
+ },
+ _DelayedEvent: function _DelayedEvent() {
+ },
+ _DelayedData: function _DelayedData(t0, t1) {
+ this.value = t0;
+ this.next = null;
+ this.$ti = t1;
+ },
+ _DelayedError: function _DelayedError(t0, t1) {
+ this.error = t0;
+ this.stackTrace = t1;
+ this.next = null;
+ },
+ _DelayedDone: function _DelayedDone() {
+ },
+ _PendingEvents: function _PendingEvents() {
+ },
+ _PendingEvents_schedule_closure: function _PendingEvents_schedule_closure(t0, t1) {
+ this.$this = t0;
+ this.dispatch = t1;
+ },
+ _StreamImplEvents: function _StreamImplEvents(t0) {
+ var _ = this;
+ _.lastPendingEvent = _.firstPendingEvent = null;
+ _._state = 0;
+ _.$ti = t0;
+ },
+ _DoneStreamSubscription: function _DoneStreamSubscription(t0, t1, t2) {
+ var _ = this;
+ _._zone = t0;
+ _._state = 0;
+ _._onDone = t1;
+ _.$ti = t2;
+ },
+ _StreamIterator: function _StreamIterator(t0) {
+ this.$ti = t0;
+ },
+ _EmptyStream: function _EmptyStream(t0) {
+ this.$ti = t0;
+ },
+ _cancelAndError_closure: function _cancelAndError_closure(t0, t1, t2) {
+ this.future = t0;
+ this.error = t1;
+ this.stackTrace = t2;
+ },
+ _cancelAndErrorClosure_closure: function _cancelAndErrorClosure_closure(t0, t1) {
+ this.subscription = t0;
+ this.future = t1;
+ },
+ _cancelAndValue_closure: function _cancelAndValue_closure(t0, t1) {
+ this.future = t0;
+ this.value = t1;
+ },
+ Timer: function Timer() {
+ },
+ AsyncError: function AsyncError(t0, t1) {
+ this.error = t0;
+ this.stackTrace = t1;
+ },
+ _ZoneFunction: function _ZoneFunction(t0, t1, t2) {
+ this.zone = t0;
+ this.$function = t1;
+ this.$ti = t2;
+ },
+ ZoneSpecification: function ZoneSpecification() {
+ },
+ _ZoneSpecification: function _ZoneSpecification(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12) {
+ var _ = this;
+ _.handleUncaughtError = t0;
+ _.run = t1;
+ _.runUnary = t2;
+ _.runBinary = t3;
+ _.registerCallback = t4;
+ _.registerUnaryCallback = t5;
+ _.registerBinaryCallback = t6;
+ _.errorCallback = t7;
+ _.scheduleMicrotask = t8;
+ _.createTimer = t9;
+ _.createPeriodicTimer = t10;
+ _.print = t11;
+ _.fork = t12;
+ },
+ ZoneDelegate: function ZoneDelegate() {
+ },
+ Zone: function Zone() {
+ },
+ _ZoneDelegate: function _ZoneDelegate(t0) {
+ this._delegationTarget = t0;
+ },
+ _Zone: function _Zone() {
+ },
+ _CustomZone: function _CustomZone(t0, t1) {
+ var _ = this;
+ _._delegateCache = _._handleUncaughtError = _._fork = _._print = _._createPeriodicTimer = _._createTimer = _._scheduleMicrotask = _._errorCallback = _._registerBinaryCallback = _._registerUnaryCallback = _._registerCallback = _._runBinary = _._runUnary = _._run = null;
+ _.parent = t0;
+ _._async$_map = t1;
+ },
+ _CustomZone_bindCallback_closure: function _CustomZone_bindCallback_closure(t0, t1, t2) {
+ this.$this = t0;
+ this.registered = t1;
+ this.R = t2;
+ },
+ _CustomZone_bindUnaryCallback_closure: function _CustomZone_bindUnaryCallback_closure(t0, t1, t2, t3) {
+ var _ = this;
+ _.$this = t0;
+ _.registered = t1;
+ _.T = t2;
+ _.R = t3;
+ },
+ _CustomZone_bindCallbackGuarded_closure: function _CustomZone_bindCallbackGuarded_closure(t0, t1) {
+ this.$this = t0;
+ this.registered = t1;
+ },
+ _CustomZone_bindUnaryCallbackGuarded_closure: function _CustomZone_bindUnaryCallbackGuarded_closure(t0, t1, t2) {
+ this.$this = t0;
+ this.registered = t1;
+ this.T = t2;
+ },
+ _rootHandleUncaughtError_closure: function _rootHandleUncaughtError_closure(t0, t1) {
+ this._box_0 = t0;
+ this.stackTrace = t1;
+ },
+ _RootZone: function _RootZone() {
+ },
+ _RootZone_bindCallback_closure: function _RootZone_bindCallback_closure(t0, t1, t2) {
+ this.$this = t0;
+ this.f = t1;
+ this.R = t2;
+ },
+ _RootZone_bindCallbackGuarded_closure: function _RootZone_bindCallbackGuarded_closure(t0, t1) {
+ this.$this = t0;
+ this.f = t1;
+ },
+ _RootZone_bindUnaryCallbackGuarded_closure: function _RootZone_bindUnaryCallbackGuarded_closure(t0, t1, t2) {
+ this.$this = t0;
+ this.f = t1;
+ this.T = t2;
+ },
+ runZoned_closure: function runZoned_closure(t0) {
+ this._box_0 = t0;
+ },
+ HashMap_HashMap: function($K, $V) {
+ return new P._HashMap($K._eval$1("@<0>")._bind$1($V)._eval$1("_HashMap<1,2>"));
+ },
+ _HashMap__getTableEntry: function(table, key) {
+ var entry = table[key];
+ return entry === table ? null : entry;
+ },
+ _HashMap__setTableEntry: function(table, key, value) {
+ if (value == null)
+ table[key] = table;
+ else
+ table[key] = value;
+ },
+ _HashMap__newHashTable: function() {
+ var table = Object.create(null);
+ P._HashMap__setTableEntry(table, "<non-identifier-key>", table);
+ delete table["<non-identifier-key>"];
+ return table;
+ },
+ LinkedHashMap_LinkedHashMap: function($K, $V) {
+ return new H.JsLinkedHashMap($K._eval$1("@<0>")._bind$1($V)._eval$1("JsLinkedHashMap<1,2>"));
+ },
+ LinkedHashMap_LinkedHashMap$_literal: function(keyValuePairs, $K, $V) {
+ return $K._eval$1("@<0>")._bind$1($V)._eval$1("LinkedHashMap<1,2>")._check(H.fillLiteralMap(keyValuePairs, new H.JsLinkedHashMap($K._eval$1("@<0>")._bind$1($V)._eval$1("JsLinkedHashMap<1,2>"))));
+ },
+ LinkedHashMap_LinkedHashMap$_empty: function($K, $V) {
+ return new H.JsLinkedHashMap($K._eval$1("@<0>")._bind$1($V)._eval$1("JsLinkedHashMap<1,2>"));
+ },
+ LinkedHashSet_LinkedHashSet: function($E) {
+ return new P._LinkedHashSet($E._eval$1("_LinkedHashSet<0>"));
+ },
+ LinkedHashSet_LinkedHashSet$_empty: function($E) {
+ return new P._LinkedHashSet($E._eval$1("_LinkedHashSet<0>"));
+ },
+ LinkedHashSet_LinkedHashSet$_literal: function(values, $E) {
+ return $E._eval$1("LinkedHashSet<0>")._check(H.fillLiteralSet(values, new P._LinkedHashSet($E._eval$1("_LinkedHashSet<0>"))));
+ },
+ _LinkedHashSet__newHashTable: function() {
+ var table = Object.create(null);
+ H.assertHelper(table != null);
+ table["<non-identifier-key>"] = table;
+ delete table["<non-identifier-key>"];
+ return table;
+ },
+ _LinkedHashSetIterator$: function(_set, _modifications, $E) {
+ var t1 = new P._LinkedHashSetIterator(_set, _modifications, $E._eval$1("_LinkedHashSetIterator<0>"));
+ t1._collection$_cell = _set._collection$_first;
+ return t1;
+ },
+ HashMap_HashMap$from: function(other, $K, $V) {
+ var result = P.HashMap_HashMap($K, $V);
+ other.forEach$1(0, new P.HashMap_HashMap$from_closure(result, $K, $V));
+ return result;
+ },
+ IterableBase_iterableToShortString: function(iterable, leftDelimiter, rightDelimiter) {
+ var parts, t1;
+ if (P._isToStringVisiting(iterable)) {
+ if (leftDelimiter === "(" && rightDelimiter === ")")
+ return "(...)";
+ return leftDelimiter + "..." + rightDelimiter;
+ }
+ parts = H.setRuntimeTypeInfo([], type$.JSArray_String);
+ C.JSArray_methods.add$1($._toStringVisiting, iterable);
+ try {
+ P._iterablePartsToStrings(iterable, parts);
+ } finally {
+ H.assertHelper(C.JSArray_methods.get$last($._toStringVisiting) === iterable);
+ if (0 >= $._toStringVisiting.length)
+ return H.ioore($._toStringVisiting, -1);
+ $._toStringVisiting.pop();
+ }
+ t1 = P.StringBuffer__writeAll(leftDelimiter, type$.Iterable_dynamic._check(parts), ", ") + rightDelimiter;
+ return t1.charCodeAt(0) == 0 ? t1 : t1;
+ },
+ IterableBase_iterableToFullString: function(iterable, leftDelimiter, rightDelimiter) {
+ var buffer, t1;
+ if (P._isToStringVisiting(iterable))
+ return leftDelimiter + "..." + rightDelimiter;
+ buffer = new P.StringBuffer(leftDelimiter);
+ C.JSArray_methods.add$1($._toStringVisiting, iterable);
+ try {
+ t1 = buffer;
+ t1._contents = P.StringBuffer__writeAll(t1._contents, iterable, ", ");
+ } finally {
+ H.assertHelper(C.JSArray_methods.get$last($._toStringVisiting) === iterable);
+ if (0 >= $._toStringVisiting.length)
+ return H.ioore($._toStringVisiting, -1);
+ $._toStringVisiting.pop();
+ }
+ buffer._contents += rightDelimiter;
+ t1 = buffer._contents;
+ return t1.charCodeAt(0) == 0 ? t1 : t1;
+ },
+ _isToStringVisiting: function(o) {
+ var t1, i;
+ for (t1 = $._toStringVisiting.length, i = 0; i < t1; ++i)
+ if (o === $._toStringVisiting[i])
+ return true;
+ return false;
+ },
+ _iterablePartsToStrings: function(iterable, parts) {
+ var next, ultimateString, penultimateString, penultimate, ultimate, ultimate0, elision,
+ it = iterable.get$iterator(iterable),
+ $length = 0, count = 0;
+ while (true) {
+ if (!($length < 80 || count < 3))
+ break;
+ if (!it.moveNext$0())
+ return;
+ next = H.S(it.get$current());
+ C.JSArray_methods.add$1(parts, next);
+ $length += next.length + 2;
+ ++count;
+ }
+ if (!it.moveNext$0()) {
+ if (count <= 5)
+ return;
+ if (0 >= parts.length)
+ return H.ioore(parts, -1);
+ ultimateString = parts.pop();
+ if (0 >= parts.length)
+ return H.ioore(parts, -1);
+ penultimateString = parts.pop();
+ } else {
+ penultimate = it.get$current();
+ ++count;
+ if (!it.moveNext$0()) {
+ if (count <= 4) {
+ C.JSArray_methods.add$1(parts, H.S(penultimate));
+ return;
+ }
+ ultimateString = H.S(penultimate);
+ if (0 >= parts.length)
+ return H.ioore(parts, -1);
+ penultimateString = parts.pop();
+ $length += ultimateString.length + 2;
+ } else {
+ ultimate = it.get$current();
+ ++count;
+ H.assertHelper(count < 100);
+ for (; it.moveNext$0(); penultimate = ultimate, ultimate = ultimate0) {
+ ultimate0 = it.get$current();
+ ++count;
+ if (count > 100) {
+ while (true) {
+ if (!($length > 75 && count > 3))
+ break;
+ if (0 >= parts.length)
+ return H.ioore(parts, -1);
+ $length -= parts.pop().length + 2;
+ --count;
+ }
+ C.JSArray_methods.add$1(parts, "...");
+ return;
+ }
+ }
+ penultimateString = H.S(penultimate);
+ ultimateString = H.S(ultimate);
+ $length += ultimateString.length + penultimateString.length + 4;
+ }
+ }
+ if (count > parts.length + 2) {
+ $length += 5;
+ elision = "...";
+ } else
+ elision = null;
+ while (true) {
+ if (!($length > 80 && parts.length > 3))
+ break;
+ if (0 >= parts.length)
+ return H.ioore(parts, -1);
+ $length -= parts.pop().length + 2;
+ if (elision == null) {
+ $length += 5;
+ elision = "...";
+ }
+ }
+ if (elision != null)
+ C.JSArray_methods.add$1(parts, elision);
+ C.JSArray_methods.add$1(parts, penultimateString);
+ C.JSArray_methods.add$1(parts, ultimateString);
+ },
+ LinkedHashMap_LinkedHashMap$from: function(other, $K, $V) {
+ var result = P.LinkedHashMap_LinkedHashMap($K, $V);
+ other.forEach$1(0, new P.LinkedHashMap_LinkedHashMap$from_closure(result, $K, $V));
+ return result;
+ },
+ LinkedHashSet_LinkedHashSet$from: function(elements, $E) {
+ var t1,
+ result = P.LinkedHashSet_LinkedHashSet($E);
+ for (t1 = J.get$iterator$ax(elements); t1.moveNext$0();)
+ result.add$1(0, $E._check(t1.get$current()));
+ return result;
+ },
+ MapBase_mapToString: function(m) {
+ var result, t1 = {};
+ if (P._isToStringVisiting(m))
+ return "{...}";
+ result = new P.StringBuffer("");
+ try {
+ C.JSArray_methods.add$1($._toStringVisiting, m);
+ result._contents += "{";
+ t1.first = true;
+ m.forEach$1(0, new P.MapBase_mapToString_closure(t1, result));
+ result._contents += "}";
+ } finally {
+ H.assertHelper(C.JSArray_methods.get$last($._toStringVisiting) === m);
+ if (0 >= $._toStringVisiting.length)
+ return H.ioore($._toStringVisiting, -1);
+ $._toStringVisiting.pop();
+ }
+ t1 = result._contents;
+ return t1.charCodeAt(0) == 0 ? t1 : t1;
+ },
+ ListQueue$: function($E) {
+ var t1 = new P.ListQueue($E._eval$1("ListQueue<0>")),
+ t2 = new Array(8);
+ t2.fixed$length = Array;
+ t1.set$_table(H.setRuntimeTypeInfo(t2, $E._eval$1("JSArray<0>")));
+ return t1;
+ },
+ _ListQueueIterator$: function(queue, $E) {
+ return new P._ListQueueIterator(queue, queue._tail, queue._modificationCount, queue._head, $E._eval$1("_ListQueueIterator<0>"));
+ },
+ _HashMap: function _HashMap(t0) {
+ var _ = this;
+ _._collection$_length = 0;
+ _._keys = _._collection$_rest = _._nums = _._strings = null;
+ _.$ti = t0;
+ },
+ _IdentityHashMap: function _IdentityHashMap(t0) {
+ var _ = this;
+ _._collection$_length = 0;
+ _._keys = _._collection$_rest = _._nums = _._strings = null;
+ _.$ti = t0;
+ },
+ _HashMapKeyIterable: function _HashMapKeyIterable(t0, t1) {
+ this._map = t0;
+ this.$ti = t1;
+ },
+ _HashMapKeyIterator: function _HashMapKeyIterator(t0, t1, t2) {
+ var _ = this;
+ _._map = t0;
+ _._keys = t1;
+ _._offset = 0;
+ _._collection$_current = null;
+ _.$ti = t2;
+ },
+ _LinkedHashSet: function _LinkedHashSet(t0) {
+ var _ = this;
+ _._collection$_length = 0;
+ _._collection$_last = _._collection$_first = _._collection$_rest = _._nums = _._strings = null;
+ _._collection$_modifications = 0;
+ _.$ti = t0;
+ },
+ _LinkedHashSetCell: function _LinkedHashSetCell(t0) {
+ this._element = t0;
+ this._collection$_previous = this._collection$_next = null;
+ },
+ _LinkedHashSetIterator: function _LinkedHashSetIterator(t0, t1, t2) {
+ var _ = this;
+ _._set = t0;
+ _._collection$_modifications = t1;
+ _._collection$_current = _._collection$_cell = null;
+ _.$ti = t2;
+ },
+ UnmodifiableListView: function UnmodifiableListView(t0, t1) {
+ this._collection$_source = t0;
+ this.$ti = t1;
+ },
+ HashMap_HashMap$from_closure: function HashMap_HashMap$from_closure(t0, t1, t2) {
+ this.result = t0;
+ this.K = t1;
+ this.V = t2;
+ },
+ IterableBase: function IterableBase() {
+ },
+ LinkedHashMap_LinkedHashMap$from_closure: function LinkedHashMap_LinkedHashMap$from_closure(t0, t1, t2) {
+ this.result = t0;
+ this.K = t1;
+ this.V = t2;
+ },
+ ListBase: function ListBase() {
+ },
+ ListMixin: function ListMixin() {
+ },
+ MapBase: function MapBase() {
+ },
+ MapBase_mapToString_closure: function MapBase_mapToString_closure(t0, t1) {
+ this._box_0 = t0;
+ this.result = t1;
+ },
+ MapMixin: function MapMixin() {
+ },
+ _UnmodifiableMapMixin: function _UnmodifiableMapMixin() {
+ },
+ MapView: function MapView() {
+ },
+ UnmodifiableMapView: function UnmodifiableMapView(t0, t1) {
+ this._map = t0;
+ this.$ti = t1;
+ },
+ ListQueue: function ListQueue(t0) {
+ var _ = this;
+ _._table = null;
+ _._modificationCount = _._tail = _._head = 0;
+ _.$ti = t0;
+ },
+ _ListQueueIterator: function _ListQueueIterator(t0, t1, t2, t3, t4) {
+ var _ = this;
+ _._queue = t0;
+ _._end = t1;
+ _._modificationCount = t2;
+ _._position = t3;
+ _._collection$_current = null;
+ _.$ti = t4;
+ },
+ SetMixin: function SetMixin() {
+ },
+ SetBase: function SetBase() {
+ },
+ _SetBase: function _SetBase() {
+ },
+ _ListBase_Object_ListMixin: function _ListBase_Object_ListMixin() {
+ },
+ _SetBase_Object_SetMixin: function _SetBase_Object_SetMixin() {
+ },
+ _UnmodifiableMapView_MapView__UnmodifiableMapMixin: function _UnmodifiableMapView_MapView__UnmodifiableMapMixin() {
+ },
+ _parseJson: function(source, reviver) {
+ var parsed, e, exception, t1;
+ if (typeof source != "string")
+ throw H.wrapException(H.argumentErrorValue(source));
+ parsed = null;
+ try {
+ parsed = JSON.parse(source);
+ } catch (exception) {
+ e = H.unwrapException(exception);
+ t1 = P.FormatException$(String(e), null, null);
+ throw H.wrapException(t1);
+ }
+ t1 = P._convertJsonToDartLazy(parsed);
+ return t1;
+ },
+ _convertJsonToDartLazy: function(object) {
+ var i;
+ if (object == null)
+ return null;
+ if (typeof object != "object")
+ return object;
+ if (Object.getPrototypeOf(object) !== Array.prototype)
+ return new P._JsonMap(object, Object.create(null));
+ for (i = 0; i < object.length; ++i)
+ object[i] = P._convertJsonToDartLazy(object[i]);
+ return object;
+ },
+ Utf8Decoder__convertIntercepted: function(allowMalformed, codeUnits, start, end) {
+ if (codeUnits instanceof Uint8Array)
+ return P.Utf8Decoder__convertInterceptedUint8List(false, codeUnits, start, end);
+ return null;
+ },
+ Utf8Decoder__convertInterceptedUint8List: function(allowMalformed, codeUnits, start, end) {
+ var t1, $length,
+ decoder = $.$get$Utf8Decoder__decoder();
+ if (decoder == null)
+ return null;
+ t1 = 0 === start;
+ if (t1 && true)
+ return P.Utf8Decoder__useTextDecoderChecked(decoder, codeUnits);
+ $length = codeUnits.length;
+ end = P.RangeError_checkValidRange(start, end, $length);
+ if (t1 && end === $length)
+ return P.Utf8Decoder__useTextDecoderChecked(decoder, codeUnits);
+ return P.Utf8Decoder__useTextDecoderChecked(decoder, codeUnits.subarray(start, end));
+ },
+ Utf8Decoder__useTextDecoderChecked: function(decoder, codeUnits) {
+ if (P.Utf8Decoder__unsafe(codeUnits))
+ return null;
+ return P.Utf8Decoder__useTextDecoderUnchecked(decoder, codeUnits);
+ },
+ Utf8Decoder__useTextDecoderUnchecked: function(decoder, codeUnits) {
+ var t1, exception;
+ try {
+ t1 = decoder.decode(codeUnits);
+ return t1;
+ } catch (exception) {
+ H.unwrapException(exception);
+ }
+ return null;
+ },
+ Utf8Decoder__unsafe: function(codeUnits) {
+ var i,
+ limit = codeUnits.length - 2;
+ for (i = 0; i < limit; ++i)
+ if (codeUnits[i] === 237)
+ if ((codeUnits[i + 1] & 224) === 160)
+ return true;
+ return false;
+ },
+ Utf8Decoder__makeDecoder: function() {
+ var t1, exception;
+ try {
+ t1 = new TextDecoder("utf-8", {fatal: true});
+ return t1;
+ } catch (exception) {
+ H.unwrapException(exception);
+ }
+ return null;
+ },
+ _scanOneByteCharacters: function(units, from, endIndex) {
+ var t1, i, unit;
+ for (t1 = J.getInterceptor$asx(units), i = from; i < endIndex; ++i) {
+ unit = t1.$index(units, i);
+ if (typeof unit !== "number")
+ return unit.$and();
+ if ((unit & 127) !== unit)
+ return i - from;
+ }
+ return endIndex - from;
+ },
+ Base64Codec__checkPadding: function(source, sourceIndex, sourceEnd, firstPadding, paddingCount, $length) {
+ if (C.JSInt_methods.$mod($length, 4) !== 0)
+ throw H.wrapException(P.FormatException$("Invalid base64 padding, padded length must be multiple of four, is " + $length, source, sourceEnd));
+ if (firstPadding + paddingCount !== $length)
+ throw H.wrapException(P.FormatException$("Invalid base64 padding, '=' not at the end", source, sourceIndex));
+ if (paddingCount > 2)
+ throw H.wrapException(P.FormatException$("Invalid base64 padding, more than two '=' characters", source, sourceIndex));
+ },
+ _JsonMap: function _JsonMap(t0, t1) {
+ this._original = t0;
+ this._processed = t1;
+ this._data = null;
+ },
+ _JsonMapKeyIterable: function _JsonMapKeyIterable(t0) {
+ this._parent = t0;
+ },
+ AsciiCodec: function AsciiCodec() {
+ },
+ _UnicodeSubsetEncoder: function _UnicodeSubsetEncoder() {
+ },
+ AsciiEncoder: function AsciiEncoder(t0) {
+ this._subsetMask = t0;
+ },
+ Base64Codec: function Base64Codec() {
+ },
+ Base64Encoder: function Base64Encoder() {
+ },
+ Codec: function Codec() {
+ },
+ _FusedCodec: function _FusedCodec(t0, t1, t2) {
+ this._convert$_first = t0;
+ this._second = t1;
+ this.$ti = t2;
+ },
+ Converter: function Converter() {
+ },
+ Encoding: function Encoding() {
+ },
+ JsonCodec: function JsonCodec() {
+ },
+ JsonDecoder: function JsonDecoder(t0) {
+ this._reviver = t0;
+ },
+ Utf8Codec: function Utf8Codec() {
+ },
+ Utf8Encoder: function Utf8Encoder() {
+ },
+ _Utf8Encoder: function _Utf8Encoder(t0) {
+ this._bufferIndex = this._carry = 0;
+ this._buffer = t0;
+ },
+ Utf8Decoder: function Utf8Decoder(t0) {
+ this._allowMalformed = t0;
+ },
+ _Utf8Decoder: function _Utf8Decoder(t0, t1) {
+ var _ = this;
+ _._allowMalformed = t0;
+ _._stringSink = t1;
+ _._isFirstCharacter = true;
+ _._extraUnits = _._expectedUnits = _._convert$_value = 0;
+ },
+ int_parse: function(source, onError, radix) {
+ var value = H.Primitives_parseInt(source, radix);
+ if (value != null)
+ return value;
+ if (onError != null)
+ return onError.call$1(source);
+ throw H.wrapException(P.FormatException$(source, null, null));
+ },
+ Error__objectToString: function(object) {
+ if (object instanceof H.Closure)
+ return object.toString$0(0);
+ return "Instance of '" + H.S(H.Primitives_objectTypeName(object)) + "'";
+ },
+ List_List$filled: function($length, fill, $E) {
+ var i,
+ result = J.JSArray_JSArray$fixed($length, $E);
+ if ($length !== 0 && true)
+ for (i = 0; i < result.length; ++i)
+ C.JSArray_methods.$indexSet(result, i, fill);
+ return result;
+ },
+ List_List$from: function(elements, growable, $E) {
+ var t1,
+ list = H.setRuntimeTypeInfo([], $E._eval$1("JSArray<0>"));
+ for (t1 = J.get$iterator$ax(elements); t1.moveNext$0();)
+ C.JSArray_methods.add$1(list, $E._check(t1.get$current()));
+ if (growable)
+ return list;
+ return $E._eval$1("List<0>")._check(J.JSArray_markFixedList(list));
+ },
+ List_List$unmodifiable: function(elements, $E) {
+ var result = P.List_List$from(elements, false, $E);
+ result.fixed$length = Array;
+ result.immutable$list = Array;
+ return $E._eval$1("List<0>")._check(result);
+ },
+ String_String$fromCharCodes: function(charCodes, start, end) {
+ var len;
+ if (Array.isArray(charCodes)) {
+ type$.JSArray_int._check(charCodes);
+ len = charCodes.length;
+ end = P.RangeError_checkValidRange(start, end, len);
+ return H.Primitives_stringFromCharCodes(start > 0 || end < len ? C.JSArray_methods.sublist$2(charCodes, start, end) : charCodes);
+ }
+ if (type$.NativeUint8List._is(charCodes))
+ return H.Primitives_stringFromNativeUint8List(charCodes, start, P.RangeError_checkValidRange(start, end, charCodes.length));
+ return P.String__stringFromIterable(charCodes, start, end);
+ },
+ String_String$fromCharCode: function(charCode) {
+ return H.Primitives_stringFromCharCode(charCode);
+ },
+ String__stringFromIterable: function(charCodes, start, end) {
+ var t1, it, i, list, _null = null;
+ if (start < 0)
+ throw H.wrapException(P.RangeError$range(start, 0, J.get$length$asx(charCodes), _null, _null));
+ t1 = end == null;
+ if (!t1 && end < start)
+ throw H.wrapException(P.RangeError$range(end, start, J.get$length$asx(charCodes), _null, _null));
+ it = J.get$iterator$ax(charCodes);
+ for (i = 0; i < start; ++i)
+ if (!it.moveNext$0())
+ throw H.wrapException(P.RangeError$range(start, 0, i, _null, _null));
+ list = [];
+ if (t1)
+ for (; it.moveNext$0();)
+ list.push(it.get$current());
+ else
+ for (i = start; i < end; ++i) {
+ if (!it.moveNext$0())
+ throw H.wrapException(P.RangeError$range(end, start, i, _null, _null));
+ list.push(it.get$current());
+ }
+ return H.Primitives_stringFromCharCodes(list);
+ },
+ RegExp_RegExp: function(source, multiLine) {
+ return new H.JSSyntaxRegExp(source, H.JSSyntaxRegExp_makeNative(source, multiLine, true, false, false, false));
+ },
+ StringBuffer__writeAll: function(string, objects, separator) {
+ var iterator = J.get$iterator$ax(objects);
+ if (!iterator.moveNext$0())
+ return string;
+ if (separator.length === 0) {
+ do
+ string += H.S(iterator.get$current());
+ while (iterator.moveNext$0());
+ } else {
+ string += H.S(iterator.get$current());
+ for (; iterator.moveNext$0();)
+ string = string + separator + H.S(iterator.get$current());
+ }
+ return string;
+ },
+ Uri_base: function() {
+ var uri = H.Primitives_currentUri();
+ if (uri != null)
+ return P.Uri_parse(uri);
+ throw H.wrapException(P.UnsupportedError$("'Uri.base' is not supported"));
+ },
+ _Uri__uriEncode: function(canonicalTable, text, encoding, spaceToPlus) {
+ var t1, bytes, i, t2, byte, t3,
+ _s16_ = "0123456789ABCDEF";
+ if (encoding === C.C_Utf8Codec) {
+ t1 = $.$get$_Uri__needsNoEncoding()._nativeRegExp;
+ if (typeof text != "string")
+ H.throwExpression(H.argumentErrorValue(text));
+ t1 = t1.test(text);
+ } else
+ t1 = false;
+ if (t1)
+ return text;
+ H._instanceType(encoding)._eval$1("Codec.S")._check(text);
+ bytes = encoding.get$encoder().convert$1(text);
+ for (t1 = bytes.length, i = 0, t2 = ""; i < t1; ++i) {
+ byte = bytes[i];
+ if (byte < 128) {
+ t3 = byte >>> 4;
+ if (t3 >= 8)
+ return H.ioore(canonicalTable, t3);
+ t3 = (canonicalTable[t3] & 1 << (byte & 15)) !== 0;
+ } else
+ t3 = false;
+ if (t3)
+ t2 += H.Primitives_stringFromCharCode(byte);
+ else
+ t2 = spaceToPlus && byte === 32 ? t2 + "+" : t2 + "%" + _s16_[byte >>> 4 & 15] + _s16_[byte & 15];
+ }
+ return t2.charCodeAt(0) == 0 ? t2 : t2;
+ },
+ StackTrace_current: function() {
+ var stackTrace, exception;
+ if (H.boolConversionCheck($.$get$_hasErrorStackProperty()))
+ return H.getTraceFromException(new Error());
+ try {
+ throw H.wrapException("");
+ } catch (exception) {
+ H.unwrapException(exception);
+ stackTrace = H.getTraceFromException(exception);
+ return stackTrace;
+ }
+ },
+ DateTime__fourDigits: function(n) {
+ var absN = Math.abs(n),
+ sign = n < 0 ? "-" : "";
+ if (absN >= 1000)
+ return "" + n;
+ if (absN >= 100)
+ return sign + "0" + absN;
+ if (absN >= 10)
+ return sign + "00" + absN;
+ return sign + "000" + absN;
+ },
+ DateTime__threeDigits: function(n) {
+ if (n >= 100)
+ return "" + n;
+ if (n >= 10)
+ return "0" + n;
+ return "00" + n;
+ },
+ DateTime__twoDigits: function(n) {
+ if (n >= 10)
+ return "" + n;
+ return "0" + n;
+ },
+ Duration$: function(microseconds, minutes) {
+ if (typeof microseconds !== "number")
+ return H.iae(microseconds);
+ return new P.Duration(60000000 * minutes + microseconds);
+ },
+ Error_safeToString: function(object) {
+ if (typeof object == "number" || H._isBool(object) || null == object)
+ return J.toString$0$(object);
+ if (typeof object == "string")
+ return JSON.stringify(object);
+ return P.Error__objectToString(object);
+ },
+ AssertionError$: function(message) {
+ return new P.AssertionError(message);
+ },
+ ArgumentError$: function(message) {
+ return new P.ArgumentError(false, null, null, message);
+ },
+ ArgumentError$value: function(value, $name, message) {
+ return new P.ArgumentError(true, value, $name, message);
+ },
+ ArgumentError$notNull: function($name) {
+ return new P.ArgumentError(false, null, $name, "Must not be null");
+ },
+ RangeError$: function(message) {
+ var _null = null;
+ return new P.RangeError(_null, _null, false, _null, _null, message);
+ },
+ RangeError$value: function(value, $name) {
+ return new P.RangeError(null, null, true, value, $name, "Value not in range");
+ },
+ RangeError$range: function(invalidValue, minValue, maxValue, $name, message) {
+ return new P.RangeError(minValue, maxValue, true, invalidValue, $name, "Invalid value");
+ },
+ RangeError_checkValueInInterval: function(value, minValue, maxValue, $name) {
+ if (value < minValue || value > maxValue)
+ throw H.wrapException(P.RangeError$range(value, minValue, maxValue, $name, null));
+ },
+ RangeError_checkValidRange: function(start, end, $length) {
+ if (0 > start || start > $length)
+ throw H.wrapException(P.RangeError$range(start, 0, $length, "start", null));
+ if (end != null) {
+ if (start > end || end > $length)
+ throw H.wrapException(P.RangeError$range(end, start, $length, "end", null));
+ return end;
+ }
+ return $length;
+ },
+ RangeError_checkNotNegative: function(value, $name) {
+ if (typeof value !== "number")
+ return value.$lt();
+ if (value < 0)
+ throw H.wrapException(P.RangeError$range(value, 0, null, $name, null));
+ },
+ IndexError$: function(invalidValue, indexable, $name, message, $length) {
+ var t1 = H._checkIntNullable($length == null ? J.get$length$asx(indexable) : $length);
+ return new P.IndexError(t1, true, invalidValue, $name, "Index out of range");
+ },
+ UnsupportedError$: function(message) {
+ return new P.UnsupportedError(message);
+ },
+ UnimplementedError$: function(message) {
+ return new P.UnimplementedError(message);
+ },
+ StateError$: function(message) {
+ return new P.StateError(message);
+ },
+ ConcurrentModificationError$: function(modifiedObject) {
+ return new P.ConcurrentModificationError(modifiedObject);
+ },
+ FormatException$: function(message, source, offset) {
+ return new P.FormatException(message, source, offset);
+ },
+ List_List$generate: function($length, generator, growable, $E) {
+ var i,
+ result = H.setRuntimeTypeInfo([], $E._eval$1("JSArray<0>"));
+ C.JSArray_methods.set$length(result, $length);
+ for (i = 0; i < $length; ++i)
+ C.JSArray_methods.$indexSet(result, i, generator.call$1(i));
+ return result;
+ },
+ Map_castFrom: function(source, $K, $V, K2, V2) {
+ return new H.CastMap(source, $K._eval$1("@<0>")._bind$1($V)._bind$1(K2)._bind$1(V2)._eval$1("CastMap<1,2,3,4>"));
+ },
+ print: function(object) {
+ var line = H.S(object),
+ t1 = $.printToZone;
+ if (t1 == null)
+ H.printString(line);
+ else
+ t1.call$1(line);
+ },
+ _combineSurrogatePair: function(start, end) {
+ return 65536 + ((start & 1023) << 10) + (end & 1023);
+ },
+ Uri_parse: function(uri) {
+ var delta, t1, indices, schemeEnd, hostStart, portStart, pathStart, queryStart, fragmentStart, isSimple, scheme, t2, schemeAuth, queryStart0, pathStart0, _null = null,
+ end = uri.length;
+ if (end >= 5) {
+ delta = ((J._codeUnitAt$1$s(uri, 4) ^ 58) * 3 | C.JSString_methods._codeUnitAt$1(uri, 0) ^ 100 | C.JSString_methods._codeUnitAt$1(uri, 1) ^ 97 | C.JSString_methods._codeUnitAt$1(uri, 2) ^ 116 | C.JSString_methods._codeUnitAt$1(uri, 3) ^ 97) >>> 0;
+ if (delta === 0)
+ return P.UriData__parse(end < end ? C.JSString_methods.substring$2(uri, 0, end) : uri, 5, _null).get$uri();
+ else if (delta === 32)
+ return P.UriData__parse(C.JSString_methods.substring$2(uri, 5, end), 0, _null).get$uri();
+ }
+ t1 = new Array(8);
+ t1.fixed$length = Array;
+ indices = H.setRuntimeTypeInfo(t1, type$.JSArray_int);
+ C.JSArray_methods.$indexSet(indices, 0, 0);
+ C.JSArray_methods.$indexSet(indices, 1, -1);
+ C.JSArray_methods.$indexSet(indices, 2, -1);
+ C.JSArray_methods.$indexSet(indices, 7, -1);
+ C.JSArray_methods.$indexSet(indices, 3, 0);
+ C.JSArray_methods.$indexSet(indices, 4, 0);
+ C.JSArray_methods.$indexSet(indices, 5, end);
+ C.JSArray_methods.$indexSet(indices, 6, end);
+ if (P._scan(uri, 0, end, 0, indices) >= 14)
+ C.JSArray_methods.$indexSet(indices, 7, end);
+ schemeEnd = indices[1];
+ if (typeof schemeEnd !== "number")
+ return schemeEnd.$ge();
+ if (schemeEnd >= 0)
+ if (P._scan(uri, 0, schemeEnd, 20, indices) === 20)
+ indices[7] = schemeEnd;
+ t1 = indices[2];
+ if (typeof t1 !== "number")
+ return t1.$add();
+ hostStart = t1 + 1;
+ portStart = indices[3];
+ pathStart = indices[4];
+ queryStart = indices[5];
+ fragmentStart = indices[6];
+ if (typeof fragmentStart !== "number")
+ return fragmentStart.$lt();
+ if (typeof queryStart !== "number")
+ return H.iae(queryStart);
+ if (fragmentStart < queryStart)
+ queryStart = fragmentStart;
+ if (typeof pathStart !== "number")
+ return pathStart.$lt();
+ if (pathStart < hostStart)
+ pathStart = queryStart;
+ else if (pathStart <= schemeEnd)
+ pathStart = schemeEnd + 1;
+ if (typeof portStart !== "number")
+ return portStart.$lt();
+ if (portStart < hostStart)
+ portStart = pathStart;
+ H.assertHelper(hostStart === 0 || schemeEnd <= hostStart);
+ H.assertHelper(hostStart <= portStart);
+ H.assertHelper(schemeEnd <= pathStart);
+ H.assertHelper(portStart <= pathStart);
+ H.assertHelper(pathStart <= queryStart);
+ H.assertHelper(queryStart <= fragmentStart);
+ t1 = indices[7];
+ if (typeof t1 !== "number")
+ return t1.$lt();
+ isSimple = t1 < 0;
+ if (isSimple)
+ if (hostStart > schemeEnd + 3) {
+ scheme = _null;
+ isSimple = false;
+ } else {
+ t1 = portStart > 0;
+ if (t1 && portStart + 1 === pathStart) {
+ scheme = _null;
+ isSimple = false;
+ } else {
+ if (!(queryStart < end && queryStart === pathStart + 2 && J.startsWith$2$s(uri, "..", pathStart)))
+ t2 = queryStart > pathStart + 2 && J.startsWith$2$s(uri, "/..", queryStart - 3);
+ else
+ t2 = true;
+ if (t2) {
+ scheme = _null;
+ isSimple = false;
+ } else {
+ if (schemeEnd === 4)
+ if (J.startsWith$2$s(uri, "file", 0)) {
+ if (hostStart <= 0) {
+ if (!C.JSString_methods.startsWith$2(uri, "/", pathStart)) {
+ schemeAuth = "file:///";
+ delta = 3;
+ } else {
+ schemeAuth = "file://";
+ delta = 2;
+ }
+ uri = schemeAuth + C.JSString_methods.substring$2(uri, pathStart, end);
+ schemeEnd -= 0;
+ t1 = delta - 0;
+ queryStart += t1;
+ fragmentStart += t1;
+ end = uri.length;
+ hostStart = 7;
+ portStart = 7;
+ pathStart = 7;
+ } else if (pathStart === queryStart) {
+ queryStart0 = queryStart + 1;
+ ++fragmentStart;
+ uri = C.JSString_methods.replaceRange$3(uri, pathStart, queryStart, "/");
+ ++end;
+ queryStart = queryStart0;
+ }
+ scheme = "file";
+ } else if (C.JSString_methods.startsWith$2(uri, "http", 0)) {
+ if (t1 && portStart + 3 === pathStart && C.JSString_methods.startsWith$2(uri, "80", portStart + 1)) {
+ pathStart0 = pathStart - 3;
+ queryStart -= 3;
+ fragmentStart -= 3;
+ uri = C.JSString_methods.replaceRange$3(uri, portStart, pathStart, "");
+ end -= 3;
+ pathStart = pathStart0;
+ }
+ scheme = "http";
+ } else
+ scheme = _null;
+ else if (schemeEnd === 5 && J.startsWith$2$s(uri, "https", 0)) {
+ if (t1 && portStart + 4 === pathStart && J.startsWith$2$s(uri, "443", portStart + 1)) {
+ pathStart0 = pathStart - 4;
+ queryStart -= 4;
+ fragmentStart -= 4;
+ uri = J.replaceRange$3$asx(uri, portStart, pathStart, "");
+ end -= 3;
+ pathStart = pathStart0;
+ }
+ scheme = "https";
+ } else
+ scheme = _null;
+ isSimple = true;
+ }
+ }
+ }
+ else
+ scheme = _null;
+ if (isSimple) {
+ t1 = uri.length;
+ if (end < t1) {
+ uri = J.substring$2$s(uri, 0, end);
+ schemeEnd -= 0;
+ hostStart -= 0;
+ portStart -= 0;
+ pathStart -= 0;
+ queryStart -= 0;
+ fragmentStart -= 0;
+ }
+ return new P._SimpleUri(uri, schemeEnd, hostStart, portStart, pathStart, queryStart, fragmentStart, scheme);
+ }
+ return P._Uri__Uri$notSimple(uri, 0, end, schemeEnd, hostStart, portStart, pathStart, queryStart, fragmentStart, scheme);
+ },
+ Uri_decodeComponent: function(encodedComponent) {
+ H._checkStringNullable(encodedComponent);
+ return P._Uri__uriDecode(encodedComponent, 0, encodedComponent.length, C.C_Utf8Codec, false);
+ },
+ Uri__parseIPv4Address: function(host, start, end) {
+ var t1, i, partStart, partIndex, char, part, partIndex0, _null = null,
+ _s43_ = "IPv4 address should contain exactly 4 parts",
+ _s37_ = "each part must be in the range 0..255",
+ error = new P.Uri__parseIPv4Address_error(host),
+ result = new Uint8Array(4);
+ for (t1 = result.length, i = start, partStart = i, partIndex = 0; i < end; ++i) {
+ char = C.JSString_methods.codeUnitAt$1(host, i);
+ if (char !== 46) {
+ if ((char ^ 48) > 9)
+ error.call$2("invalid character", i);
+ } else {
+ if (partIndex === 3)
+ error.call$2(_s43_, i);
+ part = P.int_parse(C.JSString_methods.substring$2(host, partStart, i), _null, _null);
+ if (typeof part !== "number")
+ return part.$gt();
+ if (part > 255)
+ error.call$2(_s37_, partStart);
+ partIndex0 = partIndex + 1;
+ if (partIndex >= t1)
+ return H.ioore(result, partIndex);
+ result[partIndex] = part;
+ partStart = i + 1;
+ partIndex = partIndex0;
+ }
+ }
+ if (partIndex !== 3)
+ error.call$2(_s43_, end);
+ part = P.int_parse(C.JSString_methods.substring$2(host, partStart, end), _null, _null);
+ if (typeof part !== "number")
+ return part.$gt();
+ if (part > 255)
+ error.call$2(_s37_, partStart);
+ if (partIndex >= t1)
+ return H.ioore(result, partIndex);
+ result[partIndex] = part;
+ return result;
+ },
+ Uri_parseIPv6Address: function(host, start, end) {
+ var parts, i, partStart, wildcardSeen, seenDot, char, atEnd, t1, last, bytes, t2, wildCardLength, index, value, j, t3,
+ error = new P.Uri_parseIPv6Address_error(host),
+ parseHex = new P.Uri_parseIPv6Address_parseHex(error, host);
+ if (host.length < 2)
+ error.call$1("address is too short");
+ parts = H.setRuntimeTypeInfo([], type$.JSArray_int);
+ for (i = start, partStart = i, wildcardSeen = false, seenDot = false; i < end; ++i) {
+ char = C.JSString_methods.codeUnitAt$1(host, i);
+ if (char === 58) {
+ if (i === start) {
+ ++i;
+ if (C.JSString_methods.codeUnitAt$1(host, i) !== 58)
+ error.call$2("invalid start colon.", i);
+ partStart = i;
+ }
+ if (i === partStart) {
+ if (wildcardSeen)
+ error.call$2("only one wildcard `::` is allowed", i);
+ C.JSArray_methods.add$1(parts, -1);
+ wildcardSeen = true;
+ } else
+ C.JSArray_methods.add$1(parts, parseHex.call$2(partStart, i));
+ partStart = i + 1;
+ } else if (char === 46)
+ seenDot = true;
+ }
+ if (parts.length === 0)
+ error.call$1("too few parts");
+ atEnd = partStart === end;
+ t1 = C.JSArray_methods.get$last(parts);
+ if (atEnd && t1 !== -1)
+ error.call$2("expected a part after last `:`", end);
+ if (!atEnd)
+ if (!seenDot)
+ C.JSArray_methods.add$1(parts, parseHex.call$2(partStart, end));
+ else {
+ last = P.Uri__parseIPv4Address(host, partStart, end);
+ C.JSArray_methods.add$1(parts, (last[0] << 8 | last[1]) >>> 0);
+ C.JSArray_methods.add$1(parts, (last[2] << 8 | last[3]) >>> 0);
+ }
+ if (wildcardSeen) {
+ if (parts.length > 7)
+ error.call$1("an address with a wildcard must have less than 7 parts");
+ } else if (parts.length !== 8)
+ error.call$1("an address without a wildcard must contain exactly 8 parts");
+ bytes = new Uint8Array(16);
+ for (t1 = parts.length, t2 = bytes.length, wildCardLength = 9 - t1, i = 0, index = 0; i < t1; ++i) {
+ value = parts[i];
+ if (value === -1)
+ for (j = 0; j < wildCardLength; ++j) {
+ if (index < 0 || index >= t2)
+ return H.ioore(bytes, index);
+ bytes[index] = 0;
+ t3 = index + 1;
+ if (t3 >= t2)
+ return H.ioore(bytes, t3);
+ bytes[t3] = 0;
+ index += 2;
+ }
+ else {
+ t3 = C.JSInt_methods._shrOtherPositive$1(value, 8);
+ if (index < 0 || index >= t2)
+ return H.ioore(bytes, index);
+ bytes[index] = t3;
+ t3 = index + 1;
+ if (t3 >= t2)
+ return H.ioore(bytes, t3);
+ bytes[t3] = value & 255;
+ index += 2;
+ }
+ }
+ return bytes;
+ },
+ _Uri__Uri$notSimple: function(uri, start, end, schemeEnd, hostStart, portStart, pathStart, queryStart, fragmentStart, scheme) {
+ var userInfoStart, userInfo, host, t1, port, path, query, _null = null;
+ if (scheme == null)
+ if (schemeEnd > start)
+ scheme = P._Uri__makeScheme(uri, start, schemeEnd);
+ else {
+ if (schemeEnd === start)
+ P._Uri__fail(uri, start, "Invalid empty scheme");
+ scheme = "";
+ }
+ if (hostStart > start) {
+ userInfoStart = schemeEnd + 3;
+ userInfo = userInfoStart < hostStart ? P._Uri__makeUserInfo(uri, userInfoStart, hostStart - 1) : "";
+ host = P._Uri__makeHost(uri, hostStart, portStart, false);
+ t1 = portStart + 1;
+ port = t1 < pathStart ? P._Uri__makePort(P.int_parse(J.substring$2$s(uri, t1, pathStart), new P._Uri__Uri$notSimple_closure(uri, portStart), _null), scheme) : _null;
+ } else {
+ port = _null;
+ host = port;
+ userInfo = "";
+ }
+ path = P._Uri__makePath(uri, pathStart, queryStart, _null, scheme, host != null);
+ query = queryStart < fragmentStart ? P._Uri__makeQuery(uri, queryStart + 1, fragmentStart, _null) : _null;
+ return new P._Uri(scheme, userInfo, host, port, path, query, fragmentStart < end ? P._Uri__makeFragment(uri, fragmentStart + 1, end) : _null);
+ },
+ _Uri__Uri: function(host, path, pathSegments, scheme) {
+ var userInfo, query, fragment, port, isFile, t1, hasAuthority, t2, _null = null;
+ scheme = P._Uri__makeScheme(scheme, 0, scheme == null ? 0 : scheme.length);
+ userInfo = P._Uri__makeUserInfo(_null, 0, 0);
+ host = P._Uri__makeHost(host, 0, host == null ? 0 : host.length, false);
+ query = P._Uri__makeQuery(_null, 0, 0, _null);
+ fragment = P._Uri__makeFragment(_null, 0, 0);
+ port = P._Uri__makePort(_null, scheme);
+ isFile = scheme === "file";
+ if (host == null)
+ t1 = userInfo.length !== 0 || port != null || isFile;
+ else
+ t1 = false;
+ if (t1)
+ host = "";
+ t1 = host == null;
+ hasAuthority = !t1;
+ path = P._Uri__makePath(path, 0, path == null ? 0 : path.length, pathSegments, scheme, hasAuthority);
+ t2 = scheme.length === 0;
+ if (t2 && t1 && !C.JSString_methods.startsWith$1(path, "/"))
+ path = P._Uri__normalizeRelativePath(path, !t2 || hasAuthority);
+ else
+ path = P._Uri__removeDotSegments(path);
+ return new P._Uri(scheme, userInfo, t1 && C.JSString_methods.startsWith$1(path, "//") ? "" : host, port, path, query, fragment);
+ },
+ _Uri__defaultPort: function(scheme) {
+ if (scheme === "http")
+ return 80;
+ if (scheme === "https")
+ return 443;
+ return 0;
+ },
+ _Uri__fail: function(uri, index, message) {
+ throw H.wrapException(P.FormatException$(message, uri, index));
+ },
+ _Uri__Uri$file: function(path, windows) {
+ return windows ? P._Uri__makeWindowsFileUrl(path, false) : P._Uri__makeFileUri(path, false);
+ },
+ _Uri__checkNonWindowsPathReservedCharacters: function(segments, argumentError) {
+ C.JSArray_methods.forEach$1(segments, new P._Uri__checkNonWindowsPathReservedCharacters_closure(false));
+ },
+ _Uri__checkWindowsPathReservedCharacters: function(segments, argumentError, firstSegment) {
+ var t1, t2;
+ for (t1 = H.SubListIterable$(segments, firstSegment, null, H._arrayInstanceType(segments)._precomputed1), t1 = new H.ListIterator(t1, t1.get$length(t1), t1.$ti._eval$1("ListIterator<ListIterable.E>")); t1.moveNext$0();) {
+ t2 = t1.__internal$_current;
+ if (J.contains$1$asx(t2, P.RegExp_RegExp('["*/:<>?\\\\|]', false)))
+ if (argumentError)
+ throw H.wrapException(P.ArgumentError$("Illegal character in path"));
+ else
+ throw H.wrapException(P.UnsupportedError$("Illegal character in path: " + t2));
+ }
+ },
+ _Uri__checkWindowsDriveLetter: function(charCode, argumentError) {
+ var t1,
+ _s21_ = "Illegal drive letter ";
+ if (!(65 <= charCode && charCode <= 90))
+ t1 = 97 <= charCode && charCode <= 122;
+ else
+ t1 = true;
+ if (t1)
+ return;
+ if (argumentError)
+ throw H.wrapException(P.ArgumentError$(_s21_ + P.String_String$fromCharCode(charCode)));
+ else
+ throw H.wrapException(P.UnsupportedError$(_s21_ + P.String_String$fromCharCode(charCode)));
+ },
+ _Uri__makeFileUri: function(path, slashTerminated) {
+ var _null = null,
+ segments = H.setRuntimeTypeInfo(path.split("/"), type$.JSArray_String);
+ if (C.JSString_methods.startsWith$1(path, "/"))
+ return P._Uri__Uri(_null, _null, segments, "file");
+ else
+ return P._Uri__Uri(_null, _null, segments, _null);
+ },
+ _Uri__makeWindowsFileUrl: function(path, slashTerminated) {
+ var t1, pathSegments, pathStart, hostPart, _s1_ = "\\", _null = null, _s4_ = "file";
+ if (C.JSString_methods.startsWith$1(path, "\\\\?\\"))
+ if (C.JSString_methods.startsWith$2(path, "UNC\\", 4))
+ path = C.JSString_methods.replaceRange$3(path, 0, 7, _s1_);
+ else {
+ path = C.JSString_methods.substring$1(path, 4);
+ if (path.length < 3 || C.JSString_methods._codeUnitAt$1(path, 1) !== 58 || C.JSString_methods._codeUnitAt$1(path, 2) !== 92)
+ throw H.wrapException(P.ArgumentError$("Windows paths with \\\\?\\ prefix must be absolute"));
+ }
+ else
+ path = H.stringReplaceAllUnchecked(path, "/", _s1_);
+ t1 = path.length;
+ if (t1 > 1 && C.JSString_methods._codeUnitAt$1(path, 1) === 58) {
+ P._Uri__checkWindowsDriveLetter(C.JSString_methods._codeUnitAt$1(path, 0), true);
+ if (t1 === 2 || C.JSString_methods._codeUnitAt$1(path, 2) !== 92)
+ throw H.wrapException(P.ArgumentError$("Windows paths with drive letter must be absolute"));
+ pathSegments = H.setRuntimeTypeInfo(path.split(_s1_), type$.JSArray_String);
+ P._Uri__checkWindowsPathReservedCharacters(pathSegments, true, 1);
+ return P._Uri__Uri(_null, _null, pathSegments, _s4_);
+ }
+ if (C.JSString_methods.startsWith$1(path, _s1_))
+ if (C.JSString_methods.startsWith$2(path, _s1_, 1)) {
+ pathStart = C.JSString_methods.indexOf$2(path, _s1_, 2);
+ t1 = pathStart < 0;
+ hostPart = t1 ? C.JSString_methods.substring$1(path, 2) : C.JSString_methods.substring$2(path, 2, pathStart);
+ pathSegments = H.setRuntimeTypeInfo((t1 ? "" : C.JSString_methods.substring$1(path, pathStart + 1)).split(_s1_), type$.JSArray_String);
+ P._Uri__checkWindowsPathReservedCharacters(pathSegments, true, 0);
+ return P._Uri__Uri(hostPart, _null, pathSegments, _s4_);
+ } else {
+ pathSegments = H.setRuntimeTypeInfo(path.split(_s1_), type$.JSArray_String);
+ P._Uri__checkWindowsPathReservedCharacters(pathSegments, true, 0);
+ return P._Uri__Uri(_null, _null, pathSegments, _s4_);
+ }
+ else {
+ pathSegments = H.setRuntimeTypeInfo(path.split(_s1_), type$.JSArray_String);
+ P._Uri__checkWindowsPathReservedCharacters(pathSegments, true, 0);
+ return P._Uri__Uri(_null, _null, pathSegments, _null);
+ }
+ },
+ _Uri__makePort: function(port, scheme) {
+ if (port != null && port === P._Uri__defaultPort(scheme))
+ return null;
+ return port;
+ },
+ _Uri__makeHost: function(host, start, end, strictIPv6) {
+ var t1, t2, index, zoneIDstart, zoneID, i;
+ if (host == null)
+ return null;
+ if (start === end)
+ return "";
+ if (C.JSString_methods.codeUnitAt$1(host, start) === 91) {
+ t1 = end - 1;
+ if (C.JSString_methods.codeUnitAt$1(host, t1) !== 93)
+ P._Uri__fail(host, start, "Missing end `]` to match `[` in host");
+ t2 = start + 1;
+ index = P._Uri__checkZoneID(host, t2, t1);
+ if (index < t1) {
+ zoneIDstart = index + 1;
+ zoneID = P._Uri__normalizeZoneID(host, C.JSString_methods.startsWith$2(host, "25", zoneIDstart) ? index + 3 : zoneIDstart, t1, "%25");
+ } else
+ zoneID = "";
+ P.Uri_parseIPv6Address(host, t2, index);
+ return C.JSString_methods.substring$2(host, start, index).toLowerCase() + zoneID + "]";
+ }
+ for (i = start; i < end; ++i)
+ if (C.JSString_methods.codeUnitAt$1(host, i) === 58) {
+ index = C.JSString_methods.indexOf$2(host, "%", start);
+ index = index >= start && index < end ? index : end;
+ if (index < end) {
+ zoneIDstart = index + 1;
+ zoneID = P._Uri__normalizeZoneID(host, C.JSString_methods.startsWith$2(host, "25", zoneIDstart) ? index + 3 : zoneIDstart, end, "%25");
+ } else
+ zoneID = "";
+ P.Uri_parseIPv6Address(host, start, index);
+ return "[" + C.JSString_methods.substring$2(host, start, index) + zoneID + "]";
+ }
+ return P._Uri__normalizeRegName(host, start, end);
+ },
+ _Uri__checkZoneID: function(host, start, end) {
+ var index = C.JSString_methods.indexOf$2(host, "%", start);
+ return index >= start && index < end ? index : end;
+ },
+ _Uri__normalizeZoneID: function(host, start, end, prefix) {
+ var index, sectionStart, isNormalized, char, replacement, t1, t2, tail, sourceLength,
+ buffer = prefix !== "" ? new P.StringBuffer(prefix) : null;
+ for (index = start, sectionStart = index, isNormalized = true; index < end;) {
+ char = C.JSString_methods.codeUnitAt$1(host, index);
+ if (char === 37) {
+ replacement = P._Uri__normalizeEscape(host, index, true);
+ t1 = replacement == null;
+ if (t1 && isNormalized) {
+ index += 3;
+ continue;
+ }
+ if (buffer == null)
+ buffer = new P.StringBuffer("");
+ t2 = buffer._contents += C.JSString_methods.substring$2(host, sectionStart, index);
+ if (t1)
+ replacement = C.JSString_methods.substring$2(host, index, index + 3);
+ else if (replacement === "%")
+ P._Uri__fail(host, index, "ZoneID should not contain % anymore");
+ buffer._contents = t2 + replacement;
+ index += 3;
+ sectionStart = index;
+ isNormalized = true;
+ } else {
+ if (char < 127) {
+ t1 = char >>> 4;
+ if (t1 >= 8)
+ return H.ioore(C.List_nxB, t1);
+ t1 = (C.List_nxB[t1] & 1 << (char & 15)) !== 0;
+ } else
+ t1 = false;
+ if (t1) {
+ if (isNormalized && 65 <= char && 90 >= char) {
+ if (buffer == null)
+ buffer = new P.StringBuffer("");
+ if (sectionStart < index) {
+ buffer._contents += C.JSString_methods.substring$2(host, sectionStart, index);
+ sectionStart = index;
+ }
+ isNormalized = false;
+ }
+ ++index;
+ } else {
+ if ((char & 64512) === 55296 && index + 1 < end) {
+ tail = C.JSString_methods.codeUnitAt$1(host, index + 1);
+ if ((tail & 64512) === 56320) {
+ char = 65536 | (char & 1023) << 10 | tail & 1023;
+ sourceLength = 2;
+ } else
+ sourceLength = 1;
+ } else
+ sourceLength = 1;
+ if (buffer == null)
+ buffer = new P.StringBuffer("");
+ buffer._contents += C.JSString_methods.substring$2(host, sectionStart, index);
+ buffer._contents += P._Uri__escapeChar(char);
+ index += sourceLength;
+ sectionStart = index;
+ }
+ }
+ }
+ if (buffer == null)
+ return C.JSString_methods.substring$2(host, start, end);
+ if (sectionStart < end)
+ buffer._contents += C.JSString_methods.substring$2(host, sectionStart, end);
+ t1 = buffer._contents;
+ return t1.charCodeAt(0) == 0 ? t1 : t1;
+ },
+ _Uri__normalizeRegName: function(host, start, end) {
+ var index, sectionStart, buffer, isNormalized, char, replacement, t1, slice, t2, sourceLength, tail;
+ for (index = start, sectionStart = index, buffer = null, isNormalized = true; index < end;) {
+ char = C.JSString_methods.codeUnitAt$1(host, index);
+ if (char === 37) {
+ replacement = P._Uri__normalizeEscape(host, index, true);
+ t1 = replacement == null;
+ if (t1 && isNormalized) {
+ index += 3;
+ continue;
+ }
+ if (buffer == null)
+ buffer = new P.StringBuffer("");
+ slice = C.JSString_methods.substring$2(host, sectionStart, index);
+ t2 = buffer._contents += !isNormalized ? slice.toLowerCase() : slice;
+ if (t1) {
+ replacement = C.JSString_methods.substring$2(host, index, index + 3);
+ sourceLength = 3;
+ } else if (replacement === "%") {
+ replacement = "%25";
+ sourceLength = 1;
+ } else
+ sourceLength = 3;
+ buffer._contents = t2 + replacement;
+ index += sourceLength;
+ sectionStart = index;
+ isNormalized = true;
+ } else {
+ if (char < 127) {
+ t1 = char >>> 4;
+ if (t1 >= 8)
+ return H.ioore(C.List_qNA, t1);
+ t1 = (C.List_qNA[t1] & 1 << (char & 15)) !== 0;
+ } else
+ t1 = false;
+ if (t1) {
+ if (isNormalized && 65 <= char && 90 >= char) {
+ if (buffer == null)
+ buffer = new P.StringBuffer("");
+ if (sectionStart < index) {
+ buffer._contents += C.JSString_methods.substring$2(host, sectionStart, index);
+ sectionStart = index;
+ }
+ isNormalized = false;
+ }
+ ++index;
+ } else {
+ if (char <= 93) {
+ t1 = char >>> 4;
+ if (t1 >= 8)
+ return H.ioore(C.List_2Vk, t1);
+ t1 = (C.List_2Vk[t1] & 1 << (char & 15)) !== 0;
+ } else
+ t1 = false;
+ if (t1)
+ P._Uri__fail(host, index, "Invalid character");
+ else {
+ if ((char & 64512) === 55296 && index + 1 < end) {
+ tail = C.JSString_methods.codeUnitAt$1(host, index + 1);
+ if ((tail & 64512) === 56320) {
+ char = 65536 | (char & 1023) << 10 | tail & 1023;
+ sourceLength = 2;
+ } else
+ sourceLength = 1;
+ } else
+ sourceLength = 1;
+ if (buffer == null)
+ buffer = new P.StringBuffer("");
+ slice = C.JSString_methods.substring$2(host, sectionStart, index);
+ buffer._contents += !isNormalized ? slice.toLowerCase() : slice;
+ buffer._contents += P._Uri__escapeChar(char);
+ index += sourceLength;
+ sectionStart = index;
+ }
+ }
+ }
+ }
+ if (buffer == null)
+ return C.JSString_methods.substring$2(host, start, end);
+ if (sectionStart < end) {
+ slice = C.JSString_methods.substring$2(host, sectionStart, end);
+ buffer._contents += !isNormalized ? slice.toLowerCase() : slice;
+ }
+ t1 = buffer._contents;
+ return t1.charCodeAt(0) == 0 ? t1 : t1;
+ },
+ _Uri__makeScheme: function(scheme, start, end) {
+ var i, containsUpperCase, codeUnit, t1;
+ if (start === end)
+ return "";
+ if (!P._Uri__isAlphabeticCharacter(J.getInterceptor$s(scheme)._codeUnitAt$1(scheme, start)))
+ P._Uri__fail(scheme, start, "Scheme not starting with alphabetic character");
+ for (i = start, containsUpperCase = false; i < end; ++i) {
+ codeUnit = C.JSString_methods._codeUnitAt$1(scheme, i);
+ if (codeUnit < 128) {
+ t1 = codeUnit >>> 4;
+ if (t1 >= 8)
+ return H.ioore(C.List_JYB, t1);
+ t1 = (C.List_JYB[t1] & 1 << (codeUnit & 15)) !== 0;
+ } else
+ t1 = false;
+ if (!t1)
+ P._Uri__fail(scheme, i, "Illegal scheme character");
+ if (65 <= codeUnit && codeUnit <= 90)
+ containsUpperCase = true;
+ }
+ scheme = C.JSString_methods.substring$2(scheme, start, end);
+ return P._Uri__canonicalizeScheme(containsUpperCase ? scheme.toLowerCase() : scheme);
+ },
+ _Uri__canonicalizeScheme: function(scheme) {
+ if (scheme === "http")
+ return "http";
+ if (scheme === "file")
+ return "file";
+ if (scheme === "https")
+ return "https";
+ if (scheme === "package")
+ return "package";
+ return scheme;
+ },
+ _Uri__makeUserInfo: function(userInfo, start, end) {
+ if (userInfo == null)
+ return "";
+ return P._Uri__normalizeOrSubstring(userInfo, start, end, C.List_gRj, false);
+ },
+ _Uri__makePath: function(path, start, end, pathSegments, scheme, hasAuthority) {
+ var result,
+ isFile = scheme === "file",
+ ensureLeadingSlash = isFile || hasAuthority,
+ t1 = path == null;
+ if (t1 && pathSegments == null)
+ return isFile ? "/" : "";
+ t1 = !t1;
+ if (t1 && pathSegments != null)
+ throw H.wrapException(P.ArgumentError$("Both path and pathSegments specified"));
+ if (t1)
+ result = P._Uri__normalizeOrSubstring(path, start, end, C.List_qg4, true);
+ else {
+ pathSegments.toString;
+ t1 = H._arrayInstanceType(pathSegments);
+ result = new H.MappedListIterable(pathSegments, t1._eval$1("String(1)")._check(new P._Uri__makePath_closure()), t1._eval$1("MappedListIterable<1,String>")).join$1(0, "/");
+ }
+ if (result.length === 0) {
+ if (isFile)
+ return "/";
+ } else if (ensureLeadingSlash && !C.JSString_methods.startsWith$1(result, "/"))
+ result = "/" + result;
+ return P._Uri__normalizePath(result, scheme, hasAuthority);
+ },
+ _Uri__normalizePath: function(path, scheme, hasAuthority) {
+ var t1 = scheme.length === 0;
+ if (t1 && !hasAuthority && !C.JSString_methods.startsWith$1(path, "/"))
+ return P._Uri__normalizeRelativePath(path, !t1 || hasAuthority);
+ return P._Uri__removeDotSegments(path);
+ },
+ _Uri__makeQuery: function(query, start, end, queryParameters) {
+ if (query != null)
+ return P._Uri__normalizeOrSubstring(query, start, end, C.List_CVk, true);
+ return null;
+ },
+ _Uri__makeFragment: function(fragment, start, end) {
+ if (fragment == null)
+ return null;
+ return P._Uri__normalizeOrSubstring(fragment, start, end, C.List_CVk, true);
+ },
+ _Uri__normalizeEscape: function(source, index, lowerCase) {
+ var t1, firstDigit, secondDigit, firstDigitValue, secondDigitValue, value;
+ H.assertHelper(C.JSString_methods.codeUnitAt$1(source, index) === 37);
+ t1 = index + 2;
+ if (t1 >= source.length)
+ return "%";
+ firstDigit = C.JSString_methods.codeUnitAt$1(source, index + 1);
+ secondDigit = C.JSString_methods.codeUnitAt$1(source, t1);
+ firstDigitValue = H.hexDigitValue(firstDigit);
+ secondDigitValue = H.hexDigitValue(secondDigit);
+ if (firstDigitValue < 0 || secondDigitValue < 0)
+ return "%";
+ value = firstDigitValue * 16 + secondDigitValue;
+ if (value < 127) {
+ t1 = C.JSInt_methods._shrOtherPositive$1(value, 4);
+ if (t1 >= 8)
+ return H.ioore(C.List_nxB, t1);
+ t1 = (C.List_nxB[t1] & 1 << (value & 15)) !== 0;
+ } else
+ t1 = false;
+ if (t1)
+ return H.Primitives_stringFromCharCode(lowerCase && 65 <= value && 90 >= value ? (value | 32) >>> 0 : value);
+ if (firstDigit >= 97 || secondDigit >= 97)
+ return C.JSString_methods.substring$2(source, index, index + 3).toUpperCase();
+ return null;
+ },
+ _Uri__escapeChar: function(char) {
+ var t1, codeUnits, flag, encodedBytes, index, byte,
+ _s16_ = "0123456789ABCDEF";
+ H.assertHelper(char <= 1114111);
+ if (char < 128) {
+ t1 = new Array(3);
+ t1.fixed$length = Array;
+ codeUnits = H.setRuntimeTypeInfo(t1, type$.JSArray_int);
+ C.JSArray_methods.$indexSet(codeUnits, 0, 37);
+ C.JSArray_methods.$indexSet(codeUnits, 1, C.JSString_methods._codeUnitAt$1(_s16_, char >>> 4));
+ C.JSArray_methods.$indexSet(codeUnits, 2, C.JSString_methods._codeUnitAt$1(_s16_, char & 15));
+ } else {
+ if (char > 2047)
+ if (char > 65535) {
+ flag = 240;
+ encodedBytes = 4;
+ } else {
+ flag = 224;
+ encodedBytes = 3;
+ }
+ else {
+ flag = 192;
+ encodedBytes = 2;
+ }
+ t1 = new Array(3 * encodedBytes);
+ t1.fixed$length = Array;
+ codeUnits = H.setRuntimeTypeInfo(t1, type$.JSArray_int);
+ for (index = 0; --encodedBytes, encodedBytes >= 0; flag = 128) {
+ byte = C.JSInt_methods._shrReceiverPositive$1(char, 6 * encodedBytes) & 63 | flag;
+ C.JSArray_methods.$indexSet(codeUnits, index, 37);
+ C.JSArray_methods.$indexSet(codeUnits, index + 1, C.JSString_methods._codeUnitAt$1(_s16_, byte >>> 4));
+ C.JSArray_methods.$indexSet(codeUnits, index + 2, C.JSString_methods._codeUnitAt$1(_s16_, byte & 15));
+ index += 3;
+ }
+ }
+ return P.String_String$fromCharCodes(codeUnits, 0, null);
+ },
+ _Uri__normalizeOrSubstring: function(component, start, end, charTable, escapeDelimiters) {
+ var t1 = P._Uri__normalize(component, start, end, charTable, escapeDelimiters);
+ return t1 == null ? C.JSString_methods.substring$2(component, start, end) : t1;
+ },
+ _Uri__normalize: function(component, start, end, charTable, escapeDelimiters) {
+ var t1, index, sectionStart, buffer, char, t2, replacement, sourceLength, tail, _null = null;
+ for (t1 = !escapeDelimiters, index = start, sectionStart = index, buffer = _null; index < end;) {
+ char = C.JSString_methods.codeUnitAt$1(component, index);
+ if (char < 127) {
+ t2 = char >>> 4;
+ if (t2 >= 8)
+ return H.ioore(charTable, t2);
+ t2 = (charTable[t2] & 1 << (char & 15)) !== 0;
+ } else
+ t2 = false;
+ if (t2)
+ ++index;
+ else {
+ if (char === 37) {
+ replacement = P._Uri__normalizeEscape(component, index, false);
+ if (replacement == null) {
+ index += 3;
+ continue;
+ }
+ if ("%" === replacement) {
+ replacement = "%25";
+ sourceLength = 1;
+ } else
+ sourceLength = 3;
+ } else {
+ if (t1)
+ if (char <= 93) {
+ t2 = char >>> 4;
+ if (t2 >= 8)
+ return H.ioore(C.List_2Vk, t2);
+ t2 = (C.List_2Vk[t2] & 1 << (char & 15)) !== 0;
+ } else
+ t2 = false;
+ else
+ t2 = false;
+ if (t2) {
+ P._Uri__fail(component, index, "Invalid character");
+ sourceLength = _null;
+ replacement = sourceLength;
+ } else {
+ if ((char & 64512) === 55296) {
+ t2 = index + 1;
+ if (t2 < end) {
+ tail = C.JSString_methods.codeUnitAt$1(component, t2);
+ if ((tail & 64512) === 56320) {
+ char = 65536 | (char & 1023) << 10 | tail & 1023;
+ sourceLength = 2;
+ } else
+ sourceLength = 1;
+ } else
+ sourceLength = 1;
+ } else
+ sourceLength = 1;
+ replacement = P._Uri__escapeChar(char);
+ }
+ }
+ if (buffer == null)
+ buffer = new P.StringBuffer("");
+ buffer._contents += C.JSString_methods.substring$2(component, sectionStart, index);
+ buffer._contents += H.S(replacement);
+ if (typeof sourceLength !== "number")
+ return H.iae(sourceLength);
+ index += sourceLength;
+ sectionStart = index;
+ }
+ }
+ if (buffer == null)
+ return _null;
+ if (sectionStart < end)
+ buffer._contents += C.JSString_methods.substring$2(component, sectionStart, end);
+ t1 = buffer._contents;
+ return t1.charCodeAt(0) == 0 ? t1 : t1;
+ },
+ _Uri__mayContainDotSegments: function(path) {
+ if (C.JSString_methods.startsWith$1(path, "."))
+ return true;
+ return C.JSString_methods.indexOf$1(path, "/.") !== -1;
+ },
+ _Uri__removeDotSegments: function(path) {
+ var output, t1, t2, appendSlash, _i, segment, t3;
+ if (!P._Uri__mayContainDotSegments(path))
+ return path;
+ H.assertHelper(path.length !== 0);
+ output = H.setRuntimeTypeInfo([], type$.JSArray_String);
+ for (t1 = path.split("/"), t2 = t1.length, appendSlash = false, _i = 0; _i < t2; ++_i) {
+ segment = t1[_i];
+ if (J.$eq$(segment, "..")) {
+ t3 = output.length;
+ if (t3 !== 0) {
+ if (0 >= t3)
+ return H.ioore(output, -1);
+ output.pop();
+ if (output.length === 0)
+ C.JSArray_methods.add$1(output, "");
+ }
+ appendSlash = true;
+ } else if ("." === segment)
+ appendSlash = true;
+ else {
+ C.JSArray_methods.add$1(output, segment);
+ appendSlash = false;
+ }
+ }
+ if (appendSlash)
+ C.JSArray_methods.add$1(output, "");
+ return C.JSArray_methods.join$1(output, "/");
+ },
+ _Uri__normalizeRelativePath: function(path, allowScheme) {
+ var output, t1, t2, appendSlash, _i, segment;
+ H.assertHelper(!C.JSString_methods.startsWith$1(path, "/"));
+ if (!P._Uri__mayContainDotSegments(path))
+ return !allowScheme ? P._Uri__escapeScheme(path) : path;
+ H.assertHelper(path.length !== 0);
+ output = H.setRuntimeTypeInfo([], type$.JSArray_String);
+ for (t1 = path.split("/"), t2 = t1.length, appendSlash = false, _i = 0; _i < t2; ++_i) {
+ segment = t1[_i];
+ if (".." === segment)
+ if (output.length !== 0 && C.JSArray_methods.get$last(output) !== "..") {
+ if (0 >= output.length)
+ return H.ioore(output, -1);
+ output.pop();
+ appendSlash = true;
+ } else {
+ C.JSArray_methods.add$1(output, "..");
+ appendSlash = false;
+ }
+ else if ("." === segment)
+ appendSlash = true;
+ else {
+ C.JSArray_methods.add$1(output, segment);
+ appendSlash = false;
+ }
+ }
+ t1 = output.length;
+ if (t1 !== 0)
+ if (t1 === 1) {
+ if (0 >= t1)
+ return H.ioore(output, 0);
+ t1 = output[0].length === 0;
+ } else
+ t1 = false;
+ else
+ t1 = true;
+ if (t1)
+ return "./";
+ if (appendSlash || C.JSArray_methods.get$last(output) === "..")
+ C.JSArray_methods.add$1(output, "");
+ if (!allowScheme) {
+ if (0 >= output.length)
+ return H.ioore(output, 0);
+ C.JSArray_methods.$indexSet(output, 0, P._Uri__escapeScheme(output[0]));
+ }
+ return C.JSArray_methods.join$1(output, "/");
+ },
+ _Uri__escapeScheme: function(path) {
+ var i, char, t2,
+ t1 = path.length;
+ if (t1 >= 2 && P._Uri__isAlphabeticCharacter(J._codeUnitAt$1$s(path, 0)))
+ for (i = 1; i < t1; ++i) {
+ char = C.JSString_methods._codeUnitAt$1(path, i);
+ if (char === 58)
+ return C.JSString_methods.substring$2(path, 0, i) + "%3A" + C.JSString_methods.substring$1(path, i + 1);
+ if (char <= 127) {
+ t2 = char >>> 4;
+ if (t2 >= 8)
+ return H.ioore(C.List_JYB, t2);
+ t2 = (C.List_JYB[t2] & 1 << (char & 15)) === 0;
+ } else
+ t2 = true;
+ if (t2)
+ break;
+ }
+ return path;
+ },
+ _Uri__toWindowsFilePath: function(uri) {
+ var hasDriveLetter, t2, host,
+ segments = uri.get$pathSegments(),
+ t1 = segments.length;
+ if (t1 > 0 && J.get$length$asx(segments[0]) === 2 && J.codeUnitAt$1$s(segments[0], 1) === 58) {
+ if (0 >= t1)
+ return H.ioore(segments, 0);
+ P._Uri__checkWindowsDriveLetter(J.codeUnitAt$1$s(segments[0], 0), false);
+ P._Uri__checkWindowsPathReservedCharacters(segments, false, 1);
+ hasDriveLetter = true;
+ } else {
+ P._Uri__checkWindowsPathReservedCharacters(segments, false, 0);
+ hasDriveLetter = false;
+ }
+ t2 = uri.get$hasAbsolutePath() && !hasDriveLetter ? "\\" : "";
+ if (uri.get$hasAuthority()) {
+ host = uri.get$host(uri);
+ if (host.length !== 0)
+ t2 = t2 + "\\" + host + "\\";
+ }
+ t2 = P.StringBuffer__writeAll(t2, segments, "\\");
+ t1 = hasDriveLetter && t1 === 1 ? t2 + "\\" : t2;
+ return t1.charCodeAt(0) == 0 ? t1 : t1;
+ },
+ _Uri__hexCharPairToByte: function(s, pos) {
+ var byte, i, charCode;
+ for (byte = 0, i = 0; i < 2; ++i) {
+ charCode = C.JSString_methods._codeUnitAt$1(s, pos + i);
+ if (48 <= charCode && charCode <= 57)
+ byte = byte * 16 + charCode - 48;
+ else {
+ charCode |= 32;
+ if (97 <= charCode && charCode <= 102)
+ byte = byte * 16 + charCode - 87;
+ else
+ throw H.wrapException(P.ArgumentError$("Invalid URL encoding"));
+ }
+ }
+ return byte;
+ },
+ _Uri__uriDecode: function(text, start, end, encoding, plusToSpace) {
+ var t1, simple, t2, i, codeUnit, t3, bytes;
+ H.assertHelper(start <= end);
+ t1 = text.length;
+ H.assertHelper(end <= t1);
+ t2 = J.getInterceptor$s(text);
+ i = start;
+ while (true) {
+ if (!(i < end)) {
+ simple = true;
+ break;
+ }
+ codeUnit = t2._codeUnitAt$1(text, i);
+ if (codeUnit <= 127)
+ if (codeUnit !== 37)
+ t3 = false;
+ else
+ t3 = true;
+ else
+ t3 = true;
+ if (t3) {
+ simple = false;
+ break;
+ }
+ ++i;
+ }
+ if (simple) {
+ if (C.C_Utf8Codec !== encoding)
+ t1 = false;
+ else
+ t1 = true;
+ if (t1)
+ return t2.substring$2(text, start, end);
+ else
+ bytes = new H.CodeUnits(t2.substring$2(text, start, end));
+ } else {
+ bytes = H.setRuntimeTypeInfo([], type$.JSArray_int);
+ for (i = start; i < end; ++i) {
+ codeUnit = t2._codeUnitAt$1(text, i);
+ if (codeUnit > 127)
+ throw H.wrapException(P.ArgumentError$("Illegal percent encoding in URI"));
+ if (codeUnit === 37) {
+ if (i + 3 > t1)
+ throw H.wrapException(P.ArgumentError$("Truncated URI"));
+ C.JSArray_methods.add$1(bytes, P._Uri__hexCharPairToByte(text, i + 1));
+ i += 2;
+ } else
+ C.JSArray_methods.add$1(bytes, codeUnit);
+ }
+ }
+ type$.List_int._check(bytes);
+ return new P.Utf8Decoder(false).convert$1(bytes);
+ },
+ _Uri__isAlphabeticCharacter: function(codeUnit) {
+ var lowerCase = codeUnit | 32;
+ return 97 <= lowerCase && lowerCase <= 122;
+ },
+ UriData__writeUri: function(mimeType, charsetName, parameters, buffer, indices) {
+ var slashIndex, t1;
+ if (true)
+ buffer._contents = buffer._contents;
+ else {
+ slashIndex = P.UriData__validateMimeType("");
+ if (slashIndex < 0)
+ throw H.wrapException(P.ArgumentError$value("", "mimeType", "Invalid MIME type"));
+ t1 = buffer._contents += H.S(P._Uri__uriEncode(C.List_qFt, C.JSString_methods.substring$2("", 0, slashIndex), C.C_Utf8Codec, false));
+ buffer._contents = t1 + "/";
+ buffer._contents += H.S(P._Uri__uriEncode(C.List_qFt, C.JSString_methods.substring$1("", slashIndex + 1), C.C_Utf8Codec, false));
+ }
+ },
+ UriData__validateMimeType: function(mimeType) {
+ var t1, slashIndex, i;
+ for (t1 = mimeType.length, slashIndex = -1, i = 0; i < t1; ++i) {
+ if (C.JSString_methods._codeUnitAt$1(mimeType, i) !== 47)
+ continue;
+ if (slashIndex < 0) {
+ slashIndex = i;
+ continue;
+ }
+ return -1;
+ }
+ return slashIndex;
+ },
+ UriData__parse: function(text, start, sourceUri) {
+ var indices, t1, i, slashIndex, char, equalsIndex, lastSeparator, t2, data,
+ _s17_ = "Invalid MIME type";
+ H.assertHelper(start === 0 || start === 5);
+ H.assertHelper(start === 5 === C.JSString_methods.startsWith$1(text, "data:"));
+ indices = H.setRuntimeTypeInfo([start - 1], type$.JSArray_int);
+ for (t1 = text.length, i = start, slashIndex = -1, char = null; i < t1; ++i) {
+ char = C.JSString_methods._codeUnitAt$1(text, i);
+ if (char === 44 || char === 59)
+ break;
+ if (char === 47) {
+ if (slashIndex < 0) {
+ slashIndex = i;
+ continue;
+ }
+ throw H.wrapException(P.FormatException$(_s17_, text, i));
+ }
+ }
+ if (slashIndex < 0 && i > start)
+ throw H.wrapException(P.FormatException$(_s17_, text, i));
+ for (; char !== 44;) {
+ C.JSArray_methods.add$1(indices, i);
+ ++i;
+ for (equalsIndex = -1; i < t1; ++i) {
+ char = C.JSString_methods._codeUnitAt$1(text, i);
+ if (char === 61) {
+ if (equalsIndex < 0)
+ equalsIndex = i;
+ } else if (char === 59 || char === 44)
+ break;
+ }
+ if (equalsIndex >= 0)
+ C.JSArray_methods.add$1(indices, equalsIndex);
+ else {
+ lastSeparator = C.JSArray_methods.get$last(indices);
+ if (char !== 44 || i !== lastSeparator + 7 || !C.JSString_methods.startsWith$2(text, "base64", lastSeparator + 1))
+ throw H.wrapException(P.FormatException$("Expecting '='", text, i));
+ break;
+ }
+ }
+ C.JSArray_methods.add$1(indices, i);
+ t2 = i + 1;
+ if ((indices.length & 1) === 1)
+ text = C.C_Base64Codec.normalize$3(text, t2, t1);
+ else {
+ data = P._Uri__normalize(text, t2, t1, C.List_CVk, true);
+ if (data != null)
+ text = C.JSString_methods.replaceRange$3(text, t2, t1, data);
+ }
+ return new P.UriData(text, indices, sourceUri);
+ },
+ UriData__uriEncodeBytes: function(canonicalTable, bytes, buffer) {
+ var t1, byteOr, i, byte, t2, t3,
+ _s16_ = "0123456789ABCDEF";
+ for (t1 = J.getInterceptor$asx(bytes), byteOr = 0, i = 0; i < t1.get$length(bytes); ++i) {
+ byte = t1.$index(bytes, i);
+ if (typeof byte !== "number")
+ return H.iae(byte);
+ byteOr |= byte;
+ if (byte < 128) {
+ t2 = C.JSInt_methods._shrOtherPositive$1(byte, 4);
+ if (t2 >= 8)
+ return H.ioore(canonicalTable, t2);
+ t2 = (canonicalTable[t2] & 1 << (byte & 15)) !== 0;
+ } else
+ t2 = false;
+ t3 = buffer._contents;
+ if (t2)
+ buffer._contents = t3 + H.Primitives_stringFromCharCode(byte);
+ else {
+ t2 = t3 + H.Primitives_stringFromCharCode(37);
+ buffer._contents = t2;
+ t2 += H.Primitives_stringFromCharCode(C.JSString_methods._codeUnitAt$1(_s16_, C.JSInt_methods._shrOtherPositive$1(byte, 4)));
+ buffer._contents = t2;
+ buffer._contents = t2 + H.Primitives_stringFromCharCode(C.JSString_methods._codeUnitAt$1(_s16_, byte & 15));
+ }
+ }
+ if ((byteOr & 4294967040) >>> 0 !== 0)
+ for (i = 0; i < t1.get$length(bytes); ++i) {
+ byte = t1.$index(bytes, i);
+ if (typeof byte !== "number")
+ return byte.$lt();
+ if (byte < 0 || byte > 255)
+ throw H.wrapException(P.ArgumentError$value(byte, "non-byte value", null));
+ }
+ },
+ _createTables: function() {
+ var _s77_ = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-._~!$&'()*+,;=",
+ _s1_ = ".", _s1_0 = ":", _s1_1 = "/", _s1_2 = "?", _s1_3 = "#",
+ t1 = type$.Uint8List,
+ tables = P.List_List$generate(22, new P._createTables_closure(), true, t1),
+ t2 = new P._createTables_build(tables),
+ t3 = new P._createTables_setChars(),
+ t4 = new P._createTables_setRange(),
+ t5 = t1._check(t2.call$2(0, 225));
+ t3.call$3(t5, _s77_, 1);
+ t3.call$3(t5, _s1_, 14);
+ t3.call$3(t5, _s1_0, 34);
+ t3.call$3(t5, _s1_1, 3);
+ t3.call$3(t5, _s1_2, 172);
+ t3.call$3(t5, _s1_3, 205);
+ t5 = t1._check(t2.call$2(14, 225));
+ t3.call$3(t5, _s77_, 1);
+ t3.call$3(t5, _s1_, 15);
+ t3.call$3(t5, _s1_0, 34);
+ t3.call$3(t5, _s1_1, 234);
+ t3.call$3(t5, _s1_2, 172);
+ t3.call$3(t5, _s1_3, 205);
+ t5 = t1._check(t2.call$2(15, 225));
+ t3.call$3(t5, _s77_, 1);
+ t3.call$3(t5, "%", 225);
+ t3.call$3(t5, _s1_0, 34);
+ t3.call$3(t5, _s1_1, 9);
+ t3.call$3(t5, _s1_2, 172);
+ t3.call$3(t5, _s1_3, 205);
+ t5 = t1._check(t2.call$2(1, 225));
+ t3.call$3(t5, _s77_, 1);
+ t3.call$3(t5, _s1_0, 34);
+ t3.call$3(t5, _s1_1, 10);
+ t3.call$3(t5, _s1_2, 172);
+ t3.call$3(t5, _s1_3, 205);
+ t5 = t1._check(t2.call$2(2, 235));
+ t3.call$3(t5, _s77_, 139);
+ t3.call$3(t5, _s1_1, 131);
+ t3.call$3(t5, _s1_, 146);
+ t3.call$3(t5, _s1_2, 172);
+ t3.call$3(t5, _s1_3, 205);
+ t5 = t1._check(t2.call$2(3, 235));
+ t3.call$3(t5, _s77_, 11);
+ t3.call$3(t5, _s1_1, 68);
+ t3.call$3(t5, _s1_, 18);
+ t3.call$3(t5, _s1_2, 172);
+ t3.call$3(t5, _s1_3, 205);
+ t5 = t1._check(t2.call$2(4, 229));
+ t3.call$3(t5, _s77_, 5);
+ t4.call$3(t5, "AZ", 229);
+ t3.call$3(t5, _s1_0, 102);
+ t3.call$3(t5, "@", 68);
+ t3.call$3(t5, "[", 232);
+ t3.call$3(t5, _s1_1, 138);
+ t3.call$3(t5, _s1_2, 172);
+ t3.call$3(t5, _s1_3, 205);
+ t5 = t1._check(t2.call$2(5, 229));
+ t3.call$3(t5, _s77_, 5);
+ t4.call$3(t5, "AZ", 229);
+ t3.call$3(t5, _s1_0, 102);
+ t3.call$3(t5, "@", 68);
+ t3.call$3(t5, _s1_1, 138);
+ t3.call$3(t5, _s1_2, 172);
+ t3.call$3(t5, _s1_3, 205);
+ t5 = t1._check(t2.call$2(6, 231));
+ t4.call$3(t5, "19", 7);
+ t3.call$3(t5, "@", 68);
+ t3.call$3(t5, _s1_1, 138);
+ t3.call$3(t5, _s1_2, 172);
+ t3.call$3(t5, _s1_3, 205);
+ t5 = t1._check(t2.call$2(7, 231));
+ t4.call$3(t5, "09", 7);
+ t3.call$3(t5, "@", 68);
+ t3.call$3(t5, _s1_1, 138);
+ t3.call$3(t5, _s1_2, 172);
+ t3.call$3(t5, _s1_3, 205);
+ t3.call$3(t1._check(t2.call$2(8, 8)), "]", 5);
+ t5 = t1._check(t2.call$2(9, 235));
+ t3.call$3(t5, _s77_, 11);
+ t3.call$3(t5, _s1_, 16);
+ t3.call$3(t5, _s1_1, 234);
+ t3.call$3(t5, _s1_2, 172);
+ t3.call$3(t5, _s1_3, 205);
+ t5 = t1._check(t2.call$2(16, 235));
+ t3.call$3(t5, _s77_, 11);
+ t3.call$3(t5, _s1_, 17);
+ t3.call$3(t5, _s1_1, 234);
+ t3.call$3(t5, _s1_2, 172);
+ t3.call$3(t5, _s1_3, 205);
+ t5 = t1._check(t2.call$2(17, 235));
+ t3.call$3(t5, _s77_, 11);
+ t3.call$3(t5, _s1_1, 9);
+ t3.call$3(t5, _s1_2, 172);
+ t3.call$3(t5, _s1_3, 205);
+ t5 = t1._check(t2.call$2(10, 235));
+ t3.call$3(t5, _s77_, 11);
+ t3.call$3(t5, _s1_, 18);
+ t3.call$3(t5, _s1_1, 234);
+ t3.call$3(t5, _s1_2, 172);
+ t3.call$3(t5, _s1_3, 205);
+ t5 = t1._check(t2.call$2(18, 235));
+ t3.call$3(t5, _s77_, 11);
+ t3.call$3(t5, _s1_, 19);
+ t3.call$3(t5, _s1_1, 234);
+ t3.call$3(t5, _s1_2, 172);
+ t3.call$3(t5, _s1_3, 205);
+ t5 = t1._check(t2.call$2(19, 235));
+ t3.call$3(t5, _s77_, 11);
+ t3.call$3(t5, _s1_1, 234);
+ t3.call$3(t5, _s1_2, 172);
+ t3.call$3(t5, _s1_3, 205);
+ t5 = t1._check(t2.call$2(11, 235));
+ t3.call$3(t5, _s77_, 11);
+ t3.call$3(t5, _s1_1, 10);
+ t3.call$3(t5, _s1_2, 172);
+ t3.call$3(t5, _s1_3, 205);
+ t5 = t1._check(t2.call$2(12, 236));
+ t3.call$3(t5, _s77_, 12);
+ t3.call$3(t5, _s1_2, 12);
+ t3.call$3(t5, _s1_3, 205);
+ t5 = t1._check(t2.call$2(13, 237));
+ t3.call$3(t5, _s77_, 13);
+ t3.call$3(t5, _s1_2, 13);
+ t4.call$3(t1._check(t2.call$2(20, 245)), "az", 21);
+ t2 = t1._check(t2.call$2(21, 245));
+ t4.call$3(t2, "az", 21);
+ t4.call$3(t2, "09", 21);
+ t3.call$3(t2, "+-.", 21);
+ return tables;
+ },
+ _scan: function(uri, start, end, state, indices) {
+ var t1, i, table, char, transition,
+ tables = $.$get$_scannerTables();
+ H.assertHelper(end <= uri.length);
+ for (t1 = J.getInterceptor$s(uri), i = start; i < end; ++i) {
+ if (state < 0 || state >= tables.length)
+ return H.ioore(tables, state);
+ table = tables[state];
+ char = t1._codeUnitAt$1(uri, i) ^ 96;
+ if (char > 95)
+ char = 31;
+ if (char >= table.length)
+ return H.ioore(table, char);
+ transition = table[char];
+ state = transition & 31;
+ C.JSArray_methods.$indexSet(indices, transition >>> 5, i);
+ }
+ return state;
+ },
+ bool: function bool() {
+ },
+ DateTime: function DateTime(t0, t1) {
+ this._value = t0;
+ this.isUtc = t1;
+ },
+ double: function double() {
+ },
+ Duration: function Duration(t0) {
+ this._duration = t0;
+ },
+ Duration_toString_sixDigits: function Duration_toString_sixDigits() {
+ },
+ Duration_toString_twoDigits: function Duration_toString_twoDigits() {
+ },
+ Error: function Error() {
+ },
+ AssertionError: function AssertionError(t0) {
+ this.message = t0;
+ },
+ NullThrownError: function NullThrownError() {
+ },
+ ArgumentError: function ArgumentError(t0, t1, t2, t3) {
+ var _ = this;
+ _._hasValue = t0;
+ _.invalidValue = t1;
+ _.name = t2;
+ _.message = t3;
+ },
+ RangeError: function RangeError(t0, t1, t2, t3, t4, t5) {
+ var _ = this;
+ _.start = t0;
+ _.end = t1;
+ _._hasValue = t2;
+ _.invalidValue = t3;
+ _.name = t4;
+ _.message = t5;
+ },
+ IndexError: function IndexError(t0, t1, t2, t3, t4) {
+ var _ = this;
+ _.length = t0;
+ _._hasValue = t1;
+ _.invalidValue = t2;
+ _.name = t3;
+ _.message = t4;
+ },
+ UnsupportedError: function UnsupportedError(t0) {
+ this.message = t0;
+ },
+ UnimplementedError: function UnimplementedError(t0) {
+ this.message = t0;
+ },
+ StateError: function StateError(t0) {
+ this.message = t0;
+ },
+ ConcurrentModificationError: function ConcurrentModificationError(t0) {
+ this.modifiedObject = t0;
+ },
+ OutOfMemoryError: function OutOfMemoryError() {
+ },
+ StackOverflowError: function StackOverflowError() {
+ },
+ CyclicInitializationError: function CyclicInitializationError(t0) {
+ this.variableName = t0;
+ },
+ _Exception: function _Exception(t0) {
+ this.message = t0;
+ },
+ FormatException: function FormatException(t0, t1, t2) {
+ this.message = t0;
+ this.source = t1;
+ this.offset = t2;
+ },
+ Expando: function Expando(t0, t1, t2) {
+ this._jsWeakMapOrKey = t0;
+ this.name = t1;
+ this.$ti = t2;
+ },
+ Function: function Function() {
+ },
+ int: function int() {
+ },
+ Iterable: function Iterable() {
+ },
+ Iterator: function Iterator() {
+ },
+ List: function List() {
+ },
+ Map: function Map() {
+ },
+ MapEntry: function MapEntry(t0, t1, t2) {
+ this.key = t0;
+ this.value = t1;
+ this.$ti = t2;
+ },
+ Null: function Null() {
+ },
+ num: function num() {
+ },
+ Object: function Object() {
+ },
+ Pattern: function Pattern() {
+ },
+ Match: function Match() {
+ },
+ RegExpMatch: function RegExpMatch() {
+ },
+ Set: function Set() {
+ },
+ StackTrace: function StackTrace() {
+ },
+ _StringStackTrace: function _StringStackTrace(t0) {
+ this._stackTrace = t0;
+ },
+ Stopwatch: function Stopwatch() {
+ this._stop = this._core$_start = 0;
+ },
+ String: function String() {
+ },
+ Runes: function Runes(t0) {
+ this.string = t0;
+ },
+ RuneIterator: function RuneIterator(t0) {
+ var _ = this;
+ _.string = t0;
+ _._nextPosition = _._core$_position = 0;
+ _._currentCodePoint = null;
+ },
+ StringBuffer: function StringBuffer(t0) {
+ this._contents = t0;
+ },
+ Uri: function Uri() {
+ },
+ Uri__parseIPv4Address_error: function Uri__parseIPv4Address_error(t0) {
+ this.host = t0;
+ },
+ Uri_parseIPv6Address_error: function Uri_parseIPv6Address_error(t0) {
+ this.host = t0;
+ },
+ Uri_parseIPv6Address_parseHex: function Uri_parseIPv6Address_parseHex(t0, t1) {
+ this.error = t0;
+ this.host = t1;
+ },
+ _Uri: function _Uri(t0, t1, t2, t3, t4, t5, t6) {
+ var _ = this;
+ _.scheme = t0;
+ _._userInfo = t1;
+ _._host = t2;
+ _._port = t3;
+ _.path = t4;
+ _._query = t5;
+ _._fragment = t6;
+ _._hashCodeCache = _._text = _._pathSegments = null;
+ },
+ _Uri__Uri$notSimple_closure: function _Uri__Uri$notSimple_closure(t0, t1) {
+ this.uri = t0;
+ this.portStart = t1;
+ },
+ _Uri__checkNonWindowsPathReservedCharacters_closure: function _Uri__checkNonWindowsPathReservedCharacters_closure(t0) {
+ this.argumentError = t0;
+ },
+ _Uri__makePath_closure: function _Uri__makePath_closure() {
+ },
+ UriData: function UriData(t0, t1, t2) {
+ this._text = t0;
+ this._separatorIndices = t1;
+ this._uriCache = t2;
+ },
+ _createTables_closure: function _createTables_closure() {
+ },
+ _createTables_build: function _createTables_build(t0) {
+ this.tables = t0;
+ },
+ _createTables_setChars: function _createTables_setChars() {
+ },
+ _createTables_setRange: function _createTables_setRange() {
+ },
+ _SimpleUri: function _SimpleUri(t0, t1, t2, t3, t4, t5, t6, t7) {
+ var _ = this;
+ _._uri = t0;
+ _._schemeEnd = t1;
+ _._hostStart = t2;
+ _._portStart = t3;
+ _._pathStart = t4;
+ _._queryStart = t5;
+ _._fragmentStart = t6;
+ _._schemeCache = t7;
+ _._hashCodeCache = null;
+ },
+ _DataUri: function _DataUri(t0, t1, t2, t3, t4, t5, t6) {
+ var _ = this;
+ _.scheme = t0;
+ _._userInfo = t1;
+ _._host = t2;
+ _._port = t3;
+ _.path = t4;
+ _._query = t5;
+ _._fragment = t6;
+ _._hashCodeCache = _._text = _._pathSegments = null;
+ },
+ _StructuredClone: function _StructuredClone() {
+ },
+ _StructuredClone_walk_closure: function _StructuredClone_walk_closure(t0, t1) {
+ this._box_0 = t0;
+ this.$this = t1;
+ },
+ _StructuredClone_walk_closure0: function _StructuredClone_walk_closure0(t0, t1) {
+ this._box_0 = t0;
+ this.$this = t1;
+ },
+ _AcceptStructuredClone: function _AcceptStructuredClone() {
+ },
+ _AcceptStructuredClone_walk_closure: function _AcceptStructuredClone_walk_closure(t0, t1) {
+ this._box_0 = t0;
+ this.$this = t1;
+ },
+ _StructuredCloneDart2Js: function _StructuredCloneDart2Js(t0, t1) {
+ this.values = t0;
+ this.copies = t1;
+ },
+ _AcceptStructuredCloneDart2Js: function _AcceptStructuredCloneDart2Js(t0, t1) {
+ this.values = t0;
+ this.copies = t1;
+ this.mustCopy = false;
+ },
+ _convertDataTree: function(data) {
+ return new P._convertDataTree__convert(new P._IdentityHashMap(type$._IdentityHashMap_dynamic_dynamic)).call$1(data);
+ },
+ promiseToFuture: function(jsPromise, $T) {
+ var t1 = new P._Future($.Zone__current, $T._eval$1("_Future<0>")),
+ completer = new P._AsyncCompleter(t1, $T._eval$1("_AsyncCompleter<0>"));
+ jsPromise.then(H.convertDartClosureToJS(new P.promiseToFuture_closure(completer, $T), 1), H.convertDartClosureToJS(new P.promiseToFuture_closure0(completer), 1));
+ return t1;
+ },
+ _convertDataTree__convert: function _convertDataTree__convert(t0) {
+ this._convertedObjects = t0;
+ },
+ promiseToFuture_closure: function promiseToFuture_closure(t0, t1) {
+ this.completer = t0;
+ this.T = t1;
+ },
+ promiseToFuture_closure0: function promiseToFuture_closure0(t0) {
+ this.completer = t0;
+ },
+ ByteBuffer: function ByteBuffer() {
+ },
+ ByteData: function ByteData() {
+ },
+ Int8List: function Int8List() {
+ },
+ Uint8List: function Uint8List() {
+ },
+ Uint8ClampedList: function Uint8ClampedList() {
+ },
+ Int16List: function Int16List() {
+ },
+ Uint16List: function Uint16List() {
+ },
+ Int32List: function Int32List() {
+ },
+ Uint32List: function Uint32List() {
+ },
+ Float32List: function Float32List() {
+ },
+ Float64List: function Float64List() {
+ },
+ SqlError: function SqlError() {
+ },
+ max: function(a, b, $T) {
+ H.checkTypeBound($T, type$.num, "T", "max");
+ $T._check(a);
+ $T._check(b);
+ return Math.max(H.checkNum(a), H.checkNum(b));
+ },
+ pow: function(x, exponent) {
+ return Math.pow(x, exponent);
+ }
+ },
+ W = {
+ _EventStreamSubscription$: function(_target, _eventType, onData, _useCapture, $T) {
+ var t1 = onData == null ? null : W._wrapZone(new W._EventStreamSubscription_closure(onData), type$.Event);
+ t1 = new W._EventStreamSubscription(_target, _eventType, t1, false, $T._eval$1("_EventStreamSubscription<0>"));
+ t1._tryResume$0();
+ return t1;
+ },
+ _wrapZone: function(callback, $T) {
+ var t1 = $.Zone__current;
+ if (t1 === C.C__RootZone)
+ return callback;
+ return t1.bindUnaryCallbackGuarded$1$1(callback, $T);
+ },
+ ApplicationCacheErrorEvent: function ApplicationCacheErrorEvent() {
+ },
+ Blob: function Blob() {
+ },
+ DomError: function DomError() {
+ },
+ DomException: function DomException() {
+ },
+ ErrorEvent: function ErrorEvent() {
+ },
+ Event: function Event() {
+ },
+ EventTarget: function EventTarget() {
+ },
+ File: function File() {
+ },
+ Location: function Location() {
+ },
+ MediaError: function MediaError() {
+ },
+ MediaKeyMessageEvent: function MediaKeyMessageEvent() {
+ },
+ MessageEvent: function MessageEvent() {
+ },
+ MessagePort: function MessagePort() {
+ },
+ NavigatorUserMediaError: function NavigatorUserMediaError() {
+ },
+ OverconstrainedError: function OverconstrainedError() {
+ },
+ PositionError: function PositionError() {
+ },
+ PresentationConnectionCloseEvent: function PresentationConnectionCloseEvent() {
+ },
+ SpeechRecognitionError: function SpeechRecognitionError() {
+ },
+ EventStreamProvider: function EventStreamProvider(t0) {
+ this.$ti = t0;
+ },
+ _EventStream: function _EventStream(t0, t1, t2, t3) {
+ var _ = this;
+ _._html$_target = t0;
+ _._eventType = t1;
+ _._useCapture = t2;
+ _.$ti = t3;
+ },
+ _EventStreamSubscription: function _EventStreamSubscription(t0, t1, t2, t3, t4) {
+ var _ = this;
+ _._pauseCount = 0;
+ _._html$_target = t0;
+ _._eventType = t1;
+ _._html$_onData = t2;
+ _._useCapture = t3;
+ _.$ti = t4;
+ },
+ _EventStreamSubscription_closure: function _EventStreamSubscription_closure(t0) {
+ this.onData = t0;
+ }
+ },
+ S = {AsyncMemoizer: function AsyncMemoizer(t0, t1) {
+ this._async_memoizer$_completer = t0;
+ this.$ti = t1;
+ }, NullStreamSink: function NullStreamSink(t0, t1) {
+ var _ = this;
+ _.done = t0;
+ _._addingStream = _._null_stream_sink$_closed = false;
+ _.$ti = t1;
+ }, NullStreamSink_addStream_closure: function NullStreamSink_addStream_closure(t0) {
+ this.$this = t0;
+ }, Validator: function Validator(t0) {
+ this._isDefined = t0;
+ },
+ SpanScanner$: function(string) {
+ var t1, t2;
+ string.toString;
+ t1 = new H.CodeUnits(string);
+ t2 = H.setRuntimeTypeInfo([0], type$.JSArray_int);
+ t2 = new Y.SourceFile(null, t2, new Uint32Array(H._ensureNativeList(t1.toList$0(t1))));
+ t2.SourceFile$decoded$2$url(t1, null);
+ return new S.SpanScanner(t2, null, string);
+ },
+ SpanScanner: function SpanScanner(t0, t1, t2) {
+ var _ = this;
+ _._sourceFile = t0;
+ _._lastSpan = null;
+ _.sourceUrl = t1;
+ _.string = t2;
+ _._string_scanner$_position = 0;
+ _._lastMatchPosition = _._lastMatch = null;
+ },
+ _SpanScannerState: function _SpanScannerState(t0, t1) {
+ this._span_scanner$_scanner = t0;
+ this.position = t1;
+ },
+ RemoteListener_start: function(getMain, beforeLoad, hidePrints) {
+ var printZone, spec, t3, _null = null, t1 = {},
+ controller = B.StreamChannelController$(false, true, type$.Object),
+ t2 = type$.dynamic,
+ channel = D._MultiChannel$(controller._local, t2);
+ t1.verboseChain = true;
+ printZone = $.Zone__current;
+ spec = P._ZoneSpecification$(_null, _null, _null, _null, _null, new S.RemoteListener_start_closure(printZone, channel), _null, _null, _null, _null, _null, _null, _null);
+ P.Stream_Stream$fromIterable([], t2).listen$1(new S.RemoteListener_start_closure0()).cancel$0();
+ t3 = type$.String;
+ P.runZoned(type$.Null_Function._check(new S.RemoteListener_start_closure1(t1, getMain, channel, controller, beforeLoad, printZone, spec)), _null, _null, P.LinkedHashMap_LinkedHashMap$_literal([$.$get$_currentKey(), new N.SuiteChannelManager(P.LinkedHashMap_LinkedHashMap$_empty(t3, type$.StreamChannel_dynamic), P.LinkedHashMap_LinkedHashMap$_empty(t3, type$.StreamChannelCompleter_dynamic), P.LinkedHashSet_LinkedHashSet$_empty(t3))], t2, t2), type$.Null);
+ return controller._foreign;
+ },
+ RemoteListener__deserializeSet: function(list) {
+ if (list == null)
+ return null;
+ if (J.get$isEmpty$asx(list))
+ return null;
+ return P.LinkedHashSet_LinkedHashSet$from(list, type$.String);
+ },
+ RemoteListener__sendLoadException: function(channel, message) {
+ var t1 = type$.String;
+ channel._mainController._foreign._sink.add$1(0, P.LinkedHashMap_LinkedHashMap$_literal(["type", "loadException", "message", message], t1, t1));
+ },
+ RemoteListener__sendError: function(channel, error, stackTrace, verboseChain) {
+ channel._mainController._foreign._sink.add$1(0, P.LinkedHashMap_LinkedHashMap$_literal(["type", "error", "error", U.RemoteException_serialize(error, type$.StackTraceFormatter._as($.Zone__current.$index(0, $.$get$_currentKey0())).formatStackTrace$2$verbose(stackTrace, verboseChain))], type$.String, type$.Object));
+ },
+ RemoteListener: function RemoteListener(t0, t1) {
+ this._suite = t0;
+ this._printZone = t1;
+ },
+ RemoteListener_start_closure: function RemoteListener_start_closure(t0, t1) {
+ this.printZone = t0;
+ this.channel = t1;
+ },
+ RemoteListener_start_closure0: function RemoteListener_start_closure0() {
+ },
+ RemoteListener_start_closure1: function RemoteListener_start_closure1(t0, t1, t2, t3, t4, t5, t6) {
+ var _ = this;
+ _._box_0 = t0;
+ _.getMain = t1;
+ _.channel = t2;
+ _.controller = t3;
+ _.beforeLoad = t4;
+ _.printZone = t5;
+ _.spec = t6;
+ },
+ RemoteListener_start__closure: function RemoteListener_start__closure(t0, t1, t2, t3, t4, t5, t6) {
+ var _ = this;
+ _._box_0 = t0;
+ _.getMain = t1;
+ _.channel = t2;
+ _.controller = t3;
+ _.beforeLoad = t4;
+ _.printZone = t5;
+ _.spec = t6;
+ },
+ RemoteListener_start___closure: function RemoteListener_start___closure(t0, t1, t2, t3, t4, t5) {
+ var _ = this;
+ _._box_0 = t0;
+ _.getMain = t1;
+ _.channel = t2;
+ _.controller = t3;
+ _.beforeLoad = t4;
+ _.printZone = t5;
+ },
+ RemoteListener_start____closure: function RemoteListener_start____closure(t0, t1) {
+ this.controller = t0;
+ this.channel = t1;
+ },
+ RemoteListener_start____closure0: function RemoteListener_start____closure0(t0, t1, t2) {
+ this.suite = t0;
+ this.printZone = t1;
+ this.channel = t2;
+ },
+ RemoteListener_start_____closure: function RemoteListener_start_____closure(t0, t1, t2) {
+ this.suite = t0;
+ this.printZone = t1;
+ this.channel = t2;
+ },
+ RemoteListener_start___closure0: function RemoteListener_start___closure0(t0, t1) {
+ this._box_0 = t0;
+ this.channel = t1;
+ },
+ RemoteListener__serializeGroup_closure: function RemoteListener__serializeGroup_closure(t0, t1, t2) {
+ this._box_0 = t0;
+ this.$this = t1;
+ this.channel = t2;
+ },
+ RemoteListener__serializeTest_closure: function RemoteListener__serializeTest_closure(t0, t1, t2, t3) {
+ var _ = this;
+ _.$this = t0;
+ _.test = t1;
+ _.groups = t2;
+ _.channel = t3;
+ },
+ RemoteListener__runLiveTest_closure: function RemoteListener__runLiveTest_closure(t0) {
+ this.liveTest = t0;
+ },
+ RemoteListener__runLiveTest_closure0: function RemoteListener__runLiveTest_closure0(t0) {
+ this.channel = t0;
+ },
+ RemoteListener__runLiveTest_closure1: function RemoteListener__runLiveTest_closure1(t0, t1) {
+ this.channel = t0;
+ this.liveTest = t1;
+ },
+ RemoteListener__runLiveTest_closure2: function RemoteListener__runLiveTest_closure2(t0, t1) {
+ this.$this = t0;
+ this.channel = t1;
+ },
+ RemoteListener__runLiveTest_closure3: function RemoteListener__runLiveTest_closure3(t0, t1) {
+ this.liveTest = t0;
+ this.channel = t1;
+ },
+ RemoteListener__runLiveTest__closure: function RemoteListener__runLiveTest__closure(t0) {
+ this.channel = t0;
+ }
+ },
+ O = {DelegatingSink: function DelegatingSink(t0, t1) {
+ this._sink$_sink = t0;
+ this.$ti = t1;
+ }, None: function None() {
+ }, Scanner: function Scanner(t0) {
+ this._scanner = t0;
+ this._scanner$_next = null;
+ this._endOfFileEmitted = false;
+ }, EmptyUnmodifiableSet: function EmptyUnmodifiableSet(t0) {
+ this.$ti = t0;
+ },
+ Style__getPlatformStyle: function() {
+ if (P.Uri_base().get$scheme() !== "file")
+ return $.$get$Style_url();
+ var t1 = P.Uri_base();
+ if (!C.JSString_methods.endsWith$1(t1.get$path(t1), "/"))
+ return $.$get$Style_url();
+ if (P._Uri__Uri(null, "a/b", null, null).toFilePath$0() === "a\\b")
+ return $.$get$Style_windows();
+ return $.$get$Style_posix();
+ },
+ Style: function Style() {
+ },
+ Pool$: function(_maxAllocatedResources) {
+ var t4,
+ t1 = type$.Completer_PoolResource,
+ t2 = P.ListQueue$(t1),
+ t3 = P.ListQueue$(type$.void_Function);
+ t1 = P.ListQueue$(t1);
+ t4 = $.Zone__current;
+ if (_maxAllocatedResources <= 0)
+ H.throwExpression(P.ArgumentError$value(_maxAllocatedResources, "maxAllocatedResources", "Must be greater than zero."));
+ return new O.Pool(t2, t3, t1, _maxAllocatedResources, new S.AsyncMemoizer(new P._AsyncCompleter(new P._Future(t4, type$._Future_dynamic), type$._AsyncCompleter_dynamic), type$.AsyncMemoizer_dynamic));
+ },
+ Pool: function Pool(t0, t1, t2, t3, t4) {
+ var _ = this;
+ _._requestedResources = t0;
+ _._onReleaseCallbacks = t1;
+ _._onReleaseCompleters = t2;
+ _._maxAllocatedResources = t3;
+ _._allocatedResources = 0;
+ _._closeGroup = _._timer = null;
+ _._pool$_closeMemo = t4;
+ },
+ Pool_close_closure: function Pool_close_closure(t0) {
+ this.$this = t0;
+ },
+ Pool__onResourceReleaseAllowed_closure: function Pool__onResourceReleaseAllowed_closure(t0, t1) {
+ this.zone = t0;
+ this.registered = t1;
+ },
+ Pool__runOnRelease_closure: function Pool__runOnRelease_closure(t0) {
+ this.$this = t0;
+ },
+ Pool__runOnRelease_closure0: function Pool__runOnRelease_closure0(t0) {
+ this.$this = t0;
+ },
+ PoolResource: function PoolResource(t0) {
+ this._pool = t0;
+ this._released = false;
+ },
+ mapStackTrace: function(sourceMap, stackTrace, minified, packageResolver, sdkRoot) {
+ var t2, t3, sdkLib, t4, t1 = {};
+ t1.packageResolver = packageResolver;
+ if (type$.Chain._is(stackTrace)) {
+ t2 = stackTrace.get$traces();
+ t3 = H._arrayInstanceType(t2);
+ return new U.Chain(P.List_List$unmodifiable(new H.MappedListIterable(t2, t3._eval$1("Trace(1)")._check(new O.mapStackTrace_closure(t1, sourceMap, false, sdkRoot)), t3._eval$1("MappedListIterable<1,Trace>")), type$.Trace));
+ }
+ t2 = sdkRoot == null;
+ !t2;
+ sdkLib = t2 ? null : sdkRoot.toString$0(0) + "/lib";
+ t2 = Y.Trace_Trace$from(stackTrace).get$frames();
+ t3 = H._arrayInstanceType(t2);
+ t4 = t3._eval$1("MappedListIterable<1,Frame>");
+ return new Y.Trace(P.List_List$unmodifiable(new H.MappedListIterable(t2, t3._eval$1("Frame(1)")._check(new O.mapStackTrace_closure0(t1, sourceMap, sdkRoot, sdkLib, false)), t4).super$Iterable$where(0, t4._eval$1("bool(ListIterable.E)")._check(new O.mapStackTrace_closure1())), type$.Frame), new P._StringStackTrace(null));
+ },
+ _prettifyMember: function(member) {
+ var t2, t3,
+ t1 = P.RegExp_RegExp("/?<$", false);
+ member.toString;
+ t1 = H.stringReplaceAllUnchecked(member, t1, "");
+ t2 = P.RegExp_RegExp("\\$\\d+(\\$[a-zA-Z_0-9]+)*$", false);
+ t3 = type$.String_Function_Match;
+ t2 = C.JSString_methods.splitMapJoin$2$onMatch(H.stringReplaceAllUnchecked(t1, t2, ""), P.RegExp_RegExp("(_+)closure\\d*\\.call$", false), t3._check(new O._prettifyMember_closure()));
+ t1 = P.RegExp_RegExp("\\.call$", false);
+ t1 = H.stringReplaceAllUnchecked(t2, t1, "");
+ t2 = P.RegExp_RegExp("^dart\\.", false);
+ t1 = H.stringReplaceAllUnchecked(t1, t2, "");
+ t2 = P.RegExp_RegExp("[a-zA-Z_0-9]+\\$", false);
+ t1 = H.stringReplaceAllUnchecked(t1, t2, "");
+ t2 = P.RegExp_RegExp("^[a-zA-Z_0-9]+.(static|dart).", false);
+ return C.JSString_methods.splitMapJoin$2$onMatch(H.stringReplaceAllUnchecked(t1, t2, ""), P.RegExp_RegExp("([a-zA-Z0-9]+)_", false), t3._check(new O._prettifyMember_closure0()));
+ },
+ mapStackTrace_closure: function mapStackTrace_closure(t0, t1, t2, t3) {
+ var _ = this;
+ _._box_0 = t0;
+ _.sourceMap = t1;
+ _.minified = t2;
+ _.sdkRoot = t3;
+ },
+ mapStackTrace_closure0: function mapStackTrace_closure0(t0, t1, t2, t3, t4) {
+ var _ = this;
+ _._box_0 = t0;
+ _.sourceMap = t1;
+ _.sdkRoot = t2;
+ _.sdkLib = t3;
+ _.minified = t4;
+ },
+ mapStackTrace_closure1: function mapStackTrace_closure1() {
+ },
+ _prettifyMember_closure: function _prettifyMember_closure() {
+ },
+ _prettifyMember_closure0: function _prettifyMember_closure0() {
+ },
+ StackZoneSpecification: function StackZoneSpecification(t0, t1, t2) {
+ var _ = this;
+ _._chains = t0;
+ _._stack_zone_specification$_onError = t1;
+ _._currentNode = null;
+ _._errorZone = t2;
+ },
+ StackZoneSpecification_chainFor_closure: function StackZoneSpecification_chainFor_closure(t0) {
+ this._box_0 = t0;
+ },
+ StackZoneSpecification_chainFor_closure0: function StackZoneSpecification_chainFor_closure0(t0, t1) {
+ this.$this = t0;
+ this.original = t1;
+ },
+ StackZoneSpecification__registerCallback_closure: function StackZoneSpecification__registerCallback_closure(t0, t1, t2, t3) {
+ var _ = this;
+ _.$this = t0;
+ _.f = t1;
+ _.node = t2;
+ _.R = t3;
+ },
+ StackZoneSpecification__registerUnaryCallback_closure: function StackZoneSpecification__registerUnaryCallback_closure(t0, t1, t2, t3, t4) {
+ var _ = this;
+ _.$this = t0;
+ _.f = t1;
+ _.node = t2;
+ _.T = t3;
+ _.R = t4;
+ },
+ StackZoneSpecification__registerUnaryCallback__closure: function StackZoneSpecification__registerUnaryCallback__closure(t0, t1, t2) {
+ this.f = t0;
+ this.arg = t1;
+ this.R = t2;
+ },
+ StackZoneSpecification__registerBinaryCallback_closure: function StackZoneSpecification__registerBinaryCallback_closure(t0, t1, t2, t3, t4, t5) {
+ var _ = this;
+ _.$this = t0;
+ _.f = t1;
+ _.node = t2;
+ _.T1 = t3;
+ _.T2 = t4;
+ _.R = t5;
+ },
+ StackZoneSpecification__registerBinaryCallback__closure: function StackZoneSpecification__registerBinaryCallback__closure(t0, t1, t2, t3) {
+ var _ = this;
+ _.f = t0;
+ _.arg1 = t1;
+ _.arg2 = t2;
+ _.R = t3;
+ },
+ StackZoneSpecification__currentTrace_closure: function StackZoneSpecification__currentTrace_closure(t0, t1, t2) {
+ this._box_0 = t0;
+ this.$this = t1;
+ this.stackTrace = t2;
+ },
+ _Node: function _Node(t0, t1) {
+ this.trace = t0;
+ this.previous = t1;
+ },
+ Group$: function($name, entries, metadata, setUpAll, tearDownAll, trace) {
+ var t1 = P.List_List$unmodifiable(entries, type$.GroupEntry);
+ return new O.Group($name, metadata, trace, t1, setUpAll, tearDownAll);
+ },
+ Group: function Group(t0, t1, t2, t3, t4, t5) {
+ var _ = this;
+ _.name = t0;
+ _.metadata = t1;
+ _.trace = t2;
+ _.entries = t3;
+ _.setUpAll = t4;
+ _.tearDownAll = t5;
+ },
+ Group_forPlatform_closure: function Group_forPlatform_closure(t0) {
+ this.platform = t0;
+ },
+ Group__map_closure: function Group__map_closure(t0) {
+ this.callback = t0;
+ },
+ Group__map_closure0: function Group__map_closure0() {
+ },
+ Metadata__parseOnPlatform: function(onPlatform) {
+ return P.LinkedHashMap_LinkedHashMap$_empty(type$.PlatformSelector, type$.Metadata);
+ },
+ Metadata__parseTags: function(tags) {
+ return P.LinkedHashSet_LinkedHashSet$_empty(type$.String);
+ },
+ Metadata_Metadata: function(chainStackTraces, forTag, onPlatform, retry, skip, skipReason, tags, testOn, timeout, verboseTrace) {
+ var t2, t3, empty, t4, merged, _null = null, t1 = {};
+ t1.tags = tags;
+ t1.forTag = forTag;
+ t2 = new O.Metadata_Metadata__unresolved(t1, testOn, timeout, skip, verboseTrace, chainStackTraces, retry, skipReason, onPlatform);
+ if (forTag == null || tags == null)
+ return t2.call$0();
+ t1.tags = P.LinkedHashSet_LinkedHashSet$from(tags, type$.String);
+ t3 = type$.Metadata;
+ t1.forTag = P.LinkedHashMap_LinkedHashMap$from(t1.forTag, type$.BooleanSelector, t3);
+ empty = O.Metadata$_(_null, _null, _null, _null, _null, _null, _null, _null, _null, _null);
+ t4 = t1.forTag.get$keys();
+ merged = C.JSArray_methods.fold$1$2(P.List_List$from(t4, true, H._instanceType(t4)._eval$1("Iterable.E")), empty, new O.Metadata_Metadata_closure(t1), t3);
+ if (merged === empty)
+ return t2.call$0();
+ return merged.merge$1(t2.call$0());
+ },
+ Metadata$_: function(chainStackTraces, forTag, onPlatform, retry, skip, skipReason, tags, testOn, timeout, verboseTrace) {
+ var t1 = testOn == null ? C.PlatformSelector_All : testOn,
+ t2 = timeout == null ? C.Timeout_null_1 : timeout,
+ t3 = tags == null ? P.LinkedHashSet_LinkedHashSet$_empty(type$.String) : tags.toSet$0(0),
+ t4 = onPlatform == null ? C.Map_empty : new P.UnmodifiableMapView(onPlatform, type$.UnmodifiableMapView_PlatformSelector_Metadata),
+ t5 = forTag == null ? C.Map_empty0 : new P.UnmodifiableMapView(forTag, type$.UnmodifiableMapView_BooleanSelector_Metadata);
+ t5 = new O.Metadata(t1, t2, skip, skipReason, verboseTrace, chainStackTraces, new L.UnmodifiableSetView(t3, type$.UnmodifiableSetView_String), retry, t4, t5);
+ if (retry != null)
+ P.RangeError_checkNotNegative(retry, "retry");
+ t5._validateTags$0();
+ return t5;
+ },
+ Metadata$parse: function(onPlatform, retry, skip, tags, testOn, timeout) {
+ var _null = null,
+ t1 = timeout == null ? C.Timeout_null_1 : timeout,
+ t2 = skip == null,
+ t3 = t2 ? _null : skip,
+ t4 = O.Metadata__parseOnPlatform(onPlatform);
+ t4 = new O.Metadata(C.PlatformSelector_All, t1, t3, _null, _null, _null, O.Metadata__parseTags(tags), retry, t4, C.Map_empty0);
+ !t2;
+ if (retry != null)
+ P.RangeError_checkNotNegative(retry, "retry");
+ t4._validateTags$0();
+ return t4;
+ },
+ Metadata$deserialize: function(serialized) {
+ var pair, t13,
+ t1 = J.getInterceptor$asx(serialized),
+ t2 = t1.$index(serialized, "testOn") == null ? C.PlatformSelector_All : E.PlatformSelector$parse(H._asStringNullable(t1.$index(serialized, "testOn"))),
+ t3 = O.Metadata__deserializeTimeout(t1.$index(serialized, "timeout")),
+ t4 = H._asBoolNullable(t1.$index(serialized, "skip")),
+ t5 = H._asStringNullable(t1.$index(serialized, "skipReason")),
+ t6 = H._asBoolNullable(t1.$index(serialized, "verboseTrace")),
+ t7 = H._asBoolNullable(t1.$index(serialized, "chainStackTraces")),
+ t8 = H._asIntNullable(t1.$index(serialized, "retry")),
+ t9 = type$.Iterable_dynamic,
+ t10 = P.LinkedHashSet_LinkedHashSet$from(t9._as(t1.$index(serialized, "tags")), type$.String),
+ t11 = type$.Metadata,
+ t12 = P.LinkedHashMap_LinkedHashMap$_empty(type$.PlatformSelector, t11);
+ for (t9 = J.get$iterator$ax(t9._check(t1.$index(serialized, "onPlatform"))); t9.moveNext$0();) {
+ pair = t9.get$current();
+ t13 = J.getInterceptor$ax(pair);
+ t12.$indexSet(0, E.PlatformSelector$parse(H._asStringNullable(t13.get$first(pair))), O.Metadata$deserialize(t13.get$last(pair)));
+ }
+ return new O.Metadata(t2, t3, t4, t5, t6, t7, t10, t8, t12, type$.Map_dynamic_dynamic._as(t1.$index(serialized, "forTag")).map$2$1(0, new O.Metadata$deserialize_closure(), type$.BooleanSelector, t11));
+ },
+ Metadata__deserializeTimeout: function(serialized) {
+ var scaleFactor,
+ t1 = J.getInterceptor$(serialized);
+ if (t1.$eq(serialized, "none"))
+ return C.Timeout_null_null;
+ scaleFactor = t1.$index(serialized, "scaleFactor");
+ if (scaleFactor != null)
+ return new R.Timeout(null, H._asNumNullable(scaleFactor));
+ return new R.Timeout(P.Duration$(H._asIntNullable(t1.$index(serialized, "duration")), 0), null);
+ },
+ Metadata: function Metadata(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9) {
+ var _ = this;
+ _.testOn = t0;
+ _.timeout = t1;
+ _._skip = t2;
+ _.skipReason = t3;
+ _._verboseTrace = t4;
+ _._chainStackTraces = t5;
+ _.tags = t6;
+ _._retry = t7;
+ _.onPlatform = t8;
+ _.forTag = t9;
+ },
+ Metadata_Metadata__unresolved: function Metadata_Metadata__unresolved(t0, t1, t2, t3, t4, t5, t6, t7, t8) {
+ var _ = this;
+ _._box_0 = t0;
+ _.testOn = t1;
+ _.timeout = t2;
+ _.skip = t3;
+ _.verboseTrace = t4;
+ _.chainStackTraces = t5;
+ _.retry = t6;
+ _.skipReason = t7;
+ _.onPlatform = t8;
+ },
+ Metadata_Metadata_closure: function Metadata_Metadata_closure(t0) {
+ this._box_0 = t0;
+ },
+ Metadata$deserialize_closure: function Metadata$deserialize_closure() {
+ },
+ Metadata__validateTags_closure: function Metadata__validateTags_closure() {
+ },
+ Metadata__validateTags_closure0: function Metadata__validateTags_closure0() {
+ },
+ Metadata_validatePlatformSelectors_closure: function Metadata_validatePlatformSelectors_closure(t0) {
+ this.validVariables = t0;
+ },
+ Metadata_merge_closure: function Metadata_merge_closure() {
+ },
+ Metadata_merge_closure0: function Metadata_merge_closure0() {
+ },
+ Metadata_forPlatform_closure: function Metadata_forPlatform_closure(t0, t1) {
+ this._box_0 = t0;
+ this.platform = t1;
+ },
+ Metadata_serialize_closure: function Metadata_serialize_closure(t0) {
+ this.serializedOnPlatform = t0;
+ },
+ Metadata_serialize_closure0: function Metadata_serialize_closure0() {
+ },
+ IterableSet: function IterableSet(t0, t1) {
+ this._iterable_set$_base = t0;
+ this.$ti = t1;
+ },
+ _IterableSet_SetMixin_UnmodifiableSetMixin: function _IterableSet_SetMixin_UnmodifiableSetMixin() {
+ },
+ Engine$: function() {
+ var t6, t7, t8, t9, t10, t11, _null = null,
+ t1 = $.Zone__current,
+ t2 = H.setRuntimeTypeInfo([], type$.JSArray_dynamic),
+ t3 = type$.RunnerSuite,
+ t4 = P.StreamController_StreamController(_null, _null, false, t3),
+ t5 = new L.StreamGroup(C._StreamGroupState_dormant, new H.JsLinkedHashMap(type$.JsLinkedHashMap_of_Stream_LiveTest_and_StreamSubscription_LiveTest), type$.StreamGroup_LiveTest);
+ t5.set$_stream_group$_controller(new P._SyncBroadcastStreamController(t5.get$_onListen(), t5.get$_onCancelBroadcast(), type$._SyncBroadcastStreamController_LiveTest));
+ t6 = type$.LiveTest;
+ t7 = Y.UnionSetController$(true, t6);
+ t8 = Y.UnionSetController$(true, t6);
+ t9 = Y.UnionSetController$(true, t6);
+ t10 = Q.QueueList$(t6);
+ t11 = O.Pool$(1);
+ t1 = new O.Engine(t11, O.Pool$(2), new F.FutureGroup(new P._AsyncCompleter(new P._Future(t1, type$._Future_List_dynamic), type$._AsyncCompleter_List_dynamic), t2, type$.FutureGroup_dynamic), P.LinkedHashSet_LinkedHashSet$_empty(type$.StreamSubscription_dynamic), t4, P.LinkedHashSet_LinkedHashSet$_empty(t3), new P._AsyncBroadcastStreamController(_null, _null, type$._AsyncBroadcastStreamController_RunnerSuite), P.LinkedHashSet_LinkedHashSet$_empty(type$.LiveSuite), new P._AsyncBroadcastStreamController(_null, _null, type$._AsyncBroadcastStreamController_LiveSuite), t5, t7, t8, t9, t10, P.LinkedHashSet_LinkedHashSet$_empty(t6), P.LinkedHashSet_LinkedHashSet$_empty(t6));
+ t1.Engine$3$concurrency$coverage$maxSuites(_null, _null, _null);
+ return t1;
+ },
+ Engine: function Engine(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15) {
+ var _ = this;
+ _._engine$_closed = _._engine$_runCalled = false;
+ _._closedBeforeDone = null;
+ _._runPool = t0;
+ _._loadPool = t1;
+ _._group = t2;
+ _._engine$_subscriptions = t3;
+ _._suiteController = t4;
+ _._addedSuites = t5;
+ _._onSuiteAddedController = t6;
+ _._liveSuites = t7;
+ _._onSuiteStartedController = t8;
+ _._onTestStartedGroup = t9;
+ _._passedGroup = t10;
+ _._skippedGroup = t11;
+ _._failedGroup = t12;
+ _._active = t13;
+ _._restarted = t14;
+ _._activeLoadTests = t15;
+ },
+ Engine_success_closure: function Engine_success_closure() {
+ },
+ Engine_closure: function Engine_closure(t0) {
+ this.$this = t0;
+ },
+ Engine_closure0: function Engine_closure0() {
+ },
+ Engine_run_closure: function Engine_run_closure(t0) {
+ this.$this = t0;
+ },
+ Engine_run__closure: function Engine_run__closure(t0, t1) {
+ this.$this = t0;
+ this.suite = t1;
+ },
+ Engine_run___closure: function Engine_run___closure(t0, t1, t2) {
+ this._box_0 = t0;
+ this.$this = t1;
+ this.loadResource = t2;
+ },
+ Engine_run____closure: function Engine_run____closure(t0) {
+ this._box_0 = t0;
+ },
+ Engine_run_closure0: function Engine_run_closure0(t0, t1) {
+ this._box_1 = t0;
+ this.$this = t1;
+ },
+ Engine__runLiveTest_closure: function Engine__runLiveTest_closure(t0, t1) {
+ this.$this = t0;
+ this.liveTest = t1;
+ },
+ Engine__runLiveTest_closure0: function Engine__runLiveTest_closure0(t0, t1) {
+ this._box_0 = t0;
+ this.$this = t1;
+ },
+ Engine__runLiveTest_closure1: function Engine__runLiveTest_closure1() {
+ },
+ Engine__runSkippedTest_closure: function Engine__runSkippedTest_closure() {
+ },
+ Engine__runSkippedTest_closure0: function Engine__runSkippedTest_closure0(t0, t1) {
+ this._box_0 = t0;
+ this.skipped = t1;
+ },
+ Engine__runSkippedTest_closure1: function Engine__runSkippedTest_closure1() {
+ },
+ binarySearch: function(list, matches) {
+ var max, min, half;
+ if (list.length === 0)
+ return -1;
+ if (H.boolConversionCheck(matches.call$1(C.JSArray_methods.get$first(list))))
+ return 0;
+ if (!H.boolConversionCheck(matches.call$1(C.JSArray_methods.get$last(list))))
+ return list.length;
+ max = list.length - 1;
+ for (min = 0; min < max;) {
+ half = min + C.JSInt_methods._tdivFast$1(max - min, 2);
+ if (half < 0 || half >= list.length)
+ return H.ioore(list, half);
+ if (H.boolConversionCheck(matches.call$1(list[half])))
+ max = half;
+ else
+ min = half + 1;
+ }
+ return max;
+ }
+ },
+ Y = {DelegatingStreamSubscription: function DelegatingStreamSubscription() {
+ }, StreamCompleter: function StreamCompleter(t0, t1) {
+ this._stream = t0;
+ this.$ti = t1;
+ }, _CompleterStream: function _CompleterStream(t0) {
+ this._sourceStream = this._stream_completer$_controller = null;
+ this.$ti = t0;
+ }, BooleanSelectorImpl: function BooleanSelectorImpl(t0) {
+ this._selector = t0;
+ },
+ mapMap: function(map, value, K1, V1, K2, V2) {
+ var key, result, t1 = {};
+ t1.key = key;
+ t1.value = value;
+ t1.key = null;
+ t1.key = new Y.mapMap_closure(K2, K1, V1);
+ result = P.LinkedHashMap_LinkedHashMap$_empty(K2, V2);
+ map.forEach$1(0, new Y.mapMap_closure0(t1, result, K1, V1));
+ return result;
+ },
+ mergeMaps: function(map1, map2, value, $K, $V) {
+ var result = P.LinkedHashMap_LinkedHashMap$from(map1, $K, $V);
+ map2.forEach$1(0, new Y.mergeMaps_closure(result, value, $K, $V));
+ return result;
+ },
+ mapMap_closure: function mapMap_closure(t0, t1, t2) {
+ this.K2 = t0;
+ this.K1 = t1;
+ this.V1 = t2;
+ },
+ mapMap_closure0: function mapMap_closure0(t0, t1, t2, t3) {
+ var _ = this;
+ _._box_0 = t0;
+ _.result = t1;
+ _.K1 = t2;
+ _.V1 = t3;
+ },
+ mergeMaps_closure: function mergeMaps_closure(t0, t1, t2, t3) {
+ var _ = this;
+ _.result = t0;
+ _.value = t1;
+ _.K = t2;
+ _.V = t3;
+ },
+ UnionSetController$: function(disjoint, $E) {
+ var t1 = P.LinkedHashSet_LinkedHashSet($E._eval$1("Set<0>")),
+ t2 = new Y.UnionSetController(t1, $E._eval$1("UnionSetController<0>"));
+ t2.set$_union_set_controller$_set(new M.UnionSet(t1, true, $E._eval$1("UnionSet<0>")));
+ return t2;
+ },
+ UnionSetController: function UnionSetController(t0, t1) {
+ this._union_set_controller$_set = null;
+ this._union_set_controller$_sets = t0;
+ this.$ti = t1;
+ },
+ _IsTrue: function _IsTrue() {
+ },
+ _Predicate: function _Predicate(t0, t1, t2) {
+ this._matcher = t0;
+ this._core_matchers$_description = t1;
+ this.$ti = t2;
+ },
+ FileLocation$_: function(file, offset) {
+ if (offset < 0)
+ H.throwExpression(P.RangeError$("Offset may not be negative, was " + offset + "."));
+ else if (offset > file._decodedChars.length)
+ H.throwExpression(P.RangeError$("Offset " + offset + " must not be greater than the number of characters in the file, " + file.get$length(file) + "."));
+ return new Y.FileLocation(file, offset);
+ },
+ _FileSpan$: function(file, _start, _end) {
+ if (_end < _start)
+ H.throwExpression(P.ArgumentError$("End " + _end + " must come after start " + _start + "."));
+ else if (_end > file._decodedChars.length)
+ H.throwExpression(P.RangeError$("End " + _end + " must not be greater than the number of characters in the file, " + file.get$length(file) + "."));
+ else if (_start < 0)
+ H.throwExpression(P.RangeError$("Start may not be negative, was " + _start + "."));
+ return new Y._FileSpan(file, _start, _end);
+ },
+ SourceFile: function SourceFile(t0, t1, t2) {
+ var _ = this;
+ _.url = t0;
+ _._lineStarts = t1;
+ _._decodedChars = t2;
+ _._cachedLine = null;
+ },
+ FileLocation: function FileLocation(t0, t1) {
+ this.file = t0;
+ this.offset = t1;
+ },
+ _FileSpan: function _FileSpan(t0, t1, t2) {
+ this.file = t0;
+ this._file$_start = t1;
+ this._file$_end = t2;
+ },
+ SourceSpanMixin: function SourceSpanMixin() {
+ },
+ Trace_Trace$current: function(level) {
+ return new T.LazyTrace(new Y.Trace_Trace$current_closure(Y.Trace_Trace$from(P.StackTrace_current()), level));
+ },
+ Trace_Trace$from: function(trace) {
+ if (trace == null)
+ throw H.wrapException(P.ArgumentError$("Cannot create a Trace from null."));
+ if (type$.Trace._is(trace))
+ return trace;
+ if (type$.Chain._is(trace))
+ return trace.toTrace$0();
+ return new T.LazyTrace(new Y.Trace_Trace$from_closure(trace));
+ },
+ Trace_Trace$parse: function(trace) {
+ var error, t1, exception;
+ try {
+ if (trace.length === 0) {
+ t1 = P.List_List$unmodifiable(H.setRuntimeTypeInfo([], type$.JSArray_Frame), type$.Frame);
+ return new Y.Trace(t1, new P._StringStackTrace(null));
+ }
+ if (C.JSString_methods.contains$1(trace, $.$get$_v8Trace())) {
+ t1 = Y.Trace$parseV8(trace);
+ return t1;
+ }
+ if (C.JSString_methods.contains$1(trace, "\tat ")) {
+ t1 = Y.Trace$parseJSCore(trace);
+ return t1;
+ }
+ if (C.JSString_methods.contains$1(trace, $.$get$_firefoxSafariTrace())) {
+ t1 = Y.Trace$parseFirefox(trace);
+ return t1;
+ }
+ if (C.JSString_methods.contains$1(trace, "===== asynchronous gap ===========================\n")) {
+ t1 = U.Chain_Chain$parse(trace).toTrace$0();
+ return t1;
+ }
+ if (C.JSString_methods.contains$1(trace, $.$get$_friendlyTrace())) {
+ t1 = Y.Trace$parseFriendly(trace);
+ return t1;
+ }
+ t1 = P.List_List$unmodifiable(Y.Trace__parseVM(trace), type$.Frame);
+ return new Y.Trace(t1, new P._StringStackTrace(trace));
+ } catch (exception) {
+ t1 = H.unwrapException(exception);
+ if (type$.FormatException._is(t1)) {
+ error = t1;
+ throw H.wrapException(P.FormatException$(H.S(J.get$message$x(error)) + "\nStack trace:\n" + H.S(trace), null, null));
+ } else
+ throw exception;
+ }
+ },
+ Trace__parseVM: function(trace) {
+ var t2, $frames,
+ t1 = J.trim$0$s(trace),
+ lines = H.setRuntimeTypeInfo(H.stringReplaceAllUnchecked(t1, "<asynchronous suspension>\n", "").split("\n"), type$.JSArray_String);
+ t1 = H.SubListIterable$(lines, 0, lines.length - 1, type$.String);
+ t2 = t1.$ti;
+ $frames = new H.MappedListIterable(t1, t2._eval$1("Frame(ListIterable.E)")._check(new Y.Trace__parseVM_closure()), t2._eval$1("MappedListIterable<ListIterable.E,Frame>")).toList$0(0);
+ if (!J.endsWith$1$s(C.JSArray_methods.get$last(lines), ".da"))
+ C.JSArray_methods.add$1($frames, A.Frame_Frame$parseVM(C.JSArray_methods.get$last(lines)));
+ return $frames;
+ },
+ Trace$parseV8: function(trace) {
+ var t2, t3,
+ t1 = H.SubListIterable$(H.setRuntimeTypeInfo(trace.split("\n"), type$.JSArray_String), 1, null, type$.String);
+ t1 = t1.super$Iterable$skipWhile(0, t1.$ti._eval$1("bool(ListIterable.E)")._check(new Y.Trace$parseV8_closure()));
+ t2 = type$.Frame;
+ t3 = t1.$ti;
+ return new Y.Trace(P.List_List$unmodifiable(H.MappedIterable_MappedIterable(t1, t3._eval$1("Frame(Iterable.E)")._check(new Y.Trace$parseV8_closure0()), t3._eval$1("Iterable.E"), t2), t2), new P._StringStackTrace(trace));
+ },
+ Trace$parseJSCore: function(trace) {
+ return new Y.Trace(P.List_List$unmodifiable(new H.MappedIterable(new H.WhereIterable(H.setRuntimeTypeInfo(trace.split("\n"), type$.JSArray_String), type$.bool_Function_String._check(new Y.Trace$parseJSCore_closure()), type$.WhereIterable_String), type$.Frame_Function_String._check(new Y.Trace$parseJSCore_closure0()), type$.MappedIterable_String_Frame), type$.Frame), new P._StringStackTrace(trace));
+ },
+ Trace$parseFirefox: function(trace) {
+ return new Y.Trace(P.List_List$unmodifiable(new H.MappedIterable(new H.WhereIterable(H.setRuntimeTypeInfo(C.JSString_methods.trim$0(trace).split("\n"), type$.JSArray_String), type$.bool_Function_String._check(new Y.Trace$parseFirefox_closure()), type$.WhereIterable_String), type$.Frame_Function_String._check(new Y.Trace$parseFirefox_closure0()), type$.MappedIterable_String_Frame), type$.Frame), new P._StringStackTrace(trace));
+ },
+ Trace$parseFriendly: function(trace) {
+ var t1 = trace.length === 0 ? H.setRuntimeTypeInfo([], type$.JSArray_Frame) : new H.MappedIterable(new H.WhereIterable(H.setRuntimeTypeInfo(C.JSString_methods.trim$0(trace).split("\n"), type$.JSArray_String), type$.bool_Function_String._check(new Y.Trace$parseFriendly_closure()), type$.WhereIterable_String), type$.Frame_Function_String._check(new Y.Trace$parseFriendly_closure0()), type$.MappedIterable_String_Frame);
+ return new Y.Trace(P.List_List$unmodifiable(t1, type$.Frame), new P._StringStackTrace(trace));
+ },
+ Trace: function Trace(t0, t1) {
+ this.frames = t0;
+ this.original = t1;
+ },
+ Trace_Trace$current_closure: function Trace_Trace$current_closure(t0, t1) {
+ this.trace = t0;
+ this.level = t1;
+ },
+ Trace_Trace$from_closure: function Trace_Trace$from_closure(t0) {
+ this.trace = t0;
+ },
+ Trace__parseVM_closure: function Trace__parseVM_closure() {
+ },
+ Trace$parseV8_closure: function Trace$parseV8_closure() {
+ },
+ Trace$parseV8_closure0: function Trace$parseV8_closure0() {
+ },
+ Trace$parseJSCore_closure: function Trace$parseJSCore_closure() {
+ },
+ Trace$parseJSCore_closure0: function Trace$parseJSCore_closure0() {
+ },
+ Trace$parseFirefox_closure: function Trace$parseFirefox_closure() {
+ },
+ Trace$parseFirefox_closure0: function Trace$parseFirefox_closure0() {
+ },
+ Trace$parseFriendly_closure: function Trace$parseFriendly_closure() {
+ },
+ Trace$parseFriendly_closure0: function Trace$parseFriendly_closure0() {
+ },
+ Trace_foldFrames_closure: function Trace_foldFrames_closure(t0) {
+ this.oldPredicate = t0;
+ },
+ Trace_foldFrames_closure0: function Trace_foldFrames_closure0(t0) {
+ this._box_0 = t0;
+ },
+ Trace_toString_closure0: function Trace_toString_closure0() {
+ },
+ Trace_toString_closure: function Trace_toString_closure(t0) {
+ this.longest = t0;
+ },
+ RunnerSuite: function RunnerSuite(t0, t1, t2, t3) {
+ var _ = this;
+ _._runner_suite$_controller = t0;
+ _.platform = t1;
+ _.path = t2;
+ _.group = t3;
+ },
+ RunnerSuiteController: function RunnerSuiteController(t0, t1, t2, t3, t4) {
+ var _ = this;
+ _._config = t0;
+ _._runner_suite$_onClose = t1;
+ _._onDebuggingController = t2;
+ _._channelNames = t3;
+ _._closeMemo = t4;
+ },
+ RunnerSuiteController__close_closure: function RunnerSuiteController__close_closure(t0) {
+ this.$this = t0;
+ }
+ },
+ F = {FutureGroup: function FutureGroup(t0, t1, t2) {
+ var _ = this;
+ _._future_group$_pending = 0;
+ _._future_group$_closed = false;
+ _._future_group$_completer = t0;
+ _._values = t1;
+ _.$ti = t2;
+ }, FutureGroup_add_closure: function FutureGroup_add_closure(t0, t1) {
+ this.$this = t0;
+ this.index = t1;
+ }, FutureGroup_add_closure0: function FutureGroup_add_closure0(t0) {
+ this.$this = t0;
+ }, ValueResult: function ValueResult(t0, t1) {
+ this.value = t0;
+ this.$ti = t1;
+ },
+ PackageConfigResolver__normalizeMap: function(map) {
+ var t1 = type$.String,
+ t2 = type$.Uri;
+ return new P.UnmodifiableMapView(Y.mapMap(map, new F.PackageConfigResolver__normalizeMap_closure(), t1, t2, t1, t2), type$.UnmodifiableMapView_String_Uri);
+ },
+ PackageConfigResolver: function PackageConfigResolver(t0) {
+ this.packageConfigMap = t0;
+ },
+ PackageConfigResolver__normalizeMap_closure: function PackageConfigResolver__normalizeMap_closure() {
+ },
+ UrlStyle: function UrlStyle(t0, t1, t2, t3) {
+ var _ = this;
+ _.separatorPattern = t0;
+ _.needsSeparatorPattern = t1;
+ _.rootPattern = t2;
+ _.relativeRootPattern = t3;
+ }
+ },
+ V = {ErrorResult: function ErrorResult(t0, t1) {
+ this.error = t0;
+ this.stackTrace = t1;
+ },
+ SourceLocation$: function(offset, column, line, sourceUrl) {
+ var t2, t3, t4, t5,
+ t1 = typeof sourceUrl == "string" ? P.Uri_parse(sourceUrl) : sourceUrl;
+ type$.Uri._check(t1);
+ t2 = line == null;
+ t3 = t2 ? 0 : line;
+ t4 = column == null;
+ t5 = t4 ? offset : column;
+ if (offset < 0)
+ H.throwExpression(P.RangeError$("Offset may not be negative, was " + offset + "."));
+ else if (!t2 && line < 0)
+ H.throwExpression(P.RangeError$("Line may not be negative, was " + H.S(line) + "."));
+ else if (!t4 && column < 0)
+ H.throwExpression(P.RangeError$("Column may not be negative, was " + H.S(column) + "."));
+ return new V.SourceLocation(t1, offset, t3, t5);
+ },
+ SourceLocation: function SourceLocation(t0, t1, t2, t3) {
+ var _ = this;
+ _.sourceUrl = t0;
+ _.offset = t1;
+ _.line = t2;
+ _.column = t3;
+ },
+ SourceSpan: function SourceSpan() {
+ },
+ SourceSpanBase: function SourceSpanBase() {
+ },
+ GroupEntry: function GroupEntry() {
+ },
+ LiveTestController$: function(suite, _test, onRun, onClose, groups) {
+ var _null = null,
+ t1 = H.setRuntimeTypeInfo([], type$.JSArray_AsyncError),
+ t2 = $.Zone__current,
+ t3 = P.List_List$unmodifiable(groups, type$.Group);
+ t1 = new V.LiveTestController(suite, t3, _test, onRun, onClose, t1, C.State_Status_pending_Result_success, new P._SyncBroadcastStreamController(_null, _null, type$._SyncBroadcastStreamController_State), new P._SyncBroadcastStreamController(_null, _null, type$._SyncBroadcastStreamController_AsyncError), new P._SyncBroadcastStreamController(_null, _null, type$._SyncBroadcastStreamController_Message), new P._AsyncCompleter(new P._Future(t2, type$._Future_void), type$._AsyncCompleter_void));
+ t1._liveTest = new V._LiveTest(t1);
+ return t1;
+ },
+ _LiveTest: function _LiveTest(t0) {
+ this._live_test_controller$_controller = t0;
+ },
+ LiveTestController: function LiveTestController(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10) {
+ var _ = this;
+ _._liveTest = null;
+ _._live_test_controller$_suite = t0;
+ _._groups = t1;
+ _._test = t2;
+ _._onRun = t3;
+ _._onClose = t4;
+ _._errors = t5;
+ _._live_test_controller$_state = t6;
+ _._onStateChangeController = t7;
+ _._onErrorController = t8;
+ _._onMessageController = t9;
+ _.completer = t10;
+ _._runCalled = false;
+ },
+ Test: function Test() {
+ },
+ errorsDontStopTest: function(body) {
+ var t1 = $.Zone__current,
+ t2 = new P._Future(t1, type$._Future_dynamic),
+ t3 = type$.Invoker;
+ t3._as(t1.$index(0, C.Symbol_cQL)).addOutstandingCallback$0();
+ t3._as($.Zone__current.$index(0, C.Symbol_cQL)).waitForOutstandingCallbacks$1(new V.errorsDontStopTest_closure(body, new P._AsyncCompleter(t2, type$._AsyncCompleter_dynamic))).then$1$1(new V.errorsDontStopTest_closure0(), type$.void);
+ return t2;
+ },
+ errorsDontStopTest_closure: function errorsDontStopTest_closure(t0, t1) {
+ this.body = t0;
+ this.completer = t1;
+ },
+ errorsDontStopTest_closure0: function errorsDontStopTest_closure0() {
+ }
+ },
+ E = {Result: function Result() {
+ }, StringDescription: function StringDescription(t0) {
+ this._out = t0;
+ }, FeatureMatcher: function FeatureMatcher() {
+ }, PosixStyle: function PosixStyle(t0, t1, t2) {
+ this.separatorPattern = t0;
+ this.needsSeparatorPattern = t1;
+ this.rootPattern = t2;
+ },
+ StringScannerException$: function(message, span, source) {
+ return new E.StringScannerException(message, span);
+ },
+ StringScannerException: function StringScannerException(t0, t1) {
+ this._span_exception$_message = t0;
+ this._span_exception$_span = t1;
+ },
+ PlatformSelector$parse: function(selector) {
+ return new E.PlatformSelector(E.PlatformSelector__wrapFormatException(new E.PlatformSelector$parse_closure(selector), null, type$.BooleanSelector));
+ },
+ PlatformSelector__wrapFormatException: function(body, span, $T) {
+ var t1 = body.call$0();
+ return t1;
+ },
+ PlatformSelector: function PlatformSelector(t0) {
+ this._platform_selector$_inner = t0;
+ },
+ PlatformSelector$parse_closure: function PlatformSelector$parse_closure(t0) {
+ this.selector = t0;
+ },
+ PlatformSelector_validate_closure: function PlatformSelector_validate_closure(t0, t1) {
+ this.$this = t0;
+ this.validVariables = t1;
+ },
+ PlatformSelector_validate__closure: function PlatformSelector_validate__closure(t0) {
+ this.validVariables = t0;
+ },
+ PlatformSelector_evaluate_closure: function PlatformSelector_evaluate_closure(t0) {
+ this.platform = t0;
+ },
+ SuitePlatform$: function(runtime, inGoogle, os) {
+ var t1 = os == null ? C.OperatingSystem_none_none : os;
+ if (H.boolConversionCheck(runtime.isBrowser) && t1 !== C.OperatingSystem_none_none)
+ H.throwExpression(P.ArgumentError$('No OS should be passed for runtime "' + runtime.toString$0(0) + '".'));
+ return new E.SuitePlatform(runtime, t1, inGoogle);
+ },
+ SuitePlatform: function SuitePlatform(t0, t1, t2) {
+ this.runtime = t0;
+ this.os = t1;
+ this.inGoogle = t2;
+ },
+ StackTraceMapper: function StackTraceMapper() {
+ },
+ LiveSuite: function LiveSuite() {
+ },
+ JSStackTraceMapper_deserialize: function(serialized) {
+ var t1, t2, t3,
+ _s11_ = "packageRoot",
+ packageRoot = H._asStringNullable(serialized.$index(0, _s11_));
+ if (packageRoot == null)
+ packageRoot = "";
+ t1 = H._asStringNullable(serialized.$index(0, "mapContents"));
+ t2 = P.Uri_parse(H._asStringNullable(serialized.$index(0, "sdkRoot")));
+ if (packageRoot.length !== 0)
+ t3 = new D.PackageRootResolver(B.ensureTrailingSlash(B.asUri(P.Uri_parse(H._asStringNullable(serialized.$index(0, _s11_))), _s11_)));
+ else {
+ t3 = type$.String;
+ t3 = F.PackageConfigResolver__normalizeMap(E.JSStackTraceMapper__deserializePackageConfigMap(type$.Map_dynamic_dynamic._as(serialized.$index(0, "packageConfigMap")).cast$2$0(0, t3, t3)));
+ t3 = new F.PackageConfigResolver(t3);
+ }
+ return new E.JSStackTraceMapper(t3, t2, t1, P.Uri_parse(H._asStringNullable(serialized.$index(0, "mapUrl"))));
+ },
+ JSStackTraceMapper__deserializePackageConfigMap: function(serialized) {
+ return serialized.map$2$1(0, new E.JSStackTraceMapper__deserializePackageConfigMap_closure(), type$.String, type$.Uri);
+ },
+ JSStackTraceMapper: function JSStackTraceMapper(t0, t1, t2, t3) {
+ var _ = this;
+ _._mapping = null;
+ _._packageResolver = t0;
+ _._sdkRoot = t1;
+ _._mapContents = t2;
+ _._mapUrl = t3;
+ },
+ JSStackTraceMapper__deserializePackageConfigMap_closure: function JSStackTraceMapper__deserializePackageConfigMap_closure() {
+ }
+ },
+ L = {StreamGroup: function StreamGroup(t0, t1, t2) {
+ var _ = this;
+ _._stream_group$_controller = null;
+ _._stream_group$_closed = false;
+ _._stream_group$_state = t0;
+ _._stream_group$_subscriptions = t1;
+ _.$ti = t2;
+ }, StreamGroup_add_closure: function StreamGroup_add_closure() {
+ }, StreamGroup_add_closure0: function StreamGroup_add_closure0(t0, t1) {
+ this.$this = t0;
+ this.stream = t1;
+ }, StreamGroup__onListen_closure: function StreamGroup__onListen_closure(t0) {
+ this.$this = t0;
+ }, StreamGroup__onCancelBroadcast_closure: function StreamGroup__onCancelBroadcast_closure(t0) {
+ this.$this = t0;
+ }, StreamGroup__listenToStream_closure: function StreamGroup__listenToStream_closure(t0, t1) {
+ this.$this = t0;
+ this.stream = t1;
+ }, _StreamGroupState: function _StreamGroupState(t0) {
+ this.name = t0;
+ }, Token: function Token(t0, t1) {
+ this.type = t0;
+ this.span = t1;
+ }, IdentifierToken: function IdentifierToken(t0, t1) {
+ this.span = t0;
+ this.name = t1;
+ }, TokenType: function TokenType(t0) {
+ this.name = t0;
+ },
+ UnmodifiableSetView$: function(setBase, $E) {
+ return new L.UnmodifiableSetView(setBase, $E._eval$1("UnmodifiableSetView<0>"));
+ },
+ UnmodifiableSetView: function UnmodifiableSetView(t0, t1) {
+ this._base = t0;
+ this.$ti = t1;
+ },
+ UnmodifiableSetMixin: function UnmodifiableSetMixin() {
+ },
+ _UnmodifiableSetView_DelegatingSet_UnmodifiableSetMixin: function _UnmodifiableSetView_DelegatingSet_UnmodifiableSetMixin() {
+ },
+ WindowsStyle: function WindowsStyle(t0, t1, t2, t3) {
+ var _ = this;
+ _.separatorPattern = t0;
+ _.needsSeparatorPattern = t1;
+ _.rootPattern = t2;
+ _.relativeRootPattern = t3;
+ },
+ WindowsStyle_absolutePathToUri_closure: function WindowsStyle_absolutePathToUri_closure() {
+ },
+ decodeVlq: function(chars) {
+ var t1, t2, result, $stop, shift, t3, char, digit, result0, _null = null;
+ for (t1 = chars._parser$_length, t2 = chars._internal, result = 0, $stop = false, shift = 0; !$stop;) {
+ t3 = ++chars.index;
+ if (t3 >= t1)
+ throw H.wrapException(P.StateError$("incomplete VLQ value"));
+ if (t3 >= 0 && true) {
+ if (t3 < 0 || t3 >= t2.length)
+ return H.ioore(t2, t3);
+ char = t2[t3];
+ } else
+ char = _null;
+ t3 = $.$get$_digits();
+ if (!t3.containsKey$1(char))
+ throw H.wrapException(P.FormatException$("invalid character in VLQ encoding: " + H.S(char), _null, _null));
+ digit = t3.$index(0, char);
+ if (typeof digit !== "number")
+ return digit.$and();
+ $stop = (digit & 32) === 0;
+ result += C.JSInt_methods._shlPositive$1(digit & 31, shift);
+ shift += 5;
+ }
+ result0 = result >>> 1;
+ result = (result & 1) === 1 ? -result0 : result0;
+ if (result < $.$get$MIN_INT32() || result > $.$get$MAX_INT32())
+ throw H.wrapException(P.FormatException$("expected an encoded 32 bit int, but we got: " + result, _null, _null));
+ return result;
+ },
+ closure: function closure() {
+ },
+ internalBootstrapBrowserTest: function(getMain) {
+ var t2,
+ channel = S.RemoteListener_start(getMain, new L.internalBootstrapBrowserTest_closure(), false),
+ t1 = N.postMessageChannel();
+ t1.$ti._eval$1("StreamChannel<1>")._check(channel);
+ t1.get$stream(t1).pipe$1(channel._sink);
+ t2 = channel._streamController;
+ t2.toString;
+ new P._ControllerStream(t2, H._instanceType(t2)._eval$1("_ControllerStream<1>")).pipe$1(t1.get$sink());
+ },
+ internalBootstrapBrowserTest_closure: function internalBootstrapBrowserTest_closure() {
+ }
+ },
+ G = {StreamQueue: function StreamQueue(t0, t1, t2, t3) {
+ var _ = this;
+ _._stream_queue$_source = t0;
+ _._stream_queue$_subscription = null;
+ _._isClosed = _._isDone = false;
+ _._eventsReceived = 0;
+ _._eventQueue = t1;
+ _._requestQueue = t2;
+ _.$ti = t3;
+ }, StreamQueue__ensureListening_closure: function StreamQueue__ensureListening_closure(t0) {
+ this.$this = t0;
+ }, StreamQueue__ensureListening_closure1: function StreamQueue__ensureListening_closure1(t0) {
+ this.$this = t0;
+ }, StreamQueue__ensureListening_closure0: function StreamQueue__ensureListening_closure0(t0) {
+ this.$this = t0;
+ }, _EventRequest: function _EventRequest() {
+ }, _NextRequest: function _NextRequest(t0, t1) {
+ this._completer = t0;
+ this.$ti = t1;
+ }, _RestRequest: function _RestRequest(t0, t1, t2) {
+ this._completer = t0;
+ this._streamQueue = t1;
+ this.$ti = t2;
+ }, Parser: function Parser(t0) {
+ this._parser0$_scanner = t0;
+ }, Matcher: function Matcher() {
+ }, SourceMapSpan: function SourceMapSpan(t0, t1, t2, t3) {
+ var _ = this;
+ _.isIdentifier = t0;
+ _.start = t1;
+ _.end = t2;
+ _.text = t3;
+ },
+ SourceSpanFormatException$: function(message, span, _source) {
+ return new G.SourceSpanFormatException(message, span);
+ },
+ SourceSpanException: function SourceSpanException() {
+ },
+ SourceSpanFormatException: function SourceSpanFormatException(t0, t1) {
+ this._span_exception$_message = t0;
+ this._span_exception$_span = t1;
+ },
+ State: function State(t0, t1) {
+ this.status = t0;
+ this.result = t1;
+ },
+ Status: function Status(t0) {
+ this.name = t0;
+ },
+ Result0: function Result0(t0) {
+ this.name = t0;
+ },
+ expect: function(actual, matcher, reason) {
+ G._expect(true, matcher, null, reason, null, false);
+ },
+ _expect: function(actual, matcher, formatter, reason, skip, verbose) {
+ var matchState, e, trace, exception,
+ t1 = type$.Invoker;
+ if (t1._as($.Zone__current.$index(0, C.Symbol_cQL)) == null)
+ throw H.wrapException(P.StateError$("expect() may only be called within a test."));
+ t1 = t1._as($.Zone__current.$index(0, C.Symbol_cQL));
+ if (H.boolConversionCheck(H._asBoolNullable($.Zone__current.$index(0, t1._closableKey))) && t1._onCloseCompleter.future._state !== 0)
+ throw H.wrapException(K.ClosedException$());
+ matcher = M.wrapMatcher(matcher);
+ t1 = type$.dynamic;
+ matchState = P.LinkedHashMap_LinkedHashMap$_empty(t1, t1);
+ try {
+ if (matcher.matches$2(0, true, matchState)) {
+ t1 = P.Future_Future$sync(new G._expect_closure(), t1);
+ return t1;
+ }
+ t1 = reason;
+ } catch (exception) {
+ e = H.unwrapException(exception);
+ trace = H.getTraceFromException(exception);
+ t1 = reason == null ? H.S(e) + " at " + H.S(trace) : reason;
+ }
+ G.fail(new G._expect_closure0().call$5(true, matcher, t1, matchState, false));
+ },
+ fail: function(message) {
+ return H.throwExpression(new G.TestFailure(message));
+ },
+ formatFailure: function(expected, actual, which, reason) {
+ var t2,
+ t1 = new E.StringDescription(new P.StringBuffer("")).addDescriptionOf$1(expected)._out._contents;
+ t1 = B.indent(t1.charCodeAt(0) == 0 ? t1 : t1, "Expected: ") + "\n";
+ t2 = new E.StringDescription(new P.StringBuffer("")).addDescriptionOf$1(true)._out._contents;
+ t2 = t1 + (B.indent(t2.charCodeAt(0) == 0 ? t2 : t2, " Actual: ") + "\n");
+ t1 = which.length !== 0 ? t2 + (B.indent(which, " Which: ") + "\n") : t2;
+ if (reason != null)
+ t1 += reason + "\n";
+ return t1.charCodeAt(0) == 0 ? t1 : t1;
+ },
+ TestFailure: function TestFailure(t0) {
+ this.message = t0;
+ },
+ _expect_closure0: function _expect_closure0() {
+ },
+ _expect_closure: function _expect_closure() {
+ },
+ method1: function() {
+ return $.x = $.x + 1;
+ },
+ method2: function() {
+ return $.x = $.x + 1;
+ },
+ main0: function() {
+ R.group("a group", new G.main_closure0());
+ },
+ main_closure0: function main_closure0() {
+ },
+ main__closure: function main__closure() {
+ }
+ },
+ T = {StreamSinkCompleter: function StreamSinkCompleter(t0, t1) {
+ this.sink = t0;
+ this.$ti = t1;
+ }, _CompleterSink: function _CompleterSink(t0) {
+ var _ = this;
+ _._destinationSink = _._stream_sink_completer$_doneCompleter = _._stream_sink_completer$_controller = null;
+ _.$ti = t0;
+ }, _CompleterSink__setDestinationSink_closure: function _CompleterSink__setDestinationSink_closure() {
+ }, SubscriptionStream: function SubscriptionStream(t0, t1) {
+ this._subscription_stream$_source = t0;
+ this.$ti = t1;
+ }, _CancelOnErrorSubscriptionWrapper: function _CancelOnErrorSubscriptionWrapper(t0, t1) {
+ this._stream_subscription$_source = t0;
+ this.$ti = t1;
+ }, _CancelOnErrorSubscriptionWrapper_onError_closure: function _CancelOnErrorSubscriptionWrapper_onError_closure(t0, t1) {
+ this.$this = t0;
+ this.handleError = t1;
+ }, _CancelOnErrorSubscriptionWrapper_onError__closure: function _CancelOnErrorSubscriptionWrapper_onError__closure(t0, t1, t2) {
+ this.handleError = t0;
+ this.error = t1;
+ this.stackTrace = t2;
+ }, Evaluator: function Evaluator(t0) {
+ this._semantics = t0;
+ },
+ parseJsonExtended: function(json, mapUrl, otherMaps) {
+ if (type$.List_dynamic._is(json))
+ return T.MappingBundle$fromJson(json, H._checkStringNullable(mapUrl));
+ return T.parseJson(type$.Map_dynamic_dynamic._as(json), null, null);
+ },
+ parseJson: function(map, mapUrl, otherMaps) {
+ var _s8_ = "sections";
+ if (!J.$eq$(map.$index(0, "version"), 3))
+ throw H.wrapException(P.ArgumentError$("unexpected source map version: " + H.S(map.$index(0, "version")) + ". Only version 3 is supported."));
+ if (map.containsKey$1(_s8_)) {
+ if (map.containsKey$1("mappings") || map.containsKey$1("sources") || map.containsKey$1("names"))
+ throw H.wrapException(P.FormatException$('map containing "sections" cannot contain "mappings", "sources", or "names".', null, null));
+ return T.MultiSectionMapping$fromJson(type$.List_dynamic._check(map.$index(0, _s8_)), otherMaps, mapUrl);
+ }
+ return T.SingleMapping$fromJson(map, mapUrl);
+ },
+ MultiSectionMapping$fromJson: function(sections, otherMaps, mapUrl) {
+ var t1 = type$.JSArray_int;
+ t1 = new T.MultiSectionMapping(H.setRuntimeTypeInfo([], t1), H.setRuntimeTypeInfo([], t1), H.setRuntimeTypeInfo([], type$.JSArray_Mapping));
+ t1.MultiSectionMapping$fromJson$3$mapUrl(sections, otherMaps, mapUrl);
+ return t1;
+ },
+ MappingBundle$fromJson: function(json, mapUrl) {
+ var t1 = new T.MappingBundle(P.LinkedHashMap_LinkedHashMap$_empty(type$.String, type$.SingleMapping));
+ t1.MappingBundle$fromJson$2$mapUrl(json, mapUrl);
+ return t1;
+ },
+ SingleMapping$fromJson: function(map, mapUrl) {
+ var t5, t6, t7, t8,
+ t1 = H._checkStringNullable(map.$index(0, "file")),
+ t2 = type$.Iterable_dynamic,
+ t3 = type$.String,
+ t4 = P.List_List$from(t2._check(map.$index(0, "sources")), true, t3);
+ t2 = P.List_List$from(t2._check(map.$index(0, "names")), true, t3);
+ t5 = H._checkIntNullable(J.get$length$asx(map.$index(0, "sources")));
+ if (typeof t5 !== "number")
+ return H.iae(t5);
+ t5 = new Array(t5);
+ t5.fixed$length = Array;
+ t5 = H.setRuntimeTypeInfo(t5, type$.JSArray_SourceFile);
+ t6 = H._checkStringNullable(map.$index(0, "sourceRoot"));
+ t7 = H.setRuntimeTypeInfo([], type$.JSArray_TargetLineEntry);
+ t8 = typeof mapUrl == "string" ? P.Uri_parse(mapUrl) : mapUrl;
+ t3 = new T.SingleMapping(t4, t2, t5, t7, t1, t6, type$.Uri._check(t8), P.LinkedHashMap_LinkedHashMap$_empty(t3, type$.dynamic));
+ t3.SingleMapping$fromJson$2$mapUrl(map, mapUrl);
+ return t3;
+ },
+ Mapping: function Mapping() {
+ },
+ MultiSectionMapping: function MultiSectionMapping(t0, t1, t2) {
+ this._lineStart = t0;
+ this._columnStart = t1;
+ this._maps = t2;
+ },
+ MappingBundle: function MappingBundle(t0) {
+ this._mappings = t0;
+ },
+ SingleMapping: function SingleMapping(t0, t1, t2, t3, t4, t5, t6, t7) {
+ var _ = this;
+ _.urls = t0;
+ _.names = t1;
+ _.files = t2;
+ _.lines = t3;
+ _.targetUrl = t4;
+ _.sourceRoot = t5;
+ _._parser$_mapUrl = t6;
+ _.extensions = t7;
+ },
+ SingleMapping$fromJson_closure: function SingleMapping$fromJson_closure(t0) {
+ this.$this = t0;
+ },
+ SingleMapping__findLine_closure: function SingleMapping__findLine_closure(t0) {
+ this.line = t0;
+ },
+ SingleMapping__findColumn_closure: function SingleMapping__findColumn_closure(t0) {
+ this.column = t0;
+ },
+ TargetLineEntry: function TargetLineEntry(t0, t1) {
+ this.line = t0;
+ this.entries = t1;
+ },
+ TargetEntry: function TargetEntry(t0, t1, t2, t3, t4) {
+ var _ = this;
+ _.column = t0;
+ _.sourceUrlId = t1;
+ _.sourceLine = t2;
+ _.sourceColumn = t3;
+ _.sourceNameId = t4;
+ },
+ _MappingTokenizer: function _MappingTokenizer(t0, t1) {
+ this._internal = t0;
+ this._parser$_length = t1;
+ this.index = -1;
+ },
+ _TokenKind: function _TokenKind(t0, t1, t2) {
+ this.isNewLine = t0;
+ this.isNewSegment = t1;
+ this.isEof = t2;
+ },
+ LazyTrace: function LazyTrace(t0) {
+ this._lazy_trace$_thunk = t0;
+ this._lazy_trace$_inner = null;
+ },
+ LazyTrace_foldFrames_closure: function LazyTrace_foldFrames_closure(t0, t1, t2) {
+ this.$this = t0;
+ this.predicate = t1;
+ this.terse = t2;
+ },
+ RuntimeSelection: function RuntimeSelection() {
+ }
+ },
+ X = {BooleanSelector: function BooleanSelector() {
+ }, All: function All() {
+ },
+ ParsedPath_ParsedPath$parse: function(path, style) {
+ var t1, parts, separators, start, i,
+ root = style.getRoot$1(path);
+ style.isRootRelative$1(path);
+ if (root != null)
+ path = J.substring$1$s(path, root.length);
+ t1 = type$.JSArray_String;
+ parts = H.setRuntimeTypeInfo([], t1);
+ separators = H.setRuntimeTypeInfo([], t1);
+ t1 = path.length;
+ if (t1 !== 0 && style.isSeparator$1(C.JSString_methods._codeUnitAt$1(path, 0))) {
+ if (0 >= t1)
+ return H.ioore(path, 0);
+ C.JSArray_methods.add$1(separators, path[0]);
+ start = 1;
+ } else {
+ C.JSArray_methods.add$1(separators, "");
+ start = 0;
+ }
+ for (i = start; i < t1; ++i)
+ if (style.isSeparator$1(C.JSString_methods._codeUnitAt$1(path, i))) {
+ C.JSArray_methods.add$1(parts, C.JSString_methods.substring$2(path, start, i));
+ C.JSArray_methods.add$1(separators, path[i]);
+ start = i + 1;
+ }
+ if (start < t1) {
+ C.JSArray_methods.add$1(parts, C.JSString_methods.substring$1(path, start));
+ C.JSArray_methods.add$1(separators, "");
+ }
+ return new X.ParsedPath(style, root, parts, separators);
+ },
+ ParsedPath: function ParsedPath(t0, t1, t2, t3) {
+ var _ = this;
+ _.style = t0;
+ _.root = t1;
+ _.parts = t2;
+ _.separators = t3;
+ },
+ ParsedPath_normalize_closure: function ParsedPath_normalize_closure(t0) {
+ this.$this = t0;
+ },
+ PathException$: function(message) {
+ return new X.PathException(message);
+ },
+ PathException: function PathException(t0) {
+ this.message = t0;
+ },
+ SourceSpanWithContext$: function(start, end, text, _context) {
+ var t1 = new X.SourceSpanWithContext(_context, start, end, text);
+ t1.SourceSpanBase$3(start, end, text);
+ if (!C.JSString_methods.contains$1(_context, text))
+ H.throwExpression(P.ArgumentError$('The context line "' + _context + '" must contain "' + text + '".'));
+ if (B.findLineStart(_context, text, start.get$column()) == null)
+ H.throwExpression(P.ArgumentError$('The span text "' + text + '" must start at column ' + (start.get$column() + 1) + ' in a line within "' + _context + '".'));
+ return t1;
+ },
+ SourceSpanWithContext: function SourceSpanWithContext(t0, t1, t2, t3) {
+ var _ = this;
+ _._context = t0;
+ _.start = t1;
+ _.end = t2;
+ _.text = t3;
+ },
+ LazyChain: function LazyChain(t0) {
+ this._thunk = t0;
+ this._lazy_chain$_inner = null;
+ },
+ LazyChain_foldFrames_closure: function LazyChain_foldFrames_closure(t0, t1, t2) {
+ this.$this = t0;
+ this.predicate = t1;
+ this.terse = t2;
+ },
+ LazyChain_toTrace_closure: function LazyChain_toTrace_closure(t0) {
+ this.$this = t0;
+ },
+ StringScanner: function StringScanner() {
+ },
+ Declarer$: function(collectTraces, metadata, noRetry, platformVariables) {
+ var _null = null,
+ t1 = metadata == null ? O.Metadata_Metadata(_null, _null, _null, _null, _null, _null, _null, _null, _null, _null) : metadata,
+ t2 = platformVariables == null ? C.C_EmptyUnmodifiableSet : platformVariables,
+ t3 = type$.JSArray_of_dynamic_Function,
+ t4 = type$.JSArray_GroupEntry;
+ return new X.Declarer(_null, _null, t1, t2, _null, collectTraces, noRetry, H.setRuntimeTypeInfo([], t3), H.setRuntimeTypeInfo([], t3), H.setRuntimeTypeInfo([], t3), new R.Timeout(P.Duration$(0, 12), _null), H.setRuntimeTypeInfo([], t3), H.setRuntimeTypeInfo([], t4), H.setRuntimeTypeInfo([], t4));
+ },
+ Declarer: function Declarer(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13) {
+ var _ = this;
+ _._declarer$_parent = t0;
+ _._declarer$_name = t1;
+ _._metadata = t2;
+ _._platformVariables = t3;
+ _._declarer$_trace = t4;
+ _._collectTraces = t5;
+ _._noRetry = t6;
+ _._setUps = t7;
+ _._tearDowns = t8;
+ _._setUpAlls = t9;
+ _._timeout = t10;
+ _._tearDownAlls = t11;
+ _._entries = t12;
+ _._built = false;
+ _._soloEntries = t13;
+ },
+ Declarer_test_closure: function Declarer_test_closure(t0, t1) {
+ this.$this = t0;
+ this.body = t1;
+ },
+ Declarer_test__closure: function Declarer_test__closure(t0, t1) {
+ this.$this = t0;
+ this.body = t1;
+ },
+ Declarer_test___closure: function Declarer_test___closure(t0, t1) {
+ this.$this = t0;
+ this.body = t1;
+ },
+ Declarer_group_closure: function Declarer_group_closure(t0) {
+ this.body = t0;
+ },
+ Declarer_build_closure: function Declarer_build_closure(t0) {
+ this.$this = t0;
+ },
+ Declarer__runSetUps_closure: function Declarer__runSetUps_closure() {
+ },
+ Declarer__tearDownAll_closure: function Declarer__tearDownAll_closure(t0) {
+ this.$this = t0;
+ },
+ Declarer__tearDownAll__closure: function Declarer__tearDownAll__closure(t0) {
+ this.$this = t0;
+ },
+ Declarer__tearDownAll___closure: function Declarer__tearDownAll___closure(t0) {
+ this.$this = t0;
+ },
+ PrintSink: function PrintSink(t0) {
+ this._print_sink$_buffer = t0;
+ }
+ },
+ U = {
+ _expandSafe: function(start, end) {
+ if (start == null || end == null)
+ return null;
+ if (start.file !== end.file)
+ return null;
+ return start.expand$1(0, end);
+ },
+ VariableNode: function VariableNode(t0, t1) {
+ this.span = t0;
+ this.name = t1;
+ },
+ NotNode: function NotNode(t0, t1) {
+ this.span = t0;
+ this.child = t1;
+ },
+ OrNode: function OrNode(t0, t1) {
+ this.left = t0;
+ this.right = t1;
+ },
+ AndNode: function AndNode(t0, t1) {
+ this.left = t0;
+ this.right = t1;
+ },
+ ConditionalNode: function ConditionalNode(t0, t1, t2) {
+ this.condition = t0;
+ this.whenTrue = t1;
+ this.whenFalse = t2;
+ },
+ Highlighter__normalizeNewlines: function(span) {
+ var t1, endOffset, i, t2, t3, t4,
+ text = span.get$text();
+ if (!C.JSString_methods.contains$1(text, "\r\n"))
+ return span;
+ t1 = span.get$end();
+ endOffset = t1.get$offset(t1);
+ for (t1 = text.length - 1, i = 0; i < t1; ++i)
+ if (C.JSString_methods._codeUnitAt$1(text, i) === 13 && C.JSString_methods._codeUnitAt$1(text, i + 1) === 10)
+ --endOffset;
+ t1 = span.get$start();
+ t2 = span.get$sourceUrl();
+ t3 = span.get$end().get$line();
+ t2 = V.SourceLocation$(endOffset, span.get$end().get$column(), t3, t2);
+ t3 = H.stringReplaceAllUnchecked(text, "\r\n", "\n");
+ t4 = span.get$context();
+ return X.SourceSpanWithContext$(t1, t2, t3, H.stringReplaceAllUnchecked(t4, "\r\n", "\n"));
+ },
+ Highlighter__normalizeTrailingNewline: function(span) {
+ var context, text, start, end, t1, t2, t3;
+ if (!C.JSString_methods.endsWith$1(span.get$context(), "\n"))
+ return span;
+ if (C.JSString_methods.endsWith$1(span.get$text(), "\n\n"))
+ return span;
+ context = C.JSString_methods.substring$2(span.get$context(), 0, span.get$context().length - 1);
+ text = span.get$text();
+ start = span.get$start();
+ end = span.get$end();
+ if (C.JSString_methods.endsWith$1(span.get$text(), "\n")) {
+ t1 = B.findLineStart(span.get$context(), span.get$text(), span.get$start().get$column());
+ t2 = span.get$start().get$column();
+ if (typeof t1 !== "number")
+ return t1.$add();
+ t2 = t1 + t2 + span.get$length(span) === span.get$context().length;
+ t1 = t2;
+ } else
+ t1 = false;
+ if (t1) {
+ text = C.JSString_methods.substring$2(span.get$text(), 0, span.get$text().length - 1);
+ t1 = span.get$end();
+ t1 = t1.get$offset(t1);
+ t2 = span.get$sourceUrl();
+ t3 = span.get$end().get$line();
+ if (typeof t3 !== "number")
+ return t3.$sub();
+ end = V.SourceLocation$(t1 - 1, U.Highlighter__lastLineLength(text), t3 - 1, t2);
+ t1 = span.get$start();
+ t1 = t1.get$offset(t1);
+ t2 = span.get$end();
+ start = t1 === t2.get$offset(t2) ? end : span.get$start();
+ }
+ return X.SourceSpanWithContext$(start, end, text, context);
+ },
+ Highlighter__normalizeEndOfLine: function(span) {
+ var text, t1, t2, t3, t4;
+ if (span.get$end().get$column() !== 0)
+ return span;
+ if (span.get$end().get$line() == span.get$start().get$line())
+ return span;
+ text = C.JSString_methods.substring$2(span.get$text(), 0, span.get$text().length - 1);
+ t1 = span.get$start();
+ t2 = span.get$end();
+ t2 = t2.get$offset(t2);
+ t3 = span.get$sourceUrl();
+ t4 = span.get$end().get$line();
+ if (typeof t4 !== "number")
+ return t4.$sub();
+ return X.SourceSpanWithContext$(t1, V.SourceLocation$(t2 - 1, U.Highlighter__lastLineLength(text), t4 - 1, t3), text, span.get$context());
+ },
+ Highlighter__lastLineLength: function(text) {
+ var t1 = text.length;
+ if (t1 === 0)
+ return 0;
+ if (C.JSString_methods.codeUnitAt$1(text, t1 - 1) === 10)
+ return t1 === 1 ? 0 : t1 - C.JSString_methods.lastIndexOf$2(text, "\n", t1 - 2) - 1;
+ else
+ return t1 - C.JSString_methods.lastIndexOf$1(text, "\n") - 1;
+ },
+ Highlighter: function Highlighter(t0, t1, t2, t3, t4) {
+ var _ = this;
+ _._span = t0;
+ _._color = t1;
+ _._multiline = t2;
+ _._paddingBeforeSidebar = t3;
+ _._highlighter$_buffer = t4;
+ },
+ Highlighter__writeFirstLine_closure: function Highlighter__writeFirstLine_closure(t0, t1) {
+ this.$this = t0;
+ this.line = t1;
+ },
+ Highlighter__writeFirstLine_closure0: function Highlighter__writeFirstLine_closure0(t0, t1) {
+ this.$this = t0;
+ this.textInside = t1;
+ },
+ Highlighter__writeFirstLine_closure1: function Highlighter__writeFirstLine_closure1(t0, t1) {
+ this._box_0 = t0;
+ this.$this = t1;
+ },
+ Highlighter__writeFirstLine_closure2: function Highlighter__writeFirstLine_closure2(t0, t1) {
+ this._box_0 = t0;
+ this.$this = t1;
+ },
+ Highlighter__writeIntermediateLines_closure: function Highlighter__writeIntermediateLines_closure(t0, t1) {
+ this.$this = t0;
+ this.line = t1;
+ },
+ Highlighter__writeLastLine_closure: function Highlighter__writeLastLine_closure(t0, t1) {
+ this.$this = t0;
+ this.line = t1;
+ },
+ Highlighter__writeLastLine_closure0: function Highlighter__writeLastLine_closure0(t0, t1) {
+ this.$this = t0;
+ this.textInside = t1;
+ },
+ Highlighter__writeLastLine_closure1: function Highlighter__writeLastLine_closure1(t0, t1) {
+ this._box_0 = t0;
+ this.$this = t1;
+ },
+ Highlighter__writeSidebar_closure: function Highlighter__writeSidebar_closure(t0, t1, t2) {
+ this.$this = t0;
+ this.line = t1;
+ this.end = t2;
+ },
+ Chain_capture: function(callback, errorZone, when, $T) {
+ var t1, spec, _null = null;
+ if (!when)
+ return P.runZoned(callback, _null, _null, _null, $T);
+ if (typeof WeakMap == "function")
+ t1 = new WeakMap();
+ else {
+ t1 = $.Expando__keyCount;
+ $.Expando__keyCount = t1 + 1;
+ t1 = "expando$key$" + t1;
+ }
+ spec = new O.StackZoneSpecification(new P.Expando(t1, "stack chains", type$.Expando__Node), _null, false);
+ t1 = type$.dynamic;
+ return P.runZoned(new U.Chain_capture_closure(callback, $T), _null, P._ZoneSpecification$(_null, _null, spec.get$_stack_zone_specification$_errorCallback(), _null, _null, _null, spec.get$_stack_zone_specification$_registerBinaryCallback(), spec.get$_stack_zone_specification$_registerCallback(), spec.get$_stack_zone_specification$_registerUnaryCallback(), _null, _null, _null, _null), P.LinkedHashMap_LinkedHashMap$_literal([$.$get$_specKey(), spec, $.$get$StackZoneSpecification_disableKey(), false], t1, t1), $T);
+ },
+ Chain_Chain$current: function() {
+ var t1 = $.Zone__current,
+ t2 = $.$get$_specKey(),
+ t3 = type$.StackZoneSpecification;
+ if (t3._check(t1.$index(0, t2)) != null) {
+ t1 = t3._check($.Zone__current.$index(0, t2));
+ t2 = t1._currentTrace$1(3);
+ t1 = t1._currentNode;
+ return new O._Node(Y.Trace_Trace$from(t2), t1).toChain$0();
+ }
+ return new X.LazyChain(new U.Chain_Chain$current_closure(U.Chain_Chain$forTrace(P.StackTrace_current()), 0));
+ },
+ Chain_Chain$forTrace: function(trace) {
+ var t1, t2, t3;
+ if (type$.Chain._is(trace))
+ return trace;
+ t1 = $.Zone__current;
+ t2 = $.$get$_specKey();
+ t3 = type$.StackZoneSpecification;
+ if (t3._check(t1.$index(0, t2)) != null)
+ return t3._check($.Zone__current.$index(0, t2)).chainFor$1(trace);
+ t1 = type$.Trace;
+ if (t1._is(trace))
+ return new U.Chain(P.List_List$unmodifiable(H.setRuntimeTypeInfo([trace], type$.JSArray_Trace), t1));
+ return new X.LazyChain(new U.Chain_Chain$forTrace_closure(trace));
+ },
+ Chain_Chain$parse: function(chain) {
+ var _s26_ = "<asynchronous suspension>\n",
+ _s51_ = "===== asynchronous gap ===========================\n";
+ if (chain.length === 0)
+ return new U.Chain(P.List_List$unmodifiable(H.setRuntimeTypeInfo([], type$.JSArray_Trace), type$.Trace));
+ if (C.JSString_methods.contains$1(chain, _s26_))
+ return new U.Chain(P.List_List$unmodifiable(new H.MappedListIterable(H.setRuntimeTypeInfo(chain.split(_s26_), type$.JSArray_String), type$.Trace_Function_String._check(new U.Chain_Chain$parse_closure()), type$.MappedListIterable_String_Trace), type$.Trace));
+ if (!C.JSString_methods.contains$1(chain, _s51_))
+ return new U.Chain(P.List_List$unmodifiable(H.setRuntimeTypeInfo([Y.Trace_Trace$parse(chain)], type$.JSArray_Trace), type$.Trace));
+ return new U.Chain(P.List_List$unmodifiable(new H.MappedListIterable(H.setRuntimeTypeInfo(chain.split(_s51_), type$.JSArray_String), type$.Trace_Function_String._check(new U.Chain_Chain$parse_closure0()), type$.MappedListIterable_String_Trace), type$.Trace));
+ },
+ Chain: function Chain(t0) {
+ this.traces = t0;
+ },
+ Chain_capture_closure: function Chain_capture_closure(t0, t1) {
+ this.callback = t0;
+ this.T = t1;
+ },
+ Chain_Chain$current_closure: function Chain_Chain$current_closure(t0, t1) {
+ this.chain = t0;
+ this.level = t1;
+ },
+ Chain_Chain$forTrace_closure: function Chain_Chain$forTrace_closure(t0) {
+ this.trace = t0;
+ },
+ Chain_Chain$parse_closure: function Chain_Chain$parse_closure() {
+ },
+ Chain_Chain$parse_closure0: function Chain_Chain$parse_closure0() {
+ },
+ Chain_foldFrames_closure: function Chain_foldFrames_closure(t0, t1) {
+ this.predicate = t0;
+ this.terse = t1;
+ },
+ Chain_foldFrames_closure0: function Chain_foldFrames_closure0(t0) {
+ this.terse = t0;
+ },
+ Chain_toTrace_closure: function Chain_toTrace_closure() {
+ },
+ Chain_toString_closure0: function Chain_toString_closure0() {
+ },
+ Chain_toString__closure0: function Chain_toString__closure0() {
+ },
+ Chain_toString_closure: function Chain_toString_closure(t0) {
+ this.longest = t0;
+ },
+ Chain_toString__closure: function Chain_toString__closure(t0) {
+ this.longest = t0;
+ },
+ Invoker_guard: function(callback, $T) {
+ var _null = null;
+ return P.runZoned(callback, _null, P._ZoneSpecification$(_null, _null, _null, _null, new U.Invoker_guard_closure(), _null, _null, _null, _null, _null, _null, _null, _null), _null, $T);
+ },
+ LocalTest: function LocalTest(t0, t1, t2, t3, t4, t5) {
+ var _ = this;
+ _.name = t0;
+ _.metadata = t1;
+ _.trace = t2;
+ _.isScaffoldAll = t3;
+ _._body = t4;
+ _._guarded = t5;
+ },
+ Invoker: function Invoker(t0, t1, t2, t3, t4, t5, t6) {
+ var _ = this;
+ _._invoker$_controller = null;
+ _._guarded = t0;
+ _._closableKey = t1;
+ _._onCloseCompleter = t2;
+ _._outstandingCallbackZones = t3;
+ _._counterKey = t4;
+ _._runCount = 0;
+ _._timeoutTimer = _._invokerZone = null;
+ _._invoker$_tearDowns = t5;
+ _._printsOnFailure = t6;
+ },
+ Invoker_guard_closure: function Invoker_guard_closure() {
+ },
+ Invoker_guard__closure: function Invoker_guard__closure(t0, t1, t2, t3) {
+ var _ = this;
+ _.invoker = t0;
+ _.zone = t1;
+ _.error = t2;
+ _.stackTrace = t3;
+ },
+ Invoker_waitForOutstandingCallbacks_closure: function Invoker_waitForOutstandingCallbacks_closure(t0, t1, t2, t3) {
+ var _ = this;
+ _._box_0 = t0;
+ _.$this = t1;
+ _.fn = t2;
+ _.counter = t3;
+ },
+ Invoker_waitForOutstandingCallbacks_closure0: function Invoker_waitForOutstandingCallbacks_closure0(t0, t1) {
+ this._box_0 = t0;
+ this.$this = t1;
+ },
+ Invoker_heartbeat_message: function Invoker_heartbeat_message(t0) {
+ this.timeout = t0;
+ },
+ Invoker_heartbeat_closure: function Invoker_heartbeat_closure(t0, t1, t2) {
+ this.$this = t0;
+ this.message = t1;
+ this.timeout = t2;
+ },
+ Invoker_heartbeat__closure: function Invoker_heartbeat__closure(t0, t1, t2) {
+ this.$this = t0;
+ this.message = t1;
+ this.timeout = t2;
+ },
+ Invoker__handleError_closure: function Invoker__handleError_closure(t0) {
+ this._box_0 = t0;
+ },
+ Invoker__handleError_closure0: function Invoker__handleError_closure0(t0) {
+ this.$this = t0;
+ },
+ Invoker__onRun_closure: function Invoker__onRun_closure(t0, t1) {
+ this.$this = t0;
+ this.outstandingCallbacksForBody = t1;
+ },
+ Invoker__onRun__closure: function Invoker__onRun__closure(t0, t1) {
+ this.$this = t0;
+ this.outstandingCallbacksForBody = t1;
+ },
+ Invoker__onRun___closure: function Invoker__onRun___closure(t0) {
+ this.$this = t0;
+ },
+ Invoker__onRun____closure: function Invoker__onRun____closure(t0) {
+ this.$this = t0;
+ },
+ Invoker__onRun___closure0: function Invoker__onRun___closure0(t0) {
+ this.$this = t0;
+ },
+ _AsyncCounter: function _AsyncCounter(t0) {
+ this._count = 1;
+ this._invoker$_completer = t0;
+ },
+ StackTraceFormatter: function StackTraceFormatter(t0, t1) {
+ this._mapper = null;
+ this._except = t0;
+ this._only = t1;
+ },
+ StackTraceFormatter_formatStackTrace_closure: function StackTraceFormatter_formatStackTrace_closure(t0) {
+ this.$this = t0;
+ },
+ Suite__filterGroup: function(group, platform) {
+ var t1, _null = null,
+ filtered = group.forPlatform$1(platform);
+ if (filtered != null)
+ return filtered;
+ t1 = P.List_List$unmodifiable(H.setRuntimeTypeInfo([], type$.JSArray_GroupEntry), type$.GroupEntry);
+ return new O.Group(_null, group.metadata, _null, t1, _null, _null);
+ },
+ Suite: function Suite(t0, t1, t2) {
+ this.platform = t0;
+ this.path = t1;
+ this.group = t2;
+ },
+ SuiteConfiguration__list: function(input, $T) {
+ return null;
+ },
+ SuiteConfiguration__map: function(input, $K, $V) {
+ return C.Map_empty1;
+ },
+ SuiteConfiguration: function SuiteConfiguration() {
+ },
+ RemoteException_serialize: function(error, stackTrace) {
+ var exception, supertype, t1, message = null;
+ if (typeof error == "string")
+ message = error;
+ else
+ try {
+ message = J.toString$0$(J.get$message$x(error));
+ } catch (exception) {
+ if (!type$.NoSuchMethodError._is(H.unwrapException(exception)))
+ throw exception;
+ }
+ supertype = error instanceof G.TestFailure ? "TestFailure" : null;
+ t1 = J.getInterceptor$(error);
+ return P.LinkedHashMap_LinkedHashMap$_literal(["message", message, "type", t1.get$runtimeType(error).toString$0(0), "supertype", supertype, "toString", t1.toString$0(error), "stackChain", J.toString$0$(U.Chain_Chain$forTrace(stackTrace))], type$.String, type$.dynamic);
+ }
+ },
+ R = {IntersectionSelector: function IntersectionSelector(t0, t1) {
+ this._selector1 = t0;
+ this._selector2 = t1;
+ }, StreamChannel: function StreamChannel() {
+ }, _StreamChannel: function _StreamChannel(t0, t1, t2) {
+ this.stream = t0;
+ this.sink = t1;
+ this.$ti = t2;
+ }, StreamChannelMixin: function StreamChannelMixin() {
+ }, Timeout: function Timeout(t0, t1) {
+ this.duration = t0;
+ this.scaleFactor = t1;
+ }, ExpandedReporter: function ExpandedReporter(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12) {
+ var _ = this;
+ _._expanded$_color = t0;
+ _._green = t1;
+ _._red = t2;
+ _._yellow = t3;
+ _._gray = t4;
+ _._bold = t5;
+ _._noColor = t6;
+ _._engine = t7;
+ _._printPath = t8;
+ _._printPlatform = t9;
+ _._stopwatch = t10;
+ _._lastProgressSuffix = _._lastProgressMessage = _._lastProgressFailed = _._lastProgressSkipped = _._lastProgressPassed = null;
+ _._subscriptions = t11;
+ _._expanded$_sink = t12;
+ }, ExpandedReporter__onTestStarted_closure: function ExpandedReporter__onTestStarted_closure(t0, t1) {
+ this.$this = t0;
+ this.liveTest = t1;
+ }, ExpandedReporter__onTestStarted_closure0: function ExpandedReporter__onTestStarted_closure0(t0, t1) {
+ this.$this = t0;
+ this.liveTest = t1;
+ }, ExpandedReporter__onTestStarted_closure1: function ExpandedReporter__onTestStarted_closure1(t0, t1) {
+ this.$this = t0;
+ this.liveTest = t1;
+ },
+ _declarer: function() {
+ var t1,
+ declarer = type$.Declarer._as($.Zone__current.$index(0, C.Symbol_Drw));
+ if (declarer != null)
+ return declarer;
+ t1 = $._globalDeclarer;
+ if (t1 != null)
+ return t1;
+ $._globalDeclarer = X.Declarer$(false, null, false, null);
+ P.scheduleMicrotask(new R._declarer_closure());
+ return $._globalDeclarer;
+ },
+ test: function(description, body) {
+ var _null = null;
+ R._declarer().test$9$onPlatform$retry$skip$solo$tags$testOn$timeout(description, body, _null, _null, _null, false, _null, _null, _null);
+ return;
+ },
+ group: function(description, body) {
+ var _null = null;
+ R._declarer().group$9$onPlatform$retry$skip$solo$tags$testOn$timeout(description, body, _null, _null, _null, false, _null, _null, _null);
+ return;
+ },
+ _declarer_closure: function _declarer_closure() {
+ },
+ _declarer__closure: function _declarer__closure(t0) {
+ this.engine = t0;
+ },
+ main: function() {
+ L.internalBootstrapBrowserTest(new R.main_closure());
+ },
+ main_closure: function main_closure() {
+ }
+ },
+ B = {RecursiveVisitor: function RecursiveVisitor() {
+ }, InternalStyle: function InternalStyle() {
+ },
+ StreamChannelController$: function(allowForeignErrors, sync, $T) {
+ var _null = null,
+ t1 = new B.StreamChannelController($T._eval$1("StreamChannelController<0>")),
+ localToForeignController = P.StreamController_StreamController(_null, _null, true, $T),
+ foreignToLocalController = P.StreamController_StreamController(_null, _null, true, $T),
+ t2 = H._instanceType(foreignToLocalController),
+ t3 = H._instanceType(localToForeignController);
+ t1.set$_local(K.GuaranteeChannel$(new P._ControllerStream(foreignToLocalController, t2._eval$1("_ControllerStream<1>")), new P._StreamSinkWrapper(localToForeignController, t3._eval$1("_StreamSinkWrapper<1>")), true, $T));
+ t1.set$_foreign(K.GuaranteeChannel$(new P._ControllerStream(localToForeignController, t3._eval$1("_ControllerStream<1>")), new P._StreamSinkWrapper(foreignToLocalController, t2._eval$1("_StreamSinkWrapper<1>")), allowForeignErrors, $T));
+ return t1;
+ },
+ StreamChannelController: function StreamChannelController(t0) {
+ this._foreign = this._local = null;
+ this.$ti = t0;
+ },
+ Runtime_Runtime$deserialize: function(serialized) {
+ var $parent, t1, t2, t3,
+ _s10_ = "identifier";
+ if (typeof serialized == "string")
+ return C.JSArray_methods.firstWhere$1(C.List_m7e, new B.Runtime_Runtime$deserialize_closure(serialized));
+ type$.Map_dynamic_dynamic._as(serialized);
+ $parent = serialized.$index(0, "parent");
+ if ($parent != null) {
+ t1 = H._asStringNullable(serialized.$index(0, "name"));
+ t2 = H._asStringNullable(serialized.$index(0, _s10_));
+ t3 = B.Runtime_Runtime$deserialize($parent);
+ return new B.Runtime(t1, t2, t3, t3.isDartVM, t3.isBrowser, t3.isJS, t3.isBlink, t3.isHeadless);
+ }
+ return new B.Runtime(H._asStringNullable(serialized.$index(0, "name")), H._asStringNullable(serialized.$index(0, _s10_)), null, H._asBoolNullable(serialized.$index(0, "isDartVM")), H._asBoolNullable(serialized.$index(0, "isBrowser")), H._asBoolNullable(serialized.$index(0, "isJS")), H._asBoolNullable(serialized.$index(0, "isBlink")), H._asBoolNullable(serialized.$index(0, "isHeadless")));
+ },
+ Runtime: function Runtime(t0, t1, t2, t3, t4, t5, t6, t7) {
+ var _ = this;
+ _.name = t0;
+ _.identifier = t1;
+ _.parent = t2;
+ _.isDartVM = t3;
+ _.isBrowser = t4;
+ _.isJS = t5;
+ _.isBlink = t6;
+ _.isHeadless = t7;
+ },
+ Runtime_Runtime$deserialize_closure: function Runtime_Runtime$deserialize_closure(t0) {
+ this.serialized = t0;
+ },
+ indent: function(string, first) {
+ var size = first == null ? 2 : first.length;
+ return B.prefixLines(string, C.JSString_methods.$mul(" ", size), first);
+ },
+ toSentence: function(iter) {
+ var result,
+ t1 = iter.length;
+ if (t1 === 1)
+ return J.toString$0$(C.JSArray_methods.get$first(iter));
+ result = H.SubListIterable$(iter, 0, t1 - 1, H._arrayInstanceType(iter)._precomputed1).join$1(0, ", ");
+ if (iter.length > 2)
+ result += ",";
+ return result + " and " + H.S(C.JSArray_methods.get$last(iter));
+ },
+ pluralize: function($name, number) {
+ if (number === 1)
+ return $name;
+ return $name + "s";
+ },
+ prefixLines: function(text, prefix, first) {
+ var single, lines, t1, t2;
+ if (first == null)
+ first = prefix;
+ single = first;
+ lines = H.setRuntimeTypeInfo(text.split("\n"), type$.JSArray_String);
+ if (lines.length === 1)
+ return single + text;
+ t1 = first + H.S(C.JSArray_methods.get$first(lines)) + "\n";
+ for (t2 = H.SubListIterable$(lines, 1, null, type$.String).take$1(0, lines.length - 2), t2 = new H.ListIterator(t2, t2.get$length(t2), t2.$ti._eval$1("ListIterator<ListIterable.E>")); t2.moveNext$0();)
+ t1 += prefix + H.S(t2.__internal$_current) + "\n";
+ t1 += prefix + H.S(C.JSArray_methods.get$last(lines));
+ return t1.charCodeAt(0) == 0 ? t1 : t1;
+ },
+ closure0: function closure0() {
+ },
+ LiveSuiteController$: function(_suite) {
+ var t1 = $.Zone__current,
+ t2 = H.setRuntimeTypeInfo([], type$.JSArray_dynamic),
+ t3 = $.Zone__current,
+ t4 = type$._Future_dynamic,
+ t5 = type$._AsyncCompleter_dynamic,
+ t6 = type$.LiveTest;
+ t5 = new B.LiveSuiteController(_suite, new F.FutureGroup(new P._AsyncCompleter(new P._Future(t1, type$._Future_List_dynamic), type$._AsyncCompleter_List_dynamic), t2, type$.FutureGroup_dynamic), new P._AsyncCompleter(new P._Future(t3, t4), t5), new P._SyncBroadcastStreamController(null, null, type$._SyncBroadcastStreamController_LiveTest), P.LinkedHashSet_LinkedHashSet$_empty(t6), P.LinkedHashSet_LinkedHashSet$_empty(t6), P.LinkedHashSet_LinkedHashSet$_empty(t6), new S.AsyncMemoizer(new P._AsyncCompleter(new P._Future(t3, t4), t5), type$.AsyncMemoizer_dynamic));
+ t5.LiveSuiteController$1(_suite);
+ return t5;
+ },
+ _LiveSuite: function _LiveSuite(t0) {
+ this._live_suite_controller$_controller = t0;
+ },
+ LiveSuiteController: function LiveSuiteController(t0, t1, t2, t3, t4, t5, t6, t7) {
+ var _ = this;
+ _._liveSuite = null;
+ _._live_suite_controller$_suite = t0;
+ _._onCompleteGroup = t1;
+ _._live_suite_controller$_onCloseCompleter = t2;
+ _._onTestStartedController = t3;
+ _._passed = t4;
+ _._skipped = t5;
+ _._failed = t6;
+ _._live_suite_controller$_active = null;
+ _._live_suite_controller$_closeMemo = t7;
+ },
+ LiveSuiteController_closure: function LiveSuiteController_closure(t0) {
+ this.$this = t0;
+ },
+ LiveSuiteController_closure0: function LiveSuiteController_closure0() {
+ },
+ LiveSuiteController_reportLiveTest_closure: function LiveSuiteController_reportLiveTest_closure(t0, t1, t2) {
+ this.$this = t0;
+ this.liveTest = t1;
+ this.countSuccess = t2;
+ },
+ LiveSuiteController_close_closure: function LiveSuiteController_close_closure(t0) {
+ this.$this = t0;
+ },
+ asUri: function(uri, $name) {
+ if (type$.Uri._is(uri))
+ return uri;
+ throw H.wrapException(P.ArgumentError$value(uri, $name, "Must be a String or a Uri."));
+ },
+ ensureTrailingSlash: function(uri) {
+ var t1;
+ if (uri.get$pathSegments().length === 0)
+ return uri.replace$1$path(0, "/");
+ t1 = C.JSArray_methods.get$last(uri.get$pathSegments());
+ t1.toString;
+ if (J.get$length$asx(t1) === 0)
+ return uri;
+ t1 = uri.get$pathSegments();
+ t1 = H.setRuntimeTypeInfo(t1.slice(0), H._arrayInstanceType(t1)._eval$1("JSArray<1>"));
+ C.JSArray_methods.add$1(t1, "");
+ return uri.replace$1$pathSegments(0, t1);
+ },
+ isAlphabetic: function(char) {
+ var t1;
+ if (!(char >= 65 && char <= 90))
+ t1 = char >= 97 && char <= 122;
+ else
+ t1 = true;
+ return t1;
+ },
+ isDriveLetter: function(path, index) {
+ var t1 = path.length,
+ t2 = index + 2;
+ if (t1 < t2)
+ return false;
+ if (!B.isAlphabetic(C.JSString_methods.codeUnitAt$1(path, index)))
+ return false;
+ if (C.JSString_methods.codeUnitAt$1(path, index + 1) !== 58)
+ return false;
+ if (t1 === t2)
+ return true;
+ return C.JSString_methods.codeUnitAt$1(path, t2) === 47;
+ },
+ countCodeUnits: function(string, codeUnit) {
+ var t1, count;
+ for (t1 = new H.CodeUnits(string), t1 = new H.ListIterator(t1, t1.get$length(t1), type$.CodeUnits._eval$1("ListIterator<ListMixin.E>")), count = 0; t1.moveNext$0();)
+ if (t1.__internal$_current === codeUnit)
+ ++count;
+ return count;
+ },
+ findLineStart: function(context, text, column) {
+ var beginningOfLine, index, lineStart;
+ if (text.length === 0)
+ for (beginningOfLine = 0; true;) {
+ index = C.JSString_methods.indexOf$2(context, "\n", beginningOfLine);
+ if (index === -1)
+ return context.length - beginningOfLine >= column ? beginningOfLine : null;
+ if (index - beginningOfLine >= column)
+ return beginningOfLine;
+ beginningOfLine = index + 1;
+ }
+ index = C.JSString_methods.indexOf$1(context, text);
+ for (; index !== -1;) {
+ lineStart = index === 0 ? 0 : C.JSString_methods.lastIndexOf$2(context, "\n", index - 1) + 1;
+ if (column === index - lineStart)
+ return lineStart;
+ index = C.JSString_methods.indexOf$2(context, text, index + 1);
+ }
+ return null;
+ },
+ validateErrorArgs: function(string, match, position, $length) {
+ var t1;
+ if (position < 0)
+ throw H.wrapException(P.RangeError$("position must be greater than or equal to 0."));
+ else if (position > string.length)
+ throw H.wrapException(P.RangeError$("position must be less than or equal to the string length."));
+ t1 = position + $length > string.length;
+ if (t1)
+ throw H.wrapException(P.RangeError$("position plus length must not go beyond the end of the string."));
+ }
+ },
+ Q = {
+ QueueList$: function($E) {
+ var t1 = new Q.QueueList($E._eval$1("QueueList<0>")),
+ t2 = new Array(8);
+ t2.fixed$length = Array;
+ t1.set$_queue_list$_table(H.setRuntimeTypeInfo(t2, $E._eval$1("JSArray<0>")));
+ return t1;
+ },
+ QueueList__nextPowerOf2: function(number) {
+ var nextNumber;
+ H.assertHelper(number > 0);
+ number = (number << 1 >>> 0) - 1;
+ for (; true; number = nextNumber) {
+ nextNumber = (number & number - 1) >>> 0;
+ if (nextNumber === 0)
+ return number;
+ }
+ },
+ QueueList: function QueueList(t0) {
+ var _ = this;
+ _._queue_list$_table = null;
+ _._queue_list$_tail = _._queue_list$_head = 0;
+ _.$ti = t0;
+ },
+ _QueueList_Object_ListMixin: function _QueueList_Object_ListMixin() {
+ }
+ },
+ M = {UnionSet: function UnionSet(t0, t1, t2) {
+ this._sets = t0;
+ this._disjoint = t1;
+ this.$ti = t2;
+ }, UnionSet_length_closure: function UnionSet_length_closure(t0) {
+ this.$this = t0;
+ }, UnionSet__iterable_closure: function UnionSet__iterable_closure(t0) {
+ this.$this = t0;
+ }, _UnionSet_SetBase_UnmodifiableSetMixin: function _UnionSet_SetBase_UnmodifiableSetMixin() {
+ }, _DelegatingIterableBase: function _DelegatingIterableBase() {
+ }, DelegatingIterable: function DelegatingIterable() {
+ }, DelegatingSet: function DelegatingSet(t0, t1) {
+ this._base = t0;
+ this.$ti = t1;
+ }, TypeMatcher: function TypeMatcher() {
+ },
+ wrapMatcher: function(x) {
+ var _s18_ = "satisfies function";
+ if (x instanceof G.Matcher)
+ return x;
+ else if (type$.bool_Function_Object._is(x))
+ return new Y._Predicate(x, _s18_, type$._Predicate_Object);
+ else if (type$.bool_Function_Null._is(x))
+ return new Y._Predicate(new M.wrapMatcher_closure(x), _s18_, type$._Predicate_dynamic);
+ else
+ return typeof x == "string" ? new D._StringEqualsMatcher(x) : new D._DeepMatcher(x, 100);
+ },
+ escape: function(str) {
+ str.toString;
+ return C.JSString_methods.splitMapJoin$2$onMatch(H.stringReplaceAllUnchecked(str, "\\", "\\\\"), $.$get$_escapeRegExp(), type$.String_Function_Match._check(new M.escape_closure()));
+ },
+ _getHexLiteral: function(input) {
+ var t1, it, result;
+ H._checkStringNullable(input);
+ input.toString;
+ t1 = new P.Runes(input);
+ it = t1.get$iterator(t1);
+ if (!it.moveNext$0())
+ H.throwExpression(H.IterableElementError_noElement());
+ result = it.get$current();
+ if (it.moveNext$0())
+ H.throwExpression(H.IterableElementError_tooMany());
+ return "\\x" + C.JSString_methods.padLeft$2(J.toRadixString$1$n(result, 16).toUpperCase(), 2, "0");
+ },
+ wrapMatcher_closure: function wrapMatcher_closure(t0) {
+ this.x = t0;
+ },
+ escape_closure: function escape_closure() {
+ },
+ Context_Context: function(style) {
+ var current = style == null ? D.current() : ".";
+ if (style == null)
+ style = $.$get$Style_platform();
+ return new M.Context(style, current);
+ },
+ _parseUri: function(uri) {
+ if (type$.Uri._is(uri))
+ return uri;
+ throw H.wrapException(P.ArgumentError$value(uri, "uri", "Value must be a String or a Uri"));
+ },
+ _validateArgList: function(method, args) {
+ var numArgs, i, numArgs0, message, t1, t2, t3;
+ for (numArgs = args.length, i = 1; i < numArgs; ++i) {
+ if (args[i] == null || args[i - 1] != null)
+ continue;
+ for (; numArgs >= 1; numArgs = numArgs0) {
+ numArgs0 = numArgs - 1;
+ if (args[numArgs0] != null)
+ break;
+ }
+ message = new P.StringBuffer("");
+ t1 = method + "(";
+ message._contents = t1;
+ t2 = H.SubListIterable$(args, 0, numArgs, H._arrayInstanceType(args)._precomputed1);
+ t3 = t2.$ti;
+ t3 = t1 + new H.MappedListIterable(t2, t3._eval$1("String(ListIterable.E)")._check(new M._validateArgList_closure()), t3._eval$1("MappedListIterable<ListIterable.E,String>")).join$1(0, ", ");
+ message._contents = t3;
+ message._contents = t3 + ("): part " + (i - 1) + " was null, but part " + i + " was not.");
+ throw H.wrapException(P.ArgumentError$(message.toString$0(0)));
+ }
+ },
+ Context: function Context(t0, t1) {
+ this.style = t0;
+ this._context$_current = t1;
+ },
+ Context_join_closure: function Context_join_closure() {
+ },
+ Context_joinAll_closure: function Context_joinAll_closure() {
+ },
+ Context_split_closure: function Context_split_closure() {
+ },
+ _validateArgList_closure: function _validateArgList_closure() {
+ },
+ _PathDirection: function _PathDirection(t0) {
+ this.name = t0;
+ },
+ _PathRelation: function _PathRelation(t0) {
+ this.name = t0;
+ }
+ },
+ D = {
+ _StringEqualsMatcher__writeLeading: function(buff, s, start) {
+ var t1 = buff._contents;
+ if (start > 10) {
+ t1 += "... ";
+ buff._contents = t1;
+ buff._contents = t1 + C.JSString_methods.substring$2(s, start - 10, start);
+ } else
+ buff._contents = t1 + C.JSString_methods.substring$2(s, 0, start);
+ },
+ _StringEqualsMatcher__writeTrailing: function(buff, s, start) {
+ var t1 = start + 10,
+ t2 = buff._contents;
+ if (t1 > s.length)
+ buff._contents = t2 + C.JSString_methods.substring$1(s, start);
+ else {
+ t1 = t2 + C.JSString_methods.substring$2(s, start, t1);
+ buff._contents = t1;
+ buff._contents = t1 + " ...";
+ }
+ },
+ _StringEqualsMatcher: function _StringEqualsMatcher(t0) {
+ this._equals_matcher$_value = t0;
+ },
+ _DeepMatcher: function _DeepMatcher(t0, t1) {
+ this._expected = t0;
+ this._limit = t1;
+ },
+ _DeepMatcher__compareSets_closure: function _DeepMatcher__compareSets_closure(t0, t1, t2, t3) {
+ var _ = this;
+ _.matcher = t0;
+ _.expectedElement = t1;
+ _.location = t2;
+ _.depth = t3;
+ },
+ PackageRootResolver: function PackageRootResolver(t0) {
+ this.packageRoot = t0;
+ },
+ SourceLocationMixin: function SourceLocationMixin() {
+ },
+ _MultiChannel$: function(_inner, $T) {
+ var t1 = type$.int;
+ t1 = new D._MultiChannel(_inner, B.StreamChannelController$(true, true, $T), P.LinkedHashMap_LinkedHashMap$_empty(t1, $T._eval$1("StreamChannelController<0>")), P.LinkedHashSet_LinkedHashSet(t1), P.LinkedHashSet_LinkedHashSet(t1), $T._eval$1("_MultiChannel<0>"));
+ t1._MultiChannel$1(_inner, $T);
+ return t1;
+ },
+ _MultiChannel: function _MultiChannel(t0, t1, t2, t3, t4, t5) {
+ var _ = this;
+ _._multi_channel$_inner = t0;
+ _._innerStreamSubscription = null;
+ _._mainController = t1;
+ _._controllers = t2;
+ _._pendingIds = t3;
+ _._closedIds = t4;
+ _._nextId = 1;
+ _.$ti = t5;
+ },
+ _MultiChannel_closure: function _MultiChannel_closure(t0, t1) {
+ this.$this = t0;
+ this.T = t1;
+ },
+ _MultiChannel_closure0: function _MultiChannel_closure0(t0) {
+ this.$this = t0;
+ },
+ _MultiChannel_closure1: function _MultiChannel_closure1(t0, t1) {
+ this.$this = t0;
+ this.T = t1;
+ },
+ _MultiChannel__closure: function _MultiChannel__closure(t0, t1, t2) {
+ this.$this = t0;
+ this.id = t1;
+ this.T = t2;
+ },
+ _MultiChannel_virtualChannel_closure: function _MultiChannel_virtualChannel_closure(t0, t1) {
+ this._box_0 = t0;
+ this.$this = t1;
+ },
+ _MultiChannel_virtualChannel_closure0: function _MultiChannel_virtualChannel_closure0(t0, t1) {
+ this._box_0 = t0;
+ this.$this = t1;
+ },
+ VirtualChannel: function VirtualChannel(t0, t1, t2, t3, t4) {
+ var _ = this;
+ _._multi_channel$_parent = t0;
+ _.id = t1;
+ _.stream = t2;
+ _.sink = t3;
+ _.$ti = t4;
+ },
+ Message: function Message(t0, t1) {
+ this.type = t0;
+ this.text = t1;
+ },
+ MessageType: function MessageType(t0) {
+ this.name = t0;
+ },
+ current: function() {
+ var exception, t1, path, lastIndex, uri = null;
+ try {
+ uri = P.Uri_base();
+ } catch (exception) {
+ if (type$.Exception._is(H.unwrapException(exception))) {
+ t1 = $._current;
+ if (t1 != null)
+ return t1;
+ throw exception;
+ } else
+ throw exception;
+ }
+ if (J.$eq$(uri, $._currentUriBase))
+ return $._current;
+ $._currentUriBase = uri;
+ if ($.$get$Style_platform() == $.$get$Style_url())
+ return $._current = uri.resolve$1(".").toString$0(0);
+ else {
+ path = uri.toFilePath$0();
+ t1 = path.length;
+ lastIndex = t1 - 1;
+ if (lastIndex < 0)
+ return H.ioore(path, lastIndex);
+ t1 = path[lastIndex];
+ H.assertHelper(t1 === "/" || t1 === "\\");
+ return $._current = lastIndex === 0 ? path : C.JSString_methods.substring$2(path, 0, lastIndex);
+ }
+ }
+ },
+ Z = {
+ prettyPrint: function(object, maxItems, maxLineLength) {
+ return new Z.prettyPrint__prettyPrint(maxItems, maxLineLength).call$4(object, 0, P.LinkedHashSet_LinkedHashSet$_empty(type$.Object), true);
+ },
+ _typeName: function(x) {
+ if (type$.Type._is(x))
+ return "Type";
+ if (type$.Uri._is(x))
+ return "Uri";
+ if (type$.Set_dynamic._is(x))
+ return "Set";
+ return J.get$runtimeType$(x).toString$0(0);
+ },
+ _escapeString: function(source) {
+ var t1 = M.escape(H._checkStringNullable(source));
+ return H.stringReplaceAllUnchecked(t1, "'", "\\'");
+ },
+ prettyPrint__prettyPrint: function prettyPrint__prettyPrint(t0, t1) {
+ this.maxItems = t0;
+ this.maxLineLength = t1;
+ },
+ prettyPrint__prettyPrint_pp: function prettyPrint__prettyPrint_pp(t0, t1, t2) {
+ this._box_0 = t0;
+ this._prettyPrint = t1;
+ this.indent = t2;
+ },
+ prettyPrint__prettyPrint_closure: function prettyPrint__prettyPrint_closure(t0) {
+ this.indent = t0;
+ },
+ prettyPrint__prettyPrint_closure0: function prettyPrint__prettyPrint_closure0(t0, t1) {
+ this.pp = t0;
+ this.object = t1;
+ },
+ prettyPrint__prettyPrint_closure1: function prettyPrint__prettyPrint_closure1(t0) {
+ this.indent = t0;
+ },
+ LiveTest: function LiveTest() {
+ }
+ },
+ A = {
+ Frame_Frame$parseVM: function(frame) {
+ return A.Frame__catchFormatException(frame, new A.Frame_Frame$parseVM_closure(frame));
+ },
+ Frame_Frame$parseV8: function(frame) {
+ return A.Frame__catchFormatException(frame, new A.Frame_Frame$parseV8_closure(frame));
+ },
+ Frame_Frame$parseFirefox: function(frame) {
+ return A.Frame__catchFormatException(frame, new A.Frame_Frame$parseFirefox_closure(frame));
+ },
+ Frame_Frame$parseFriendly: function(frame) {
+ return A.Frame__catchFormatException(frame, new A.Frame_Frame$parseFriendly_closure(frame));
+ },
+ Frame__uriOrPathToUri: function(uriOrPath) {
+ if (J.getInterceptor$asx(uriOrPath).contains$1(uriOrPath, $.$get$Frame__uriRegExp()))
+ return P.Uri_parse(uriOrPath);
+ else if (C.JSString_methods.contains$1(uriOrPath, $.$get$Frame__windowsRegExp()))
+ return P._Uri__Uri$file(uriOrPath, true);
+ else if (C.JSString_methods.startsWith$1(uriOrPath, "/"))
+ return P._Uri__Uri$file(uriOrPath, false);
+ if (C.JSString_methods.contains$1(uriOrPath, "\\"))
+ return $.$get$windows().toUri$1(uriOrPath);
+ return P.Uri_parse(uriOrPath);
+ },
+ Frame__catchFormatException: function(text, body) {
+ var t1, exception;
+ try {
+ t1 = body.call$0();
+ return t1;
+ } catch (exception) {
+ if (type$.FormatException._is(H.unwrapException(exception)))
+ return new N.UnparsedFrame(P._Uri__Uri(null, "unparsed", null, null), text);
+ else
+ throw exception;
+ }
+ },
+ Frame: function Frame(t0, t1, t2, t3) {
+ var _ = this;
+ _.uri = t0;
+ _.line = t1;
+ _.column = t2;
+ _.member = t3;
+ },
+ Frame_Frame$parseVM_closure: function Frame_Frame$parseVM_closure(t0) {
+ this.frame = t0;
+ },
+ Frame_Frame$parseV8_closure: function Frame_Frame$parseV8_closure(t0) {
+ this.frame = t0;
+ },
+ Frame_Frame$parseV8_closure_parseLocation: function Frame_Frame$parseV8_closure_parseLocation(t0) {
+ this.frame = t0;
+ },
+ Frame_Frame$parseFirefox_closure: function Frame_Frame$parseFirefox_closure(t0) {
+ this.frame = t0;
+ },
+ Frame_Frame$parseFriendly_closure: function Frame_Frame$parseFriendly_closure(t0) {
+ this.frame = t0;
+ },
+ AsciiGlyphSet: function AsciiGlyphSet() {
+ }
+ },
+ N = {UnparsedFrame: function UnparsedFrame(t0, t1) {
+ this.uri = t0;
+ this.member = t1;
+ }, StreamChannelCompleter: function StreamChannelCompleter(t0, t1, t2) {
+ var _ = this;
+ _._streamCompleter = t0;
+ _._sinkCompleter = t1;
+ _._stream_channel_completer$_channel = null;
+ _._stream_channel_completer$_set = false;
+ _.$ti = t2;
+ },
+ postMessageChannel: function() {
+ var t1, t2,
+ controller = B.StreamChannelController$(true, true, type$.dynamic);
+ new W._EventStream(window, "message", false, type$._EventStream_MessageEvent).firstWhere$1(0, new N.postMessageChannel_closure()).then$1$1(new N.postMessageChannel_closure0(controller), type$.Null);
+ t1 = P.LinkedHashMap_LinkedHashMap$_literal(["href", window.location.href, "ready", true], type$.String, type$.Object);
+ t1 = P._convertDataTree(t1);
+ t2 = window.location;
+ self.window.parent.postMessage(t1, (t2 && C.Location_methods).get$origin(t2));
+ return controller._foreign;
+ },
+ postMessageChannel_closure: function postMessageChannel_closure() {
+ },
+ postMessageChannel_closure0: function postMessageChannel_closure0(t0) {
+ this.controller = t0;
+ },
+ postMessageChannel__closure: function postMessageChannel__closure(t0) {
+ this.controller = t0;
+ },
+ postMessageChannel__closure0: function postMessageChannel__closure0(t0) {
+ this.port = t0;
+ },
+ postMessageChannel__closure1: function postMessageChannel__closure1(t0, t1) {
+ this.port = t0;
+ this.portSubscription = t1;
+ },
+ OperatingSystem_find: function(identifier) {
+ return C.JSArray_methods.firstWhere$2$orElse(C.List_opx, new N.OperatingSystem_find_closure(identifier), new N.OperatingSystem_find_closure0());
+ },
+ OperatingSystem: function OperatingSystem(t0, t1) {
+ this.name = t0;
+ this.identifier = t1;
+ },
+ OperatingSystem_find_closure: function OperatingSystem_find_closure(t0) {
+ this.identifier = t0;
+ },
+ OperatingSystem_find_closure0: function OperatingSystem_find_closure0() {
+ },
+ SuiteChannelManager: function SuiteChannelManager(t0, t1, t2) {
+ this._incomingConnections = t0;
+ this._outgoingConnections = t1;
+ this._names = t2;
+ }
+ },
+ K = {
+ GuaranteeChannel$: function(innerStream, innerSink, allowSinkErrors, $T) {
+ var t2, t1 = {};
+ t1.innerStream = innerStream;
+ t2 = new K.GuaranteeChannel($T._eval$1("GuaranteeChannel<0>"));
+ t2.GuaranteeChannel$3$allowSinkErrors(innerSink, allowSinkErrors, t1, $T);
+ return t2;
+ },
+ GuaranteeChannel: function GuaranteeChannel(t0) {
+ var _ = this;
+ _._subscription = _._streamController = _._sink = null;
+ _._disconnected = false;
+ _.$ti = t0;
+ },
+ GuaranteeChannel_closure: function GuaranteeChannel_closure(t0, t1) {
+ this._box_0 = t0;
+ this.$this = t1;
+ },
+ GuaranteeChannel__closure: function GuaranteeChannel__closure(t0) {
+ this.$this = t0;
+ },
+ _GuaranteeSink: function _GuaranteeSink(t0, t1, t2, t3, t4) {
+ var _ = this;
+ _._inner = t0;
+ _._channel = t1;
+ _._doneCompleter = t2;
+ _._closed = _._disconnected = false;
+ _._addStreamCompleter = _._addStreamSubscription = null;
+ _._allowErrors = t3;
+ _.$ti = t4;
+ },
+ _GuaranteeSink__addError_closure: function _GuaranteeSink__addError_closure() {
+ },
+ _GuaranteeSink_addStream_closure: function _GuaranteeSink_addStream_closure(t0) {
+ this.$this = t0;
+ },
+ UnicodeGlyphSet: function UnicodeGlyphSet() {
+ },
+ ClosedException$: function() {
+ return new K.ClosedException();
+ },
+ ClosedException: function ClosedException() {
+ }
+ };
+ var holders = [C, H, J, P, W, S, O, Y, F, V, E, L, G, T, X, U, R, B, Q, M, D, Z, A, N, K];
+ hunkHelpers.setFunctionNamesIfNecessary(holders);
+ var $ = {};
+ H.JS_CONST.prototype = {};
+ J.Interceptor.prototype = {
+ $eq: function(receiver, other) {
+ return receiver === other;
+ },
+ get$hashCode: function(receiver) {
+ return H.Primitives_objectHashCode(receiver);
+ },
+ toString$0: function(receiver) {
+ return "Instance of '" + H.S(H.Primitives_objectTypeName(receiver)) + "'";
+ },
+ get$runtimeType: function(receiver) {
+ return H.getRuntimeType(receiver);
+ }
+ };
+ J.JSBool.prototype = {
+ toString$0: function(receiver) {
+ return String(receiver);
+ },
+ get$hashCode: function(receiver) {
+ return receiver ? 519018 : 218159;
+ },
+ get$runtimeType: function(receiver) {
+ return C.Type_bool_lhE;
+ },
+ $isbool: 1
+ };
+ J.JSNull.prototype = {
+ $eq: function(receiver, other) {
+ return null == other;
+ },
+ toString$0: function(receiver) {
+ return "null";
+ },
+ get$hashCode: function(receiver) {
+ return 0;
+ },
+ get$runtimeType: function(receiver) {
+ return C.Type_Null_Yyn;
+ },
+ $isNull: 1
+ };
+ J.JSObject.prototype = {};
+ J.JavaScriptObject.prototype = {
+ get$hashCode: function(receiver) {
+ return 0;
+ },
+ get$runtimeType: function(receiver) {
+ return C.Type_JSObject_8k0;
+ },
+ toString$0: function(receiver) {
+ return String(receiver);
+ },
+ $isJSObject: 1
+ };
+ J.PlainJavaScriptObject.prototype = {};
+ J.UnknownJavaScriptObject.prototype = {};
+ J.JavaScriptFunction.prototype = {
+ toString$0: function(receiver) {
+ var dartClosure = receiver[$.$get$DART_CLOSURE_PROPERTY_NAME()];
+ if (dartClosure == null)
+ return this.super$JavaScriptObject$toString(receiver);
+ return "JavaScript function for " + H.S(J.toString$0$(dartClosure));
+ },
+ $signature: function() {
+ return {func: 1, opt: [,,,,,,,,,,,,,,,,]};
+ },
+ $isFunction: 1
+ };
+ J.JSArray.prototype = {
+ add$1: function(receiver, value) {
+ H._arrayInstanceType(receiver)._precomputed1._check(value);
+ if (!!receiver.fixed$length)
+ H.throwExpression(P.UnsupportedError$("add"));
+ receiver.push(value);
+ },
+ removeAt$1: function(receiver, index) {
+ var t1;
+ if (!!receiver.fixed$length)
+ H.throwExpression(P.UnsupportedError$("removeAt"));
+ t1 = receiver.length;
+ if (index >= t1)
+ throw H.wrapException(P.RangeError$value(index, null));
+ return receiver.splice(index, 1)[0];
+ },
+ insert$2: function(receiver, index, value) {
+ var t1;
+ H._arrayInstanceType(receiver)._precomputed1._check(value);
+ if (!!receiver.fixed$length)
+ H.throwExpression(P.UnsupportedError$("insert"));
+ t1 = receiver.length;
+ if (index > t1)
+ throw H.wrapException(P.RangeError$value(index, null));
+ receiver.splice(index, 0, value);
+ },
+ insertAll$2: function(receiver, index, iterable) {
+ var t1, insertionLength, end;
+ H._arrayInstanceType(receiver)._eval$1("Iterable<1>")._check(iterable);
+ if (!!receiver.fixed$length)
+ H.throwExpression(P.UnsupportedError$("insertAll"));
+ t1 = receiver.length;
+ P.RangeError_checkValueInInterval(index, 0, t1, "index");
+ insertionLength = iterable.length;
+ this.set$length(receiver, t1 + insertionLength);
+ end = index + insertionLength;
+ this.setRange$4(receiver, end, receiver.length, receiver, index);
+ this.setRange$3(receiver, index, end, iterable);
+ },
+ removeLast$0: function(receiver) {
+ if (!!receiver.fixed$length)
+ H.throwExpression(P.UnsupportedError$("removeLast"));
+ if (receiver.length === 0)
+ throw H.wrapException(H.diagnoseIndexError(receiver, -1));
+ return receiver.pop();
+ },
+ remove$1: function(receiver, element) {
+ var i;
+ if (!!receiver.fixed$length)
+ H.throwExpression(P.UnsupportedError$("remove"));
+ for (i = 0; i < receiver.length; ++i)
+ if (J.$eq$(receiver[i], element)) {
+ receiver.splice(i, 1);
+ return true;
+ }
+ return false;
+ },
+ addAll$1: function(receiver, collection) {
+ var i, t1, e, i0;
+ H._arrayInstanceType(receiver)._eval$1("Iterable<1>")._check(collection);
+ i = receiver.length;
+ if (!!receiver.fixed$length)
+ H.throwExpression(P.UnsupportedError$("addAll"));
+ for (t1 = J.get$iterator$ax(collection); t1.moveNext$0(); i = i0) {
+ e = t1.get$current();
+ i0 = i + 1;
+ H.assertHelper(i === receiver.length || H.throwExpression(P.ConcurrentModificationError$(receiver)));
+ receiver.push(e);
+ }
+ },
+ forEach$1: function(receiver, f) {
+ var end, i;
+ H._arrayInstanceType(receiver)._eval$1("~(1)")._check(f);
+ end = receiver.length;
+ for (i = 0; i < end; ++i) {
+ f.call$1(receiver[i]);
+ if (receiver.length !== end)
+ throw H.wrapException(P.ConcurrentModificationError$(receiver));
+ }
+ },
+ map$1$1: function(receiver, f, $T) {
+ var t1 = H._arrayInstanceType(receiver);
+ return new H.MappedListIterable(receiver, t1._bind$1($T)._eval$1("1(2)")._check(f), t1._eval$1("@<1>")._bind$1($T)._eval$1("MappedListIterable<1,2>"));
+ },
+ join$1: function(receiver, separator) {
+ var i,
+ list = new Array(receiver.length);
+ list.fixed$length = Array;
+ for (i = 0; i < receiver.length; ++i)
+ this.$indexSet(list, i, H.S(receiver[i]));
+ return list.join(separator);
+ },
+ join$0: function($receiver) {
+ return this.join$1($receiver, "");
+ },
+ fold$1$2: function(receiver, initialValue, combine, $T) {
+ var $length, value, i;
+ $T._check(initialValue);
+ H._arrayInstanceType(receiver)._bind$1($T)._eval$1("1(1,2)")._check(combine);
+ $length = receiver.length;
+ for (value = initialValue, i = 0; i < $length; ++i) {
+ value = combine.call$2(value, receiver[i]);
+ if (receiver.length !== $length)
+ throw H.wrapException(P.ConcurrentModificationError$(receiver));
+ }
+ return value;
+ },
+ firstWhere$2$orElse: function(receiver, test, orElse) {
+ var end, i, element,
+ t1 = H._arrayInstanceType(receiver);
+ t1._eval$1("bool(1)")._check(test);
+ t1._eval$1("1()")._check(orElse);
+ end = receiver.length;
+ for (i = 0; i < end; ++i) {
+ element = receiver[i];
+ if (H.boolConversionCheck(test.call$1(element)))
+ return element;
+ if (receiver.length !== end)
+ throw H.wrapException(P.ConcurrentModificationError$(receiver));
+ }
+ if (orElse != null)
+ return orElse.call$0();
+ throw H.wrapException(H.IterableElementError_noElement());
+ },
+ firstWhere$1: function($receiver, test) {
+ return this.firstWhere$2$orElse($receiver, test, null);
+ },
+ elementAt$1: function(receiver, index) {
+ if (index < 0 || index >= receiver.length)
+ return H.ioore(receiver, index);
+ return receiver[index];
+ },
+ sublist$2: function(receiver, start, end) {
+ if (start < 0 || start > receiver.length)
+ throw H.wrapException(P.RangeError$range(start, 0, receiver.length, "start", null));
+ if (end < start || end > receiver.length)
+ throw H.wrapException(P.RangeError$range(end, start, receiver.length, "end", null));
+ if (start === end)
+ return H.setRuntimeTypeInfo([], H._arrayInstanceType(receiver));
+ return H.setRuntimeTypeInfo(receiver.slice(start, end), H._arrayInstanceType(receiver));
+ },
+ get$first: function(receiver) {
+ if (receiver.length > 0)
+ return receiver[0];
+ throw H.wrapException(H.IterableElementError_noElement());
+ },
+ get$last: function(receiver) {
+ var t1 = receiver.length;
+ if (t1 > 0)
+ return receiver[t1 - 1];
+ throw H.wrapException(H.IterableElementError_noElement());
+ },
+ get$single: function(receiver) {
+ var t1 = receiver.length;
+ if (t1 === 1) {
+ if (0 >= t1)
+ return H.ioore(receiver, 0);
+ return receiver[0];
+ }
+ if (t1 === 0)
+ throw H.wrapException(H.IterableElementError_noElement());
+ throw H.wrapException(H.IterableElementError_tooMany());
+ },
+ setRange$4: function(receiver, start, end, iterable, skipCount) {
+ var $length, i,
+ t1 = H._arrayInstanceType(receiver);
+ t1._eval$1("Iterable<1>")._check(iterable);
+ if (!!receiver.immutable$list)
+ H.throwExpression(P.UnsupportedError$("setRange"));
+ P.RangeError_checkValidRange(start, end, receiver.length);
+ $length = end - start;
+ if ($length === 0)
+ return;
+ P.RangeError_checkNotNegative(skipCount, "skipCount");
+ t1._eval$1("List<1>")._check(iterable);
+ t1 = J.getInterceptor$asx(iterable);
+ if (skipCount + $length > t1.get$length(iterable))
+ throw H.wrapException(H.IterableElementError_tooFew());
+ if (skipCount < start)
+ for (i = $length - 1; i >= 0; --i)
+ receiver[start + i] = t1.$index(iterable, skipCount + i);
+ else
+ for (i = 0; i < $length; ++i)
+ receiver[start + i] = t1.$index(iterable, skipCount + i);
+ },
+ setRange$3: function($receiver, start, end, iterable) {
+ return this.setRange$4($receiver, start, end, iterable, 0);
+ },
+ fillRange$3: function(receiver, start, end, fillValue) {
+ var i;
+ H._arrayInstanceType(receiver)._precomputed1._check(fillValue);
+ if (!!receiver.immutable$list)
+ H.throwExpression(P.UnsupportedError$("fill range"));
+ P.RangeError_checkValidRange(start, end, receiver.length);
+ for (i = start; i < end; ++i)
+ receiver[i] = fillValue;
+ },
+ replaceRange$3: function(receiver, start, end, replacement) {
+ var t1, removeLength, insertEnd, delta, newLength, _this = this;
+ H._arrayInstanceType(receiver)._eval$1("Iterable<1>")._check(replacement);
+ if (!!receiver.fixed$length)
+ H.throwExpression(P.UnsupportedError$("replaceRange"));
+ t1 = receiver.length;
+ P.RangeError_checkValidRange(start, end, t1);
+ removeLength = end - start;
+ insertEnd = start + 1;
+ if (removeLength >= 1) {
+ delta = removeLength - 1;
+ newLength = t1 - delta;
+ _this.setRange$3(receiver, start, insertEnd, replacement);
+ if (delta !== 0) {
+ _this.setRange$4(receiver, insertEnd, newLength, receiver, end);
+ _this.set$length(receiver, newLength);
+ }
+ } else {
+ newLength = t1 + (1 - removeLength);
+ _this.set$length(receiver, newLength);
+ _this.setRange$4(receiver, insertEnd, newLength, receiver, end);
+ _this.setRange$3(receiver, start, insertEnd, replacement);
+ }
+ },
+ contains$1: function(receiver, other) {
+ var i;
+ for (i = 0; i < receiver.length; ++i)
+ if (J.$eq$(receiver[i], other))
+ return true;
+ return false;
+ },
+ get$isEmpty: function(receiver) {
+ return receiver.length === 0;
+ },
+ toString$0: function(receiver) {
+ return P.IterableBase_iterableToFullString(receiver, "[", "]");
+ },
+ toSet$0: function(receiver) {
+ return P.LinkedHashSet_LinkedHashSet$from(receiver, H._arrayInstanceType(receiver)._precomputed1);
+ },
+ get$iterator: function(receiver) {
+ return new J.ArrayIterator(receiver, receiver.length, H._arrayInstanceType(receiver)._eval$1("ArrayIterator<1>"));
+ },
+ get$hashCode: function(receiver) {
+ return H.Primitives_objectHashCode(receiver);
+ },
+ get$length: function(receiver) {
+ return receiver.length;
+ },
+ set$length: function(receiver, newLength) {
+ var _s9_ = "newLength";
+ if (!!receiver.fixed$length)
+ H.throwExpression(P.UnsupportedError$("set length"));
+ if (!H._isInt(newLength))
+ throw H.wrapException(P.ArgumentError$value(newLength, _s9_, null));
+ if (newLength < 0)
+ throw H.wrapException(P.RangeError$range(newLength, 0, null, _s9_, null));
+ receiver.length = newLength;
+ },
+ $index: function(receiver, index) {
+ H._checkIntNullable(index);
+ if (!H._isInt(index))
+ throw H.wrapException(H.diagnoseIndexError(receiver, index));
+ if (index >= receiver.length || index < 0)
+ throw H.wrapException(H.diagnoseIndexError(receiver, index));
+ return receiver[index];
+ },
+ $indexSet: function(receiver, index, value) {
+ H._checkIntNullable(index);
+ H._arrayInstanceType(receiver)._precomputed1._check(value);
+ if (!!receiver.immutable$list)
+ H.throwExpression(P.UnsupportedError$("indexed set"));
+ if (!H._isInt(index))
+ throw H.wrapException(H.diagnoseIndexError(receiver, index));
+ if (index >= receiver.length || index < 0)
+ throw H.wrapException(H.diagnoseIndexError(receiver, index));
+ receiver[index] = value;
+ },
+ $isEfficientLengthIterable: 1,
+ $isIterable: 1,
+ $isList: 1
+ };
+ J.JSUnmodifiableArray.prototype = {};
+ J.ArrayIterator.prototype = {
+ get$current: function() {
+ return this._current;
+ },
+ moveNext$0: function() {
+ var t2, _this = this,
+ t1 = _this._iterable,
+ $length = t1.length;
+ if (_this._length !== $length)
+ throw H.wrapException(H.throwConcurrentModificationError(t1));
+ t2 = _this._index;
+ if (t2 >= $length) {
+ _this.set$_current(null);
+ return false;
+ }
+ _this.set$_current(t1[t2]);
+ ++_this._index;
+ return true;
+ },
+ set$_current: function(_current) {
+ this._current = this.$ti._precomputed1._check(_current);
+ },
+ $isIterator: 1
+ };
+ J.JSNumber.prototype = {
+ floor$0: function(receiver) {
+ var truncated, d;
+ if (receiver >= 0) {
+ if (receiver <= 2147483647)
+ return receiver | 0;
+ } else if (receiver >= -2147483648) {
+ truncated = receiver | 0;
+ return receiver === truncated ? truncated : truncated - 1;
+ }
+ d = Math.floor(receiver);
+ if (isFinite(d))
+ return d;
+ throw H.wrapException(P.UnsupportedError$("" + receiver + ".floor()"));
+ },
+ round$0: function(receiver) {
+ if (receiver > 0) {
+ if (receiver !== 1 / 0)
+ return Math.round(receiver);
+ } else if (receiver > -1 / 0)
+ return 0 - Math.round(0 - receiver);
+ throw H.wrapException(P.UnsupportedError$("" + receiver + ".round()"));
+ },
+ toRadixString$1: function(receiver, radix) {
+ var result, match, t1, exponent;
+ if (radix < 2 || radix > 36)
+ throw H.wrapException(P.RangeError$range(radix, 2, 36, "radix", null));
+ result = receiver.toString(radix);
+ if (C.JSString_methods.codeUnitAt$1(result, result.length - 1) !== 41)
+ return result;
+ match = /^([\da-z]+)(?:\.([\da-z]+))?\(e\+(\d+)\)$/.exec(result);
+ if (match == null)
+ H.throwExpression(P.UnsupportedError$("Unexpected toString result: " + result));
+ t1 = match.length;
+ if (1 >= t1)
+ return H.ioore(match, 1);
+ result = match[1];
+ if (3 >= t1)
+ return H.ioore(match, 3);
+ exponent = +match[3];
+ t1 = match[2];
+ if (t1 != null) {
+ result += t1;
+ exponent -= t1.length;
+ }
+ return result + C.JSString_methods.$mul("0", exponent);
+ },
+ toString$0: function(receiver) {
+ if (receiver === 0 && 1 / receiver < 0)
+ return "-0.0";
+ else
+ return "" + receiver;
+ },
+ get$hashCode: function(receiver) {
+ var absolute, floorLog2, factor, scaled,
+ intValue = receiver | 0;
+ if (receiver === intValue)
+ return 536870911 & intValue;
+ absolute = Math.abs(receiver);
+ floorLog2 = Math.log(absolute) / 0.6931471805599453 | 0;
+ factor = Math.pow(2, floorLog2);
+ scaled = absolute < 1 ? absolute / factor : factor / absolute;
+ return 536870911 & ((scaled * 9007199254740992 | 0) + (scaled * 3542243181176521 | 0)) * 599197 + floorLog2 * 1259;
+ },
+ $mod: function(receiver, other) {
+ var result = receiver % other;
+ if (result === 0)
+ return 0;
+ if (result > 0)
+ return result;
+ if (other < 0)
+ return result - other;
+ else
+ return result + other;
+ },
+ $tdiv: function(receiver, other) {
+ if ((receiver | 0) === receiver)
+ if (other >= 1 || other < -1)
+ return receiver / other | 0;
+ return this._tdivSlow$1(receiver, other);
+ },
+ _tdivFast$1: function(receiver, other) {
+ return (receiver | 0) === receiver ? receiver / other | 0 : this._tdivSlow$1(receiver, other);
+ },
+ _tdivSlow$1: function(receiver, other) {
+ var quotient = receiver / other;
+ if (quotient >= -2147483648 && quotient <= 2147483647)
+ return quotient | 0;
+ if (quotient > 0) {
+ if (quotient !== 1 / 0)
+ return Math.floor(quotient);
+ } else if (quotient > -1 / 0)
+ return Math.ceil(quotient);
+ throw H.wrapException(P.UnsupportedError$("Result of truncating division is " + H.S(quotient) + ": " + H.S(receiver) + " ~/ " + other));
+ },
+ _shlPositive$1: function(receiver, other) {
+ return other > 31 ? 0 : receiver << other >>> 0;
+ },
+ _shrOtherPositive$1: function(receiver, other) {
+ var t1;
+ if (receiver > 0)
+ t1 = this._shrBothPositive$1(receiver, other);
+ else {
+ t1 = other > 31 ? 31 : other;
+ t1 = receiver >> t1 >>> 0;
+ }
+ return t1;
+ },
+ _shrReceiverPositive$1: function(receiver, other) {
+ if (other < 0)
+ throw H.wrapException(H.argumentErrorValue(other));
+ return this._shrBothPositive$1(receiver, other);
+ },
+ _shrBothPositive$1: function(receiver, other) {
+ return other > 31 ? 0 : receiver >>> other;
+ },
+ get$runtimeType: function(receiver) {
+ return C.Type_num_cv7;
+ },
+ $isdouble: 1,
+ $isnum: 1
+ };
+ J.JSInt.prototype = {
+ get$runtimeType: function(receiver) {
+ return C.Type_int_tHn;
+ },
+ $isint: 1
+ };
+ J.JSDouble.prototype = {
+ get$runtimeType: function(receiver) {
+ return C.Type_double_K1J;
+ }
+ };
+ J.JSString.prototype = {
+ codeUnitAt$1: function(receiver, index) {
+ if (index < 0)
+ throw H.wrapException(H.diagnoseIndexError(receiver, index));
+ if (index >= receiver.length)
+ H.throwExpression(H.diagnoseIndexError(receiver, index));
+ return receiver.charCodeAt(index);
+ },
+ _codeUnitAt$1: function(receiver, index) {
+ if (index >= receiver.length)
+ throw H.wrapException(H.diagnoseIndexError(receiver, index));
+ return receiver.charCodeAt(index);
+ },
+ allMatches$2: function(receiver, string, start) {
+ var t1;
+ if (typeof string != "string")
+ H.throwExpression(H.argumentErrorValue(string));
+ t1 = string.length;
+ if (start > t1)
+ throw H.wrapException(P.RangeError$range(start, 0, t1, null, null));
+ return new H._StringAllMatchesIterable(string, receiver, start);
+ },
+ allMatches$1: function($receiver, string) {
+ return this.allMatches$2($receiver, string, 0);
+ },
+ matchAsPrefix$2: function(receiver, string, start) {
+ var t1, t2, i, _null = null;
+ if (start < 0 || start > string.length)
+ throw H.wrapException(P.RangeError$range(start, 0, string.length, _null, _null));
+ t1 = receiver.length;
+ if (start + t1 > string.length)
+ return _null;
+ for (t2 = J.getInterceptor$s(string), i = 0; i < t1; ++i)
+ if (t2.codeUnitAt$1(string, start + i) !== this._codeUnitAt$1(receiver, i))
+ return _null;
+ return new H.StringMatch(start, receiver);
+ },
+ $add: function(receiver, other) {
+ if (typeof other != "string")
+ throw H.wrapException(P.ArgumentError$value(other, null, null));
+ return receiver + other;
+ },
+ endsWith$1: function(receiver, other) {
+ var otherLength = other.length,
+ t1 = receiver.length;
+ if (otherLength > t1)
+ return false;
+ return other === this.substring$1(receiver, t1 - otherLength);
+ },
+ splitMapJoin$2$onMatch: function(receiver, from, onMatch) {
+ return H.stringReplaceAllFuncUnchecked(receiver, from, type$.String_Function_Match._check(onMatch), type$.String_Function_String._check(null));
+ },
+ replaceFirst$2: function(receiver, from, to) {
+ P.RangeError_checkValueInInterval(0, 0, receiver.length, "startIndex");
+ return H.stringReplaceFirstUnchecked(receiver, from, to, 0);
+ },
+ replaceRange$3: function(receiver, start, end, replacement) {
+ end = P.RangeError_checkValidRange(start, end, receiver.length);
+ return H.stringReplaceRangeUnchecked(receiver, start, end, replacement);
+ },
+ startsWith$2: function(receiver, pattern, index) {
+ var endIndex;
+ type$.Pattern._check(pattern);
+ if (index < 0 || index > receiver.length)
+ throw H.wrapException(P.RangeError$range(index, 0, receiver.length, null, null));
+ if (typeof pattern == "string") {
+ endIndex = index + pattern.length;
+ if (endIndex > receiver.length)
+ return false;
+ return pattern === receiver.substring(index, endIndex);
+ }
+ return J.matchAsPrefix$2$s(pattern, receiver, index) != null;
+ },
+ startsWith$1: function($receiver, pattern) {
+ return this.startsWith$2($receiver, pattern, 0);
+ },
+ substring$2: function(receiver, startIndex, endIndex) {
+ if (endIndex == null)
+ endIndex = receiver.length;
+ if (startIndex < 0)
+ throw H.wrapException(P.RangeError$value(startIndex, null));
+ if (startIndex > endIndex)
+ throw H.wrapException(P.RangeError$value(startIndex, null));
+ if (endIndex > receiver.length)
+ throw H.wrapException(P.RangeError$value(endIndex, null));
+ return receiver.substring(startIndex, endIndex);
+ },
+ substring$1: function($receiver, startIndex) {
+ return this.substring$2($receiver, startIndex, null);
+ },
+ trim$0: function(receiver) {
+ var startIndex, t1, endIndex0,
+ result = receiver.trim(),
+ endIndex = result.length;
+ if (endIndex === 0)
+ return result;
+ if (this._codeUnitAt$1(result, 0) === 133) {
+ startIndex = J.JSString__skipLeadingWhitespace(result, 1);
+ if (startIndex === endIndex)
+ return "";
+ } else
+ startIndex = 0;
+ t1 = endIndex - 1;
+ endIndex0 = this.codeUnitAt$1(result, t1) === 133 ? J.JSString__skipTrailingWhitespace(result, t1) : endIndex;
+ if (startIndex === 0 && endIndex0 === endIndex)
+ return result;
+ return result.substring(startIndex, endIndex0);
+ },
+ $mul: function(receiver, times) {
+ var s, result;
+ if (0 >= times)
+ return "";
+ if (times === 1 || receiver.length === 0)
+ return receiver;
+ if (times !== times >>> 0)
+ throw H.wrapException(C.C_OutOfMemoryError);
+ for (s = receiver, result = ""; true;) {
+ if ((times & 1) === 1)
+ result = s + result;
+ times = times >>> 1;
+ if (times === 0)
+ break;
+ s += s;
+ }
+ return result;
+ },
+ padLeft$2: function(receiver, width, padding) {
+ var delta = width - receiver.length;
+ if (delta <= 0)
+ return receiver;
+ return this.$mul(padding, delta) + receiver;
+ },
+ padRight$1: function(receiver, width) {
+ var delta;
+ if (typeof width !== "number")
+ return width.$sub();
+ delta = width - receiver.length;
+ if (delta <= 0)
+ return receiver;
+ return receiver + this.$mul(" ", delta);
+ },
+ indexOf$2: function(receiver, pattern, start) {
+ var t1;
+ if (start < 0 || start > receiver.length)
+ throw H.wrapException(P.RangeError$range(start, 0, receiver.length, null, null));
+ t1 = receiver.indexOf(pattern, start);
+ return t1;
+ },
+ indexOf$1: function($receiver, pattern) {
+ return this.indexOf$2($receiver, pattern, 0);
+ },
+ lastIndexOf$2: function(receiver, pattern, start) {
+ var t1, t2;
+ if (start == null)
+ start = receiver.length;
+ else if (start < 0 || start > receiver.length)
+ throw H.wrapException(P.RangeError$range(start, 0, receiver.length, null, null));
+ t1 = pattern.length;
+ t2 = receiver.length;
+ if (start + t1 > t2)
+ start = t2 - t1;
+ return receiver.lastIndexOf(pattern, start);
+ },
+ lastIndexOf$1: function($receiver, pattern) {
+ return this.lastIndexOf$2($receiver, pattern, null);
+ },
+ contains$1: function(receiver, other) {
+ if (other == null)
+ H.throwExpression(H.argumentErrorValue(other));
+ return H.stringContainsUnchecked(receiver, other, 0);
+ },
+ toString$0: function(receiver) {
+ return receiver;
+ },
+ get$hashCode: function(receiver) {
+ var t1, hash, i;
+ for (t1 = receiver.length, hash = 0, i = 0; i < t1; ++i) {
+ hash = 536870911 & hash + receiver.charCodeAt(i);
+ hash = 536870911 & hash + ((524287 & hash) << 10);
+ hash ^= hash >> 6;
+ }
+ hash = 536870911 & hash + ((67108863 & hash) << 3);
+ hash ^= hash >> 11;
+ return 536870911 & hash + ((16383 & hash) << 15);
+ },
+ get$runtimeType: function(receiver) {
+ return C.Type_String_k8F;
+ },
+ get$length: function(receiver) {
+ return receiver.length;
+ },
+ $index: function(receiver, index) {
+ H._checkIntNullable(index);
+ if (index >= receiver.length || index < 0)
+ throw H.wrapException(H.diagnoseIndexError(receiver, index));
+ return receiver[index];
+ },
+ $isPattern: 1,
+ $isString: 1
+ };
+ H._CastIterableBase.prototype = {
+ get$iterator: function(_) {
+ var t1 = this._source,
+ t2 = H._instanceType(this);
+ return new H.CastIterator(t1.get$iterator(t1), t2._eval$1("@<1>")._bind$1(t2._rest[1])._eval$1("CastIterator<1,2>"));
+ },
+ get$length: function(_) {
+ var t1 = this._source;
+ return t1.get$length(t1);
+ },
+ get$isEmpty: function(_) {
+ var t1 = this._source;
+ return t1.get$isEmpty(t1);
+ },
+ get$first: function(_) {
+ var t1 = this._source;
+ return H._instanceType(this)._rest[1]._as(t1.get$first(t1));
+ },
+ get$last: function(_) {
+ var t1 = this._source;
+ return H._instanceType(this)._rest[1]._as(t1.get$last(t1));
+ },
+ contains$1: function(_, other) {
+ return this._source.contains$1(0, other);
+ },
+ toString$0: function(_) {
+ return this._source.toString$0(0);
+ }
+ };
+ H.CastIterator.prototype = {
+ moveNext$0: function() {
+ return this._source.moveNext$0();
+ },
+ get$current: function() {
+ return this.$ti._rest[1]._as(this._source.get$current());
+ },
+ $isIterator: 1
+ };
+ H.CastIterable.prototype = {};
+ H._EfficientLengthCastIterable.prototype = {$isEfficientLengthIterable: 1};
+ H.CastMap.prototype = {
+ cast$2$0: function(_, RK, RV) {
+ var t1 = this.$ti;
+ return new H.CastMap(this._source, t1._eval$1("@<1>")._bind$1(t1._rest[1])._bind$1(RK)._bind$1(RV)._eval$1("CastMap<1,2,3,4>"));
+ },
+ containsKey$1: function(key) {
+ return this._source.containsKey$1(key);
+ },
+ $index: function(_, key) {
+ return this.$ti._rest[3]._as(this._source.$index(0, key));
+ },
+ remove$1: function(_, key) {
+ return this.$ti._rest[3]._as(this._source.remove$1(0, key));
+ },
+ forEach$1: function(_, f) {
+ this._source.forEach$1(0, new H.CastMap_forEach_closure(this, this.$ti._eval$1("~(3,4)")._check(f)));
+ },
+ get$keys: function() {
+ var t1 = this.$ti;
+ return H.CastIterable_CastIterable(this._source.get$keys(), t1._precomputed1, t1._rest[2]);
+ },
+ get$length: function(_) {
+ var t1 = this._source;
+ return t1.get$length(t1);
+ },
+ get$isEmpty: function(_) {
+ var t1 = this._source;
+ return t1.get$isEmpty(t1);
+ }
+ };
+ H.CastMap_forEach_closure.prototype = {
+ call$2: function(key, value) {
+ var t1 = this.$this.$ti;
+ t1._precomputed1._check(key);
+ t1._rest[1]._check(value);
+ this.f.call$2(t1._rest[2]._as(key), t1._rest[3]._as(value));
+ },
+ $signature: function() {
+ return this.$this.$ti._eval$1("Null(1,2)");
+ }
+ };
+ H.CodeUnits.prototype = {
+ get$length: function(_) {
+ return this._string.length;
+ },
+ $index: function(_, i) {
+ return C.JSString_methods.codeUnitAt$1(this._string, H._checkIntNullable(i));
+ }
+ };
+ H.EfficientLengthIterable.prototype = {};
+ H.ListIterable.prototype = {
+ get$iterator: function(_) {
+ var _this = this;
+ return new H.ListIterator(_this, _this.get$length(_this), H._instanceType(_this)._eval$1("ListIterator<ListIterable.E>"));
+ },
+ get$isEmpty: function(_) {
+ return this.get$length(this) === 0;
+ },
+ get$first: function(_) {
+ if (this.get$length(this) === 0)
+ throw H.wrapException(H.IterableElementError_noElement());
+ return this.elementAt$1(0, 0);
+ },
+ get$last: function(_) {
+ var _this = this;
+ if (_this.get$length(_this) === 0)
+ throw H.wrapException(H.IterableElementError_noElement());
+ return _this.elementAt$1(0, _this.get$length(_this) - 1);
+ },
+ contains$1: function(_, element) {
+ var i, _this = this,
+ $length = _this.get$length(_this);
+ for (i = 0; i < $length; ++i) {
+ if (J.$eq$(_this.elementAt$1(0, i), element))
+ return true;
+ if ($length !== _this.get$length(_this))
+ throw H.wrapException(P.ConcurrentModificationError$(_this));
+ }
+ return false;
+ },
+ join$1: function(_, separator) {
+ var first, t1, i, _this = this,
+ $length = _this.get$length(_this);
+ if (separator.length !== 0) {
+ if ($length === 0)
+ return "";
+ first = H.S(_this.elementAt$1(0, 0));
+ if ($length !== _this.get$length(_this))
+ throw H.wrapException(P.ConcurrentModificationError$(_this));
+ for (t1 = first, i = 1; i < $length; ++i) {
+ t1 = t1 + separator + H.S(_this.elementAt$1(0, i));
+ if ($length !== _this.get$length(_this))
+ throw H.wrapException(P.ConcurrentModificationError$(_this));
+ }
+ return t1.charCodeAt(0) == 0 ? t1 : t1;
+ } else {
+ for (i = 0, t1 = ""; i < $length; ++i) {
+ t1 += H.S(_this.elementAt$1(0, i));
+ if ($length !== _this.get$length(_this))
+ throw H.wrapException(P.ConcurrentModificationError$(_this));
+ }
+ return t1.charCodeAt(0) == 0 ? t1 : t1;
+ }
+ },
+ join$0: function($receiver) {
+ return this.join$1($receiver, "");
+ },
+ map$1$1: function(_, f, $T) {
+ var t1 = H._instanceType(this);
+ return new H.MappedListIterable(this, t1._bind$1($T)._eval$1("1(ListIterable.E)")._check(f), t1._eval$1("@<ListIterable.E>")._bind$1($T)._eval$1("MappedListIterable<1,2>"));
+ },
+ fold$1$2: function(_, initialValue, combine, $T) {
+ var $length, value, i, _this = this;
+ $T._check(initialValue);
+ H._instanceType(_this)._bind$1($T)._eval$1("1(1,ListIterable.E)")._check(combine);
+ $length = _this.get$length(_this);
+ for (value = initialValue, i = 0; i < $length; ++i) {
+ value = combine.call$2(value, _this.elementAt$1(0, i));
+ if ($length !== _this.get$length(_this))
+ throw H.wrapException(P.ConcurrentModificationError$(_this));
+ }
+ return value;
+ },
+ toList$1$growable: function(_, growable) {
+ var i, _this = this,
+ result = H.setRuntimeTypeInfo([], H._instanceType(_this)._eval$1("JSArray<ListIterable.E>"));
+ C.JSArray_methods.set$length(result, _this.get$length(_this));
+ for (i = 0; i < _this.get$length(_this); ++i)
+ C.JSArray_methods.$indexSet(result, i, _this.elementAt$1(0, i));
+ return result;
+ },
+ toList$0: function($receiver) {
+ return this.toList$1$growable($receiver, true);
+ },
+ toSet$0: function(_) {
+ var i, _this = this,
+ result = P.LinkedHashSet_LinkedHashSet(H._instanceType(_this)._eval$1("ListIterable.E"));
+ for (i = 0; i < _this.get$length(_this); ++i)
+ result.add$1(0, _this.elementAt$1(0, i));
+ return result;
+ }
+ };
+ H.SubListIterable.prototype = {
+ get$_endIndex: function() {
+ var $length = J.get$length$asx(this.__internal$_iterable),
+ t1 = this._endOrLength;
+ if (t1 == null || t1 > $length)
+ return $length;
+ return t1;
+ },
+ get$_startIndex: function() {
+ var $length = J.get$length$asx(this.__internal$_iterable),
+ t1 = this.__internal$_start;
+ if (t1 > $length)
+ return $length;
+ return t1;
+ },
+ get$length: function(_) {
+ var t2,
+ $length = J.get$length$asx(this.__internal$_iterable),
+ t1 = this.__internal$_start;
+ if (t1 >= $length)
+ return 0;
+ t2 = this._endOrLength;
+ if (t2 == null || t2 >= $length)
+ return $length - t1;
+ if (typeof t2 !== "number")
+ return t2.$sub();
+ return t2 - t1;
+ },
+ elementAt$1: function(_, index) {
+ var t1, _this = this,
+ realIndex = _this.get$_startIndex() + index;
+ if (index >= 0) {
+ t1 = _this.get$_endIndex();
+ if (typeof t1 !== "number")
+ return H.iae(t1);
+ t1 = realIndex >= t1;
+ } else
+ t1 = true;
+ if (t1)
+ throw H.wrapException(P.IndexError$(index, _this, "index", null, null));
+ return J.elementAt$1$ax(_this.__internal$_iterable, realIndex);
+ },
+ take$1: function(_, count) {
+ var t1, t2, newEnd, _this = this;
+ P.RangeError_checkNotNegative(count, "count");
+ t1 = _this._endOrLength;
+ t2 = _this.__internal$_start;
+ newEnd = t2 + count;
+ if (t1 == null)
+ return H.SubListIterable$(_this.__internal$_iterable, t2, newEnd, _this.$ti._precomputed1);
+ else {
+ if (t1 < newEnd)
+ return _this;
+ return H.SubListIterable$(_this.__internal$_iterable, t2, newEnd, _this.$ti._precomputed1);
+ }
+ }
+ };
+ H.ListIterator.prototype = {
+ get$current: function() {
+ return this.__internal$_current;
+ },
+ moveNext$0: function() {
+ var t3, _this = this,
+ t1 = _this.__internal$_iterable,
+ t2 = J.getInterceptor$asx(t1),
+ $length = t2.get$length(t1);
+ if (_this.__internal$_length !== $length)
+ throw H.wrapException(P.ConcurrentModificationError$(t1));
+ t3 = _this.__internal$_index;
+ if (t3 >= $length) {
+ _this.set$__internal$_current(null);
+ return false;
+ }
+ _this.set$__internal$_current(t2.elementAt$1(t1, t3));
+ ++_this.__internal$_index;
+ return true;
+ },
+ set$__internal$_current: function(_current) {
+ this.__internal$_current = this.$ti._precomputed1._check(_current);
+ },
+ $isIterator: 1
+ };
+ H.MappedIterable.prototype = {
+ get$iterator: function(_) {
+ var t1 = H._instanceType(this);
+ return new H.MappedIterator(J.get$iterator$ax(this.__internal$_iterable), this._f, t1._eval$1("@<1>")._bind$1(t1._rest[1])._eval$1("MappedIterator<1,2>"));
+ },
+ get$length: function(_) {
+ return J.get$length$asx(this.__internal$_iterable);
+ },
+ get$isEmpty: function(_) {
+ return J.get$isEmpty$asx(this.__internal$_iterable);
+ },
+ get$first: function(_) {
+ return this._f.call$1(J.get$first$ax(this.__internal$_iterable));
+ },
+ get$last: function(_) {
+ return this._f.call$1(J.get$last$ax(this.__internal$_iterable));
+ }
+ };
+ H.EfficientLengthMappedIterable.prototype = {$isEfficientLengthIterable: 1};
+ H.MappedIterator.prototype = {
+ moveNext$0: function() {
+ var _this = this,
+ t1 = _this._iterator;
+ if (t1.moveNext$0()) {
+ _this.set$__internal$_current(_this._f.call$1(t1.get$current()));
+ return true;
+ }
+ _this.set$__internal$_current(null);
+ return false;
+ },
+ get$current: function() {
+ return this.__internal$_current;
+ },
+ set$__internal$_current: function(_current) {
+ this.__internal$_current = this.$ti._rest[1]._check(_current);
+ }
+ };
+ H.MappedListIterable.prototype = {
+ get$length: function(_) {
+ return J.get$length$asx(this._source);
+ },
+ elementAt$1: function(_, index) {
+ return this._f.call$1(J.elementAt$1$ax(this._source, index));
+ }
+ };
+ H.WhereIterable.prototype = {
+ get$iterator: function(_) {
+ return new H.WhereIterator(J.get$iterator$ax(this.__internal$_iterable), this._f, this.$ti._eval$1("WhereIterator<1>"));
+ },
+ map$1$1: function(_, f, $T) {
+ var t1 = this.$ti;
+ return new H.MappedIterable(this, t1._bind$1($T)._eval$1("1(2)")._check(f), t1._eval$1("@<1>")._bind$1($T)._eval$1("MappedIterable<1,2>"));
+ }
+ };
+ H.WhereIterator.prototype = {
+ moveNext$0: function() {
+ var t1, t2;
+ for (t1 = this._iterator, t2 = this._f; t1.moveNext$0();)
+ if (H.boolConversionCheck(t2.call$1(t1.get$current())))
+ return true;
+ return false;
+ },
+ get$current: function() {
+ return this._iterator.get$current();
+ }
+ };
+ H.ExpandIterable.prototype = {
+ get$iterator: function(_) {
+ var t1 = this.$ti;
+ return new H.ExpandIterator(J.get$iterator$ax(this.__internal$_iterable), this._f, C.C_EmptyIterator, t1._eval$1("@<1>")._bind$1(t1._rest[1])._eval$1("ExpandIterator<1,2>"));
+ }
+ };
+ H.ExpandIterator.prototype = {
+ get$current: function() {
+ return this.__internal$_current;
+ },
+ moveNext$0: function() {
+ var t1, t2, _this = this;
+ if (_this._currentExpansion == null)
+ return false;
+ for (t1 = _this._iterator, t2 = _this._f; !_this._currentExpansion.moveNext$0();) {
+ _this.set$__internal$_current(null);
+ if (t1.moveNext$0()) {
+ _this.set$_currentExpansion(null);
+ _this.set$_currentExpansion(J.get$iterator$ax(t2.call$1(t1.get$current())));
+ } else
+ return false;
+ }
+ _this.set$__internal$_current(_this._currentExpansion.get$current());
+ return true;
+ },
+ set$_currentExpansion: function(_currentExpansion) {
+ this._currentExpansion = this.$ti._eval$1("Iterator<2>")._check(_currentExpansion);
+ },
+ set$__internal$_current: function(_current) {
+ this.__internal$_current = this.$ti._rest[1]._check(_current);
+ },
+ $isIterator: 1
+ };
+ H.SkipWhileIterable.prototype = {
+ get$iterator: function(_) {
+ return new H.SkipWhileIterator(J.get$iterator$ax(this.__internal$_iterable), this._f, this.$ti._eval$1("SkipWhileIterator<1>"));
+ }
+ };
+ H.SkipWhileIterator.prototype = {
+ moveNext$0: function() {
+ var t1, t2, _this = this;
+ if (!_this._hasSkipped) {
+ _this._hasSkipped = true;
+ for (t1 = _this._iterator, t2 = _this._f; t1.moveNext$0();)
+ if (!H.boolConversionCheck(t2.call$1(t1.get$current())))
+ return true;
+ }
+ return _this._iterator.moveNext$0();
+ },
+ get$current: function() {
+ return this._iterator.get$current();
+ }
+ };
+ H.EmptyIterator.prototype = {
+ moveNext$0: function() {
+ return false;
+ },
+ get$current: function() {
+ return null;
+ },
+ $isIterator: 1
+ };
+ H.FixedLengthListMixin.prototype = {
+ set$length: function(receiver, newLength) {
+ throw H.wrapException(P.UnsupportedError$("Cannot change the length of a fixed-length list"));
+ }
+ };
+ H.UnmodifiableListMixin.prototype = {
+ $indexSet: function(_, index, value) {
+ H._checkIntNullable(index);
+ H._instanceType(this)._eval$1("UnmodifiableListMixin.E")._check(value);
+ throw H.wrapException(P.UnsupportedError$("Cannot modify an unmodifiable list"));
+ },
+ set$length: function(_, newLength) {
+ throw H.wrapException(P.UnsupportedError$("Cannot change the length of an unmodifiable list"));
+ }
+ };
+ H.UnmodifiableListBase.prototype = {};
+ H.ReversedListIterable.prototype = {
+ get$length: function(_) {
+ return J.get$length$asx(this._source);
+ },
+ elementAt$1: function(_, index) {
+ var t1 = this._source,
+ t2 = J.getInterceptor$asx(t1);
+ return t2.elementAt$1(t1, t2.get$length(t1) - 1 - index);
+ }
+ };
+ H.Symbol.prototype = {
+ get$hashCode: function(_) {
+ var hash = this._hashCode;
+ if (hash != null)
+ return hash;
+ hash = 536870911 & 664597 * J.get$hashCode$(this.__internal$_name);
+ this._hashCode = hash;
+ return hash;
+ },
+ toString$0: function(_) {
+ return 'Symbol("' + H.S(this.__internal$_name) + '")';
+ },
+ $eq: function(_, other) {
+ if (other == null)
+ return false;
+ return other instanceof H.Symbol && this.__internal$_name == other.__internal$_name;
+ }
+ };
+ H.ConstantMap.prototype = {
+ cast$2$0: function(_, RK, RV) {
+ var t1 = H._instanceType(this);
+ return P.Map_castFrom(this, t1._precomputed1, t1._rest[1], RK, RV);
+ },
+ get$isEmpty: function(_) {
+ return this.get$length(this) === 0;
+ },
+ toString$0: function(_) {
+ return P.MapBase_mapToString(this);
+ },
+ remove$1: function(_, key) {
+ return H.ConstantMap__throwUnmodifiable();
+ },
+ map$2$1: function(_, transform, K2, V2) {
+ var result = P.LinkedHashMap_LinkedHashMap$_empty(K2, V2);
+ this.forEach$1(0, new H.ConstantMap_map_closure(this, H._instanceType(this)._bind$1(K2)._bind$1(V2)._eval$1("MapEntry<1,2>(3,4)")._check(transform), result));
+ return result;
+ },
+ $isMap: 1
+ };
+ H.ConstantMap_map_closure.prototype = {
+ call$2: function(key, value) {
+ var t1 = H._instanceType(this.$this),
+ entry = this.transform.call$2(t1._precomputed1._check(key), t1._rest[1]._check(value));
+ this.result.$indexSet(0, entry.key, entry.value);
+ },
+ $signature: function() {
+ return H._instanceType(this.$this)._eval$1("Null(1,2)");
+ }
+ };
+ H.ConstantStringMap.prototype = {
+ get$length: function(_) {
+ return this.__js_helper$_length;
+ },
+ containsKey$1: function(key) {
+ if (typeof key != "string")
+ return false;
+ if ("__proto__" === key)
+ return false;
+ return this._jsObject.hasOwnProperty(key);
+ },
+ $index: function(_, key) {
+ if (!this.containsKey$1(key))
+ return null;
+ return this._fetch$1(key);
+ },
+ _fetch$1: function(key) {
+ return this._jsObject[H._checkStringNullable(key)];
+ },
+ forEach$1: function(_, f) {
+ var keys, t2, i, key,
+ t1 = H._instanceType(this);
+ t1._eval$1("~(1,2)")._check(f);
+ keys = this.__js_helper$_keys;
+ for (t2 = keys.length, t1 = t1._rest[1], i = 0; i < t2; ++i) {
+ key = keys[i];
+ f.call$2(key, t1._check(this._fetch$1(key)));
+ }
+ },
+ get$keys: function() {
+ return new H._ConstantMapKeyIterable(this, H._instanceType(this)._eval$1("_ConstantMapKeyIterable<1>"));
+ }
+ };
+ H._ConstantMapKeyIterable.prototype = {
+ get$iterator: function(_) {
+ var t1 = this.__js_helper$_map.__js_helper$_keys;
+ return new J.ArrayIterator(t1, t1.length, H._arrayInstanceType(t1)._eval$1("ArrayIterator<1>"));
+ },
+ get$length: function(_) {
+ return this.__js_helper$_map.__js_helper$_keys.length;
+ }
+ };
+ H.Instantiation.prototype = {
+ Instantiation$1: function(_genericClosure) {
+ if (false)
+ H.instantiatedGenericFunctionType(0, 0);
+ },
+ toString$0: function(_) {
+ var types = "<" + C.JSArray_methods.join$1([H.createRuntimeType(this.$ti._precomputed1)], ", ") + ">";
+ return H.S(this._genericClosure) + " with " + types;
+ }
+ };
+ H.Instantiation1.prototype = {
+ call$2: function(a0, a1) {
+ return this._genericClosure.call$1$2(a0, a1, this.$ti._rest[0]);
+ },
+ call$4: function(a0, a1, a2, a3) {
+ return this._genericClosure.call$1$4(a0, a1, a2, a3, this.$ti._rest[0]);
+ },
+ $signature: function() {
+ return H.instantiatedGenericFunctionType(H.closureFunctionType(this._genericClosure), this.$ti);
+ }
+ };
+ H.Primitives_initTicker_closure.prototype = {
+ call$0: function() {
+ return C.JSNumber_methods.floor$0(1000 * this.performance.now());
+ },
+ $signature: 36
+ };
+ H.TypeErrorDecoder.prototype = {
+ matchTypeError$1: function(message) {
+ var result, t1, _this = this,
+ match = new RegExp(_this._pattern).exec(message);
+ if (match == null)
+ return null;
+ result = Object.create(null);
+ t1 = _this._arguments;
+ if (t1 !== -1)
+ result.arguments = match[t1 + 1];
+ t1 = _this._argumentsExpr;
+ if (t1 !== -1)
+ result.argumentsExpr = match[t1 + 1];
+ t1 = _this._expr;
+ if (t1 !== -1)
+ result.expr = match[t1 + 1];
+ t1 = _this._method;
+ if (t1 !== -1)
+ result.method = match[t1 + 1];
+ t1 = _this._receiver;
+ if (t1 !== -1)
+ result.receiver = match[t1 + 1];
+ return result;
+ }
+ };
+ H.NullError.prototype = {
+ toString$0: function(_) {
+ var t1 = this._method;
+ if (t1 == null)
+ return "NoSuchMethodError: " + H.S(this.__js_helper$_message);
+ return "NoSuchMethodError: method not found: '" + t1 + "' on null";
+ },
+ $isNoSuchMethodError: 1
+ };
+ H.JsNoSuchMethodError.prototype = {
+ toString$0: function(_) {
+ var t2, _this = this,
+ _s38_ = "NoSuchMethodError: method not found: '",
+ t1 = _this._method;
+ if (t1 == null)
+ return "NoSuchMethodError: " + H.S(_this.__js_helper$_message);
+ t2 = _this._receiver;
+ if (t2 == null)
+ return _s38_ + t1 + "' (" + H.S(_this.__js_helper$_message) + ")";
+ return _s38_ + t1 + "' on '" + t2 + "' (" + H.S(_this.__js_helper$_message) + ")";
+ },
+ $isNoSuchMethodError: 1
+ };
+ H.UnknownJsTypeError.prototype = {
+ toString$0: function(_) {
+ var t1 = this.__js_helper$_message;
+ return t1.length === 0 ? "Error" : "Error: " + t1;
+ }
+ };
+ H.ExceptionAndStackTrace.prototype = {};
+ H.unwrapException_saveStackTrace.prototype = {
+ call$1: function(error) {
+ if (type$.Error._is(error))
+ if (error.$thrownJsError == null)
+ error.$thrownJsError = this.ex;
+ return error;
+ },
+ $signature: 18
+ };
+ H._StackTrace.prototype = {
+ toString$0: function(_) {
+ var trace,
+ t1 = this._trace;
+ if (t1 != null)
+ return t1;
+ t1 = this._exception;
+ trace = t1 !== null && typeof t1 === "object" ? t1.stack : null;
+ return this._trace = trace == null ? "" : trace;
+ },
+ $isStackTrace: 1
+ };
+ H.Closure.prototype = {
+ toString$0: function(_) {
+ var $constructor = this.constructor,
+ $name = $constructor == null ? null : $constructor.name;
+ return "Closure '" + H.unminifyOrTag($name == null ? "unknown" : $name) + "'";
+ },
+ $isFunction: 1,
+ get$$call: function() {
+ return this;
+ },
+ "call*": "call$1",
+ $requiredArgCount: 1,
+ $defaultValues: null
+ };
+ H.TearOffClosure.prototype = {};
+ H.StaticClosure.prototype = {
+ toString$0: function(_) {
+ var $name = this.$static_name;
+ if ($name == null)
+ return "Closure of unknown static method";
+ return "Closure '" + H.unminifyOrTag($name) + "'";
+ }
+ };
+ H.BoundClosure.prototype = {
+ $eq: function(_, other) {
+ var _this = this;
+ if (other == null)
+ return false;
+ if (_this === other)
+ return true;
+ if (!(other instanceof H.BoundClosure))
+ return false;
+ return _this._self === other._self && _this._target === other._target && _this._receiver === other._receiver;
+ },
+ get$hashCode: function(_) {
+ var receiverHashCode,
+ t1 = this._receiver;
+ if (t1 == null)
+ receiverHashCode = H.Primitives_objectHashCode(this._self);
+ else
+ receiverHashCode = typeof t1 !== "object" ? J.get$hashCode$(t1) : H.Primitives_objectHashCode(t1);
+ return (receiverHashCode ^ H.Primitives_objectHashCode(this._target)) >>> 0;
+ },
+ toString$0: function(_) {
+ var receiver = this._receiver;
+ if (receiver == null)
+ receiver = this._self;
+ return "Closure '" + H.S(this._name) + "' of " + ("Instance of '" + H.S(H.Primitives_objectTypeName(receiver)) + "'");
+ }
+ };
+ H.TypeErrorImplementation.prototype = {
+ toString$0: function(_) {
+ return this.message;
+ },
+ get$message: function(receiver) {
+ return this.message;
+ }
+ };
+ H.RuntimeError.prototype = {
+ toString$0: function(_) {
+ return "RuntimeError: " + H.S(this.message);
+ },
+ get$message: function(receiver) {
+ return this.message;
+ }
+ };
+ H._AssertionError.prototype = {
+ toString$0: function(_) {
+ return "Assertion failed: " + P.Error_safeToString(this.message);
+ }
+ };
+ H.JsLinkedHashMap.prototype = {
+ get$length: function(_) {
+ return this.__js_helper$_length;
+ },
+ get$isEmpty: function(_) {
+ return this.__js_helper$_length === 0;
+ },
+ get$keys: function() {
+ return new H.LinkedHashMapKeyIterable(this, H._instanceType(this)._eval$1("LinkedHashMapKeyIterable<1>"));
+ },
+ get$values: function() {
+ var t1 = H._instanceType(this);
+ return H.MappedIterable_MappedIterable(this.get$keys(), new H.JsLinkedHashMap_values_closure(this), t1._precomputed1, t1._rest[1]);
+ },
+ containsKey$1: function(key) {
+ var strings, nums, _this = this;
+ if (typeof key == "string") {
+ strings = _this.__js_helper$_strings;
+ if (strings == null)
+ return false;
+ return _this._containsTableEntry$2(strings, key);
+ } else if (typeof key == "number" && (key & 0x3ffffff) === key) {
+ nums = _this.__js_helper$_nums;
+ if (nums == null)
+ return false;
+ return _this._containsTableEntry$2(nums, key);
+ } else
+ return _this.internalContainsKey$1(key);
+ },
+ internalContainsKey$1: function(key) {
+ var _this = this,
+ rest = _this.__js_helper$_rest;
+ if (rest == null)
+ return false;
+ return _this.internalFindBucketIndex$2(_this._getTableBucket$2(rest, _this.internalComputeHashCode$1(key)), key) >= 0;
+ },
+ addAll$1: function(_, other) {
+ H._instanceType(this)._eval$1("Map<1,2>")._check(other).forEach$1(0, new H.JsLinkedHashMap_addAll_closure(this));
+ },
+ $index: function(_, key) {
+ var strings, cell, t1, nums, _this = this, _null = null;
+ if (typeof key == "string") {
+ strings = _this.__js_helper$_strings;
+ if (strings == null)
+ return _null;
+ cell = _this._getTableCell$2(strings, key);
+ t1 = cell == null ? _null : cell.hashMapCellValue;
+ return t1;
+ } else if (typeof key == "number" && (key & 0x3ffffff) === key) {
+ nums = _this.__js_helper$_nums;
+ if (nums == null)
+ return _null;
+ cell = _this._getTableCell$2(nums, key);
+ t1 = cell == null ? _null : cell.hashMapCellValue;
+ return t1;
+ } else
+ return _this.internalGet$1(key);
+ },
+ internalGet$1: function(key) {
+ var bucket, index, _this = this,
+ rest = _this.__js_helper$_rest;
+ if (rest == null)
+ return null;
+ bucket = _this._getTableBucket$2(rest, _this.internalComputeHashCode$1(key));
+ index = _this.internalFindBucketIndex$2(bucket, key);
+ if (index < 0)
+ return null;
+ return bucket[index].hashMapCellValue;
+ },
+ $indexSet: function(_, key, value) {
+ var strings, nums, _this = this,
+ t1 = H._instanceType(_this);
+ t1._precomputed1._check(key);
+ t1._rest[1]._check(value);
+ if (typeof key == "string") {
+ strings = _this.__js_helper$_strings;
+ _this.__js_helper$_addHashTableEntry$3(strings == null ? _this.__js_helper$_strings = _this._newHashTable$0() : strings, key, value);
+ } else if (typeof key == "number" && (key & 0x3ffffff) === key) {
+ nums = _this.__js_helper$_nums;
+ _this.__js_helper$_addHashTableEntry$3(nums == null ? _this.__js_helper$_nums = _this._newHashTable$0() : nums, key, value);
+ } else
+ _this.internalSet$2(key, value);
+ },
+ internalSet$2: function(key, value) {
+ var rest, hash, bucket, index, _this = this,
+ t1 = H._instanceType(_this);
+ t1._precomputed1._check(key);
+ t1._rest[1]._check(value);
+ rest = _this.__js_helper$_rest;
+ if (rest == null)
+ rest = _this.__js_helper$_rest = _this._newHashTable$0();
+ hash = _this.internalComputeHashCode$1(key);
+ bucket = _this._getTableBucket$2(rest, hash);
+ if (bucket == null)
+ _this._setTableEntry$3(rest, hash, [_this._newLinkedCell$2(key, value)]);
+ else {
+ index = _this.internalFindBucketIndex$2(bucket, key);
+ if (index >= 0)
+ bucket[index].hashMapCellValue = value;
+ else
+ bucket.push(_this._newLinkedCell$2(key, value));
+ }
+ },
+ putIfAbsent$2: function(key, ifAbsent) {
+ var value, _this = this,
+ t1 = H._instanceType(_this);
+ t1._precomputed1._check(key);
+ t1._eval$1("2()")._check(ifAbsent);
+ if (_this.containsKey$1(key))
+ return _this.$index(0, key);
+ value = ifAbsent.call$0();
+ _this.$indexSet(0, key, value);
+ return value;
+ },
+ remove$1: function(_, key) {
+ var _this = this;
+ if (typeof key == "string")
+ return _this.__js_helper$_removeHashTableEntry$2(_this.__js_helper$_strings, key);
+ else if (typeof key == "number" && (key & 0x3ffffff) === key)
+ return _this.__js_helper$_removeHashTableEntry$2(_this.__js_helper$_nums, key);
+ else
+ return _this.internalRemove$1(key);
+ },
+ internalRemove$1: function(key) {
+ var hash, bucket, index, cell, _this = this,
+ rest = _this.__js_helper$_rest;
+ if (rest == null)
+ return null;
+ hash = _this.internalComputeHashCode$1(key);
+ bucket = _this._getTableBucket$2(rest, hash);
+ index = _this.internalFindBucketIndex$2(bucket, key);
+ if (index < 0)
+ return null;
+ cell = bucket.splice(index, 1)[0];
+ _this.__js_helper$_unlinkCell$1(cell);
+ if (bucket.length === 0)
+ _this._deleteTableEntry$2(rest, hash);
+ return cell.hashMapCellValue;
+ },
+ clear$0: function(_) {
+ var _this = this;
+ if (_this.__js_helper$_length > 0) {
+ _this.__js_helper$_strings = _this.__js_helper$_nums = _this.__js_helper$_rest = _this._first = _this._last = null;
+ _this.__js_helper$_length = 0;
+ _this._modified$0();
+ }
+ },
+ forEach$1: function(_, action) {
+ var cell, modifications, _this = this;
+ H._instanceType(_this)._eval$1("~(1,2)")._check(action);
+ cell = _this._first;
+ modifications = _this._modifications;
+ for (; cell != null;) {
+ action.call$2(cell.hashMapCellKey, cell.hashMapCellValue);
+ if (modifications !== _this._modifications)
+ throw H.wrapException(P.ConcurrentModificationError$(_this));
+ cell = cell._next;
+ }
+ },
+ __js_helper$_addHashTableEntry$3: function(table, key, value) {
+ var cell, _this = this,
+ t1 = H._instanceType(_this);
+ t1._precomputed1._check(key);
+ t1._rest[1]._check(value);
+ cell = _this._getTableCell$2(table, key);
+ if (cell == null)
+ _this._setTableEntry$3(table, key, _this._newLinkedCell$2(key, value));
+ else
+ cell.hashMapCellValue = value;
+ },
+ __js_helper$_removeHashTableEntry$2: function(table, key) {
+ var cell;
+ if (table == null)
+ return null;
+ cell = this._getTableCell$2(table, key);
+ if (cell == null)
+ return null;
+ this.__js_helper$_unlinkCell$1(cell);
+ this._deleteTableEntry$2(table, key);
+ return cell.hashMapCellValue;
+ },
+ _modified$0: function() {
+ this._modifications = this._modifications + 1 & 67108863;
+ },
+ _newLinkedCell$2: function(key, value) {
+ var last, _this = this,
+ t1 = H._instanceType(_this),
+ cell = new H.LinkedHashMapCell(t1._precomputed1._check(key), t1._rest[1]._check(value));
+ if (_this._first == null)
+ _this._first = _this._last = cell;
+ else {
+ last = _this._last;
+ cell._previous = last;
+ _this._last = last._next = cell;
+ }
+ ++_this.__js_helper$_length;
+ _this._modified$0();
+ return cell;
+ },
+ __js_helper$_unlinkCell$1: function(cell) {
+ var _this = this,
+ previous = cell._previous,
+ next = cell._next;
+ if (previous == null) {
+ H.assertHelper(cell == _this._first);
+ _this._first = next;
+ } else
+ previous._next = next;
+ if (next == null) {
+ H.assertHelper(cell == _this._last);
+ _this._last = previous;
+ } else
+ next._previous = previous;
+ --_this.__js_helper$_length;
+ _this._modified$0();
+ },
+ internalComputeHashCode$1: function(key) {
+ return J.get$hashCode$(key) & 0x3ffffff;
+ },
+ internalFindBucketIndex$2: function(bucket, key) {
+ var $length, i;
+ if (bucket == null)
+ return -1;
+ $length = bucket.length;
+ for (i = 0; i < $length; ++i)
+ if (J.$eq$(bucket[i].hashMapCellKey, key))
+ return i;
+ return -1;
+ },
+ toString$0: function(_) {
+ return P.MapBase_mapToString(this);
+ },
+ _getTableCell$2: function(table, key) {
+ return table[key];
+ },
+ _getTableBucket$2: function(table, key) {
+ return table[key];
+ },
+ _setTableEntry$3: function(table, key, value) {
+ H.assertHelper(value != null);
+ table[key] = value;
+ },
+ _deleteTableEntry$2: function(table, key) {
+ delete table[key];
+ },
+ _containsTableEntry$2: function(table, key) {
+ return this._getTableCell$2(table, key) != null;
+ },
+ _newHashTable$0: function() {
+ var _s20_ = "<non-identifier-key>",
+ table = Object.create(null);
+ this._setTableEntry$3(table, _s20_, table);
+ this._deleteTableEntry$2(table, _s20_);
+ return table;
+ },
+ $isLinkedHashMap: 1
+ };
+ H.JsLinkedHashMap_values_closure.prototype = {
+ call$1: function(each) {
+ var t1 = this.$this;
+ return t1.$index(0, H._instanceType(t1)._precomputed1._check(each));
+ },
+ $signature: function() {
+ return H._instanceType(this.$this)._eval$1("2(1)");
+ }
+ };
+ H.JsLinkedHashMap_addAll_closure.prototype = {
+ call$2: function(key, value) {
+ var t1 = this.$this,
+ t2 = H._instanceType(t1);
+ t1.$indexSet(0, t2._precomputed1._check(key), t2._rest[1]._check(value));
+ },
+ $signature: function() {
+ return H._instanceType(this.$this)._eval$1("Null(1,2)");
+ }
+ };
+ H.LinkedHashMapCell.prototype = {};
+ H.LinkedHashMapKeyIterable.prototype = {
+ get$length: function(_) {
+ return this.__js_helper$_map.__js_helper$_length;
+ },
+ get$isEmpty: function(_) {
+ return this.__js_helper$_map.__js_helper$_length === 0;
+ },
+ get$iterator: function(_) {
+ var t1 = this.__js_helper$_map,
+ t2 = new H.LinkedHashMapKeyIterator(t1, t1._modifications, this.$ti._eval$1("LinkedHashMapKeyIterator<1>"));
+ t2._cell = t1._first;
+ return t2;
+ },
+ contains$1: function(_, element) {
+ return this.__js_helper$_map.containsKey$1(element);
+ }
+ };
+ H.LinkedHashMapKeyIterator.prototype = {
+ get$current: function() {
+ return this.__js_helper$_current;
+ },
+ moveNext$0: function() {
+ var _this = this,
+ t1 = _this.__js_helper$_map;
+ if (_this._modifications !== t1._modifications)
+ throw H.wrapException(P.ConcurrentModificationError$(t1));
+ else {
+ t1 = _this._cell;
+ if (t1 == null) {
+ _this.set$__js_helper$_current(null);
+ return false;
+ } else {
+ _this.set$__js_helper$_current(t1.hashMapCellKey);
+ _this._cell = _this._cell._next;
+ return true;
+ }
+ }
+ },
+ set$__js_helper$_current: function(_current) {
+ this.__js_helper$_current = this.$ti._precomputed1._check(_current);
+ },
+ $isIterator: 1
+ };
+ H.initHooks_closure.prototype = {
+ call$1: function(o) {
+ return this.getTag(o);
+ },
+ $signature: 18
+ };
+ H.initHooks_closure0.prototype = {
+ call$2: function(o, tag) {
+ return this.getUnknownTag(o, tag);
+ },
+ $signature: 104
+ };
+ H.initHooks_closure1.prototype = {
+ call$1: function(tag) {
+ return this.prototypeForTag(H._checkStringNullable(tag));
+ },
+ $signature: 94
+ };
+ H.JSSyntaxRegExp.prototype = {
+ toString$0: function(_) {
+ return "RegExp/" + this.pattern + "/" + this._nativeRegExp.flags;
+ },
+ get$_nativeGlobalVersion: function() {
+ var _this = this,
+ t1 = _this._nativeGlobalRegExp;
+ if (t1 != null)
+ return t1;
+ t1 = _this._nativeRegExp;
+ return _this._nativeGlobalRegExp = H.JSSyntaxRegExp_makeNative(_this.pattern, t1.multiline, !t1.ignoreCase, t1.unicode, t1.dotAll, true);
+ },
+ get$_nativeAnchoredVersion: function() {
+ var _this = this,
+ t1 = _this._nativeAnchoredRegExp;
+ if (t1 != null)
+ return t1;
+ t1 = _this._nativeRegExp;
+ return _this._nativeAnchoredRegExp = H.JSSyntaxRegExp_makeNative(_this.pattern + "|()", t1.multiline, !t1.ignoreCase, t1.unicode, t1.dotAll, true);
+ },
+ firstMatch$1: function(string) {
+ var m;
+ if (typeof string != "string")
+ H.throwExpression(H.argumentErrorValue(string));
+ m = this._nativeRegExp.exec(string);
+ if (m == null)
+ return null;
+ return H._MatchImplementation$(this, m);
+ },
+ allMatches$2: function(_, string, start) {
+ var t1 = string.length;
+ if (start > t1)
+ throw H.wrapException(P.RangeError$range(start, 0, t1, null, null));
+ return new H._AllMatchesIterable(this, string, start);
+ },
+ allMatches$1: function($receiver, string) {
+ return this.allMatches$2($receiver, string, 0);
+ },
+ _execGlobal$2: function(string, start) {
+ var match,
+ regexp = this.get$_nativeGlobalVersion();
+ regexp.lastIndex = start;
+ match = regexp.exec(string);
+ if (match == null)
+ return null;
+ return H._MatchImplementation$(this, match);
+ },
+ _execAnchored$2: function(string, start) {
+ var match,
+ regexp = this.get$_nativeAnchoredVersion();
+ regexp.lastIndex = start;
+ match = regexp.exec(string);
+ if (match == null)
+ return null;
+ if (0 >= match.length)
+ return H.ioore(match, -1);
+ if (match.pop() != null)
+ return null;
+ return H._MatchImplementation$(this, match);
+ },
+ matchAsPrefix$2: function(_, string, start) {
+ if (start < 0 || start > string.length)
+ throw H.wrapException(P.RangeError$range(start, 0, string.length, null, null));
+ return this._execAnchored$2(string, start);
+ },
+ $isPattern: 1,
+ $isRegExp: 1
+ };
+ H._MatchImplementation.prototype = {
+ get$start: function() {
+ return this._match.index;
+ },
+ get$end: function() {
+ var t1 = this._match;
+ return t1.index + t1[0].length;
+ },
+ $index: function(_, index) {
+ var t1;
+ H._checkIntNullable(index);
+ t1 = this._match;
+ if (index >= t1.length)
+ return H.ioore(t1, index);
+ return t1[index];
+ },
+ $isMatch: 1,
+ $isRegExpMatch: 1
+ };
+ H._AllMatchesIterable.prototype = {
+ get$iterator: function(_) {
+ return new H._AllMatchesIterator(this._re, this.__js_helper$_string, this._start);
+ }
+ };
+ H._AllMatchesIterator.prototype = {
+ get$current: function() {
+ return this.__js_helper$_current;
+ },
+ moveNext$0: function() {
+ var t2, t3, match, nextIndex, _this = this,
+ t1 = _this.__js_helper$_string;
+ if (t1 == null)
+ return false;
+ t2 = _this._nextIndex;
+ if (t2 <= t1.length) {
+ t3 = _this._regExp;
+ match = t3._execGlobal$2(t1, t2);
+ if (match != null) {
+ _this.__js_helper$_current = match;
+ nextIndex = match.get$end();
+ if (match._match.index === nextIndex) {
+ if (t3._nativeRegExp.unicode) {
+ t1 = _this._nextIndex;
+ t2 = t1 + 1;
+ t3 = _this.__js_helper$_string;
+ if (t2 < t3.length) {
+ t1 = J.getInterceptor$s(t3).codeUnitAt$1(t3, t1);
+ if (t1 >= 55296 && t1 <= 56319) {
+ t1 = C.JSString_methods.codeUnitAt$1(t3, t2);
+ t1 = t1 >= 56320 && t1 <= 57343;
+ } else
+ t1 = false;
+ } else
+ t1 = false;
+ } else
+ t1 = false;
+ nextIndex = (t1 ? nextIndex + 1 : nextIndex) + 1;
+ }
+ _this._nextIndex = nextIndex;
+ return true;
+ }
+ }
+ _this.__js_helper$_string = _this.__js_helper$_current = null;
+ return false;
+ },
+ $isIterator: 1
+ };
+ H.StringMatch.prototype = {
+ get$end: function() {
+ return this.start + this.pattern.length;
+ },
+ $index: function(_, g) {
+ H._checkIntNullable(g);
+ if (g !== 0)
+ H.throwExpression(P.RangeError$value(g, null));
+ return this.pattern;
+ },
+ $isMatch: 1,
+ get$start: function() {
+ return this.start;
+ }
+ };
+ H._StringAllMatchesIterable.prototype = {
+ get$iterator: function(_) {
+ return new H._StringAllMatchesIterator(this._input, this._pattern, this.__js_helper$_index);
+ },
+ get$first: function(_) {
+ var t1 = this._pattern,
+ index = this._input.indexOf(t1, this.__js_helper$_index);
+ if (index >= 0)
+ return new H.StringMatch(index, t1);
+ throw H.wrapException(H.IterableElementError_noElement());
+ }
+ };
+ H._StringAllMatchesIterator.prototype = {
+ moveNext$0: function() {
+ var index, end, _this = this,
+ t1 = _this.__js_helper$_index,
+ t2 = _this._pattern,
+ t3 = t2.length,
+ t4 = _this._input,
+ t5 = t4.length;
+ if (t1 + t3 > t5) {
+ _this.__js_helper$_current = null;
+ return false;
+ }
+ index = t4.indexOf(t2, t1);
+ if (index < 0) {
+ _this.__js_helper$_index = t5 + 1;
+ _this.__js_helper$_current = null;
+ return false;
+ }
+ end = index + t3;
+ _this.__js_helper$_current = new H.StringMatch(index, t2);
+ _this.__js_helper$_index = end === _this.__js_helper$_index ? end + 1 : end;
+ return true;
+ },
+ get$current: function() {
+ return this.__js_helper$_current;
+ },
+ $isIterator: 1
+ };
+ H.NativeByteBuffer.prototype = {
+ get$runtimeType: function(receiver) {
+ return C.Type_ByteBuffer_RkP;
+ },
+ $isNativeByteBuffer: 1,
+ $isByteBuffer: 1
+ };
+ H.NativeTypedData.prototype = {$isNativeTypedData: 1};
+ H.NativeByteData.prototype = {
+ get$runtimeType: function(receiver) {
+ return C.Type_ByteData_zNC;
+ }
+ };
+ H.NativeTypedArray.prototype = {
+ get$length: function(receiver) {
+ return receiver.length;
+ },
+ $isJavaScriptIndexingBehavior: 1
+ };
+ H.NativeTypedArrayOfDouble.prototype = {
+ $index: function(receiver, index) {
+ H._checkIntNullable(index);
+ H._checkValidIndex(index, receiver, receiver.length);
+ return receiver[index];
+ },
+ $indexSet: function(receiver, index, value) {
+ H._checkIntNullable(index);
+ H._checkDoubleNullable(value);
+ H._checkValidIndex(index, receiver, receiver.length);
+ receiver[index] = value;
+ },
+ $isEfficientLengthIterable: 1,
+ $isIterable: 1,
+ $isList: 1
+ };
+ H.NativeTypedArrayOfInt.prototype = {
+ $indexSet: function(receiver, index, value) {
+ H._checkIntNullable(index);
+ H._checkIntNullable(value);
+ H._checkValidIndex(index, receiver, receiver.length);
+ receiver[index] = value;
+ },
+ $isEfficientLengthIterable: 1,
+ $isIterable: 1,
+ $isList: 1
+ };
+ H.NativeFloat32List.prototype = {
+ get$runtimeType: function(receiver) {
+ return C.Type_Float32List_LB7;
+ }
+ };
+ H.NativeFloat64List.prototype = {
+ get$runtimeType: function(receiver) {
+ return C.Type_Float64List_LB7;
+ }
+ };
+ H.NativeInt16List.prototype = {
+ get$runtimeType: function(receiver) {
+ return C.Type_Int16List_uXf;
+ },
+ $index: function(receiver, index) {
+ H._checkIntNullable(index);
+ H._checkValidIndex(index, receiver, receiver.length);
+ return receiver[index];
+ }
+ };
+ H.NativeInt32List.prototype = {
+ get$runtimeType: function(receiver) {
+ return C.Type_Int32List_O50;
+ },
+ $index: function(receiver, index) {
+ H._checkIntNullable(index);
+ H._checkValidIndex(index, receiver, receiver.length);
+ return receiver[index];
+ }
+ };
+ H.NativeInt8List.prototype = {
+ get$runtimeType: function(receiver) {
+ return C.Type_Int8List_ekJ;
+ },
+ $index: function(receiver, index) {
+ H._checkIntNullable(index);
+ H._checkValidIndex(index, receiver, receiver.length);
+ return receiver[index];
+ }
+ };
+ H.NativeUint16List.prototype = {
+ get$runtimeType: function(receiver) {
+ return C.Type_Uint16List_2bx;
+ },
+ $index: function(receiver, index) {
+ H._checkIntNullable(index);
+ H._checkValidIndex(index, receiver, receiver.length);
+ return receiver[index];
+ }
+ };
+ H.NativeUint32List.prototype = {
+ get$runtimeType: function(receiver) {
+ return C.Type_Uint32List_2bx;
+ },
+ $index: function(receiver, index) {
+ H._checkIntNullable(index);
+ H._checkValidIndex(index, receiver, receiver.length);
+ return receiver[index];
+ },
+ sublist$2: function(receiver, start, end) {
+ return new Uint32Array(receiver.subarray(start, H._checkValidRange(start, end, receiver.length)));
+ },
+ $isUint32List: 1
+ };
+ H.NativeUint8ClampedList.prototype = {
+ get$runtimeType: function(receiver) {
+ return C.Type_Uint8ClampedList_Jik;
+ },
+ get$length: function(receiver) {
+ return receiver.length;
+ },
+ $index: function(receiver, index) {
+ H._checkIntNullable(index);
+ H._checkValidIndex(index, receiver, receiver.length);
+ return receiver[index];
+ }
+ };
+ H.NativeUint8List.prototype = {
+ get$runtimeType: function(receiver) {
+ return C.Type_Uint8List_WLA;
+ },
+ get$length: function(receiver) {
+ return receiver.length;
+ },
+ $index: function(receiver, index) {
+ H._checkIntNullable(index);
+ H._checkValidIndex(index, receiver, receiver.length);
+ return receiver[index];
+ },
+ sublist$2: function(receiver, start, end) {
+ return new Uint8Array(receiver.subarray(start, H._checkValidRange(start, end, receiver.length)));
+ },
+ $isNativeUint8List: 1,
+ $isUint8List: 1
+ };
+ H._NativeTypedArrayOfDouble_NativeTypedArray_ListMixin.prototype = {};
+ H._NativeTypedArrayOfDouble_NativeTypedArray_ListMixin_FixedLengthListMixin.prototype = {};
+ H._NativeTypedArrayOfInt_NativeTypedArray_ListMixin.prototype = {};
+ H._NativeTypedArrayOfInt_NativeTypedArray_ListMixin_FixedLengthListMixin.prototype = {};
+ H.Rti.prototype = {
+ _eval$1: function(recipe) {
+ return H._Universe_evalInEnvironment(init.typeUniverse, this, recipe);
+ },
+ _bind$1: function(typeOrTuple) {
+ return H._Universe_bind(init.typeUniverse, this, typeOrTuple);
+ }
+ };
+ H._FunctionParameters.prototype = {};
+ H._Type.prototype = {
+ get$hashCode: function(_) {
+ var s,
+ t1 = this._hashCode;
+ if (t1 == null) {
+ s = this._rti._canonicalRecipe;
+ if (H.assertTest(typeof s == "string"))
+ H.assertThrow("Missing canonical recipe");
+ t1 = this._hashCode = C.JSString_methods.get$hashCode(s);
+ }
+ return t1;
+ },
+ $eq: function(_, other) {
+ if (other == null)
+ return false;
+ return other instanceof H._Type && this._rti == other._rti;
+ },
+ toString$0: function(_) {
+ return H._rtiToString(this._rti, null);
+ },
+ $isType: 1
+ };
+ H._Error.prototype = {
+ toString$0: function(_) {
+ return this._message;
+ }
+ };
+ H._CastError.prototype = {};
+ H._TypeError.prototype = {
+ get$message: function(_) {
+ return this._message;
+ }
+ };
+ P._AsyncRun__initializeScheduleImmediate_internalCallback.prototype = {
+ call$1: function(_) {
+ var t1 = this._box_0,
+ f = t1.storedCallback;
+ t1.storedCallback = null;
+ f.call$0();
+ },
+ $signature: 3
+ };
+ P._AsyncRun__initializeScheduleImmediate_closure.prototype = {
+ call$1: function(callback) {
+ var t1, t2;
+ type$.void_Function._check(callback);
+ t1 = this._box_0;
+ H.assertHelper(t1.storedCallback == null);
+ t1.storedCallback = callback;
+ t1 = this.div;
+ t2 = this.span;
+ t1.firstChild ? t1.removeChild(t2) : t1.appendChild(t2);
+ },
+ $signature: 91
+ };
+ P._AsyncRun__scheduleImmediateJsOverride_internalCallback.prototype = {
+ call$0: function() {
+ this.callback.call$0();
+ },
+ $signature: 0
+ };
+ P._AsyncRun__scheduleImmediateWithSetImmediate_internalCallback.prototype = {
+ call$0: function() {
+ this.callback.call$0();
+ },
+ $signature: 0
+ };
+ P._TimerImpl.prototype = {
+ _TimerImpl$2: function(milliseconds, callback) {
+ if (self.setTimeout != null)
+ this._handle = self.setTimeout(H.convertDartClosureToJS(new P._TimerImpl_internalCallback(this, callback), 0), milliseconds);
+ else
+ throw H.wrapException(P.UnsupportedError$("`setTimeout()` not found."));
+ },
+ _TimerImpl$periodic$2: function(milliseconds, callback) {
+ if (self.setTimeout != null)
+ this._handle = self.setInterval(H.convertDartClosureToJS(new P._TimerImpl$periodic_closure(this, milliseconds, Date.now(), callback), 0), milliseconds);
+ else
+ throw H.wrapException(P.UnsupportedError$("Periodic timer."));
+ },
+ cancel$0: function() {
+ if (self.setTimeout != null) {
+ var t1 = this._handle;
+ if (t1 == null)
+ return;
+ if (this._once)
+ self.clearTimeout(t1);
+ else
+ self.clearInterval(t1);
+ this._handle = null;
+ } else
+ throw H.wrapException(P.UnsupportedError$("Canceling a timer."));
+ },
+ $isTimer: 1
+ };
+ P._TimerImpl_internalCallback.prototype = {
+ call$0: function() {
+ var t1 = this.$this;
+ t1._handle = null;
+ t1._tick = 1;
+ this.callback.call$0();
+ },
+ $signature: 1
+ };
+ P._TimerImpl$periodic_closure.prototype = {
+ call$0: function() {
+ var duration, _this = this,
+ t1 = _this.$this,
+ tick = t1._tick + 1,
+ t2 = _this.milliseconds;
+ if (t2 > 0) {
+ duration = Date.now() - _this.start;
+ if (duration > (tick + 1) * t2)
+ tick = C.JSInt_methods.$tdiv(duration, t2);
+ }
+ t1._tick = tick;
+ _this.callback.call$1(t1);
+ },
+ $signature: 0
+ };
+ P._AsyncAwaitCompleter.prototype = {
+ complete$1: function(value) {
+ var t2, t3,
+ t1 = this.$ti;
+ t1._eval$1("1/")._check(value);
+ t2 = !this.isSync || t1._eval$1("Future<1>")._is(value);
+ t3 = this._future;
+ if (t2)
+ t3._asyncComplete$1(value);
+ else
+ t3._completeWithValue$1(t1._precomputed1._check(value));
+ },
+ completeError$2: function(e, st) {
+ var t1 = this._future;
+ if (this.isSync)
+ t1._completeError$2(e, st);
+ else
+ t1._asyncCompleteError$2(e, st);
+ },
+ $isCompleter: 1
+ };
+ P._awaitOnObject_closure.prototype = {
+ call$1: function(result) {
+ return this.bodyFunction.call$2(0, result);
+ },
+ $signature: 15
+ };
+ P._awaitOnObject_closure0.prototype = {
+ call$2: function(error, stackTrace) {
+ this.bodyFunction.call$2(1, new H.ExceptionAndStackTrace(error, type$.StackTrace._check(stackTrace)));
+ },
+ $signature: 5
+ };
+ P._wrapJsFunctionForAsync_closure.prototype = {
+ call$2: function(errorCode, result) {
+ this.$protected(H._checkIntNullable(errorCode), result);
+ },
+ $signature: 89
+ };
+ P._BroadcastStream.prototype = {
+ get$isBroadcast: function() {
+ return true;
+ }
+ };
+ P._BroadcastSubscription.prototype = {
+ _onPause$0: function() {
+ },
+ _onResume$0: function() {
+ },
+ set$_async$_next: function(_next) {
+ this._async$_next = this.$ti._check(_next);
+ },
+ set$_async$_previous: function(_previous) {
+ this._async$_previous = this.$ti._check(_previous);
+ }
+ };
+ P._BroadcastStreamController.prototype = {
+ get$_mayAddEvent: function() {
+ return this._state < 4;
+ },
+ _ensureDoneFuture$0: function() {
+ var t1 = this._doneFuture;
+ if (t1 != null)
+ return t1;
+ return this._doneFuture = new P._Future($.Zone__current, type$._Future_dynamic);
+ },
+ _removeListener$1: function(subscription) {
+ var previous, next, _this = this;
+ H._instanceType(_this)._eval$1("_BroadcastSubscription<1>")._check(subscription);
+ H.assertHelper(subscription._controller === _this);
+ H.assertHelper(subscription._async$_next !== subscription);
+ previous = subscription._async$_previous;
+ next = subscription._async$_next;
+ if (previous == null)
+ _this.set$_firstSubscription(next);
+ else
+ previous.set$_async$_next(next);
+ if (next == null)
+ _this.set$_lastSubscription(previous);
+ else
+ next.set$_async$_previous(previous);
+ subscription.set$_async$_previous(subscription);
+ subscription.set$_async$_next(subscription);
+ },
+ _subscribe$4: function(onData, onError, onDone, cancelOnError) {
+ var t2, t3, t4, subscription, oldLast, _this = this,
+ t1 = H._instanceType(_this);
+ t1._eval$1("~(1)")._check(onData);
+ type$.void_Function._check(onDone);
+ if ((_this._state & 4) !== 0) {
+ if (onDone == null)
+ onDone = P.async___nullDoneHandler$closure();
+ t1 = new P._DoneStreamSubscription($.Zone__current, onDone, t1._eval$1("_DoneStreamSubscription<1>"));
+ t1._schedule$0();
+ return t1;
+ }
+ t2 = $.Zone__current;
+ t3 = cancelOnError ? 1 : 0;
+ t4 = t1._eval$1("_BroadcastSubscription<1>");
+ subscription = new P._BroadcastSubscription(_this, t2, t3, t4);
+ subscription._BufferingStreamSubscription$4(onData, onError, onDone, cancelOnError, t1._precomputed1);
+ subscription.set$_async$_previous(subscription);
+ subscription.set$_async$_next(subscription);
+ t4._check(subscription);
+ H.assertHelper(subscription._async$_next === subscription);
+ subscription._eventState = _this._state & 1;
+ oldLast = _this._lastSubscription;
+ _this.set$_lastSubscription(subscription);
+ subscription.set$_async$_next(null);
+ subscription.set$_async$_previous(oldLast);
+ if (oldLast == null)
+ _this.set$_firstSubscription(subscription);
+ else
+ oldLast.set$_async$_next(subscription);
+ if (_this._firstSubscription == _this._lastSubscription)
+ P._runGuarded(_this.onListen);
+ return subscription;
+ },
+ _recordCancel$1: function(sub) {
+ var _this = this,
+ t1 = H._instanceType(_this);
+ sub = t1._eval$1("_BroadcastSubscription<1>")._check(t1._eval$1("StreamSubscription<1>")._check(sub));
+ if (sub._async$_next === sub)
+ return null;
+ t1 = (sub._eventState & 2) !== 0;
+ if (t1) {
+ H.assertHelper(t1);
+ sub._eventState |= 4;
+ } else {
+ _this._removeListener$1(sub);
+ if ((_this._state & 2) === 0 && _this._firstSubscription == null)
+ _this._callOnCancel$0();
+ }
+ return null;
+ },
+ _recordPause$1: function(subscription) {
+ H._instanceType(this)._eval$1("StreamSubscription<1>")._check(subscription);
+ },
+ _recordResume$1: function(subscription) {
+ H._instanceType(this)._eval$1("StreamSubscription<1>")._check(subscription);
+ },
+ _addEventError$0: function() {
+ var t1 = this._state;
+ if ((t1 & 4) !== 0)
+ return new P.StateError("Cannot add new events after calling close");
+ H.assertHelper((t1 & 8) !== 0);
+ return new P.StateError("Cannot add new events while doing an addStream");
+ },
+ add$1: function(_, data) {
+ var _this = this;
+ H._instanceType(_this)._precomputed1._check(data);
+ if (!_this.get$_mayAddEvent())
+ throw H.wrapException(_this._addEventError$0());
+ _this._sendData$1(data);
+ },
+ addError$2: function(error, stackTrace) {
+ var replacement;
+ type$.StackTrace._check(stackTrace);
+ if (error == null)
+ error = new P.NullThrownError();
+ if (!this.get$_mayAddEvent())
+ throw H.wrapException(this._addEventError$0());
+ replacement = $.Zone__current.errorCallback$2(error, stackTrace);
+ if (replacement != null) {
+ error = replacement.error;
+ if (error == null)
+ error = new P.NullThrownError();
+ stackTrace = replacement.stackTrace;
+ }
+ this._sendError$2(error, stackTrace);
+ },
+ addError$1: function(error) {
+ return this.addError$2(error, null);
+ },
+ close$0: function(_) {
+ var doneFuture, _this = this;
+ if ((_this._state & 4) !== 0) {
+ H.assertHelper(_this._doneFuture != null);
+ return _this._doneFuture;
+ }
+ if (!_this.get$_mayAddEvent())
+ throw H.wrapException(_this._addEventError$0());
+ _this._state |= 4;
+ doneFuture = _this._ensureDoneFuture$0();
+ _this._sendDone$0();
+ return doneFuture;
+ },
+ _async$_addError$2: function(error, stackTrace) {
+ this._sendError$2(error, type$.StackTrace._check(stackTrace));
+ },
+ _close$0: function() {
+ var addState, _this = this;
+ H.assertHelper((_this._state & 8) !== 0);
+ addState = _this._addStreamState;
+ _this.set$_addStreamState(null);
+ _this._state &= 4294967287;
+ addState.addStreamFuture._asyncComplete$1(null);
+ },
+ _forEachListener$1: function(action) {
+ var t1, subscription, id, next, _this = this;
+ H._instanceType(_this)._eval$1("~(_BufferingStreamSubscription<1>)")._check(action);
+ t1 = _this._state;
+ if ((t1 & 2) !== 0)
+ throw H.wrapException(P.StateError$("Cannot fire new event. Controller is already firing an event"));
+ subscription = _this._firstSubscription;
+ if (subscription == null)
+ return;
+ id = t1 & 1;
+ _this._state = t1 ^ 3;
+ for (; subscription != null;) {
+ t1 = subscription._eventState;
+ if ((t1 & 1) === id) {
+ subscription._eventState = t1 | 2;
+ action.call$1(subscription);
+ t1 = subscription._eventState ^= 1;
+ next = subscription._async$_next;
+ if ((t1 & 4) !== 0)
+ _this._removeListener$1(subscription);
+ subscription._eventState &= 4294967293;
+ subscription = next;
+ } else
+ subscription = subscription._async$_next;
+ }
+ _this._state &= 4294967293;
+ if (_this._firstSubscription == null)
+ _this._callOnCancel$0();
+ },
+ _callOnCancel$0: function() {
+ var _this = this;
+ H.assertHelper(_this._firstSubscription == null);
+ if ((_this._state & 4) !== 0 && _this._doneFuture._state === 0)
+ _this._doneFuture._asyncComplete$1(null);
+ P._runGuarded(_this.onCancel);
+ },
+ set$_firstSubscription: function(_firstSubscription) {
+ this._firstSubscription = H._instanceType(this)._eval$1("_BroadcastSubscription<1>")._check(_firstSubscription);
+ },
+ set$_lastSubscription: function(_lastSubscription) {
+ this._lastSubscription = H._instanceType(this)._eval$1("_BroadcastSubscription<1>")._check(_lastSubscription);
+ },
+ set$_addStreamState: function(_addStreamState) {
+ this._addStreamState = H._instanceType(this)._eval$1("_AddStreamState<1>")._check(_addStreamState);
+ },
+ $isEventSink: 1,
+ $isStreamConsumer: 1,
+ $isStreamSink: 1,
+ $isStreamController: 1,
+ $is_StreamControllerLifecycle: 1,
+ $is_EventDispatch: 1,
+ $isSink: 1
+ };
+ P._SyncBroadcastStreamController.prototype = {
+ get$_mayAddEvent: function() {
+ return P._BroadcastStreamController.prototype.get$_mayAddEvent.call(this) && (this._state & 2) === 0;
+ },
+ _addEventError$0: function() {
+ if ((this._state & 2) !== 0)
+ return new P.StateError("Cannot fire new event. Controller is already firing an event");
+ return this.super$_BroadcastStreamController$_addEventError();
+ },
+ _sendData$1: function(data) {
+ var t1, _this = this;
+ _this.$ti._precomputed1._check(data);
+ if (_this._firstSubscription == null)
+ return;
+ t1 = _this._firstSubscription;
+ if (t1 == _this._lastSubscription) {
+ _this._state |= 2;
+ t1._add$1(data);
+ _this._state &= 4294967293;
+ if (_this._firstSubscription == null)
+ _this._callOnCancel$0();
+ return;
+ }
+ _this._forEachListener$1(new P._SyncBroadcastStreamController__sendData_closure(_this, data));
+ },
+ _sendError$2: function(error, stackTrace) {
+ if (this._firstSubscription == null)
+ return;
+ this._forEachListener$1(new P._SyncBroadcastStreamController__sendError_closure(this, error, stackTrace));
+ },
+ _sendDone$0: function() {
+ var _this = this;
+ if (_this._firstSubscription != null)
+ _this._forEachListener$1(new P._SyncBroadcastStreamController__sendDone_closure(_this));
+ else {
+ H.assertHelper(_this._doneFuture != null);
+ H.assertHelper(_this._doneFuture._state === 0);
+ _this._doneFuture._asyncComplete$1(null);
+ }
+ }
+ };
+ P._SyncBroadcastStreamController__sendData_closure.prototype = {
+ call$1: function(subscription) {
+ this.$this.$ti._eval$1("_BufferingStreamSubscription<1>")._check(subscription)._add$1(this.data);
+ },
+ $signature: function() {
+ return this.$this.$ti._eval$1("Null(_BufferingStreamSubscription<1>)");
+ }
+ };
+ P._SyncBroadcastStreamController__sendError_closure.prototype = {
+ call$1: function(subscription) {
+ this.$this.$ti._eval$1("_BufferingStreamSubscription<1>")._check(subscription)._async$_addError$2(this.error, this.stackTrace);
+ },
+ $signature: function() {
+ return this.$this.$ti._eval$1("Null(_BufferingStreamSubscription<1>)");
+ }
+ };
+ P._SyncBroadcastStreamController__sendDone_closure.prototype = {
+ call$1: function(subscription) {
+ this.$this.$ti._eval$1("_BufferingStreamSubscription<1>")._check(subscription)._close$0();
+ },
+ $signature: function() {
+ return this.$this.$ti._eval$1("Null(_BufferingStreamSubscription<1>)");
+ }
+ };
+ P._AsyncBroadcastStreamController.prototype = {
+ _sendData$1: function(data) {
+ var subscription,
+ t1 = this.$ti;
+ t1._precomputed1._check(data);
+ for (subscription = this._firstSubscription, t1 = t1._eval$1("_DelayedData<1>"); subscription != null; subscription = subscription._async$_next)
+ subscription._addPending$1(new P._DelayedData(data, t1));
+ },
+ _sendError$2: function(error, stackTrace) {
+ var subscription;
+ for (subscription = this._firstSubscription; subscription != null; subscription = subscription._async$_next)
+ subscription._addPending$1(new P._DelayedError(error, stackTrace));
+ },
+ _sendDone$0: function() {
+ var _this = this,
+ subscription = _this._firstSubscription;
+ if (subscription != null)
+ for (; subscription != null; subscription = subscription._async$_next)
+ subscription._addPending$1(C.C__DelayedDone);
+ else {
+ H.assertHelper(_this._doneFuture != null);
+ H.assertHelper(_this._doneFuture._state === 0);
+ _this._doneFuture._asyncComplete$1(null);
+ }
+ }
+ };
+ P.Future.prototype = {};
+ P.Future_Future_closure.prototype = {
+ call$0: function() {
+ var e, s, exception;
+ try {
+ this.result._complete$1(this.computation.call$0());
+ } catch (exception) {
+ e = H.unwrapException(exception);
+ s = H.getTraceFromException(exception);
+ P._completeWithErrorCallback(this.result, e, s);
+ }
+ },
+ $signature: 0
+ };
+ P.Future_Future$microtask_closure.prototype = {
+ call$0: function() {
+ var e, s, exception;
+ try {
+ this.result._complete$1(this.computation.call$0());
+ } catch (exception) {
+ e = H.unwrapException(exception);
+ s = H.getTraceFromException(exception);
+ P._completeWithErrorCallback(this.result, e, s);
+ }
+ },
+ $signature: 0
+ };
+ P.Future_wait_handleError.prototype = {
+ call$2: function(theError, theStackTrace) {
+ var t1, t2, _this = this;
+ type$.StackTrace._check(theStackTrace);
+ t1 = _this._box_0;
+ t2 = --t1.remaining;
+ if (t1.values != null) {
+ t1.values = null;
+ if (t1.remaining === 0 || _this.eagerError)
+ _this.result._completeError$2(theError, theStackTrace);
+ else {
+ t1.error = theError;
+ t1.stackTrace = theStackTrace;
+ }
+ } else if (t2 === 0 && !_this.eagerError)
+ _this.result._completeError$2(t1.error, t1.stackTrace);
+ },
+ $signature: 5
+ };
+ P.Future_wait_closure.prototype = {
+ call$1: function(value) {
+ var t1, t2, _this = this;
+ _this.T._check(value);
+ t1 = _this._box_0;
+ --t1.remaining;
+ t2 = t1.values;
+ if (t2 != null) {
+ C.JSArray_methods.$indexSet(t2, _this.pos, value);
+ if (t1.remaining === 0)
+ _this.result._completeWithValue$1(t1.values);
+ } else if (t1.remaining === 0 && !_this.eagerError)
+ _this.result._completeError$2(t1.error, t1.stackTrace);
+ },
+ $signature: function() {
+ return this.T._eval$1("Null(0)");
+ }
+ };
+ P.Future_forEach_closure.prototype = {
+ call$0: function() {
+ var result,
+ t1 = this.iterator;
+ if (!t1.moveNext$0())
+ return false;
+ result = this.action.call$1(t1._current);
+ if (type$.Future_dynamic._is(result))
+ return result.then$1$1(P.async_Future__kTrue$closure(), type$.bool);
+ return true;
+ },
+ $signature: 81
+ };
+ P.Future_doWhile_closure.prototype = {
+ call$1: function(keepGoing) {
+ var result, error, stackTrace, t1, t2, exception, error0, stackTrace0, replacement, _this = this;
+ H._checkBoolNullable(keepGoing);
+ for (t1 = type$.Future_bool, t2 = _this.action; H.boolConversionCheck(keepGoing);) {
+ result = null;
+ try {
+ result = t2.call$0();
+ } catch (exception) {
+ error = H.unwrapException(exception);
+ stackTrace = H.getTraceFromException(exception);
+ error0 = error;
+ stackTrace0 = stackTrace;
+ replacement = $.Zone__current.errorCallback$2(error0, stackTrace0);
+ if (replacement != null) {
+ error = replacement.error;
+ if (error == null)
+ error = new P.NullThrownError();
+ stackTrace = replacement.stackTrace;
+ } else {
+ stackTrace = stackTrace0;
+ error = error0;
+ }
+ _this.doneSignal._asyncCompleteError$2(error, stackTrace);
+ return;
+ }
+ if (t1._is(result)) {
+ result.then$1$2$onError(_this._box_0.nextIteration, _this.doneSignal.get$_completeError(), type$.void);
+ return;
+ }
+ keepGoing = H._checkBoolNullable(result);
+ }
+ _this.doneSignal._complete$1(null);
+ },
+ $signature: 43
+ };
+ P.TimeoutException.prototype = {
+ toString$0: function(_) {
+ var t1 = this.duration,
+ result = (t1 != null ? "TimeoutException after " + t1.toString$0(0) : "TimeoutException") + ": " + this.message;
+ return result;
+ },
+ $isException: 1,
+ get$message: function(receiver) {
+ return this.message;
+ }
+ };
+ P.Completer.prototype = {};
+ P._Completer.prototype = {
+ completeError$2: function(error, stackTrace) {
+ var replacement;
+ if (error == null)
+ error = new P.NullThrownError();
+ if (this.future._state !== 0)
+ throw H.wrapException(P.StateError$("Future already completed"));
+ replacement = $.Zone__current.errorCallback$2(error, stackTrace);
+ if (replacement != null) {
+ error = replacement.error;
+ if (error == null)
+ error = new P.NullThrownError();
+ stackTrace = replacement.stackTrace;
+ }
+ this._completeError$2(error, stackTrace);
+ },
+ completeError$1: function(error) {
+ return this.completeError$2(error, null);
+ },
+ $isCompleter: 1
+ };
+ P._AsyncCompleter.prototype = {
+ complete$1: function(value) {
+ var t1;
+ this.$ti._eval$1("1/")._check(value);
+ t1 = this.future;
+ if (t1._state !== 0)
+ throw H.wrapException(P.StateError$("Future already completed"));
+ t1._asyncComplete$1(value);
+ },
+ complete$0: function() {
+ return this.complete$1(null);
+ },
+ _completeError$2: function(error, stackTrace) {
+ this.future._asyncCompleteError$2(error, stackTrace);
+ }
+ };
+ P._SyncCompleter.prototype = {
+ complete$1: function(value) {
+ var t1;
+ this.$ti._eval$1("1/")._check(value);
+ t1 = this.future;
+ if (t1._state !== 0)
+ throw H.wrapException(P.StateError$("Future already completed"));
+ t1._complete$1(value);
+ },
+ complete$0: function() {
+ return this.complete$1(null);
+ },
+ _completeError$2: function(error, stackTrace) {
+ this.future._completeError$2(error, stackTrace);
+ }
+ };
+ P._FutureListener.prototype = {
+ matchesErrorTest$1: function(asyncError) {
+ if ((this.state & 15) !== 6)
+ return true;
+ return this.result._zone.runUnary$2$2(type$.bool_Function_Object._check(this.callback), asyncError.error, type$.bool, type$.Object);
+ },
+ handleError$1: function(asyncError) {
+ var errorCallback, t2, t3, t4, _this = this,
+ t1 = (_this.state & 2) !== 0;
+ if (t1) {
+ H.assertHelper(t1);
+ t1 = _this.errorCallback != null;
+ } else
+ t1 = false;
+ H.assertHelper(t1);
+ errorCallback = _this.errorCallback;
+ t1 = type$.dynamic;
+ t2 = type$.Object;
+ t3 = _this.$ti._eval$1("2/");
+ t4 = _this.result._zone;
+ if (type$.dynamic_Function_Object_StackTrace._is(errorCallback))
+ return t3._check(t4.runBinary$3$3(errorCallback, asyncError.error, asyncError.stackTrace, t1, t2, type$.StackTrace));
+ else {
+ H.assertHelper(type$.dynamic_Function_Object._is(errorCallback));
+ return t3._check(t4.runUnary$2$2(errorCallback, asyncError.error, t1, t2));
+ }
+ }
+ };
+ P._Future.prototype = {
+ then$1$2$onError: function(f, onError, $R) {
+ var currentZone, result, t2,
+ t1 = this.$ti;
+ t1._bind$1($R)._eval$1("1/(2)")._check(f);
+ currentZone = $.Zone__current;
+ if (currentZone !== C.C__RootZone) {
+ f = currentZone.registerUnaryCallback$2$1(f, $R._eval$1("0/"), t1._precomputed1);
+ if (onError != null)
+ onError = P._registerErrorHandler(onError, currentZone);
+ }
+ result = new P._Future($.Zone__current, $R._eval$1("_Future<0>"));
+ t2 = onError == null ? 1 : 3;
+ this._addListener$1(new P._FutureListener(result, t2, f, onError, t1._eval$1("@<1>")._bind$1($R)._eval$1("_FutureListener<1,2>")));
+ return result;
+ },
+ then$1$1: function(f, $R) {
+ return this.then$1$2$onError(f, null, $R);
+ },
+ _thenAwait$1$2: function(f, onError, $E) {
+ var result,
+ t1 = this.$ti;
+ t1._bind$1($E)._eval$1("1/(2)")._check(f);
+ result = new P._Future($.Zone__current, $E._eval$1("_Future<0>"));
+ this._addListener$1(new P._FutureListener(result, (onError == null ? 1 : 3) | 16, f, onError, t1._eval$1("@<1>")._bind$1($E)._eval$1("_FutureListener<1,2>")));
+ return result;
+ },
+ catchError$1: function(onError) {
+ var t1, t2, result;
+ type$.bool_Function_dynamic._check(null);
+ t1 = this.$ti;
+ t2 = $.Zone__current;
+ result = new P._Future(t2, t1);
+ if (t2 !== C.C__RootZone)
+ onError = P._registerErrorHandler(onError, t2);
+ this._addListener$1(new P._FutureListener(result, 2, null, onError, t1._eval$1("@<1>")._bind$1(t1._precomputed1)._eval$1("_FutureListener<1,2>")));
+ return result;
+ },
+ whenComplete$1: function(action) {
+ var t1, t2, result;
+ type$.dynamic_Function._check(action);
+ t1 = this.$ti;
+ t2 = $.Zone__current;
+ result = new P._Future(t2, t1);
+ if (t2 !== C.C__RootZone)
+ action = t2.registerCallback$1$1(action, type$.dynamic);
+ this._addListener$1(new P._FutureListener(result, 8, action, null, t1._eval$1("@<1>")._bind$1(t1._precomputed1)._eval$1("_FutureListener<1,2>")));
+ return result;
+ },
+ _cloneResult$1: function(source) {
+ H.assertHelper(this._state < 4);
+ H.assertHelper(source._state >= 4);
+ this._state = source._state;
+ this._resultOrListeners = source._resultOrListeners;
+ },
+ _addListener$1: function(listener) {
+ var t1, source, _this = this;
+ H.assertHelper(listener._nextListener == null);
+ t1 = _this._state;
+ if (t1 <= 1) {
+ listener._nextListener = type$._FutureListener_dynamic_dynamic._check(_this._resultOrListeners);
+ _this._resultOrListeners = listener;
+ } else {
+ if (t1 === 2) {
+ source = type$._Future_dynamic._check(_this._resultOrListeners);
+ if (source._state < 4) {
+ source._addListener$1(listener);
+ return;
+ }
+ _this._cloneResult$1(source);
+ }
+ H.assertHelper(_this._state >= 4);
+ _this._zone.scheduleMicrotask$1(new P._Future__addListener_closure(_this, listener));
+ }
+ },
+ _prependListeners$1: function(listeners) {
+ var t1, existingListeners, cursor, cursor0, source, _this = this, _box_0 = {};
+ _box_0.listeners = listeners;
+ if (listeners == null)
+ return;
+ t1 = _this._state;
+ if (t1 <= 1) {
+ existingListeners = type$._FutureListener_dynamic_dynamic._check(_this._resultOrListeners);
+ cursor = _this._resultOrListeners = listeners;
+ if (existingListeners != null) {
+ for (; cursor0 = cursor._nextListener, cursor0 != null; cursor = cursor0)
+ ;
+ cursor._nextListener = existingListeners;
+ }
+ } else {
+ if (t1 === 2) {
+ source = type$._Future_dynamic._check(_this._resultOrListeners);
+ if (source._state < 4) {
+ source._prependListeners$1(listeners);
+ return;
+ }
+ _this._cloneResult$1(source);
+ }
+ H.assertHelper(_this._state >= 4);
+ _box_0.listeners = _this._reverseListeners$1(listeners);
+ _this._zone.scheduleMicrotask$1(new P._Future__prependListeners_closure(_box_0, _this));
+ }
+ },
+ _removeListeners$0: function() {
+ var current, _this = this;
+ H.assertHelper(_this._state < 4);
+ current = type$._FutureListener_dynamic_dynamic._check(_this._resultOrListeners);
+ _this._resultOrListeners = null;
+ return _this._reverseListeners$1(current);
+ },
+ _reverseListeners$1: function(listeners) {
+ var current, prev, next;
+ for (current = listeners, prev = null; current != null; prev = current, current = next) {
+ next = current._nextListener;
+ current._nextListener = prev;
+ }
+ return prev;
+ },
+ _complete$1: function(value) {
+ var listeners, _this = this,
+ t1 = _this.$ti;
+ t1._eval$1("1/")._check(value);
+ H.assertHelper(_this._state < 4);
+ if (t1._eval$1("Future<1>")._is(value))
+ if (t1._is(value))
+ P._Future__chainCoreFuture(value, _this);
+ else
+ P._Future__chainForeignFuture(value, _this);
+ else {
+ listeners = _this._removeListeners$0();
+ t1._precomputed1._check(value);
+ H.assertHelper(_this._state < 4);
+ _this._state = 4;
+ _this._resultOrListeners = value;
+ P._Future__propagateToListeners(_this, listeners);
+ }
+ },
+ _completeWithValue$1: function(value) {
+ var listeners, _this = this,
+ t1 = _this.$ti;
+ t1._precomputed1._check(value);
+ H.assertHelper(_this._state < 4);
+ H.assertHelper(!t1._eval$1("Future<1>")._is(value));
+ listeners = _this._removeListeners$0();
+ H.assertHelper(_this._state < 4);
+ _this._state = 4;
+ _this._resultOrListeners = value;
+ P._Future__propagateToListeners(_this, listeners);
+ },
+ _completeError$2: function(error, stackTrace) {
+ var listeners, _this = this;
+ type$.StackTrace._check(stackTrace);
+ H.assertHelper(_this._state < 4);
+ listeners = _this._removeListeners$0();
+ H.assertHelper(_this._state < 4);
+ _this._state = 8;
+ _this._resultOrListeners = new P.AsyncError(error, stackTrace);
+ P._Future__propagateToListeners(_this, listeners);
+ },
+ _completeError$1: function(error) {
+ return this._completeError$2(error, null);
+ },
+ _asyncComplete$1: function(value) {
+ var _this = this,
+ t1 = _this.$ti;
+ t1._eval$1("1/")._check(value);
+ H.assertHelper(_this._state < 4);
+ if (t1._eval$1("Future<1>")._is(value)) {
+ _this._chainFuture$1(value);
+ return;
+ }
+ H.assertHelper(_this._state === 0);
+ _this._state = 1;
+ _this._zone.scheduleMicrotask$1(new P._Future__asyncComplete_closure(_this, value));
+ },
+ _chainFuture$1: function(value) {
+ var _this = this,
+ t1 = _this.$ti;
+ t1._eval$1("Future<1>")._check(value);
+ if (t1._is(value)) {
+ if (value._state === 8) {
+ H.assertHelper(_this._state === 0);
+ _this._state = 1;
+ _this._zone.scheduleMicrotask$1(new P._Future__chainFuture_closure(_this, value));
+ } else
+ P._Future__chainCoreFuture(value, _this);
+ return;
+ }
+ P._Future__chainForeignFuture(value, _this);
+ },
+ _asyncCompleteError$2: function(error, stackTrace) {
+ var _this = this;
+ type$.StackTrace._check(stackTrace);
+ H.assertHelper(_this._state < 4);
+ H.assertHelper(_this._state === 0);
+ _this._state = 1;
+ _this._zone.scheduleMicrotask$1(new P._Future__asyncCompleteError_closure(_this, error, stackTrace));
+ },
+ $isFuture: 1
+ };
+ P._Future__addListener_closure.prototype = {
+ call$0: function() {
+ P._Future__propagateToListeners(this.$this, this.listener);
+ },
+ $signature: 0
+ };
+ P._Future__prependListeners_closure.prototype = {
+ call$0: function() {
+ P._Future__propagateToListeners(this.$this, this._box_0.listeners);
+ },
+ $signature: 0
+ };
+ P._Future__chainForeignFuture_closure.prototype = {
+ call$1: function(value) {
+ var t1 = this.target;
+ H.assertHelper(t1._state === 1);
+ H.assertHelper(t1._state === 1);
+ t1._state = 0;
+ t1._complete$1(value);
+ },
+ $signature: 3
+ };
+ P._Future__chainForeignFuture_closure0.prototype = {
+ call$2: function(error, stackTrace) {
+ var t1;
+ type$.StackTrace._check(stackTrace);
+ t1 = this.target;
+ H.assertHelper(t1._state === 1);
+ t1._completeError$2(error, stackTrace);
+ },
+ call$1: function(error) {
+ return this.call$2(error, null);
+ },
+ $signature: 80
+ };
+ P._Future__chainForeignFuture_closure1.prototype = {
+ call$0: function() {
+ this.target._completeError$2(this.e, this.s);
+ },
+ $signature: 0
+ };
+ P._Future__asyncComplete_closure.prototype = {
+ call$0: function() {
+ var t1 = this.$this;
+ t1._completeWithValue$1(t1.$ti._precomputed1._check(this.value));
+ },
+ $signature: 0
+ };
+ P._Future__chainFuture_closure.prototype = {
+ call$0: function() {
+ P._Future__chainCoreFuture(this.value, this.$this);
+ },
+ $signature: 0
+ };
+ P._Future__asyncCompleteError_closure.prototype = {
+ call$0: function() {
+ this.$this._completeError$2(this.error, this.stackTrace);
+ },
+ $signature: 0
+ };
+ P._Future__propagateToListeners_handleWhenCompleteCallback.prototype = {
+ call$0: function() {
+ var completeResult, e, s, t3, exception, originalSource, _this = this,
+ t1 = _this.listener,
+ t2 = t1.state;
+ H.assertHelper((t2 & 1) === 0);
+ t3 = (t2 & 2) === 0;
+ H.assertHelper(t3);
+ completeResult = null;
+ try {
+ H.assertHelper(t3);
+ H.assertHelper((t2 & 15) === 8);
+ completeResult = t1.result._zone.run$1$1(type$.dynamic_Function._check(t1.callback), type$.dynamic);
+ } catch (exception) {
+ e = H.unwrapException(exception);
+ s = H.getTraceFromException(exception);
+ if (_this.hasError) {
+ t1 = _this._box_1.source;
+ H.assertHelper(t1._state === 8);
+ t1 = type$.AsyncError._check(t1._resultOrListeners).error;
+ t2 = e;
+ t2 = t1 == null ? t2 == null : t1 === t2;
+ t1 = t2;
+ } else
+ t1 = false;
+ t2 = _this._box_0;
+ if (t1) {
+ t1 = _this._box_1.source;
+ H.assertHelper(t1._state === 8);
+ t2.listenerValueOrError = type$.AsyncError._check(t1._resultOrListeners);
+ } else
+ t2.listenerValueOrError = new P.AsyncError(e, s);
+ t2.listenerHasError = true;
+ return;
+ }
+ if (type$.Future_dynamic._is(completeResult)) {
+ if (completeResult instanceof P._Future && completeResult._state >= 4) {
+ if (completeResult._state === 8) {
+ t1 = completeResult;
+ H.assertHelper(t1._state === 8);
+ t2 = _this._box_0;
+ t2.listenerValueOrError = type$.AsyncError._check(t1._resultOrListeners);
+ t2.listenerHasError = true;
+ }
+ return;
+ }
+ originalSource = _this._box_1.source;
+ t1 = _this._box_0;
+ t1.listenerValueOrError = completeResult.then$1$1(new P._Future__propagateToListeners_handleWhenCompleteCallback_closure(originalSource), type$.dynamic);
+ t1.listenerHasError = false;
+ }
+ },
+ $signature: 1
+ };
+ P._Future__propagateToListeners_handleWhenCompleteCallback_closure.prototype = {
+ call$1: function(_) {
+ return this.originalSource;
+ },
+ $signature: 75
+ };
+ P._Future__propagateToListeners_handleValueCallback.prototype = {
+ call$0: function() {
+ var e, s, t1, t2, t3, t4, exception, _this = this;
+ try {
+ t1 = _this.listener;
+ t2 = t1.$ti;
+ t3 = t2._precomputed1;
+ t4 = t3._check(_this.sourceResult);
+ H.assertHelper((t1.state & 1) !== 0);
+ _this._box_0.listenerValueOrError = t1.result._zone.runUnary$2$2(t2._eval$1("2/(1)")._check(t1.callback), t4, t2._eval$1("2/"), t3);
+ } catch (exception) {
+ e = H.unwrapException(exception);
+ s = H.getTraceFromException(exception);
+ t1 = _this._box_0;
+ t1.listenerValueOrError = new P.AsyncError(e, s);
+ t1.listenerHasError = true;
+ }
+ },
+ $signature: 1
+ };
+ P._Future__propagateToListeners_handleError.prototype = {
+ call$0: function() {
+ var asyncError, e, s, t1, t2, exception, t3, t4, t5, _this = this;
+ try {
+ t1 = _this._box_1.source;
+ H.assertHelper(t1._state === 8);
+ asyncError = type$.AsyncError._check(t1._resultOrListeners);
+ t1 = _this.listener;
+ if (H.boolConversionCheck(t1.matchesErrorTest$1(asyncError))) {
+ H.assertHelper((t1.state & 2) !== 0);
+ t2 = t1.errorCallback != null;
+ } else
+ t2 = false;
+ if (t2) {
+ t2 = _this._box_0;
+ t2.listenerValueOrError = t1.handleError$1(asyncError);
+ t2.listenerHasError = false;
+ }
+ } catch (exception) {
+ e = H.unwrapException(exception);
+ s = H.getTraceFromException(exception);
+ t1 = _this._box_1;
+ t2 = t1.source;
+ H.assertHelper(t2._state === 8);
+ t3 = type$.AsyncError;
+ t2 = t3._check(t2._resultOrListeners).error;
+ t4 = e;
+ t5 = _this._box_0;
+ if (t2 == null ? t4 == null : t2 === t4) {
+ t1 = t1.source;
+ H.assertHelper(t1._state === 8);
+ t5.listenerValueOrError = t3._check(t1._resultOrListeners);
+ } else
+ t5.listenerValueOrError = new P.AsyncError(e, s);
+ t5.listenerHasError = true;
+ }
+ },
+ $signature: 1
+ };
+ P._AsyncCallbackEntry.prototype = {};
+ P.Stream.prototype = {
+ get$isBroadcast: function() {
+ return false;
+ },
+ pipe$1: function(streamConsumer) {
+ H._instanceType(this)._eval$1("StreamConsumer<Stream.T>")._check(streamConsumer);
+ return streamConsumer.addStream$1(this).then$1$1(new P.Stream_pipe_closure(streamConsumer), type$.dynamic);
+ },
+ get$length: function(_) {
+ var t1 = {},
+ future = new P._Future($.Zone__current, type$._Future_int);
+ t1.count = 0;
+ this.listen$4$cancelOnError$onDone$onError(new P.Stream_length_closure(t1, this), true, new P.Stream_length_closure0(t1, future), future.get$_completeError());
+ return future;
+ },
+ get$first: function(_) {
+ var t1 = {},
+ future = new P._Future($.Zone__current, H._instanceType(this)._eval$1("_Future<Stream.T>"));
+ t1.subscription = null;
+ t1.subscription = this.listen$4$cancelOnError$onDone$onError(new P.Stream_first_closure(t1, this, future), true, new P.Stream_first_closure0(future), future.get$_completeError());
+ return future;
+ },
+ get$last: function(_) {
+ var t1 = {},
+ future = new P._Future($.Zone__current, H._instanceType(this)._eval$1("_Future<Stream.T>"));
+ t1.result = null;
+ t1.foundResult = false;
+ this.listen$4$cancelOnError$onDone$onError(new P.Stream_last_closure(t1, this), true, new P.Stream_last_closure0(t1, future), future.get$_completeError());
+ return future;
+ },
+ firstWhere$1: function(_, test) {
+ var future, _this = this, t1 = {},
+ t2 = H._instanceType(_this);
+ t2._eval$1("bool(Stream.T)")._check(test);
+ t2._eval$1("Stream.T()")._check(null);
+ future = new P._Future($.Zone__current, t2._eval$1("_Future<Stream.T>"));
+ t1.subscription = null;
+ t1.subscription = _this.listen$4$cancelOnError$onDone$onError(new P.Stream_firstWhere_closure(t1, _this, test, future), true, new P.Stream_firstWhere_closure0(_this, null, future), future.get$_completeError());
+ return future;
+ }
+ };
+ P.Stream_Stream$fromFuture_closure.prototype = {
+ call$1: function(value) {
+ var t1 = this.controller;
+ t1._add$1(this.T._check(value));
+ t1._closeUnchecked$0();
+ },
+ $signature: function() {
+ return this.T._eval$1("Null(0)");
+ }
+ };
+ P.Stream_Stream$fromFuture_closure0.prototype = {
+ call$2: function(error, stackTrace) {
+ var t1 = this.controller;
+ t1._async$_addError$2(error, type$.StackTrace._check(stackTrace));
+ t1._closeUnchecked$0();
+ },
+ $signature: 6
+ };
+ P.Stream_Stream$fromIterable_closure.prototype = {
+ call$0: function() {
+ var t1 = this.elements;
+ return new P._IterablePendingEvents(new J.ArrayIterator(t1, 0, H._arrayInstanceType(t1)._eval$1("ArrayIterator<1>")), this.T._eval$1("_IterablePendingEvents<0>"));
+ },
+ $signature: function() {
+ return this.T._eval$1("_IterablePendingEvents<0>()");
+ }
+ };
+ P.Stream_pipe_closure.prototype = {
+ call$1: function(_) {
+ return this.streamConsumer.close$0(0);
+ },
+ $signature: 73
+ };
+ P.Stream_length_closure.prototype = {
+ call$1: function(_) {
+ H._instanceType(this.$this)._eval$1("Stream.T")._check(_);
+ ++this._box_0.count;
+ },
+ $signature: function() {
+ return H._instanceType(this.$this)._eval$1("Null(Stream.T)");
+ }
+ };
+ P.Stream_length_closure0.prototype = {
+ call$0: function() {
+ this.future._complete$1(this._box_0.count);
+ },
+ $signature: 0
+ };
+ P.Stream_first_closure.prototype = {
+ call$1: function(value) {
+ H._instanceType(this.$this)._eval$1("Stream.T")._check(value);
+ P._cancelAndValue(this._box_0.subscription, this.future, value);
+ },
+ $signature: function() {
+ return H._instanceType(this.$this)._eval$1("Null(Stream.T)");
+ }
+ };
+ P.Stream_first_closure0.prototype = {
+ call$0: function() {
+ var e, s, t1, exception;
+ try {
+ t1 = H.IterableElementError_noElement();
+ throw H.wrapException(t1);
+ } catch (exception) {
+ e = H.unwrapException(exception);
+ s = H.getTraceFromException(exception);
+ P._completeWithErrorCallback(this.future, e, s);
+ }
+ },
+ $signature: 0
+ };
+ P.Stream_last_closure.prototype = {
+ call$1: function(value) {
+ var t1;
+ H._instanceType(this.$this)._eval$1("Stream.T")._check(value);
+ t1 = this._box_0;
+ t1.foundResult = true;
+ t1.result = value;
+ },
+ $signature: function() {
+ return H._instanceType(this.$this)._eval$1("Null(Stream.T)");
+ }
+ };
+ P.Stream_last_closure0.prototype = {
+ call$0: function() {
+ var e, s, exception,
+ t1 = this._box_0;
+ if (t1.foundResult) {
+ this.future._complete$1(t1.result);
+ return;
+ }
+ try {
+ t1 = H.IterableElementError_noElement();
+ throw H.wrapException(t1);
+ } catch (exception) {
+ e = H.unwrapException(exception);
+ s = H.getTraceFromException(exception);
+ P._completeWithErrorCallback(this.future, e, s);
+ }
+ },
+ $signature: 0
+ };
+ P.Stream_firstWhere_closure.prototype = {
+ call$1: function(value) {
+ var t1, t2, _this = this;
+ H._instanceType(_this.$this)._eval$1("Stream.T")._check(value);
+ t1 = _this._box_0;
+ t2 = _this.future;
+ P._runUserCode(new P.Stream_firstWhere__closure(_this.test, value), new P.Stream_firstWhere__closure0(t1, t2, value), P._cancelAndErrorClosure(t1.subscription, t2), type$.bool);
+ },
+ $signature: function() {
+ return H._instanceType(this.$this)._eval$1("Null(Stream.T)");
+ }
+ };
+ P.Stream_firstWhere__closure.prototype = {
+ call$0: function() {
+ return this.test.call$1(this.value);
+ },
+ $signature: 49
+ };
+ P.Stream_firstWhere__closure0.prototype = {
+ call$1: function(isMatch) {
+ if (H.boolConversionCheck(H._checkBoolNullable(isMatch)))
+ P._cancelAndValue(this._box_0.subscription, this.future, this.value);
+ },
+ $signature: 43
+ };
+ P.Stream_firstWhere_closure0.prototype = {
+ call$0: function() {
+ var e, s, t1, exception;
+ try {
+ t1 = H.IterableElementError_noElement();
+ throw H.wrapException(t1);
+ } catch (exception) {
+ e = H.unwrapException(exception);
+ s = H.getTraceFromException(exception);
+ P._completeWithErrorCallback(this.future, e, s);
+ }
+ },
+ $signature: 0
+ };
+ P.StreamSubscription.prototype = {};
+ P.StreamTransformerBase.prototype = {$isStreamTransformer: 1};
+ P._StreamController.prototype = {
+ get$_pendingEvents: function() {
+ var t1, _this = this;
+ H.assertHelper((_this._state & 3) === 0);
+ if ((_this._state & 8) === 0)
+ return H._instanceType(_this)._eval$1("_PendingEvents<1>")._check(_this._varData);
+ t1 = H._instanceType(_this);
+ return t1._eval$1("_PendingEvents<1>")._check(t1._eval$1("_StreamControllerAddStreamState<1>")._check(_this._varData).varData);
+ },
+ _ensurePendingEvents$0: function() {
+ var t1, state, t2, _this = this;
+ H.assertHelper((_this._state & 3) === 0);
+ if ((_this._state & 8) === 0) {
+ t1 = _this._varData;
+ if (t1 == null)
+ t1 = _this._varData = new P._StreamImplEvents(H._instanceType(_this)._eval$1("_StreamImplEvents<1>"));
+ return H._instanceType(_this)._eval$1("_StreamImplEvents<1>")._check(t1);
+ }
+ t1 = H._instanceType(_this);
+ state = t1._eval$1("_StreamControllerAddStreamState<1>")._check(_this._varData);
+ t2 = state.varData;
+ if (t2 == null)
+ t2 = state.varData = new P._StreamImplEvents(t1._eval$1("_StreamImplEvents<1>"));
+ return t1._eval$1("_StreamImplEvents<1>")._check(t2);
+ },
+ get$_async$_subscription: function() {
+ var t1, _this = this;
+ H.assertHelper((_this._state & 1) !== 0);
+ if ((_this._state & 8) !== 0) {
+ t1 = H._instanceType(_this);
+ return t1._eval$1("_ControllerSubscription<1>")._check(t1._eval$1("_StreamControllerAddStreamState<1>")._check(_this._varData).varData);
+ }
+ return H._instanceType(_this)._eval$1("_ControllerSubscription<1>")._check(_this._varData);
+ },
+ _badEventState$0: function() {
+ var t1 = this._state;
+ if ((t1 & 4) !== 0)
+ return new P.StateError("Cannot add event after closing");
+ H.assertHelper((t1 & 8) !== 0);
+ return new P.StateError("Cannot add event while adding a stream");
+ },
+ addStream$2$cancelOnError: function(source, cancelOnError) {
+ var t2, t3, t4, t5, _this = this,
+ t1 = H._instanceType(_this);
+ t1._eval$1("Stream<1>")._check(source);
+ t2 = _this._state;
+ if (t2 >= 4)
+ throw H.wrapException(_this._badEventState$0());
+ if ((t2 & 2) !== 0) {
+ t1 = new P._Future($.Zone__current, type$._Future_dynamic);
+ t1._asyncComplete$1(null);
+ return t1;
+ }
+ t2 = _this._varData;
+ t3 = cancelOnError === true;
+ t4 = new P._Future($.Zone__current, type$._Future_dynamic);
+ t5 = t3 ? P._AddStreamState_makeErrorHandler(_this) : _this.get$_async$_addError();
+ t5 = source.listen$4$cancelOnError$onDone$onError(_this.get$_add(), t3, _this.get$_close(), t5);
+ t3 = _this._state;
+ if ((t3 & 1) !== 0 ? (_this.get$_async$_subscription()._state & 4) !== 0 : (t3 & 2) === 0)
+ t5.pause$0();
+ _this._varData = new P._StreamControllerAddStreamState(t2, t4, t5, t1._eval$1("_StreamControllerAddStreamState<1>"));
+ _this._state |= 8;
+ return t4;
+ },
+ _ensureDoneFuture$0: function() {
+ var t1 = this._doneFuture;
+ if (t1 == null)
+ t1 = this._doneFuture = (this._state & 2) !== 0 ? $.$get$Future__nullFuture() : new P._Future($.Zone__current, type$._Future_dynamic);
+ return t1;
+ },
+ add$1: function(_, value) {
+ var _this = this;
+ H._instanceType(_this)._precomputed1._check(value);
+ if (_this._state >= 4)
+ throw H.wrapException(_this._badEventState$0());
+ _this._add$1(value);
+ },
+ addError$2: function(error, stackTrace) {
+ var replacement;
+ type$.StackTrace._check(stackTrace);
+ if (this._state >= 4)
+ throw H.wrapException(this._badEventState$0());
+ if (error == null)
+ error = new P.NullThrownError();
+ replacement = $.Zone__current.errorCallback$2(error, stackTrace);
+ if (replacement != null) {
+ error = replacement.error;
+ if (error == null)
+ error = new P.NullThrownError();
+ stackTrace = replacement.stackTrace;
+ }
+ this._async$_addError$2(error, stackTrace);
+ },
+ addError$1: function(error) {
+ return this.addError$2(error, null);
+ },
+ close$0: function(_) {
+ var _this = this,
+ t1 = _this._state;
+ if ((t1 & 4) !== 0)
+ return _this._ensureDoneFuture$0();
+ if (t1 >= 4)
+ throw H.wrapException(_this._badEventState$0());
+ _this._closeUnchecked$0();
+ return _this._ensureDoneFuture$0();
+ },
+ _closeUnchecked$0: function() {
+ var t1 = this._state |= 4;
+ if ((t1 & 1) !== 0)
+ this._sendDone$0();
+ else if ((t1 & 3) === 0)
+ this._ensurePendingEvents$0().add$1(0, C.C__DelayedDone);
+ },
+ _add$1: function(value) {
+ var t2, _this = this,
+ t1 = H._instanceType(_this);
+ t1._precomputed1._check(value);
+ t2 = _this._state;
+ if ((t2 & 1) !== 0)
+ _this._sendData$1(value);
+ else if ((t2 & 3) === 0)
+ _this._ensurePendingEvents$0().add$1(0, new P._DelayedData(value, t1._eval$1("_DelayedData<1>")));
+ },
+ _async$_addError$2: function(error, stackTrace) {
+ var t1;
+ type$.StackTrace._check(stackTrace);
+ t1 = this._state;
+ if ((t1 & 1) !== 0)
+ this._sendError$2(error, stackTrace);
+ else if ((t1 & 3) === 0)
+ this._ensurePendingEvents$0().add$1(0, new P._DelayedError(error, stackTrace));
+ },
+ _close$0: function() {
+ var addState, _this = this;
+ H.assertHelper((_this._state & 8) !== 0);
+ addState = H._instanceType(_this)._eval$1("_StreamControllerAddStreamState<1>")._check(_this._varData);
+ _this._varData = addState.varData;
+ _this._state &= 4294967287;
+ addState.addStreamFuture._asyncComplete$1(null);
+ },
+ _subscribe$4: function(onData, onError, onDone, cancelOnError) {
+ var t2, t3, subscription, pendingEvents, addState, _this = this,
+ t1 = H._instanceType(_this);
+ t1._eval$1("~(1)")._check(onData);
+ type$.void_Function._check(onDone);
+ if ((_this._state & 3) !== 0)
+ throw H.wrapException(P.StateError$("Stream has already been listened to."));
+ t2 = $.Zone__current;
+ t3 = cancelOnError ? 1 : 0;
+ subscription = new P._ControllerSubscription(_this, t2, t3, t1._eval$1("_ControllerSubscription<1>"));
+ subscription._BufferingStreamSubscription$4(onData, onError, onDone, cancelOnError, t1._precomputed1);
+ pendingEvents = _this.get$_pendingEvents();
+ t3 = _this._state |= 1;
+ if ((t3 & 8) !== 0) {
+ addState = t1._eval$1("_StreamControllerAddStreamState<1>")._check(_this._varData);
+ addState.varData = subscription;
+ addState.addSubscription.resume$0();
+ } else
+ _this._varData = subscription;
+ subscription._setPendingEvents$1(pendingEvents);
+ subscription._guardCallback$1(new P._StreamController__subscribe_closure(_this));
+ return subscription;
+ },
+ _recordCancel$1: function(subscription) {
+ var result, e, s, exception, result0, _this = this,
+ t1 = H._instanceType(_this);
+ t1._eval$1("StreamSubscription<1>")._check(subscription);
+ result = null;
+ if ((_this._state & 8) !== 0)
+ result = t1._eval$1("_StreamControllerAddStreamState<1>")._check(_this._varData).cancel$0();
+ _this._varData = null;
+ _this._state = _this._state & 4294967286 | 2;
+ t1 = _this.onCancel;
+ if (t1 != null)
+ if (result == null)
+ try {
+ result = type$.Future_dynamic._check(t1.call$0());
+ } catch (exception) {
+ e = H.unwrapException(exception);
+ s = H.getTraceFromException(exception);
+ result0 = new P._Future($.Zone__current, type$._Future_dynamic);
+ result0._asyncCompleteError$2(e, s);
+ result = result0;
+ }
+ else
+ result = result.whenComplete$1(t1);
+ t1 = new P._StreamController__recordCancel_complete(_this);
+ if (result != null)
+ result = result.whenComplete$1(t1);
+ else
+ t1.call$0();
+ return result;
+ },
+ _recordPause$1: function(subscription) {
+ var _this = this,
+ t1 = H._instanceType(_this);
+ t1._eval$1("StreamSubscription<1>")._check(subscription);
+ if ((_this._state & 8) !== 0)
+ t1._eval$1("_StreamControllerAddStreamState<1>")._check(_this._varData).addSubscription.pause$0();
+ P._runGuarded(_this.onPause);
+ },
+ _recordResume$1: function(subscription) {
+ var _this = this,
+ t1 = H._instanceType(_this);
+ t1._eval$1("StreamSubscription<1>")._check(subscription);
+ if ((_this._state & 8) !== 0)
+ t1._eval$1("_StreamControllerAddStreamState<1>")._check(_this._varData).addSubscription.resume$0();
+ P._runGuarded(_this.onResume);
+ },
+ $isEventSink: 1,
+ $isStreamConsumer: 1,
+ $isStreamSink: 1,
+ $isStreamController: 1,
+ $is_StreamControllerLifecycle: 1,
+ $is_EventDispatch: 1,
+ $isSink: 1
+ };
+ P._StreamController__subscribe_closure.prototype = {
+ call$0: function() {
+ P._runGuarded(this.$this.onListen);
+ },
+ $signature: 0
+ };
+ P._StreamController__recordCancel_complete.prototype = {
+ call$0: function() {
+ var t1 = this.$this._doneFuture;
+ if (t1 != null && t1._state === 0)
+ t1._asyncComplete$1(null);
+ },
+ $signature: 1
+ };
+ P._SyncStreamControllerDispatch.prototype = {
+ _sendData$1: function(data) {
+ this.$ti._precomputed1._check(data);
+ this.get$_async$_subscription()._add$1(data);
+ },
+ _sendError$2: function(error, stackTrace) {
+ this.get$_async$_subscription()._async$_addError$2(error, stackTrace);
+ },
+ _sendDone$0: function() {
+ this.get$_async$_subscription()._close$0();
+ }
+ };
+ P._AsyncStreamControllerDispatch.prototype = {
+ _sendData$1: function(data) {
+ var t1 = this.$ti;
+ t1._precomputed1._check(data);
+ this.get$_async$_subscription()._addPending$1(new P._DelayedData(data, t1._eval$1("_DelayedData<1>")));
+ },
+ _sendError$2: function(error, stackTrace) {
+ this.get$_async$_subscription()._addPending$1(new P._DelayedError(error, stackTrace));
+ },
+ _sendDone$0: function() {
+ this.get$_async$_subscription()._addPending$1(C.C__DelayedDone);
+ }
+ };
+ P._AsyncStreamController.prototype = {};
+ P._SyncStreamController.prototype = {};
+ P._ControllerStream.prototype = {
+ _createSubscription$4: function(onData, onError, onDone, cancelOnError) {
+ return this._controller._subscribe$4(H._instanceType(this)._eval$1("~(1)")._check(onData), onError, type$.void_Function._check(onDone), cancelOnError);
+ },
+ get$hashCode: function(_) {
+ return (H.Primitives_objectHashCode(this._controller) ^ 892482866) >>> 0;
+ },
+ $eq: function(_, other) {
+ if (other == null)
+ return false;
+ if (this === other)
+ return true;
+ return other instanceof P._ControllerStream && other._controller === this._controller;
+ }
+ };
+ P._ControllerSubscription.prototype = {
+ _onCancel$0: function() {
+ return this._controller._recordCancel$1(this);
+ },
+ _onPause$0: function() {
+ this._controller._recordPause$1(this);
+ },
+ _onResume$0: function() {
+ this._controller._recordResume$1(this);
+ }
+ };
+ P._StreamSinkWrapper.prototype = {
+ add$1: function(_, data) {
+ this._async$_target.add$1(0, this.$ti._precomputed1._check(data));
+ },
+ $isEventSink: 1,
+ $isStreamConsumer: 1,
+ $isStreamSink: 1,
+ $isSink: 1
+ };
+ P._AddStreamState.prototype = {
+ cancel$0: function() {
+ var cancel = this.addSubscription.cancel$0();
+ if (cancel == null) {
+ this.addStreamFuture._asyncComplete$1(null);
+ return null;
+ }
+ return cancel.whenComplete$1(new P._AddStreamState_cancel_closure(this));
+ }
+ };
+ P._AddStreamState_makeErrorHandler_closure.prototype = {
+ call$2: function(e, s) {
+ var t1 = this.controller;
+ t1._async$_addError$2(e, type$.StackTrace._check(s));
+ t1._close$0();
+ },
+ $signature: 5
+ };
+ P._AddStreamState_cancel_closure.prototype = {
+ call$0: function() {
+ this.$this.addStreamFuture._asyncComplete$1(null);
+ },
+ $signature: 0
+ };
+ P._StreamControllerAddStreamState.prototype = {};
+ P._BufferingStreamSubscription.prototype = {
+ _BufferingStreamSubscription$4: function(onData, onError, onDone, cancelOnError, $T) {
+ this.onData$1(onData);
+ this.onError$1(0, onError);
+ this.onDone$1(onDone);
+ },
+ _setPendingEvents$1: function(pendingEvents) {
+ var _this = this;
+ H._instanceType(_this)._eval$1("_PendingEvents<_BufferingStreamSubscription.T>")._check(pendingEvents);
+ H.assertHelper(_this._pending == null);
+ if (pendingEvents == null)
+ return;
+ _this.set$_pending(pendingEvents);
+ if (!pendingEvents.get$isEmpty(pendingEvents)) {
+ _this._state = (_this._state | 64) >>> 0;
+ _this._pending.schedule$1(_this);
+ }
+ },
+ onData$1: function(handleData) {
+ var t1 = H._instanceType(this);
+ t1._eval$1("~(_BufferingStreamSubscription.T)")._check(handleData);
+ if (handleData == null)
+ handleData = P.async___nullDataHandler$closure();
+ this.set$_onData(this._zone.registerUnaryCallback$2$1(handleData, type$.dynamic, t1._eval$1("_BufferingStreamSubscription.T")));
+ },
+ onError$1: function(_, handleError) {
+ var _this = this;
+ if (handleError == null)
+ handleError = P.async___nullErrorHandler$closure();
+ if (type$.void_Function_Object_StackTrace._is(handleError))
+ _this._onError = _this._zone.registerBinaryCallback$3$1(handleError, type$.dynamic, type$.Object, type$.StackTrace);
+ else if (type$.void_Function_Object._is(handleError))
+ _this._onError = _this._zone.registerUnaryCallback$2$1(handleError, type$.dynamic, type$.Object);
+ else
+ throw H.wrapException(P.ArgumentError$("handleError callback must take either an Object (the error), or both an Object (the error) and a StackTrace."));
+ },
+ onDone$1: function(handleDone) {
+ type$.void_Function._check(handleDone);
+ if (handleDone == null)
+ handleDone = P.async___nullDoneHandler$closure();
+ this.set$_onDone(this._zone.registerCallback$1$1(handleDone, type$.void));
+ },
+ pause$1: function(resumeSignal) {
+ var t2, t3, _this = this,
+ t1 = _this._state;
+ if ((t1 & 8) !== 0)
+ return;
+ t2 = (t1 + 128 | 4) >>> 0;
+ _this._state = t2;
+ if (t1 < 128 && _this._pending != null) {
+ t3 = _this._pending;
+ if (t3._state === 1)
+ t3._state = 3;
+ }
+ if ((t1 & 4) === 0 && (t2 & 32) === 0)
+ _this._guardCallback$1(_this.get$_onPause());
+ },
+ pause$0: function() {
+ return this.pause$1(null);
+ },
+ resume$0: function() {
+ var _this = this,
+ t1 = _this._state;
+ if ((t1 & 8) !== 0)
+ return;
+ if (t1 >= 128) {
+ t1 = _this._state -= 128;
+ if (t1 < 128) {
+ if ((t1 & 64) !== 0) {
+ t1 = _this._pending;
+ t1 = !t1.get$isEmpty(t1);
+ } else
+ t1 = false;
+ if (t1)
+ _this._pending.schedule$1(_this);
+ else {
+ H.assertHelper(_this.get$_mayResumeInput());
+ t1 = (_this._state & 4294967291) >>> 0;
+ _this._state = t1;
+ if ((t1 & 32) === 0)
+ _this._guardCallback$1(_this.get$_onResume());
+ }
+ }
+ }
+ },
+ cancel$0: function() {
+ var _this = this,
+ t1 = (_this._state & 4294967279) >>> 0;
+ _this._state = t1;
+ if ((t1 & 8) === 0)
+ _this._cancel$0();
+ t1 = _this._cancelFuture;
+ return t1 == null ? $.$get$Future__nullFuture() : t1;
+ },
+ get$_mayResumeInput: function() {
+ if (this._state < 128) {
+ var t1 = this._pending;
+ t1 = t1 == null || t1.get$isEmpty(t1);
+ } else
+ t1 = false;
+ return t1;
+ },
+ get$isPaused: function() {
+ return this._state >= 128;
+ },
+ _cancel$0: function() {
+ var t2, _this = this,
+ t1 = _this._state = (_this._state | 8) >>> 0;
+ if ((t1 & 64) !== 0) {
+ t2 = _this._pending;
+ if (t2._state === 1)
+ t2._state = 3;
+ }
+ if ((t1 & 32) === 0)
+ _this.set$_pending(null);
+ _this._cancelFuture = _this._onCancel$0();
+ },
+ _add$1: function(data) {
+ var t2, _this = this,
+ t1 = H._instanceType(_this);
+ t1._eval$1("_BufferingStreamSubscription.T")._check(data);
+ H.assertHelper((_this._state & 2) === 0);
+ t2 = _this._state;
+ if ((t2 & 8) !== 0)
+ return;
+ if (t2 < 32)
+ _this._sendData$1(data);
+ else
+ _this._addPending$1(new P._DelayedData(data, t1._eval$1("_DelayedData<_BufferingStreamSubscription.T>")));
+ },
+ _async$_addError$2: function(error, stackTrace) {
+ var t1 = this._state;
+ if ((t1 & 8) !== 0)
+ return;
+ if (t1 < 32)
+ this._sendError$2(error, stackTrace);
+ else
+ this._addPending$1(new P._DelayedError(error, stackTrace));
+ },
+ _close$0: function() {
+ var t1, _this = this;
+ H.assertHelper((_this._state & 2) === 0);
+ t1 = _this._state;
+ if ((t1 & 8) !== 0)
+ return;
+ t1 = (t1 | 2) >>> 0;
+ _this._state = t1;
+ if (t1 < 32)
+ _this._sendDone$0();
+ else
+ _this._addPending$1(C.C__DelayedDone);
+ },
+ _onPause$0: function() {
+ H.assertHelper((this._state & 4) !== 0);
+ },
+ _onResume$0: function() {
+ H.assertHelper((this._state & 4) === 0);
+ },
+ _onCancel$0: function() {
+ H.assertHelper((this._state & 8) !== 0);
+ return null;
+ },
+ _addPending$1: function($event) {
+ var _this = this,
+ t1 = H._instanceType(_this)._eval$1("_StreamImplEvents<_BufferingStreamSubscription.T>"),
+ pending = t1._check(_this._pending);
+ if (pending == null) {
+ pending = new P._StreamImplEvents(t1);
+ _this.set$_pending(pending);
+ }
+ pending.add$1(0, $event);
+ t1 = _this._state;
+ if ((t1 & 64) === 0) {
+ t1 = (t1 | 64) >>> 0;
+ _this._state = t1;
+ if (t1 < 128)
+ _this._pending.schedule$1(_this);
+ }
+ },
+ _sendData$1: function(data) {
+ var t2, _this = this,
+ t1 = H._instanceType(_this)._eval$1("_BufferingStreamSubscription.T");
+ t1._check(data);
+ H.assertHelper((_this._state & 8) === 0);
+ H.assertHelper(_this._state < 128);
+ H.assertHelper((_this._state & 32) === 0);
+ t2 = _this._state;
+ _this._state = (t2 | 32) >>> 0;
+ _this._zone.runUnaryGuarded$1$2(_this._onData, data, t1);
+ _this._state = (_this._state & 4294967263) >>> 0;
+ _this._checkState$1((t2 & 4) !== 0);
+ },
+ _sendError$2: function(error, stackTrace) {
+ var t1, t2, _this = this;
+ type$.StackTrace._check(stackTrace);
+ H.assertHelper((_this._state & 8) === 0);
+ H.assertHelper(_this._state < 128);
+ H.assertHelper((_this._state & 32) === 0);
+ t1 = _this._state;
+ t2 = new P._BufferingStreamSubscription__sendError_sendError(_this, error, stackTrace);
+ if ((t1 & 1) !== 0) {
+ _this._state = (t1 | 16) >>> 0;
+ _this._cancel$0();
+ t1 = _this._cancelFuture;
+ if (t1 != null && t1 !== $.$get$Future__nullFuture())
+ t1.whenComplete$1(t2);
+ else
+ t2.call$0();
+ } else {
+ t2.call$0();
+ _this._checkState$1((t1 & 4) !== 0);
+ }
+ },
+ _sendDone$0: function() {
+ var t1, t2, _this = this;
+ H.assertHelper((_this._state & 8) === 0);
+ H.assertHelper(_this._state < 128);
+ H.assertHelper((_this._state & 32) === 0);
+ t1 = new P._BufferingStreamSubscription__sendDone_sendDone(_this);
+ _this._cancel$0();
+ _this._state = (_this._state | 16) >>> 0;
+ t2 = _this._cancelFuture;
+ if (t2 != null && t2 !== $.$get$Future__nullFuture())
+ t2.whenComplete$1(t1);
+ else
+ t1.call$0();
+ },
+ _guardCallback$1: function(callback) {
+ var t1, _this = this;
+ type$.void_Function._check(callback);
+ H.assertHelper((_this._state & 32) === 0);
+ t1 = _this._state;
+ _this._state = (t1 | 32) >>> 0;
+ callback.call$0();
+ _this._state = (_this._state & 4294967263) >>> 0;
+ _this._checkState$1((t1 & 4) !== 0);
+ },
+ _checkState$1: function(wasInputPaused) {
+ var t1, isInputPaused, _this = this;
+ H.assertHelper((_this._state & 32) === 0);
+ if ((_this._state & 64) !== 0) {
+ t1 = _this._pending;
+ t1 = t1.get$isEmpty(t1);
+ } else
+ t1 = false;
+ if (t1) {
+ t1 = (_this._state & 4294967231) >>> 0;
+ _this._state = t1;
+ if ((t1 & 4) !== 0 && _this.get$_mayResumeInput())
+ _this._state = (_this._state & 4294967291) >>> 0;
+ }
+ for (; true; wasInputPaused = isInputPaused) {
+ t1 = _this._state;
+ if ((t1 & 8) !== 0) {
+ _this.set$_pending(null);
+ return;
+ }
+ isInputPaused = (t1 & 4) !== 0;
+ if (wasInputPaused === isInputPaused)
+ break;
+ _this._state = (t1 ^ 32) >>> 0;
+ if (isInputPaused)
+ _this._onPause$0();
+ else
+ _this._onResume$0();
+ _this._state = (_this._state & 4294967263) >>> 0;
+ }
+ t1 = _this._state;
+ if ((t1 & 64) !== 0 && t1 < 128)
+ _this._pending.schedule$1(_this);
+ },
+ set$_onData: function(_onData) {
+ this._onData = H._instanceType(this)._eval$1("~(_BufferingStreamSubscription.T)")._check(_onData);
+ },
+ set$_onDone: function(_onDone) {
+ this._onDone = type$.void_Function._check(_onDone);
+ },
+ set$_pending: function(_pending) {
+ this._pending = H._instanceType(this)._eval$1("_PendingEvents<_BufferingStreamSubscription.T>")._check(_pending);
+ },
+ $isStreamSubscription: 1,
+ $is_EventDispatch: 1
+ };
+ P._BufferingStreamSubscription__sendError_sendError.prototype = {
+ call$0: function() {
+ var onError, t3, t4, t5,
+ t1 = this.$this,
+ t2 = t1._state;
+ if ((t2 & 8) !== 0 && (t2 & 16) === 0)
+ return;
+ t1._state = (t2 | 32) >>> 0;
+ onError = t1._onError;
+ t2 = this.error;
+ t3 = type$.Object;
+ t4 = t1._zone;
+ if (type$.void_Function_Object_StackTrace._is(onError))
+ t4.runBinaryGuarded$2$3(onError, t2, this.stackTrace, t3, type$.StackTrace);
+ else {
+ t5 = type$.void_Function_Object;
+ H.assertHelper(t5._is(onError));
+ t4.runUnaryGuarded$1$2(t5._check(t1._onError), t2, t3);
+ }
+ t1._state = (t1._state & 4294967263) >>> 0;
+ },
+ $signature: 1
+ };
+ P._BufferingStreamSubscription__sendDone_sendDone.prototype = {
+ call$0: function() {
+ var t1 = this.$this,
+ t2 = t1._state;
+ if ((t2 & 16) === 0)
+ return;
+ t1._state = (t2 | 42) >>> 0;
+ t1._zone.runGuarded$1(t1._onDone);
+ t1._state = (t1._state & 4294967263) >>> 0;
+ },
+ $signature: 1
+ };
+ P._StreamImpl.prototype = {
+ listen$4$cancelOnError$onDone$onError: function(onData, cancelOnError, onDone, onError) {
+ return this._createSubscription$4(H._instanceType(this)._eval$1("~(1)")._check(onData), onError, type$.void_Function._check(onDone), true === H._checkBoolNullable(cancelOnError));
+ },
+ listen$2$onDone: function(onData, onDone) {
+ return this.listen$4$cancelOnError$onDone$onError(onData, null, onDone, null);
+ },
+ listen$3$onDone$onError: function(onData, onDone, onError) {
+ return this.listen$4$cancelOnError$onDone$onError(onData, null, onDone, onError);
+ },
+ listen$1: function(onData) {
+ return this.listen$4$cancelOnError$onDone$onError(onData, null, null, null);
+ },
+ _createSubscription$4: function(onData, onError, onDone, cancelOnError) {
+ var t1 = H._instanceType(this);
+ return P._BufferingStreamSubscription$(t1._eval$1("~(1)")._check(onData), onError, type$.void_Function._check(onDone), cancelOnError, t1._precomputed1);
+ }
+ };
+ P._GeneratedStreamImpl.prototype = {
+ _createSubscription$4: function(onData, onError, onDone, cancelOnError) {
+ var _this = this,
+ t1 = _this.$ti;
+ t1._eval$1("~(1)")._check(onData);
+ type$.void_Function._check(onDone);
+ if (_this._isUsed)
+ throw H.wrapException(P.StateError$("Stream has already been listened to."));
+ _this._isUsed = true;
+ t1 = P._BufferingStreamSubscription$(onData, onError, onDone, cancelOnError, t1._precomputed1);
+ t1._setPendingEvents$1(_this._pending.call$0());
+ return t1;
+ }
+ };
+ P._IterablePendingEvents.prototype = {
+ get$isEmpty: function(_) {
+ return this._async$_iterator == null;
+ },
+ handleNext$1: function(dispatch) {
+ var hasMore, e, s, t1, exception, _this = this;
+ _this.$ti._eval$1("_EventDispatch<1>")._check(dispatch);
+ t1 = _this._async$_iterator;
+ if (t1 == null)
+ throw H.wrapException(P.StateError$("No events pending."));
+ hasMore = null;
+ try {
+ hasMore = t1.moveNext$0();
+ if (H.boolConversionCheck(hasMore))
+ dispatch._sendData$1(_this._async$_iterator.get$current());
+ else {
+ _this.set$_async$_iterator(null);
+ dispatch._sendDone$0();
+ }
+ } catch (exception) {
+ e = H.unwrapException(exception);
+ s = H.getTraceFromException(exception);
+ if (hasMore == null) {
+ _this.set$_async$_iterator(C.C_EmptyIterator);
+ dispatch._sendError$2(e, s);
+ } else
+ dispatch._sendError$2(e, s);
+ }
+ },
+ set$_async$_iterator: function(_iterator) {
+ this._async$_iterator = this.$ti._eval$1("Iterator<1>")._check(_iterator);
+ }
+ };
+ P._DelayedEvent.prototype = {
+ set$next: function(next) {
+ this.next = type$._DelayedEvent_dynamic._check(next);
+ },
+ get$next: function() {
+ return this.next;
+ }
+ };
+ P._DelayedData.prototype = {
+ perform$1: function(dispatch) {
+ this.$ti._eval$1("_EventDispatch<1>")._check(dispatch)._sendData$1(this.value);
+ }
+ };
+ P._DelayedError.prototype = {
+ perform$1: function(dispatch) {
+ dispatch._sendError$2(this.error, this.stackTrace);
+ }
+ };
+ P._DelayedDone.prototype = {
+ perform$1: function(dispatch) {
+ dispatch._sendDone$0();
+ },
+ get$next: function() {
+ return null;
+ },
+ set$next: function(_) {
+ throw H.wrapException(P.StateError$("No events after a done."));
+ },
+ $is_DelayedEvent: 1
+ };
+ P._PendingEvents.prototype = {
+ schedule$1: function(dispatch) {
+ var t1, _this = this;
+ H._instanceType(_this)._eval$1("_EventDispatch<1>")._check(dispatch);
+ if (_this._state === 1)
+ return;
+ H.assertHelper(!_this.get$isEmpty(_this));
+ t1 = _this._state;
+ if (t1 >= 1) {
+ H.assertHelper(t1 === 3);
+ _this._state = 1;
+ return;
+ }
+ P.scheduleMicrotask(new P._PendingEvents_schedule_closure(_this, dispatch));
+ _this._state = 1;
+ }
+ };
+ P._PendingEvents_schedule_closure.prototype = {
+ call$0: function() {
+ var t1 = this.$this,
+ oldState = t1._state;
+ t1._state = 0;
+ if (oldState === 3)
+ return;
+ t1.handleNext$1(this.dispatch);
+ },
+ $signature: 0
+ };
+ P._StreamImplEvents.prototype = {
+ get$isEmpty: function(_) {
+ return this.lastPendingEvent == null;
+ },
+ add$1: function(_, $event) {
+ var _this = this,
+ t1 = _this.lastPendingEvent;
+ if (t1 == null)
+ _this.firstPendingEvent = _this.lastPendingEvent = $event;
+ else {
+ t1.set$next($event);
+ _this.lastPendingEvent = $event;
+ }
+ },
+ handleNext$1: function(dispatch) {
+ var $event, t1, _this = this;
+ _this.$ti._eval$1("_EventDispatch<1>")._check(dispatch);
+ H.assertHelper(_this._state !== 1);
+ $event = _this.firstPendingEvent;
+ t1 = $event.get$next();
+ _this.firstPendingEvent = t1;
+ if (t1 == null)
+ _this.lastPendingEvent = null;
+ $event.perform$1(dispatch);
+ }
+ };
+ P._DoneStreamSubscription.prototype = {
+ get$isPaused: function() {
+ return this._state >= 4;
+ },
+ _schedule$0: function() {
+ var _this = this;
+ if ((_this._state & 2) !== 0)
+ return;
+ _this._zone.scheduleMicrotask$1(_this.get$_sendDone());
+ _this._state = (_this._state | 2) >>> 0;
+ },
+ onData$1: function(handleData) {
+ this.$ti._eval$1("~(1)")._check(handleData);
+ },
+ onError$1: function(_, handleError) {
+ },
+ onDone$1: function(handleDone) {
+ this.set$_onDone(type$.void_Function._check(handleDone));
+ },
+ pause$1: function(resumeSignal) {
+ this._state += 4;
+ },
+ pause$0: function() {
+ return this.pause$1(null);
+ },
+ resume$0: function() {
+ var t1 = this._state;
+ if (t1 >= 4) {
+ t1 = this._state = t1 - 4;
+ if (t1 < 4 && (t1 & 1) === 0)
+ this._schedule$0();
+ }
+ },
+ cancel$0: function() {
+ return $.$get$Future__nullFuture();
+ },
+ _sendDone$0: function() {
+ var _this = this,
+ t1 = _this._state = (_this._state & 4294967293) >>> 0;
+ if (t1 >= 4)
+ return;
+ _this._state = (t1 | 1) >>> 0;
+ t1 = _this._onDone;
+ if (t1 != null)
+ _this._zone.runGuarded$1(t1);
+ },
+ set$_onDone: function(_onDone) {
+ this._onDone = type$.void_Function._check(_onDone);
+ },
+ $isStreamSubscription: 1
+ };
+ P._StreamIterator.prototype = {};
+ P._EmptyStream.prototype = {
+ get$isBroadcast: function() {
+ return true;
+ },
+ listen$4$cancelOnError$onDone$onError: function(onData, cancelOnError, onDone, onError) {
+ var t1 = this.$ti;
+ t1._eval$1("~(1)")._check(onData);
+ type$.void_Function._check(onDone);
+ H._checkBoolNullable(cancelOnError);
+ t1 = new P._DoneStreamSubscription($.Zone__current, onDone, t1._eval$1("_DoneStreamSubscription<1>"));
+ t1._schedule$0();
+ return t1;
+ },
+ listen$3$onDone$onError: function(onData, onDone, onError) {
+ return this.listen$4$cancelOnError$onDone$onError(onData, null, onDone, onError);
+ },
+ listen$1: function(onData) {
+ return this.listen$4$cancelOnError$onDone$onError(onData, null, null, null);
+ }
+ };
+ P._cancelAndError_closure.prototype = {
+ call$0: function() {
+ return this.future._completeError$2(this.error, this.stackTrace);
+ },
+ $signature: 1
+ };
+ P._cancelAndErrorClosure_closure.prototype = {
+ call$2: function(error, stackTrace) {
+ P._cancelAndError(this.subscription, this.future, error, type$.StackTrace._check(stackTrace));
+ },
+ $signature: 5
+ };
+ P._cancelAndValue_closure.prototype = {
+ call$0: function() {
+ return this.future._complete$1(this.value);
+ },
+ $signature: 1
+ };
+ P.Timer.prototype = {};
+ P.AsyncError.prototype = {
+ toString$0: function(_) {
+ return H.S(this.error);
+ },
+ $isError: 1
+ };
+ P._ZoneFunction.prototype = {};
+ P.ZoneSpecification.prototype = {};
+ P._ZoneSpecification.prototype = {$isZoneSpecification: 1};
+ P.ZoneDelegate.prototype = {};
+ P.Zone.prototype = {};
+ P._ZoneDelegate.prototype = {
+ handleUncaughtError$3: function(zone, error, stackTrace) {
+ var implementation, implZone;
+ type$.StackTrace._check(stackTrace);
+ implementation = this._delegationTarget.get$_handleUncaughtError();
+ implZone = implementation.zone;
+ return implementation.$function.call$5(implZone, P._parentDelegate(implZone), zone, error, stackTrace);
+ },
+ registerCallback$1$2: function(zone, f, $R) {
+ var implementation, implZone;
+ $R._eval$1("0()")._check(f);
+ implementation = this._delegationTarget.get$_registerCallback();
+ implZone = implementation.zone;
+ return type$.A_Function_Function_A_4_Zone_and_ZoneDelegate_and_Zone_and_A_Function._check(implementation.$function).call$1$4(implZone, P._parentDelegate(implZone), zone, f, $R);
+ },
+ registerUnaryCallback$2$2: function(zone, f, $R, $T) {
+ var implementation, implZone;
+ $R._eval$1("@<0>")._bind$1($T)._eval$1("1(2)")._check(f);
+ implementation = this._delegationTarget.get$_registerUnaryCallback();
+ implZone = implementation.zone;
+ return type$.A_Function_B_Function_A_and_B_4_Zone_and_ZoneDelegate_and_Zone_and_A_Function_B._check(implementation.$function).call$2$4(implZone, P._parentDelegate(implZone), zone, f, $R, $T);
+ },
+ registerBinaryCallback$3$2: function(zone, f, $R, T1, T2) {
+ var implementation, implZone;
+ $R._eval$1("@<0>")._bind$1(T1)._bind$1(T2)._eval$1("1(2,3)")._check(f);
+ implementation = this._delegationTarget.get$_registerBinaryCallback();
+ implZone = implementation.zone;
+ return type$.A_Function_2_B_and_C_Function_A_and_B_and_C_4_Zone_and_ZoneDelegate_and_Zone_and_A_Function_2_B_and_C._check(implementation.$function).call$3$4(implZone, P._parentDelegate(implZone), zone, f, $R, T1, T2);
+ },
+ errorCallback$3: function(zone, error, stackTrace) {
+ var implementation = this._delegationTarget.get$_errorCallback(),
+ implZone = implementation.zone;
+ if (implZone === C.C__RootZone)
+ return null;
+ return implementation.$function.call$5(implZone, P._parentDelegate(implZone), zone, error, stackTrace);
+ },
+ $isZoneDelegate: 1
+ };
+ P._Zone.prototype = {$isZone: 1};
+ P._CustomZone.prototype = {
+ get$_delegate: function() {
+ var t1 = this._delegateCache;
+ if (t1 != null)
+ return t1;
+ return this._delegateCache = new P._ZoneDelegate(this);
+ },
+ get$errorZone: function() {
+ return this._handleUncaughtError.zone;
+ },
+ runGuarded$1: function(f) {
+ var e, s, exception;
+ type$.void_Function._check(f);
+ try {
+ this.run$1$1(f, type$.void);
+ } catch (exception) {
+ e = H.unwrapException(exception);
+ s = H.getTraceFromException(exception);
+ this.handleUncaughtError$2(e, s);
+ }
+ },
+ runUnaryGuarded$1$2: function(f, arg, $T) {
+ var e, s, exception;
+ $T._eval$1("~(0)")._check(f);
+ $T._check(arg);
+ try {
+ this.runUnary$2$2(f, arg, type$.void, $T);
+ } catch (exception) {
+ e = H.unwrapException(exception);
+ s = H.getTraceFromException(exception);
+ this.handleUncaughtError$2(e, s);
+ }
+ },
+ runBinaryGuarded$2$3: function(f, arg1, arg2, T1, T2) {
+ var e, s, exception;
+ T1._eval$1("@<0>")._bind$1(T2)._eval$1("~(1,2)")._check(f);
+ T1._check(arg1);
+ T2._check(arg2);
+ try {
+ this.runBinary$3$3(f, arg1, arg2, type$.void, T1, T2);
+ } catch (exception) {
+ e = H.unwrapException(exception);
+ s = H.getTraceFromException(exception);
+ this.handleUncaughtError$2(e, s);
+ }
+ },
+ bindCallback$1$1: function(f, $R) {
+ return new P._CustomZone_bindCallback_closure(this, this.registerCallback$1$1($R._eval$1("0()")._check(f), $R), $R);
+ },
+ bindUnaryCallback$2$1: function(f, $R, $T) {
+ return new P._CustomZone_bindUnaryCallback_closure(this, this.registerUnaryCallback$2$1($R._eval$1("@<0>")._bind$1($T)._eval$1("1(2)")._check(f), $R, $T), $T, $R);
+ },
+ bindCallbackGuarded$1: function(f) {
+ return new P._CustomZone_bindCallbackGuarded_closure(this, this.registerCallback$1$1(type$.void_Function._check(f), type$.void));
+ },
+ bindUnaryCallbackGuarded$1$1: function(f, $T) {
+ return new P._CustomZone_bindUnaryCallbackGuarded_closure(this, this.registerUnaryCallback$2$1($T._eval$1("~(0)")._check(f), type$.void, $T), $T);
+ },
+ $index: function(_, key) {
+ var value,
+ t1 = this._async$_map,
+ result = t1.$index(0, key);
+ if (result != null || t1.containsKey$1(key))
+ return result;
+ value = this.parent.$index(0, key);
+ if (value != null)
+ t1.$indexSet(0, key, value);
+ return value;
+ },
+ handleUncaughtError$2: function(error, stackTrace) {
+ var implementation, t1, parentDelegate;
+ type$.StackTrace._check(stackTrace);
+ implementation = this._handleUncaughtError;
+ H.assertHelper(implementation != null);
+ t1 = implementation.zone;
+ parentDelegate = P._parentDelegate(t1);
+ return implementation.$function.call$5(t1, parentDelegate, this, error, stackTrace);
+ },
+ fork$2$specification$zoneValues: function(specification, zoneValues) {
+ var t1, parentDelegate,
+ implementation = this._fork;
+ H.assertHelper(implementation != null);
+ t1 = implementation.zone;
+ parentDelegate = P._parentDelegate(t1);
+ return implementation.$function.call$5(t1, parentDelegate, this, specification, zoneValues);
+ },
+ run$1$1: function(f, $R) {
+ var implementation, t1, parentDelegate;
+ $R._eval$1("0()")._check(f);
+ implementation = this._run;
+ H.assertHelper(implementation != null);
+ t1 = implementation.zone;
+ parentDelegate = P._parentDelegate(t1);
+ return type$.A_Function_A_4_Zone_and_ZoneDelegate_and_Zone_and_A_Function._check(implementation.$function).call$1$4(t1, parentDelegate, this, f, $R);
+ },
+ runUnary$2$2: function(f, arg, $R, $T) {
+ var implementation, t1, parentDelegate;
+ $R._eval$1("@<0>")._bind$1($T)._eval$1("1(2)")._check(f);
+ $T._check(arg);
+ implementation = this._runUnary;
+ H.assertHelper(implementation != null);
+ t1 = implementation.zone;
+ parentDelegate = P._parentDelegate(t1);
+ return type$.A_Function_A_and_B_5_Zone_and_ZoneDelegate_and_Zone_and_A_Function_B_and_B._check(implementation.$function).call$2$5(t1, parentDelegate, this, f, arg, $R, $T);
+ },
+ runBinary$3$3: function(f, arg1, arg2, $R, T1, T2) {
+ var implementation, t1, parentDelegate;
+ $R._eval$1("@<0>")._bind$1(T1)._bind$1(T2)._eval$1("1(2,3)")._check(f);
+ T1._check(arg1);
+ T2._check(arg2);
+ implementation = this._runBinary;
+ H.assertHelper(implementation != null);
+ t1 = implementation.zone;
+ parentDelegate = P._parentDelegate(t1);
+ return type$.A_Function_A_and_B_and_C_6_Zone_and_ZoneDelegate_and_Zone_and_A_Function_2_B_and_C_and_B_and_C._check(implementation.$function).call$3$6(t1, parentDelegate, this, f, arg1, arg2, $R, T1, T2);
+ },
+ registerCallback$1$1: function(callback, $R) {
+ var implementation, t1, parentDelegate;
+ $R._eval$1("0()")._check(callback);
+ implementation = this._registerCallback;
+ H.assertHelper(implementation != null);
+ t1 = implementation.zone;
+ parentDelegate = P._parentDelegate(t1);
+ return type$.A_Function_Function_A_4_Zone_and_ZoneDelegate_and_Zone_and_A_Function._check(implementation.$function).call$1$4(t1, parentDelegate, this, callback, $R);
+ },
+ registerUnaryCallback$2$1: function(callback, $R, $T) {
+ var implementation, t1, parentDelegate;
+ $R._eval$1("@<0>")._bind$1($T)._eval$1("1(2)")._check(callback);
+ implementation = this._registerUnaryCallback;
+ H.assertHelper(implementation != null);
+ t1 = implementation.zone;
+ parentDelegate = P._parentDelegate(t1);
+ return type$.A_Function_B_Function_A_and_B_4_Zone_and_ZoneDelegate_and_Zone_and_A_Function_B._check(implementation.$function).call$2$4(t1, parentDelegate, this, callback, $R, $T);
+ },
+ registerBinaryCallback$3$1: function(callback, $R, T1, T2) {
+ var implementation, t1, parentDelegate;
+ $R._eval$1("@<0>")._bind$1(T1)._bind$1(T2)._eval$1("1(2,3)")._check(callback);
+ implementation = this._registerBinaryCallback;
+ H.assertHelper(implementation != null);
+ t1 = implementation.zone;
+ parentDelegate = P._parentDelegate(t1);
+ return type$.A_Function_2_B_and_C_Function_A_and_B_and_C_4_Zone_and_ZoneDelegate_and_Zone_and_A_Function_2_B_and_C._check(implementation.$function).call$3$4(t1, parentDelegate, this, callback, $R, T1, T2);
+ },
+ errorCallback$2: function(error, stackTrace) {
+ var implementation, implementationZone, parentDelegate;
+ type$.StackTrace._check(stackTrace);
+ implementation = this._errorCallback;
+ H.assertHelper(implementation != null);
+ implementationZone = implementation.zone;
+ if (implementationZone === C.C__RootZone)
+ return null;
+ parentDelegate = P._parentDelegate(implementationZone);
+ return implementation.$function.call$5(implementationZone, parentDelegate, this, error, stackTrace);
+ },
+ scheduleMicrotask$1: function(f) {
+ var implementation, t1, parentDelegate;
+ type$.void_Function._check(f);
+ implementation = this._scheduleMicrotask;
+ H.assertHelper(implementation != null);
+ t1 = implementation.zone;
+ parentDelegate = P._parentDelegate(t1);
+ return implementation.$function.call$4(t1, parentDelegate, this, f);
+ },
+ createTimer$2: function(duration, f) {
+ var implementation, t1, parentDelegate;
+ type$.void_Function._check(f);
+ implementation = this._createTimer;
+ H.assertHelper(implementation != null);
+ t1 = implementation.zone;
+ parentDelegate = P._parentDelegate(t1);
+ return implementation.$function.call$5(t1, parentDelegate, this, duration, f);
+ },
+ print$1: function(_, line) {
+ var t1, parentDelegate,
+ implementation = this._print;
+ H.assertHelper(implementation != null);
+ t1 = implementation.zone;
+ parentDelegate = P._parentDelegate(t1);
+ return implementation.$function.call$4(t1, parentDelegate, this, line);
+ },
+ set$_run: function(_run) {
+ this._run = type$._ZoneFunction_Function._check(_run);
+ },
+ set$_runUnary: function(_runUnary) {
+ this._runUnary = type$._ZoneFunction_Function._check(_runUnary);
+ },
+ set$_runBinary: function(_runBinary) {
+ this._runBinary = type$._ZoneFunction_Function._check(_runBinary);
+ },
+ set$_registerCallback: function(_registerCallback) {
+ this._registerCallback = type$._ZoneFunction_Function._check(_registerCallback);
+ },
+ set$_registerUnaryCallback: function(_registerUnaryCallback) {
+ this._registerUnaryCallback = type$._ZoneFunction_Function._check(_registerUnaryCallback);
+ },
+ set$_registerBinaryCallback: function(_registerBinaryCallback) {
+ this._registerBinaryCallback = type$._ZoneFunction_Function._check(_registerBinaryCallback);
+ },
+ set$_errorCallback: function(_errorCallback) {
+ this._errorCallback = type$._ZoneFunction_of_AsyncError_Function_Zone_ZoneDelegate_Zone_Object_StackTrace._check(_errorCallback);
+ },
+ set$_scheduleMicrotask: function(_scheduleMicrotask) {
+ this._scheduleMicrotask = type$._ZoneFunction_of_void_Function_4_Zone_and_ZoneDelegate_and_Zone_and_void_Function._check(_scheduleMicrotask);
+ },
+ set$_createTimer: function(_createTimer) {
+ this._createTimer = type$._ZoneFunction_of_Timer_Function_5_Zone_and_ZoneDelegate_and_Zone_and_Duration_and_void_Function._check(_createTimer);
+ },
+ set$_createPeriodicTimer: function(_createPeriodicTimer) {
+ this._createPeriodicTimer = type$._ZoneFunction_of_Timer_Function_5_Zone_and_ZoneDelegate_and_Zone_and_Duration_and_void_Function_Timer._check(_createPeriodicTimer);
+ },
+ set$_print: function(_print) {
+ this._print = type$._ZoneFunction_of_void_Function_Zone_ZoneDelegate_Zone_String._check(_print);
+ },
+ set$_fork: function(_fork) {
+ this._fork = type$._ZoneFunction_of_Zone_Function_5_Zone_and_ZoneDelegate_and_Zone_and_ZoneSpecification_and_Map_dynamic_dynamic._check(_fork);
+ },
+ set$_handleUncaughtError: function(_handleUncaughtError) {
+ this._handleUncaughtError = type$._ZoneFunction_of_void_Function_Zone_ZoneDelegate_Zone_Object_StackTrace._check(_handleUncaughtError);
+ },
+ get$_run: function() {
+ return this._run;
+ },
+ get$_runUnary: function() {
+ return this._runUnary;
+ },
+ get$_runBinary: function() {
+ return this._runBinary;
+ },
+ get$_registerCallback: function() {
+ return this._registerCallback;
+ },
+ get$_registerUnaryCallback: function() {
+ return this._registerUnaryCallback;
+ },
+ get$_registerBinaryCallback: function() {
+ return this._registerBinaryCallback;
+ },
+ get$_errorCallback: function() {
+ return this._errorCallback;
+ },
+ get$_scheduleMicrotask: function() {
+ return this._scheduleMicrotask;
+ },
+ get$_createTimer: function() {
+ return this._createTimer;
+ },
+ get$_createPeriodicTimer: function() {
+ return this._createPeriodicTimer;
+ },
+ get$_print: function() {
+ return this._print;
+ },
+ get$_fork: function() {
+ return this._fork;
+ },
+ get$_handleUncaughtError: function() {
+ return this._handleUncaughtError;
+ },
+ get$parent: function(receiver) {
+ return this.parent;
+ },
+ get$_async$_map: function() {
+ return this._async$_map;
+ }
+ };
+ P._CustomZone_bindCallback_closure.prototype = {
+ call$0: function() {
+ return this.$this.run$1$1(this.registered, this.R);
+ },
+ $signature: function() {
+ return this.R._eval$1("0()");
+ }
+ };
+ P._CustomZone_bindUnaryCallback_closure.prototype = {
+ call$1: function(arg) {
+ var _this = this,
+ t1 = _this.T;
+ return _this.$this.runUnary$2$2(_this.registered, t1._check(arg), _this.R, t1);
+ },
+ $signature: function() {
+ return this.R._eval$1("@<0>")._bind$1(this.T)._eval$1("1(2)");
+ }
+ };
+ P._CustomZone_bindCallbackGuarded_closure.prototype = {
+ call$0: function() {
+ return this.$this.runGuarded$1(this.registered);
+ },
+ $signature: 1
+ };
+ P._CustomZone_bindUnaryCallbackGuarded_closure.prototype = {
+ call$1: function(arg) {
+ var t1 = this.T;
+ return this.$this.runUnaryGuarded$1$2(this.registered, t1._check(arg), t1);
+ },
+ $signature: function() {
+ return this.T._eval$1("~(0)");
+ }
+ };
+ P._rootHandleUncaughtError_closure.prototype = {
+ call$0: function() {
+ var error,
+ t1 = this._box_0,
+ t2 = t1.error;
+ t1 = t2 == null ? t1.error = new P.NullThrownError() : t2;
+ t2 = this.stackTrace;
+ if (t2 == null)
+ throw H.wrapException(t1);
+ error = H.wrapException(t1);
+ error.stack = t2.toString$0(0);
+ throw error;
+ },
+ $signature: 0
+ };
+ P._RootZone.prototype = {
+ get$_run: function() {
+ return C._ZoneFunction__RootZone__rootRun;
+ },
+ get$_runUnary: function() {
+ return C._ZoneFunction__RootZone__rootRunUnary;
+ },
+ get$_runBinary: function() {
+ return C._ZoneFunction__RootZone__rootRunBinary;
+ },
+ get$_registerCallback: function() {
+ return C._ZoneFunction__RootZone__rootRegisterCallback;
+ },
+ get$_registerUnaryCallback: function() {
+ return C._ZoneFunction_Eeh;
+ },
+ get$_registerBinaryCallback: function() {
+ return C._ZoneFunction_7G2;
+ },
+ get$_errorCallback: function() {
+ return C._ZoneFunction__RootZone__rootErrorCallback;
+ },
+ get$_scheduleMicrotask: function() {
+ return C._ZoneFunction__RootZone__rootScheduleMicrotask;
+ },
+ get$_createTimer: function() {
+ return C._ZoneFunction__RootZone__rootCreateTimer;
+ },
+ get$_createPeriodicTimer: function() {
+ return C._ZoneFunction_3bB;
+ },
+ get$_print: function() {
+ return C._ZoneFunction__RootZone__rootPrint;
+ },
+ get$_fork: function() {
+ return C._ZoneFunction__RootZone__rootFork;
+ },
+ get$_handleUncaughtError: function() {
+ return C._ZoneFunction_NMc;
+ },
+ get$parent: function(_) {
+ return null;
+ },
+ get$_async$_map: function() {
+ return $.$get$_RootZone__rootMap();
+ },
+ get$_delegate: function() {
+ var t1 = $._RootZone__rootDelegate;
+ if (t1 != null)
+ return t1;
+ return $._RootZone__rootDelegate = new P._ZoneDelegate(this);
+ },
+ get$errorZone: function() {
+ return this;
+ },
+ runGuarded$1: function(f) {
+ var e, s, exception, _null = null;
+ type$.void_Function._check(f);
+ try {
+ if (C.C__RootZone === $.Zone__current) {
+ f.call$0();
+ return;
+ }
+ P._rootRun(_null, _null, this, f, type$.void);
+ } catch (exception) {
+ e = H.unwrapException(exception);
+ s = H.getTraceFromException(exception);
+ P._rootHandleUncaughtError(_null, _null, this, e, type$.StackTrace._check(s));
+ }
+ },
+ runUnaryGuarded$1$2: function(f, arg, $T) {
+ var e, s, exception, _null = null;
+ $T._eval$1("~(0)")._check(f);
+ $T._check(arg);
+ try {
+ if (C.C__RootZone === $.Zone__current) {
+ f.call$1(arg);
+ return;
+ }
+ P._rootRunUnary(_null, _null, this, f, arg, type$.void, $T);
+ } catch (exception) {
+ e = H.unwrapException(exception);
+ s = H.getTraceFromException(exception);
+ P._rootHandleUncaughtError(_null, _null, this, e, type$.StackTrace._check(s));
+ }
+ },
+ runBinaryGuarded$2$3: function(f, arg1, arg2, T1, T2) {
+ var e, s, exception, _null = null;
+ T1._eval$1("@<0>")._bind$1(T2)._eval$1("~(1,2)")._check(f);
+ T1._check(arg1);
+ T2._check(arg2);
+ try {
+ if (C.C__RootZone === $.Zone__current) {
+ f.call$2(arg1, arg2);
+ return;
+ }
+ P._rootRunBinary(_null, _null, this, f, arg1, arg2, type$.void, T1, T2);
+ } catch (exception) {
+ e = H.unwrapException(exception);
+ s = H.getTraceFromException(exception);
+ P._rootHandleUncaughtError(_null, _null, this, e, type$.StackTrace._check(s));
+ }
+ },
+ bindCallback$1$1: function(f, $R) {
+ return new P._RootZone_bindCallback_closure(this, $R._eval$1("0()")._check(f), $R);
+ },
+ bindCallbackGuarded$1: function(f) {
+ return new P._RootZone_bindCallbackGuarded_closure(this, type$.void_Function._check(f));
+ },
+ bindUnaryCallbackGuarded$1$1: function(f, $T) {
+ return new P._RootZone_bindUnaryCallbackGuarded_closure(this, $T._eval$1("~(0)")._check(f), $T);
+ },
+ $index: function(_, key) {
+ return null;
+ },
+ handleUncaughtError$2: function(error, stackTrace) {
+ P._rootHandleUncaughtError(null, null, this, error, type$.StackTrace._check(stackTrace));
+ },
+ fork$2$specification$zoneValues: function(specification, zoneValues) {
+ return P._rootFork(null, null, this, specification, zoneValues);
+ },
+ run$1$1: function(f, $R) {
+ $R._eval$1("0()")._check(f);
+ if ($.Zone__current === C.C__RootZone)
+ return f.call$0();
+ return P._rootRun(null, null, this, f, $R);
+ },
+ runUnary$2$2: function(f, arg, $R, $T) {
+ $R._eval$1("@<0>")._bind$1($T)._eval$1("1(2)")._check(f);
+ $T._check(arg);
+ if ($.Zone__current === C.C__RootZone)
+ return f.call$1(arg);
+ return P._rootRunUnary(null, null, this, f, arg, $R, $T);
+ },
+ runBinary$3$3: function(f, arg1, arg2, $R, T1, T2) {
+ $R._eval$1("@<0>")._bind$1(T1)._bind$1(T2)._eval$1("1(2,3)")._check(f);
+ T1._check(arg1);
+ T2._check(arg2);
+ if ($.Zone__current === C.C__RootZone)
+ return f.call$2(arg1, arg2);
+ return P._rootRunBinary(null, null, this, f, arg1, arg2, $R, T1, T2);
+ },
+ registerCallback$1$1: function(f, $R) {
+ return $R._eval$1("0()")._check(f);
+ },
+ registerUnaryCallback$2$1: function(f, $R, $T) {
+ return $R._eval$1("@<0>")._bind$1($T)._eval$1("1(2)")._check(f);
+ },
+ registerBinaryCallback$3$1: function(f, $R, T1, T2) {
+ return $R._eval$1("@<0>")._bind$1(T1)._bind$1(T2)._eval$1("1(2,3)")._check(f);
+ },
+ errorCallback$2: function(error, stackTrace) {
+ type$.StackTrace._check(stackTrace);
+ return null;
+ },
+ scheduleMicrotask$1: function(f) {
+ P._rootScheduleMicrotask(null, null, this, type$.void_Function._check(f));
+ },
+ createTimer$2: function(duration, f) {
+ return P.Timer__createTimer(duration, type$.void_Function._check(f));
+ },
+ print$1: function(_, line) {
+ H.printString(line);
+ }
+ };
+ P._RootZone_bindCallback_closure.prototype = {
+ call$0: function() {
+ return this.$this.run$1$1(this.f, this.R);
+ },
+ $signature: function() {
+ return this.R._eval$1("0()");
+ }
+ };
+ P._RootZone_bindCallbackGuarded_closure.prototype = {
+ call$0: function() {
+ return this.$this.runGuarded$1(this.f);
+ },
+ $signature: 1
+ };
+ P._RootZone_bindUnaryCallbackGuarded_closure.prototype = {
+ call$1: function(arg) {
+ var t1 = this.T;
+ return this.$this.runUnaryGuarded$1$2(this.f, t1._check(arg), t1);
+ },
+ $signature: function() {
+ return this.T._eval$1("~(0)");
+ }
+ };
+ P.runZoned_closure.prototype = {
+ call$5: function($self, $parent, zone, error, stackTrace) {
+ var e, s, t2, t3, t4, exception,
+ t1 = type$.StackTrace;
+ t1._check(stackTrace);
+ try {
+ t2 = this._box_0;
+ t3 = type$.void;
+ t4 = type$.Object;
+ if (t2.binaryOnError != null)
+ $self.get$parent($self).runBinary$3$3(t2.binaryOnError, error, stackTrace, t3, t4, t1);
+ else {
+ H.assertHelper(t2.unaryOnError != null);
+ $self.get$parent($self).runUnary$2$2(t2.unaryOnError, error, t3, t4);
+ }
+ } catch (exception) {
+ e = H.unwrapException(exception);
+ s = H.getTraceFromException(exception);
+ t1 = e;
+ if (t1 == null ? error == null : t1 === error)
+ $parent.handleUncaughtError$3(zone, error, stackTrace);
+ else
+ $parent.handleUncaughtError$3(zone, e, s);
+ }
+ },
+ $signature: 28
+ };
+ P._HashMap.prototype = {
+ get$length: function(_) {
+ return this._collection$_length;
+ },
+ get$isEmpty: function(_) {
+ return this._collection$_length === 0;
+ },
+ get$keys: function() {
+ return new P._HashMapKeyIterable(this, H._instanceType(this)._eval$1("_HashMapKeyIterable<1>"));
+ },
+ containsKey$1: function(key) {
+ var strings, nums;
+ if (typeof key == "string" && key !== "__proto__") {
+ strings = this._strings;
+ return strings == null ? false : strings[key] != null;
+ } else if (typeof key == "number" && (key & 1073741823) === key) {
+ nums = this._nums;
+ return nums == null ? false : nums[key] != null;
+ } else
+ return this._containsKey$1(key);
+ },
+ _containsKey$1: function(key) {
+ var rest = this._collection$_rest;
+ if (rest == null)
+ return false;
+ return this._findBucketIndex$2(this._getBucket$2(rest, key), key) >= 0;
+ },
+ $index: function(_, key) {
+ var strings, t1, nums;
+ if (typeof key == "string" && key !== "__proto__") {
+ strings = this._strings;
+ t1 = strings == null ? null : P._HashMap__getTableEntry(strings, key);
+ return t1;
+ } else if (typeof key == "number" && (key & 1073741823) === key) {
+ nums = this._nums;
+ t1 = nums == null ? null : P._HashMap__getTableEntry(nums, key);
+ return t1;
+ } else
+ return this._get$1(key);
+ },
+ _get$1: function(key) {
+ var bucket, index,
+ rest = this._collection$_rest;
+ if (rest == null)
+ return null;
+ bucket = this._getBucket$2(rest, key);
+ index = this._findBucketIndex$2(bucket, key);
+ return index < 0 ? null : bucket[index + 1];
+ },
+ $indexSet: function(_, key, value) {
+ var strings, nums, _this = this,
+ t1 = H._instanceType(_this);
+ t1._precomputed1._check(key);
+ t1._rest[1]._check(value);
+ if (typeof key == "string" && key !== "__proto__") {
+ strings = _this._strings;
+ _this._addHashTableEntry$3(strings == null ? _this._strings = P._HashMap__newHashTable() : strings, key, value);
+ } else if (typeof key == "number" && (key & 1073741823) === key) {
+ nums = _this._nums;
+ _this._addHashTableEntry$3(nums == null ? _this._nums = P._HashMap__newHashTable() : nums, key, value);
+ } else
+ _this._set$2(key, value);
+ },
+ _set$2: function(key, value) {
+ var rest, hash, bucket, index, _this = this,
+ t1 = H._instanceType(_this);
+ t1._precomputed1._check(key);
+ t1._rest[1]._check(value);
+ rest = _this._collection$_rest;
+ if (rest == null)
+ rest = _this._collection$_rest = P._HashMap__newHashTable();
+ hash = _this._computeHashCode$1(key);
+ bucket = rest[hash];
+ if (bucket == null) {
+ P._HashMap__setTableEntry(rest, hash, [key, value]);
+ ++_this._collection$_length;
+ _this._keys = null;
+ } else {
+ index = _this._findBucketIndex$2(bucket, key);
+ if (index >= 0)
+ bucket[index + 1] = value;
+ else {
+ bucket.push(key, value);
+ ++_this._collection$_length;
+ _this._keys = null;
+ }
+ }
+ },
+ remove$1: function(_, key) {
+ var t1 = this._remove$1(key);
+ return t1;
+ },
+ _remove$1: function(key) {
+ var hash, bucket, index, result, _this = this,
+ rest = _this._collection$_rest;
+ if (rest == null)
+ return null;
+ hash = _this._computeHashCode$1(key);
+ bucket = rest[hash];
+ index = _this._findBucketIndex$2(bucket, key);
+ if (index < 0)
+ return null;
+ --_this._collection$_length;
+ _this._keys = null;
+ result = bucket.splice(index, 2)[1];
+ if (0 === bucket.length)
+ delete rest[hash];
+ return result;
+ },
+ forEach$1: function(_, action) {
+ var keys, $length, i, key, _this = this,
+ t1 = H._instanceType(_this);
+ t1._eval$1("~(1,2)")._check(action);
+ keys = _this._computeKeys$0();
+ for ($length = keys.length, t1 = t1._precomputed1, i = 0; i < $length; ++i) {
+ key = keys[i];
+ action.call$2(t1._check(key), _this.$index(0, key));
+ if (keys !== _this._keys)
+ throw H.wrapException(P.ConcurrentModificationError$(_this));
+ }
+ },
+ _computeKeys$0: function() {
+ var result, strings, names, entries, index, i, nums, rest, bucket, $length, i0, _this = this,
+ t1 = _this._keys;
+ if (t1 != null)
+ return t1;
+ result = new Array(_this._collection$_length);
+ result.fixed$length = Array;
+ strings = _this._strings;
+ if (strings != null) {
+ names = Object.getOwnPropertyNames(strings);
+ entries = names.length;
+ for (index = 0, i = 0; i < entries; ++i) {
+ result[index] = names[i];
+ ++index;
+ }
+ } else
+ index = 0;
+ nums = _this._nums;
+ if (nums != null) {
+ names = Object.getOwnPropertyNames(nums);
+ entries = names.length;
+ for (i = 0; i < entries; ++i) {
+ result[index] = +names[i];
+ ++index;
+ }
+ }
+ rest = _this._collection$_rest;
+ if (rest != null) {
+ names = Object.getOwnPropertyNames(rest);
+ entries = names.length;
+ for (i = 0; i < entries; ++i) {
+ bucket = rest[names[i]];
+ $length = bucket.length;
+ for (i0 = 0; i0 < $length; i0 += 2) {
+ result[index] = bucket[i0];
+ ++index;
+ }
+ }
+ }
+ H.assertHelper(index === _this._collection$_length);
+ return _this._keys = result;
+ },
+ _addHashTableEntry$3: function(table, key, value) {
+ var t1 = H._instanceType(this);
+ t1._precomputed1._check(key);
+ t1._rest[1]._check(value);
+ if (table[key] == null) {
+ ++this._collection$_length;
+ this._keys = null;
+ }
+ P._HashMap__setTableEntry(table, key, value);
+ },
+ _computeHashCode$1: function(key) {
+ return J.get$hashCode$(key) & 1073741823;
+ },
+ _getBucket$2: function(table, key) {
+ return table[this._computeHashCode$1(key)];
+ },
+ _findBucketIndex$2: function(bucket, key) {
+ var $length, i;
+ if (bucket == null)
+ return -1;
+ $length = bucket.length;
+ for (i = 0; i < $length; i += 2)
+ if (J.$eq$(bucket[i], key))
+ return i;
+ return -1;
+ }
+ };
+ P._IdentityHashMap.prototype = {
+ _computeHashCode$1: function(key) {
+ return H.objectHashCode(key) & 1073741823;
+ },
+ _findBucketIndex$2: function(bucket, key) {
+ var $length, i, t1;
+ if (bucket == null)
+ return -1;
+ $length = bucket.length;
+ for (i = 0; i < $length; i += 2) {
+ t1 = bucket[i];
+ if (t1 == null ? key == null : t1 === key)
+ return i;
+ }
+ return -1;
+ }
+ };
+ P._HashMapKeyIterable.prototype = {
+ get$length: function(_) {
+ return this._map._collection$_length;
+ },
+ get$isEmpty: function(_) {
+ return this._map._collection$_length === 0;
+ },
+ get$iterator: function(_) {
+ var t1 = this._map;
+ return new P._HashMapKeyIterator(t1, t1._computeKeys$0(), this.$ti._eval$1("_HashMapKeyIterator<1>"));
+ },
+ contains$1: function(_, element) {
+ return this._map.containsKey$1(element);
+ }
+ };
+ P._HashMapKeyIterator.prototype = {
+ get$current: function() {
+ return this._collection$_current;
+ },
+ moveNext$0: function() {
+ var _this = this,
+ keys = _this._keys,
+ offset = _this._offset,
+ t1 = _this._map;
+ if (keys !== t1._keys)
+ throw H.wrapException(P.ConcurrentModificationError$(t1));
+ else if (offset >= keys.length) {
+ _this.set$_collection$_current(null);
+ return false;
+ } else {
+ _this.set$_collection$_current(keys[offset]);
+ _this._offset = offset + 1;
+ return true;
+ }
+ },
+ set$_collection$_current: function(_current) {
+ this._collection$_current = this.$ti._precomputed1._check(_current);
+ },
+ $isIterator: 1
+ };
+ P._LinkedHashSet.prototype = {
+ _newSet$0: function() {
+ return new P._LinkedHashSet(H._instanceType(this)._eval$1("_LinkedHashSet<1>"));
+ },
+ get$iterator: function(_) {
+ var _this = this,
+ t1 = new P._LinkedHashSetIterator(_this, _this._collection$_modifications, H._instanceType(_this)._eval$1("_LinkedHashSetIterator<1>"));
+ t1._collection$_cell = _this._collection$_first;
+ return t1;
+ },
+ get$length: function(_) {
+ return this._collection$_length;
+ },
+ get$isEmpty: function(_) {
+ return this._collection$_length === 0;
+ },
+ contains$1: function(_, object) {
+ var strings, nums;
+ if (typeof object == "string" && object !== "__proto__") {
+ strings = this._strings;
+ if (strings == null)
+ return false;
+ return type$._LinkedHashSetCell._check(strings[object]) != null;
+ } else if (typeof object == "number" && (object & 1073741823) === object) {
+ nums = this._nums;
+ if (nums == null)
+ return false;
+ return type$._LinkedHashSetCell._check(nums[object]) != null;
+ } else
+ return this._contains$1(object);
+ },
+ _contains$1: function(object) {
+ var rest = this._collection$_rest;
+ if (rest == null)
+ return false;
+ return this._findBucketIndex$2(rest[this._computeHashCode$1(object)], object) >= 0;
+ },
+ get$first: function(_) {
+ var t1 = this._collection$_first;
+ if (t1 == null)
+ throw H.wrapException(P.StateError$("No elements"));
+ return H._instanceType(this)._precomputed1._check(t1._element);
+ },
+ get$last: function(_) {
+ var t1 = this._collection$_last;
+ if (t1 == null)
+ throw H.wrapException(P.StateError$("No elements"));
+ return H._instanceType(this)._precomputed1._check(t1._element);
+ },
+ add$1: function(_, element) {
+ var strings, nums, _this = this;
+ H._instanceType(_this)._precomputed1._check(element);
+ if (typeof element == "string" && element !== "__proto__") {
+ strings = _this._strings;
+ return _this._addHashTableEntry$2(strings == null ? _this._strings = P._LinkedHashSet__newHashTable() : strings, element);
+ } else if (typeof element == "number" && (element & 1073741823) === element) {
+ nums = _this._nums;
+ return _this._addHashTableEntry$2(nums == null ? _this._nums = P._LinkedHashSet__newHashTable() : nums, element);
+ } else
+ return _this._collection$_add$1(element);
+ },
+ _collection$_add$1: function(element) {
+ var rest, hash, bucket, t1, _this = this;
+ H._instanceType(_this)._precomputed1._check(element);
+ rest = _this._collection$_rest;
+ if (rest == null)
+ rest = _this._collection$_rest = P._LinkedHashSet__newHashTable();
+ hash = _this._computeHashCode$1(element);
+ bucket = rest[hash];
+ if (bucket == null) {
+ t1 = [_this._collection$_newLinkedCell$1(element)];
+ H.assertHelper(t1 != null);
+ rest[hash] = t1;
+ } else {
+ if (_this._findBucketIndex$2(bucket, element) >= 0)
+ return false;
+ bucket.push(_this._collection$_newLinkedCell$1(element));
+ }
+ return true;
+ },
+ remove$1: function(_, object) {
+ var _this = this;
+ if (typeof object == "string" && object !== "__proto__")
+ return _this._removeHashTableEntry$2(_this._strings, object);
+ else if (typeof object == "number" && (object & 1073741823) === object)
+ return _this._removeHashTableEntry$2(_this._nums, object);
+ else
+ return _this._remove$1(object);
+ },
+ _remove$1: function(object) {
+ var hash, bucket, index, cell, _this = this,
+ rest = _this._collection$_rest;
+ if (rest == null)
+ return false;
+ hash = _this._computeHashCode$1(object);
+ bucket = rest[hash];
+ index = _this._findBucketIndex$2(bucket, object);
+ if (index < 0)
+ return false;
+ cell = bucket.splice(index, 1)[0];
+ if (0 === bucket.length)
+ delete rest[hash];
+ _this._unlinkCell$1(cell);
+ return true;
+ },
+ _addHashTableEntry$2: function(table, element) {
+ H._instanceType(this)._precomputed1._check(element);
+ if (type$._LinkedHashSetCell._check(table[element]) != null)
+ return false;
+ table[element] = this._collection$_newLinkedCell$1(element);
+ return true;
+ },
+ _removeHashTableEntry$2: function(table, element) {
+ var cell;
+ if (table == null)
+ return false;
+ cell = type$._LinkedHashSetCell._check(table[element]);
+ if (cell == null)
+ return false;
+ this._unlinkCell$1(cell);
+ delete table[element];
+ return true;
+ },
+ _collection$_modified$0: function() {
+ this._collection$_modifications = 1073741823 & this._collection$_modifications + 1;
+ },
+ _collection$_newLinkedCell$1: function(element) {
+ var last, _this = this,
+ cell = new P._LinkedHashSetCell(H._instanceType(_this)._precomputed1._check(element));
+ if (_this._collection$_first == null)
+ _this._collection$_first = _this._collection$_last = cell;
+ else {
+ last = _this._collection$_last;
+ cell._collection$_previous = last;
+ _this._collection$_last = last._collection$_next = cell;
+ }
+ ++_this._collection$_length;
+ _this._collection$_modified$0();
+ return cell;
+ },
+ _unlinkCell$1: function(cell) {
+ var _this = this,
+ previous = cell._collection$_previous,
+ next = cell._collection$_next;
+ if (previous == null) {
+ H.assertHelper(cell == _this._collection$_first);
+ _this._collection$_first = next;
+ } else
+ previous._collection$_next = next;
+ if (next == null) {
+ H.assertHelper(cell == _this._collection$_last);
+ _this._collection$_last = previous;
+ } else
+ next._collection$_previous = previous;
+ --_this._collection$_length;
+ _this._collection$_modified$0();
+ },
+ _computeHashCode$1: function(element) {
+ return J.get$hashCode$(element) & 1073741823;
+ },
+ _findBucketIndex$2: function(bucket, element) {
+ var $length, i;
+ if (bucket == null)
+ return -1;
+ $length = bucket.length;
+ for (i = 0; i < $length; ++i)
+ if (J.$eq$(bucket[i]._element, element))
+ return i;
+ return -1;
+ },
+ $isLinkedHashSet: 1
+ };
+ P._LinkedHashSetCell.prototype = {};
+ P._LinkedHashSetIterator.prototype = {
+ get$current: function() {
+ return this._collection$_current;
+ },
+ moveNext$0: function() {
+ var _this = this,
+ t1 = _this._set;
+ if (_this._collection$_modifications !== t1._collection$_modifications)
+ throw H.wrapException(P.ConcurrentModificationError$(t1));
+ else {
+ t1 = _this._collection$_cell;
+ if (t1 == null) {
+ _this.set$_collection$_current(null);
+ return false;
+ } else {
+ _this.set$_collection$_current(_this.$ti._precomputed1._check(t1._element));
+ _this._collection$_cell = _this._collection$_cell._collection$_next;
+ return true;
+ }
+ }
+ },
+ set$_collection$_current: function(_current) {
+ this._collection$_current = this.$ti._precomputed1._check(_current);
+ },
+ $isIterator: 1
+ };
+ P.UnmodifiableListView.prototype = {
+ get$length: function(_) {
+ var t1 = this._collection$_source;
+ return t1.get$length(t1);
+ },
+ $index: function(_, index) {
+ return this._collection$_source.$index(0, H._checkIntNullable(index));
+ }
+ };
+ P.HashMap_HashMap$from_closure.prototype = {
+ call$2: function(k, v) {
+ this.result.$indexSet(0, this.K._check(k), this.V._check(v));
+ },
+ $signature: 6
+ };
+ P.IterableBase.prototype = {};
+ P.LinkedHashMap_LinkedHashMap$from_closure.prototype = {
+ call$2: function(k, v) {
+ this.result.$indexSet(0, this.K._check(k), this.V._check(v));
+ },
+ $signature: 6
+ };
+ P.ListBase.prototype = {$isEfficientLengthIterable: 1, $isIterable: 1, $isList: 1};
+ P.ListMixin.prototype = {
+ get$iterator: function(receiver) {
+ return new H.ListIterator(receiver, this.get$length(receiver), H.instanceType(receiver)._eval$1("ListIterator<ListMixin.E>"));
+ },
+ elementAt$1: function(receiver, index) {
+ return this.$index(receiver, index);
+ },
+ get$isEmpty: function(receiver) {
+ return this.get$length(receiver) === 0;
+ },
+ get$first: function(receiver) {
+ if (this.get$length(receiver) === 0)
+ throw H.wrapException(H.IterableElementError_noElement());
+ return this.$index(receiver, 0);
+ },
+ get$last: function(receiver) {
+ if (this.get$length(receiver) === 0)
+ throw H.wrapException(H.IterableElementError_noElement());
+ return this.$index(receiver, this.get$length(receiver) - 1);
+ },
+ map$1$1: function(receiver, f, $T) {
+ var t1 = H.instanceType(receiver);
+ return new H.MappedListIterable(receiver, t1._bind$1($T)._eval$1("1(ListMixin.E)")._check(f), t1._eval$1("@<ListMixin.E>")._bind$1($T)._eval$1("MappedListIterable<1,2>"));
+ },
+ toList$1$growable: function(receiver, growable) {
+ var i,
+ result = H.setRuntimeTypeInfo([], H.instanceType(receiver)._eval$1("JSArray<ListMixin.E>"));
+ C.JSArray_methods.set$length(result, this.get$length(receiver));
+ for (i = 0; i < this.get$length(receiver); ++i)
+ C.JSArray_methods.$indexSet(result, i, this.$index(receiver, i));
+ return result;
+ },
+ toList$0: function($receiver) {
+ return this.toList$1$growable($receiver, true);
+ },
+ toSet$0: function(receiver) {
+ var i,
+ result = P.LinkedHashSet_LinkedHashSet(H.instanceType(receiver)._eval$1("ListMixin.E"));
+ for (i = 0; i < this.get$length(receiver); ++i)
+ result.add$1(0, this.$index(receiver, i));
+ return result;
+ },
+ remove$1: function(receiver, element) {
+ var i;
+ for (i = 0; i < this.get$length(receiver); ++i)
+ if (J.$eq$(this.$index(receiver, i), element)) {
+ this._closeGap$2(receiver, i, i + 1);
+ return true;
+ }
+ return false;
+ },
+ _closeGap$2: function(receiver, start, end) {
+ var size, i, _this = this,
+ $length = _this.get$length(receiver);
+ H.assertHelper(start < end);
+ H.assertHelper(end <= $length);
+ size = end - start;
+ for (i = end; i < $length; ++i)
+ _this.$indexSet(receiver, i - size, _this.$index(receiver, i));
+ _this.set$length(receiver, $length - size);
+ },
+ fillRange$3: function(receiver, start, end, fill) {
+ var i;
+ H.instanceType(receiver)._eval$1("ListMixin.E")._check(fill);
+ P.RangeError_checkValidRange(start, end, this.get$length(receiver));
+ for (i = start; i < end; ++i)
+ this.$indexSet(receiver, i, fill);
+ },
+ toString$0: function(receiver) {
+ return P.IterableBase_iterableToFullString(receiver, "[", "]");
+ }
+ };
+ P.MapBase.prototype = {};
+ P.MapBase_mapToString_closure.prototype = {
+ call$2: function(k, v) {
+ var t2,
+ t1 = this._box_0;
+ if (!t1.first)
+ this.result._contents += ", ";
+ t1.first = false;
+ t1 = this.result;
+ t2 = t1._contents += H.S(k);
+ t1._contents = t2 + ": ";
+ t1._contents += H.S(v);
+ },
+ $signature: 6
+ };
+ P.MapMixin.prototype = {
+ cast$2$0: function(_, RK, RV) {
+ var t1 = H._instanceType(this);
+ return P.Map_castFrom(this, t1._eval$1("MapMixin.K"), t1._eval$1("MapMixin.V"), RK, RV);
+ },
+ forEach$1: function(_, action) {
+ var t1, key;
+ H._instanceType(this)._eval$1("~(MapMixin.K,MapMixin.V)")._check(action);
+ for (t1 = this.get$keys(), t1 = t1.get$iterator(t1); t1.moveNext$0();) {
+ key = t1.get$current();
+ action.call$2(key, this.$index(0, key));
+ }
+ },
+ map$2$1: function(_, transform, K2, V2) {
+ var result, t1, key, entry;
+ H._instanceType(this)._bind$1(K2)._bind$1(V2)._eval$1("MapEntry<1,2>(MapMixin.K,MapMixin.V)")._check(transform);
+ result = P.LinkedHashMap_LinkedHashMap$_empty(K2, V2);
+ for (t1 = this.get$keys(), t1 = t1.get$iterator(t1); t1.moveNext$0();) {
+ key = t1.get$current();
+ entry = transform.call$2(key, this.$index(0, key));
+ result.$indexSet(0, entry.key, entry.value);
+ }
+ return result;
+ },
+ containsKey$1: function(key) {
+ return this.get$keys().contains$1(0, key);
+ },
+ get$length: function(_) {
+ var t1 = this.get$keys();
+ return t1.get$length(t1);
+ },
+ get$isEmpty: function(_) {
+ var t1 = this.get$keys();
+ return t1.get$isEmpty(t1);
+ },
+ toString$0: function(_) {
+ return P.MapBase_mapToString(this);
+ },
+ $isMap: 1
+ };
+ P._UnmodifiableMapMixin.prototype = {
+ remove$1: function(_, key) {
+ throw H.wrapException(P.UnsupportedError$("Cannot modify unmodifiable map"));
+ }
+ };
+ P.MapView.prototype = {
+ cast$2$0: function(_, RK, RV) {
+ return this._map.cast$2$0(0, RK, RV);
+ },
+ $index: function(_, key) {
+ return this._map.$index(0, key);
+ },
+ containsKey$1: function(key) {
+ return this._map.containsKey$1(key);
+ },
+ forEach$1: function(_, action) {
+ this._map.forEach$1(0, H._instanceType(this)._eval$1("~(1,2)")._check(action));
+ },
+ get$isEmpty: function(_) {
+ var t1 = this._map;
+ return t1.get$isEmpty(t1);
+ },
+ get$length: function(_) {
+ var t1 = this._map;
+ return t1.get$length(t1);
+ },
+ get$keys: function() {
+ return this._map.get$keys();
+ },
+ remove$1: function(_, key) {
+ return this._map.remove$1(0, key);
+ },
+ toString$0: function(_) {
+ return this._map.toString$0(0);
+ },
+ map$2$1: function(_, transform, K2, V2) {
+ return this._map.map$2$1(0, H._instanceType(this)._bind$1(K2)._bind$1(V2)._eval$1("MapEntry<1,2>(3,4)")._check(transform), K2, V2);
+ },
+ $isMap: 1
+ };
+ P.UnmodifiableMapView.prototype = {
+ cast$2$0: function(_, RK, RV) {
+ return new P.UnmodifiableMapView(this._map.cast$2$0(0, RK, RV), RK._eval$1("@<0>")._bind$1(RV)._eval$1("UnmodifiableMapView<1,2>"));
+ }
+ };
+ P.ListQueue.prototype = {
+ get$iterator: function(_) {
+ var _this = this;
+ return new P._ListQueueIterator(_this, _this._tail, _this._modificationCount, _this._head, _this.$ti._eval$1("_ListQueueIterator<1>"));
+ },
+ get$isEmpty: function(_) {
+ return this._head === this._tail;
+ },
+ get$length: function(_) {
+ return (this._tail - this._head & this._table.length - 1) >>> 0;
+ },
+ get$first: function(_) {
+ var t2,
+ t1 = this._head;
+ if (t1 === this._tail)
+ throw H.wrapException(H.IterableElementError_noElement());
+ t2 = this._table;
+ if (t1 >= t2.length)
+ return H.ioore(t2, t1);
+ return t2[t1];
+ },
+ get$last: function(_) {
+ var t3,
+ t1 = this._head,
+ t2 = this._tail;
+ if (t1 === t2)
+ throw H.wrapException(H.IterableElementError_noElement());
+ t1 = this._table;
+ t3 = t1.length;
+ t2 = (t2 - 1 & t3 - 1) >>> 0;
+ if (t2 < 0 || t2 >= t3)
+ return H.ioore(t1, t2);
+ return t1[t2];
+ },
+ elementAt$1: function(_, index) {
+ var t1, t2, t3, _this = this,
+ $length = _this.get$length(_this);
+ if (0 > index || index >= $length)
+ H.throwExpression(P.IndexError$(index, _this, "index", null, $length));
+ t1 = _this._table;
+ t2 = t1.length;
+ t3 = (_this._head + index & t2 - 1) >>> 0;
+ if (t3 < 0 || t3 >= t2)
+ return H.ioore(t1, t3);
+ return t1[t3];
+ },
+ clear$0: function(_) {
+ var _this = this,
+ i = _this._head;
+ if (i !== _this._tail) {
+ for (; i !== _this._tail; i = (i + 1 & _this._table.length - 1) >>> 0)
+ C.JSArray_methods.$indexSet(_this._table, i, null);
+ _this._head = _this._tail = 0;
+ ++_this._modificationCount;
+ }
+ },
+ toString$0: function(_) {
+ return P.IterableBase_iterableToFullString(this, "{", "}");
+ },
+ removeFirst$0: function() {
+ var t2, result, _this = this,
+ t1 = _this._head;
+ if (t1 === _this._tail)
+ throw H.wrapException(H.IterableElementError_noElement());
+ ++_this._modificationCount;
+ t2 = _this._table;
+ if (t1 >= t2.length)
+ return H.ioore(t2, t1);
+ result = t2[t1];
+ C.JSArray_methods.$indexSet(t2, t1, null);
+ _this._head = (_this._head + 1 & _this._table.length - 1) >>> 0;
+ return result;
+ },
+ _collection$_add$1: function(element) {
+ var t2, t3, newTable, split, _this = this,
+ t1 = _this.$ti;
+ t1._precomputed1._check(element);
+ C.JSArray_methods.$indexSet(_this._table, _this._tail, element);
+ t2 = _this._tail;
+ t3 = _this._table.length;
+ t2 = (t2 + 1 & t3 - 1) >>> 0;
+ _this._tail = t2;
+ if (_this._head === t2) {
+ t2 = new Array(t3 * 2);
+ t2.fixed$length = Array;
+ newTable = H.setRuntimeTypeInfo(t2, t1._eval$1("JSArray<1>"));
+ t1 = _this._table;
+ t2 = _this._head;
+ split = t1.length - t2;
+ C.JSArray_methods.setRange$4(newTable, 0, split, t1, t2);
+ C.JSArray_methods.setRange$4(newTable, split, split + _this._head, _this._table, 0);
+ _this._head = 0;
+ _this._tail = _this._table.length;
+ _this.set$_table(newTable);
+ }
+ ++_this._modificationCount;
+ },
+ set$_table: function(_table) {
+ this._table = this.$ti._eval$1("List<1>")._check(_table);
+ },
+ $isQueue: 1
+ };
+ P._ListQueueIterator.prototype = {
+ get$current: function() {
+ return this._collection$_current;
+ },
+ moveNext$0: function() {
+ var t2, t3, _this = this,
+ t1 = _this._queue;
+ if (_this._modificationCount !== t1._modificationCount)
+ H.throwExpression(P.ConcurrentModificationError$(t1));
+ t2 = _this._position;
+ if (t2 === _this._end) {
+ _this.set$_collection$_current(null);
+ return false;
+ }
+ t3 = t1._table;
+ if (t2 >= t3.length)
+ return H.ioore(t3, t2);
+ _this.set$_collection$_current(t3[t2]);
+ _this._position = (_this._position + 1 & t1._table.length - 1) >>> 0;
+ return true;
+ },
+ set$_collection$_current: function(_current) {
+ this._collection$_current = this.$ti._precomputed1._check(_current);
+ },
+ $isIterator: 1
+ };
+ P.SetMixin.prototype = {
+ get$isEmpty: function(_) {
+ return this.get$length(this) === 0;
+ },
+ map$1$1: function(_, f, $T) {
+ var t1 = H._instanceType(this);
+ return new H.EfficientLengthMappedIterable(this, t1._bind$1($T)._eval$1("1(2)")._check(f), t1._eval$1("@<1>")._bind$1($T)._eval$1("EfficientLengthMappedIterable<1,2>"));
+ },
+ toString$0: function(_) {
+ return P.IterableBase_iterableToFullString(this, "{", "}");
+ },
+ every$1: function(_, f) {
+ var t1;
+ H._instanceType(this)._eval$1("bool(1)")._check(f);
+ for (t1 = this.get$iterator(this); t1.moveNext$0();)
+ if (!H.boolConversionCheck(f.call$1(t1.get$current())))
+ return false;
+ return true;
+ },
+ get$first: function(_) {
+ var it = this.get$iterator(this);
+ if (!it.moveNext$0())
+ throw H.wrapException(H.IterableElementError_noElement());
+ return it.get$current();
+ },
+ get$last: function(_) {
+ var result,
+ it = this.get$iterator(this);
+ if (!it.moveNext$0())
+ throw H.wrapException(H.IterableElementError_noElement());
+ do
+ result = it.get$current();
+ while (it.moveNext$0());
+ return result;
+ },
+ $isEfficientLengthIterable: 1,
+ $isIterable: 1,
+ $isSet: 1
+ };
+ P.SetBase.prototype = {$isEfficientLengthIterable: 1, $isIterable: 1, $isSet: 1};
+ P._SetBase.prototype = {
+ toSet$0: function(_) {
+ var t1 = this._newSet$0();
+ t1.addAll$1(0, this);
+ return t1;
+ },
+ get$isEmpty: function(_) {
+ return this._collection$_length === 0;
+ },
+ addAll$1: function(_, elements) {
+ var t1;
+ H._instanceType(this)._eval$1("Iterable<1>")._check(elements);
+ for (t1 = elements.get$iterator(elements); t1.moveNext$0();)
+ this.add$1(0, t1.get$current());
+ },
+ union$1: function(other) {
+ var t1;
+ H._instanceType(this)._eval$1("Set<1>")._check(other);
+ t1 = this.toSet$0(0);
+ t1.addAll$1(0, other);
+ return t1;
+ },
+ toList$1$growable: function(_, growable) {
+ var i, i0, _this = this,
+ t1 = H._instanceType(_this),
+ result = H.setRuntimeTypeInfo([], t1._eval$1("JSArray<1>"));
+ C.JSArray_methods.set$length(result, _this._collection$_length);
+ for (t1 = P._LinkedHashSetIterator$(_this, _this._collection$_modifications, t1._precomputed1), i = 0; t1.moveNext$0(); i = i0) {
+ i0 = i + 1;
+ C.JSArray_methods.$indexSet(result, i, t1._collection$_current);
+ }
+ return result;
+ },
+ toList$0: function($receiver) {
+ return this.toList$1$growable($receiver, true);
+ },
+ map$1$1: function(_, f, $T) {
+ var t1 = H._instanceType(this);
+ return new H.EfficientLengthMappedIterable(this, t1._bind$1($T)._eval$1("1(2)")._check(f), t1._eval$1("@<1>")._bind$1($T)._eval$1("EfficientLengthMappedIterable<1,2>"));
+ },
+ toString$0: function(_) {
+ return P.IterableBase_iterableToFullString(this, "{", "}");
+ },
+ where$1: function(_, f) {
+ var t1 = H._instanceType(this);
+ return new H.WhereIterable(this, t1._eval$1("bool(1)")._check(f), t1._eval$1("WhereIterable<1>"));
+ },
+ fold$1$2: function(_, initialValue, combine, $T) {
+ var t1, value;
+ $T._check(initialValue);
+ t1 = H._instanceType(this);
+ t1._bind$1($T)._eval$1("1(1,2)")._check(combine);
+ for (t1 = P._LinkedHashSetIterator$(this, this._collection$_modifications, t1._precomputed1), value = initialValue; t1.moveNext$0();)
+ value = combine.call$2(value, t1._collection$_current);
+ return value;
+ },
+ every$1: function(_, f) {
+ var t1 = H._instanceType(this);
+ t1._eval$1("bool(1)")._check(f);
+ for (t1 = P._LinkedHashSetIterator$(this, this._collection$_modifications, t1._precomputed1); t1.moveNext$0();)
+ if (!H.boolConversionCheck(f.call$1(t1._collection$_current)))
+ return false;
+ return true;
+ },
+ any$1: function(_, test) {
+ var t1 = H._instanceType(this);
+ t1._eval$1("bool(1)")._check(test);
+ for (t1 = P._LinkedHashSetIterator$(this, this._collection$_modifications, t1._precomputed1); t1.moveNext$0();)
+ if (H.boolConversionCheck(test.call$1(t1._collection$_current)))
+ return true;
+ return false;
+ },
+ get$first: function(_) {
+ var it = P._LinkedHashSetIterator$(this, this._collection$_modifications, H._instanceType(this)._precomputed1);
+ if (!it.moveNext$0())
+ throw H.wrapException(H.IterableElementError_noElement());
+ return it._collection$_current;
+ },
+ get$last: function(_) {
+ var result,
+ it = P._LinkedHashSetIterator$(this, this._collection$_modifications, H._instanceType(this)._precomputed1);
+ if (!it.moveNext$0())
+ throw H.wrapException(H.IterableElementError_noElement());
+ do
+ result = it._collection$_current;
+ while (it.moveNext$0());
+ return result;
+ },
+ $isEfficientLengthIterable: 1,
+ $isIterable: 1,
+ $isSet: 1
+ };
+ P._ListBase_Object_ListMixin.prototype = {};
+ P._SetBase_Object_SetMixin.prototype = {};
+ P._UnmodifiableMapView_MapView__UnmodifiableMapMixin.prototype = {};
+ P._JsonMap.prototype = {
+ $index: function(_, key) {
+ var result,
+ t1 = this._processed;
+ if (t1 == null)
+ return this.get$_upgradedMap().$index(0, key);
+ else if (typeof key != "string")
+ return null;
+ else {
+ result = t1[key];
+ return typeof result == "undefined" ? this._process$1(key) : result;
+ }
+ },
+ get$length: function(_) {
+ var t1;
+ if (this._processed == null) {
+ t1 = this.get$_upgradedMap();
+ t1 = t1.get$length(t1);
+ } else
+ t1 = this._convert$_computeKeys$0().length;
+ return t1;
+ },
+ get$isEmpty: function(_) {
+ return this.get$length(this) === 0;
+ },
+ get$keys: function() {
+ if (this._processed == null)
+ return this.get$_upgradedMap().get$keys();
+ return new P._JsonMapKeyIterable(this);
+ },
+ containsKey$1: function(key) {
+ if (this._processed == null)
+ return this.get$_upgradedMap().containsKey$1(key);
+ if (typeof key != "string")
+ return false;
+ return Object.prototype.hasOwnProperty.call(this._original, key);
+ },
+ remove$1: function(_, key) {
+ if (this._processed != null && !this.containsKey$1(key))
+ return null;
+ return this._upgrade$0().remove$1(0, key);
+ },
+ forEach$1: function(_, f) {
+ var keys, i, key, value, _this = this;
+ type$.void_Function_String_dynamic._check(f);
+ if (_this._processed == null)
+ return _this.get$_upgradedMap().forEach$1(0, f);
+ keys = _this._convert$_computeKeys$0();
+ for (i = 0; i < keys.length; ++i) {
+ key = keys[i];
+ value = _this._processed[key];
+ if (typeof value == "undefined") {
+ value = P._convertJsonToDartLazy(_this._original[key]);
+ _this._processed[key] = value;
+ }
+ f.call$2(key, value);
+ if (keys !== _this._data)
+ throw H.wrapException(P.ConcurrentModificationError$(_this));
+ }
+ },
+ get$_upgradedMap: function() {
+ H.assertHelper(this._processed == null);
+ return this._data;
+ },
+ _convert$_computeKeys$0: function() {
+ var keys, _this = this;
+ H.assertHelper(_this._processed != null);
+ keys = type$.List_dynamic._check(_this._data);
+ if (keys == null)
+ keys = _this._data = H.setRuntimeTypeInfo(Object.keys(_this._original), type$.JSArray_String);
+ return keys;
+ },
+ _upgrade$0: function() {
+ var result, keys, i, t1, key, _this = this;
+ if (_this._processed == null)
+ return _this.get$_upgradedMap();
+ result = P.LinkedHashMap_LinkedHashMap$_empty(type$.String, type$.dynamic);
+ keys = _this._convert$_computeKeys$0();
+ for (i = 0; t1 = keys.length, i < t1; ++i) {
+ key = keys[i];
+ result.$indexSet(0, key, _this.$index(0, key));
+ }
+ if (t1 === 0)
+ C.JSArray_methods.add$1(keys, null);
+ else
+ C.JSArray_methods.set$length(keys, 0);
+ _this._original = _this._processed = null;
+ return _this._data = result;
+ },
+ _process$1: function(key) {
+ var result;
+ if (!Object.prototype.hasOwnProperty.call(this._original, key))
+ return null;
+ result = P._convertJsonToDartLazy(this._original[key]);
+ return this._processed[key] = result;
+ }
+ };
+ P._JsonMapKeyIterable.prototype = {
+ get$length: function(_) {
+ var t1 = this._parent;
+ return t1.get$length(t1);
+ },
+ elementAt$1: function(_, index) {
+ var t1 = this._parent;
+ if (t1._processed == null)
+ t1 = t1.get$keys().elementAt$1(0, index);
+ else {
+ t1 = t1._convert$_computeKeys$0();
+ if (index < 0 || index >= t1.length)
+ return H.ioore(t1, index);
+ t1 = t1[index];
+ }
+ return t1;
+ },
+ get$iterator: function(_) {
+ var t1 = this._parent;
+ if (t1._processed == null) {
+ t1 = t1.get$keys();
+ t1 = t1.get$iterator(t1);
+ } else {
+ t1 = t1._convert$_computeKeys$0();
+ t1 = new J.ArrayIterator(t1, t1.length, H._arrayInstanceType(t1)._eval$1("ArrayIterator<1>"));
+ }
+ return t1;
+ },
+ contains$1: function(_, key) {
+ return this._parent.containsKey$1(key);
+ }
+ };
+ P.AsciiCodec.prototype = {
+ encode$1: function(source) {
+ return C.AsciiEncoder_127.convert$1(source);
+ }
+ };
+ P._UnicodeSubsetEncoder.prototype = {
+ convert$1: function(string) {
+ var $length, result, t1, t2, t3, i, codeUnit;
+ H._checkStringNullable(string);
+ $length = P.RangeError_checkValidRange(0, null, string.length) - 0;
+ result = new Uint8Array($length);
+ for (t1 = result.length, t2 = ~this._subsetMask, t3 = J.getInterceptor$s(string), i = 0; i < $length; ++i) {
+ codeUnit = t3._codeUnitAt$1(string, i);
+ if ((codeUnit & t2) !== 0)
+ throw H.wrapException(P.ArgumentError$value(string, "string", "Contains invalid characters."));
+ if (i >= t1)
+ return H.ioore(result, i);
+ result[i] = codeUnit;
+ }
+ return result;
+ }
+ };
+ P.AsciiEncoder.prototype = {};
+ P.Base64Codec.prototype = {
+ normalize$3: function(source, start, end) {
+ var inverseAlphabet, i, sliceStart, buffer, firstPadding, firstPaddingSourceIndex, paddingCount, i0, char, i1, digit1, digit2, char0, value, t2, endLength, $length,
+ _s31_ = "Invalid base64 encoding length ",
+ t1 = source.length;
+ end = P.RangeError_checkValidRange(start, end, t1);
+ inverseAlphabet = $.$get$_Base64Decoder__inverseAlphabet();
+ for (i = start, sliceStart = i, buffer = null, firstPadding = -1, firstPaddingSourceIndex = -1, paddingCount = 0; i < end; i = i0) {
+ i0 = i + 1;
+ char = C.JSString_methods._codeUnitAt$1(source, i);
+ if (char === 37) {
+ i1 = i0 + 2;
+ if (i1 <= end) {
+ H.assertHelper(i1 <= t1);
+ digit1 = H.hexDigitValue(C.JSString_methods._codeUnitAt$1(source, i0));
+ digit2 = H.hexDigitValue(C.JSString_methods._codeUnitAt$1(source, i0 + 1));
+ char0 = digit1 * 16 + digit2 - (digit2 & 256);
+ if (char0 === 37)
+ char0 = -1;
+ i0 = i1;
+ } else
+ char0 = -1;
+ } else
+ char0 = char;
+ if (0 <= char0 && char0 <= 127) {
+ if (char0 < 0 || char0 >= inverseAlphabet.length)
+ return H.ioore(inverseAlphabet, char0);
+ value = inverseAlphabet[char0];
+ if (value >= 0) {
+ char0 = C.JSString_methods.codeUnitAt$1("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", value);
+ if (char0 === char)
+ continue;
+ char = char0;
+ } else {
+ if (value === -1) {
+ if (firstPadding < 0) {
+ t2 = buffer == null ? null : buffer._contents.length;
+ if (t2 == null)
+ t2 = 0;
+ firstPadding = t2 + (i - sliceStart);
+ firstPaddingSourceIndex = i;
+ }
+ ++paddingCount;
+ if (char === 61)
+ continue;
+ }
+ char = char0;
+ }
+ if (value !== -2) {
+ if (buffer == null)
+ buffer = new P.StringBuffer("");
+ t2 = buffer._contents += C.JSString_methods.substring$2(source, sliceStart, i);
+ buffer._contents = t2 + H.Primitives_stringFromCharCode(char);
+ sliceStart = i0;
+ continue;
+ }
+ }
+ throw H.wrapException(P.FormatException$("Invalid base64 data", source, i));
+ }
+ if (buffer != null) {
+ t1 = buffer._contents += C.JSString_methods.substring$2(source, sliceStart, end);
+ t2 = t1.length;
+ if (firstPadding >= 0)
+ P.Base64Codec__checkPadding(source, firstPaddingSourceIndex, end, firstPadding, paddingCount, t2);
+ else {
+ endLength = C.JSInt_methods.$mod(t2 - 1, 4) + 1;
+ if (endLength === 1)
+ throw H.wrapException(P.FormatException$(_s31_, source, end));
+ for (; endLength < 4;) {
+ t1 += "=";
+ buffer._contents = t1;
+ ++endLength;
+ }
+ }
+ t1 = buffer._contents;
+ return C.JSString_methods.replaceRange$3(source, start, end, t1.charCodeAt(0) == 0 ? t1 : t1);
+ }
+ $length = end - start;
+ if (firstPadding >= 0)
+ P.Base64Codec__checkPadding(source, firstPaddingSourceIndex, end, firstPadding, paddingCount, $length);
+ else {
+ endLength = C.JSInt_methods.$mod($length, 4);
+ if (endLength === 1)
+ throw H.wrapException(P.FormatException$(_s31_, source, end));
+ if (endLength > 1)
+ source = C.JSString_methods.replaceRange$3(source, end, end, endLength === 2 ? "==" : "=");
+ }
+ return source;
+ }
+ };
+ P.Base64Encoder.prototype = {};
+ P.Codec.prototype = {};
+ P._FusedCodec.prototype = {};
+ P.Converter.prototype = {};
+ P.Encoding.prototype = {};
+ P.JsonCodec.prototype = {
+ decode$2$reviver: function(source, reviver) {
+ var t1;
+ type$.dynamic_Function_Object_Object._check(reviver);
+ t1 = P._parseJson(source, this.get$decoder()._reviver);
+ return t1;
+ },
+ get$decoder: function() {
+ return C.JsonDecoder_null;
+ }
+ };
+ P.JsonDecoder.prototype = {};
+ P.Utf8Codec.prototype = {
+ get$encoder: function() {
+ return C.C_Utf8Encoder;
+ }
+ };
+ P.Utf8Encoder.prototype = {
+ convert$1: function(string) {
+ var end, $length, t1, encoder, endPosition, t2, lastCodeUnit;
+ H._checkStringNullable(string);
+ end = P.RangeError_checkValidRange(0, null, string.length);
+ $length = end - 0;
+ if ($length === 0)
+ return new Uint8Array(0);
+ t1 = new Uint8Array($length * 3);
+ encoder = new P._Utf8Encoder(t1);
+ endPosition = encoder._fillBuffer$3(string, 0, end);
+ t2 = end - 1;
+ H.assertHelper(endPosition >= t2);
+ if (endPosition !== end) {
+ lastCodeUnit = J.codeUnitAt$1$s(string, t2);
+ H.assertHelper((lastCodeUnit & 64512) === 55296);
+ H.assertHelper(!encoder._writeSurrogate$2(lastCodeUnit, 0));
+ }
+ return C.NativeUint8List_methods.sublist$2(t1, 0, encoder._bufferIndex);
+ }
+ };
+ P._Utf8Encoder.prototype = {
+ _writeSurrogate$2: function(leadingSurrogate, nextCodeUnit) {
+ var rune, t3, t4, _this = this,
+ t1 = _this._buffer,
+ t2 = t1.length;
+ if ((nextCodeUnit & 64512) === 56320) {
+ rune = 65536 + ((leadingSurrogate & 1023) << 10) | nextCodeUnit & 1023;
+ H.assertHelper(rune > 65535);
+ H.assertHelper(rune <= 1114111);
+ t3 = _this._bufferIndex;
+ t4 = _this._bufferIndex = t3 + 1;
+ if (t3 >= t2)
+ return H.ioore(t1, t3);
+ t1[t3] = 240 | rune >>> 18;
+ t3 = _this._bufferIndex = t4 + 1;
+ if (t4 >= t2)
+ return H.ioore(t1, t4);
+ t1[t4] = 128 | rune >>> 12 & 63;
+ t4 = _this._bufferIndex = t3 + 1;
+ if (t3 >= t2)
+ return H.ioore(t1, t3);
+ t1[t3] = 128 | rune >>> 6 & 63;
+ _this._bufferIndex = t4 + 1;
+ if (t4 >= t2)
+ return H.ioore(t1, t4);
+ t1[t4] = 128 | rune & 63;
+ return true;
+ } else {
+ t3 = _this._bufferIndex;
+ t4 = _this._bufferIndex = t3 + 1;
+ if (t3 >= t2)
+ return H.ioore(t1, t3);
+ t1[t3] = 224 | leadingSurrogate >>> 12;
+ t3 = _this._bufferIndex = t4 + 1;
+ if (t4 >= t2)
+ return H.ioore(t1, t4);
+ t1[t4] = 128 | leadingSurrogate >>> 6 & 63;
+ _this._bufferIndex = t3 + 1;
+ if (t3 >= t2)
+ return H.ioore(t1, t3);
+ t1[t3] = 128 | leadingSurrogate & 63;
+ return false;
+ }
+ },
+ _fillBuffer$3: function(str, start, end) {
+ var t1, t2, t3, stringIndex, codeUnit, t4, stringIndex0, t5, _this = this;
+ if (start !== end && (J.codeUnitAt$1$s(str, end - 1) & 64512) === 55296)
+ --end;
+ for (t1 = _this._buffer, t2 = t1.length, t3 = J.getInterceptor$s(str), stringIndex = start; stringIndex < end; ++stringIndex) {
+ codeUnit = t3._codeUnitAt$1(str, stringIndex);
+ if (codeUnit <= 127) {
+ t4 = _this._bufferIndex;
+ if (t4 >= t2)
+ break;
+ _this._bufferIndex = t4 + 1;
+ t1[t4] = codeUnit;
+ } else if ((codeUnit & 64512) === 55296) {
+ if (_this._bufferIndex + 3 >= t2)
+ break;
+ stringIndex0 = stringIndex + 1;
+ if (_this._writeSurrogate$2(codeUnit, C.JSString_methods._codeUnitAt$1(str, stringIndex0)))
+ stringIndex = stringIndex0;
+ } else if (codeUnit <= 2047) {
+ t4 = _this._bufferIndex;
+ t5 = t4 + 1;
+ if (t5 >= t2)
+ break;
+ _this._bufferIndex = t5;
+ if (t4 >= t2)
+ return H.ioore(t1, t4);
+ t1[t4] = 192 | codeUnit >>> 6;
+ _this._bufferIndex = t5 + 1;
+ t1[t5] = 128 | codeUnit & 63;
+ } else {
+ H.assertHelper(codeUnit <= 65535);
+ t4 = _this._bufferIndex;
+ if (t4 + 2 >= t2)
+ break;
+ t5 = _this._bufferIndex = t4 + 1;
+ if (t4 >= t2)
+ return H.ioore(t1, t4);
+ t1[t4] = 224 | codeUnit >>> 12;
+ t4 = _this._bufferIndex = t5 + 1;
+ if (t5 >= t2)
+ return H.ioore(t1, t5);
+ t1[t5] = 128 | codeUnit >>> 6 & 63;
+ _this._bufferIndex = t4 + 1;
+ if (t4 >= t2)
+ return H.ioore(t1, t4);
+ t1[t4] = 128 | codeUnit & 63;
+ }
+ }
+ return stringIndex;
+ }
+ };
+ P.Utf8Decoder.prototype = {
+ convert$1: function(codeUnits) {
+ var result, end, oneBytes, firstPart, buffer, start, isFirstCharacter, decoder, t1;
+ type$.List_int._check(codeUnits);
+ result = P.Utf8Decoder__convertIntercepted(false, codeUnits, 0, null);
+ if (result != null)
+ return result;
+ end = P.RangeError_checkValidRange(0, null, J.get$length$asx(codeUnits));
+ oneBytes = P._scanOneByteCharacters(codeUnits, 0, end);
+ if (oneBytes > 0) {
+ firstPart = P.String_String$fromCharCodes(codeUnits, 0, oneBytes);
+ if (oneBytes === end)
+ return firstPart;
+ buffer = new P.StringBuffer(firstPart);
+ start = oneBytes;
+ isFirstCharacter = false;
+ } else {
+ start = 0;
+ buffer = null;
+ isFirstCharacter = true;
+ }
+ if (buffer == null)
+ buffer = new P.StringBuffer("");
+ decoder = new P._Utf8Decoder(false, buffer);
+ decoder._isFirstCharacter = isFirstCharacter;
+ decoder.convert$3(codeUnits, start, end);
+ decoder.flush$2(codeUnits, end);
+ t1 = buffer._contents;
+ return t1.charCodeAt(0) == 0 ? t1 : t1;
+ }
+ };
+ P._Utf8Decoder.prototype = {
+ flush$2: function(source, offset) {
+ var t1;
+ type$.List_int._check(source);
+ if (this._expectedUnits > 0) {
+ t1 = P.FormatException$("Unfinished UTF-8 octet sequence", source, offset);
+ throw H.wrapException(t1);
+ }
+ },
+ convert$3: function(codeUnits, startIndex, endIndex) {
+ var value, expectedUnits, extraUnits, t1, t2, i, unit, t3, oneBytes, i0, i1, t4, _this = this,
+ _s21_ = "Bad UTF-8 encoding 0x";
+ type$.List_int._check(codeUnits);
+ value = _this._convert$_value;
+ expectedUnits = _this._expectedUnits;
+ extraUnits = _this._extraUnits;
+ _this._extraUnits = _this._expectedUnits = _this._convert$_value = 0;
+ $label0$0:
+ for (t1 = J.getInterceptor$asx(codeUnits), t2 = _this._stringSink, i = startIndex; true; i = i1) {
+ $label1$1:
+ if (expectedUnits > 0) {
+ do {
+ if (i === endIndex)
+ break $label0$0;
+ unit = t1.$index(codeUnits, i);
+ if (typeof unit !== "number")
+ return unit.$and();
+ if ((unit & 192) !== 128) {
+ t3 = P.FormatException$(_s21_ + C.JSInt_methods.toRadixString$1(unit, 16), codeUnits, i);
+ throw H.wrapException(t3);
+ } else {
+ value = (value << 6 | unit & 63) >>> 0;
+ --expectedUnits;
+ ++i;
+ }
+ } while (expectedUnits > 0);
+ t3 = extraUnits - 1;
+ if (t3 < 0 || t3 >= 4)
+ return H.ioore(C.List_127_2047_65535_1114111, t3);
+ if (value <= C.List_127_2047_65535_1114111[t3]) {
+ t3 = P.FormatException$("Overlong encoding of 0x" + C.JSInt_methods.toRadixString$1(value, 16), codeUnits, i - extraUnits - 1);
+ throw H.wrapException(t3);
+ }
+ if (value > 1114111) {
+ t3 = P.FormatException$("Character outside valid Unicode range: 0x" + C.JSInt_methods.toRadixString$1(value, 16), codeUnits, i - extraUnits - 1);
+ throw H.wrapException(t3);
+ }
+ if (!_this._isFirstCharacter || value !== 65279)
+ t2._contents += H.Primitives_stringFromCharCode(value);
+ _this._isFirstCharacter = false;
+ }
+ for (t3 = i < endIndex; t3;) {
+ oneBytes = P._scanOneByteCharacters(codeUnits, i, endIndex);
+ if (oneBytes > 0) {
+ _this._isFirstCharacter = false;
+ i0 = i + oneBytes;
+ H.assertHelper(i0 <= endIndex);
+ t2._contents += P.String_String$fromCharCodes(codeUnits, i, i0);
+ if (i0 === endIndex)
+ break;
+ } else
+ i0 = i;
+ i1 = i0 + 1;
+ unit = t1.$index(codeUnits, i0);
+ if (typeof unit !== "number")
+ return unit.$lt();
+ if (unit < 0) {
+ t4 = P.FormatException$("Negative UTF-8 code unit: -0x" + C.JSInt_methods.toRadixString$1(-unit, 16), codeUnits, i1 - 1);
+ throw H.wrapException(t4);
+ } else {
+ H.assertHelper(unit > 127);
+ if ((unit & 224) === 192) {
+ value = unit & 31;
+ expectedUnits = 1;
+ extraUnits = 1;
+ continue $label0$0;
+ }
+ if ((unit & 240) === 224) {
+ value = unit & 15;
+ expectedUnits = 2;
+ extraUnits = 2;
+ continue $label0$0;
+ }
+ if ((unit & 248) === 240 && unit < 245) {
+ value = unit & 7;
+ expectedUnits = 3;
+ extraUnits = 3;
+ continue $label0$0;
+ }
+ t4 = P.FormatException$(_s21_ + C.JSInt_methods.toRadixString$1(unit, 16), codeUnits, i1 - 1);
+ throw H.wrapException(t4);
+ }
+ }
+ break $label0$0;
+ }
+ if (expectedUnits > 0) {
+ _this._convert$_value = value;
+ _this._expectedUnits = expectedUnits;
+ _this._extraUnits = extraUnits;
+ }
+ }
+ };
+ P.bool.prototype = {};
+ P.DateTime.prototype = {
+ $eq: function(_, other) {
+ if (other == null)
+ return false;
+ return other instanceof P.DateTime && this._value === other._value && true;
+ },
+ get$hashCode: function(_) {
+ var t1 = this._value;
+ return (t1 ^ C.JSInt_methods._shrOtherPositive$1(t1, 30)) & 1073741823;
+ },
+ toString$0: function(_) {
+ var _this = this,
+ y = P.DateTime__fourDigits(H.Primitives_getYear(_this)),
+ m = P.DateTime__twoDigits(H.Primitives_getMonth(_this)),
+ d = P.DateTime__twoDigits(H.Primitives_getDay(_this)),
+ h = P.DateTime__twoDigits(H.Primitives_getHours(_this)),
+ min = P.DateTime__twoDigits(H.Primitives_getMinutes(_this)),
+ sec = P.DateTime__twoDigits(H.Primitives_getSeconds(_this)),
+ ms = P.DateTime__threeDigits(H.Primitives_getMilliseconds(_this)),
+ t1 = y + "-" + m + "-" + d + " " + h + ":" + min + ":" + sec + "." + ms + "Z";
+ return t1;
+ }
+ };
+ P.double.prototype = {};
+ P.Duration.prototype = {
+ $eq: function(_, other) {
+ if (other == null)
+ return false;
+ return other instanceof P.Duration && this._duration === other._duration;
+ },
+ get$hashCode: function(_) {
+ return C.JSInt_methods.get$hashCode(this._duration);
+ },
+ toString$0: function(_) {
+ var twoDigitMinutes, twoDigitSeconds, sixDigitUs,
+ t1 = new P.Duration_toString_twoDigits(),
+ t2 = this._duration;
+ if (t2 < 0)
+ return "-" + new P.Duration(0 - t2).toString$0(0);
+ twoDigitMinutes = t1.call$1(C.JSInt_methods._tdivFast$1(t2, 60000000) % 60);
+ twoDigitSeconds = t1.call$1(C.JSInt_methods._tdivFast$1(t2, 1000000) % 60);
+ sixDigitUs = new P.Duration_toString_sixDigits().call$1(t2 % 1000000);
+ return "" + C.JSInt_methods._tdivFast$1(t2, 3600000000) + ":" + H.S(twoDigitMinutes) + ":" + H.S(twoDigitSeconds) + "." + H.S(sixDigitUs);
+ }
+ };
+ P.Duration_toString_sixDigits.prototype = {
+ call$1: function(n) {
+ if (n >= 100000)
+ return "" + n;
+ if (n >= 10000)
+ return "0" + n;
+ if (n >= 1000)
+ return "00" + n;
+ if (n >= 100)
+ return "000" + n;
+ if (n >= 10)
+ return "0000" + n;
+ return "00000" + n;
+ },
+ $signature: 25
+ };
+ P.Duration_toString_twoDigits.prototype = {
+ call$1: function(n) {
+ if (n >= 10)
+ return "" + n;
+ return "0" + n;
+ },
+ $signature: 25
+ };
+ P.Error.prototype = {};
+ P.AssertionError.prototype = {
+ toString$0: function(_) {
+ var t1 = this.message;
+ if (t1 != null)
+ return "Assertion failed: " + P.Error_safeToString(t1);
+ return "Assertion failed";
+ },
+ get$message: function(receiver) {
+ return this.message;
+ }
+ };
+ P.NullThrownError.prototype = {
+ toString$0: function(_) {
+ return "Throw of null.";
+ }
+ };
+ P.ArgumentError.prototype = {
+ get$_errorName: function() {
+ return "Invalid argument" + (!this._hasValue ? "(s)" : "");
+ },
+ get$_errorExplanation: function() {
+ return "";
+ },
+ toString$0: function(_) {
+ var message, prefix, explanation, errorValue, _this = this,
+ t1 = _this.name,
+ nameString = t1 != null ? " (" + t1 + ")" : "";
+ t1 = _this.message;
+ message = t1 == null ? "" : ": " + H.S(t1);
+ prefix = _this.get$_errorName() + nameString + message;
+ if (!_this._hasValue)
+ return prefix;
+ explanation = _this.get$_errorExplanation();
+ errorValue = P.Error_safeToString(_this.invalidValue);
+ return prefix + explanation + ": " + errorValue;
+ },
+ get$message: function(receiver) {
+ return this.message;
+ }
+ };
+ P.RangeError.prototype = {
+ get$_errorName: function() {
+ return "RangeError";
+ },
+ get$_errorExplanation: function() {
+ var t1, explanation, t2, _this = this;
+ H.assertHelper(_this._hasValue);
+ t1 = _this.start;
+ if (t1 == null) {
+ t1 = _this.end;
+ explanation = t1 != null ? ": Not less than or equal to " + H.S(t1) : "";
+ } else {
+ t2 = _this.end;
+ if (t2 == null)
+ explanation = ": Not greater than or equal to " + H.S(t1);
+ else if (t2 > t1)
+ explanation = ": Not in range " + H.S(t1) + ".." + H.S(t2) + ", inclusive";
+ else
+ explanation = t2 < t1 ? ": Valid value range is empty" : ": Only valid value is " + H.S(t1);
+ }
+ return explanation;
+ }
+ };
+ P.IndexError.prototype = {
+ get$_errorName: function() {
+ return "RangeError";
+ },
+ get$_errorExplanation: function() {
+ var invalidValue, t1;
+ H.assertHelper(this._hasValue);
+ invalidValue = H._checkIntNullable(this.invalidValue);
+ if (typeof invalidValue !== "number")
+ return invalidValue.$lt();
+ if (invalidValue < 0)
+ return ": index must not be negative";
+ t1 = this.length;
+ if (t1 === 0)
+ return ": no indices are valid";
+ return ": index should be less than " + H.S(t1);
+ },
+ get$length: function(receiver) {
+ return this.length;
+ }
+ };
+ P.UnsupportedError.prototype = {
+ toString$0: function(_) {
+ return "Unsupported operation: " + this.message;
+ },
+ get$message: function(receiver) {
+ return this.message;
+ }
+ };
+ P.UnimplementedError.prototype = {
+ toString$0: function(_) {
+ var t1 = this.message;
+ return t1 != null ? "UnimplementedError: " + t1 : "UnimplementedError";
+ },
+ get$message: function(receiver) {
+ return this.message;
+ }
+ };
+ P.StateError.prototype = {
+ toString$0: function(_) {
+ return "Bad state: " + this.message;
+ },
+ get$message: function(receiver) {
+ return this.message;
+ }
+ };
+ P.ConcurrentModificationError.prototype = {
+ toString$0: function(_) {
+ var t1 = this.modifiedObject;
+ if (t1 == null)
+ return "Concurrent modification during iteration.";
+ return "Concurrent modification during iteration: " + P.Error_safeToString(t1) + ".";
+ }
+ };
+ P.OutOfMemoryError.prototype = {
+ toString$0: function(_) {
+ return "Out of Memory";
+ },
+ $isError: 1
+ };
+ P.StackOverflowError.prototype = {
+ toString$0: function(_) {
+ return "Stack Overflow";
+ },
+ $isError: 1
+ };
+ P.CyclicInitializationError.prototype = {
+ toString$0: function(_) {
+ var t1 = this.variableName;
+ return t1 == null ? "Reading static variable during its initialization" : "Reading static variable '" + t1 + "' during its initialization";
+ }
+ };
+ P._Exception.prototype = {
+ toString$0: function(_) {
+ return "Exception: " + this.message;
+ },
+ $isException: 1,
+ get$message: function(receiver) {
+ return this.message;
+ }
+ };
+ P.FormatException.prototype = {
+ toString$0: function(_) {
+ var source, lineNum, lineStart, previousCharWasCR, i, char, lineEnd, end, start, prefix, postfix, slice,
+ t1 = this.message,
+ report = t1 != null && "" !== t1 ? "FormatException: " + H.S(t1) : "FormatException",
+ offset = this.offset,
+ objectSource = this.source;
+ if (typeof objectSource == "string") {
+ if (offset != null)
+ t1 = offset < 0 || offset > objectSource.length;
+ else
+ t1 = false;
+ if (t1)
+ offset = null;
+ if (offset == null) {
+ source = objectSource.length > 78 ? C.JSString_methods.substring$2(objectSource, 0, 75) + "..." : objectSource;
+ return report + "\n" + source;
+ }
+ for (lineNum = 1, lineStart = 0, previousCharWasCR = false, i = 0; i < offset; ++i) {
+ char = C.JSString_methods._codeUnitAt$1(objectSource, i);
+ if (char === 10) {
+ if (lineStart !== i || !previousCharWasCR)
+ ++lineNum;
+ lineStart = i + 1;
+ previousCharWasCR = false;
+ } else if (char === 13) {
+ ++lineNum;
+ lineStart = i + 1;
+ previousCharWasCR = true;
+ }
+ }
+ report = lineNum > 1 ? report + (" (at line " + lineNum + ", character " + (offset - lineStart + 1) + ")\n") : report + (" (at character " + (offset + 1) + ")\n");
+ lineEnd = objectSource.length;
+ for (i = offset; i < lineEnd; ++i) {
+ char = C.JSString_methods.codeUnitAt$1(objectSource, i);
+ if (char === 10 || char === 13) {
+ lineEnd = i;
+ break;
+ }
+ }
+ if (lineEnd - lineStart > 78)
+ if (offset - lineStart < 75) {
+ end = lineStart + 75;
+ start = lineStart;
+ prefix = "";
+ postfix = "...";
+ } else {
+ if (lineEnd - offset < 75) {
+ start = lineEnd - 75;
+ end = lineEnd;
+ postfix = "";
+ } else {
+ start = offset - 36;
+ end = offset + 36;
+ postfix = "...";
+ }
+ prefix = "...";
+ }
+ else {
+ end = lineEnd;
+ start = lineStart;
+ prefix = "";
+ postfix = "";
+ }
+ slice = C.JSString_methods.substring$2(objectSource, start, end);
+ return report + prefix + slice + postfix + "\n" + C.JSString_methods.$mul(" ", offset - start + prefix.length) + "^\n";
+ } else
+ return offset != null ? report + (" (at offset " + H.S(offset) + ")") : report;
+ },
+ $isException: 1,
+ get$message: function(receiver) {
+ return this.message;
+ }
+ };
+ P.Expando.prototype = {
+ $index: function(_, object) {
+ var t2, values,
+ t1 = this._jsWeakMapOrKey;
+ if (typeof t1 != "string") {
+ if (object != null)
+ t2 = typeof object == "number" || typeof object == "string";
+ else
+ t2 = true;
+ if (t2)
+ H.throwExpression(P.ArgumentError$value(object, "Expandos are not allowed on strings, numbers, booleans or null", null));
+ return t1.get(object);
+ }
+ values = H.Primitives_getProperty(object, "expando$values");
+ t1 = values == null ? null : H.Primitives_getProperty(values, t1);
+ return this.$ti._precomputed1._check(t1);
+ },
+ $indexSet: function(_, object, value) {
+ var t1, values,
+ _s14_ = "expando$values";
+ this.$ti._precomputed1._check(value);
+ t1 = this._jsWeakMapOrKey;
+ if (typeof t1 != "string")
+ t1.set(object, value);
+ else {
+ values = H.Primitives_getProperty(object, _s14_);
+ if (values == null) {
+ values = new P.Object();
+ H.Primitives_setProperty(object, _s14_, values);
+ }
+ H.Primitives_setProperty(values, t1, value);
+ }
+ },
+ toString$0: function(_) {
+ return "Expando:" + this.name;
+ }
+ };
+ P.Function.prototype = {};
+ P.int.prototype = {};
+ P.Iterable.prototype = {
+ map$1$1: function(_, f, $T) {
+ var t1 = H._instanceType(this);
+ return H.MappedIterable_MappedIterable(this, t1._bind$1($T)._eval$1("1(Iterable.E)")._check(f), t1._eval$1("Iterable.E"), $T);
+ },
+ where$1: function(_, test) {
+ var t1 = H._instanceType(this);
+ return new H.WhereIterable(this, t1._eval$1("bool(Iterable.E)")._check(test), t1._eval$1("WhereIterable<Iterable.E>"));
+ },
+ contains$1: function(_, element) {
+ var t1;
+ for (t1 = this.get$iterator(this); t1.moveNext$0();)
+ if (J.$eq$(t1.get$current(), element))
+ return true;
+ return false;
+ },
+ join$1: function(_, separator) {
+ var t1,
+ iterator = this.get$iterator(this);
+ if (!iterator.moveNext$0())
+ return "";
+ if (separator === "") {
+ t1 = "";
+ do
+ t1 += H.S(iterator.get$current());
+ while (iterator.moveNext$0());
+ } else {
+ t1 = H.S(iterator.get$current());
+ for (; iterator.moveNext$0();)
+ t1 = t1 + separator + H.S(iterator.get$current());
+ }
+ return t1.charCodeAt(0) == 0 ? t1 : t1;
+ },
+ join$0: function($receiver) {
+ return this.join$1($receiver, "");
+ },
+ toList$1$growable: function(_, growable) {
+ return P.List_List$from(this, true, H._instanceType(this)._eval$1("Iterable.E"));
+ },
+ toList$0: function($receiver) {
+ return this.toList$1$growable($receiver, true);
+ },
+ toSet$0: function(_) {
+ return P.LinkedHashSet_LinkedHashSet$from(this, H._instanceType(this)._eval$1("Iterable.E"));
+ },
+ get$length: function(_) {
+ var it, count;
+ H.assertHelper(!type$.EfficientLengthIterable_dynamic._is(this));
+ it = this.get$iterator(this);
+ for (count = 0; it.moveNext$0();)
+ ++count;
+ return count;
+ },
+ get$isEmpty: function(_) {
+ return !this.get$iterator(this).moveNext$0();
+ },
+ skipWhile$1: function(_, test) {
+ var t1 = H._instanceType(this);
+ return new H.SkipWhileIterable(this, t1._eval$1("bool(Iterable.E)")._check(test), t1._eval$1("SkipWhileIterable<Iterable.E>"));
+ },
+ get$first: function(_) {
+ var it = this.get$iterator(this);
+ if (!it.moveNext$0())
+ throw H.wrapException(H.IterableElementError_noElement());
+ return it.get$current();
+ },
+ get$last: function(_) {
+ var result,
+ it = this.get$iterator(this);
+ if (!it.moveNext$0())
+ throw H.wrapException(H.IterableElementError_noElement());
+ do
+ result = it.get$current();
+ while (it.moveNext$0());
+ return result;
+ },
+ elementAt$1: function(_, index) {
+ var t1, elementIndex, element;
+ P.RangeError_checkNotNegative(index, "index");
+ for (t1 = this.get$iterator(this), elementIndex = 0; t1.moveNext$0();) {
+ element = t1.get$current();
+ if (index === elementIndex)
+ return element;
+ ++elementIndex;
+ }
+ throw H.wrapException(P.IndexError$(index, this, "index", null, elementIndex));
+ },
+ toString$0: function(_) {
+ return P.IterableBase_iterableToShortString(this, "(", ")");
+ }
+ };
+ P.Iterator.prototype = {};
+ P.List.prototype = {$isEfficientLengthIterable: 1, $isIterable: 1};
+ P.Map.prototype = {};
+ P.MapEntry.prototype = {
+ toString$0: function(_) {
+ return "MapEntry(" + H.S(this.key) + ": " + H.S(this.value) + ")";
+ }
+ };
+ P.Null.prototype = {
+ get$hashCode: function(_) {
+ return P.Object.prototype.get$hashCode.call(this, this);
+ },
+ toString$0: function(_) {
+ return "null";
+ }
+ };
+ P.num.prototype = {};
+ P.Object.prototype = {constructor: P.Object, $isObject: 1,
+ $eq: function(_, other) {
+ return this === other;
+ },
+ get$hashCode: function(_) {
+ return H.Primitives_objectHashCode(this);
+ },
+ toString$0: function(_) {
+ return "Instance of '" + H.S(H.Primitives_objectTypeName(this)) + "'";
+ },
+ get$runtimeType: function(_) {
+ return H.getRuntimeType(this);
+ },
+ toString: function() {
+ return this.toString$0(this);
+ }
+ };
+ P.Pattern.prototype = {};
+ P.Match.prototype = {};
+ P.RegExpMatch.prototype = {$isMatch: 1};
+ P.Set.prototype = {};
+ P.StackTrace.prototype = {};
+ P._StringStackTrace.prototype = {
+ toString$0: function(_) {
+ return this._stackTrace;
+ },
+ $isStackTrace: 1
+ };
+ P.Stopwatch.prototype = {
+ get$elapsedMicroseconds: function() {
+ var t2, ticks,
+ t1 = this._stop;
+ if (t1 == null)
+ t1 = H._checkIntNullable($.Primitives_timerTicks.call$0());
+ t2 = this._core$_start;
+ if (typeof t1 !== "number")
+ return t1.$sub();
+ ticks = t1 - t2;
+ t1 = $.Stopwatch__frequency;
+ if (t1 === 1000000)
+ return ticks;
+ H.assertHelper(t1 === 1000);
+ return ticks * 1000;
+ }
+ };
+ P.String.prototype = {$isPattern: 1};
+ P.Runes.prototype = {
+ get$iterator: function(_) {
+ return new P.RuneIterator(this.string);
+ },
+ get$last: function(_) {
+ var code, previousCode,
+ t1 = this.string,
+ t2 = t1.length;
+ if (t2 === 0)
+ throw H.wrapException(P.StateError$("No elements."));
+ code = C.JSString_methods.codeUnitAt$1(t1, t2 - 1);
+ if ((code & 64512) === 56320 && t2 > 1) {
+ previousCode = C.JSString_methods.codeUnitAt$1(t1, t2 - 2);
+ if ((previousCode & 64512) === 55296)
+ return P._combineSurrogatePair(previousCode, code);
+ }
+ return code;
+ }
+ };
+ P.RuneIterator.prototype = {
+ get$current: function() {
+ return this._currentCodePoint;
+ },
+ moveNext$0: function() {
+ var codeUnit, nextPosition, nextCodeUnit, _this = this,
+ t1 = _this._core$_position = _this._nextPosition,
+ t2 = _this.string,
+ t3 = t2.length;
+ if (t1 === t3) {
+ _this._currentCodePoint = null;
+ return false;
+ }
+ codeUnit = C.JSString_methods._codeUnitAt$1(t2, t1);
+ nextPosition = t1 + 1;
+ if ((codeUnit & 64512) === 55296 && nextPosition < t3) {
+ nextCodeUnit = C.JSString_methods._codeUnitAt$1(t2, nextPosition);
+ if ((nextCodeUnit & 64512) === 56320) {
+ _this._nextPosition = nextPosition + 1;
+ _this._currentCodePoint = P._combineSurrogatePair(codeUnit, nextCodeUnit);
+ return true;
+ }
+ }
+ _this._nextPosition = nextPosition;
+ _this._currentCodePoint = codeUnit;
+ return true;
+ },
+ $isIterator: 1
+ };
+ P.StringBuffer.prototype = {
+ get$length: function(_) {
+ return this._contents.length;
+ },
+ toString$0: function(_) {
+ var t1 = this._contents;
+ return t1.charCodeAt(0) == 0 ? t1 : t1;
+ },
+ $isStringSink: 1
+ };
+ P.Uri.prototype = {};
+ P.Uri__parseIPv4Address_error.prototype = {
+ call$2: function(msg, position) {
+ throw H.wrapException(P.FormatException$("Illegal IPv4 address, " + msg, this.host, position));
+ },
+ $signature: 68
+ };
+ P.Uri_parseIPv6Address_error.prototype = {
+ call$2: function(msg, position) {
+ throw H.wrapException(P.FormatException$("Illegal IPv6 address, " + msg, this.host, position));
+ },
+ call$1: function(msg) {
+ return this.call$2(msg, null);
+ },
+ $signature: 67
+ };
+ P.Uri_parseIPv6Address_parseHex.prototype = {
+ call$2: function(start, end) {
+ var value;
+ if (end - start > 4)
+ this.error.call$2("an IPv6 part can only contain a maximum of 4 hex digits", start);
+ value = P.int_parse(C.JSString_methods.substring$2(this.host, start, end), null, 16);
+ if (typeof value !== "number")
+ return value.$lt();
+ if (value < 0 || value > 65535)
+ this.error.call$2("each part must be in the range of `0x0..0xFFFF`", start);
+ return value;
+ },
+ $signature: 65
+ };
+ P._Uri.prototype = {
+ get$userInfo: function() {
+ return this._userInfo;
+ },
+ get$host: function(_) {
+ var t1 = this._host;
+ if (t1 == null)
+ return "";
+ if (C.JSString_methods.startsWith$1(t1, "["))
+ return C.JSString_methods.substring$2(t1, 1, t1.length - 1);
+ return t1;
+ },
+ get$port: function(_) {
+ var t1 = this._port;
+ if (t1 == null)
+ return P._Uri__defaultPort(this.scheme);
+ return t1;
+ },
+ get$query: function() {
+ var t1 = this._query;
+ return t1 == null ? "" : t1;
+ },
+ get$fragment: function() {
+ var t1 = this._fragment;
+ return t1 == null ? "" : t1;
+ },
+ replace$2$path$pathSegments: function(_, path, pathSegments) {
+ var scheme, isFile, userInfo, port, host, hasAuthority, t1, _this = this;
+ type$.Iterable_String._check(pathSegments);
+ type$.Map_String_dynamic._check(null);
+ scheme = _this.scheme;
+ isFile = scheme === "file";
+ userInfo = _this._userInfo;
+ port = _this._port;
+ host = _this._host;
+ if (!(host != null))
+ host = userInfo.length !== 0 || port != null || isFile ? "" : null;
+ hasAuthority = host != null;
+ t1 = path == null;
+ if (!t1 || pathSegments != null)
+ path = P._Uri__makePath(path, 0, t1 ? 0 : path.length, pathSegments, scheme, hasAuthority);
+ else {
+ path = _this.path;
+ if (!isFile)
+ t1 = hasAuthority && path.length !== 0;
+ else
+ t1 = true;
+ if (t1 && !C.JSString_methods.startsWith$1(path, "/"))
+ path = "/" + path;
+ }
+ return new P._Uri(scheme, userInfo, host, port, path, _this._query, _this._fragment);
+ },
+ replace$1$path: function($receiver, path) {
+ return this.replace$2$path$pathSegments($receiver, path, null);
+ },
+ replace$1$pathSegments: function($receiver, pathSegments) {
+ return this.replace$2$path$pathSegments($receiver, null, pathSegments);
+ },
+ get$pathSegments: function() {
+ var pathToSplit,
+ result = this._pathSegments;
+ if (result != null)
+ return result;
+ pathToSplit = this.path;
+ if (pathToSplit.length !== 0 && C.JSString_methods._codeUnitAt$1(pathToSplit, 0) === 47)
+ pathToSplit = C.JSString_methods.substring$1(pathToSplit, 1);
+ result = pathToSplit === "" ? C.List_empty : P.List_List$unmodifiable(new H.MappedListIterable(H.setRuntimeTypeInfo(pathToSplit.split("/"), type$.JSArray_String), type$.dynamic_Function_String._check(P.core_Uri_decodeComponent$closure()), type$.MappedListIterable_String_dynamic), type$.String);
+ this.set$_pathSegments(result);
+ return result;
+ },
+ _mergePaths$2: function(base, reference) {
+ var backCount, refStart, baseEnd, newEnd, delta, t1;
+ for (backCount = 0, refStart = 0; C.JSString_methods.startsWith$2(reference, "../", refStart);) {
+ refStart += 3;
+ ++backCount;
+ }
+ baseEnd = C.JSString_methods.lastIndexOf$1(base, "/");
+ while (true) {
+ if (!(baseEnd > 0 && backCount > 0))
+ break;
+ newEnd = C.JSString_methods.lastIndexOf$2(base, "/", baseEnd - 1);
+ if (newEnd < 0)
+ break;
+ delta = baseEnd - newEnd;
+ t1 = delta !== 2;
+ if (!t1 || delta === 3)
+ if (C.JSString_methods.codeUnitAt$1(base, newEnd + 1) === 46)
+ t1 = !t1 || C.JSString_methods.codeUnitAt$1(base, newEnd + 2) === 46;
+ else
+ t1 = false;
+ else
+ t1 = false;
+ if (t1)
+ break;
+ --backCount;
+ baseEnd = newEnd;
+ }
+ return C.JSString_methods.replaceRange$3(base, baseEnd + 1, null, C.JSString_methods.substring$1(reference, refStart - 3 * backCount));
+ },
+ resolve$1: function(reference) {
+ return this.resolveUri$1(P.Uri_parse(reference));
+ },
+ resolveUri$1: function(reference) {
+ var targetScheme, targetUserInfo, targetHost, targetPort, targetPath, targetQuery, t1, mergedPath, t2, _this = this, _null = null;
+ if (reference.get$scheme().length !== 0) {
+ targetScheme = reference.get$scheme();
+ if (reference.get$hasAuthority()) {
+ targetUserInfo = reference.get$userInfo();
+ targetHost = reference.get$host(reference);
+ targetPort = reference.get$hasPort() ? reference.get$port(reference) : _null;
+ } else {
+ targetPort = _null;
+ targetHost = targetPort;
+ targetUserInfo = "";
+ }
+ targetPath = P._Uri__removeDotSegments(reference.get$path(reference));
+ targetQuery = reference.get$hasQuery() ? reference.get$query() : _null;
+ } else {
+ targetScheme = _this.scheme;
+ if (reference.get$hasAuthority()) {
+ targetUserInfo = reference.get$userInfo();
+ targetHost = reference.get$host(reference);
+ targetPort = P._Uri__makePort(reference.get$hasPort() ? reference.get$port(reference) : _null, targetScheme);
+ targetPath = P._Uri__removeDotSegments(reference.get$path(reference));
+ targetQuery = reference.get$hasQuery() ? reference.get$query() : _null;
+ } else {
+ targetUserInfo = _this._userInfo;
+ targetHost = _this._host;
+ targetPort = _this._port;
+ if (reference.get$path(reference) === "") {
+ targetPath = _this.path;
+ targetQuery = reference.get$hasQuery() ? reference.get$query() : _this._query;
+ } else {
+ if (reference.get$hasAbsolutePath())
+ targetPath = P._Uri__removeDotSegments(reference.get$path(reference));
+ else {
+ t1 = _this.path;
+ if (t1.length === 0)
+ if (targetHost == null)
+ targetPath = targetScheme.length === 0 ? reference.get$path(reference) : P._Uri__removeDotSegments(reference.get$path(reference));
+ else
+ targetPath = P._Uri__removeDotSegments("/" + reference.get$path(reference));
+ else {
+ mergedPath = _this._mergePaths$2(t1, reference.get$path(reference));
+ t2 = targetScheme.length === 0;
+ if (!t2 || targetHost != null || C.JSString_methods.startsWith$1(t1, "/"))
+ targetPath = P._Uri__removeDotSegments(mergedPath);
+ else
+ targetPath = P._Uri__normalizeRelativePath(mergedPath, !t2 || targetHost != null);
+ }
+ }
+ targetQuery = reference.get$hasQuery() ? reference.get$query() : _null;
+ }
+ }
+ }
+ return new P._Uri(targetScheme, targetUserInfo, targetHost, targetPort, targetPath, targetQuery, reference.get$hasFragment() ? reference.get$fragment() : _null);
+ },
+ get$hasAuthority: function() {
+ return this._host != null;
+ },
+ get$hasPort: function() {
+ return this._port != null;
+ },
+ get$hasQuery: function() {
+ return this._query != null;
+ },
+ get$hasFragment: function() {
+ return this._fragment != null;
+ },
+ get$hasAbsolutePath: function() {
+ return C.JSString_methods.startsWith$1(this.path, "/");
+ },
+ toFilePath$0: function() {
+ var windows, pathSegments, _this = this,
+ t1 = _this.scheme;
+ if (t1 !== "" && t1 !== "file")
+ throw H.wrapException(P.UnsupportedError$("Cannot extract a file path from a " + H.S(t1) + " URI"));
+ t1 = _this._query;
+ if ((t1 == null ? "" : t1) !== "")
+ throw H.wrapException(P.UnsupportedError$("Cannot extract a file path from a URI with a query component"));
+ t1 = _this._fragment;
+ if ((t1 == null ? "" : t1) !== "")
+ throw H.wrapException(P.UnsupportedError$("Cannot extract a file path from a URI with a fragment component"));
+ windows = $.$get$_Uri__isWindowsCached();
+ if (H.boolConversionCheck(windows))
+ t1 = P._Uri__toWindowsFilePath(_this);
+ else {
+ if (_this._host != null && _this.get$host(_this) !== "")
+ H.throwExpression(P.UnsupportedError$("Cannot extract a non-Windows file path from a file URI with an authority"));
+ pathSegments = _this.get$pathSegments();
+ P._Uri__checkNonWindowsPathReservedCharacters(pathSegments, false);
+ t1 = P.StringBuffer__writeAll(C.JSString_methods.startsWith$1(_this.path, "/") ? "/" : "", pathSegments, "/");
+ t1 = t1.charCodeAt(0) == 0 ? t1 : t1;
+ }
+ return t1;
+ },
+ toString$0: function(_) {
+ var t2, t3, t4, _this = this,
+ t1 = _this._text;
+ if (t1 == null) {
+ t1 = _this.scheme;
+ t2 = t1.length !== 0 ? t1 + ":" : "";
+ t3 = _this._host;
+ t4 = t3 == null;
+ if (!t4 || t1 === "file") {
+ t1 = t2 + "//";
+ t2 = _this._userInfo;
+ if (t2.length !== 0)
+ t1 = t1 + t2 + "@";
+ if (!t4)
+ t1 += t3;
+ t2 = _this._port;
+ if (t2 != null)
+ t1 = t1 + ":" + H.S(t2);
+ } else
+ t1 = t2;
+ t1 += _this.path;
+ t2 = _this._query;
+ if (t2 != null)
+ t1 = t1 + "?" + t2;
+ t2 = _this._fragment;
+ if (t2 != null)
+ t1 = t1 + "#" + t2;
+ t1 = _this._text = t1.charCodeAt(0) == 0 ? t1 : t1;
+ }
+ return t1;
+ },
+ $eq: function(_, other) {
+ var t1, t2, _this = this;
+ if (other == null)
+ return false;
+ if (_this === other)
+ return true;
+ if (type$.Uri._is(other))
+ if (_this.scheme == other.get$scheme())
+ if (_this._host != null === other.get$hasAuthority())
+ if (_this._userInfo == other.get$userInfo())
+ if (_this.get$host(_this) == other.get$host(other))
+ if (_this.get$port(_this) == other.get$port(other))
+ if (_this.path === other.get$path(other)) {
+ t1 = _this._query;
+ t2 = t1 == null;
+ if (!t2 === other.get$hasQuery()) {
+ if (t2)
+ t1 = "";
+ if (t1 === other.get$query()) {
+ t1 = _this._fragment;
+ t2 = t1 == null;
+ if (!t2 === other.get$hasFragment()) {
+ if (t2)
+ t1 = "";
+ t1 = t1 === other.get$fragment();
+ } else
+ t1 = false;
+ } else
+ t1 = false;
+ } else
+ t1 = false;
+ } else
+ t1 = false;
+ else
+ t1 = false;
+ else
+ t1 = false;
+ else
+ t1 = false;
+ else
+ t1 = false;
+ else
+ t1 = false;
+ else
+ t1 = false;
+ return t1;
+ },
+ get$hashCode: function(_) {
+ var t1 = this._hashCodeCache;
+ return t1 == null ? this._hashCodeCache = C.JSString_methods.get$hashCode(this.toString$0(0)) : t1;
+ },
+ set$_pathSegments: function(_pathSegments) {
+ this._pathSegments = type$.List_String._check(_pathSegments);
+ },
+ $isUri: 1,
+ get$scheme: function() {
+ return this.scheme;
+ },
+ get$path: function(receiver) {
+ return this.path;
+ }
+ };
+ P._Uri__Uri$notSimple_closure.prototype = {
+ call$1: function(_) {
+ throw H.wrapException(P.FormatException$("Invalid port", this.uri, this.portStart + 1));
+ },
+ $signature: 30
+ };
+ P._Uri__checkNonWindowsPathReservedCharacters_closure.prototype = {
+ call$1: function(segment) {
+ var _s23_ = "Illegal path character ";
+ H._checkStringNullable(segment);
+ if (J.contains$1$asx(segment, "/"))
+ if (this.argumentError)
+ throw H.wrapException(P.ArgumentError$(_s23_ + segment));
+ else
+ throw H.wrapException(P.UnsupportedError$(_s23_ + segment));
+ },
+ $signature: 30
+ };
+ P._Uri__makePath_closure.prototype = {
+ call$1: function(s) {
+ return P._Uri__uriEncode(C.List_qg40, H._checkStringNullable(s), C.C_Utf8Codec, false);
+ },
+ $signature: 7
+ };
+ P.UriData.prototype = {
+ get$uri: function() {
+ var t2, queryIndex, end, query, _this = this, _null = null,
+ t1 = _this._uriCache;
+ if (t1 != null)
+ return t1;
+ t1 = _this._separatorIndices;
+ if (0 >= t1.length)
+ return H.ioore(t1, 0);
+ t2 = _this._text;
+ t1 = t1[0] + 1;
+ queryIndex = C.JSString_methods.indexOf$2(t2, "?", t1);
+ end = t2.length;
+ if (queryIndex >= 0) {
+ query = P._Uri__normalizeOrSubstring(t2, queryIndex + 1, end, C.List_CVk, false);
+ end = queryIndex;
+ } else
+ query = _null;
+ return _this._uriCache = new P._DataUri("data", _null, _null, _null, P._Uri__normalizeOrSubstring(t2, t1, end, C.List_qg4, false), query, _null);
+ },
+ toString$0: function(_) {
+ var t2,
+ t1 = this._separatorIndices;
+ if (0 >= t1.length)
+ return H.ioore(t1, 0);
+ t2 = this._text;
+ return t1[0] === -1 ? "data:" + t2 : t2;
+ }
+ };
+ P._createTables_closure.prototype = {
+ call$1: function(_) {
+ return new Uint8Array(96);
+ },
+ $signature: 64
+ };
+ P._createTables_build.prototype = {
+ call$2: function(state, defaultTransition) {
+ var t1 = this.tables;
+ if (state >= t1.length)
+ return H.ioore(t1, state);
+ t1 = t1[state];
+ J.fillRange$3$ax(t1, 0, 96, defaultTransition);
+ return t1;
+ },
+ $signature: 62
+ };
+ P._createTables_setChars.prototype = {
+ call$3: function(target, chars, transition) {
+ var t1, t2, i, t3;
+ for (t1 = chars.length, t2 = target.length, i = 0; i < t1; ++i) {
+ t3 = C.JSString_methods._codeUnitAt$1(chars, i) ^ 96;
+ if (t3 >= t2)
+ return H.ioore(target, t3);
+ target[t3] = transition;
+ }
+ },
+ $signature: 41
+ };
+ P._createTables_setRange.prototype = {
+ call$3: function(target, range, transition) {
+ var i, n, t1, t2;
+ for (i = C.JSString_methods._codeUnitAt$1(range, 0), n = C.JSString_methods._codeUnitAt$1(range, 1), t1 = target.length; i <= n; ++i) {
+ t2 = (i ^ 96) >>> 0;
+ if (t2 >= t1)
+ return H.ioore(target, t2);
+ target[t2] = transition;
+ }
+ },
+ $signature: 41
+ };
+ P._SimpleUri.prototype = {
+ get$hasAuthority: function() {
+ return this._hostStart > 0;
+ },
+ get$hasPort: function() {
+ return this._hostStart > 0 && this._portStart + 1 < this._pathStart;
+ },
+ get$hasQuery: function() {
+ return this._queryStart < this._fragmentStart;
+ },
+ get$hasFragment: function() {
+ return this._fragmentStart < this._uri.length;
+ },
+ get$_isFile: function() {
+ return this._schemeEnd === 4 && C.JSString_methods.startsWith$1(this._uri, "file");
+ },
+ get$_isHttp: function() {
+ return this._schemeEnd === 4 && C.JSString_methods.startsWith$1(this._uri, "http");
+ },
+ get$_isHttps: function() {
+ return this._schemeEnd === 5 && C.JSString_methods.startsWith$1(this._uri, "https");
+ },
+ get$hasAbsolutePath: function() {
+ return C.JSString_methods.startsWith$2(this._uri, "/", this._pathStart);
+ },
+ get$scheme: function() {
+ var t2, _this = this,
+ _s7_ = "package",
+ t1 = _this._schemeEnd;
+ if (t1 <= 0)
+ return "";
+ t2 = _this._schemeCache;
+ if (t2 != null)
+ return t2;
+ if (_this.get$_isHttp())
+ t1 = _this._schemeCache = "http";
+ else if (_this.get$_isHttps()) {
+ _this._schemeCache = "https";
+ t1 = "https";
+ } else if (_this.get$_isFile()) {
+ _this._schemeCache = "file";
+ t1 = "file";
+ } else if (t1 === 7 && C.JSString_methods.startsWith$1(_this._uri, _s7_)) {
+ _this._schemeCache = _s7_;
+ t1 = _s7_;
+ } else {
+ t1 = C.JSString_methods.substring$2(_this._uri, 0, t1);
+ _this._schemeCache = t1;
+ }
+ return t1;
+ },
+ get$userInfo: function() {
+ var t1 = this._hostStart,
+ t2 = this._schemeEnd + 3;
+ return t1 > t2 ? C.JSString_methods.substring$2(this._uri, t2, t1 - 1) : "";
+ },
+ get$host: function(_) {
+ var t1 = this._hostStart;
+ return t1 > 0 ? C.JSString_methods.substring$2(this._uri, t1, this._portStart) : "";
+ },
+ get$port: function(_) {
+ var _this = this;
+ if (_this.get$hasPort())
+ return P.int_parse(C.JSString_methods.substring$2(_this._uri, _this._portStart + 1, _this._pathStart), null, null);
+ if (_this.get$_isHttp())
+ return 80;
+ if (_this.get$_isHttps())
+ return 443;
+ return 0;
+ },
+ get$path: function(_) {
+ return C.JSString_methods.substring$2(this._uri, this._pathStart, this._queryStart);
+ },
+ get$query: function() {
+ var t1 = this._queryStart,
+ t2 = this._fragmentStart;
+ return t1 < t2 ? C.JSString_methods.substring$2(this._uri, t1 + 1, t2) : "";
+ },
+ get$fragment: function() {
+ var t1 = this._fragmentStart,
+ t2 = this._uri;
+ return t1 < t2.length ? C.JSString_methods.substring$1(t2, t1 + 1) : "";
+ },
+ get$pathSegments: function() {
+ var parts, i,
+ start = this._pathStart,
+ end = this._queryStart,
+ t1 = this._uri;
+ if (C.JSString_methods.startsWith$2(t1, "/", start))
+ ++start;
+ if (start === end)
+ return C.List_empty;
+ parts = H.setRuntimeTypeInfo([], type$.JSArray_String);
+ for (i = start; i < end; ++i)
+ if (C.JSString_methods.codeUnitAt$1(t1, i) === 47) {
+ C.JSArray_methods.add$1(parts, C.JSString_methods.substring$2(t1, start, i));
+ start = i + 1;
+ }
+ C.JSArray_methods.add$1(parts, C.JSString_methods.substring$2(t1, start, end));
+ return P.List_List$unmodifiable(parts, type$.String);
+ },
+ _isPort$1: function(port) {
+ var portDigitStart = this._portStart + 1;
+ return portDigitStart + port.length === this._pathStart && C.JSString_methods.startsWith$2(this._uri, port, portDigitStart);
+ },
+ removeFragment$0: function() {
+ var _this = this,
+ t1 = _this._fragmentStart,
+ t2 = _this._uri;
+ if (t1 >= t2.length)
+ return _this;
+ return new P._SimpleUri(C.JSString_methods.substring$2(t2, 0, t1), _this._schemeEnd, _this._hostStart, _this._portStart, _this._pathStart, _this._queryStart, t1, _this._schemeCache);
+ },
+ replace$2$path$pathSegments: function(_, path, pathSegments) {
+ var scheme, isFile, t1, userInfo, port, host, hasAuthority, t2, query, fragment, _this = this, _null = null;
+ type$.Iterable_String._check(pathSegments);
+ type$.Map_String_dynamic._check(null);
+ scheme = _this.get$scheme();
+ isFile = scheme === "file";
+ t1 = _this._hostStart;
+ userInfo = t1 > 0 ? C.JSString_methods.substring$2(_this._uri, _this._schemeEnd + 3, t1) : "";
+ port = _this.get$hasPort() ? _this.get$port(_this) : _null;
+ t1 = _this._hostStart;
+ if (t1 > 0)
+ host = C.JSString_methods.substring$2(_this._uri, t1, _this._portStart);
+ else
+ host = userInfo.length !== 0 || port != null || isFile ? "" : _null;
+ hasAuthority = host != null;
+ t1 = path == null;
+ if (!t1 || pathSegments != null)
+ path = P._Uri__makePath(path, 0, t1 ? 0 : path.length, pathSegments, scheme, hasAuthority);
+ else {
+ path = C.JSString_methods.substring$2(_this._uri, _this._pathStart, _this._queryStart);
+ if (!isFile)
+ t1 = hasAuthority && path.length !== 0;
+ else
+ t1 = true;
+ if (t1 && !C.JSString_methods.startsWith$1(path, "/"))
+ path = "/" + path;
+ }
+ t1 = _this._queryStart;
+ t2 = _this._fragmentStart;
+ query = t1 < t2 ? C.JSString_methods.substring$2(_this._uri, t1 + 1, t2) : _null;
+ t1 = _this._fragmentStart;
+ t2 = _this._uri;
+ fragment = t1 < t2.length ? C.JSString_methods.substring$1(t2, t1 + 1) : _null;
+ return new P._Uri(scheme, userInfo, host, port, path, query, fragment);
+ },
+ replace$1$path: function($receiver, path) {
+ return this.replace$2$path$pathSegments($receiver, path, null);
+ },
+ replace$1$pathSegments: function($receiver, pathSegments) {
+ return this.replace$2$path$pathSegments($receiver, null, pathSegments);
+ },
+ resolve$1: function(reference) {
+ return this.resolveUri$1(P.Uri_parse(reference));
+ },
+ resolveUri$1: function(reference) {
+ if (reference instanceof P._SimpleUri)
+ return this._simpleMerge$2(this, reference);
+ return this._toNonSimple$0().resolveUri$1(reference);
+ },
+ _simpleMerge$2: function(base, ref) {
+ var t2, t3, isSimple, delta, refStart, baseStart, baseEnd, baseUri, baseStart0, backCount, refStart0, insert,
+ t1 = ref._schemeEnd;
+ if (t1 > 0)
+ return ref;
+ t2 = ref._hostStart;
+ if (t2 > 0) {
+ t3 = base._schemeEnd;
+ if (t3 <= 0)
+ return ref;
+ if (base.get$_isFile())
+ isSimple = ref._pathStart !== ref._queryStart;
+ else if (base.get$_isHttp())
+ isSimple = !ref._isPort$1("80");
+ else
+ isSimple = !base.get$_isHttps() || !ref._isPort$1("443");
+ if (isSimple) {
+ delta = t3 + 1;
+ return new P._SimpleUri(C.JSString_methods.substring$2(base._uri, 0, delta) + C.JSString_methods.substring$1(ref._uri, t1 + 1), t3, t2 + delta, ref._portStart + delta, ref._pathStart + delta, ref._queryStart + delta, ref._fragmentStart + delta, base._schemeCache);
+ } else
+ return this._toNonSimple$0().resolveUri$1(ref);
+ }
+ refStart = ref._pathStart;
+ t1 = ref._queryStart;
+ if (refStart === t1) {
+ t2 = ref._fragmentStart;
+ if (t1 < t2) {
+ t3 = base._queryStart;
+ delta = t3 - t1;
+ return new P._SimpleUri(C.JSString_methods.substring$2(base._uri, 0, t3) + C.JSString_methods.substring$1(ref._uri, t1), base._schemeEnd, base._hostStart, base._portStart, base._pathStart, t1 + delta, t2 + delta, base._schemeCache);
+ }
+ t1 = ref._uri;
+ if (t2 < t1.length) {
+ t3 = base._fragmentStart;
+ return new P._SimpleUri(C.JSString_methods.substring$2(base._uri, 0, t3) + C.JSString_methods.substring$1(t1, t2), base._schemeEnd, base._hostStart, base._portStart, base._pathStart, base._queryStart, t2 + (t3 - t2), base._schemeCache);
+ }
+ return base.removeFragment$0();
+ }
+ t2 = ref._uri;
+ if (C.JSString_methods.startsWith$2(t2, "/", refStart)) {
+ t3 = base._pathStart;
+ delta = t3 - refStart;
+ return new P._SimpleUri(C.JSString_methods.substring$2(base._uri, 0, t3) + C.JSString_methods.substring$1(t2, refStart), base._schemeEnd, base._hostStart, base._portStart, t3, t1 + delta, ref._fragmentStart + delta, base._schemeCache);
+ }
+ baseStart = base._pathStart;
+ baseEnd = base._queryStart;
+ if (baseStart === baseEnd && base._hostStart > 0) {
+ for (; C.JSString_methods.startsWith$2(t2, "../", refStart);)
+ refStart += 3;
+ delta = baseStart - refStart + 1;
+ return new P._SimpleUri(C.JSString_methods.substring$2(base._uri, 0, baseStart) + "/" + C.JSString_methods.substring$1(t2, refStart), base._schemeEnd, base._hostStart, base._portStart, baseStart, t1 + delta, ref._fragmentStart + delta, base._schemeCache);
+ }
+ baseUri = base._uri;
+ for (baseStart0 = baseStart; C.JSString_methods.startsWith$2(baseUri, "../", baseStart0);)
+ baseStart0 += 3;
+ backCount = 0;
+ while (true) {
+ refStart0 = refStart + 3;
+ if (!(refStart0 <= t1 && C.JSString_methods.startsWith$2(t2, "../", refStart)))
+ break;
+ ++backCount;
+ refStart = refStart0;
+ }
+ for (insert = ""; baseEnd > baseStart0;) {
+ --baseEnd;
+ if (C.JSString_methods.codeUnitAt$1(baseUri, baseEnd) === 47) {
+ if (backCount === 0) {
+ insert = "/";
+ break;
+ }
+ --backCount;
+ insert = "/";
+ }
+ }
+ if (baseEnd === baseStart0 && base._schemeEnd <= 0 && !C.JSString_methods.startsWith$2(baseUri, "/", baseStart)) {
+ refStart -= backCount * 3;
+ insert = "";
+ }
+ delta = baseEnd - refStart + insert.length;
+ return new P._SimpleUri(C.JSString_methods.substring$2(baseUri, 0, baseEnd) + insert + C.JSString_methods.substring$1(t2, refStart), base._schemeEnd, base._hostStart, base._portStart, baseStart, t1 + delta, ref._fragmentStart + delta, base._schemeCache);
+ },
+ toFilePath$0: function() {
+ var t1, t2, windows, _this = this;
+ if (_this._schemeEnd >= 0 && !_this.get$_isFile())
+ throw H.wrapException(P.UnsupportedError$("Cannot extract a file path from a " + H.S(_this.get$scheme()) + " URI"));
+ t1 = _this._queryStart;
+ t2 = _this._uri;
+ if (t1 < t2.length) {
+ if (t1 < _this._fragmentStart)
+ throw H.wrapException(P.UnsupportedError$("Cannot extract a file path from a URI with a query component"));
+ throw H.wrapException(P.UnsupportedError$("Cannot extract a file path from a URI with a fragment component"));
+ }
+ windows = $.$get$_Uri__isWindowsCached();
+ if (H.boolConversionCheck(windows))
+ t1 = P._Uri__toWindowsFilePath(_this);
+ else {
+ if (_this._hostStart < _this._portStart)
+ H.throwExpression(P.UnsupportedError$("Cannot extract a non-Windows file path from a file URI with an authority"));
+ t1 = C.JSString_methods.substring$2(t2, _this._pathStart, t1);
+ }
+ return t1;
+ },
+ get$hashCode: function(_) {
+ var t1 = this._hashCodeCache;
+ return t1 == null ? this._hashCodeCache = C.JSString_methods.get$hashCode(this._uri) : t1;
+ },
+ $eq: function(_, other) {
+ if (other == null)
+ return false;
+ if (this === other)
+ return true;
+ return type$.Uri._is(other) && this._uri === other.toString$0(0);
+ },
+ _toNonSimple$0: function() {
+ var _this = this, _null = null,
+ t1 = _this.get$scheme(),
+ t2 = _this.get$userInfo(),
+ t3 = _this._hostStart > 0 ? _this.get$host(_this) : _null,
+ t4 = _this.get$hasPort() ? _this.get$port(_this) : _null,
+ t5 = _this._uri,
+ t6 = _this._queryStart,
+ t7 = C.JSString_methods.substring$2(t5, _this._pathStart, t6),
+ t8 = _this._fragmentStart;
+ t6 = t6 < t8 ? _this.get$query() : _null;
+ return new P._Uri(t1, t2, t3, t4, t7, t6, t8 < t5.length ? _this.get$fragment() : _null);
+ },
+ toString$0: function(_) {
+ return this._uri;
+ },
+ $isUri: 1
+ };
+ P._DataUri.prototype = {};
+ W.ApplicationCacheErrorEvent.prototype = {
+ get$message: function(receiver) {
+ return receiver.message;
+ }
+ };
+ W.Blob.prototype = {$isBlob: 1};
+ W.DomError.prototype = {
+ get$message: function(receiver) {
+ return receiver.message;
+ }
+ };
+ W.DomException.prototype = {
+ toString$0: function(receiver) {
+ return String(receiver);
+ },
+ get$message: function(receiver) {
+ return receiver.message;
+ }
+ };
+ W.ErrorEvent.prototype = {
+ get$message: function(receiver) {
+ return receiver.message;
+ }
+ };
+ W.Event.prototype = {$isEvent: 1};
+ W.EventTarget.prototype = {
+ addEventListener$3: function(receiver, type, listener, useCapture) {
+ type$.dynamic_Function_Event._check(listener);
+ if (listener != null)
+ this._addEventListener$3(receiver, type, listener, false);
+ },
+ _addEventListener$3: function(receiver, type, listener, options) {
+ return receiver.addEventListener(type, H.convertDartClosureToJS(type$.dynamic_Function_Event._check(listener), 1), false);
+ },
+ _removeEventListener$3: function(receiver, type, listener, options) {
+ return receiver.removeEventListener(type, H.convertDartClosureToJS(type$.dynamic_Function_Event._check(listener), 1), false);
+ },
+ $isEventTarget: 1
+ };
+ W.File.prototype = {$isFile: 1};
+ W.Location.prototype = {
+ get$origin: function(receiver) {
+ if ("origin" in receiver)
+ return receiver.origin;
+ return H.S(receiver.protocol) + "//" + H.S(receiver.host);
+ },
+ toString$0: function(receiver) {
+ return String(receiver);
+ }
+ };
+ W.MediaError.prototype = {
+ get$message: function(receiver) {
+ return receiver.message;
+ }
+ };
+ W.MediaKeyMessageEvent.prototype = {
+ get$message: function(receiver) {
+ return receiver.message;
+ }
+ };
+ W.MessageEvent.prototype = {$isMessageEvent: 1};
+ W.MessagePort.prototype = {
+ addEventListener$3: function(receiver, type, listener, useCapture) {
+ type$.dynamic_Function_Event._check(listener);
+ if (type === "message")
+ receiver.start();
+ this.super$EventTarget$addEventListener(receiver, type, listener, false);
+ },
+ postMessage$1: function(receiver, message) {
+ type$.List_Object._check(null);
+ receiver.postMessage(new P._StructuredCloneDart2Js([], []).walk$1(message));
+ return;
+ },
+ $isMessagePort: 1
+ };
+ W.NavigatorUserMediaError.prototype = {
+ get$message: function(receiver) {
+ return receiver.message;
+ }
+ };
+ W.OverconstrainedError.prototype = {
+ get$message: function(receiver) {
+ return receiver.message;
+ }
+ };
+ W.PositionError.prototype = {
+ get$message: function(receiver) {
+ return receiver.message;
+ }
+ };
+ W.PresentationConnectionCloseEvent.prototype = {
+ get$message: function(receiver) {
+ return receiver.message;
+ }
+ };
+ W.SpeechRecognitionError.prototype = {
+ get$message: function(receiver) {
+ return receiver.message;
+ }
+ };
+ W.EventStreamProvider.prototype = {};
+ W._EventStream.prototype = {
+ get$isBroadcast: function() {
+ return true;
+ },
+ listen$4$cancelOnError$onDone$onError: function(onData, cancelOnError, onDone, onError) {
+ var t1 = this.$ti;
+ t1._eval$1("~(1)")._check(onData);
+ type$.void_Function._check(onDone);
+ H._checkBoolNullable(cancelOnError);
+ return W._EventStreamSubscription$(this._html$_target, this._eventType, onData, false, t1._precomputed1);
+ },
+ listen$3$onDone$onError: function(onData, onDone, onError) {
+ return this.listen$4$cancelOnError$onDone$onError(onData, null, onDone, onError);
+ },
+ listen$1: function(onData) {
+ return this.listen$4$cancelOnError$onDone$onError(onData, null, null, null);
+ }
+ };
+ W._EventStreamSubscription.prototype = {
+ cancel$0: function() {
+ var _this = this;
+ if (_this._html$_target == null)
+ return null;
+ _this._unlisten$0();
+ _this._html$_target = null;
+ _this.set$_html$_onData(null);
+ return null;
+ },
+ pause$1: function(resumeSignal) {
+ if (this._html$_target == null)
+ return;
+ ++this._pauseCount;
+ this._unlisten$0();
+ },
+ pause$0: function() {
+ return this.pause$1(null);
+ },
+ resume$0: function() {
+ var _this = this;
+ if (_this._html$_target == null || _this._pauseCount <= 0)
+ return;
+ --_this._pauseCount;
+ _this._tryResume$0();
+ },
+ _tryResume$0: function() {
+ var _this = this,
+ t1 = _this._html$_onData;
+ if (t1 != null && _this._pauseCount <= 0)
+ J.addEventListener$3$x(_this._html$_target, _this._eventType, t1, false);
+ },
+ _unlisten$0: function() {
+ var t3,
+ t1 = this._html$_onData,
+ t2 = t1 != null;
+ if (t2) {
+ t3 = this._html$_target;
+ t3.toString;
+ type$.dynamic_Function_Event._check(t1);
+ if (t2)
+ J._removeEventListener$3$x(t3, this._eventType, t1, false);
+ }
+ },
+ set$_html$_onData: function(_onData) {
+ this._html$_onData = type$.dynamic_Function_Event._check(_onData);
+ }
+ };
+ W._EventStreamSubscription_closure.prototype = {
+ call$1: function(e) {
+ return this.onData.call$1(type$.Event._check(e));
+ },
+ $signature: 61
+ };
+ P._StructuredClone.prototype = {
+ findSlot$1: function(value) {
+ var i,
+ t1 = this.values,
+ $length = t1.length;
+ for (i = 0; i < $length; ++i)
+ if (t1[i] === value)
+ return i;
+ C.JSArray_methods.add$1(t1, value);
+ C.JSArray_methods.add$1(this.copies, null);
+ return $length;
+ },
+ walk$1: function(e) {
+ var slot, t2, copy, _this = this, t1 = {};
+ if (e == null)
+ return e;
+ if (H._isBool(e))
+ return e;
+ if (typeof e == "number")
+ return e;
+ if (typeof e == "string")
+ return e;
+ if (e instanceof P.DateTime)
+ return new Date(e._value);
+ if (type$.RegExp._is(e))
+ throw H.wrapException(P.UnimplementedError$("structured clone of RegExp"));
+ if (type$.File._is(e))
+ return e;
+ if (type$.Blob._is(e))
+ return e;
+ if (type$.NativeByteBuffer._is(e) || type$.NativeTypedData._is(e) || type$.MessagePort._is(e))
+ return e;
+ if (type$.Map_dynamic_dynamic._is(e)) {
+ slot = _this.findSlot$1(e);
+ t2 = _this.copies;
+ if (slot >= t2.length)
+ return H.ioore(t2, slot);
+ copy = t1.copy = t2[slot];
+ if (copy != null)
+ return copy;
+ copy = {};
+ t1.copy = copy;
+ C.JSArray_methods.$indexSet(t2, slot, copy);
+ e.forEach$1(0, new P._StructuredClone_walk_closure(t1, _this));
+ return t1.copy;
+ }
+ if (type$.List_dynamic._is(e)) {
+ slot = _this.findSlot$1(e);
+ t1 = _this.copies;
+ if (slot >= t1.length)
+ return H.ioore(t1, slot);
+ copy = t1[slot];
+ if (copy != null)
+ return copy;
+ return _this.copyList$2(e, slot);
+ }
+ if (type$.JSObject._is(e)) {
+ slot = _this.findSlot$1(e);
+ t2 = _this.copies;
+ if (slot >= t2.length)
+ return H.ioore(t2, slot);
+ copy = t1.copy = t2[slot];
+ if (copy != null)
+ return copy;
+ copy = {};
+ t1.copy = copy;
+ C.JSArray_methods.$indexSet(t2, slot, copy);
+ _this.forEachObjectKey$2(e, new P._StructuredClone_walk_closure0(t1, _this));
+ return t1.copy;
+ }
+ throw H.wrapException(P.UnimplementedError$("structured clone of other type"));
+ },
+ copyList$2: function(e, slot) {
+ var i,
+ t1 = J.getInterceptor$asx(e),
+ $length = t1.get$length(e),
+ copy = new Array($length);
+ C.JSArray_methods.$indexSet(this.copies, slot, copy);
+ for (i = 0; i < $length; ++i)
+ C.JSArray_methods.$indexSet(copy, i, this.walk$1(t1.$index(e, i)));
+ return copy;
+ }
+ };
+ P._StructuredClone_walk_closure.prototype = {
+ call$2: function(key, value) {
+ this._box_0.copy[key] = this.$this.walk$1(value);
+ },
+ $signature: 6
+ };
+ P._StructuredClone_walk_closure0.prototype = {
+ call$2: function(key, value) {
+ this._box_0.copy[key] = this.$this.walk$1(value);
+ },
+ $signature: 6
+ };
+ P._AcceptStructuredClone.prototype = {
+ findSlot$1: function(value) {
+ var i,
+ t1 = this.values,
+ $length = t1.length;
+ for (i = 0; i < $length; ++i)
+ if (t1[i] === value)
+ return i;
+ C.JSArray_methods.add$1(t1, value);
+ C.JSArray_methods.add$1(this.copies, null);
+ return $length;
+ },
+ walk$1: function(e) {
+ var millisSinceEpoch, t1, proto, slot, copy, t2, l, $length, i, _this = this, _box_0 = {};
+ if (e == null)
+ return e;
+ if (H._isBool(e))
+ return e;
+ if (typeof e == "number")
+ return e;
+ if (typeof e == "string")
+ return e;
+ if (e instanceof Date) {
+ millisSinceEpoch = e.getTime();
+ if (Math.abs(millisSinceEpoch) <= 864e13)
+ t1 = false;
+ else
+ t1 = true;
+ if (t1)
+ H.throwExpression(P.ArgumentError$("DateTime is outside valid range: " + millisSinceEpoch));
+ return new P.DateTime(millisSinceEpoch, true);
+ }
+ if (e instanceof RegExp)
+ throw H.wrapException(P.UnimplementedError$("structured clone of RegExp"));
+ if (typeof Promise != "undefined" && e instanceof Promise)
+ return P.promiseToFuture(e, type$.dynamic);
+ proto = Object.getPrototypeOf(e);
+ if (proto === Object.prototype || proto === null) {
+ slot = _this.findSlot$1(e);
+ t1 = _this.copies;
+ if (slot >= t1.length)
+ return H.ioore(t1, slot);
+ copy = _box_0.copy = t1[slot];
+ if (copy != null)
+ return copy;
+ t2 = type$.dynamic;
+ copy = P.LinkedHashMap_LinkedHashMap$_empty(t2, t2);
+ _box_0.copy = copy;
+ C.JSArray_methods.$indexSet(t1, slot, copy);
+ _this.forEachJsField$2(e, new P._AcceptStructuredClone_walk_closure(_box_0, _this));
+ return _box_0.copy;
+ }
+ if (e instanceof Array) {
+ l = e;
+ slot = _this.findSlot$1(l);
+ t1 = _this.copies;
+ if (slot >= t1.length)
+ return H.ioore(t1, slot);
+ copy = t1[slot];
+ if (copy != null)
+ return copy;
+ t2 = J.getInterceptor$asx(l);
+ $length = t2.get$length(l);
+ copy = _this.mustCopy ? new Array($length) : l;
+ C.JSArray_methods.$indexSet(t1, slot, copy);
+ for (t1 = J.getInterceptor$ax(copy), i = 0; i < $length; ++i)
+ t1.$indexSet(copy, i, _this.walk$1(t2.$index(l, i)));
+ return copy;
+ }
+ return e;
+ },
+ convertNativeToDart_AcceptStructuredClone$2$mustCopy: function(object, mustCopy) {
+ this.mustCopy = true;
+ return this.walk$1(object);
+ }
+ };
+ P._AcceptStructuredClone_walk_closure.prototype = {
+ call$2: function(key, value) {
+ var t1 = this._box_0.copy,
+ t2 = this.$this.walk$1(value);
+ J.$indexSet$ax(t1, key, t2);
+ return t2;
+ },
+ $signature: 60
+ };
+ P._StructuredCloneDart2Js.prototype = {
+ forEachObjectKey$2: function(object, action) {
+ var t1, t2, _i, key;
+ type$.dynamic_Function_dynamic_dynamic._check(action);
+ for (t1 = Object.keys(object), t2 = t1.length, _i = 0; _i < t2; ++_i) {
+ key = t1[_i];
+ action.call$2(key, object[key]);
+ }
+ }
+ };
+ P._AcceptStructuredCloneDart2Js.prototype = {
+ forEachJsField$2: function(object, action) {
+ var t1, t2, _i, key;
+ type$.dynamic_Function_dynamic_dynamic._check(action);
+ for (t1 = Object.keys(object), t2 = t1.length, _i = 0; _i < t1.length; t1.length === t2 || (0, H.throwConcurrentModificationError)(t1), ++_i) {
+ key = t1[_i];
+ action.call$2(key, object[key]);
+ }
+ }
+ };
+ P._convertDataTree__convert.prototype = {
+ call$1: function(o) {
+ var convertedMap, key, convertedList,
+ t1 = this._convertedObjects;
+ if (t1.containsKey$1(o))
+ return t1.$index(0, o);
+ if (type$.Map_dynamic_dynamic._is(o)) {
+ convertedMap = {};
+ t1.$indexSet(0, o, convertedMap);
+ for (t1 = o.get$keys(), t1 = t1.get$iterator(t1); t1.moveNext$0();) {
+ key = t1.get$current();
+ convertedMap[key] = this.call$1(o.$index(0, key));
+ }
+ return convertedMap;
+ } else if (type$.Iterable_dynamic._is(o)) {
+ convertedList = [];
+ t1.$indexSet(0, o, convertedList);
+ C.JSArray_methods.addAll$1(convertedList, J.map$1$1$ax(o, this, type$.dynamic));
+ return convertedList;
+ } else
+ return o;
+ },
+ $signature: 18
+ };
+ P.promiseToFuture_closure.prototype = {
+ call$1: function(r) {
+ return this.completer.complete$1(this.T._eval$1("0/")._check(r));
+ },
+ $signature: 15
+ };
+ P.promiseToFuture_closure0.prototype = {
+ call$1: function(e) {
+ return this.completer.completeError$1(e);
+ },
+ $signature: 15
+ };
+ P.ByteBuffer.prototype = {};
+ P.ByteData.prototype = {};
+ P.Int8List.prototype = {$isEfficientLengthIterable: 1, $isIterable: 1, $isList: 1};
+ P.Uint8List.prototype = {$isEfficientLengthIterable: 1, $isIterable: 1, $isList: 1};
+ P.Uint8ClampedList.prototype = {$isEfficientLengthIterable: 1, $isIterable: 1, $isList: 1};
+ P.Int16List.prototype = {$isEfficientLengthIterable: 1, $isIterable: 1, $isList: 1};
+ P.Uint16List.prototype = {$isEfficientLengthIterable: 1, $isIterable: 1, $isList: 1};
+ P.Int32List.prototype = {$isEfficientLengthIterable: 1, $isIterable: 1, $isList: 1};
+ P.Uint32List.prototype = {$isEfficientLengthIterable: 1, $isIterable: 1, $isList: 1};
+ P.Float32List.prototype = {$isEfficientLengthIterable: 1, $isIterable: 1, $isList: 1};
+ P.Float64List.prototype = {$isEfficientLengthIterable: 1, $isIterable: 1, $isList: 1};
+ P.SqlError.prototype = {
+ get$message: function(receiver) {
+ return receiver.message;
+ }
+ };
+ S.AsyncMemoizer.prototype = {
+ runOnce$1: function(computation) {
+ var t2, t3,
+ t1 = this.$ti;
+ t1._eval$1("1/()")._check(computation);
+ t2 = this._async_memoizer$_completer;
+ t3 = t2.future;
+ if (t3._state === 0)
+ t2.complete$1(P.Future_Future$sync(computation, t1._precomputed1));
+ return t3;
+ }
+ };
+ O.DelegatingSink.prototype = {$isSink: 1};
+ Y.DelegatingStreamSubscription.prototype = {
+ onData$1: function(handleData) {
+ this._stream_subscription$_source.onData$1(this.$ti._eval$1("~(1)")._check(handleData));
+ },
+ onError$1: function(_, handleError) {
+ this._stream_subscription$_source.onError$1(0, handleError);
+ },
+ onDone$1: function(handleDone) {
+ this._stream_subscription$_source.onDone$1(type$.void_Function._check(handleDone));
+ },
+ pause$1: function(resumeFuture) {
+ this._stream_subscription$_source.pause$1(resumeFuture);
+ },
+ pause$0: function() {
+ return this.pause$1(null);
+ },
+ resume$0: function() {
+ this._stream_subscription$_source.resume$0();
+ },
+ cancel$0: function() {
+ return this._stream_subscription$_source.cancel$0();
+ },
+ $isStreamSubscription: 1
+ };
+ F.FutureGroup.prototype = {
+ add$1: function(_, task) {
+ var t1, index, _this = this;
+ _this.$ti._eval$1("Future<1>")._check(task);
+ if (_this._future_group$_closed)
+ throw H.wrapException(P.StateError$("The FutureGroup is closed."));
+ t1 = _this._values;
+ index = t1.length;
+ C.JSArray_methods.add$1(t1, null);
+ ++_this._future_group$_pending;
+ task.then$1$1(new F.FutureGroup_add_closure(_this, index), type$.Null).catchError$1(new F.FutureGroup_add_closure0(_this));
+ },
+ close$0: function(_) {
+ var t1, _this = this;
+ _this._future_group$_closed = true;
+ if (_this._future_group$_pending !== 0)
+ return;
+ t1 = _this._future_group$_completer;
+ if (t1.future._state !== 0)
+ return;
+ t1.complete$1(_this._values);
+ },
+ $isSink: 1
+ };
+ F.FutureGroup_add_closure.prototype = {
+ call$1: function(value) {
+ var t2, t3,
+ t1 = this.$this;
+ t1.$ti._precomputed1._check(value);
+ t2 = t1._future_group$_completer;
+ if (t2.future._state !== 0)
+ return null;
+ --t1._future_group$_pending;
+ t3 = t1._values;
+ C.JSArray_methods.$indexSet(t3, this.index, value);
+ if (t1._future_group$_pending !== 0)
+ return null;
+ if (!t1._future_group$_closed)
+ return null;
+ t2.complete$1(t3);
+ },
+ $signature: function() {
+ return this.$this.$ti._eval$1("Null(1)");
+ }
+ };
+ F.FutureGroup_add_closure0.prototype = {
+ call$2: function(error, stackTrace) {
+ var t1 = this.$this._future_group$_completer;
+ if (t1.future._state !== 0)
+ return null;
+ t1.completeError$2(error, type$.StackTrace._check(stackTrace));
+ },
+ $signature: 6
+ };
+ S.NullStreamSink.prototype = {
+ add$1: function(_, data) {
+ this.$ti._precomputed1._check(data);
+ this._checkEventAllowed$0();
+ },
+ addStream$1: function(stream) {
+ var future, _this = this;
+ _this.$ti._eval$1("Stream<1>")._check(stream);
+ _this._checkEventAllowed$0();
+ _this._addingStream = true;
+ future = stream.listen$1(null).cancel$0();
+ if (future == null) {
+ future = new P._Future($.Zone__current, type$._Future_dynamic);
+ future._asyncComplete$1(null);
+ }
+ return future.whenComplete$1(new S.NullStreamSink_addStream_closure(_this));
+ },
+ _checkEventAllowed$0: function() {
+ if (this._null_stream_sink$_closed)
+ throw H.wrapException(P.StateError$("Cannot add to a closed sink."));
+ if (this._addingStream)
+ throw H.wrapException(P.StateError$("Cannot add to a sink while adding a stream."));
+ },
+ close$0: function(_) {
+ this._null_stream_sink$_closed = true;
+ return this.done;
+ },
+ $isEventSink: 1,
+ $isStreamConsumer: 1,
+ $isStreamSink: 1,
+ $isSink: 1,
+ get$done: function() {
+ return this.done;
+ }
+ };
+ S.NullStreamSink_addStream_closure.prototype = {
+ call$0: function() {
+ this.$this._addingStream = false;
+ },
+ $signature: 0
+ };
+ V.ErrorResult.prototype = {
+ complete$1: function(completer) {
+ completer.completeError$2(this.error, this.stackTrace);
+ },
+ addTo$1: function(sink) {
+ sink.addError$2(this.error, this.stackTrace);
+ },
+ get$hashCode: function(_) {
+ return (J.get$hashCode$(this.error) ^ J.get$hashCode$(this.stackTrace) ^ 492929599) >>> 0;
+ },
+ $eq: function(_, other) {
+ if (other == null)
+ return false;
+ return other instanceof V.ErrorResult && J.$eq$(this.error, other.error) && this.stackTrace == other.stackTrace;
+ },
+ $isResult: 1
+ };
+ E.Result.prototype = {};
+ F.ValueResult.prototype = {
+ complete$1: function(completer) {
+ this.$ti._eval$1("Completer<1>")._check(completer).complete$1(this.value);
+ },
+ addTo$1: function(sink) {
+ this.$ti._eval$1("EventSink<1>")._check(sink).add$1(0, this.value);
+ },
+ get$hashCode: function(_) {
+ return (J.get$hashCode$(this.value) ^ 842997089) >>> 0;
+ },
+ $eq: function(_, other) {
+ if (other == null)
+ return false;
+ return other instanceof F.ValueResult && J.$eq$(this.value, other.value);
+ },
+ $isResult: 1
+ };
+ Y.StreamCompleter.prototype = {
+ setSourceStream$1: function(sourceStream) {
+ var t1;
+ this.$ti._eval$1("Stream<1>")._check(sourceStream);
+ t1 = this._stream;
+ if (t1._sourceStream != null)
+ throw H.wrapException(P.StateError$("Source stream already set"));
+ t1.set$_sourceStream(t1.$ti._eval$1("Stream<1>")._check(sourceStream));
+ if (t1._stream_completer$_controller != null)
+ t1._linkStreamToController$0();
+ }
+ };
+ Y._CompleterStream.prototype = {
+ listen$4$cancelOnError$onDone$onError: function(onData, cancelOnError, onDone, onError) {
+ var t1, _this = this;
+ _this.$ti._eval$1("@(1)")._check(onData);
+ type$.void_Function._check(onDone);
+ H._checkBoolNullable(cancelOnError);
+ if (_this._stream_completer$_controller == null) {
+ t1 = _this._sourceStream;
+ if (t1 != null && !t1.get$isBroadcast())
+ return _this._sourceStream.listen$4$cancelOnError$onDone$onError(onData, cancelOnError, onDone, onError);
+ _this._createController$0();
+ if (_this._sourceStream != null)
+ _this._linkStreamToController$0();
+ }
+ t1 = _this._stream_completer$_controller;
+ t1.toString;
+ return new P._ControllerStream(t1, H._instanceType(t1)._eval$1("_ControllerStream<1>")).listen$4$cancelOnError$onDone$onError(onData, cancelOnError, onDone, onError);
+ },
+ listen$3$onDone$onError: function(onData, onDone, onError) {
+ return this.listen$4$cancelOnError$onDone$onError(onData, null, onDone, onError);
+ },
+ listen$1: function(onData) {
+ return this.listen$4$cancelOnError$onDone$onError(onData, null, null, null);
+ },
+ _linkStreamToController$0: function() {
+ var t1, t2, _this = this;
+ H.assertHelper(_this._stream_completer$_controller != null);
+ H.assertHelper(_this._sourceStream != null);
+ t1 = _this._stream_completer$_controller.addStream$2$cancelOnError(_this._sourceStream, false);
+ t2 = _this._stream_completer$_controller;
+ t1.whenComplete$1(t2.get$close(t2));
+ },
+ _createController$0: function() {
+ H.assertHelper(this._stream_completer$_controller == null);
+ this.set$_stream_completer$_controller(P.StreamController_StreamController(null, null, true, this.$ti._precomputed1));
+ },
+ set$_stream_completer$_controller: function(_controller) {
+ this._stream_completer$_controller = this.$ti._eval$1("StreamController<1>")._check(_controller);
+ },
+ set$_sourceStream: function(_sourceStream) {
+ this._sourceStream = this.$ti._eval$1("Stream<1>")._check(_sourceStream);
+ }
+ };
+ L.StreamGroup.prototype = {
+ add$1: function(_, stream) {
+ var t1, _this = this;
+ _this.$ti._eval$1("Stream<1>")._check(stream);
+ if (_this._stream_group$_closed)
+ throw H.wrapException(P.StateError$("Can't add a Stream to a closed StreamGroup."));
+ t1 = _this._stream_group$_state;
+ if (t1 === C._StreamGroupState_dormant)
+ _this._stream_group$_subscriptions.putIfAbsent$2(stream, new L.StreamGroup_add_closure());
+ else if (t1 === C._StreamGroupState_canceled)
+ return stream.listen$1(null).cancel$0();
+ else
+ _this._stream_group$_subscriptions.putIfAbsent$2(stream, new L.StreamGroup_add_closure0(_this, stream));
+ return null;
+ },
+ _onListen$0: function() {
+ this._stream_group$_state = C._StreamGroupState_listening;
+ this._stream_group$_subscriptions.forEach$1(0, new L.StreamGroup__onListen_closure(this));
+ },
+ _onCancelBroadcast$0: function() {
+ this._stream_group$_state = C._StreamGroupState_dormant;
+ this._stream_group$_subscriptions.forEach$1(0, new L.StreamGroup__onCancelBroadcast_closure(this));
+ },
+ _listenToStream$1: function(stream) {
+ var t1, subscription, _this = this;
+ _this.$ti._eval$1("Stream<1>")._check(stream);
+ t1 = _this._stream_group$_controller;
+ subscription = stream.listen$3$onDone$onError(t1.get$add(t1), new L.StreamGroup__listenToStream_closure(_this, stream), t1.get$addError());
+ if (_this._stream_group$_state === C._StreamGroupState_paused)
+ subscription.pause$0();
+ return subscription;
+ },
+ close$0: function(_) {
+ var t1, _this = this;
+ if (_this._stream_group$_closed)
+ return _this._stream_group$_controller._ensureDoneFuture$0();
+ _this._stream_group$_closed = true;
+ t1 = _this._stream_group$_subscriptions;
+ if (t1.get$isEmpty(t1))
+ _this._stream_group$_controller.close$0(0);
+ return _this._stream_group$_controller._ensureDoneFuture$0();
+ },
+ set$_stream_group$_controller: function(_controller) {
+ this._stream_group$_controller = this.$ti._eval$1("StreamController<1>")._check(_controller);
+ },
+ $isSink: 1
+ };
+ L.StreamGroup_add_closure.prototype = {
+ call$0: function() {
+ return null;
+ },
+ $signature: 0
+ };
+ L.StreamGroup_add_closure0.prototype = {
+ call$0: function() {
+ return this.$this._listenToStream$1(this.stream);
+ },
+ $signature: function() {
+ return this.$this.$ti._eval$1("StreamSubscription<1>()");
+ }
+ };
+ L.StreamGroup__onListen_closure.prototype = {
+ call$2: function(stream, subscription) {
+ var t1 = this.$this,
+ t2 = t1.$ti;
+ t2._eval$1("Stream<1>")._check(stream);
+ if (t2._eval$1("StreamSubscription<1>")._check(subscription) != null)
+ return;
+ t1._stream_group$_subscriptions.$indexSet(0, stream, t1._listenToStream$1(stream));
+ },
+ $signature: function() {
+ return this.$this.$ti._eval$1("Null(Stream<1>,StreamSubscription<1>)");
+ }
+ };
+ L.StreamGroup__onCancelBroadcast_closure.prototype = {
+ call$2: function(stream, subscription) {
+ var t1 = this.$this,
+ t2 = t1.$ti;
+ t2._eval$1("Stream<1>")._check(stream);
+ t2._eval$1("StreamSubscription<1>")._check(subscription);
+ if (!stream.get$isBroadcast())
+ return;
+ subscription.cancel$0();
+ t1._stream_group$_subscriptions.$indexSet(0, stream, null);
+ },
+ $signature: function() {
+ return this.$this.$ti._eval$1("Null(Stream<1>,StreamSubscription<1>)");
+ }
+ };
+ L.StreamGroup__listenToStream_closure.prototype = {
+ call$0: function() {
+ var t1 = this.$this,
+ t2 = t1._stream_group$_subscriptions,
+ subscription = t2.remove$1(0, t1.$ti._eval$1("Stream<1>")._check(this.stream)),
+ future = subscription == null ? null : subscription.cancel$0();
+ if (t1._stream_group$_closed && t2.get$isEmpty(t2))
+ t1._stream_group$_controller.close$0(0);
+ return future;
+ },
+ $signature: 14
+ };
+ L._StreamGroupState.prototype = {
+ toString$0: function(_) {
+ return this.name;
+ }
+ };
+ G.StreamQueue.prototype = {
+ get$next: function() {
+ var t1, t2, _this = this;
+ if (!_this._isClosed) {
+ t1 = _this.$ti;
+ t2 = new P._Future($.Zone__current, t1._eval$1("_Future<1>"));
+ _this._addRequest$1(new G._NextRequest(new P._AsyncCompleter(t2, t1._eval$1("_AsyncCompleter<1>")), t1._eval$1("_NextRequest<1>")));
+ return t2;
+ }
+ throw H.wrapException(_this._failClosed$0());
+ },
+ _updateRequests$0: function() {
+ var t1, t2, t3, t4, _this = this;
+ for (t1 = _this._requestQueue, t2 = _this._eventQueue; !t1.get$isEmpty(t1);) {
+ t3 = t1._head;
+ if (t3 === t1._tail)
+ H.throwExpression(H.IterableElementError_noElement());
+ t4 = t1._table;
+ if (t3 >= t4.length)
+ return H.ioore(t4, t3);
+ if (t4[t3].update$2(t2, _this._isDone))
+ t1.removeFirst$0();
+ else
+ return;
+ }
+ if (!_this._isDone)
+ _this._stream_queue$_subscription.pause$0();
+ },
+ _extractStream$0: function() {
+ var t1, wasPaused, _this = this, _null = null;
+ H.assertHelper(_this._isClosed);
+ if (_this._isDone)
+ return new P._EmptyStream(_this.$ti._eval$1("_EmptyStream<1>"));
+ _this._isDone = true;
+ t1 = _this._stream_queue$_subscription;
+ if (t1 == null)
+ return _this._stream_queue$_source;
+ _this.set$_stream_queue$_subscription(_null);
+ wasPaused = t1.get$isPaused();
+ t1.pause$0();
+ t1.onData$1(_null);
+ t1.onError$1(0, _null);
+ t1.onDone$1(_null);
+ if (wasPaused)
+ t1.resume$0();
+ return new T.SubscriptionStream(t1, _this.$ti._eval$1("SubscriptionStream<1>"));
+ },
+ _ensureListening$0: function() {
+ var t1, _this = this;
+ if (_this._isDone)
+ return;
+ t1 = _this._stream_queue$_subscription;
+ if (t1 == null)
+ _this.set$_stream_queue$_subscription(_this._stream_queue$_source.listen$3$onDone$onError(new G.StreamQueue__ensureListening_closure(_this), new G.StreamQueue__ensureListening_closure0(_this), new G.StreamQueue__ensureListening_closure1(_this)));
+ else
+ t1.resume$0();
+ },
+ _addResult$1: function(result) {
+ var t1, _this = this;
+ _this.$ti._eval$1("Result<1>")._check(result);
+ ++_this._eventsReceived;
+ t1 = _this._eventQueue;
+ t1._queue_list$_add$1(t1.$ti._precomputed1._check(result));
+ _this._updateRequests$0();
+ },
+ _failClosed$0: function() {
+ return new P.StateError("Already cancelled");
+ },
+ _addRequest$1: function(request) {
+ var t1, _this = this;
+ _this.$ti._eval$1("_EventRequest<1>")._check(request);
+ t1 = _this._requestQueue;
+ if (t1._head === t1._tail) {
+ if (request.update$2(_this._eventQueue, _this._isDone))
+ return;
+ _this._ensureListening$0();
+ }
+ t1._collection$_add$1(t1.$ti._precomputed1._check(request));
+ },
+ set$_stream_queue$_subscription: function(_subscription) {
+ this._stream_queue$_subscription = this.$ti._eval$1("StreamSubscription<1>")._check(_subscription);
+ }
+ };
+ G.StreamQueue__ensureListening_closure.prototype = {
+ call$1: function(data) {
+ var t1 = this.$this,
+ t2 = t1.$ti;
+ t1._addResult$1(new F.ValueResult(t2._precomputed1._check(data), t2._eval$1("ValueResult<1>")));
+ },
+ $signature: function() {
+ return this.$this.$ti._eval$1("Null(1)");
+ }
+ };
+ G.StreamQueue__ensureListening_closure1.prototype = {
+ call$2: function(error, stackTrace) {
+ this.$this._addResult$1(new V.ErrorResult(error, type$.StackTrace._check(stackTrace)));
+ },
+ $signature: 5
+ };
+ G.StreamQueue__ensureListening_closure0.prototype = {
+ call$0: function() {
+ var t1 = this.$this;
+ t1.set$_stream_queue$_subscription(null);
+ t1._isDone = true;
+ t1._updateRequests$0();
+ },
+ $signature: 0
+ };
+ G._EventRequest.prototype = {};
+ G._NextRequest.prototype = {
+ update$2: function(events, isDone) {
+ this.$ti._eval$1("QueueList<Result<1>>")._check(events);
+ if (events.get$length(events) !== 0) {
+ events.removeFirst$0().complete$1(this._completer);
+ return true;
+ }
+ if (isDone) {
+ this._completer.completeError$2(new P.StateError("No elements"), P.StackTrace_current());
+ return true;
+ }
+ return false;
+ },
+ $is_EventRequest: 1
+ };
+ G._RestRequest.prototype = {
+ update$2: function(events, isDone) {
+ var t2, controller, _this = this,
+ t1 = _this.$ti;
+ t1._eval$1("QueueList<Result<1>>")._check(events);
+ if (events.get$length(events) === 0) {
+ t1 = _this._streamQueue;
+ t2 = _this._completer;
+ if (t1._isDone) {
+ t1 = t2._stream;
+ t2 = t1._sourceStream == null;
+ if (!t2)
+ H.throwExpression(P.StateError$("Source stream already set"));
+ H.assertHelper(t2);
+ if (t1._stream_completer$_controller == null)
+ t1._createController$0();
+ t2 = t1._stream_completer$_controller;
+ t2.toString;
+ t1.set$_sourceStream(new P._ControllerStream(t2, H._instanceType(t2)._eval$1("_ControllerStream<1>")));
+ t1._stream_completer$_controller.close$0(0);
+ } else
+ t2.setSourceStream$1(t1._extractStream$0());
+ } else {
+ controller = P.StreamController_StreamController(null, null, false, t1._precomputed1);
+ for (t1 = new H.ListIterator(events, events.get$length(events), events.$ti._eval$1("ListIterator<ListMixin.E>")); t1.moveNext$0();)
+ t1.__internal$_current.addTo$1(controller);
+ controller.addStream$2$cancelOnError(_this._streamQueue._extractStream$0(), false).whenComplete$1(controller.get$close(controller));
+ _this._completer.setSourceStream$1(new P._ControllerStream(controller, H._instanceType(controller)._eval$1("_ControllerStream<1>")));
+ }
+ return true;
+ },
+ $is_EventRequest: 1
+ };
+ T.StreamSinkCompleter.prototype = {};
+ T._CompleterSink.prototype = {
+ get$_canSendDirectly: function() {
+ return this._stream_sink_completer$_controller == null && this._destinationSink != null;
+ },
+ get$done: function() {
+ var t1 = this._stream_sink_completer$_doneCompleter;
+ if (t1 != null)
+ return t1.future;
+ t1 = this._destinationSink;
+ if (t1 == null) {
+ t1 = new P._Future($.Zone__current, type$._Future_dynamic);
+ this._stream_sink_completer$_doneCompleter = new P._SyncCompleter(t1, type$._SyncCompleter_dynamic);
+ return t1;
+ }
+ return t1.get$done();
+ },
+ addStream$1: function(stream) {
+ var _this = this;
+ _this.$ti._eval$1("Stream<1>")._check(stream);
+ if (_this.get$_canSendDirectly())
+ return _this._destinationSink.addStream$1(stream);
+ _this._ensureController$0();
+ return _this._stream_sink_completer$_controller.addStream$2$cancelOnError(stream, false);
+ },
+ close$0: function(_) {
+ var _this = this;
+ if (_this.get$_canSendDirectly())
+ _this._destinationSink.close$0(0);
+ else {
+ _this._ensureController$0();
+ _this._stream_sink_completer$_controller.close$0(0);
+ }
+ return _this.get$done();
+ },
+ _ensureController$0: function() {
+ if (this._stream_sink_completer$_controller == null)
+ this.set$_stream_sink_completer$_controller(P.StreamController_StreamController(null, null, true, this.$ti._precomputed1));
+ },
+ _setDestinationSink$1: function(sink) {
+ var t1, _this = this;
+ _this.$ti._eval$1("StreamSink<1>")._check(sink);
+ H.assertHelper(_this._destinationSink == null);
+ _this.set$_destinationSink(sink);
+ t1 = _this._stream_sink_completer$_controller;
+ if (t1 != null)
+ sink.addStream$1(new P._ControllerStream(t1, H._instanceType(t1)._eval$1("_ControllerStream<1>"))).whenComplete$1(sink.get$close(sink)).catchError$1(new T._CompleterSink__setDestinationSink_closure());
+ t1 = _this._stream_sink_completer$_doneCompleter;
+ if (t1 != null)
+ t1.complete$1(sink.get$done());
+ },
+ set$_stream_sink_completer$_controller: function(_controller) {
+ this._stream_sink_completer$_controller = this.$ti._eval$1("StreamController<1>")._check(_controller);
+ },
+ set$_destinationSink: function(_destinationSink) {
+ this._destinationSink = this.$ti._eval$1("StreamSink<1>")._check(_destinationSink);
+ },
+ $isEventSink: 1,
+ $isStreamConsumer: 1,
+ $isStreamSink: 1,
+ $isSink: 1
+ };
+ T._CompleterSink__setDestinationSink_closure.prototype = {
+ call$1: function(_) {
+ },
+ $signature: 3
+ };
+ T.SubscriptionStream.prototype = {
+ listen$4$cancelOnError$onDone$onError: function(onData, cancelOnError, onDone, onError) {
+ var result, result0,
+ t1 = this.$ti;
+ t1._eval$1("~(1)")._check(onData);
+ type$.void_Function._check(onDone);
+ H._checkBoolNullable(cancelOnError);
+ result = this._subscription_stream$_source;
+ if (result == null)
+ throw H.wrapException(P.StateError$("Stream has already been listened to."));
+ this.set$_subscription_stream$_source(null);
+ result0 = true === cancelOnError ? new T._CancelOnErrorSubscriptionWrapper(result, t1._eval$1("_CancelOnErrorSubscriptionWrapper<1>")) : result;
+ result0.onData$1(onData);
+ result0.onError$1(0, onError);
+ result0.onDone$1(onDone);
+ result.resume$0();
+ return result0;
+ },
+ listen$3$onDone$onError: function(onData, onDone, onError) {
+ return this.listen$4$cancelOnError$onDone$onError(onData, null, onDone, onError);
+ },
+ listen$1: function(onData) {
+ return this.listen$4$cancelOnError$onDone$onError(onData, null, null, null);
+ },
+ set$_subscription_stream$_source: function(_source) {
+ this._subscription_stream$_source = this.$ti._eval$1("StreamSubscription<1>")._check(_source);
+ }
+ };
+ T._CancelOnErrorSubscriptionWrapper.prototype = {
+ onError$1: function(_, handleError) {
+ this.super$DelegatingStreamSubscription$onError(0, new T._CancelOnErrorSubscriptionWrapper_onError_closure(this, handleError));
+ }
+ };
+ T._CancelOnErrorSubscriptionWrapper_onError_closure.prototype = {
+ call$2: function(error, stackTrace) {
+ var cancelFuture, t1;
+ type$.StackTrace._check(stackTrace);
+ cancelFuture = this.$this.super$DelegatingStreamSubscription$cancel();
+ if (cancelFuture != null)
+ cancelFuture.whenComplete$1(new T._CancelOnErrorSubscriptionWrapper_onError__closure(this.handleError, error, stackTrace));
+ else {
+ t1 = this.handleError;
+ if (type$.dynamic_Function_dynamic_dynamic._is(t1))
+ t1.call$2(error, stackTrace);
+ else
+ t1.call$1(error);
+ }
+ },
+ $signature: 5
+ };
+ T._CancelOnErrorSubscriptionWrapper_onError__closure.prototype = {
+ call$0: function() {
+ var t1 = this.handleError,
+ t2 = this.error;
+ if (type$.dynamic_Function_dynamic_dynamic._is(t1))
+ t1.call$2(t2, this.stackTrace);
+ else
+ t1.call$1(t2);
+ },
+ $signature: 0
+ };
+ X.BooleanSelector.prototype = {};
+ X.All.prototype = {
+ evaluate$1: function(semantics) {
+ return true;
+ },
+ intersection$1: function(other) {
+ return other;
+ },
+ validate$1: function(isDefined) {
+ type$.bool_Function_String._check(isDefined);
+ },
+ toString$0: function(_) {
+ return "<all>";
+ },
+ $isBooleanSelector: 1
+ };
+ U.VariableNode.prototype = {
+ accept$1: function(visitor) {
+ return visitor.visitVariable$1(this);
+ },
+ toString$0: function(_) {
+ return this.name;
+ },
+ $eq: function(_, other) {
+ if (other == null)
+ return false;
+ return other instanceof U.VariableNode && this.name == other.name;
+ },
+ get$hashCode: function(_) {
+ return J.get$hashCode$(this.name);
+ },
+ $isNode: 1,
+ get$span: function() {
+ return this.span;
+ }
+ };
+ U.NotNode.prototype = {
+ accept$1: function(visitor) {
+ return visitor.visitNot$1(this);
+ },
+ toString$0: function(_) {
+ var t1 = this.child;
+ return t1 instanceof U.VariableNode || t1 instanceof U.NotNode ? "!" + t1.toString$0(0) : "!(" + t1.toString$0(0) + ")";
+ },
+ $eq: function(_, other) {
+ if (other == null)
+ return false;
+ return other instanceof U.NotNode && this.child.$eq(0, other.child);
+ },
+ get$hashCode: function(_) {
+ var t1 = this.child;
+ return ~t1.get$hashCode(t1) >>> 0;
+ },
+ $isNode: 1,
+ get$span: function() {
+ return this.span;
+ }
+ };
+ U.OrNode.prototype = {
+ get$span: function() {
+ return U._expandSafe(this.left.get$span(), this.right.get$span());
+ },
+ accept$1: function(visitor) {
+ return visitor.visitOr$1(this);
+ },
+ toString$0: function(_) {
+ var string2,
+ string1 = this.left;
+ if (string1 instanceof U.AndNode || string1 instanceof U.ConditionalNode)
+ string1 = "(" + string1.toString$0(0) + ")";
+ string2 = this.right;
+ if (string2 instanceof U.AndNode || string2 instanceof U.ConditionalNode)
+ string2 = "(" + string2.toString$0(0) + ")";
+ return H.S(string1) + " || " + H.S(string2);
+ },
+ $eq: function(_, other) {
+ if (other == null)
+ return false;
+ return other instanceof U.OrNode && this.left.$eq(0, other.left) && this.right.$eq(0, other.right);
+ },
+ get$hashCode: function(_) {
+ var t1 = this.left,
+ t2 = this.right;
+ return (t1.get$hashCode(t1) ^ t2.get$hashCode(t2)) >>> 0;
+ },
+ $isNode: 1
+ };
+ U.AndNode.prototype = {
+ get$span: function() {
+ return U._expandSafe(this.left.get$span(), this.right.get$span());
+ },
+ accept$1: function(visitor) {
+ return visitor.visitAnd$1(this);
+ },
+ toString$0: function(_) {
+ var string2,
+ string1 = this.left;
+ if (string1 instanceof U.OrNode || string1 instanceof U.ConditionalNode)
+ string1 = "(" + string1.toString$0(0) + ")";
+ string2 = this.right;
+ if (string2 instanceof U.OrNode || string2 instanceof U.ConditionalNode)
+ string2 = "(" + string2.toString$0(0) + ")";
+ return H.S(string1) + " && " + H.S(string2);
+ },
+ $eq: function(_, other) {
+ if (other == null)
+ return false;
+ return other instanceof U.AndNode && this.left.$eq(0, other.left) && this.right.$eq(0, other.right);
+ },
+ get$hashCode: function(_) {
+ var t1 = this.left,
+ t2 = this.right;
+ return (t1.get$hashCode(t1) ^ t2.get$hashCode(t2)) >>> 0;
+ },
+ $isNode: 1
+ };
+ U.ConditionalNode.prototype = {
+ get$span: function() {
+ return U._expandSafe(this.condition.get$span(), this.whenFalse.get$span());
+ },
+ accept$1: function(visitor) {
+ return visitor.visitConditional$1(this);
+ },
+ toString$0: function(_) {
+ var trueString,
+ conditionString = this.condition;
+ if (conditionString instanceof U.ConditionalNode)
+ conditionString = "(" + conditionString.toString$0(0) + ")";
+ trueString = this.whenTrue;
+ if (trueString instanceof U.ConditionalNode)
+ trueString = "(" + trueString.toString$0(0) + ")";
+ return H.S(conditionString) + " ? " + H.S(trueString) + " : " + this.whenFalse.toString$0(0);
+ },
+ $eq: function(_, other) {
+ if (other == null)
+ return false;
+ return other instanceof U.ConditionalNode && this.condition.$eq(0, other.condition) && this.whenTrue.$eq(0, other.whenTrue) && this.whenFalse.$eq(0, other.whenFalse);
+ },
+ get$hashCode: function(_) {
+ var t1 = this.condition,
+ t2 = this.whenTrue,
+ t3 = this.whenFalse;
+ return (t1.get$hashCode(t1) ^ t2.get$hashCode(t2) ^ t3.get$hashCode(t3)) >>> 0;
+ },
+ $isNode: 1
+ };
+ T.Evaluator.prototype = {
+ visitVariable$1: function(node) {
+ return this._semantics.call$1(node.name);
+ },
+ visitNot$1: function(node) {
+ return !H.boolConversionCheck(node.child.accept$1(this));
+ },
+ visitOr$1: function(node) {
+ return H.boolConversionCheck(node.left.accept$1(this)) || H.boolConversionCheck(node.right.accept$1(this));
+ },
+ visitAnd$1: function(node) {
+ return H.boolConversionCheck(node.left.accept$1(this)) && H.boolConversionCheck(node.right.accept$1(this));
+ },
+ visitConditional$1: function(node) {
+ return H.boolConversionCheck(node.condition.accept$1(this)) ? node.whenTrue.accept$1(this) : node.whenFalse.accept$1(this);
+ },
+ $isVisitor: 1
+ };
+ Y.BooleanSelectorImpl.prototype = {
+ evaluate$1: function(semantics) {
+ var t1;
+ if (type$.Iterable_dynamic._is(semantics)) {
+ t1 = semantics.toSet$0(0);
+ t1 = t1.get$contains(t1);
+ } else {
+ type$.bool_Function_String._as(semantics);
+ t1 = semantics;
+ }
+ return this._selector.accept$1(new T.Evaluator(t1));
+ },
+ intersection$1: function(other) {
+ var t1 = J.getInterceptor$(other);
+ if (t1.$eq(other, C.C_All))
+ return this;
+ if (t1.$eq(other, C.C_None))
+ return other;
+ return other instanceof Y.BooleanSelectorImpl ? new Y.BooleanSelectorImpl(new U.AndNode(this._selector, other._selector)) : new R.IntersectionSelector(this, other);
+ },
+ validate$1: function(isDefined) {
+ this._selector.accept$1(new S.Validator(type$.bool_Function_String._check(isDefined)));
+ },
+ toString$0: function(_) {
+ return this._selector.toString$0(0);
+ },
+ $eq: function(_, other) {
+ if (other == null)
+ return false;
+ return other instanceof Y.BooleanSelectorImpl && this._selector.$eq(0, other._selector);
+ },
+ get$hashCode: function(_) {
+ var t1 = this._selector;
+ return t1.get$hashCode(t1);
+ },
+ $isBooleanSelector: 1
+ };
+ R.IntersectionSelector.prototype = {
+ evaluate$1: function(semantics) {
+ return H.boolConversionCheck(this._selector1.evaluate$1(semantics)) && H.boolConversionCheck(this._selector2.evaluate$1(semantics));
+ },
+ intersection$1: function(other) {
+ return new R.IntersectionSelector(this, other);
+ },
+ validate$1: function(isDefined) {
+ type$.bool_Function_String._check(isDefined);
+ this._selector1.validate$1(isDefined);
+ this._selector2.validate$1(isDefined);
+ },
+ toString$0: function(_) {
+ return "(" + this._selector1.toString$0(0) + ") && (" + H.S(this._selector2) + ")";
+ },
+ $eq: function(_, other) {
+ if (other == null)
+ return false;
+ return other instanceof R.IntersectionSelector && this._selector1.$eq(0, other._selector1) && J.$eq$(this._selector2, other._selector2);
+ },
+ get$hashCode: function(_) {
+ var t1 = this._selector1;
+ return (t1.get$hashCode(t1) ^ J.get$hashCode$(this._selector2)) >>> 0;
+ },
+ $isBooleanSelector: 1
+ };
+ O.None.prototype = {
+ evaluate$1: function(semantics) {
+ return false;
+ },
+ intersection$1: function(other) {
+ return this;
+ },
+ validate$1: function(isDefined) {
+ type$.bool_Function_String._check(isDefined);
+ },
+ toString$0: function(_) {
+ return "<none>";
+ },
+ $isBooleanSelector: 1
+ };
+ G.Parser.prototype = {
+ parse$0: function() {
+ var selector = this._conditional$0(),
+ t1 = this._parser0$_scanner,
+ t2 = t1.peek$0();
+ if (t2.get$type(t2) !== C.TokenType_wwi)
+ throw H.wrapException(G.SourceSpanFormatException$("Expected end of input.", t1.peek$0().get$span(), null));
+ return selector;
+ },
+ _conditional$0: function() {
+ var whenTrue, _this = this,
+ condition = _this._or$0(),
+ t1 = _this._parser0$_scanner;
+ if (!t1.scan$1(C.TokenType_69P))
+ return condition;
+ whenTrue = _this._conditional$0();
+ if (!t1.scan$1(C.TokenType_colon))
+ throw H.wrapException(G.SourceSpanFormatException$('Expected ":".', t1.peek$0().get$span(), null));
+ return new U.ConditionalNode(condition, whenTrue, _this._conditional$0());
+ },
+ _or$0: function() {
+ var left = this._and$0();
+ if (!this._parser0$_scanner.scan$1(C.TokenType_or))
+ return left;
+ return new U.OrNode(left, this._or$0());
+ },
+ _and$0: function() {
+ var left = this._simpleExpression$0();
+ if (!this._parser0$_scanner.scan$1(C.TokenType_and))
+ return left;
+ return new U.AndNode(left, this._and$0());
+ },
+ _simpleExpression$0: function() {
+ var child,
+ t1 = this._parser0$_scanner,
+ token = t1.next$0();
+ switch (token.get$type(token)) {
+ case C.TokenType_not:
+ child = this._simpleExpression$0();
+ return new U.NotNode(token.get$span().expand$1(0, child.get$span()), child);
+ case C.TokenType_e7P:
+ child = this._conditional$0();
+ if (!t1.scan$1(C.TokenType_31K))
+ throw H.wrapException(G.SourceSpanFormatException$('Expected ")".', t1.peek$0().get$span(), null));
+ return child;
+ case C.TokenType_identifier:
+ type$.IdentifierToken._as(token);
+ return new U.VariableNode(token.span, token.name);
+ default:
+ throw H.wrapException(G.SourceSpanFormatException$("Expected expression.", token.get$span(), null));
+ }
+ }
+ };
+ O.Scanner.prototype = {
+ peek$0: function() {
+ var t1 = this._scanner$_next;
+ return t1 == null ? this._scanner$_next = this._getNext$0() : t1;
+ },
+ next$0: function() {
+ var _this = this,
+ token = _this._scanner$_next;
+ if (token == null)
+ token = _this._getNext$0();
+ _this._endOfFileEmitted = token.get$type(token) === C.TokenType_wwi;
+ _this._scanner$_next = null;
+ return token;
+ },
+ scan$1: function(type) {
+ var t1 = this.peek$0();
+ if (t1.get$type(t1) !== type)
+ return false;
+ this.next$0();
+ return true;
+ },
+ _getNext$0: function() {
+ var t1, t2, _this = this;
+ if (_this._endOfFileEmitted)
+ throw H.wrapException(P.StateError$("No more tokens."));
+ _this._consumeWhitespace$0();
+ t1 = _this._scanner;
+ t2 = t1._string_scanner$_position;
+ if (t2 === t1.string.length)
+ return new L.Token(C.TokenType_wwi, t1.spanFrom$1(new S._SpanScannerState(t1, t2)));
+ switch (t1.peekChar$0()) {
+ case 40:
+ return _this._scanOperator$1(C.TokenType_e7P);
+ case 41:
+ return _this._scanOperator$1(C.TokenType_31K);
+ case 63:
+ return _this._scanOperator$1(C.TokenType_69P);
+ case 58:
+ return _this._scanOperator$1(C.TokenType_colon);
+ case 33:
+ return _this._scanOperator$1(C.TokenType_not);
+ case 124:
+ t2 = t1._string_scanner$_position;
+ t1.expect$1("||");
+ return new L.Token(C.TokenType_or, t1.spanFrom$1(new S._SpanScannerState(t1, t2)));
+ case 38:
+ t2 = t1._string_scanner$_position;
+ t1.expect$1("&&");
+ return new L.Token(C.TokenType_and, t1.spanFrom$1(new S._SpanScannerState(t1, t2)));
+ default:
+ t1.expect$2$name($.$get$_hyphenatedIdentifier0(), "expression");
+ t2 = t1.get$lastMatch().$index(0, 0);
+ if (t1.get$lastMatch() == null)
+ t1._lastSpan = null;
+ return new L.IdentifierToken(t1._lastSpan, t2);
+ }
+ },
+ _scanOperator$1: function(type) {
+ var t1 = this._scanner,
+ t2 = t1._string_scanner$_position,
+ t3 = t1.string;
+ if (t2 === t3.length)
+ t1.error$3$length$position(0, "expected more input.", 0, t2);
+ J.codeUnitAt$1$s(t3, t1._string_scanner$_position++);
+ return new L.Token(type, t1.spanFrom$1(new S._SpanScannerState(t1, t2)));
+ },
+ _consumeWhitespace$0: function() {
+ var success,
+ t1 = this._scanner;
+ while (true) {
+ success = t1.matches$1(0, $.$get$_whitespaceAndSingleLineComments());
+ if (success)
+ t1._lastMatchPosition = t1._string_scanner$_position = t1._lastMatch.get$end();
+ if (!(success || this._multiLineComment$0()))
+ break;
+ }
+ },
+ _multiLineComment$0: function() {
+ var success,
+ t1 = this._scanner;
+ if (!t1.scan$1("/*"))
+ return false;
+ while (true) {
+ success = t1.matches$1(0, $.$get$_multiLineCommentBody());
+ if (success)
+ t1._lastMatchPosition = t1._string_scanner$_position = t1._lastMatch.get$end();
+ if (!(success || this._multiLineComment$0()))
+ break;
+ }
+ t1.expect$1("*/");
+ return true;
+ }
+ };
+ L.Token.prototype = {
+ get$type: function(receiver) {
+ return this.type;
+ },
+ get$span: function() {
+ return this.span;
+ }
+ };
+ L.IdentifierToken.prototype = {
+ toString$0: function(_) {
+ return 'identifier "' + H.S(this.name) + '"';
+ },
+ $isToken: 1,
+ get$type: function() {
+ return C.TokenType_identifier;
+ },
+ get$span: function() {
+ return this.span;
+ }
+ };
+ L.TokenType.prototype = {
+ toString$0: function(_) {
+ return this.name;
+ }
+ };
+ S.Validator.prototype = {
+ visitVariable$1: function(node) {
+ if (H.boolConversionCheck(this._isDefined.call$1(node.name)))
+ return;
+ throw H.wrapException(G.SourceSpanFormatException$("Undefined variable.", node.span, null));
+ }
+ };
+ B.RecursiveVisitor.prototype = {
+ visitNot$1: function(node) {
+ node.child.accept$1(this);
+ },
+ visitOr$1: function(node) {
+ node.left.accept$1(this);
+ node.right.accept$1(this);
+ },
+ visitAnd$1: function(node) {
+ node.left.accept$1(this);
+ node.right.accept$1(this);
+ },
+ visitConditional$1: function(node) {
+ node.condition.accept$1(this);
+ node.whenTrue.accept$1(this);
+ node.whenFalse.accept$1(this);
+ },
+ $isVisitor: 1
+ };
+ O.EmptyUnmodifiableSet.prototype = {
+ get$iterator: function(_) {
+ return C.C_EmptyIterator;
+ },
+ get$length: function(_) {
+ return 0;
+ },
+ contains$1: function(_, element) {
+ return false;
+ },
+ toSet$0: function(_) {
+ return P.LinkedHashSet_LinkedHashSet(this.$ti._precomputed1);
+ },
+ $isEfficientLengthIterable: 1,
+ $isSet: 1
+ };
+ Y.mapMap_closure.prototype = {
+ call$2: function(mapKey, _) {
+ this.K1._check(mapKey);
+ this.V1._check(_);
+ return this.K2._as(mapKey);
+ },
+ $signature: function() {
+ return this.K2._eval$1("@<0>")._bind$1(this.K1)._bind$1(this.V1)._eval$1("1(2,3)");
+ }
+ };
+ Y.mapMap_closure0.prototype = {
+ call$2: function(mapKey, mapValue) {
+ var t1, _this = this;
+ _this.K1._check(mapKey);
+ _this.V1._check(mapValue);
+ t1 = _this._box_0;
+ _this.result.$indexSet(0, t1.key.call$2(mapKey, mapValue), t1.value.call$2(mapKey, mapValue));
+ },
+ $signature: function() {
+ return this.K1._eval$1("@<0>")._bind$1(this.V1)._eval$1("Null(1,2)");
+ }
+ };
+ Y.mergeMaps_closure.prototype = {
+ call$2: function(key, mapValue) {
+ var t1, _this = this;
+ _this.K._check(key);
+ _this.V._check(mapValue);
+ t1 = _this.result;
+ t1.$indexSet(0, key, t1.containsKey$1(key) ? _this.value.call$2(t1.$index(0, key), mapValue) : mapValue);
+ },
+ $signature: function() {
+ return this.K._eval$1("@<0>")._bind$1(this.V)._eval$1("Null(1,2)");
+ }
+ };
+ Q.QueueList.prototype = {
+ toString$0: function(_) {
+ return P.IterableBase_iterableToFullString(this, "{", "}");
+ },
+ removeFirst$0: function() {
+ var t2, result, _this = this,
+ t1 = _this._queue_list$_head;
+ if (t1 === _this._queue_list$_tail)
+ throw H.wrapException(P.StateError$("No element"));
+ t2 = _this._queue_list$_table;
+ if (t1 >= t2.length)
+ return H.ioore(t2, t1);
+ result = t2[t1];
+ C.JSArray_methods.$indexSet(t2, t1, null);
+ _this._queue_list$_head = (_this._queue_list$_head + 1 & _this._queue_list$_table.length - 1) >>> 0;
+ return result;
+ },
+ get$length: function(_) {
+ return (this._queue_list$_tail - this._queue_list$_head & this._queue_list$_table.length - 1) >>> 0;
+ },
+ set$length: function(_, value) {
+ var delta, t1, newTail, t2, _this = this;
+ if (value < 0)
+ throw H.wrapException(P.RangeError$("Length " + value + " may not be negative."));
+ delta = value - _this.get$length(_this);
+ if (delta >= 0) {
+ if (_this._queue_list$_table.length <= value)
+ _this._preGrow$1(value);
+ _this._queue_list$_tail = (_this._queue_list$_tail + delta & _this._queue_list$_table.length - 1) >>> 0;
+ return;
+ }
+ t1 = _this._queue_list$_tail;
+ newTail = t1 + delta;
+ t2 = _this._queue_list$_table;
+ if (newTail >= 0)
+ C.JSArray_methods.fillRange$3(t2, newTail, t1, null);
+ else {
+ newTail += t2.length;
+ C.JSArray_methods.fillRange$3(t2, 0, t1, null);
+ t1 = _this._queue_list$_table;
+ C.JSArray_methods.fillRange$3(t1, newTail, t1.length, null);
+ }
+ _this._queue_list$_tail = newTail;
+ },
+ $index: function(_, index) {
+ var t1, t2, t3, _this = this;
+ H._checkIntNullable(index);
+ if (index < 0 || index >= _this.get$length(_this))
+ throw H.wrapException(P.RangeError$("Index " + index + " must be in the range [0.." + _this.get$length(_this) + ")."));
+ t1 = _this._queue_list$_table;
+ t2 = t1.length;
+ t3 = (_this._queue_list$_head + index & t2 - 1) >>> 0;
+ if (t3 < 0 || t3 >= t2)
+ return H.ioore(t1, t3);
+ return t1[t3];
+ },
+ $indexSet: function(_, index, value) {
+ var t1, _this = this;
+ H._checkIntNullable(index);
+ _this.$ti._precomputed1._check(value);
+ if (typeof index !== "number")
+ return index.$lt();
+ if (index < 0 || index >= _this.get$length(_this))
+ throw H.wrapException(P.RangeError$("Index " + index + " must be in the range [0.." + _this.get$length(_this) + ")."));
+ t1 = _this._queue_list$_table;
+ C.JSArray_methods.$indexSet(t1, (_this._queue_list$_head + index & t1.length - 1) >>> 0, value);
+ },
+ _queue_list$_add$1: function(element) {
+ var t2, t3, newTable, split, _this = this,
+ t1 = _this.$ti;
+ t1._precomputed1._check(element);
+ C.JSArray_methods.$indexSet(_this._queue_list$_table, _this._queue_list$_tail, element);
+ t2 = _this._queue_list$_tail;
+ t3 = _this._queue_list$_table.length;
+ t2 = (t2 + 1 & t3 - 1) >>> 0;
+ _this._queue_list$_tail = t2;
+ if (_this._queue_list$_head === t2) {
+ t2 = new Array(t3 * 2);
+ t2.fixed$length = Array;
+ newTable = H.setRuntimeTypeInfo(t2, t1._eval$1("JSArray<1>"));
+ t1 = _this._queue_list$_table;
+ t2 = _this._queue_list$_head;
+ split = t1.length - t2;
+ C.JSArray_methods.setRange$4(newTable, 0, split, t1, t2);
+ C.JSArray_methods.setRange$4(newTable, split, split + _this._queue_list$_head, _this._queue_list$_table, 0);
+ _this._queue_list$_head = 0;
+ _this._queue_list$_tail = _this._queue_list$_table.length;
+ _this.set$_queue_list$_table(newTable);
+ }
+ },
+ _writeToList$1: function(target) {
+ var t1, t2, t3, $length, firstPartSize, _this = this;
+ _this.$ti._eval$1("List<1>")._check(target);
+ H.assertHelper(target.length >= _this.get$length(_this));
+ t1 = _this._queue_list$_head;
+ t2 = _this._queue_list$_tail;
+ t3 = _this._queue_list$_table;
+ if (t1 <= t2) {
+ $length = t2 - t1;
+ C.JSArray_methods.setRange$4(target, 0, $length, t3, t1);
+ return $length;
+ } else {
+ firstPartSize = t3.length - t1;
+ C.JSArray_methods.setRange$4(target, 0, firstPartSize, t3, t1);
+ C.JSArray_methods.setRange$4(target, firstPartSize, firstPartSize + _this._queue_list$_tail, _this._queue_list$_table, 0);
+ return _this._queue_list$_tail + firstPartSize;
+ }
+ },
+ _preGrow$1: function(newElementCount) {
+ var newCapacity, t1, newTable, _this = this;
+ H.assertHelper(newElementCount >= _this.get$length(_this));
+ newCapacity = Q.QueueList__nextPowerOf2(newElementCount + C.JSInt_methods._shrOtherPositive$1(newElementCount, 1));
+ if (typeof newCapacity !== "number")
+ return H.iae(newCapacity);
+ t1 = new Array(newCapacity);
+ t1.fixed$length = Array;
+ newTable = H.setRuntimeTypeInfo(t1, _this.$ti._eval$1("JSArray<1>"));
+ _this._queue_list$_tail = _this._writeToList$1(newTable);
+ _this.set$_queue_list$_table(newTable);
+ _this._queue_list$_head = 0;
+ },
+ set$_queue_list$_table: function(_table) {
+ this._queue_list$_table = this.$ti._eval$1("List<1>")._check(_table);
+ },
+ $isEfficientLengthIterable: 1,
+ $isQueue: 1,
+ $isIterable: 1,
+ $isList: 1
+ };
+ Q._QueueList_Object_ListMixin.prototype = {};
+ M.UnionSet.prototype = {
+ get$length: function(_) {
+ var t1 = this._sets.fold$1$2(0, 0, new M.UnionSet_length_closure(this), type$.int);
+ return t1;
+ },
+ get$iterator: function(_) {
+ var t1 = this.get$_union_set$_iterable();
+ return t1.get$iterator(t1);
+ },
+ get$_union_set$_iterable: function() {
+ var t1 = this._sets,
+ t2 = this.$ti._precomputed1,
+ t3 = H._instanceType(t1),
+ t4 = t3._bind$1(t2)._eval$1("Iterable<1>(2)")._check(new M.UnionSet__iterable_closure(this));
+ return new H.ExpandIterable(t1, t4, t3._eval$1("@<1>")._bind$1(t2)._eval$1("ExpandIterable<1,2>"));
+ },
+ toSet$0: function(_) {
+ var t1,
+ result = P.LinkedHashSet_LinkedHashSet(this.$ti._precomputed1);
+ for (t1 = this._sets, t1 = P._LinkedHashSetIterator$(t1, t1._collection$_modifications, H._instanceType(t1)._precomputed1); t1.moveNext$0();)
+ result.addAll$1(0, t1._collection$_current);
+ return result;
+ }
+ };
+ M.UnionSet_length_closure.prototype = {
+ call$2: function($length, set) {
+ var t1;
+ H._checkIntNullable($length);
+ this.$this.$ti._eval$1("Set<1>")._check(set);
+ t1 = set.get$length(set);
+ if (typeof $length !== "number")
+ return $length.$add();
+ if (typeof t1 !== "number")
+ return H.iae(t1);
+ return $length + t1;
+ },
+ $signature: function() {
+ return this.$this.$ti._eval$1("int(int,Set<1>)");
+ }
+ };
+ M.UnionSet__iterable_closure.prototype = {
+ call$1: function(set) {
+ return this.$this.$ti._eval$1("Set<1>")._check(set);
+ },
+ $signature: function() {
+ return this.$this.$ti._eval$1("Set<1>(Set<1>)");
+ }
+ };
+ M._UnionSet_SetBase_UnmodifiableSetMixin.prototype = {};
+ Y.UnionSetController.prototype = {
+ set$_union_set_controller$_set: function(_set) {
+ this._union_set_controller$_set = this.$ti._eval$1("UnionSet<1>")._check(_set);
+ }
+ };
+ L.UnmodifiableSetView.prototype = {};
+ L.UnmodifiableSetMixin.prototype = {};
+ L._UnmodifiableSetView_DelegatingSet_UnmodifiableSetMixin.prototype = {};
+ M._DelegatingIterableBase.prototype = {
+ contains$1: function(_, element) {
+ return this._base.contains$1(0, element);
+ },
+ every$1: function(_, test) {
+ return this._base.every$1(0, H._instanceType(this)._eval$1("bool(1)")._check(test));
+ },
+ get$first: function(_) {
+ var t1 = this._base;
+ return t1.get$first(t1);
+ },
+ get$isEmpty: function(_) {
+ var t1 = this._base;
+ return t1.get$isEmpty(t1);
+ },
+ get$iterator: function(_) {
+ var t1 = this._base;
+ return t1.get$iterator(t1);
+ },
+ get$last: function(_) {
+ var t1 = this._base;
+ return t1.get$last(t1);
+ },
+ get$length: function(_) {
+ var t1 = this._base;
+ return t1.get$length(t1);
+ },
+ map$1$1: function(_, f, $T) {
+ return this._base.map$1$1(0, H._instanceType(this)._bind$1($T)._eval$1("1(2)")._check(f), $T);
+ },
+ toList$1$growable: function(_, growable) {
+ return this._base.toList$1$growable(0, true);
+ },
+ toList$0: function($receiver) {
+ return this.toList$1$growable($receiver, true);
+ },
+ toSet$0: function(_) {
+ return this._base.toSet$0(0);
+ },
+ where$1: function(_, test) {
+ return this._base.where$1(0, H._instanceType(this)._eval$1("bool(1)")._check(test));
+ },
+ toString$0: function(_) {
+ return this._base.toString$0(0);
+ },
+ $isIterable: 1
+ };
+ M.DelegatingIterable.prototype = {};
+ M.DelegatingSet.prototype = {
+ union$1: function(other) {
+ var t1 = H._instanceType(this)._eval$1("Set<1>");
+ t1._check(other);
+ return t1._check(this._base).union$1(other);
+ },
+ toSet$0: function(_) {
+ var t1 = H._instanceType(this);
+ return new M.DelegatingSet(t1._eval$1("Set<1>")._check(this._base).toSet$0(0), t1._eval$1("DelegatingSet<1>"));
+ },
+ $isEfficientLengthIterable: 1,
+ $isSet: 1
+ };
+ Y._IsTrue.prototype = {
+ matches$2: function(_, item, matchState) {
+ return J.$eq$(item, true);
+ },
+ describe$1: function(description) {
+ description._out._contents += "true";
+ return description;
+ }
+ };
+ Y._Predicate.prototype = {
+ typedMatches$2: function(item, matchState) {
+ return this._matcher.call$1(this.$ti._precomputed1._check(item));
+ },
+ describe$1: function(description) {
+ description._out._contents += this._core_matchers$_description;
+ return description;
+ }
+ };
+ E.StringDescription.prototype = {
+ get$length: function(_) {
+ return this._out._contents.length;
+ },
+ toString$0: function(_) {
+ var t1 = this._out._contents;
+ return t1.charCodeAt(0) == 0 ? t1 : t1;
+ },
+ addDescriptionOf$1: function(value) {
+ if (value instanceof G.Matcher)
+ value.describe$1(this);
+ else
+ this._out._contents += Z.prettyPrint(value, 25, 80);
+ return this;
+ },
+ $isDescription: 1
+ };
+ D._StringEqualsMatcher.prototype = {
+ typedMatches$2: function(item, matchState) {
+ return this._equals_matcher$_value === H._checkStringNullable(item);
+ },
+ describe$1: function(description) {
+ return description.addDescriptionOf$1(this._equals_matcher$_value);
+ },
+ describeTypedMismatch$4: function(item, mismatchDescription, matchState, verbose) {
+ var buff, escapedItem, escapedValue, minLength, minLength0, minLength1, start, t1, i;
+ H._checkStringNullable(true);
+ buff = new P.StringBuffer("");
+ buff._contents = "is different.";
+ escapedItem = M.escape(true);
+ escapedValue = M.escape(this._equals_matcher$_value);
+ minLength = escapedItem.length;
+ minLength0 = escapedValue.length;
+ minLength1 = minLength < minLength0 ? minLength : minLength0;
+ for (start = 0; start < minLength1; ++start)
+ if (C.JSString_methods._codeUnitAt$1(escapedValue, start) !== C.JSString_methods._codeUnitAt$1(escapedItem, start))
+ break;
+ if (start === minLength1) {
+ t1 = buff._contents;
+ if (minLength0 < minLength) {
+ buff._contents = t1 + " Both strings start the same, but the actual value also has the following trailing characters: ";
+ D._StringEqualsMatcher__writeTrailing(buff, escapedItem, minLength0);
+ } else {
+ buff._contents = t1 + " Both strings start the same, but the actual value is missing the following trailing characters: ";
+ D._StringEqualsMatcher__writeTrailing(buff, escapedValue, minLength);
+ }
+ } else {
+ buff._contents += "\nExpected: ";
+ D._StringEqualsMatcher__writeLeading(buff, escapedValue, start);
+ D._StringEqualsMatcher__writeTrailing(buff, escapedValue, start);
+ buff._contents += "\n Actual: ";
+ D._StringEqualsMatcher__writeLeading(buff, escapedItem, start);
+ D._StringEqualsMatcher__writeTrailing(buff, escapedItem, start);
+ t1 = buff._contents += "\n ";
+ i = start > 10 ? 14 : start;
+ for (; i > 0; --i) {
+ t1 += " ";
+ buff._contents = t1;
+ }
+ buff._contents += "^\n Differ at offset " + start;
+ }
+ t1 = buff._contents;
+ mismatchDescription._out._contents += t1.charCodeAt(0) == 0 ? t1 : t1;
+ return mismatchDescription;
+ }
+ };
+ D._DeepMatcher.prototype = {
+ _compareIterables$5: function(expected, actual, matcher, depth, $location) {
+ var expectedIterator, actualIterator, index, expectedNext, actualNext, t1, newLocation, rp;
+ type$.List_String_Function_dynamic_dynamic_String_int._check(matcher);
+ if (type$.Iterable_dynamic._is(actual)) {
+ expectedIterator = J.get$iterator$ax(expected);
+ actualIterator = J.get$iterator$ax(actual);
+ for (index = 0; true; ++index) {
+ expectedNext = expectedIterator.moveNext$0();
+ actualNext = actualIterator.moveNext$0();
+ t1 = !expectedNext;
+ if (t1 && !actualNext)
+ return null;
+ newLocation = $location + "[" + index + "]";
+ if (t1)
+ return H.setRuntimeTypeInfo(["longer than expected", newLocation], type$.JSArray_String);
+ if (!actualNext)
+ return H.setRuntimeTypeInfo(["shorter than expected", newLocation], type$.JSArray_String);
+ rp = matcher.call$4(expectedIterator.get$current(), actualIterator.get$current(), newLocation, depth);
+ if (rp != null)
+ return rp;
+ }
+ } else
+ return H.setRuntimeTypeInfo(["is not Iterable", $location], type$.JSArray_String);
+ },
+ _compareSets$5: function(expected, actual, matcher, depth, $location) {
+ var other, t1, expectedElement, t2;
+ type$.List_String_Function_dynamic_dynamic_String_int._check(matcher);
+ if (type$.Iterable_dynamic._is(actual)) {
+ other = J.toSet$0$ax(actual);
+ for (t1 = expected.get$iterator(expected); t1.moveNext$0();) {
+ expectedElement = t1.get$current();
+ if (other.every$1(0, new D._DeepMatcher__compareSets_closure(matcher, expectedElement, $location, depth)))
+ return H.setRuntimeTypeInfo(["does not contain " + H.S(expectedElement), $location], type$.JSArray_String);
+ }
+ t1 = other.get$length(other);
+ t2 = expected.get$length(expected);
+ if (typeof t2 !== "number")
+ return H.iae(t2);
+ if (t1 > t2)
+ return H.setRuntimeTypeInfo(["larger than expected", $location], type$.JSArray_String);
+ else {
+ t1 = other.get$length(other);
+ t2 = expected.get$length(expected);
+ if (typeof t2 !== "number")
+ return H.iae(t2);
+ if (t1 < t2)
+ return H.setRuntimeTypeInfo(["smaller than expected", $location], type$.JSArray_String);
+ else
+ return null;
+ }
+ } else
+ return H.setRuntimeTypeInfo(["is not Iterable", $location], type$.JSArray_String);
+ },
+ _recursiveMatch$4: function(expected, actual, $location, depth) {
+ var e, t1, description, exception, err, key, t2, rp, _this = this;
+ if (expected instanceof G.Matcher) {
+ t1 = type$.dynamic;
+ if (expected.matches$2(0, actual, P.LinkedHashMap_LinkedHashMap$_empty(t1, t1)))
+ return null;
+ description = new E.StringDescription(new P.StringBuffer(""));
+ expected.describe$1(description);
+ return H.setRuntimeTypeInfo(["does not match " + description.toString$0(0), $location], type$.JSArray_String);
+ } else
+ try {
+ if (J.$eq$(expected, actual))
+ return null;
+ } catch (exception) {
+ e = H.unwrapException(exception);
+ t1 = H.setRuntimeTypeInfo(['== threw "' + H.S(e) + '"', $location], type$.JSArray_String);
+ return t1;
+ }
+ t1 = _this._limit;
+ if (depth > t1)
+ return H.setRuntimeTypeInfo(["recursion depth limit exceeded", $location], type$.JSArray_String);
+ if (depth === 0 || t1 > 1)
+ if (type$.Set_dynamic._is(expected))
+ return _this._compareSets$5(expected, actual, _this.get$_recursiveMatch(), depth + 1, $location);
+ else if (type$.Iterable_dynamic._is(expected))
+ return _this._compareIterables$5(expected, actual, _this.get$_recursiveMatch(), depth + 1, $location);
+ else {
+ t1 = type$.Map_dynamic_dynamic;
+ if (t1._is(expected)) {
+ if (!t1._is(actual))
+ return H.setRuntimeTypeInfo(["expected a map", $location], type$.JSArray_String);
+ err = expected.get$length(expected) == actual.get$length(actual) ? "" : "has different length and ";
+ for (t1 = expected.get$keys(), t1 = t1.get$iterator(t1); t1.moveNext$0();) {
+ key = t1.get$current();
+ if (!actual.containsKey$1(key))
+ return H.setRuntimeTypeInfo([err + "is missing map key '" + H.S(key) + "'", $location], type$.JSArray_String);
+ }
+ for (t1 = actual.get$keys(), t1 = t1.get$iterator(t1); t1.moveNext$0();) {
+ key = t1.get$current();
+ if (!expected.containsKey$1(key))
+ return H.setRuntimeTypeInfo([err + "has extra map key '" + H.S(key) + "'", $location], type$.JSArray_String);
+ }
+ for (t1 = expected.get$keys(), t1 = t1.get$iterator(t1), t2 = depth + 1; t1.moveNext$0();) {
+ key = t1.get$current();
+ rp = _this._recursiveMatch$4(expected.$index(0, key), actual.$index(0, key), $location + "['" + H.S(key) + "']", t2);
+ if (rp != null)
+ return rp;
+ }
+ return null;
+ }
+ }
+ t1 = new P.StringBuffer("");
+ if (depth > 0) {
+ t1._contents = "was ";
+ t2 = new E.StringDescription(t1).addDescriptionOf$1(actual);
+ t2._out._contents += " instead of ";
+ t2.addDescriptionOf$1(expected);
+ t1 = t1._contents;
+ return H.setRuntimeTypeInfo([t1.charCodeAt(0) == 0 ? t1 : t1, $location], type$.JSArray_String);
+ }
+ return H.setRuntimeTypeInfo(["", $location], type$.JSArray_String);
+ },
+ _equals_matcher$_match$3: function(expected, actual, matchState) {
+ var t1, t2, reason, innerState,
+ rp = this._recursiveMatch$4(expected, actual, "", 0);
+ if (rp == null)
+ return null;
+ t1 = J.getInterceptor$asx(rp);
+ t2 = t1.$index(rp, 0);
+ t2.toString;
+ if (J.get$length$asx(t2) !== 0) {
+ t2 = t1.$index(rp, 1);
+ t2.toString;
+ reason = J.get$length$asx(t2) !== 0 ? H.S(t1.$index(rp, 0)) + " at location " + H.S(t1.$index(rp, 1)) : t1.$index(rp, 0);
+ } else
+ reason = "";
+ t1 = type$.dynamic;
+ t2 = P.LinkedHashMap_LinkedHashMap$_literal(["reason", reason], t1, t1);
+ innerState = P.LinkedHashMap_LinkedHashMap$from(matchState, t1, t1);
+ matchState.clear$0(0);
+ matchState.$indexSet(0, "state", innerState);
+ matchState.addAll$1(0, t2);
+ return reason;
+ },
+ matches$2: function(_, item, matchState) {
+ return this._equals_matcher$_match$3(this._expected, item, matchState) == null;
+ },
+ describe$1: function(description) {
+ return description.addDescriptionOf$1(this._expected);
+ },
+ describeMismatch$4: function(item, mismatchDescription, matchState, verbose) {
+ var t1, t2, t3,
+ reason = H._asStringNullable(matchState.$index(0, "reason"));
+ if (reason == null)
+ reason = "";
+ t1 = reason.length === 0 && mismatchDescription._out._contents.length > 0;
+ t2 = mismatchDescription._out;
+ t3 = t2._contents;
+ if (t1) {
+ t2._contents = t3 + "is ";
+ mismatchDescription.addDescriptionOf$1(true);
+ } else
+ t2._contents = t3 + reason;
+ return mismatchDescription;
+ }
+ };
+ D._DeepMatcher__compareSets_closure.prototype = {
+ call$1: function(actualElement) {
+ var _this = this;
+ return _this.matcher.call$4(_this.expectedElement, actualElement, _this.location, _this.depth) != null;
+ },
+ $signature: 9
+ };
+ E.FeatureMatcher.prototype = {
+ matches$2: function(_, item, matchState) {
+ return this.super$TypeMatcher$matches(0, item, matchState) && H.boolConversionCheck(this.typedMatches$2(H._instanceType(this)._eval$1("FeatureMatcher.T")._check(item), matchState));
+ },
+ describeMismatch$4: function(item, mismatchDescription, matchState, verbose) {
+ if (H._instanceType(this)._eval$1("FeatureMatcher.T")._is(true))
+ return this.describeTypedMismatch$4(true, mismatchDescription, matchState, false);
+ mismatchDescription._out._contents += "not an ";
+ return this.super$TypeMatcher$describe(mismatchDescription);
+ },
+ describeTypedMismatch$4: function(item, mismatchDescription, matchState, verbose) {
+ H._instanceType(this)._eval$1("FeatureMatcher.T")._check(true);
+ return mismatchDescription;
+ }
+ };
+ G.Matcher.prototype = {
+ describeMismatch$4: function(item, mismatchDescription, matchState, verbose) {
+ return mismatchDescription;
+ }
+ };
+ Z.prettyPrint__prettyPrint.prototype = {
+ call$4: function(object, indent, seen, $top) {
+ var description, type, t2, strings, t3, singleLine, value, defaultToString, _this = this, t1 = {};
+ t1.seen = seen;
+ if (object instanceof G.Matcher) {
+ description = new E.StringDescription(new P.StringBuffer(""));
+ object.describe$1(description);
+ return "<" + description.toString$0(0) + ">";
+ }
+ if (seen.contains$1(0, object))
+ return "(recursive)";
+ t1.seen = seen.union$1(P.LinkedHashSet_LinkedHashSet$_literal([object], type$.dynamic));
+ t1 = new Z.prettyPrint__prettyPrint_pp(t1, _this, indent);
+ if (type$.Iterable_dynamic._is(object)) {
+ type = type$.List_dynamic._is(object) ? "" : Z._typeName(object) + ":";
+ t2 = type$.String;
+ strings = J.map$1$1$ax(object, t1, t2).toList$0(0);
+ t1 = strings.length;
+ t3 = _this.maxItems;
+ if (t1 > t3)
+ C.JSArray_methods.replaceRange$3(strings, t3 - 1, t1, H.setRuntimeTypeInfo(["..."], type$.JSArray_String));
+ singleLine = type + "[" + C.JSArray_methods.join$1(strings, ", ") + "]";
+ if (singleLine.length + indent <= _this.maxLineLength && !C.JSString_methods.contains$1(singleLine, "\n"))
+ return singleLine;
+ t1 = H._arrayInstanceType(strings);
+ return type + "[\n" + new H.MappedListIterable(strings, t1._eval$1("String(1)")._check(new Z.prettyPrint__prettyPrint_closure(indent)), t1._eval$1("MappedListIterable<1,String>")).join$1(0, ",\n") + "\n" + C.JSArray_methods.join$1(P.List_List$filled(indent, " ", t2), "") + "]";
+ } else if (type$.Map_dynamic_dynamic._is(object)) {
+ t2 = type$.String;
+ strings = object.get$keys().map$1$1(0, new Z.prettyPrint__prettyPrint_closure0(t1, object), t2).toList$0(0);
+ t1 = strings.length;
+ t3 = _this.maxItems;
+ if (t1 > t3)
+ C.JSArray_methods.replaceRange$3(strings, t3 - 1, t1, H.setRuntimeTypeInfo(["..."], type$.JSArray_String));
+ singleLine = "{" + C.JSArray_methods.join$1(strings, ", ") + "}";
+ if (singleLine.length + indent <= _this.maxLineLength && !C.JSString_methods.contains$1(singleLine, "\n"))
+ return singleLine;
+ t1 = H._arrayInstanceType(strings);
+ return "{\n" + new H.MappedListIterable(strings, t1._eval$1("String(1)")._check(new Z.prettyPrint__prettyPrint_closure1(indent)), t1._eval$1("MappedListIterable<1,String>")).join$1(0, ",\n") + "\n" + C.JSArray_methods.join$1(P.List_List$filled(indent, " ", t2), "") + "}";
+ } else {
+ t1 = type$.String;
+ if (typeof object == "string")
+ return "'" + new H.MappedListIterable(H.setRuntimeTypeInfo(object.split("\n"), type$.JSArray_String), type$.String_Function_String._check(Z.pretty_print___escapeString$closure()), type$.MappedListIterable_String_String).join$1(0, "\\n'\n" + C.JSArray_methods.join$1(P.List_List$filled(indent + 2, " ", t1), "") + "'") + "'";
+ else {
+ t2 = J.toString$0$(object);
+ t1 = C.JSArray_methods.join$1(P.List_List$filled(indent, " ", t1), "") + "\n";
+ t2.toString;
+ value = H.stringReplaceAllUnchecked(t2, "\n", t1);
+ defaultToString = C.JSString_methods.startsWith$1(value, "Instance of ");
+ if ($top)
+ value = "<" + value + ">";
+ if (typeof object == "number" || H._isBool(object) || type$.Function._is(object) || type$.RegExp._is(object) || object instanceof P.MapEntry || object instanceof P.Expando || object == null || defaultToString)
+ return value;
+ else
+ return Z._typeName(object) + ":" + value;
+ }
+ }
+ },
+ $signature: 55
+ };
+ Z.prettyPrint__prettyPrint_pp.prototype = {
+ call$1: function(child) {
+ return this._prettyPrint.call$4(child, this.indent + 2, this._box_0.seen, false);
+ },
+ $signature: 40
+ };
+ Z.prettyPrint__prettyPrint_closure.prototype = {
+ call$1: function(string) {
+ H._checkStringNullable(string);
+ return C.JSString_methods.$add(C.JSArray_methods.join$1(P.List_List$filled(this.indent + 2, " ", type$.String), ""), string);
+ },
+ $signature: 7
+ };
+ Z.prettyPrint__prettyPrint_closure0.prototype = {
+ call$1: function(key) {
+ var t1 = this.pp;
+ return H.S(t1.call$1(key)) + ": " + H.S(t1.call$1(this.object.$index(0, key)));
+ },
+ $signature: 40
+ };
+ Z.prettyPrint__prettyPrint_closure1.prototype = {
+ call$1: function(string) {
+ H._checkStringNullable(string);
+ return C.JSString_methods.$add(C.JSArray_methods.join$1(P.List_List$filled(this.indent + 2, " ", type$.String), ""), string);
+ },
+ $signature: 7
+ };
+ M.TypeMatcher.prototype = {
+ describe$1: function(description) {
+ var $name,
+ t1 = H._rtiToString(H.createRuntimeType(H._instanceType(this)._eval$1("TypeMatcher.T"))._rti, null),
+ t2 = $.$get$_dart2DynamicArgs();
+ t1.toString;
+ $name = H.stringReplaceAllUnchecked(t1, t2, "");
+ description._out._contents += "<Instance of '" + $name + "'>";
+ return description;
+ },
+ matches$2: function(_, item, matchState) {
+ return H._instanceType(this)._eval$1("TypeMatcher.T")._is(item);
+ }
+ };
+ M.wrapMatcher_closure.prototype = {
+ call$1: function(a) {
+ return H._checkBoolNullable(this.x.call$1(a));
+ },
+ $signature: 9
+ };
+ M.escape_closure.prototype = {
+ call$1: function(match) {
+ var mapped = C.Map_F9GZw.$index(0, match.$index(0, 0));
+ if (mapped != null)
+ return mapped;
+ return M._getHexLiteral(match.$index(0, 0));
+ },
+ $signature: 24
+ };
+ F.PackageConfigResolver.prototype = {$isSyncPackageResolver: 1,
+ get$packageRoot: function() {
+ return null;
+ },
+ get$packageConfigMap: function() {
+ return this.packageConfigMap;
+ }
+ };
+ F.PackageConfigResolver__normalizeMap_closure.prototype = {
+ call$2: function(_, uri) {
+ return B.ensureTrailingSlash(type$.Uri._check(uri));
+ },
+ $signature: 51
+ };
+ D.PackageRootResolver.prototype = {$isSyncPackageResolver: 1,
+ get$packageConfigMap: function() {
+ return null;
+ },
+ get$packageRoot: function() {
+ return this.packageRoot;
+ }
+ };
+ M.Context.prototype = {
+ absolute$7: function(_, part1, part2, part3, part4, part5, part6, part7) {
+ var t1;
+ M._validateArgList("absolute", H.setRuntimeTypeInfo([part1, part2, part3, part4, part5, part6, part7], type$.JSArray_String));
+ t1 = this.style;
+ t1 = t1.rootLength$1(part1) > 0 && !t1.isRootRelative$1(part1);
+ if (t1)
+ return part1;
+ t1 = this._context$_current;
+ return this.join$8(0, t1 != null ? t1 : D.current(), part1, part2, part3, part4, part5, part6, part7);
+ },
+ absolute$1: function($receiver, part1) {
+ return this.absolute$7($receiver, part1, null, null, null, null, null, null);
+ },
+ join$8: function(_, part1, part2, part3, part4, part5, part6, part7, part8) {
+ var parts = H.setRuntimeTypeInfo([part1, part2, part3, part4, part5, part6, part7, part8], type$.JSArray_String);
+ M._validateArgList("join", parts);
+ return this.joinAll$1(new H.WhereIterable(parts, type$.bool_Function_String._check(new M.Context_join_closure()), type$.WhereIterable_String));
+ },
+ join$2: function($receiver, part1, part2) {
+ return this.join$8($receiver, part1, part2, null, null, null, null, null, null);
+ },
+ joinAll$1: function(parts) {
+ var t1, t2, t3, needsSeparator, isAbsoluteAndNotRootRelative, t4, t5, parsed, path, t6;
+ type$.Iterable_String._check(parts);
+ for (t1 = parts.$ti, t2 = t1._eval$1("bool(Iterable.E)")._check(new M.Context_joinAll_closure()), t3 = parts.get$iterator(parts), t1 = new H.WhereIterator(t3, t2, t1._eval$1("WhereIterator<Iterable.E>")), t2 = this.style, needsSeparator = false, isAbsoluteAndNotRootRelative = false, t4 = ""; t1.moveNext$0();) {
+ t5 = t3.get$current();
+ if (t2.isRootRelative$1(t5) && isAbsoluteAndNotRootRelative) {
+ parsed = X.ParsedPath_ParsedPath$parse(t5, t2);
+ path = t4.charCodeAt(0) == 0 ? t4 : t4;
+ t4 = C.JSString_methods.substring$2(path, 0, t2.rootLength$2$withDrive(path, true));
+ parsed.root = t4;
+ if (t2.needsSeparator$1(t4))
+ C.JSArray_methods.$indexSet(parsed.separators, 0, t2.get$separator());
+ t4 = parsed.toString$0(0);
+ } else if (t2.rootLength$1(t5) > 0) {
+ isAbsoluteAndNotRootRelative = !t2.isRootRelative$1(t5);
+ t4 = H.S(t5);
+ } else {
+ t6 = t5.length;
+ if (t6 !== 0) {
+ if (0 >= t6)
+ return H.ioore(t5, 0);
+ t6 = t2.containsSeparator$1(t5[0]);
+ } else
+ t6 = false;
+ if (!t6)
+ if (needsSeparator)
+ t4 += t2.get$separator();
+ t4 += t5;
+ }
+ needsSeparator = t2.needsSeparator$1(t5);
+ }
+ return t4.charCodeAt(0) == 0 ? t4 : t4;
+ },
+ split$1: function(_, path) {
+ var parsed = X.ParsedPath_ParsedPath$parse(path, this.style),
+ t1 = parsed.parts,
+ t2 = H._arrayInstanceType(t1),
+ t3 = t2._eval$1("WhereIterable<1>");
+ parsed.set$parts(P.List_List$from(new H.WhereIterable(t1, t2._eval$1("bool(1)")._check(new M.Context_split_closure()), t3), true, t3._eval$1("Iterable.E")));
+ t1 = parsed.root;
+ if (t1 != null)
+ C.JSArray_methods.insert$2(parsed.parts, 0, t1);
+ return parsed.parts;
+ },
+ normalize$1: function(path) {
+ var parsed;
+ if (!this._needsNormalization$1(path))
+ return path;
+ parsed = X.ParsedPath_ParsedPath$parse(path, this.style);
+ parsed.normalize$0();
+ return parsed.toString$0(0);
+ },
+ _needsNormalization$1: function(path) {
+ var t1, root, i, start, previous, t2, t3, previousPrevious, codeUnit, t4;
+ path.toString;
+ t1 = this.style;
+ root = t1.rootLength$1(path);
+ if (root !== 0) {
+ if (t1 === $.$get$Style_windows())
+ for (i = 0; i < root; ++i)
+ if (C.JSString_methods._codeUnitAt$1(path, i) === 47)
+ return true;
+ start = root;
+ previous = 47;
+ } else {
+ start = 0;
+ previous = null;
+ }
+ for (t2 = new H.CodeUnits(path)._string, t3 = t2.length, i = start, previousPrevious = null; i < t3; ++i, previousPrevious = previous, previous = codeUnit) {
+ codeUnit = C.JSString_methods.codeUnitAt$1(t2, i);
+ if (t1.isSeparator$1(codeUnit)) {
+ if (t1 === $.$get$Style_windows() && codeUnit === 47)
+ return true;
+ if (previous != null && t1.isSeparator$1(previous))
+ return true;
+ if (previous === 46)
+ t4 = previousPrevious == null || previousPrevious === 46 || t1.isSeparator$1(previousPrevious);
+ else
+ t4 = false;
+ if (t4)
+ return true;
+ }
+ }
+ if (previous == null)
+ return true;
+ if (t1.isSeparator$1(previous))
+ return true;
+ if (previous === 46)
+ t1 = previousPrevious == null || t1.isSeparator$1(previousPrevious) || previousPrevious === 46;
+ else
+ t1 = false;
+ if (t1)
+ return true;
+ return false;
+ },
+ relative$2$from: function(path, from) {
+ var fromParsed, pathParsed, t2, t3, t4, t5, _this = this,
+ _s26_ = 'Unable to find a path to "',
+ t1 = from == null;
+ if (t1 && _this.style.rootLength$1(path) <= 0)
+ return _this.normalize$1(path);
+ if (t1) {
+ t1 = _this._context$_current;
+ from = t1 != null ? t1 : D.current();
+ } else
+ from = _this.absolute$1(0, from);
+ t1 = _this.style;
+ if (t1.rootLength$1(from) <= 0 && t1.rootLength$1(path) > 0)
+ return _this.normalize$1(path);
+ if (t1.rootLength$1(path) <= 0 || t1.isRootRelative$1(path))
+ path = _this.absolute$1(0, path);
+ if (t1.rootLength$1(path) <= 0 && t1.rootLength$1(from) > 0)
+ throw H.wrapException(X.PathException$(_s26_ + H.S(path) + '" from "' + H.S(from) + '".'));
+ fromParsed = X.ParsedPath_ParsedPath$parse(from, t1);
+ fromParsed.normalize$0();
+ pathParsed = X.ParsedPath_ParsedPath$parse(path, t1);
+ pathParsed.normalize$0();
+ t2 = fromParsed.parts;
+ t3 = t2.length;
+ if (t3 !== 0) {
+ if (0 >= t3)
+ return H.ioore(t2, 0);
+ t2 = J.$eq$(t2[0], ".");
+ } else
+ t2 = false;
+ if (t2)
+ return pathParsed.toString$0(0);
+ t2 = fromParsed.root;
+ t3 = pathParsed.root;
+ if (t2 != t3)
+ t2 = t2 == null || t3 == null || !t1.pathsEqual$2(t2, t3);
+ else
+ t2 = false;
+ if (t2)
+ return pathParsed.toString$0(0);
+ while (true) {
+ t2 = fromParsed.parts;
+ t3 = t2.length;
+ if (t3 !== 0) {
+ t4 = pathParsed.parts;
+ t5 = t4.length;
+ if (t5 !== 0) {
+ if (0 >= t3)
+ return H.ioore(t2, 0);
+ t2 = t2[0];
+ if (0 >= t5)
+ return H.ioore(t4, 0);
+ t4 = t1.pathsEqual$2(t2, t4[0]);
+ t2 = t4;
+ } else
+ t2 = false;
+ } else
+ t2 = false;
+ if (!t2)
+ break;
+ C.JSArray_methods.removeAt$1(fromParsed.parts, 0);
+ C.JSArray_methods.removeAt$1(fromParsed.separators, 1);
+ C.JSArray_methods.removeAt$1(pathParsed.parts, 0);
+ C.JSArray_methods.removeAt$1(pathParsed.separators, 1);
+ }
+ t2 = fromParsed.parts;
+ t3 = t2.length;
+ if (t3 !== 0) {
+ if (0 >= t3)
+ return H.ioore(t2, 0);
+ t2 = J.$eq$(t2[0], "..");
+ } else
+ t2 = false;
+ if (t2)
+ throw H.wrapException(X.PathException$(_s26_ + H.S(path) + '" from "' + H.S(from) + '".'));
+ t2 = type$.String;
+ C.JSArray_methods.insertAll$2(pathParsed.parts, 0, P.List_List$filled(fromParsed.parts.length, "..", t2));
+ C.JSArray_methods.$indexSet(pathParsed.separators, 0, "");
+ C.JSArray_methods.insertAll$2(pathParsed.separators, 1, P.List_List$filled(fromParsed.parts.length, t1.get$separator(), t2));
+ t1 = pathParsed.parts;
+ t2 = t1.length;
+ if (t2 === 0)
+ return ".";
+ if (t2 > 1 && J.$eq$(C.JSArray_methods.get$last(t1), ".")) {
+ C.JSArray_methods.removeLast$0(pathParsed.parts);
+ t1 = pathParsed.separators;
+ C.JSArray_methods.removeLast$0(t1);
+ C.JSArray_methods.removeLast$0(t1);
+ C.JSArray_methods.add$1(t1, "");
+ }
+ pathParsed.root = "";
+ pathParsed.removeTrailingSeparators$0();
+ return pathParsed.toString$0(0);
+ },
+ relative$1: function(path) {
+ return this.relative$2$from(path, null);
+ },
+ _isWithinOrEquals$2: function($parent, child) {
+ var relative, childIsRootRelative, parentIsRootRelative, result, exception, _this = this,
+ t1 = _this.style,
+ parentIsAbsolute = t1.rootLength$1(H._checkStringNullable($parent)) > 0,
+ childIsAbsolute = t1.rootLength$1(H._checkStringNullable(child)) > 0;
+ if (parentIsAbsolute && !childIsAbsolute) {
+ child = _this.absolute$1(0, child);
+ if (t1.isRootRelative$1($parent))
+ $parent = _this.absolute$1(0, $parent);
+ } else if (childIsAbsolute && !parentIsAbsolute) {
+ $parent = _this.absolute$1(0, $parent);
+ if (t1.isRootRelative$1(child))
+ child = _this.absolute$1(0, child);
+ } else if (childIsAbsolute && parentIsAbsolute) {
+ childIsRootRelative = t1.isRootRelative$1(child);
+ parentIsRootRelative = t1.isRootRelative$1($parent);
+ if (childIsRootRelative && !parentIsRootRelative)
+ child = _this.absolute$1(0, child);
+ else if (parentIsRootRelative && !childIsRootRelative)
+ $parent = _this.absolute$1(0, $parent);
+ }
+ result = _this._isWithinOrEqualsFast$2($parent, child);
+ if (result !== C._PathRelation_inconclusive)
+ return result;
+ relative = null;
+ try {
+ relative = _this.relative$2$from(child, $parent);
+ } catch (exception) {
+ if (H.unwrapException(exception) instanceof X.PathException)
+ return C._PathRelation_different;
+ else
+ throw exception;
+ }
+ if (t1.rootLength$1(H._checkStringNullable(relative)) > 0)
+ return C._PathRelation_different;
+ if (J.$eq$(relative, "."))
+ return C._PathRelation_equal;
+ if (J.$eq$(relative, ".."))
+ return C._PathRelation_different;
+ return J.get$length$asx(relative) >= 3 && J.startsWith$1$s(relative, "..") && t1.isSeparator$1(J.codeUnitAt$1$s(relative, 2)) ? C._PathRelation_different : C._PathRelation_within;
+ },
+ _isWithinOrEqualsFast$2: function($parent, child) {
+ var t1, parentRootLength, childRootLength, t2, t3, i, childIndex, parentIndex, lastCodeUnit, lastParentSeparator, parentCodeUnit, childCodeUnit, parentIndex0, t4, direction, _this = this;
+ if ($parent === ".")
+ $parent = "";
+ t1 = _this.style;
+ parentRootLength = t1.rootLength$1($parent);
+ childRootLength = t1.rootLength$1(child);
+ if (parentRootLength !== childRootLength)
+ return C._PathRelation_different;
+ for (t2 = J.getInterceptor$s($parent), t3 = J.getInterceptor$s(child), i = 0; i < parentRootLength; ++i)
+ if (!t1.codeUnitsEqual$2(t2._codeUnitAt$1($parent, i), t3._codeUnitAt$1(child, i)))
+ return C._PathRelation_different;
+ t2 = $parent.length;
+ childIndex = childRootLength;
+ parentIndex = parentRootLength;
+ lastCodeUnit = 47;
+ lastParentSeparator = null;
+ while (true) {
+ if (!(parentIndex < t2 && childIndex < child.length))
+ break;
+ c$0: {
+ parentCodeUnit = C.JSString_methods.codeUnitAt$1($parent, parentIndex);
+ childCodeUnit = t3.codeUnitAt$1(child, childIndex);
+ if (t1.codeUnitsEqual$2(parentCodeUnit, childCodeUnit)) {
+ if (t1.isSeparator$1(parentCodeUnit))
+ lastParentSeparator = parentIndex;
+ ++parentIndex;
+ ++childIndex;
+ lastCodeUnit = parentCodeUnit;
+ break c$0;
+ }
+ if (t1.isSeparator$1(parentCodeUnit) && t1.isSeparator$1(lastCodeUnit)) {
+ parentIndex0 = parentIndex + 1;
+ lastParentSeparator = parentIndex;
+ parentIndex = parentIndex0;
+ break c$0;
+ } else if (t1.isSeparator$1(childCodeUnit) && t1.isSeparator$1(lastCodeUnit)) {
+ ++childIndex;
+ break c$0;
+ }
+ if (parentCodeUnit === 46 && t1.isSeparator$1(lastCodeUnit)) {
+ ++parentIndex;
+ if (parentIndex === t2)
+ break;
+ parentCodeUnit = C.JSString_methods.codeUnitAt$1($parent, parentIndex);
+ if (t1.isSeparator$1(parentCodeUnit)) {
+ parentIndex0 = parentIndex + 1;
+ lastParentSeparator = parentIndex;
+ parentIndex = parentIndex0;
+ break c$0;
+ }
+ if (parentCodeUnit === 46) {
+ ++parentIndex;
+ if (parentIndex === t2 || t1.isSeparator$1(C.JSString_methods.codeUnitAt$1($parent, parentIndex)))
+ return C._PathRelation_inconclusive;
+ }
+ }
+ if (childCodeUnit === 46 && t1.isSeparator$1(lastCodeUnit)) {
+ ++childIndex;
+ t4 = child.length;
+ if (childIndex === t4)
+ break;
+ childCodeUnit = C.JSString_methods.codeUnitAt$1(child, childIndex);
+ if (t1.isSeparator$1(childCodeUnit)) {
+ ++childIndex;
+ break c$0;
+ }
+ if (childCodeUnit === 46) {
+ ++childIndex;
+ if (childIndex === t4 || t1.isSeparator$1(C.JSString_methods.codeUnitAt$1(child, childIndex)))
+ return C._PathRelation_inconclusive;
+ }
+ }
+ if (_this._pathDirection$2(child, childIndex) !== C._PathDirection_988)
+ return C._PathRelation_inconclusive;
+ if (_this._pathDirection$2($parent, parentIndex) !== C._PathDirection_988)
+ return C._PathRelation_inconclusive;
+ return C._PathRelation_different;
+ }
+ }
+ if (childIndex === child.length) {
+ if (parentIndex === t2 || t1.isSeparator$1(C.JSString_methods.codeUnitAt$1($parent, parentIndex)))
+ lastParentSeparator = parentIndex;
+ else if (lastParentSeparator == null)
+ lastParentSeparator = Math.max(0, parentRootLength - 1);
+ direction = _this._pathDirection$2($parent, lastParentSeparator);
+ if (direction === C._PathDirection_8Gl)
+ return C._PathRelation_equal;
+ return direction === C._PathDirection_ZGD ? C._PathRelation_inconclusive : C._PathRelation_different;
+ }
+ direction = _this._pathDirection$2(child, childIndex);
+ if (direction === C._PathDirection_8Gl)
+ return C._PathRelation_equal;
+ if (direction === C._PathDirection_ZGD)
+ return C._PathRelation_inconclusive;
+ return t1.isSeparator$1(C.JSString_methods.codeUnitAt$1(child, childIndex)) || t1.isSeparator$1(lastCodeUnit) ? C._PathRelation_within : C._PathRelation_different;
+ },
+ _pathDirection$2: function(path, index) {
+ var t1, t2, i, depth, reachedRoot, i0, t3;
+ for (t1 = path.length, t2 = this.style, i = index, depth = 0, reachedRoot = false; i < t1;) {
+ while (true) {
+ if (!(i < t1 && t2.isSeparator$1(C.JSString_methods.codeUnitAt$1(path, i))))
+ break;
+ ++i;
+ }
+ if (i === t1)
+ break;
+ i0 = i;
+ while (true) {
+ if (!(i0 < t1 && !t2.isSeparator$1(C.JSString_methods.codeUnitAt$1(path, i0))))
+ break;
+ ++i0;
+ }
+ t3 = i0 - i;
+ if (!(t3 === 1 && C.JSString_methods.codeUnitAt$1(path, i) === 46))
+ if (t3 === 2 && C.JSString_methods.codeUnitAt$1(path, i) === 46 && C.JSString_methods.codeUnitAt$1(path, i + 1) === 46) {
+ --depth;
+ if (depth < 0)
+ break;
+ if (depth === 0)
+ reachedRoot = true;
+ } else
+ ++depth;
+ if (i0 === t1)
+ break;
+ i = i0 + 1;
+ }
+ if (depth < 0)
+ return C._PathDirection_ZGD;
+ if (depth === 0)
+ return C._PathDirection_8Gl;
+ if (reachedRoot)
+ return C._PathDirection_FIw;
+ return C._PathDirection_988;
+ },
+ toUri$1: function(path) {
+ var t2,
+ t1 = this.style;
+ if (t1.rootLength$1(path) <= 0)
+ return t1.relativePathToUri$1(path);
+ else {
+ t2 = this._context$_current;
+ return t1.absolutePathToUri$1(this.join$2(0, t2 != null ? t2 : D.current(), path));
+ }
+ },
+ prettyUri$1: function(uri) {
+ var path, rel, _this = this,
+ typedUri = M._parseUri(uri);
+ if (typedUri.get$scheme() === "file" && _this.style == $.$get$Style_url())
+ return typedUri.toString$0(0);
+ else if (typedUri.get$scheme() !== "file" && typedUri.get$scheme() !== "" && _this.style != $.$get$Style_url())
+ return typedUri.toString$0(0);
+ path = _this.normalize$1(_this.style.pathFromUri$1(M._parseUri(typedUri)));
+ rel = _this.relative$1(path);
+ return _this.split$1(0, rel).length > _this.split$1(0, path).length ? path : rel;
+ }
+ };
+ M.Context_join_closure.prototype = {
+ call$1: function(part) {
+ return H._checkStringNullable(part) != null;
+ },
+ $signature: 4
+ };
+ M.Context_joinAll_closure.prototype = {
+ call$1: function(part) {
+ return H._checkStringNullable(part) !== "";
+ },
+ $signature: 4
+ };
+ M.Context_split_closure.prototype = {
+ call$1: function(part) {
+ return H._checkStringNullable(part).length !== 0;
+ },
+ $signature: 4
+ };
+ M._validateArgList_closure.prototype = {
+ call$1: function(arg) {
+ H._checkStringNullable(arg);
+ return arg == null ? "null" : '"' + arg + '"';
+ },
+ $signature: 7
+ };
+ M._PathDirection.prototype = {
+ toString$0: function(_) {
+ return this.name;
+ }
+ };
+ M._PathRelation.prototype = {
+ toString$0: function(_) {
+ return this.name;
+ }
+ };
+ B.InternalStyle.prototype = {
+ getRoot$1: function(path) {
+ var t1,
+ $length = this.rootLength$1(path);
+ if ($length > 0)
+ return J.substring$2$s(path, 0, $length);
+ if (this.isRootRelative$1(path)) {
+ if (0 >= path.length)
+ return H.ioore(path, 0);
+ t1 = path[0];
+ } else
+ t1 = null;
+ return t1;
+ },
+ relativePathToUri$1: function(path) {
+ var segments = M.Context_Context(this).split$1(0, path);
+ if (this.isSeparator$1(J.codeUnitAt$1$s(path, path.length - 1)))
+ C.JSArray_methods.add$1(segments, "");
+ return P._Uri__Uri(null, null, segments, null);
+ },
+ codeUnitsEqual$2: function(codeUnit1, codeUnit2) {
+ return codeUnit1 === codeUnit2;
+ },
+ pathsEqual$2: function(path1, path2) {
+ return path1 == path2;
+ }
+ };
+ X.ParsedPath.prototype = {
+ get$hasTrailingSeparator: function() {
+ var t1 = this.parts;
+ if (t1.length !== 0)
+ t1 = J.$eq$(C.JSArray_methods.get$last(t1), "") || !J.$eq$(C.JSArray_methods.get$last(this.separators), "");
+ else
+ t1 = false;
+ return t1;
+ },
+ removeTrailingSeparators$0: function() {
+ var t1, t2, _this = this;
+ while (true) {
+ t1 = _this.parts;
+ if (!(t1.length !== 0 && J.$eq$(C.JSArray_methods.get$last(t1), "")))
+ break;
+ C.JSArray_methods.removeLast$0(_this.parts);
+ C.JSArray_methods.removeLast$0(_this.separators);
+ }
+ t1 = _this.separators;
+ t2 = t1.length;
+ if (t2 !== 0)
+ C.JSArray_methods.$indexSet(t1, t2 - 1, "");
+ },
+ normalize$0: function() {
+ var t1, t2, leadingDoubles, _i, part, t3, newSeparators, _this = this,
+ newParts = H.setRuntimeTypeInfo([], type$.JSArray_String);
+ for (t1 = _this.parts, t2 = t1.length, leadingDoubles = 0, _i = 0; _i < t1.length; t1.length === t2 || (0, H.throwConcurrentModificationError)(t1), ++_i) {
+ part = t1[_i];
+ t3 = J.getInterceptor$(part);
+ if (!(t3.$eq(part, ".") || t3.$eq(part, "")))
+ if (t3.$eq(part, "..")) {
+ t3 = newParts.length;
+ if (t3 !== 0) {
+ if (0 >= t3)
+ return H.ioore(newParts, -1);
+ newParts.pop();
+ } else
+ ++leadingDoubles;
+ } else
+ C.JSArray_methods.add$1(newParts, part);
+ }
+ if (_this.root == null)
+ C.JSArray_methods.insertAll$2(newParts, 0, P.List_List$filled(leadingDoubles, "..", type$.String));
+ if (newParts.length === 0 && _this.root == null)
+ C.JSArray_methods.add$1(newParts, ".");
+ newSeparators = P.List_List$generate(newParts.length, new X.ParsedPath_normalize_closure(_this), true, type$.String);
+ t1 = _this.root;
+ C.JSArray_methods.insert$2(newSeparators, 0, t1 != null && newParts.length !== 0 && _this.style.needsSeparator$1(t1) ? _this.style.get$separator() : "");
+ _this.set$parts(newParts);
+ _this.set$separators(newSeparators);
+ t1 = _this.root;
+ if (t1 != null && _this.style === $.$get$Style_windows()) {
+ t1.toString;
+ _this.root = H.stringReplaceAllUnchecked(t1, "/", "\\");
+ }
+ _this.removeTrailingSeparators$0();
+ },
+ toString$0: function(_) {
+ var i, t2, _this = this,
+ t1 = _this.root;
+ t1 = t1 != null ? t1 : "";
+ for (i = 0; i < _this.parts.length; ++i) {
+ t2 = _this.separators;
+ if (i >= t2.length)
+ return H.ioore(t2, i);
+ t2 = t1 + H.S(t2[i]);
+ t1 = _this.parts;
+ if (i >= t1.length)
+ return H.ioore(t1, i);
+ t1 = t2 + H.S(t1[i]);
+ }
+ t1 += H.S(C.JSArray_methods.get$last(_this.separators));
+ return t1.charCodeAt(0) == 0 ? t1 : t1;
+ },
+ set$parts: function(parts) {
+ this.parts = type$.List_String._check(parts);
+ },
+ set$separators: function(separators) {
+ this.separators = type$.List_String._check(separators);
+ }
+ };
+ X.ParsedPath_normalize_closure.prototype = {
+ call$1: function(_) {
+ return this.$this.style.get$separator();
+ },
+ $signature: 25
+ };
+ X.PathException.prototype = {
+ toString$0: function(_) {
+ return "PathException: " + this.message;
+ },
+ $isException: 1,
+ get$message: function(receiver) {
+ return this.message;
+ }
+ };
+ O.Style.prototype = {
+ toString$0: function(_) {
+ return this.get$name(this);
+ }
+ };
+ E.PosixStyle.prototype = {
+ containsSeparator$1: function(path) {
+ return C.JSString_methods.contains$1(path, "/");
+ },
+ isSeparator$1: function(codeUnit) {
+ return codeUnit === 47;
+ },
+ needsSeparator$1: function(path) {
+ var t1 = path.length;
+ return t1 !== 0 && C.JSString_methods.codeUnitAt$1(path, t1 - 1) !== 47;
+ },
+ rootLength$2$withDrive: function(path, withDrive) {
+ if (path.length !== 0 && C.JSString_methods._codeUnitAt$1(path, 0) === 47)
+ return 1;
+ return 0;
+ },
+ rootLength$1: function(path) {
+ return this.rootLength$2$withDrive(path, false);
+ },
+ isRootRelative$1: function(path) {
+ return false;
+ },
+ pathFromUri$1: function(uri) {
+ var t1;
+ if (uri.get$scheme() === "" || uri.get$scheme() === "file") {
+ t1 = uri.get$path(uri);
+ return P._Uri__uriDecode(t1, 0, t1.length, C.C_Utf8Codec, false);
+ }
+ throw H.wrapException(P.ArgumentError$("Uri " + uri.toString$0(0) + " must have scheme 'file:'."));
+ },
+ absolutePathToUri$1: function(path) {
+ var parsed = X.ParsedPath_ParsedPath$parse(path, this),
+ t1 = parsed.parts;
+ if (t1.length === 0)
+ C.JSArray_methods.addAll$1(t1, H.setRuntimeTypeInfo(["", ""], type$.JSArray_String));
+ else if (parsed.get$hasTrailingSeparator())
+ C.JSArray_methods.add$1(parsed.parts, "");
+ return P._Uri__Uri(null, null, parsed.parts, "file");
+ },
+ get$name: function() {
+ return "posix";
+ },
+ get$separator: function() {
+ return "/";
+ }
+ };
+ F.UrlStyle.prototype = {
+ containsSeparator$1: function(path) {
+ return C.JSString_methods.contains$1(path, "/");
+ },
+ isSeparator$1: function(codeUnit) {
+ return codeUnit === 47;
+ },
+ needsSeparator$1: function(path) {
+ var t1 = path.length;
+ if (t1 === 0)
+ return false;
+ if (C.JSString_methods.codeUnitAt$1(path, t1 - 1) !== 47)
+ return true;
+ return C.JSString_methods.endsWith$1(path, "://") && this.rootLength$1(path) === t1;
+ },
+ rootLength$2$withDrive: function(path, withDrive) {
+ var i, codeUnit, index, t2,
+ t1 = path.length;
+ if (t1 === 0)
+ return 0;
+ if (C.JSString_methods._codeUnitAt$1(path, 0) === 47)
+ return 1;
+ for (i = 0; i < t1; ++i) {
+ codeUnit = C.JSString_methods._codeUnitAt$1(path, i);
+ if (codeUnit === 47)
+ return 0;
+ if (codeUnit === 58) {
+ if (i === 0)
+ return 0;
+ index = C.JSString_methods.indexOf$2(path, "/", C.JSString_methods.startsWith$2(path, "//", i + 1) ? i + 3 : i);
+ if (index <= 0)
+ return t1;
+ if (!withDrive || t1 < index + 3)
+ return index;
+ if (!C.JSString_methods.startsWith$1(path, "file://"))
+ return index;
+ if (!B.isDriveLetter(path, index + 1))
+ return index;
+ t2 = index + 3;
+ return t1 === t2 ? t2 : index + 4;
+ }
+ }
+ return 0;
+ },
+ rootLength$1: function(path) {
+ return this.rootLength$2$withDrive(path, false);
+ },
+ isRootRelative$1: function(path) {
+ return path.length !== 0 && C.JSString_methods._codeUnitAt$1(path, 0) === 47;
+ },
+ pathFromUri$1: function(uri) {
+ return J.toString$0$(uri);
+ },
+ relativePathToUri$1: function(path) {
+ return P.Uri_parse(path);
+ },
+ absolutePathToUri$1: function(path) {
+ return P.Uri_parse(path);
+ },
+ get$name: function() {
+ return "url";
+ },
+ get$separator: function() {
+ return "/";
+ }
+ };
+ L.WindowsStyle.prototype = {
+ containsSeparator$1: function(path) {
+ return C.JSString_methods.contains$1(path, "/");
+ },
+ isSeparator$1: function(codeUnit) {
+ return codeUnit === 47 || codeUnit === 92;
+ },
+ needsSeparator$1: function(path) {
+ var t1 = path.length;
+ if (t1 === 0)
+ return false;
+ t1 = C.JSString_methods.codeUnitAt$1(path, t1 - 1);
+ return !(t1 === 47 || t1 === 92);
+ },
+ rootLength$2$withDrive: function(path, withDrive) {
+ var t2, index,
+ t1 = path.length;
+ if (t1 === 0)
+ return 0;
+ t2 = C.JSString_methods._codeUnitAt$1(path, 0);
+ if (t2 === 47)
+ return 1;
+ if (t2 === 92) {
+ if (t1 < 2 || C.JSString_methods._codeUnitAt$1(path, 1) !== 92)
+ return 1;
+ index = C.JSString_methods.indexOf$2(path, "\\", 2);
+ if (index > 0) {
+ index = C.JSString_methods.indexOf$2(path, "\\", index + 1);
+ if (index > 0)
+ return index;
+ }
+ return t1;
+ }
+ if (t1 < 3)
+ return 0;
+ if (!B.isAlphabetic(t2))
+ return 0;
+ if (C.JSString_methods._codeUnitAt$1(path, 1) !== 58)
+ return 0;
+ t1 = C.JSString_methods._codeUnitAt$1(path, 2);
+ if (!(t1 === 47 || t1 === 92))
+ return 0;
+ return 3;
+ },
+ rootLength$1: function(path) {
+ return this.rootLength$2$withDrive(path, false);
+ },
+ isRootRelative$1: function(path) {
+ return this.rootLength$1(path) === 1;
+ },
+ pathFromUri$1: function(uri) {
+ var path, t1;
+ if (uri.get$scheme() !== "" && uri.get$scheme() !== "file")
+ throw H.wrapException(P.ArgumentError$("Uri " + uri.toString$0(0) + " must have scheme 'file:'."));
+ path = uri.get$path(uri);
+ if (uri.get$host(uri) === "") {
+ if (path.length >= 3 && C.JSString_methods.startsWith$1(path, "/") && B.isDriveLetter(path, 1))
+ path = C.JSString_methods.replaceFirst$2(path, "/", "");
+ } else
+ path = "\\\\" + H.S(uri.get$host(uri)) + path;
+ t1 = H.stringReplaceAllUnchecked(path, "/", "\\");
+ return P._Uri__uriDecode(t1, 0, t1.length, C.C_Utf8Codec, false);
+ },
+ absolutePathToUri$1: function(path) {
+ var rootParts, t2,
+ parsed = X.ParsedPath_ParsedPath$parse(path, this),
+ t1 = parsed.root;
+ if (J.startsWith$1$s(t1, "\\\\")) {
+ rootParts = new H.WhereIterable(H.setRuntimeTypeInfo(t1.split("\\"), type$.JSArray_String), type$.bool_Function_String._check(new L.WindowsStyle_absolutePathToUri_closure()), type$.WhereIterable_String);
+ C.JSArray_methods.insert$2(parsed.parts, 0, rootParts.get$last(rootParts));
+ if (parsed.get$hasTrailingSeparator())
+ C.JSArray_methods.add$1(parsed.parts, "");
+ return P._Uri__Uri(rootParts.get$first(rootParts), null, parsed.parts, "file");
+ } else {
+ if (parsed.parts.length === 0 || parsed.get$hasTrailingSeparator())
+ C.JSArray_methods.add$1(parsed.parts, "");
+ t1 = parsed.parts;
+ t2 = parsed.root;
+ t2.toString;
+ t2 = H.stringReplaceAllUnchecked(t2, "/", "");
+ C.JSArray_methods.insert$2(t1, 0, H.stringReplaceAllUnchecked(t2, "\\", ""));
+ return P._Uri__Uri(null, null, parsed.parts, "file");
+ }
+ },
+ codeUnitsEqual$2: function(codeUnit1, codeUnit2) {
+ var upperCase1;
+ if (codeUnit1 === codeUnit2)
+ return true;
+ if (codeUnit1 === 47)
+ return codeUnit2 === 92;
+ if (codeUnit1 === 92)
+ return codeUnit2 === 47;
+ if ((codeUnit1 ^ codeUnit2) !== 32)
+ return false;
+ upperCase1 = codeUnit1 | 32;
+ return upperCase1 >= 97 && upperCase1 <= 122;
+ },
+ pathsEqual$2: function(path1, path2) {
+ var t1, t2, i;
+ if (path1 == path2)
+ return true;
+ t1 = path1.length;
+ if (t1 !== path2.length)
+ return false;
+ for (t2 = J.getInterceptor$s(path2), i = 0; i < t1; ++i)
+ if (!this.codeUnitsEqual$2(C.JSString_methods._codeUnitAt$1(path1, i), t2._codeUnitAt$1(path2, i)))
+ return false;
+ return true;
+ },
+ get$name: function() {
+ return "windows";
+ },
+ get$separator: function() {
+ return "\\";
+ }
+ };
+ L.WindowsStyle_absolutePathToUri_closure.prototype = {
+ call$1: function(part) {
+ return H._checkStringNullable(part) !== "";
+ },
+ $signature: 4
+ };
+ O.Pool.prototype = {
+ request$0: function(_) {
+ var t1, t2, _this = this;
+ if (_this._pool$_closeMemo._async_memoizer$_completer.future._state !== 0)
+ throw H.wrapException(P.StateError$("request() may not be called on a closed Pool."));
+ t1 = _this._allocatedResources;
+ if (t1 < _this._maxAllocatedResources) {
+ _this._allocatedResources = t1 + 1;
+ t1 = new P._Future($.Zone__current, type$._Future_PoolResource);
+ t1._asyncComplete$1(new O.PoolResource(_this));
+ return t1;
+ } else {
+ t1 = _this._onReleaseCallbacks;
+ if (!t1.get$isEmpty(t1))
+ return _this._runOnRelease$1(t1.removeFirst$0());
+ else {
+ t1 = new P._Future($.Zone__current, type$._Future_PoolResource);
+ t2 = _this._requestedResources;
+ t2._collection$_add$1(t2.$ti._precomputed1._check(new P._AsyncCompleter(t1, type$._AsyncCompleter_PoolResource)));
+ _this._resetTimer$0();
+ return t1;
+ }
+ }
+ },
+ withResource$1$1: function(callback, $T) {
+ $T._eval$1("0/()")._check(callback);
+ return this.withResource$body$Pool(callback, $T, $T);
+ },
+ withResource$body$Pool: function(callback, $T, $async$type) {
+ var $async$goto = 0,
+ $async$completer = P._makeAsyncAwaitCompleter($async$type),
+ $async$returnValue, $async$handler = 2, $async$currentError, $async$next = [], $async$self = this, resource, t1;
+ var $async$withResource$1$1 = P._wrapJsFunctionForAsync(function($async$errorCode, $async$result) {
+ if ($async$errorCode === 1) {
+ $async$currentError = $async$result;
+ $async$goto = $async$handler;
+ }
+ while (true)
+ switch ($async$goto) {
+ case 0:
+ // Function start
+ if ($async$self._pool$_closeMemo._async_memoizer$_completer.future._state !== 0)
+ throw H.wrapException(P.StateError$("withResource() may not be called on a closed Pool."));
+ $async$goto = 3;
+ return P._asyncAwait($async$self.request$0(0), $async$withResource$1$1);
+ case 3:
+ // returning from await.
+ resource = $async$result;
+ $async$handler = 4;
+ $async$goto = 7;
+ return P._asyncAwait(callback.call$0(), $async$withResource$1$1);
+ case 7:
+ // returning from await.
+ t1 = $async$result;
+ $async$returnValue = t1;
+ $async$next = [1];
+ // goto finally
+ $async$goto = 5;
+ break;
+ $async$next.push(6);
+ // goto finally
+ $async$goto = 5;
+ break;
+ case 4:
+ // uncaught
+ $async$next = [2];
+ case 5:
+ // finally
+ $async$handler = 2;
+ resource.release$0();
+ // goto the next finally handler
+ $async$goto = $async$next.pop();
+ break;
+ case 6:
+ // after finally
+ case 1:
+ // return
+ return P._asyncReturn($async$returnValue, $async$completer);
+ case 2:
+ // rethrow
+ return P._asyncRethrow($async$currentError, $async$completer);
+ }
+ });
+ return P._asyncStartSync($async$withResource$1$1, $async$completer);
+ },
+ close$0: function(_) {
+ return this._pool$_closeMemo.runOnce$1(new O.Pool_close_closure(this));
+ },
+ _onResourceReleaseAllowed$1: function(onRelease) {
+ var t1, zone, t2, _this = this;
+ type$.dynamic_Function._check(onRelease);
+ _this._resetTimer$0();
+ t1 = _this._requestedResources;
+ if (!t1.get$isEmpty(t1))
+ t1.removeFirst$0().complete$1(_this._runOnRelease$1(onRelease));
+ else {
+ t1 = type$.dynamic;
+ if (_this._pool$_closeMemo._async_memoizer$_completer.future._state !== 0) {
+ _this._closeGroup.add$1(0, P.Future_Future$sync(onRelease, t1));
+ if (--_this._allocatedResources === 0)
+ _this._closeGroup.close$0(0);
+ } else {
+ zone = $.Zone__current;
+ t2 = _this._onReleaseCallbacks;
+ t2._collection$_add$1(t2.$ti._precomputed1._check(new O.Pool__onResourceReleaseAllowed_closure(zone, zone.registerCallback$1$1(onRelease, t1))));
+ }
+ }
+ },
+ _runOnRelease$1: function(onRelease) {
+ var t1, t2;
+ P.Future_Future$sync(type$.dynamic_Function._check(onRelease), type$.dynamic).then$1$1(new O.Pool__runOnRelease_closure(this), type$.Null).catchError$1(new O.Pool__runOnRelease_closure0(this));
+ t1 = new P._Future($.Zone__current, type$._Future_PoolResource);
+ t2 = this._onReleaseCompleters;
+ t2._collection$_add$1(t2.$ti._precomputed1._check(new P._SyncCompleter(t1, type$._SyncCompleter_PoolResource)));
+ return t1;
+ },
+ _resetTimer$0: function() {
+ var t2,
+ t1 = this._timer;
+ if (t1 == null)
+ return;
+ t2 = this._requestedResources;
+ if (t2._head === t2._tail)
+ t1._restartable_timer$_timer.cancel$0();
+ else {
+ t1._restartable_timer$_timer.cancel$0();
+ t1._restartable_timer$_timer = P.Timer_Timer(t1._restartable_timer$_duration, t1._callback);
+ }
+ }
+ };
+ O.Pool_close_closure.prototype = {
+ call$0: function() {
+ var t3, t4, callback,
+ t1 = this.$this,
+ t2 = t1._closeGroup;
+ if (t2 != null)
+ return t2._future_group$_completer.future;
+ t1._resetTimer$0();
+ t1._closeGroup = new F.FutureGroup(new P._AsyncCompleter(new P._Future($.Zone__current, type$._Future_List_dynamic), type$._AsyncCompleter_List_dynamic), H.setRuntimeTypeInfo([], type$.JSArray_dynamic), type$.FutureGroup_dynamic);
+ for (t2 = t1._onReleaseCallbacks, t3 = P._ListQueueIterator$(t2, t2.$ti._precomputed1), t4 = type$.dynamic; t3.moveNext$0();) {
+ callback = t3._collection$_current;
+ t1._closeGroup.add$1(0, P.Future_Future$sync(callback, t4));
+ }
+ t1._allocatedResources = t1._allocatedResources - t2.get$length(t2);
+ t2.clear$0(0);
+ if (t1._allocatedResources === 0)
+ t1._closeGroup.close$0(0);
+ return t1._closeGroup._future_group$_completer.future;
+ },
+ $signature: 50
+ };
+ O.Pool__onResourceReleaseAllowed_closure.prototype = {
+ call$0: function() {
+ return this.zone.run$1$1(this.registered, type$.void);
+ },
+ $signature: 1
+ };
+ O.Pool__runOnRelease_closure.prototype = {
+ call$1: function(value) {
+ var t1 = this.$this;
+ t1._onReleaseCompleters.removeFirst$0().complete$1(new O.PoolResource(t1));
+ },
+ $signature: 3
+ };
+ O.Pool__runOnRelease_closure0.prototype = {
+ call$2: function(error, stackTrace) {
+ type$.StackTrace._check(stackTrace);
+ this.$this._onReleaseCompleters.removeFirst$0().completeError$2(error, stackTrace);
+ },
+ $signature: 5
+ };
+ O.PoolResource.prototype = {
+ release$0: function() {
+ var t1, t2;
+ if (this._released)
+ throw H.wrapException(P.StateError$("A PoolResource may only be released once."));
+ this._released = true;
+ t1 = this._pool;
+ t1._resetTimer$0();
+ t2 = t1._requestedResources;
+ if (!t2.get$isEmpty(t2))
+ t2.removeFirst$0().complete$1(new O.PoolResource(t1));
+ else {
+ t2 = --t1._allocatedResources;
+ if (t1._pool$_closeMemo._async_memoizer$_completer.future._state !== 0 && t2 === 0)
+ t1._closeGroup.close$0(0);
+ }
+ }
+ };
+ O.mapStackTrace_closure.prototype = {
+ call$1: function(trace) {
+ var _this = this;
+ return Y.Trace_Trace$from(O.mapStackTrace(_this.sourceMap, type$.Trace._check(trace), _this.minified, _this._box_0.packageResolver, _this.sdkRoot));
+ },
+ $signature: 45
+ };
+ O.mapStackTrace_closure0.prototype = {
+ call$1: function(frame) {
+ var column, t1, t2, span, sourceUrl, t3, packageUrl, t4, _this = this;
+ type$.Frame._check(frame);
+ if (frame.get$line() == null)
+ return null;
+ column = frame.get$column() == null ? 0 : frame.get$column();
+ t1 = frame.get$line();
+ if (typeof t1 !== "number")
+ return t1.$sub();
+ if (typeof column !== "number")
+ return column.$sub();
+ t2 = frame.get$uri();
+ t2 = t2 == null ? null : t2.toString$0(0);
+ span = _this.sourceMap.spanFor$3$uri(t1 - 1, column - 1, t2);
+ if (span == null)
+ return null;
+ sourceUrl = J.toString$0$(span.get$sourceUrl());
+ if (_this.sdkRoot != null && $.$get$url()._isWithinOrEquals$2(_this.sdkLib, sourceUrl) === C._PathRelation_within)
+ sourceUrl = C.JSString_methods.$add("dart:", $.$get$url().relative$2$from(sourceUrl, _this.sdkLib));
+ else {
+ t1 = _this._box_0;
+ t2 = t1.packageResolver;
+ if (t2 != null)
+ if (t2.get$packageRoot() != null && $.$get$url()._isWithinOrEquals$2(J.toString$0$(t1.packageResolver.get$packageRoot()), sourceUrl) === C._PathRelation_within)
+ sourceUrl = C.JSString_methods.$add("package:", $.$get$url().relative$2$from(sourceUrl, J.toString$0$(t1.packageResolver.get$packageRoot())));
+ else if (t1.packageResolver.get$packageConfigMap() != null)
+ for (t2 = t1.packageResolver.get$packageConfigMap()._map.get$keys(), t2 = t2.get$iterator(t2); t2.moveNext$0();) {
+ t3 = t2.get$current();
+ packageUrl = J.toString$0$(t1.packageResolver.get$packageConfigMap()._map.$index(0, t3));
+ t4 = $.$get$url();
+ if (t4._isWithinOrEquals$2(packageUrl, sourceUrl) !== C._PathRelation_within)
+ continue;
+ sourceUrl = C.JSString_methods.$add("package:" + H.S(t3) + "/", t4.relative$2$from(sourceUrl, packageUrl));
+ break;
+ }
+ }
+ t1 = P.Uri_parse(sourceUrl);
+ t2 = span.get$start().get$line();
+ if (typeof t2 !== "number")
+ return t2.$add();
+ t3 = span.get$start().get$column();
+ if (_this.minified)
+ t4 = span.get$isIdentifier() ? span.get$text() : frame.get$member();
+ else
+ t4 = O._prettifyMember(frame.get$member());
+ return new A.Frame(t1, t2 + 1, t3 + 1, t4);
+ },
+ $signature: 46
+ };
+ O.mapStackTrace_closure1.prototype = {
+ call$1: function(frame) {
+ return type$.Frame._check(frame) != null;
+ },
+ $signature: 21
+ };
+ O._prettifyMember_closure.prototype = {
+ call$1: function(match) {
+ return C.JSString_methods.$mul(".<fn>", match.$index(0, 1).length);
+ },
+ $signature: 24
+ };
+ O._prettifyMember_closure0.prototype = {
+ call$1: function(match) {
+ return J.$add$ansx(match.$index(0, 1), ".");
+ },
+ $signature: 24
+ };
+ T.Mapping.prototype = {};
+ T.MultiSectionMapping.prototype = {
+ MultiSectionMapping$fromJson$3$mapUrl: function(sections, otherMaps, mapUrl) {
+ var t1, t2, t3, t4, t5, section, t6, line, column, url, map, _s6_ = "offset", _null = null;
+ for (t1 = J.get$iterator$ax(sections), t2 = this._maps, t3 = type$.Map_dynamic_dynamic, t4 = this._lineStart, t5 = this._columnStart; t1.moveNext$0();) {
+ section = t1.get$current();
+ t6 = J.getInterceptor$asx(section);
+ if (t6.$index(section, _s6_) == null)
+ throw H.wrapException(P.FormatException$("section missing offset", _null, _null));
+ line = J.$index$asx(t6.$index(section, _s6_), "line");
+ if (line == null)
+ throw H.wrapException(P.FormatException$("offset missing line", _null, _null));
+ column = J.$index$asx(t6.$index(section, _s6_), "column");
+ if (column == null)
+ throw H.wrapException(P.FormatException$("offset missing column", _null, _null));
+ C.JSArray_methods.add$1(t4, H._checkIntNullable(line));
+ C.JSArray_methods.add$1(t5, H._checkIntNullable(column));
+ url = t6.$index(section, "url");
+ map = t6.$index(section, "map");
+ t6 = url != null;
+ if (t6 && map != null)
+ throw H.wrapException(P.FormatException$("section can't use both url and map entries", _null, _null));
+ else if (t6) {
+ t6 = P.FormatException$("section contains refers to " + H.S(url) + ', but no map was given for it. Make sure a map is passed in "otherMaps"', _null, _null);
+ throw H.wrapException(t6);
+ } else if (map != null)
+ C.JSArray_methods.add$1(t2, T.parseJson(t3._check(map), mapUrl, otherMaps));
+ else
+ throw H.wrapException(P.FormatException$("section missing url or map", _null, _null));
+ }
+ if (t4.length === 0)
+ throw H.wrapException(P.FormatException$("expected at least one section", _null, _null));
+ },
+ _indexFor$2: function(line, column) {
+ var t1, t2, t3, t4, i, t5;
+ for (t1 = this._lineStart, t2 = t1.length, t3 = this._columnStart, t4 = t3.length, i = 0; i < t2; ++i) {
+ t5 = t1[i];
+ if (line < t5)
+ return i - 1;
+ if (line === t5) {
+ if (i >= t4)
+ return H.ioore(t3, i);
+ t5 = column < t3[i];
+ } else
+ t5 = false;
+ if (t5)
+ return i - 1;
+ }
+ return t2 - 1;
+ },
+ spanFor$4$files$uri: function(line, column, files, uri) {
+ var index, t1, t2, t3, _this = this;
+ type$.Map_String_SourceFile._check(files);
+ index = _this._indexFor$2(line, column);
+ t1 = _this._maps;
+ if (index < 0 || index >= t1.length)
+ return H.ioore(t1, index);
+ t1 = t1[index];
+ t2 = _this._lineStart;
+ if (index >= t2.length)
+ return H.ioore(t2, index);
+ t2 = t2[index];
+ t3 = _this._columnStart;
+ if (index >= t3.length)
+ return H.ioore(t3, index);
+ return t1.spanFor$3$files(line - t2, column - t3[index], files);
+ },
+ spanFor$3$uri: function(line, column, uri) {
+ return this.spanFor$4$files$uri(line, column, null, uri);
+ },
+ spanFor$3$files: function(line, column, files) {
+ return this.spanFor$4$files$uri(line, column, files, null);
+ },
+ toString$0: function(_) {
+ var t2, t3, t4, i, _this = this,
+ t1 = H.getRuntimeType(_this).toString$0(0) + " : [";
+ for (t2 = _this._lineStart, t3 = _this._columnStart, t4 = _this._maps, i = 0; i < t2.length; ++i) {
+ t1 = t1 + "(" + t2[i] + ",";
+ if (i >= t3.length)
+ return H.ioore(t3, i);
+ t1 = t1 + t3[i] + ":";
+ if (i >= t4.length)
+ return H.ioore(t4, i);
+ t1 = t1 + t4[i].toString$0(0) + ")";
+ }
+ t1 += "]";
+ return t1.charCodeAt(0) == 0 ? t1 : t1;
+ }
+ };
+ T.MappingBundle.prototype = {
+ MappingBundle$fromJson$2$mapUrl: function(json, mapUrl) {
+ var t1, t2, t3, t4, t5;
+ for (t1 = J.get$iterator$ax(json), t2 = type$.Map_dynamic_dynamic, t3 = type$.SingleMapping, t4 = this._mappings; t1.moveNext$0();) {
+ t5 = t3._as(T.parseJson(t2._check(t1.get$current()), mapUrl, null));
+ t4.$indexSet(0, t5.targetUrl, t5);
+ }
+ },
+ toString$0: function(_) {
+ var t1, t2;
+ for (t1 = this._mappings.get$values(), t1 = t1.get$iterator(t1), t2 = ""; t1.moveNext$0();)
+ t2 += J.toString$0$(t1.get$current());
+ return t2.charCodeAt(0) == 0 ? t2 : t2;
+ },
+ spanFor$4$files$uri: function(line, column, files, uri) {
+ var separatorCodeUnits, t1, t2, onBoundary, i, candidate, $location;
+ type$.Map_String_SourceFile._check(files);
+ if (uri == null)
+ throw H.wrapException(P.ArgumentError$notNull("uri"));
+ separatorCodeUnits = H.setRuntimeTypeInfo([47, 58], type$.JSArray_int);
+ for (t1 = uri.length, t2 = this._mappings, onBoundary = true, i = 0; i < t1; ++i) {
+ if (onBoundary) {
+ candidate = C.JSString_methods.substring$1(uri, i);
+ if (t2.containsKey$1(candidate))
+ return t2.$index(0, candidate).spanFor$4$files$uri(line, column, files, candidate);
+ }
+ onBoundary = C.JSArray_methods.contains$1(separatorCodeUnits, C.JSString_methods._codeUnitAt$1(uri, i));
+ }
+ $location = V.SourceLocation$(line * 1000000 + column, column, line, P.Uri_parse(uri));
+ t1 = new G.SourceMapSpan(false, $location, $location, "");
+ t1.SourceSpanBase$3($location, $location, "");
+ return t1;
+ },
+ spanFor$3$uri: function(line, column, uri) {
+ return this.spanFor$4$files$uri(line, column, null, uri);
+ }
+ };
+ T.SingleMapping.prototype = {
+ SingleMapping$fromJson$2$mapUrl: function(map, mapUrl) {
+ var t5, source, t6, t7, tokenizer, entries, line, column, srcUrlId, srcLine, srcColumn, srcNameId, _this = this,
+ _s14_ = "sourcesContent",
+ _null = null,
+ sourcesContent = map.$index(0, _s14_) == null ? C.List_empty0 : P.List_List$from(type$.Iterable_dynamic._check(map.$index(0, _s14_)), true, type$.String),
+ t1 = type$.Uri,
+ t2 = _this.files,
+ t3 = _this.urls,
+ t4 = type$.JSArray_int,
+ i = 0;
+ while (true) {
+ t5 = t3.length;
+ if (!(i < t5 && i < sourcesContent.length))
+ break;
+ c$0: {
+ if (i >= sourcesContent.length)
+ return H.ioore(sourcesContent, i);
+ source = sourcesContent[i];
+ if (source == null)
+ break c$0;
+ H._checkStringNullable(source);
+ if (i >= t5)
+ return H.ioore(t3, i);
+ t5 = t3[i];
+ t6 = new H.CodeUnits(source);
+ t7 = H.setRuntimeTypeInfo([0], t4);
+ t7 = new Y.SourceFile(t1._check(typeof t5 == "string" ? P.Uri_parse(t5) : t5), t7, new Uint32Array(H._ensureNativeList(t6.toList$0(t6))));
+ t7.SourceFile$decoded$2$url(t6, t5);
+ C.JSArray_methods.$indexSet(t2, i, t7);
+ }
+ ++i;
+ }
+ t1 = H._checkStringNullable(map.$index(0, "mappings"));
+ t2 = t1.length;
+ tokenizer = new T._MappingTokenizer(t1, t2);
+ t1 = type$.JSArray_TargetEntry;
+ entries = H.setRuntimeTypeInfo([], t1);
+ t4 = _this.names;
+ t5 = t2 - 1;
+ t2 = t2 > 0;
+ t6 = _this.lines;
+ line = 0;
+ column = 0;
+ srcUrlId = 0;
+ srcLine = 0;
+ srcColumn = 0;
+ srcNameId = 0;
+ while (true) {
+ if (!(tokenizer.index < t5 && t2))
+ break;
+ c$1: {
+ if (tokenizer.get$nextKind().isNewLine) {
+ if (entries.length !== 0) {
+ C.JSArray_methods.add$1(t6, new T.TargetLineEntry(line, entries));
+ entries = H.setRuntimeTypeInfo([], t1);
+ }
+ ++line;
+ ++tokenizer.index;
+ column = 0;
+ break c$1;
+ }
+ if (tokenizer.get$nextKind().isNewSegment)
+ throw H.wrapException(_this._segmentError$2(0, line));
+ column += L.decodeVlq(tokenizer);
+ t7 = tokenizer.get$nextKind();
+ if (!(!t7.isNewLine && !t7.isNewSegment && !t7.isEof))
+ C.JSArray_methods.add$1(entries, new T.TargetEntry(column, _null, _null, _null, _null));
+ else {
+ srcUrlId += L.decodeVlq(tokenizer);
+ if (srcUrlId >= t3.length)
+ throw H.wrapException(P.StateError$("Invalid source url id. " + H.S(_this.targetUrl) + ", " + line + ", " + srcUrlId));
+ t7 = tokenizer.get$nextKind();
+ if (!(!t7.isNewLine && !t7.isNewSegment && !t7.isEof))
+ throw H.wrapException(_this._segmentError$2(2, line));
+ srcLine += L.decodeVlq(tokenizer);
+ t7 = tokenizer.get$nextKind();
+ if (!(!t7.isNewLine && !t7.isNewSegment && !t7.isEof))
+ throw H.wrapException(_this._segmentError$2(3, line));
+ srcColumn += L.decodeVlq(tokenizer);
+ t7 = tokenizer.get$nextKind();
+ if (!(!t7.isNewLine && !t7.isNewSegment && !t7.isEof))
+ C.JSArray_methods.add$1(entries, new T.TargetEntry(column, srcUrlId, srcLine, srcColumn, _null));
+ else {
+ srcNameId += L.decodeVlq(tokenizer);
+ if (srcNameId >= t4.length)
+ throw H.wrapException(P.StateError$("Invalid name id: " + H.S(_this.targetUrl) + ", " + line + ", " + srcNameId));
+ C.JSArray_methods.add$1(entries, new T.TargetEntry(column, srcUrlId, srcLine, srcColumn, srcNameId));
+ }
+ }
+ if (tokenizer.get$nextKind().isNewSegment)
+ ++tokenizer.index;
+ }
+ }
+ if (entries.length !== 0)
+ C.JSArray_methods.add$1(t6, new T.TargetLineEntry(line, entries));
+ map.forEach$1(0, new T.SingleMapping$fromJson_closure(_this));
+ },
+ _segmentError$2: function(seen, line) {
+ return new P.StateError("Invalid entry in sourcemap, expected 1, 4, or 5 values, but got " + seen + ".\ntargeturl: " + H.S(this.targetUrl) + ", line: " + line);
+ },
+ _findLine$1: function(line) {
+ var t2,
+ t1 = this.lines,
+ index = O.binarySearch(t1, new T.SingleMapping__findLine_closure(line));
+ if (index <= 0)
+ t1 = null;
+ else {
+ t2 = index - 1;
+ if (t2 >= t1.length)
+ return H.ioore(t1, t2);
+ t2 = t1[t2];
+ t1 = t2;
+ }
+ return t1;
+ },
+ _findColumn$3: function(line, column, lineEntry) {
+ var entries, index, t1;
+ if (lineEntry == null || lineEntry.entries.length === 0)
+ return null;
+ if (lineEntry.line !== line)
+ return C.JSArray_methods.get$last(lineEntry.entries);
+ entries = lineEntry.entries;
+ index = O.binarySearch(entries, new T.SingleMapping__findColumn_closure(column));
+ if (index <= 0)
+ t1 = null;
+ else {
+ t1 = index - 1;
+ if (t1 >= entries.length)
+ return H.ioore(entries, t1);
+ t1 = entries[t1];
+ }
+ return t1;
+ },
+ spanFor$4$files$uri: function(line, column, files, uri) {
+ var entry, url, t1, t2, start, t3, _this = this;
+ type$.Map_String_SourceFile._check(files);
+ entry = _this._findColumn$3(line, column, _this._findLine$1(line));
+ if (entry == null || entry.sourceUrlId == null)
+ return null;
+ url = C.JSArray_methods.$index(_this.urls, entry.sourceUrlId);
+ t1 = _this.sourceRoot;
+ if (t1 != null)
+ url = t1 + H.S(url);
+ t1 = _this._parser$_mapUrl;
+ t1 = t1 == null ? url : t1.resolve$1(url);
+ t2 = entry.sourceLine;
+ start = V.SourceLocation$(0, entry.sourceColumn, t2, t1);
+ t1 = entry.sourceNameId;
+ if (t1 != null) {
+ t2 = _this.names;
+ if (t1 >>> 0 !== t1 || t1 >= t2.length)
+ return H.ioore(t2, t1);
+ t1 = t2[t1];
+ t2 = t1.length;
+ t2 = V.SourceLocation$(start.offset + t2, start.column + t2, start.line, start.sourceUrl);
+ t3 = new G.SourceMapSpan(true, start, t2, t1);
+ t3.SourceSpanBase$3(start, t2, t1);
+ return t3;
+ } else {
+ t1 = new G.SourceMapSpan(false, start, start, "");
+ t1.SourceSpanBase$3(start, start, "");
+ return t1;
+ }
+ },
+ spanFor$3$uri: function(line, column, uri) {
+ return this.spanFor$4$files$uri(line, column, null, uri);
+ },
+ spanFor$3$files: function(line, column, files) {
+ return this.spanFor$4$files$uri(line, column, files, null);
+ },
+ toString$0: function(_) {
+ var _this = this,
+ t1 = H.getRuntimeType(_this).toString$0(0);
+ t1 + " : [";
+ t1 = t1 + " : [targetUrl: " + H.S(_this.targetUrl) + ", sourceRoot: " + H.S(_this.sourceRoot) + ", urls: " + H.S(_this.urls) + ", names: " + H.S(_this.names) + ", lines: " + H.S(_this.lines) + "]";
+ return t1.charCodeAt(0) == 0 ? t1 : t1;
+ }
+ };
+ T.SingleMapping$fromJson_closure.prototype = {
+ call$2: function($name, value) {
+ if (J.startsWith$1$s($name, "x_"))
+ this.$this.extensions.$indexSet(0, H._checkStringNullable($name), value);
+ },
+ $signature: 6
+ };
+ T.SingleMapping__findLine_closure.prototype = {
+ call$1: function(e) {
+ return e.get$line() > this.line;
+ },
+ $signature: 9
+ };
+ T.SingleMapping__findColumn_closure.prototype = {
+ call$1: function(e) {
+ return e.get$column() > this.column;
+ },
+ $signature: 9
+ };
+ T.TargetLineEntry.prototype = {
+ toString$0: function(_) {
+ return H.getRuntimeType(this).toString$0(0) + ": " + this.line + " " + H.S(this.entries);
+ },
+ get$line: function() {
+ return this.line;
+ }
+ };
+ T.TargetEntry.prototype = {
+ toString$0: function(_) {
+ var _this = this;
+ return H.getRuntimeType(_this).toString$0(0) + ": (" + _this.column + ", " + H.S(_this.sourceUrlId) + ", " + H.S(_this.sourceLine) + ", " + H.S(_this.sourceColumn) + ", " + H.S(_this.sourceNameId) + ")";
+ },
+ get$column: function() {
+ return this.column;
+ }
+ };
+ T._MappingTokenizer.prototype = {
+ moveNext$0: function() {
+ return ++this.index < this._parser$_length;
+ },
+ get$current: function() {
+ var t2,
+ t1 = this.index;
+ if (t1 >= 0 && t1 < this._parser$_length) {
+ t2 = this._internal;
+ if (t1 < 0 || t1 >= t2.length)
+ return H.ioore(t2, t1);
+ t1 = t2[t1];
+ } else
+ t1 = null;
+ return t1;
+ },
+ get$hasTokens: function() {
+ var t1 = this._parser$_length;
+ return this.index < t1 - 1 && t1 > 0;
+ },
+ get$nextKind: function() {
+ var t1, t2, next;
+ if (!this.get$hasTokens())
+ return C._TokenKind_false_false_true;
+ t1 = this._internal;
+ t2 = this.index + 1;
+ if (t2 < 0 || t2 >= t1.length)
+ return H.ioore(t1, t2);
+ next = t1[t2];
+ if (next === ";")
+ return C._TokenKind_true_false_false;
+ if (next === ",")
+ return C._TokenKind_false_true_false;
+ return C._TokenKind_false_false_false;
+ },
+ toString$0: function(_) {
+ var t1, i, t2, t3, _this = this;
+ for (t1 = _this._internal, i = 0, t2 = ""; i < _this.index; ++i) {
+ if (i >= t1.length)
+ return H.ioore(t1, i);
+ t2 += t1[i];
+ }
+ t2 += "\x1b[31m";
+ t2 = t2 + H.S(_this.get$current() == null ? "" : _this.get$current()) + "\x1b[0m";
+ for (i = _this.index + 1, t3 = t1.length; i < t3; ++i) {
+ if (i < 0)
+ return H.ioore(t1, i);
+ t2 += t1[i];
+ }
+ t1 = t2 + (" (" + _this.index + ")");
+ return t1.charCodeAt(0) == 0 ? t1 : t1;
+ },
+ $isIterator: 1
+ };
+ T._TokenKind.prototype = {};
+ G.SourceMapSpan.prototype = {
+ get$isIdentifier: function() {
+ return this.isIdentifier;
+ }
+ };
+ L.closure.prototype = {
+ call$0: function() {
+ var i,
+ map = P.LinkedHashMap_LinkedHashMap$_empty(type$.String, type$.int);
+ for (i = 0; i < 64; ++i)
+ map.$indexSet(0, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[i], i);
+ return map;
+ },
+ $signature: 93
+ };
+ Y.SourceFile.prototype = {
+ get$length: function(_) {
+ return this._decodedChars.length;
+ },
+ get$lines: function() {
+ return this._lineStarts.length;
+ },
+ SourceFile$decoded$2$url: function(decodedChars, url) {
+ var t1, t2, t3, i, c, j, t4;
+ for (t1 = this._decodedChars, t2 = t1.length, t3 = this._lineStarts, i = 0; i < t2; ++i) {
+ c = t1[i];
+ if (c === 13) {
+ j = i + 1;
+ if (j < t2) {
+ if (j >= t2)
+ return H.ioore(t1, j);
+ t4 = t1[j] !== 10;
+ } else
+ t4 = true;
+ if (t4)
+ c = 10;
+ }
+ if (c === 10)
+ C.JSArray_methods.add$1(t3, i + 1);
+ }
+ },
+ span$2: function(start, end) {
+ return Y._FileSpan$(this, start, end);
+ },
+ getLine$1: function(offset) {
+ var t1, _this = this;
+ if (offset < 0)
+ throw H.wrapException(P.RangeError$("Offset may not be negative, was " + offset + "."));
+ else if (offset > _this._decodedChars.length)
+ throw H.wrapException(P.RangeError$("Offset " + offset + " must not be greater than the number of characters in the file, " + _this.get$length(_this) + "."));
+ t1 = _this._lineStarts;
+ if (offset < C.JSArray_methods.get$first(t1))
+ return -1;
+ if (offset >= C.JSArray_methods.get$last(t1))
+ return t1.length - 1;
+ if (_this._isNearCachedLine$1(offset))
+ return _this._cachedLine;
+ return _this._cachedLine = _this._binarySearch$1(offset) - 1;
+ },
+ _isNearCachedLine$1: function(offset) {
+ var t2, t3, t4, _this = this,
+ t1 = _this._cachedLine;
+ if (t1 == null)
+ return false;
+ t2 = _this._lineStarts;
+ if (t1 >>> 0 !== t1 || t1 >= t2.length)
+ return H.ioore(t2, t1);
+ if (offset < t2[t1])
+ return false;
+ t1 = _this._cachedLine;
+ t3 = t2.length;
+ if (typeof t1 !== "number")
+ return t1.$ge();
+ if (t1 < t3 - 1) {
+ t4 = t1 + 1;
+ if (t4 < 0 || t4 >= t3)
+ return H.ioore(t2, t4);
+ t4 = offset < t2[t4];
+ } else
+ t4 = true;
+ if (t4)
+ return true;
+ if (t1 < t3 - 2) {
+ t4 = t1 + 2;
+ if (t4 < 0 || t4 >= t3)
+ return H.ioore(t2, t4);
+ t4 = offset < t2[t4];
+ t2 = t4;
+ } else
+ t2 = true;
+ if (t2) {
+ _this._cachedLine = t1 + 1;
+ return true;
+ }
+ return false;
+ },
+ _binarySearch$1: function(offset) {
+ var min, half,
+ t1 = this._lineStarts,
+ t2 = t1.length,
+ max = t2 - 1;
+ for (min = 0; min < max;) {
+ half = min + C.JSInt_methods._tdivFast$1(max - min, 2);
+ if (half < 0 || half >= t2)
+ return H.ioore(t1, half);
+ if (t1[half] > offset)
+ max = half;
+ else
+ min = half + 1;
+ }
+ return max;
+ },
+ getColumn$1: function(offset) {
+ var line, lineStart, _this = this;
+ if (offset < 0)
+ throw H.wrapException(P.RangeError$("Offset may not be negative, was " + offset + "."));
+ else if (offset > _this._decodedChars.length)
+ throw H.wrapException(P.RangeError$("Offset " + offset + " must be not be greater than the number of characters in the file, " + _this.get$length(_this) + "."));
+ line = _this.getLine$1(offset);
+ lineStart = C.JSArray_methods.$index(_this._lineStarts, line);
+ if (lineStart > offset)
+ throw H.wrapException(P.RangeError$("Line " + H.S(line) + " comes after offset " + offset + "."));
+ return offset - lineStart;
+ },
+ getOffset$2: function(line, column) {
+ var t1, t2, result, t3;
+ if (typeof line !== "number")
+ return line.$lt();
+ if (line < 0)
+ throw H.wrapException(P.RangeError$("Line may not be negative, was " + line + "."));
+ else {
+ t1 = this._lineStarts;
+ t2 = t1.length;
+ if (line >= t2)
+ throw H.wrapException(P.RangeError$("Line " + line + " must be less than the number of lines in the file, " + this.get$lines() + "."));
+ }
+ result = t1[line];
+ if (result <= this._decodedChars.length) {
+ t3 = line + 1;
+ t1 = t3 < t2 && result >= t1[t3];
+ } else
+ t1 = true;
+ if (t1)
+ throw H.wrapException(P.RangeError$("Line " + line + " doesn't have 0 columns."));
+ return result;
+ },
+ getOffset$1: function(line) {
+ return this.getOffset$2(line, null);
+ }
+ };
+ Y.FileLocation.prototype = {
+ get$sourceUrl: function() {
+ return this.file.url;
+ },
+ get$line: function() {
+ return this.file.getLine$1(this.offset);
+ },
+ get$column: function() {
+ return this.file.getColumn$1(this.offset);
+ },
+ get$offset: function(receiver) {
+ return this.offset;
+ }
+ };
+ Y._FileSpan.prototype = {
+ get$sourceUrl: function() {
+ return this.file.url;
+ },
+ get$length: function(_) {
+ return this._file$_end - this._file$_start;
+ },
+ get$start: function() {
+ return Y.FileLocation$_(this.file, this._file$_start);
+ },
+ get$end: function() {
+ return Y.FileLocation$_(this.file, this._file$_end);
+ },
+ get$text: function() {
+ return P.String_String$fromCharCodes(C.NativeUint32List_methods.sublist$2(this.file._decodedChars, this._file$_start, this._file$_end), 0, null);
+ },
+ get$context: function() {
+ var t2, _this = this,
+ t1 = _this.file,
+ endOffset = _this._file$_end,
+ endLine = t1.getLine$1(endOffset);
+ if (t1.getColumn$1(endOffset) === 0 && endLine !== 0) {
+ if (endOffset - _this._file$_start === 0) {
+ if (endLine === t1._lineStarts.length - 1)
+ t1 = "";
+ else {
+ t2 = t1.getOffset$1(endLine);
+ if (typeof endLine !== "number")
+ return endLine.$add();
+ t1 = P.String_String$fromCharCodes(C.NativeUint32List_methods.sublist$2(t1._decodedChars, t2, t1.getOffset$1(endLine + 1)), 0, null);
+ }
+ return t1;
+ }
+ } else if (endLine === t1._lineStarts.length - 1)
+ endOffset = t1._decodedChars.length;
+ else {
+ if (typeof endLine !== "number")
+ return endLine.$add();
+ endOffset = t1.getOffset$1(endLine + 1);
+ }
+ return P.String_String$fromCharCodes(C.NativeUint32List_methods.sublist$2(t1._decodedChars, t1.getOffset$1(t1.getLine$1(_this._file$_start)), endOffset), 0, null);
+ },
+ $eq: function(_, other) {
+ var _this = this;
+ if (other == null)
+ return false;
+ if (!type$.FileSpan._is(other))
+ return _this.super$SourceSpanMixin$$eq(0, other);
+ if (!(other instanceof Y._FileSpan))
+ return _this.super$SourceSpanMixin$$eq(0, other) && J.$eq$(_this.file.url, other.get$sourceUrl());
+ return _this._file$_start === other._file$_start && _this._file$_end === other._file$_end && J.$eq$(_this.file.url, other.file.url);
+ },
+ get$hashCode: function(_) {
+ return Y.SourceSpanMixin.prototype.get$hashCode.call(this, this);
+ },
+ expand$1: function(_, other) {
+ var start, _this = this,
+ t1 = _this.file;
+ if (!J.$eq$(t1.url, other.file.url))
+ throw H.wrapException(P.ArgumentError$('Source URLs "' + H.S(_this.get$sourceUrl()) + '" and "' + H.S(other.get$sourceUrl()) + "\" don't match."));
+ start = Math.min(_this._file$_start, other._file$_start);
+ return Y._FileSpan$(t1, start, Math.max(_this._file$_end, other._file$_end));
+ },
+ $isFileSpan: 1,
+ $isSourceSpanWithContext: 1
+ };
+ U.Highlighter.prototype = {
+ highlight$0: function() {
+ var t1, t2, lineStart, context, lines, t3, t4, lineNumber, _i, line, lastLineIndex, _this = this;
+ _this._writeSidebar$1$end($._glyphs.get$downEnd());
+ t1 = _this._highlighter$_buffer;
+ t1._contents += "\n";
+ t2 = _this._span;
+ lineStart = B.findLineStart(t2.get$context(), t2.get$text(), t2.get$start().get$column());
+ H.assertHelper(lineStart != null);
+ context = t2.get$context();
+ if (typeof lineStart !== "number")
+ return lineStart.$gt();
+ if (lineStart > 0) {
+ lines = C.JSString_methods.substring$2(context, 0, lineStart - 1).split("\n");
+ t3 = t2.get$start().get$line();
+ t4 = lines.length;
+ if (typeof t3 !== "number")
+ return t3.$sub();
+ lineNumber = t3 - t4;
+ for (t3 = _this._multiline, _i = 0; _i < t4; ++_i) {
+ line = lines[_i];
+ _this._writeSidebar$1$line(lineNumber);
+ t1._contents += C.JSString_methods.$mul(" ", t3 ? 3 : 1);
+ _this._writeText$1(line);
+ t1._contents += "\n";
+ ++lineNumber;
+ }
+ context = C.JSString_methods.substring$1(context, lineStart);
+ }
+ lines = H.setRuntimeTypeInfo(context.split("\n"), type$.JSArray_String);
+ t3 = t2.get$end().get$line();
+ t2 = t2.get$start().get$line();
+ if (typeof t3 !== "number")
+ return t3.$sub();
+ if (typeof t2 !== "number")
+ return H.iae(t2);
+ lastLineIndex = t3 - t2;
+ t2 = C.JSArray_methods.get$last(lines);
+ t2.toString;
+ if (J.get$length$asx(t2) === 0 && lines.length > lastLineIndex + 1) {
+ if (0 >= lines.length)
+ return H.ioore(lines, -1);
+ lines.pop();
+ }
+ _this._writeFirstLine$1(C.JSArray_methods.get$first(lines));
+ if (_this._multiline) {
+ _this._writeIntermediateLines$1(H.SubListIterable$(lines, 1, null, type$.String).take$1(0, lastLineIndex - 1));
+ if (lastLineIndex < 0 || lastLineIndex >= lines.length)
+ return H.ioore(lines, lastLineIndex);
+ _this._writeLastLine$1(lines[lastLineIndex]);
+ }
+ _this._writeTrailingLines$1(H.SubListIterable$(lines, lastLineIndex + 1, null, type$.String));
+ _this._writeSidebar$1$end($._glyphs.get$upEnd());
+ t1 = t1._contents;
+ return t1.charCodeAt(0) == 0 ? t1 : t1;
+ },
+ _writeFirstLine$1: function(line) {
+ var t3, t4, startColumn, endColumn, textBefore, textInside, tabsBefore, tabsInside, _this = this, t1 = {},
+ t2 = _this._span;
+ _this._writeSidebar$1$line(t2.get$start().get$line());
+ t3 = t2.get$start().get$column();
+ t4 = line.length;
+ startColumn = t1.startColumn = Math.min(t3, t4);
+ t3 = t2.get$end();
+ t3 = t3.get$offset(t3);
+ t2 = t2.get$start();
+ endColumn = t1.endColumn = Math.min(startColumn + t3 - t2.get$offset(t2), t4);
+ textBefore = J.substring$2$s(line, 0, startColumn);
+ t2 = _this._multiline;
+ if (t2 && _this._isOnlyWhitespace$1(textBefore)) {
+ t1 = _this._highlighter$_buffer;
+ t1._contents += " ";
+ _this._colorize$1(new U.Highlighter__writeFirstLine_closure(_this, line));
+ t1._contents += "\n";
+ return;
+ }
+ t3 = _this._highlighter$_buffer;
+ t3._contents += C.JSString_methods.$mul(" ", t2 ? 3 : 1);
+ _this._writeText$1(textBefore);
+ textInside = C.JSString_methods.substring$2(line, startColumn, endColumn);
+ _this._colorize$1(new U.Highlighter__writeFirstLine_closure0(_this, textInside));
+ _this._writeText$1(C.JSString_methods.substring$1(line, endColumn));
+ t3._contents += "\n";
+ tabsBefore = _this._countTabs$1(textBefore);
+ tabsInside = _this._countTabs$1(textInside);
+ startColumn += tabsBefore * 3;
+ t1.startColumn = startColumn;
+ t1.endColumn = endColumn + (tabsBefore + tabsInside) * 3;
+ _this._writeSidebar$0();
+ if (t2) {
+ t3._contents += " ";
+ _this._colorize$1(new U.Highlighter__writeFirstLine_closure1(t1, _this));
+ } else {
+ t3._contents += C.JSString_methods.$mul(" ", startColumn + 1);
+ _this._colorize$1(new U.Highlighter__writeFirstLine_closure2(t1, _this));
+ }
+ t3._contents += "\n";
+ },
+ _writeIntermediateLines$1: function(lines) {
+ var t1, lineNumber, t2, t3, _this = this;
+ type$.Iterable_String._check(lines);
+ H.assertHelper(_this._multiline);
+ t1 = _this._span.get$start().get$line();
+ if (typeof t1 !== "number")
+ return t1.$add();
+ lineNumber = t1 + 1;
+ for (t1 = new H.ListIterator(lines, lines.get$length(lines), lines.$ti._eval$1("ListIterator<ListIterable.E>")), t2 = _this._highlighter$_buffer; t1.moveNext$0();) {
+ t3 = t1.__internal$_current;
+ _this._writeSidebar$1$line(lineNumber);
+ t2._contents += " ";
+ _this._colorize$1(new U.Highlighter__writeIntermediateLines_closure(_this, t3));
+ t2._contents += "\n";
+ ++lineNumber;
+ }
+ },
+ _writeLastLine$1: function(line) {
+ var t3, t4, endColumn, textInside, _this = this, t1 = {},
+ t2 = _this._multiline;
+ H.assertHelper(t2);
+ t3 = _this._span;
+ _this._writeSidebar$1$line(t3.get$end().get$line());
+ t3 = t3.get$end().get$column();
+ t4 = line.length;
+ endColumn = t1.endColumn = Math.min(t3, t4);
+ if (t2 && endColumn === t4) {
+ t1 = _this._highlighter$_buffer;
+ t1._contents += " ";
+ _this._colorize$1(new U.Highlighter__writeLastLine_closure(_this, line));
+ t1._contents += "\n";
+ return;
+ }
+ t2 = _this._highlighter$_buffer;
+ t2._contents += " ";
+ textInside = J.substring$2$s(line, 0, endColumn);
+ _this._colorize$1(new U.Highlighter__writeLastLine_closure0(_this, textInside));
+ _this._writeText$1(C.JSString_methods.substring$1(line, endColumn));
+ t2._contents += "\n";
+ t1.endColumn = endColumn + _this._countTabs$1(textInside) * 3;
+ _this._writeSidebar$0();
+ t2._contents += " ";
+ _this._colorize$1(new U.Highlighter__writeLastLine_closure1(t1, _this));
+ t2._contents += "\n";
+ },
+ _writeTrailingLines$1: function(lines) {
+ var t1, lineNumber, t2, t3, t4, _this = this;
+ type$.Iterable_String._check(lines);
+ t1 = _this._span.get$end().get$line();
+ if (typeof t1 !== "number")
+ return t1.$add();
+ lineNumber = t1 + 1;
+ for (t1 = new H.ListIterator(lines, lines.get$length(lines), lines.$ti._eval$1("ListIterator<ListIterable.E>")), t2 = _this._highlighter$_buffer, t3 = _this._multiline; t1.moveNext$0();) {
+ t4 = t1.__internal$_current;
+ _this._writeSidebar$1$line(lineNumber);
+ t2._contents += C.JSString_methods.$mul(" ", t3 ? 3 : 1);
+ _this._writeText$1(t4);
+ t2._contents += "\n";
+ ++lineNumber;
+ }
+ },
+ _writeText$1: function(text) {
+ var t1, t2, t3;
+ text.toString;
+ t1 = new H.CodeUnits(text);
+ t1 = new H.ListIterator(t1, t1.get$length(t1), type$.CodeUnits._eval$1("ListIterator<ListMixin.E>"));
+ t2 = this._highlighter$_buffer;
+ for (; t1.moveNext$0();) {
+ t3 = t1.__internal$_current;
+ if (t3 === 9)
+ t2._contents += C.JSString_methods.$mul(" ", 4);
+ else
+ t2._contents += H.Primitives_stringFromCharCode(t3);
+ }
+ },
+ _writeSidebar$2$end$line: function(end, line) {
+ this._colorize$2$color(new U.Highlighter__writeSidebar_closure(this, line, end), "\x1b[34m");
+ },
+ _writeSidebar$1$end: function(end) {
+ return this._writeSidebar$2$end$line(end, null);
+ },
+ _writeSidebar$1$line: function(line) {
+ return this._writeSidebar$2$end$line(null, line);
+ },
+ _writeSidebar$0: function() {
+ return this._writeSidebar$2$end$line(null, null);
+ },
+ _countTabs$1: function(text) {
+ var t1, count;
+ for (t1 = new H.CodeUnits(text), t1 = new H.ListIterator(t1, t1.get$length(t1), type$.CodeUnits._eval$1("ListIterator<ListMixin.E>")), count = 0; t1.moveNext$0();)
+ if (t1.__internal$_current === 9)
+ ++count;
+ return count;
+ },
+ _isOnlyWhitespace$1: function(text) {
+ var t1, t2;
+ for (t1 = new H.CodeUnits(text), t1 = new H.ListIterator(t1, t1.get$length(t1), type$.CodeUnits._eval$1("ListIterator<ListMixin.E>")); t1.moveNext$0();) {
+ t2 = t1.__internal$_current;
+ if (t2 !== 32 && t2 !== 9)
+ return false;
+ }
+ return true;
+ },
+ _colorize$2$color: function(callback, color) {
+ var t1, t2;
+ type$.void_Function._check(callback);
+ t1 = this._color;
+ t2 = t1 != null;
+ if (t2) {
+ t1 = color == null ? t1 : color;
+ this._highlighter$_buffer._contents += t1;
+ }
+ callback.call$0();
+ if (t2)
+ this._highlighter$_buffer._contents += "\x1b[0m";
+ },
+ _colorize$1: function(callback) {
+ return this._colorize$2$color(callback, null);
+ }
+ };
+ U.Highlighter__writeFirstLine_closure.prototype = {
+ call$0: function() {
+ var t1 = this.$this,
+ t2 = t1._highlighter$_buffer,
+ t3 = t2._contents += $._glyphs.glyphOrAscii$2("\u250c", "/");
+ t2._contents = t3 + " ";
+ t1._writeText$1(this.line);
+ },
+ $signature: 0
+ };
+ U.Highlighter__writeFirstLine_closure0.prototype = {
+ call$0: function() {
+ return this.$this._writeText$1(this.textInside);
+ },
+ $signature: 1
+ };
+ U.Highlighter__writeFirstLine_closure1.prototype = {
+ call$0: function() {
+ var t2,
+ t1 = this.$this._highlighter$_buffer;
+ t1._contents += $._glyphs.get$topLeftCorner();
+ t2 = t1._contents += C.JSString_methods.$mul($._glyphs.get$horizontalLine(), this._box_0.startColumn + 1);
+ t1._contents = t2 + "^";
+ },
+ $signature: 0
+ };
+ U.Highlighter__writeFirstLine_closure2.prototype = {
+ call$0: function() {
+ var t1 = this._box_0;
+ this.$this._highlighter$_buffer._contents += C.JSString_methods.$mul("^", Math.max(t1.endColumn - t1.startColumn, 1));
+ return null;
+ },
+ $signature: 1
+ };
+ U.Highlighter__writeIntermediateLines_closure.prototype = {
+ call$0: function() {
+ var t1 = this.$this,
+ t2 = t1._highlighter$_buffer,
+ t3 = t2._contents += $._glyphs.get$verticalLine();
+ t2._contents = t3 + " ";
+ t1._writeText$1(this.line);
+ },
+ $signature: 0
+ };
+ U.Highlighter__writeLastLine_closure.prototype = {
+ call$0: function() {
+ var t1 = this.$this,
+ t2 = t1._highlighter$_buffer,
+ t3 = t2._contents += $._glyphs.glyphOrAscii$2("\u2514", "\\");
+ t2._contents = t3 + " ";
+ t1._writeText$1(this.line);
+ },
+ $signature: 0
+ };
+ U.Highlighter__writeLastLine_closure0.prototype = {
+ call$0: function() {
+ var t1 = this.$this,
+ t2 = t1._highlighter$_buffer,
+ t3 = t2._contents += $._glyphs.get$verticalLine();
+ t2._contents = t3 + " ";
+ t1._writeText$1(this.textInside);
+ },
+ $signature: 0
+ };
+ U.Highlighter__writeLastLine_closure1.prototype = {
+ call$0: function() {
+ var t2,
+ t1 = this.$this._highlighter$_buffer;
+ t1._contents += $._glyphs.get$bottomLeftCorner();
+ t2 = t1._contents += C.JSString_methods.$mul($._glyphs.get$horizontalLine(), this._box_0.endColumn);
+ t1._contents = t2 + "^";
+ },
+ $signature: 0
+ };
+ U.Highlighter__writeSidebar_closure.prototype = {
+ call$0: function() {
+ var t1 = this.line,
+ t2 = this.$this,
+ t3 = t2._highlighter$_buffer;
+ t2 = t2._paddingBeforeSidebar;
+ if (t1 != null)
+ t3._contents += C.JSString_methods.padRight$1(C.JSInt_methods.toString$0(t1 + 1), t2);
+ else
+ t3._contents += C.JSString_methods.$mul(" ", t2);
+ t1 = this.end;
+ t3._contents += t1 == null ? $._glyphs.get$verticalLine() : t1;
+ },
+ $signature: 0
+ };
+ V.SourceLocation.prototype = {
+ distance$1: function(other) {
+ var t1 = this.sourceUrl;
+ if (!J.$eq$(t1, other.get$sourceUrl()))
+ throw H.wrapException(P.ArgumentError$('Source URLs "' + H.S(t1) + '" and "' + H.S(other.get$sourceUrl()) + "\" don't match."));
+ return Math.abs(this.offset - other.get$offset(other));
+ },
+ $eq: function(_, other) {
+ if (other == null)
+ return false;
+ return type$.SourceLocation._is(other) && J.$eq$(this.sourceUrl, other.get$sourceUrl()) && this.offset === other.get$offset(other);
+ },
+ get$hashCode: function(_) {
+ return J.get$hashCode$(this.sourceUrl) + this.offset;
+ },
+ toString$0: function(_) {
+ var _this = this,
+ t1 = "<" + H.getRuntimeType(_this).toString$0(0) + ": " + _this.offset + " ",
+ source = _this.sourceUrl;
+ return t1 + (H.S(source == null ? "unknown source" : source) + ":" + (_this.line + 1) + ":" + (_this.column + 1)) + ">";
+ },
+ get$sourceUrl: function() {
+ return this.sourceUrl;
+ },
+ get$offset: function(receiver) {
+ return this.offset;
+ },
+ get$line: function() {
+ return this.line;
+ },
+ get$column: function() {
+ return this.column;
+ }
+ };
+ D.SourceLocationMixin.prototype = {
+ distance$1: function(other) {
+ if (!J.$eq$(this.file.url, other.get$sourceUrl()))
+ throw H.wrapException(P.ArgumentError$('Source URLs "' + H.S(this.get$sourceUrl()) + '" and "' + H.S(other.get$sourceUrl()) + "\" don't match."));
+ return Math.abs(this.offset - other.get$offset(other));
+ },
+ $eq: function(_, other) {
+ if (other == null)
+ return false;
+ return type$.SourceLocation._is(other) && J.$eq$(this.file.url, other.get$sourceUrl()) && this.offset === other.get$offset(other);
+ },
+ get$hashCode: function(_) {
+ return J.get$hashCode$(this.file.url) + this.offset;
+ },
+ toString$0: function(_) {
+ var t1 = this.offset,
+ t2 = "<" + H.getRuntimeType(this).toString$0(0) + ": " + t1 + " ",
+ t3 = this.file,
+ source = t3.url,
+ t4 = H.S(source == null ? "unknown source" : source) + ":",
+ t5 = t3.getLine$1(t1);
+ if (typeof t5 !== "number")
+ return t5.$add();
+ return t2 + (t4 + (t5 + 1) + ":" + (t3.getColumn$1(t1) + 1)) + ">";
+ },
+ $isSourceLocation: 1
+ };
+ V.SourceSpan.prototype = {};
+ V.SourceSpanBase.prototype = {
+ SourceSpanBase$3: function(start, end, text) {
+ var t3,
+ t1 = this.end,
+ t2 = this.start;
+ if (!J.$eq$(t1.get$sourceUrl(), t2.get$sourceUrl()))
+ throw H.wrapException(P.ArgumentError$('Source URLs "' + H.S(t2.get$sourceUrl()) + '" and "' + H.S(t1.get$sourceUrl()) + "\" don't match."));
+ else if (t1.get$offset(t1) < t2.get$offset(t2))
+ throw H.wrapException(P.ArgumentError$("End " + t1.toString$0(0) + " must come after start " + t2.toString$0(0) + "."));
+ else {
+ t3 = this.text;
+ if (t3.length !== t2.distance$1(t1))
+ throw H.wrapException(P.ArgumentError$('Text "' + t3 + '" must be ' + t2.distance$1(t1) + " characters long."));
+ }
+ },
+ get$start: function() {
+ return this.start;
+ },
+ get$end: function() {
+ return this.end;
+ },
+ get$text: function() {
+ return this.text;
+ }
+ };
+ G.SourceSpanException.prototype = {
+ get$message: function(_) {
+ return this._span_exception$_message;
+ },
+ toString$1$color: function(_, color) {
+ var t1 = this._span_exception$_span;
+ if (t1 == null)
+ return this._span_exception$_message;
+ return "Error on " + t1.message$2$color(0, this._span_exception$_message, color);
+ },
+ toString$0: function($receiver) {
+ return this.toString$1$color($receiver, null);
+ },
+ $isException: 1
+ };
+ G.SourceSpanFormatException.prototype = {$isFormatException: 1};
+ Y.SourceSpanMixin.prototype = {
+ get$sourceUrl: function() {
+ return this.get$start().get$sourceUrl();
+ },
+ get$length: function(_) {
+ var t2,
+ t1 = this.get$end();
+ t1 = t1.get$offset(t1);
+ t2 = this.get$start();
+ return t1 - t2.get$offset(t2);
+ },
+ message$2$color: function(_, message, color) {
+ var t2, highlight, _this = this,
+ t1 = _this.get$start().get$line();
+ if (typeof t1 !== "number")
+ return t1.$add();
+ t1 = "line " + (t1 + 1) + ", column " + (_this.get$start().get$column() + 1);
+ if (_this.get$sourceUrl() != null) {
+ t2 = _this.get$sourceUrl();
+ t2 = t1 + (" of " + H.S($.$get$context().prettyUri$1(t2)));
+ t1 = t2;
+ }
+ t1 += ": " + H.S(message);
+ highlight = _this.highlight$1$color(color);
+ if (highlight.length !== 0)
+ t1 = t1 + "\n" + highlight;
+ return t1.charCodeAt(0) == 0 ? t1 : t1;
+ },
+ message$1: function($receiver, message) {
+ return this.message$2$color($receiver, message, null);
+ },
+ highlight$1$color: function(color) {
+ var t2, t3, t4, newSpan, _this = this,
+ t1 = type$.SourceSpanWithContext._is(_this);
+ if (!t1 && _this.get$length(_this) === 0)
+ return "";
+ if (t1 && B.findLineStart(_this.get$context(), _this.get$text(), _this.get$start().get$column()) != null)
+ t1 = _this;
+ else {
+ t1 = _this.get$start();
+ t1 = V.SourceLocation$(t1.get$offset(t1), 0, 0, _this.get$sourceUrl());
+ t2 = _this.get$end();
+ t2 = t2.get$offset(t2);
+ t3 = _this.get$sourceUrl();
+ t4 = B.countCodeUnits(_this.get$text(), 10);
+ t3 = X.SourceSpanWithContext$(t1, V.SourceLocation$(t2, U.Highlighter__lastLineLength(_this.get$text()), t4, t3), _this.get$text(), _this.get$text());
+ t1 = t3;
+ }
+ newSpan = U.Highlighter__normalizeEndOfLine(U.Highlighter__normalizeTrailingNewline(U.Highlighter__normalizeNewlines(t1)));
+ return new U.Highlighter(newSpan, color, newSpan.get$start().get$line() != newSpan.get$end().get$line(), J.toString$0$(newSpan.get$end().get$line()).length + 1, new P.StringBuffer("")).highlight$0();
+ },
+ $eq: function(_, other) {
+ if (other == null)
+ return false;
+ return type$.SourceSpan._is(other) && this.get$start().$eq(0, other.get$start()) && this.get$end().$eq(0, other.get$end());
+ },
+ get$hashCode: function(_) {
+ var t2,
+ t1 = this.get$start();
+ t1 = t1.get$hashCode(t1);
+ t2 = this.get$end();
+ return t1 + 31 * t2.get$hashCode(t2);
+ },
+ toString$0: function(_) {
+ var _this = this;
+ return "<" + H.getRuntimeType(_this).toString$0(0) + ": from " + _this.get$start().toString$0(0) + " to " + _this.get$end().toString$0(0) + ' "' + _this.get$text() + '">';
+ },
+ $isSourceSpan: 1
+ };
+ X.SourceSpanWithContext.prototype = {
+ get$context: function() {
+ return this._context;
+ }
+ };
+ U.Chain.prototype = {
+ foldFrames$2$terse: function(predicate, terse) {
+ var t1 = this.traces,
+ t2 = H._arrayInstanceType(t1),
+ t3 = t2._eval$1("MappedListIterable<1,Trace>"),
+ foldedTraces = new H.MappedListIterable(t1, t2._eval$1("Trace(1)")._check(new U.Chain_foldFrames_closure(type$.bool_Function_Frame._check(predicate), true)), t3),
+ nonEmptyTraces = foldedTraces.super$Iterable$where(0, t3._eval$1("bool(ListIterable.E)")._check(new U.Chain_foldFrames_closure0(true)));
+ if (!nonEmptyTraces.get$iterator(nonEmptyTraces).moveNext$0() && !foldedTraces.get$isEmpty(foldedTraces))
+ return new U.Chain(P.List_List$unmodifiable(H.setRuntimeTypeInfo([foldedTraces.get$last(foldedTraces)], type$.JSArray_Trace), type$.Trace));
+ return new U.Chain(P.List_List$unmodifiable(nonEmptyTraces, type$.Trace));
+ },
+ toTrace$0: function() {
+ var t1 = this.traces,
+ t2 = H._arrayInstanceType(t1);
+ return new Y.Trace(P.List_List$unmodifiable(new H.ExpandIterable(t1, t2._eval$1("Iterable<Frame>(1)")._check(new U.Chain_toTrace_closure()), t2._eval$1("ExpandIterable<1,Frame>")), type$.Frame), new P._StringStackTrace(null));
+ },
+ toString$0: function(_) {
+ var t1 = this.traces,
+ t2 = H._arrayInstanceType(t1),
+ t3 = type$.int;
+ return new H.MappedListIterable(t1, t2._eval$1("String(1)")._check(new U.Chain_toString_closure(new H.MappedListIterable(t1, t2._eval$1("int(1)")._check(new U.Chain_toString_closure0()), t2._eval$1("MappedListIterable<1,int>")).fold$1$2(0, 0, H.instantiate1(P.math__max$closure(), t3), t3))), t2._eval$1("MappedListIterable<1,String>")).join$1(0, "===== asynchronous gap ===========================\n");
+ },
+ $isStackTrace: 1,
+ get$traces: function() {
+ return this.traces;
+ }
+ };
+ U.Chain_capture_closure.prototype = {
+ call$0: function() {
+ var error, stackTrace, t1, exception;
+ try {
+ t1 = this.callback.call$0();
+ return t1;
+ } catch (exception) {
+ error = H.unwrapException(exception);
+ stackTrace = H.getTraceFromException(exception);
+ $.Zone__current.handleUncaughtError$2(error, stackTrace);
+ return null;
+ }
+ },
+ $signature: function() {
+ return this.T._eval$1("0()");
+ }
+ };
+ U.Chain_Chain$current_closure.prototype = {
+ call$0: function() {
+ var t3,
+ t1 = this.chain,
+ t2 = C.JSArray_methods.get$first(t1.get$traces()).get$frames();
+ t2 = H.SubListIterable$(t2, this.level + 2, null, H._arrayInstanceType(t2)._precomputed1);
+ t3 = C.JSArray_methods.get$first(t1.get$traces()).get$original();
+ t3 = H.setRuntimeTypeInfo([new Y.Trace(P.List_List$unmodifiable(t2, type$.Frame), new P._StringStackTrace(t3._stackTrace))], type$.JSArray_Trace);
+ t1 = t1.get$traces();
+ C.JSArray_methods.addAll$1(t3, H.SubListIterable$(t1, 1, null, H._arrayInstanceType(t1)._precomputed1));
+ return new U.Chain(P.List_List$unmodifiable(t3, type$.Trace));
+ },
+ $signature: 16
+ };
+ U.Chain_Chain$forTrace_closure.prototype = {
+ call$0: function() {
+ return U.Chain_Chain$parse(J.toString$0$(this.trace));
+ },
+ $signature: 16
+ };
+ U.Chain_Chain$parse_closure.prototype = {
+ call$1: function(trace) {
+ H._checkStringNullable(trace);
+ return new Y.Trace(P.List_List$unmodifiable(Y.Trace__parseVM(trace), type$.Frame), new P._StringStackTrace(trace));
+ },
+ $signature: 42
+ };
+ U.Chain_Chain$parse_closure0.prototype = {
+ call$1: function(trace) {
+ return Y.Trace$parseFriendly(H._checkStringNullable(trace));
+ },
+ $signature: 42
+ };
+ U.Chain_foldFrames_closure.prototype = {
+ call$1: function(trace) {
+ return type$.Trace._check(trace).foldFrames$2$terse(this.predicate, this.terse);
+ },
+ $signature: 45
+ };
+ U.Chain_foldFrames_closure0.prototype = {
+ call$1: function(trace) {
+ type$.Trace._check(trace);
+ if (trace.get$frames().length > 1)
+ return true;
+ if (trace.get$frames().length === 0)
+ return false;
+ if (!this.terse)
+ return false;
+ return C.JSArray_methods.get$single(trace.get$frames()).get$line() != null;
+ },
+ $signature: 52
+ };
+ U.Chain_toTrace_closure.prototype = {
+ call$1: function(trace) {
+ return type$.Trace._check(trace).get$frames();
+ },
+ $signature: 53
+ };
+ U.Chain_toString_closure0.prototype = {
+ call$1: function(trace) {
+ var t1 = type$.Trace._check(trace).get$frames(),
+ t2 = H._arrayInstanceType(t1),
+ t3 = type$.int;
+ return new H.MappedListIterable(t1, t2._eval$1("int(1)")._check(new U.Chain_toString__closure0()), t2._eval$1("MappedListIterable<1,int>")).fold$1$2(0, 0, H.instantiate1(P.math__max$closure(), t3), t3);
+ },
+ $signature: 54
+ };
+ U.Chain_toString__closure0.prototype = {
+ call$1: function(frame) {
+ type$.Frame._check(frame);
+ return frame.get$location(frame).length;
+ },
+ $signature: 39
+ };
+ U.Chain_toString_closure.prototype = {
+ call$1: function(trace) {
+ var t1 = type$.Trace._check(trace).get$frames(),
+ t2 = H._arrayInstanceType(t1);
+ return new H.MappedListIterable(t1, t2._eval$1("String(1)")._check(new U.Chain_toString__closure(this.longest)), t2._eval$1("MappedListIterable<1,String>")).join$0(0);
+ },
+ $signature: 56
+ };
+ U.Chain_toString__closure.prototype = {
+ call$1: function(frame) {
+ type$.Frame._check(frame);
+ return J.padRight$1$s(frame.get$location(frame), this.longest) + " " + H.S(frame.get$member()) + "\n";
+ },
+ $signature: 38
+ };
+ A.Frame.prototype = {
+ get$isCore: function() {
+ return this.uri.get$scheme() === "dart";
+ },
+ get$library: function() {
+ var t1 = this.uri;
+ if (t1.get$scheme() === "data")
+ return "data:...";
+ return $.$get$context().prettyUri$1(t1);
+ },
+ get$$package: function() {
+ var t1 = this.uri;
+ if (t1.get$scheme() !== "package")
+ return null;
+ return C.JSArray_methods.get$first(t1.get$path(t1).split("/"));
+ },
+ get$location: function(_) {
+ var t2, _this = this,
+ t1 = _this.line;
+ if (t1 == null)
+ return _this.get$library();
+ t2 = _this.column;
+ if (t2 == null)
+ return H.S(_this.get$library()) + " " + H.S(t1);
+ return H.S(_this.get$library()) + " " + H.S(t1) + ":" + H.S(t2);
+ },
+ toString$0: function(_) {
+ return H.S(this.get$location(this)) + " in " + H.S(this.member);
+ },
+ get$uri: function() {
+ return this.uri;
+ },
+ get$line: function() {
+ return this.line;
+ },
+ get$column: function() {
+ return this.column;
+ },
+ get$member: function() {
+ return this.member;
+ }
+ };
+ A.Frame_Frame$parseVM_closure.prototype = {
+ call$0: function() {
+ var match, t2, t3, member, uri, lineAndColumn, line, _null = null,
+ t1 = this.frame;
+ if (t1 === "...")
+ return new A.Frame(P._Uri__Uri(_null, _null, _null, _null), _null, _null, "...");
+ match = $.$get$_vmFrame().firstMatch$1(t1);
+ if (match == null)
+ return new N.UnparsedFrame(P._Uri__Uri(_null, "unparsed", _null, _null), t1);
+ t1 = match._match;
+ if (1 >= t1.length)
+ return H.ioore(t1, 1);
+ t2 = t1[1];
+ t3 = $.$get$_asyncBody();
+ t2.toString;
+ t2 = H.stringReplaceAllUnchecked(t2, t3, "<async>");
+ member = H.stringReplaceAllUnchecked(t2, "<anonymous closure>", "<fn>");
+ if (2 >= t1.length)
+ return H.ioore(t1, 2);
+ uri = P.Uri_parse(t1[2]);
+ if (3 >= t1.length)
+ return H.ioore(t1, 3);
+ lineAndColumn = t1[3].split(":");
+ t1 = lineAndColumn.length;
+ line = t1 > 1 ? P.int_parse(lineAndColumn[1], _null, _null) : _null;
+ return new A.Frame(uri, line, t1 > 2 ? P.int_parse(lineAndColumn[2], _null, _null) : _null, member);
+ },
+ $signature: 17
+ };
+ A.Frame_Frame$parseV8_closure.prototype = {
+ call$0: function() {
+ var t2, t3, t4, _s4_ = "<fn>",
+ t1 = this.frame,
+ match = $.$get$_v8Frame().firstMatch$1(t1);
+ if (match == null)
+ return new N.UnparsedFrame(P._Uri__Uri(null, "unparsed", null, null), t1);
+ t1 = new A.Frame_Frame$parseV8_closure_parseLocation(t1);
+ t2 = match._match;
+ t3 = t2.length;
+ if (2 >= t3)
+ return H.ioore(t2, 2);
+ t4 = t2[2];
+ if (t4 != null) {
+ t2 = t2[1];
+ t2.toString;
+ t2 = H.stringReplaceAllUnchecked(t2, "<anonymous>", _s4_);
+ t2 = H.stringReplaceAllUnchecked(t2, "Anonymous function", _s4_);
+ return t1.call$2(t4, H.stringReplaceAllUnchecked(t2, "(anonymous function)", _s4_));
+ } else {
+ if (3 >= t3)
+ return H.ioore(t2, 3);
+ return t1.call$2(t2[3], _s4_);
+ }
+ },
+ $signature: 17
+ };
+ A.Frame_Frame$parseV8_closure_parseLocation.prototype = {
+ call$2: function($location, member) {
+ var t2, urlMatch, t3, _null = null,
+ t1 = $.$get$_v8EvalLocation(),
+ evalMatch = t1.firstMatch$1($location);
+ for (; evalMatch != null;) {
+ t2 = evalMatch._match;
+ if (1 >= t2.length)
+ return H.ioore(t2, 1);
+ $location = t2[1];
+ evalMatch = t1.firstMatch$1($location);
+ }
+ if ($location === "native")
+ return new A.Frame(P.Uri_parse("native"), _null, _null, member);
+ urlMatch = $.$get$_v8UrlLocation().firstMatch$1($location);
+ if (urlMatch == null)
+ return new N.UnparsedFrame(P._Uri__Uri(_null, "unparsed", _null, _null), this.frame);
+ t1 = urlMatch._match;
+ if (1 >= t1.length)
+ return H.ioore(t1, 1);
+ t2 = A.Frame__uriOrPathToUri(t1[1]);
+ if (2 >= t1.length)
+ return H.ioore(t1, 2);
+ t3 = P.int_parse(t1[2], _null, _null);
+ if (3 >= t1.length)
+ return H.ioore(t1, 3);
+ return new A.Frame(t2, t3, P.int_parse(t1[3], _null, _null), member);
+ },
+ $signature: 59
+ };
+ A.Frame_Frame$parseFirefox_closure.prototype = {
+ call$0: function() {
+ var uri, t2, t3, member, line, _null = null,
+ t1 = this.frame,
+ match = $.$get$_firefoxSafariFrame().firstMatch$1(t1);
+ if (match == null)
+ return new N.UnparsedFrame(P._Uri__Uri(_null, "unparsed", _null, _null), t1);
+ t1 = match._match;
+ if (3 >= t1.length)
+ return H.ioore(t1, 3);
+ uri = A.Frame__uriOrPathToUri(t1[3]);
+ t2 = t1.length;
+ if (1 >= t2)
+ return H.ioore(t1, 1);
+ t3 = t1[1];
+ if (t3 != null) {
+ if (2 >= t2)
+ return H.ioore(t1, 2);
+ t2 = C.JSString_methods.allMatches$1("/", t1[2]);
+ member = J.$add$ansx(t3, C.JSArray_methods.join$0(P.List_List$filled(t2.get$length(t2), ".<fn>", type$.String)));
+ if (member === "")
+ member = "<fn>";
+ member = C.JSString_methods.replaceFirst$2(member, $.$get$_initialDot(), "");
+ } else
+ member = "<fn>";
+ if (4 >= t1.length)
+ return H.ioore(t1, 4);
+ t2 = t1[4];
+ line = t2 === "" ? _null : P.int_parse(t2, _null, _null);
+ if (5 >= t1.length)
+ return H.ioore(t1, 5);
+ t1 = t1[5];
+ return new A.Frame(uri, line, t1 == null || t1 === "" ? _null : P.int_parse(t1, _null, _null), member);
+ },
+ $signature: 17
+ };
+ A.Frame_Frame$parseFriendly_closure.prototype = {
+ call$0: function() {
+ var t2, buffer, indices, uri, line, column, _null = null,
+ t1 = this.frame,
+ match = $.$get$_friendlyFrame().firstMatch$1(t1);
+ if (match == null)
+ throw H.wrapException(P.FormatException$("Couldn't parse package:stack_trace stack trace line '" + H.S(t1) + "'.", _null, _null));
+ t1 = match._match;
+ if (1 >= t1.length)
+ return H.ioore(t1, 1);
+ t2 = t1[1];
+ if (t2 === "data:...") {
+ buffer = new P.StringBuffer("");
+ indices = H.setRuntimeTypeInfo([-1], type$.JSArray_int);
+ P.UriData__writeUri(_null, _null, _null, buffer, indices);
+ C.JSArray_methods.add$1(indices, buffer._contents.length);
+ buffer._contents += ",";
+ P.UriData__uriEncodeBytes(C.List_CVk, C.C_AsciiCodec.encode$1(""), buffer);
+ t2 = buffer._contents;
+ uri = new P.UriData(t2.charCodeAt(0) == 0 ? t2 : t2, indices, _null).get$uri();
+ } else
+ uri = P.Uri_parse(t2);
+ if (uri.get$scheme() === "") {
+ t2 = $.$get$context();
+ uri = t2.toUri$1(t2.absolute$7(0, t2.style.pathFromUri$1(M._parseUri(uri)), _null, _null, _null, _null, _null, _null));
+ }
+ if (2 >= t1.length)
+ return H.ioore(t1, 2);
+ t2 = t1[2];
+ line = t2 == null ? _null : P.int_parse(t2, _null, _null);
+ if (3 >= t1.length)
+ return H.ioore(t1, 3);
+ t2 = t1[3];
+ column = t2 == null ? _null : P.int_parse(t2, _null, _null);
+ if (4 >= t1.length)
+ return H.ioore(t1, 4);
+ return new A.Frame(uri, line, column, t1[4]);
+ },
+ $signature: 17
+ };
+ X.LazyChain.prototype = {
+ get$_chain: function() {
+ var _this = this;
+ if (_this._lazy_chain$_inner == null)
+ _this.set$_lazy_chain$_inner(_this._thunk.call$0());
+ return _this._lazy_chain$_inner;
+ },
+ get$traces: function() {
+ return this.get$_chain().get$traces();
+ },
+ foldFrames$2$terse: function(predicate, terse) {
+ return new X.LazyChain(new X.LazyChain_foldFrames_closure(this, type$.bool_Function_Frame._check(predicate), true));
+ },
+ toTrace$0: function() {
+ return new T.LazyTrace(new X.LazyChain_toTrace_closure(this));
+ },
+ toString$0: function(_) {
+ return J.toString$0$(this.get$_chain());
+ },
+ set$_lazy_chain$_inner: function(_inner) {
+ this._lazy_chain$_inner = type$.Chain._check(_inner);
+ },
+ $isStackTrace: 1,
+ $isChain: 1
+ };
+ X.LazyChain_foldFrames_closure.prototype = {
+ call$0: function() {
+ return this.$this.get$_chain().foldFrames$2$terse(this.predicate, this.terse);
+ },
+ $signature: 16
+ };
+ X.LazyChain_toTrace_closure.prototype = {
+ call$0: function() {
+ return this.$this.get$_chain().toTrace$0();
+ },
+ $signature: 8
+ };
+ T.LazyTrace.prototype = {
+ get$_lazy_trace$_trace: function() {
+ var _this = this;
+ if (_this._lazy_trace$_inner == null)
+ _this.set$_lazy_trace$_inner(_this._lazy_trace$_thunk.call$0());
+ return _this._lazy_trace$_inner;
+ },
+ get$frames: function() {
+ return this.get$_lazy_trace$_trace().get$frames();
+ },
+ get$original: function() {
+ return this.get$_lazy_trace$_trace().get$original();
+ },
+ foldFrames$2$terse: function(predicate, terse) {
+ return new T.LazyTrace(new T.LazyTrace_foldFrames_closure(this, type$.bool_Function_Frame._check(predicate), true));
+ },
+ toString$0: function(_) {
+ return J.toString$0$(this.get$_lazy_trace$_trace());
+ },
+ set$_lazy_trace$_inner: function(_inner) {
+ this._lazy_trace$_inner = type$.Trace._check(_inner);
+ },
+ $isStackTrace: 1,
+ $isTrace: 1
+ };
+ T.LazyTrace_foldFrames_closure.prototype = {
+ call$0: function() {
+ return this.$this.get$_lazy_trace$_trace().foldFrames$2$terse(this.predicate, this.terse);
+ },
+ $signature: 8
+ };
+ O.StackZoneSpecification.prototype = {
+ chainFor$1: function(trace) {
+ var t2, previous, t3, t1 = {};
+ t1.trace = trace;
+ if (type$.Chain._is(trace))
+ return trace;
+ if (trace == null) {
+ trace = P.StackTrace_current();
+ t1.trace = trace;
+ t2 = trace;
+ } else
+ t2 = trace;
+ previous = this._chains.$index(0, t2);
+ if (previous == null)
+ previous = this._currentNode;
+ if (previous == null) {
+ t3 = type$.Trace;
+ if (t3._is(t2))
+ return new U.Chain(P.List_List$unmodifiable(H.setRuntimeTypeInfo([t2], type$.JSArray_Trace), t3));
+ return new X.LazyChain(new O.StackZoneSpecification_chainFor_closure(t1));
+ } else
+ return new O._Node(Y.Trace_Trace$from(!type$.Trace._is(t2) ? t1.trace = new T.LazyTrace(new O.StackZoneSpecification_chainFor_closure0(this, t2)) : t2), previous).toChain$0();
+ },
+ _stack_zone_specification$_registerCallback$1$4: function($self, $parent, zone, f, $R) {
+ var t1, t2;
+ $R._eval$1("0()")._check(f);
+ if (f == null || J.$eq$($.Zone__current.$index(0, $.$get$StackZoneSpecification_disableKey()), true))
+ return $parent.registerCallback$1$2(zone, f, $R);
+ t1 = this._currentTrace$1(2);
+ t2 = this._currentNode;
+ return $parent.registerCallback$1$2(zone, new O.StackZoneSpecification__registerCallback_closure(this, f, new O._Node(Y.Trace_Trace$from(t1), t2), $R), $R);
+ },
+ _stack_zone_specification$_registerCallback$4: function($self, $parent, zone, f) {
+ return this._stack_zone_specification$_registerCallback$1$4($self, $parent, zone, f, type$.dynamic);
+ },
+ _stack_zone_specification$_registerUnaryCallback$2$4: function($self, $parent, zone, f, $R, $T) {
+ var t1, t2;
+ $R._eval$1("@<0>")._bind$1($T)._eval$1("1(2)")._check(f);
+ if (f == null || J.$eq$($.Zone__current.$index(0, $.$get$StackZoneSpecification_disableKey()), true))
+ return $parent.registerUnaryCallback$2$2(zone, f, $R, $T);
+ t1 = this._currentTrace$1(2);
+ t2 = this._currentNode;
+ return $parent.registerUnaryCallback$2$2(zone, new O.StackZoneSpecification__registerUnaryCallback_closure(this, f, new O._Node(Y.Trace_Trace$from(t1), t2), $T, $R), $R, $T);
+ },
+ _stack_zone_specification$_registerUnaryCallback$4: function($self, $parent, zone, f) {
+ return this._stack_zone_specification$_registerUnaryCallback$2$4($self, $parent, zone, f, type$.dynamic, type$.dynamic);
+ },
+ _stack_zone_specification$_registerBinaryCallback$3$4: function($self, $parent, zone, f, $R, T1, T2) {
+ var t1, t2;
+ type$.Function._check(f);
+ if (f == null || J.$eq$($.Zone__current.$index(0, $.$get$StackZoneSpecification_disableKey()), true))
+ return $parent.registerBinaryCallback$3$2(zone, $R._eval$1("@<0>")._bind$1(T1)._bind$1(T2)._eval$1("1(2,3)")._check(f), $R, T1, T2);
+ t1 = this._currentTrace$1(2);
+ t2 = this._currentNode;
+ return $parent.registerBinaryCallback$3$2(zone, new O.StackZoneSpecification__registerBinaryCallback_closure(this, f, new O._Node(Y.Trace_Trace$from(t1), t2), T1, T2, $R), $R, T1, T2);
+ },
+ _stack_zone_specification$_registerBinaryCallback$4: function($self, $parent, zone, f) {
+ return this._stack_zone_specification$_registerBinaryCallback$3$4($self, $parent, zone, f, type$.dynamic, type$.dynamic, type$.dynamic);
+ },
+ _stack_zone_specification$_errorCallback$5: function($self, $parent, zone, error, stackTrace) {
+ var t1, t2, t3, asyncError, _this = this;
+ type$.StackTrace._check(stackTrace);
+ if (J.$eq$($.Zone__current.$index(0, $.$get$StackZoneSpecification_disableKey()), true))
+ return $parent.errorCallback$3(zone, error, stackTrace);
+ if (stackTrace == null) {
+ t1 = _this._currentTrace$1(3);
+ t2 = _this._currentNode;
+ stackTrace = new O._Node(Y.Trace_Trace$from(t1), t2).toChain$0();
+ } else {
+ t1 = _this._chains;
+ if (t1.$index(0, stackTrace) == null) {
+ t2 = _this._currentTrace$1(3);
+ t3 = _this._currentNode;
+ t1.$indexSet(0, stackTrace, new O._Node(Y.Trace_Trace$from(t2), t3));
+ }
+ }
+ asyncError = $parent.errorCallback$3(zone, error, stackTrace);
+ return asyncError == null ? new P.AsyncError(error, stackTrace) : asyncError;
+ },
+ _stack_zone_specification$_run$1$2: function(f, node, $T) {
+ var previousNode, stackTrace, t1, exception, t2, _this = this;
+ $T._eval$1("0()")._check(f);
+ previousNode = _this._currentNode;
+ _this._currentNode = node;
+ try {
+ t1 = f.call$0();
+ return t1;
+ } catch (exception) {
+ H.unwrapException(exception);
+ stackTrace = H.getTraceFromException(exception);
+ t1 = _this._chains;
+ t2 = stackTrace;
+ if (t1.$index(0, t2) == null)
+ t1.$indexSet(0, t2, node);
+ throw exception;
+ } finally {
+ _this.set$_currentNode(previousNode);
+ }
+ },
+ _currentTrace$1: function(level) {
+ var t1 = {};
+ t1.level = level;
+ return new T.LazyTrace(new O.StackZoneSpecification__currentTrace_closure(t1, this, P.StackTrace_current()));
+ },
+ _trimVMChain$1: function(trace) {
+ var text = J.toString$0$(trace),
+ index = J.getInterceptor$s(text).indexOf$1(text, "<asynchronous suspension>\n");
+ return index === -1 ? text : C.JSString_methods.substring$2(text, 0, index);
+ },
+ set$_currentNode: function(_currentNode) {
+ this._currentNode = type$._Node._check(_currentNode);
+ }
+ };
+ O.StackZoneSpecification_chainFor_closure.prototype = {
+ call$0: function() {
+ return U.Chain_Chain$parse(J.toString$0$(this._box_0.trace));
+ },
+ $signature: 16
+ };
+ O.StackZoneSpecification_chainFor_closure0.prototype = {
+ call$0: function() {
+ return Y.Trace_Trace$parse(this.$this._trimVMChain$1(this.original));
+ },
+ $signature: 8
+ };
+ O.StackZoneSpecification__registerCallback_closure.prototype = {
+ call$0: function() {
+ var _this = this;
+ return _this.$this._stack_zone_specification$_run$1$2(_this.f, _this.node, _this.R);
+ },
+ $signature: function() {
+ return this.R._eval$1("0()");
+ }
+ };
+ O.StackZoneSpecification__registerUnaryCallback_closure.prototype = {
+ call$1: function(arg) {
+ var _this = this,
+ t1 = _this.R;
+ return _this.$this._stack_zone_specification$_run$1$2(new O.StackZoneSpecification__registerUnaryCallback__closure(_this.f, _this.T._check(arg), t1), _this.node, t1);
+ },
+ $signature: function() {
+ return this.R._eval$1("@<0>")._bind$1(this.T)._eval$1("1(2)");
+ }
+ };
+ O.StackZoneSpecification__registerUnaryCallback__closure.prototype = {
+ call$0: function() {
+ return this.f.call$1(this.arg);
+ },
+ $signature: function() {
+ return this.R._eval$1("0()");
+ }
+ };
+ O.StackZoneSpecification__registerBinaryCallback_closure.prototype = {
+ call$2: function(arg1, arg2) {
+ var _this = this,
+ t1 = _this.R;
+ return _this.$this._stack_zone_specification$_run$1$2(new O.StackZoneSpecification__registerBinaryCallback__closure(_this.f, _this.T1._check(arg1), _this.T2._check(arg2), t1), _this.node, t1);
+ },
+ $signature: function() {
+ return this.R._eval$1("@<0>")._bind$1(this.T1)._bind$1(this.T2)._eval$1("1(2,3)");
+ }
+ };
+ O.StackZoneSpecification__registerBinaryCallback__closure.prototype = {
+ call$0: function() {
+ var _this = this;
+ return _this.R._check(_this.f.call$2(_this.arg1, _this.arg2));
+ },
+ $signature: function() {
+ return this.R._eval$1("0()");
+ }
+ };
+ O.StackZoneSpecification__currentTrace_closure.prototype = {
+ call$0: function() {
+ var text = this.$this._trimVMChain$1(this.stackTrace),
+ t1 = Y.Trace_Trace$parse(text).frames,
+ t2 = this._box_0.level;
+ if (typeof t2 !== "number")
+ return t2.$add();
+ return new Y.Trace(P.List_List$unmodifiable(H.SubListIterable$(t1, t2 + 2, null, H._arrayInstanceType(t1)._precomputed1), type$.Frame), new P._StringStackTrace(text));
+ },
+ $signature: 8
+ };
+ O._Node.prototype = {
+ toChain$0: function() {
+ var node,
+ nodes = H.setRuntimeTypeInfo([], type$.JSArray_Trace);
+ for (node = this; node != null;) {
+ C.JSArray_methods.add$1(nodes, node.trace);
+ node = node.previous;
+ }
+ return new U.Chain(P.List_List$unmodifiable(nodes, type$.Trace));
+ }
+ };
+ Y.Trace.prototype = {
+ foldFrames$2$terse: function(predicate, terse) {
+ var newFrames, t1, t2, _box_0 = {};
+ _box_0.predicate = predicate;
+ _box_0.predicate = new Y.Trace_foldFrames_closure(type$.bool_Function_Frame._check(predicate));
+ newFrames = H.setRuntimeTypeInfo([], type$.JSArray_Frame);
+ for (t1 = this.frames, t2 = H._arrayInstanceType(t1)._eval$1("ReversedListIterable<1>"), t1 = new H.ReversedListIterable(t1, t2), t2 = new H.ListIterator(t1, t1.get$length(t1), t2._eval$1("ListIterator<ListIterable.E>")); t2.moveNext$0();) {
+ t1 = t2.__internal$_current;
+ if (t1 instanceof N.UnparsedFrame || !H.boolConversionCheck(_box_0.predicate.call$1(t1)))
+ C.JSArray_methods.add$1(newFrames, t1);
+ else if (newFrames.length === 0 || !H.boolConversionCheck(_box_0.predicate.call$1(C.JSArray_methods.get$last(newFrames))))
+ C.JSArray_methods.add$1(newFrames, new A.Frame(t1.get$uri(), t1.get$line(), t1.get$column(), t1.get$member()));
+ }
+ newFrames = new H.MappedListIterable(newFrames, type$.Frame_Function_Frame._check(new Y.Trace_foldFrames_closure0(_box_0)), type$.MappedListIterable_Frame_Frame).toList$0(0);
+ if (newFrames.length > 1 && H.boolConversionCheck(_box_0.predicate.call$1(C.JSArray_methods.get$first(newFrames))))
+ C.JSArray_methods.removeAt$1(newFrames, 0);
+ return new Y.Trace(P.List_List$unmodifiable(new H.ReversedListIterable(newFrames, H._arrayInstanceType(newFrames)._eval$1("ReversedListIterable<1>")), type$.Frame), new P._StringStackTrace(this.original._stackTrace));
+ },
+ toString$0: function(_) {
+ var t1 = this.frames,
+ t2 = H._arrayInstanceType(t1),
+ t3 = type$.int;
+ return new H.MappedListIterable(t1, t2._eval$1("String(1)")._check(new Y.Trace_toString_closure(new H.MappedListIterable(t1, t2._eval$1("int(1)")._check(new Y.Trace_toString_closure0()), t2._eval$1("MappedListIterable<1,int>")).fold$1$2(0, 0, H.instantiate1(P.math__max$closure(), t3), t3))), t2._eval$1("MappedListIterable<1,String>")).join$0(0);
+ },
+ $isStackTrace: 1,
+ get$frames: function() {
+ return this.frames;
+ },
+ get$original: function() {
+ return this.original;
+ }
+ };
+ Y.Trace_Trace$current_closure.prototype = {
+ call$0: function() {
+ var t1 = this.trace,
+ t2 = t1.get$frames();
+ t2 = H.SubListIterable$(t2, this.level + 2, null, H._arrayInstanceType(t2)._precomputed1);
+ t1 = t1.get$original();
+ return new Y.Trace(P.List_List$unmodifiable(t2, type$.Frame), new P._StringStackTrace(t1._stackTrace));
+ },
+ $signature: 8
+ };
+ Y.Trace_Trace$from_closure.prototype = {
+ call$0: function() {
+ return Y.Trace_Trace$parse(this.trace.toString$0(0));
+ },
+ $signature: 8
+ };
+ Y.Trace__parseVM_closure.prototype = {
+ call$1: function(line) {
+ return A.Frame_Frame$parseVM(H._checkStringNullable(line));
+ },
+ $signature: 10
+ };
+ Y.Trace$parseV8_closure.prototype = {
+ call$1: function(line) {
+ return !J.startsWith$1$s(H._checkStringNullable(line), $.$get$_v8TraceLine());
+ },
+ $signature: 4
+ };
+ Y.Trace$parseV8_closure0.prototype = {
+ call$1: function(line) {
+ return A.Frame_Frame$parseV8(H._checkStringNullable(line));
+ },
+ $signature: 10
+ };
+ Y.Trace$parseJSCore_closure.prototype = {
+ call$1: function(line) {
+ return H._checkStringNullable(line) !== "\tat ";
+ },
+ $signature: 4
+ };
+ Y.Trace$parseJSCore_closure0.prototype = {
+ call$1: function(line) {
+ return A.Frame_Frame$parseV8(H._checkStringNullable(line));
+ },
+ $signature: 10
+ };
+ Y.Trace$parseFirefox_closure.prototype = {
+ call$1: function(line) {
+ H._checkStringNullable(line);
+ return line.length !== 0 && line !== "[native code]";
+ },
+ $signature: 4
+ };
+ Y.Trace$parseFirefox_closure0.prototype = {
+ call$1: function(line) {
+ return A.Frame_Frame$parseFirefox(H._checkStringNullable(line));
+ },
+ $signature: 10
+ };
+ Y.Trace$parseFriendly_closure.prototype = {
+ call$1: function(line) {
+ return !J.startsWith$1$s(H._checkStringNullable(line), "=====");
+ },
+ $signature: 4
+ };
+ Y.Trace$parseFriendly_closure0.prototype = {
+ call$1: function(line) {
+ return A.Frame_Frame$parseFriendly(H._checkStringNullable(line));
+ },
+ $signature: 10
+ };
+ Y.Trace_foldFrames_closure.prototype = {
+ call$1: function(frame) {
+ if (H.boolConversionCheck(this.oldPredicate.call$1(frame)))
+ return true;
+ if (frame.get$isCore())
+ return true;
+ if (frame.get$$package() === "stack_trace")
+ return true;
+ if (!J.contains$1$asx(frame.get$member(), "<async>"))
+ return false;
+ return frame.get$line() == null;
+ },
+ $signature: 21
+ };
+ Y.Trace_foldFrames_closure0.prototype = {
+ call$1: function(frame) {
+ var t1, t2;
+ type$.Frame._check(frame);
+ if (frame instanceof N.UnparsedFrame || !H.boolConversionCheck(this._box_0.predicate.call$1(frame)))
+ return frame;
+ t1 = frame.get$library();
+ t2 = $.$get$_terseRegExp();
+ t1.toString;
+ return new A.Frame(P.Uri_parse(H.stringReplaceAllUnchecked(t1, t2, "")), null, null, frame.get$member());
+ },
+ $signature: 46
+ };
+ Y.Trace_toString_closure0.prototype = {
+ call$1: function(frame) {
+ type$.Frame._check(frame);
+ return frame.get$location(frame).length;
+ },
+ $signature: 39
+ };
+ Y.Trace_toString_closure.prototype = {
+ call$1: function(frame) {
+ type$.Frame._check(frame);
+ if (frame instanceof N.UnparsedFrame)
+ return frame.toString$0(0) + "\n";
+ return J.padRight$1$s(frame.get$location(frame), this.longest) + " " + H.S(frame.get$member()) + "\n";
+ },
+ $signature: 38
+ };
+ N.UnparsedFrame.prototype = {
+ toString$0: function(_) {
+ return this.member;
+ },
+ $isFrame: 1,
+ get$uri: function() {
+ return this.uri;
+ },
+ get$line: function() {
+ return null;
+ },
+ get$column: function() {
+ return null;
+ },
+ get$isCore: function() {
+ return false;
+ },
+ get$library: function() {
+ return "unparsed";
+ },
+ get$$package: function() {
+ return null;
+ },
+ get$location: function() {
+ return "unparsed";
+ },
+ get$member: function() {
+ return this.member;
+ }
+ };
+ K.GuaranteeChannel.prototype = {
+ get$stream: function(_) {
+ var t1 = this._streamController;
+ t1.toString;
+ return new P._ControllerStream(t1, H._instanceType(t1)._eval$1("_ControllerStream<1>"));
+ },
+ get$sink: function() {
+ return this._sink;
+ },
+ GuaranteeChannel$3$allowSinkErrors: function(innerSink, allowSinkErrors, _box_0, $T) {
+ var _this = this;
+ _this.set$_sink(new K._GuaranteeSink(innerSink, _this, new P._AsyncCompleter(new P._Future($.Zone__current, type$._Future_dynamic), type$._AsyncCompleter_dynamic), allowSinkErrors, $T._eval$1("_GuaranteeSink<0>")));
+ _this.set$_streamController(P.StreamController_StreamController(null, new K.GuaranteeChannel_closure(_box_0, _this), true, $T));
+ },
+ _onSinkDisconnected$0: function() {
+ this._disconnected = true;
+ var t1 = this._subscription;
+ if (t1 != null)
+ t1.cancel$0();
+ this._streamController.close$0(0);
+ },
+ set$_sink: function(_sink) {
+ this._sink = this.$ti._eval$1("_GuaranteeSink<1>")._check(_sink);
+ },
+ set$_streamController: function(_streamController) {
+ this._streamController = this.$ti._eval$1("StreamController<1>")._check(_streamController);
+ },
+ set$_subscription: function(_subscription) {
+ this._subscription = this.$ti._eval$1("StreamSubscription<1>")._check(_subscription);
+ }
+ };
+ K.GuaranteeChannel_closure.prototype = {
+ call$0: function() {
+ var t2, t3,
+ t1 = this.$this;
+ if (t1._disconnected)
+ return;
+ t2 = this._box_0.innerStream;
+ t3 = t1._streamController;
+ t1.set$_subscription(t2.listen$3$onDone$onError(t3.get$add(t3), new K.GuaranteeChannel__closure(t1), t3.get$addError()));
+ },
+ $signature: 0
+ };
+ K.GuaranteeChannel__closure.prototype = {
+ call$0: function() {
+ var t1 = this.$this;
+ t1._sink._onStreamDisconnected$0();
+ t1._streamController.close$0(0);
+ },
+ $signature: 0
+ };
+ K._GuaranteeSink.prototype = {
+ get$done: function() {
+ return this._doneCompleter.future;
+ },
+ add$1: function(_, data) {
+ var t1, _this = this;
+ _this.$ti._precomputed1._check(data);
+ if (_this._closed)
+ throw H.wrapException(P.StateError$("Cannot add event after closing."));
+ if (_this._addStreamSubscription != null)
+ throw H.wrapException(P.StateError$("Cannot add event while adding stream."));
+ if (_this._disconnected)
+ return;
+ t1 = _this._inner;
+ t1._async$_target.add$1(0, t1.$ti._precomputed1._check(data));
+ },
+ addError$2: function(error, stackTrace) {
+ var _this = this;
+ type$.StackTrace._check(stackTrace);
+ if (_this._closed)
+ throw H.wrapException(P.StateError$("Cannot add event after closing."));
+ if (_this._addStreamSubscription != null)
+ throw H.wrapException(P.StateError$("Cannot add event while adding stream."));
+ if (_this._disconnected)
+ return;
+ _this._addError$2(error, stackTrace);
+ },
+ addError$1: function(error) {
+ return this.addError$2(error, null);
+ },
+ _addError$2: function(error, stackTrace) {
+ var _this = this;
+ type$.StackTrace._check(stackTrace);
+ if (_this._allowErrors) {
+ _this._inner._async$_target.addError$2(error, stackTrace);
+ return;
+ }
+ _this._doneCompleter.completeError$2(error, stackTrace);
+ _this._onStreamDisconnected$0();
+ _this._channel._onSinkDisconnected$0();
+ _this._inner._async$_target.close$0(0).catchError$1(new K._GuaranteeSink__addError_closure());
+ },
+ _addError$1: function(error) {
+ return this._addError$2(error, null);
+ },
+ addStream$1: function(stream) {
+ var t1, t2, _this = this;
+ _this.$ti._eval$1("Stream<1>")._check(stream);
+ if (_this._closed)
+ throw H.wrapException(P.StateError$("Cannot add stream after closing."));
+ if (_this._addStreamSubscription != null)
+ throw H.wrapException(P.StateError$("Cannot add stream while adding stream."));
+ if (_this._disconnected) {
+ t1 = new P._Future($.Zone__current, type$._Future_void);
+ t1._asyncComplete$1(null);
+ return t1;
+ }
+ t1 = new P._SyncCompleter(new P._Future($.Zone__current, type$._Future_dynamic), type$._SyncCompleter_dynamic);
+ _this._addStreamCompleter = t1;
+ t2 = _this._inner;
+ _this.set$_addStreamSubscription(stream.listen$3$onDone$onError(t2.get$add(t2), t1.get$complete(), _this.get$_addError()));
+ return _this._addStreamCompleter.future.then$1$1(new K._GuaranteeSink_addStream_closure(_this), type$.void);
+ },
+ close$0: function(_) {
+ var _this = this;
+ if (_this._addStreamSubscription != null)
+ throw H.wrapException(P.StateError$("Cannot close sink while adding stream."));
+ if (_this._closed)
+ return _this._doneCompleter.future;
+ _this._closed = true;
+ if (!_this._disconnected) {
+ _this._channel._onSinkDisconnected$0();
+ _this._doneCompleter.complete$1(_this._inner._async$_target.close$0(0));
+ }
+ return _this._doneCompleter.future;
+ },
+ _onStreamDisconnected$0: function() {
+ var t1, _this = this;
+ _this._disconnected = true;
+ t1 = _this._doneCompleter;
+ if (t1.future._state === 0)
+ t1.complete$0();
+ t1 = _this._addStreamSubscription;
+ if (t1 == null)
+ return;
+ _this._addStreamCompleter.complete$1(t1.cancel$0());
+ _this._addStreamCompleter = null;
+ _this.set$_addStreamSubscription(null);
+ },
+ set$_addStreamSubscription: function(_addStreamSubscription) {
+ this._addStreamSubscription = this.$ti._eval$1("StreamSubscription<1>")._check(_addStreamSubscription);
+ },
+ $isEventSink: 1,
+ $isStreamConsumer: 1,
+ $isStreamSink: 1,
+ $isSink: 1
+ };
+ K._GuaranteeSink__addError_closure.prototype = {
+ call$1: function(_) {
+ },
+ $signature: 3
+ };
+ K._GuaranteeSink_addStream_closure.prototype = {
+ call$1: function(_) {
+ var t1 = this.$this;
+ t1._addStreamCompleter = null;
+ t1.set$_addStreamSubscription(null);
+ },
+ $signature: 3
+ };
+ D._MultiChannel.prototype = {
+ _MultiChannel$1: function(_inner, $T) {
+ var t2, _this = this,
+ t1 = _this._mainController;
+ _this._controllers.$indexSet(0, 0, t1);
+ t2 = t1._local._streamController;
+ t2.toString;
+ new P._ControllerStream(t2, H._instanceType(t2)._eval$1("_ControllerStream<1>")).listen$2$onDone(new D._MultiChannel_closure(_this, $T), new D._MultiChannel_closure0(_this));
+ t2 = _this._multi_channel$_inner._streamController;
+ t2.toString;
+ _this._innerStreamSubscription = new P._ControllerStream(t2, H._instanceType(t2)._eval$1("_ControllerStream<1>")).listen$3$onDone$onError(new D._MultiChannel_closure1(_this, $T), _this.get$_closeInnerChannel(), t1._local._sink.get$addError());
+ },
+ virtualChannel$1: function(id) {
+ var t2, t3, controller, _this = this, t1 = {};
+ t1.outputId = t1.inputId = null;
+ if (id != null) {
+ t1.inputId = id;
+ t1.outputId = id + 1;
+ t2 = id;
+ } else {
+ t2 = _this._nextId;
+ t3 = t1.inputId = t2 + 1;
+ t1.outputId = t2;
+ _this._nextId = t2 + 2;
+ t2 = t3;
+ }
+ if (_this._multi_channel$_inner == null) {
+ t1 = _this.$ti;
+ t3 = new P._Future($.Zone__current, type$._Future_dynamic);
+ t3._asyncComplete$1(null);
+ return new D.VirtualChannel(_this, t2, new P._EmptyStream(t1._eval$1("_EmptyStream<1>")), new S.NullStreamSink(t3, t1._eval$1("NullStreamSink<1>")), t1._eval$1("VirtualChannel<1>"));
+ }
+ if (_this._pendingIds.remove$1(0, t2))
+ controller = _this._controllers.$index(0, t2);
+ else {
+ t3 = _this._controllers;
+ if (t3.containsKey$1(t2) || _this._closedIds.contains$1(0, t2))
+ throw H.wrapException(P.ArgumentError$("A virtual channel with id " + H.S(id) + " already exists."));
+ else {
+ controller = B.StreamChannelController$(true, true, _this.$ti._precomputed1);
+ t3.$indexSet(0, t2, controller);
+ }
+ }
+ t2 = controller._local._streamController;
+ t2.toString;
+ new P._ControllerStream(t2, H._instanceType(t2)._eval$1("_ControllerStream<1>")).listen$2$onDone(new D._MultiChannel_virtualChannel_closure(t1, _this), new D._MultiChannel_virtualChannel_closure0(t1, _this));
+ t1 = t1.outputId;
+ t2 = controller._foreign;
+ t3 = t2._streamController;
+ t3.toString;
+ return new D.VirtualChannel(_this, t1, new P._ControllerStream(t3, H._instanceType(t3)._eval$1("_ControllerStream<1>")), t2._sink, _this.$ti._eval$1("VirtualChannel<1>"));
+ },
+ virtualChannel$0: function() {
+ return this.virtualChannel$1(null);
+ },
+ _closeChannel$2: function(inputId, outputId) {
+ var t1, t2, _this = this;
+ _this._closedIds.add$1(0, inputId);
+ t1 = _this._controllers;
+ t1.remove$1(0, inputId)._local._sink.close$0(0);
+ t2 = _this._multi_channel$_inner;
+ if (t2 == null)
+ return;
+ t2._sink.add$1(0, H.setRuntimeTypeInfo([outputId], type$.JSArray_int));
+ if (t1.get$isEmpty(t1))
+ _this._closeInnerChannel$0();
+ },
+ _closeInnerChannel$0: function() {
+ var t1, t2, t3, _i, _this = this;
+ _this._multi_channel$_inner._sink.close$0(0);
+ _this._innerStreamSubscription.cancel$0();
+ _this._multi_channel$_inner = null;
+ for (t1 = _this._controllers, t2 = P.List_List$from(t1.get$values(), true, type$.dynamic), t3 = t2.length, _i = 0; _i < t2.length; t2.length === t3 || (0, H.throwConcurrentModificationError)(t2), ++_i)
+ t2[_i].get$local()._sink.close$0(0);
+ t1.clear$0(0);
+ },
+ $isMultiChannel: 1
+ };
+ D._MultiChannel_closure.prototype = {
+ call$1: function(message) {
+ this.T._check(message);
+ return this.$this._multi_channel$_inner._sink.add$1(0, [0, message]);
+ },
+ $signature: function() {
+ return this.T._eval$1("~(0)");
+ }
+ };
+ D._MultiChannel_closure0.prototype = {
+ call$0: function() {
+ return this.$this._closeChannel$2(0, 0);
+ },
+ $signature: 1
+ };
+ D._MultiChannel_closure1.prototype = {
+ call$1: function(message) {
+ var t3, controller,
+ t1 = J.getInterceptor$asx(message),
+ id = t1.$index(message, 0),
+ t2 = this.$this;
+ if (t2._closedIds.contains$1(0, id))
+ return;
+ H._checkIntNullable(id);
+ t3 = this.T;
+ controller = t2._controllers.putIfAbsent$2(id, new D._MultiChannel__closure(t2, id, t3));
+ t2 = t1.get$length(message);
+ if (typeof t2 !== "number")
+ return t2.$gt();
+ if (t2 > 1)
+ controller._local._sink.add$1(0, t3._check(t1.$index(message, 1)));
+ else
+ controller._local._sink.close$0(0);
+ },
+ $signature: 3
+ };
+ D._MultiChannel__closure.prototype = {
+ call$0: function() {
+ this.$this._pendingIds.add$1(0, H._checkIntNullable(this.id));
+ return B.StreamChannelController$(true, true, this.T);
+ },
+ $signature: function() {
+ return this.T._eval$1("StreamChannelController<0>()");
+ }
+ };
+ D._MultiChannel_virtualChannel_closure.prototype = {
+ call$1: function(message) {
+ var t1 = this.$this;
+ t1.$ti._precomputed1._check(message);
+ return t1._multi_channel$_inner._sink.add$1(0, [this._box_0.outputId, message]);
+ },
+ $signature: function() {
+ return this.$this.$ti._eval$1("~(1)");
+ }
+ };
+ D._MultiChannel_virtualChannel_closure0.prototype = {
+ call$0: function() {
+ var t1 = this._box_0;
+ return this.$this._closeChannel$2(t1.inputId, t1.outputId);
+ },
+ $signature: 1
+ };
+ D.VirtualChannel.prototype = {$isMultiChannel: 1,
+ get$stream: function(receiver) {
+ return this.stream;
+ }
+ };
+ N.StreamChannelCompleter.prototype = {
+ set$_stream_channel_completer$_channel: function(_channel) {
+ this._stream_channel_completer$_channel = this.$ti._eval$1("StreamChannel<1>")._check(_channel);
+ }
+ };
+ B.StreamChannelController.prototype = {
+ get$local: function() {
+ return this._local;
+ },
+ set$_local: function(_local) {
+ this._local = this.$ti._eval$1("StreamChannel<1>")._check(_local);
+ },
+ set$_foreign: function(_foreign) {
+ this._foreign = this.$ti._eval$1("StreamChannel<1>")._check(_foreign);
+ }
+ };
+ R.StreamChannel.prototype = {};
+ R._StreamChannel.prototype = {
+ get$stream: function(receiver) {
+ return this.stream;
+ }
+ };
+ R.StreamChannelMixin.prototype = {$isStreamChannel: 1};
+ E.StringScannerException.prototype = {};
+ S.SpanScanner.prototype = {
+ spanFrom$1: function(startState) {
+ var endPosition = this._string_scanner$_position;
+ return this._sourceFile.span$2(startState.position, endPosition);
+ },
+ matches$1: function(_, pattern) {
+ var _this = this;
+ if (!_this.super$StringScanner$matches(0, pattern)) {
+ _this._lastSpan = null;
+ return false;
+ }
+ _this._lastSpan = _this._sourceFile.span$2(_this._string_scanner$_position, _this.get$lastMatch().get$end());
+ return true;
+ },
+ error$3$length$position: function(_, message, $length, position) {
+ var t1 = this.string;
+ B.validateErrorArgs(t1, null, position, $length);
+ throw H.wrapException(E.StringScannerException$(message, this._sourceFile.span$2(position, position + $length), t1));
+ }
+ };
+ S._SpanScannerState.prototype = {$isLineScannerState: 1};
+ X.StringScanner.prototype = {
+ get$lastMatch: function() {
+ var _this = this;
+ if (_this._string_scanner$_position !== _this._lastMatchPosition)
+ _this._lastMatch = null;
+ return _this._lastMatch;
+ },
+ peekChar$0: function() {
+ var index = this._string_scanner$_position;
+ if (index < 0 || index >= this.string.length)
+ return null;
+ return J.codeUnitAt$1$s(this.string, index);
+ },
+ scan$1: function(pattern) {
+ var _this = this,
+ success = _this.matches$1(0, pattern);
+ if (success)
+ _this._lastMatchPosition = _this._string_scanner$_position = _this._lastMatch.get$end();
+ return success;
+ },
+ expect$2$name: function(pattern, $name) {
+ var t1;
+ if (this.scan$1(pattern))
+ return;
+ if ($name == null)
+ if (type$.RegExp._is(pattern))
+ $name = "/" + pattern.pattern + "/";
+ else {
+ t1 = J.toString$0$(pattern);
+ t1 = H.stringReplaceAllUnchecked(t1, "\\", "\\\\");
+ $name = '"' + H.stringReplaceAllUnchecked(t1, '"', '\\"') + '"';
+ }
+ this.error$3$length$position(0, "expected " + $name + ".", 0, this._string_scanner$_position);
+ },
+ expect$1: function(pattern) {
+ return this.expect$2$name(pattern, null);
+ },
+ matches$1: function(_, pattern) {
+ var _this = this,
+ t1 = J.matchAsPrefix$2$s(pattern, _this.string, _this._string_scanner$_position);
+ _this._lastMatch = t1;
+ _this._lastMatchPosition = _this._string_scanner$_position;
+ return t1 != null;
+ }
+ };
+ A.AsciiGlyphSet.prototype = {
+ glyphOrAscii$2: function(glyph, alternative) {
+ return alternative;
+ },
+ get$horizontalLine: function() {
+ return "-";
+ },
+ get$verticalLine: function() {
+ return "|";
+ },
+ get$topLeftCorner: function() {
+ return ",";
+ },
+ get$bottomLeftCorner: function() {
+ return "'";
+ },
+ get$upEnd: function() {
+ return "'";
+ },
+ get$downEnd: function() {
+ return ",";
+ }
+ };
+ K.UnicodeGlyphSet.prototype = {
+ glyphOrAscii$2: function(glyph, alternative) {
+ return glyph;
+ },
+ get$horizontalLine: function() {
+ return "\u2500";
+ },
+ get$verticalLine: function() {
+ return "\u2502";
+ },
+ get$topLeftCorner: function() {
+ return "\u250c";
+ },
+ get$bottomLeftCorner: function() {
+ return "\u2514";
+ },
+ get$upEnd: function() {
+ return "\u2575";
+ },
+ get$downEnd: function() {
+ return "\u2577";
+ }
+ };
+ L.internalBootstrapBrowserTest_closure.prototype = {
+ call$0: function() {
+ var $async$goto = 0,
+ $async$completer = P._makeAsyncAwaitCompleter(type$.Null),
+ $async$returnValue, t1, serialized, formatter, manager, $async$temp1;
+ var $async$call$0 = P._wrapJsFunctionForAsync(function($async$errorCode, $async$result) {
+ if ($async$errorCode === 1)
+ return P._asyncRethrow($async$result, $async$completer);
+ while (true)
+ switch ($async$goto) {
+ case 0:
+ // Function start
+ manager = type$.SuiteChannelManager._as($.Zone__current.$index(0, $.$get$_currentKey()));
+ if (manager == null)
+ H.throwExpression(P.StateError$("suiteChannel() may only be called within a test worker."));
+ t1 = manager.connectOut$1("test.browser.mapper");
+ t1 = t1.get$stream(t1);
+ $async$temp1 = type$.Map_dynamic_dynamic;
+ $async$goto = 3;
+ return P._asyncAwait(t1.get$first(t1), $async$call$0);
+ case 3:
+ // returning from await.
+ serialized = $async$temp1._as($async$result);
+ if (serialized == null) {
+ // goto return
+ $async$goto = 1;
+ break;
+ }
+ t1 = E.JSStackTraceMapper_deserialize(serialized);
+ formatter = type$.StackTraceFormatter._as($.Zone__current.$index(0, $.$get$_currentKey0()));
+ if (formatter == null)
+ H.throwExpression(P.StateError$("setStackTraceMapper() may only be called within a test worker."));
+ formatter.configure$1$mapper(t1);
+ case 1:
+ // return
+ return P._asyncReturn($async$returnValue, $async$completer);
+ }
+ });
+ return P._asyncStartSync($async$call$0, $async$completer);
+ },
+ $signature: 2
+ };
+ N.postMessageChannel_closure.prototype = {
+ call$1: function(message) {
+ var t1, t2;
+ type$.MessageEvent._check(message);
+ t1 = message.origin;
+ t2 = window.location;
+ return t1 === (t2 && C.Location_methods).get$origin(t2) && J.$eq$(new P._AcceptStructuredCloneDart2Js([], []).convertNativeToDart_AcceptStructuredClone$2$mustCopy(message.data, true), "port");
+ },
+ $signature: 69
+ };
+ N.postMessageChannel_closure0.prototype = {
+ call$1: function(message) {
+ var t2, t3, portSubscription,
+ t1 = type$.MessageEvent,
+ port = J.get$first$ax(t1._check(message).ports);
+ port.toString;
+ t2 = this.controller;
+ t3 = type$.void_Function_MessageEvent._check(new N.postMessageChannel__closure(t2));
+ type$.void_Function._check(null);
+ portSubscription = W._EventStreamSubscription$(port, "message", t3, false, t1);
+ t2 = t2._local._streamController;
+ t2.toString;
+ new P._ControllerStream(t2, H._instanceType(t2)._eval$1("_ControllerStream<1>")).listen$2$onDone(new N.postMessageChannel__closure0(port), new N.postMessageChannel__closure1(port, portSubscription));
+ },
+ $signature: 29
+ };
+ N.postMessageChannel__closure.prototype = {
+ call$1: function(message) {
+ type$.MessageEvent._check(message);
+ this.controller._local._sink.add$1(0, new P._AcceptStructuredCloneDart2Js([], []).convertNativeToDart_AcceptStructuredClone$2$mustCopy(message.data, true));
+ },
+ $signature: 29
+ };
+ N.postMessageChannel__closure0.prototype = {
+ call$1: function(data) {
+ C.MessagePort_methods.postMessage$1(this.port, P.LinkedHashMap_LinkedHashMap$_literal(["data", data], type$.String, type$.dynamic));
+ },
+ $signature: 3
+ };
+ N.postMessageChannel__closure1.prototype = {
+ call$0: function() {
+ var t1 = type$.String;
+ C.MessagePort_methods.postMessage$1(this.port, P.LinkedHashMap_LinkedHashMap$_literal(["event", "done"], t1, t1));
+ this.portSubscription.cancel$0();
+ },
+ $signature: 0
+ };
+ K.ClosedException.prototype = {
+ toString$0: function(_) {
+ return "This test has been closed.";
+ },
+ $isException: 1
+ };
+ X.Declarer.prototype = {
+ test$9$onPlatform$retry$skip$solo$tags$testOn$timeout: function($name, body, onPlatform, retry, skip, solo, tags, testOn, timeout) {
+ var newMetadata, metadata, t1, t2, _this = this;
+ type$.dynamic_Function._check(body);
+ type$.Map_String_dynamic._check(onPlatform);
+ _this._checkNotBuilt$1("test");
+ newMetadata = O.Metadata$parse(onPlatform, H.boolConversionCheck(_this._noRetry) ? 0 : retry, skip, tags, testOn, timeout);
+ newMetadata.validatePlatformSelectors$1(_this._platformVariables);
+ metadata = _this._metadata.merge$1(newMetadata);
+ t1 = _this._declarer$_name;
+ t1 = t1 == null ? $name : t1 + " " + $name;
+ t2 = H.boolConversionCheck(_this._collectTraces) ? Y.Trace_Trace$current(2) : null;
+ C.JSArray_methods.add$1(_this._entries, new U.LocalTest(t1, metadata, t2, false, new X.Declarer_test_closure(_this, body), false));
+ },
+ group$9$onPlatform$retry$skip$solo$tags$testOn$timeout: function($name, body, onPlatform, retry, skip, solo, tags, testOn, timeout) {
+ var t2, newMetadata, t3, metadata, t4, trace, t5, t6, t7, t8, t9, t10, t11, t12, declarer, _this = this, _null = null,
+ t1 = type$.void_Function;
+ t1._check(body);
+ type$.Map_String_dynamic._check(onPlatform);
+ _this._checkNotBuilt$1("group");
+ t2 = H.boolConversionCheck(_this._noRetry);
+ newMetadata = O.Metadata$parse(onPlatform, t2 ? 0 : retry, skip, tags, testOn, timeout);
+ t3 = _this._platformVariables;
+ newMetadata.validatePlatformSelectors$1(t3);
+ metadata = _this._metadata.merge$1(newMetadata);
+ t4 = H.boolConversionCheck(_this._collectTraces);
+ trace = t4 ? Y.Trace_Trace$current(2) : _null;
+ t5 = _this._declarer$_name;
+ t5 = t5 == null ? $name : t5 + " " + $name;
+ t6 = type$.JSArray_of_dynamic_Function;
+ t7 = H.setRuntimeTypeInfo([], t6);
+ t8 = H.setRuntimeTypeInfo([], t6);
+ t9 = H.setRuntimeTypeInfo([], t6);
+ t10 = P.Duration$(0, 12);
+ t6 = H.setRuntimeTypeInfo([], t6);
+ t11 = type$.JSArray_GroupEntry;
+ t12 = H.setRuntimeTypeInfo([], t11);
+ t11 = H.setRuntimeTypeInfo([], t11);
+ declarer = new X.Declarer(_this, t5, metadata, t3, trace, t4, t2, t7, t8, t9, new R.Timeout(t10, _null), t6, t12, t11);
+ t12 = type$.dynamic;
+ P.runZoned(t1._check(new X.Declarer_group_closure(body)), _null, _null, P.LinkedHashMap_LinkedHashMap$_literal([C.Symbol_Drw, declarer], t12, t12), type$.void);
+ t12 = _this._entries;
+ C.JSArray_methods.add$1(t12, declarer.build$0());
+ t1 = t11.length;
+ if (t1 !== 0)
+ C.JSArray_methods.add$1(_this._soloEntries, C.JSArray_methods.get$last(t12));
+ },
+ build$0: function() {
+ var t1, t2, _this = this;
+ _this._checkNotBuilt$1("build");
+ _this._built = true;
+ t1 = _this._entries;
+ t2 = H._arrayInstanceType(t1);
+ return O.Group$(_this._declarer$_name, new H.MappedListIterable(t1, t2._eval$1("GroupEntry(1)")._check(new X.Declarer_build_closure(_this)), t2._eval$1("MappedListIterable<1,GroupEntry>")).toList$0(0), _this._metadata, _this.get$_setUpAll(), _this.get$_tearDownAll(), _this._declarer$_trace);
+ },
+ _checkNotBuilt$1: function($name) {
+ if (!this._built)
+ return;
+ throw H.wrapException(P.StateError$("Can't call " + $name + "() once tests have begun running."));
+ },
+ _runSetUps$0: function() {
+ var $async$goto = 0,
+ $async$completer = P._makeAsyncAwaitCompleter(type$.dynamic),
+ $async$self = this, t1;
+ var $async$_runSetUps$0 = P._wrapJsFunctionForAsync(function($async$errorCode, $async$result) {
+ if ($async$errorCode === 1)
+ return P._asyncRethrow($async$result, $async$completer);
+ while (true)
+ switch ($async$goto) {
+ case 0:
+ // Function start
+ t1 = $async$self._declarer$_parent;
+ $async$goto = t1 != null ? 2 : 3;
+ break;
+ case 2:
+ // then
+ $async$goto = 4;
+ return P._asyncAwait(t1._runSetUps$0(), $async$_runSetUps$0);
+ case 4:
+ // returning from await.
+ case 3:
+ // join
+ $async$goto = 5;
+ return P._asyncAwait(P.Future_forEach($async$self._setUps, new X.Declarer__runSetUps_closure(), type$.dynamic_Function), $async$_runSetUps$0);
+ case 5:
+ // returning from await.
+ // implicit return
+ return P._asyncReturn(null, $async$completer);
+ }
+ });
+ return P._asyncStartSync($async$_runSetUps$0, $async$completer);
+ },
+ get$_setUpAll: function() {
+ return null;
+ },
+ get$_tearDownAll: function() {
+ var _this = this,
+ t1 = _this._tearDownAlls.length;
+ if (t1 === 0)
+ return null;
+ t1 = _this._declarer$_name;
+ t1 = t1 == null ? "(tearDownAll)" : t1 + " (tearDownAll)";
+ return new U.LocalTest(t1, _this._metadata.change$1$timeout(_this._timeout), null, true, new X.Declarer__tearDownAll_closure(_this), false);
+ }
+ };
+ X.Declarer_test_closure.prototype = {
+ call$0: function() {
+ var $async$goto = 0,
+ $async$completer = P._makeAsyncAwaitCompleter(type$.Null),
+ $async$returnValue, $async$self = this, declarer, declarer0, t1, t2, t3, t4, t5, _i, tearDown, t6, parents;
+ var $async$call$0 = P._wrapJsFunctionForAsync(function($async$errorCode, $async$result) {
+ if ($async$errorCode === 1)
+ return P._asyncRethrow($async$result, $async$completer);
+ while (true)
+ $async$outer:
+ switch ($async$goto) {
+ case 0:
+ // Function start
+ parents = H.setRuntimeTypeInfo([], type$.JSArray_Declarer);
+ for (declarer = $async$self.$this, declarer0 = declarer; declarer0 != null; declarer0 = declarer0._declarer$_parent)
+ C.JSArray_methods.add$1(parents, declarer0);
+ for (t1 = type$.ReversedListIterable_Declarer, t2 = new H.ReversedListIterable(parents, t1), t1 = new H.ListIterator(t2, t2.get$length(t2), t1._eval$1("ListIterator<ListIterable.E>")), t2 = type$.Invoker, t3 = type$.dynamic_Function, t4 = type$.Declarer; t1.moveNext$0();)
+ for (t5 = t1.__internal$_current._tearDowns, _i = 0; false; ++_i) {
+ if (_i >= 0) {
+ $async$returnValue = H.ioore(t5, _i);
+ // goto return
+ $async$goto = 1;
+ break $async$outer;
+ }
+ tearDown = t5[_i];
+ t6 = t2._as($.Zone__current.$index(0, C.Symbol_cQL));
+ t6.toString;
+ t3._check(tearDown);
+ if (H.boolConversionCheck(H._asBoolNullable($.Zone__current.$index(0, t6._closableKey))) && t6._onCloseCompleter.future._state !== 0)
+ H.throwExpression(K.ClosedException$());
+ if (t6._invoker$_controller._liveTest._live_test_controller$_controller._test.isScaffoldAll)
+ C.JSArray_methods.add$1(t4._as($.Zone__current.$index(0, C.Symbol_Drw))._tearDownAlls, tearDown);
+ else
+ C.JSArray_methods.add$1(t6._invoker$_tearDowns, tearDown);
+ }
+ t1 = type$.dynamic;
+ $async$goto = 3;
+ return P._asyncAwait(P.runZoned(new X.Declarer_test__closure(declarer, $async$self.body), null, null, P.LinkedHashMap_LinkedHashMap$_literal([C.Symbol_Drw, declarer], t1, t1), type$.Future_void), $async$call$0);
+ case 3:
+ // returning from await.
+ case 1:
+ // return
+ return P._asyncReturn($async$returnValue, $async$completer);
+ }
+ });
+ return P._asyncStartSync($async$call$0, $async$completer);
+ },
+ $signature: 2
+ };
+ X.Declarer_test__closure.prototype = {
+ call$0: function() {
+ return type$.Invoker._as($.Zone__current.$index(0, C.Symbol_cQL)).waitForOutstandingCallbacks$1(new X.Declarer_test___closure(this.$this, this.body));
+ },
+ $signature: 13
+ };
+ X.Declarer_test___closure.prototype = {
+ call$0: function() {
+ var $async$goto = 0,
+ $async$completer = P._makeAsyncAwaitCompleter(type$.Null),
+ $async$self = this;
+ var $async$call$0 = P._wrapJsFunctionForAsync(function($async$errorCode, $async$result) {
+ if ($async$errorCode === 1)
+ return P._asyncRethrow($async$result, $async$completer);
+ while (true)
+ switch ($async$goto) {
+ case 0:
+ // Function start
+ $async$goto = 2;
+ return P._asyncAwait($async$self.$this._runSetUps$0(), $async$call$0);
+ case 2:
+ // returning from await.
+ $async$goto = 3;
+ return P._asyncAwait($async$self.body.call$0(), $async$call$0);
+ case 3:
+ // returning from await.
+ // implicit return
+ return P._asyncReturn(null, $async$completer);
+ }
+ });
+ return P._asyncStartSync($async$call$0, $async$completer);
+ },
+ $signature: 2
+ };
+ X.Declarer_group_closure.prototype = {
+ call$0: function() {
+ if (!type$.Future_dynamic._is(this.body.call$0()))
+ return;
+ throw H.wrapException(P.ArgumentError$("Groups may not be async."));
+ },
+ $signature: 0
+ };
+ X.Declarer_build_closure.prototype = {
+ call$1: function(entry) {
+ var t1;
+ type$.GroupEntry._check(entry);
+ t1 = this.$this._soloEntries;
+ return t1.length !== 0 && !C.JSArray_methods.contains$1(t1, entry) ? new U.LocalTest(entry.get$name(entry), entry.get$metadata().change$2$skip$skipReason(true, 'does not have "solo"'), null, false, null, true) : entry;
+ },
+ $signature: 22
+ };
+ X.Declarer__runSetUps_closure.prototype = {
+ call$1: function(setUp) {
+ return setUp.call$0();
+ },
+ $signature: 18
+ };
+ X.Declarer__tearDownAll_closure.prototype = {
+ call$0: function() {
+ var t1 = this.$this,
+ t2 = type$.dynamic;
+ return P.runZoned(new X.Declarer__tearDownAll__closure(t1), null, null, P.LinkedHashMap_LinkedHashMap$_literal([C.Symbol_Drw, t1], t2, t2), type$.Future_Null);
+ },
+ $signature: 2
+ };
+ X.Declarer__tearDownAll__closure.prototype = {
+ call$0: function() {
+ return type$.Invoker._as($.Zone__current.$index(0, C.Symbol_cQL)).unclosable$1$1(new X.Declarer__tearDownAll___closure(this.$this), type$.Future_Null);
+ },
+ $signature: 2
+ };
+ X.Declarer__tearDownAll___closure.prototype = {
+ call$0: function() {
+ var $async$goto = 0,
+ $async$completer = P._makeAsyncAwaitCompleter(type$.Null),
+ $async$returnValue, $async$self = this, t1, t2;
+ var $async$call$0 = P._wrapJsFunctionForAsync(function($async$errorCode, $async$result) {
+ if ($async$errorCode === 1)
+ return P._asyncRethrow($async$result, $async$completer);
+ while (true)
+ switch ($async$goto) {
+ case 0:
+ // Function start
+ t1 = $async$self.$this._tearDownAlls;
+ case 3:
+ // for condition
+ if (!(t2 = t1.length, t2 !== 0)) {
+ // goto after for
+ $async$goto = 4;
+ break;
+ }
+ if (0 >= t2) {
+ $async$returnValue = H.ioore(t1, -1);
+ // goto return
+ $async$goto = 1;
+ break;
+ }
+ $async$goto = 5;
+ return P._asyncAwait(V.errorsDontStopTest(t1.pop()), $async$call$0);
+ case 5:
+ // returning from await.
+ // goto for condition
+ $async$goto = 3;
+ break;
+ case 4:
+ // after for
+ case 1:
+ // return
+ return P._asyncReturn($async$returnValue, $async$completer);
+ }
+ });
+ return P._asyncStartSync($async$call$0, $async$completer);
+ },
+ $signature: 2
+ };
+ O.Group.prototype = {
+ forPlatform$1: function(platform) {
+ var newMetadata, filtered, _this = this,
+ t1 = _this.metadata;
+ if (!H.boolConversionCheck(t1.testOn.evaluate$1(platform)))
+ return null;
+ newMetadata = t1.forPlatform$1(platform);
+ filtered = _this._group$_map$1(new O.Group_forPlatform_closure(platform));
+ if (filtered.length === 0 && _this.entries.length !== 0)
+ return null;
+ return O.Group$(_this.name, filtered, newMetadata, _this.setUpAll, _this.tearDownAll, _this.trace);
+ },
+ _group$_map$1: function(callback) {
+ var t1 = this.entries,
+ t2 = H._arrayInstanceType(t1),
+ t3 = t2._eval$1("MappedListIterable<1,GroupEntry>");
+ t3 = new H.MappedListIterable(t1, t2._eval$1("GroupEntry(1)")._check(new O.Group__map_closure(type$.GroupEntry_Function_GroupEntry._check(callback))), t3).super$Iterable$where(0, t3._eval$1("bool(ListIterable.E)")._check(new O.Group__map_closure0()));
+ return P.List_List$from(t3, true, t3.$ti._eval$1("Iterable.E"));
+ },
+ $isGroupEntry: 1,
+ get$name: function(receiver) {
+ return this.name;
+ },
+ get$metadata: function() {
+ return this.metadata;
+ }
+ };
+ O.Group_forPlatform_closure.prototype = {
+ call$1: function(entry) {
+ return entry.forPlatform$1(this.platform);
+ },
+ $signature: 22
+ };
+ O.Group__map_closure.prototype = {
+ call$1: function(entry) {
+ return this.callback.call$1(type$.GroupEntry._check(entry));
+ },
+ $signature: 22
+ };
+ O.Group__map_closure0.prototype = {
+ call$1: function(entry) {
+ return type$.GroupEntry._check(entry) != null;
+ },
+ $signature: 72
+ };
+ V.GroupEntry.prototype = {};
+ U.LocalTest.prototype = {
+ load$2$groups: function(suite, groups) {
+ var t1, invoker;
+ type$.Iterable_Group._check(groups);
+ t1 = new P._AsyncCompleter(new P._Future($.Zone__current, type$._Future_void), type$._AsyncCompleter_void);
+ invoker = new U.Invoker(this._guarded, new P.Object(), t1, H.setRuntimeTypeInfo([], type$.JSArray_Zone), new P.Object(), H.setRuntimeTypeInfo([], type$.JSArray_of_dynamic_Function), H.setRuntimeTypeInfo([], type$.JSArray_String));
+ t1 = V.LiveTestController$(suite, this, invoker.get$_invoker$_onRun(), t1.get$complete(), groups);
+ invoker._invoker$_controller = t1;
+ return t1._liveTest;
+ },
+ forPlatform$1: function(platform) {
+ var _this = this,
+ t1 = _this.metadata;
+ if (!H.boolConversionCheck(t1.testOn.evaluate$1(platform)))
+ return null;
+ return new U.LocalTest(_this.name, t1.forPlatform$1(platform), _this.trace, _this.isScaffoldAll, _this._body, _this._guarded);
+ },
+ get$name: function(receiver) {
+ return this.name;
+ },
+ get$metadata: function() {
+ return this.metadata;
+ }
+ };
+ U.Invoker.prototype = {
+ get$_outstandingCallbacks: function() {
+ var counter = type$._AsyncCounter._as($.Zone__current.$index(0, this._counterKey));
+ if (counter != null)
+ return counter;
+ throw H.wrapException(P.StateError$("Can't add or remove outstanding callbacks outside of a test body."));
+ },
+ addOutstandingCallback$0: function() {
+ if (H.boolConversionCheck(H._asBoolNullable($.Zone__current.$index(0, this._closableKey))) && this._onCloseCompleter.future._state !== 0)
+ throw H.wrapException(K.ClosedException$());
+ ++this.get$_outstandingCallbacks()._count;
+ },
+ waitForOutstandingCallbacks$1: function(fn) {
+ var t2, counter, t3, _this = this, t1 = {};
+ type$.FutureOr_void_Function._check(fn);
+ _this.heartbeat$0();
+ t1.zone = null;
+ t2 = new P._Future($.Zone__current, type$._Future_void);
+ counter = new U._AsyncCounter(new P._AsyncCompleter(t2, type$._AsyncCompleter_void));
+ t3 = type$.dynamic;
+ P.runZoned(new U.Invoker_waitForOutstandingCallbacks_closure(t1, _this, fn, counter), null, null, P.LinkedHashMap_LinkedHashMap$_literal([_this._counterKey, counter], t3, t3), type$.Future_Null);
+ return t2.whenComplete$1(new U.Invoker_waitForOutstandingCallbacks_closure0(t1, _this));
+ },
+ unclosable$1$1: function(fn, $T) {
+ var t1;
+ $T._eval$1("0()")._check(fn);
+ this.heartbeat$0();
+ t1 = type$.dynamic;
+ return P.runZoned(fn, null, null, P.LinkedHashMap_LinkedHashMap$_literal([this._closableKey, false], t1, t1), $T);
+ },
+ heartbeat$0: function() {
+ var t1, timeout, _this = this;
+ if (_this._invoker$_controller._liveTest._live_test_controller$_controller._live_test_controller$_state.status === C.Status_complete)
+ return;
+ t1 = _this._timeoutTimer;
+ if (t1 != null)
+ t1.cancel$0();
+ timeout = _this._invoker$_controller._liveTest._live_test_controller$_controller._test.metadata.timeout.apply$1(C.Duration_30000000);
+ if (timeout == null)
+ return;
+ _this._timeoutTimer = _this._invokerZone.createTimer$2(timeout, new U.Invoker_heartbeat_closure(_this, new U.Invoker_heartbeat_message(timeout), timeout));
+ },
+ _handleError$3: function(zone, error, stackTrace) {
+ var t2, t3, t4, shouldBeDone, _this = this, t1 = {};
+ t1.stackTrace = stackTrace;
+ if (_this._runCount !== zone.$index(0, C.Symbol_runCount))
+ return;
+ zone.run$1$1(new U.Invoker__handleError_closure(t1), type$.Null);
+ t2 = _this._invoker$_controller;
+ t3 = t2._liveTest._live_test_controller$_controller._live_test_controller$_state;
+ if (t3.status === C.Status_complete) {
+ t4 = t3.result;
+ shouldBeDone = t4 === C.Result_success || t4 === C.Result_skipped;
+ } else
+ shouldBeDone = false;
+ if (!(error instanceof G.TestFailure))
+ t2.setState$1(C.State_Status_complete_Result_error);
+ else if (t3.result !== C.Result_error)
+ t2.setState$1(C.State_Status_complete_Result_failure);
+ _this._invoker$_controller.addError$2(error, t1.stackTrace);
+ zone.run$1$1(new U.Invoker__handleError_closure0(_this), type$.void);
+ t2 = _this._invoker$_controller._liveTest._live_test_controller$_controller;
+ if (t2._test.metadata._chainStackTraces === false)
+ C.JSArray_methods.add$1(_this._printsOnFailure, "Consider enabling the flag chain-stack-traces to receive more detailed exceptions.\nFor example, 'pub run test --chain-stack-traces'.");
+ t2 = _this._printsOnFailure;
+ if (t2.length !== 0) {
+ P.print(C.JSArray_methods.join$1(t2, "\n\n"));
+ C.JSArray_methods.set$length(t2, 0);
+ }
+ if (!shouldBeDone)
+ return;
+ _this._invoker$_controller._liveTest._live_test_controller$_controller._live_test_controller$_suite.toString;
+ _this._handleError$3(zone, "This test failed after it had already completed. Make sure to use [expectAsync]\nor the [completes] matcher when testing async code.", t1.stackTrace);
+ },
+ _handleError$2: function(zone, error) {
+ return this._handleError$3(zone, error, null);
+ },
+ _invoker$_onRun$0: function() {
+ var t1, t2, _this = this;
+ _this._invoker$_controller.setState$1(C.State_Status_running_Result_success);
+ t1 = $.Zone__current;
+ ++_this._runCount;
+ t2 = _this._invoker$_controller._liveTest._live_test_controller$_controller;
+ U.Chain_capture(new U.Invoker__onRun_closure(_this, new U._AsyncCounter(new P._AsyncCompleter(new P._Future(t1, type$._Future_void), type$._AsyncCompleter_void))), false, t2._test.metadata._chainStackTraces !== false, type$.Null);
+ },
+ _runTearDowns$0: function() {
+ var $async$goto = 0,
+ $async$completer = P._makeAsyncAwaitCompleter(type$.void),
+ $async$returnValue, $async$self = this, t1, t2;
+ var $async$_runTearDowns$0 = P._wrapJsFunctionForAsync(function($async$errorCode, $async$result) {
+ if ($async$errorCode === 1)
+ return P._asyncRethrow($async$result, $async$completer);
+ while (true)
+ switch ($async$goto) {
+ case 0:
+ // Function start
+ t1 = $async$self._invoker$_tearDowns;
+ case 3:
+ // for condition
+ if (!(t2 = t1.length, t2 !== 0)) {
+ // goto after for
+ $async$goto = 4;
+ break;
+ }
+ if (0 >= t2) {
+ $async$returnValue = H.ioore(t1, -1);
+ // goto return
+ $async$goto = 1;
+ break;
+ }
+ $async$goto = 5;
+ return P._asyncAwait(V.errorsDontStopTest(t1.pop()), $async$_runTearDowns$0);
+ case 5:
+ // returning from await.
+ // goto for condition
+ $async$goto = 3;
+ break;
+ case 4:
+ // after for
+ case 1:
+ // return
+ return P._asyncReturn($async$returnValue, $async$completer);
+ }
+ });
+ return P._asyncStartSync($async$_runTearDowns$0, $async$completer);
+ }
+ };
+ U.Invoker_guard_closure.prototype = {
+ call$5: function($self, _, zone, error, stackTrace) {
+ var invoker;
+ type$.StackTrace._check(stackTrace);
+ invoker = zone.$index(0, C.Symbol_cQL);
+ if (invoker != null)
+ $self.get$parent($self).run$1$1(new U.Invoker_guard__closure(invoker, zone, error, stackTrace), type$.dynamic);
+ else
+ $self.get$parent($self).handleUncaughtError$2(error, stackTrace);
+ },
+ $signature: 28
+ };
+ U.Invoker_guard__closure.prototype = {
+ call$0: function() {
+ var _this = this;
+ return _this.invoker._handleError$3(_this.zone, _this.error, _this.stackTrace);
+ },
+ $signature: 34
+ };
+ U.Invoker_waitForOutstandingCallbacks_closure.prototype = {
+ call$0: function() {
+ var $async$goto = 0,
+ $async$completer = P._makeAsyncAwaitCompleter(type$.Null),
+ $async$self = this, zone;
+ var $async$call$0 = P._wrapJsFunctionForAsync(function($async$errorCode, $async$result) {
+ if ($async$errorCode === 1)
+ return P._asyncRethrow($async$result, $async$completer);
+ while (true)
+ switch ($async$goto) {
+ case 0:
+ // Function start
+ zone = $.Zone__current;
+ $async$self._box_0.zone = zone;
+ C.JSArray_methods.add$1($async$self.$this._outstandingCallbackZones, zone);
+ $async$goto = 2;
+ return P._asyncAwait($async$self.fn.call$0(), $async$call$0);
+ case 2:
+ // returning from await.
+ $async$self.counter.decrement$0();
+ // implicit return
+ return P._asyncReturn(null, $async$completer);
+ }
+ });
+ return P._asyncStartSync($async$call$0, $async$completer);
+ },
+ $signature: 2
+ };
+ U.Invoker_waitForOutstandingCallbacks_closure0.prototype = {
+ call$0: function() {
+ C.JSArray_methods.remove$1(this.$this._outstandingCallbackZones, this._box_0.zone);
+ },
+ $signature: 0
+ };
+ U.Invoker_heartbeat_message.prototype = {
+ call$0: function() {
+ var message,
+ t1 = this.timeout._duration,
+ minutes = C.JSInt_methods._tdivFast$1(t1, 60000000),
+ seconds = C.JSInt_methods.$mod(C.JSInt_methods._tdivFast$1(t1, 1000000), 60),
+ decaseconds = C.JSInt_methods._tdivFast$1(C.JSInt_methods.$mod(C.JSInt_methods._tdivFast$1(t1, 1000), 1000), 100),
+ t2 = minutes !== 0,
+ t3 = t2 ? "" + minutes + " minutes" : "";
+ if (!t2 || seconds !== 0) {
+ t2 = t2 ? t3 + ", " : t3;
+ t2 += seconds;
+ t2 = (decaseconds !== 0 ? t2 + ("." + decaseconds) : t2) + " seconds";
+ } else
+ t2 = t3;
+ message = "Test timed out after " + (t2.charCodeAt(0) == 0 ? t2 : t2) + ".";
+ return t1 === 30000000 ? message + " See https://pub.dev/packages/test#timeouts" : message;
+ },
+ $signature: 74
+ };
+ U.Invoker_heartbeat_closure.prototype = {
+ call$0: function() {
+ var t1 = this.$this;
+ C.JSArray_methods.get$last(t1._outstandingCallbackZones).run$1$1(new U.Invoker_heartbeat__closure(t1, this.message, this.timeout), type$.Null);
+ },
+ $signature: 0
+ };
+ U.Invoker_heartbeat__closure.prototype = {
+ call$0: function() {
+ var t1 = this.$this;
+ if (t1._invoker$_controller._liveTest._live_test_controller$_controller._live_test_controller$_state.status === C.Status_complete)
+ return;
+ t1._handleError$2($.Zone__current, new P.TimeoutException(this.message.call$0(), this.timeout));
+ },
+ $signature: 0
+ };
+ U.Invoker__handleError_closure.prototype = {
+ call$0: function() {
+ var t1 = this._box_0,
+ t2 = t1.stackTrace;
+ if (t2 == null)
+ t1.stackTrace = U.Chain_Chain$current();
+ else
+ t1.stackTrace = U.Chain_Chain$forTrace(t2);
+ },
+ $signature: 0
+ };
+ U.Invoker__handleError_closure0.prototype = {
+ call$0: function() {
+ var t1 = this.$this.get$_outstandingCallbacks()._invoker$_completer;
+ if (t1.future._state === 0)
+ t1.complete$0();
+ return null;
+ },
+ $signature: 1
+ };
+ U.Invoker__onRun_closure.prototype = {
+ call$0: function() {
+ var t1 = this.$this,
+ t2 = type$.void_Function._check(new U.Invoker__onRun__closure(t1, this.outstandingCallbacksForBody));
+ if (t1._guarded)
+ U.Invoker_guard(t2, type$.void);
+ else
+ t2.call$0();
+ },
+ $signature: 0
+ };
+ U.Invoker__onRun__closure.prototype = {
+ call$0: function() {
+ var _null = null,
+ t1 = this.$this,
+ t2 = type$.dynamic;
+ t2 = P.LinkedHashMap_LinkedHashMap$_literal([C.Symbol_cQL, t1, t1._counterKey, this.outstandingCallbacksForBody, t1._closableKey, true, C.Symbol_runCount, t1._runCount], t2, t2);
+ P.runZoned(new U.Invoker__onRun___closure(t1), _null, P._ZoneSpecification$(_null, _null, _null, _null, _null, new U.Invoker__onRun___closure0(t1), _null, _null, _null, _null, _null, _null, _null), t2, type$.Future_Null);
+ },
+ $signature: 0
+ };
+ U.Invoker__onRun___closure.prototype = {
+ call$0: function() {
+ var $async$goto = 0,
+ $async$completer = P._makeAsyncAwaitCompleter(type$.Null),
+ $async$returnValue, $async$self = this, t3, t4, t5, t6, t1, t2;
+ var $async$call$0 = P._wrapJsFunctionForAsync(function($async$errorCode, $async$result) {
+ if ($async$errorCode === 1)
+ return P._asyncRethrow($async$result, $async$completer);
+ while (true)
+ switch ($async$goto) {
+ case 0:
+ // Function start
+ t1 = $async$self.$this;
+ t2 = $.Zone__current;
+ t1._invokerZone = t2;
+ C.JSArray_methods.add$1(t1._outstandingCallbackZones, t2);
+ P.Future_Future(new U.Invoker__onRun____closure(t1), type$.void);
+ $async$goto = 3;
+ return P._asyncAwait(t1.get$_outstandingCallbacks()._invoker$_completer.future, $async$call$0);
+ case 3:
+ // returning from await.
+ t2 = t1._timeoutTimer;
+ if (t2 != null)
+ t2.cancel$0();
+ t2 = t1._invoker$_controller;
+ t3 = t2._liveTest._live_test_controller$_controller;
+ t4 = t3._live_test_controller$_state.result;
+ if (t4 !== C.Result_success) {
+ t5 = t1._runCount;
+ t6 = t3._test.metadata._retry;
+ t5 = t5 < (t6 == null ? 0 : t6) + 1;
+ } else
+ t5 = false;
+ if (t5) {
+ t2.message$1(0, new D.Message(C.MessageType_print, "Retry: " + H.S(t3._test.name)));
+ t1._invoker$_onRun$0();
+ // goto return
+ $async$goto = 1;
+ break;
+ }
+ t2.setState$1(new G.State(C.Status_complete, t4));
+ t1._invoker$_controller.completer.complete$0();
+ case 1:
+ // return
+ return P._asyncReturn($async$returnValue, $async$completer);
+ }
+ });
+ return P._asyncStartSync($async$call$0, $async$completer);
+ },
+ $signature: 2
+ };
+ U.Invoker__onRun____closure.prototype = {
+ call$0: function() {
+ var $async$goto = 0,
+ $async$completer = P._makeAsyncAwaitCompleter(type$.Null),
+ $async$self = this, t1;
+ var $async$call$0 = P._wrapJsFunctionForAsync(function($async$errorCode, $async$result) {
+ if ($async$errorCode === 1)
+ return P._asyncRethrow($async$result, $async$completer);
+ while (true)
+ switch ($async$goto) {
+ case 0:
+ // Function start
+ t1 = $async$self.$this;
+ $async$goto = 2;
+ return P._asyncAwait(t1._invoker$_controller._liveTest._live_test_controller$_controller._test._body.call$0(), $async$call$0);
+ case 2:
+ // returning from await.
+ $async$goto = 3;
+ return P._asyncAwait(t1.unclosable$1$1(t1.get$_runTearDowns(), type$.Future_void), $async$call$0);
+ case 3:
+ // returning from await.
+ t1.heartbeat$0();
+ t1.get$_outstandingCallbacks().decrement$0();
+ // implicit return
+ return P._asyncReturn(null, $async$completer);
+ }
+ });
+ return P._asyncStartSync($async$call$0, $async$completer);
+ },
+ $signature: 2
+ };
+ U.Invoker__onRun___closure0.prototype = {
+ call$4: function(_, __, ___, line) {
+ H._checkStringNullable(line);
+ return this.$this._invoker$_controller.message$1(0, new D.Message(C.MessageType_print, line));
+ },
+ $signature: 37
+ };
+ U._AsyncCounter.prototype = {
+ decrement$0: function() {
+ if (--this._count !== 0)
+ return;
+ var t1 = this._invoker$_completer;
+ if (t1.future._state !== 0)
+ return;
+ t1.complete$0();
+ }
+ };
+ Z.LiveTest.prototype = {};
+ V._LiveTest.prototype = {
+ run$0: function() {
+ var t1 = this._live_test_controller$_controller;
+ if (t1._runCalled)
+ H.throwExpression(P.StateError$("LiveTest.run() may not be called more than once."));
+ else if ((t1._onErrorController._state & 4) !== 0)
+ H.throwExpression(P.StateError$("LiveTest.run() may not be called for a closed test."));
+ t1._runCalled = true;
+ t1._onRun.call$0();
+ return t1._liveTest._live_test_controller$_controller.completer.future;
+ }
+ };
+ V.LiveTestController.prototype = {
+ addError$2: function(error, stackTrace) {
+ var asyncError,
+ t1 = this._onErrorController;
+ if ((t1._state & 4) !== 0)
+ return;
+ asyncError = new P.AsyncError(error, U.Chain_Chain$forTrace(stackTrace));
+ C.JSArray_methods.add$1(this._errors, asyncError);
+ t1.add$1(0, asyncError);
+ },
+ setState$1: function(newState) {
+ var _this = this;
+ if ((_this._onErrorController._state & 4) !== 0)
+ return;
+ if (_this._live_test_controller$_state.$eq(0, newState))
+ return;
+ _this._live_test_controller$_state = newState;
+ _this._onStateChangeController.add$1(0, newState);
+ },
+ message$1: function(_, message) {
+ var t1 = this._onMessageController;
+ if (t1._firstSubscription != null)
+ t1.add$1(0, message);
+ else
+ H.printString(message.text);
+ },
+ _live_test_controller$_run$0: function() {
+ var _this = this;
+ if (_this._runCalled)
+ throw H.wrapException(P.StateError$("LiveTest.run() may not be called more than once."));
+ else if ((_this._onErrorController._state & 4) !== 0)
+ throw H.wrapException(P.StateError$("LiveTest.run() may not be called for a closed test."));
+ _this._runCalled = true;
+ _this._onRun.call$0();
+ return _this._liveTest._live_test_controller$_controller.completer.future;
+ },
+ _live_test_controller$_close$0: function() {
+ var _this = this,
+ t1 = _this._onErrorController;
+ if ((t1._state & 4) !== 0)
+ return _this.completer.future;
+ _this._onStateChangeController.close$0(0);
+ t1.close$0(0);
+ if (_this._runCalled)
+ _this._onClose.call$0();
+ else
+ _this.completer.complete$0();
+ return _this.completer.future;
+ }
+ };
+ D.Message.prototype = {};
+ D.MessageType.prototype = {
+ toString$0: function(_) {
+ return this.name;
+ }
+ };
+ O.Metadata.prototype = {
+ _validateTags$0: function() {
+ var t1 = this.tags.where$1(0, new O.Metadata__validateTags_closure()),
+ t2 = t1.$ti,
+ t3 = t2._eval$1("MappedIterable<1,String>"),
+ invalidTags = P.List_List$from(new H.MappedIterable(t1, t2._eval$1("String(1)")._check(new O.Metadata__validateTags_closure0()), t3), true, t3._eval$1("Iterable.E"));
+ t1 = invalidTags.length;
+ if (t1 === 0)
+ return;
+ throw H.wrapException(P.ArgumentError$("Invalid " + B.pluralize("tag", t1) + " " + H.S(B.toSentence(invalidTags)) + ". Tags must be (optionally hyphenated) Dart identifiers."));
+ },
+ validatePlatformSelectors$1: function(validVariables) {
+ type$.Set_String._check(validVariables);
+ this.testOn.validate$1(validVariables);
+ this.onPlatform.forEach$1(0, new O.Metadata_validatePlatformSelectors_closure(validVariables));
+ },
+ merge$1: function(other) {
+ var t4, t5, t6, t7, t8, t9, t10, _this = this,
+ t1 = _this.testOn.intersection$1(other.testOn),
+ t2 = _this.timeout.merge$1(other.timeout),
+ t3 = other._skip;
+ if (t3 == null)
+ t3 = _this._skip;
+ t4 = other.skipReason;
+ if (t4 == null)
+ t4 = _this.skipReason;
+ t5 = other._verboseTrace;
+ if (t5 == null)
+ t5 = _this._verboseTrace;
+ t6 = other._chainStackTraces;
+ if (t6 == null)
+ t6 = _this._chainStackTraces;
+ t7 = other._retry;
+ if (t7 == null)
+ t7 = _this._retry;
+ t8 = _this.tags.union$1(other.tags);
+ t9 = type$.Metadata;
+ t10 = Y.mergeMaps(_this.onPlatform, other.onPlatform, new O.Metadata_merge_closure(), type$.PlatformSelector, t9);
+ return O.Metadata_Metadata(t6, Y.mergeMaps(_this.forTag, other.forTag, new O.Metadata_merge_closure0(), type$.BooleanSelector, t9), t10, t7, t3, t4, t8, t1, t2, t5);
+ },
+ change$4$onPlatform$skip$skipReason$timeout: function(onPlatform, skip, skipReason, timeout) {
+ var _this = this;
+ type$.Map_PlatformSelector_Metadata._check(onPlatform);
+ type$.Set_String._check(null);
+ type$.Map_BooleanSelector_Metadata._check(null);
+ if (timeout == null)
+ timeout = _this.timeout;
+ if (skip == null)
+ skip = _this._skip;
+ if (skipReason == null)
+ skipReason = _this.skipReason;
+ if (onPlatform == null)
+ onPlatform = _this.onPlatform;
+ return O.Metadata_Metadata(_this._chainStackTraces, _this.forTag, onPlatform, _this._retry, skip, skipReason, _this.tags, _this.testOn, timeout, _this._verboseTrace);
+ },
+ change$1$onPlatform: function(onPlatform) {
+ return this.change$4$onPlatform$skip$skipReason$timeout(onPlatform, null, null, null);
+ },
+ change$1$timeout: function(timeout) {
+ return this.change$4$onPlatform$skip$skipReason$timeout(null, null, null, timeout);
+ },
+ change$2$skip$skipReason: function(skip, skipReason) {
+ return this.change$4$onPlatform$skip$skipReason$timeout(null, skip, skipReason, null);
+ },
+ forPlatform$1: function(platform) {
+ var t1 = {},
+ t2 = this.onPlatform;
+ if (t2.get$isEmpty(t2))
+ return this;
+ t1.metadata = this;
+ t2.forEach$1(0, new O.Metadata_forPlatform_closure(t1, platform));
+ return t1.metadata.change$1$onPlatform(P.LinkedHashMap_LinkedHashMap$_empty(type$.PlatformSelector, type$.Metadata));
+ },
+ serialize$0: function() {
+ var t1, t2, t3, _this = this, serializedOnPlatform = [];
+ _this.onPlatform.forEach$1(0, new O.Metadata_serialize_closure(serializedOnPlatform));
+ t1 = _this.testOn._platform_selector$_inner;
+ t2 = J.getInterceptor$(t1);
+ t3 = t2.$eq(t1, C.C_All);
+ t1 = t3 ? null : t2.toString$0(t1);
+ t2 = type$.String;
+ return P.LinkedHashMap_LinkedHashMap$_literal(["testOn", t1, "timeout", _this._serializeTimeout$1(_this.timeout), "skip", _this._skip, "skipReason", _this.skipReason, "verboseTrace", _this._verboseTrace, "chainStackTraces", _this._chainStackTraces, "retry", _this._retry, "tags", _this.tags.toList$0(0), "onPlatform", serializedOnPlatform, "forTag", _this.forTag.map$2$1(0, new O.Metadata_serialize_closure0(), t2, type$.Map_String_dynamic)], t2, type$.dynamic);
+ },
+ _serializeTimeout$1: function(timeout) {
+ var t1;
+ if (timeout.$eq(0, C.Timeout_null_null))
+ return "none";
+ t1 = timeout.duration;
+ t1 = t1 == null ? null : t1._duration;
+ return P.LinkedHashMap_LinkedHashMap$_literal(["duration", t1, "scaleFactor", timeout.scaleFactor], type$.String, type$.num);
+ }
+ };
+ O.Metadata_Metadata__unresolved.prototype = {
+ call$0: function() {
+ var _this = this,
+ t1 = _this._box_0,
+ t2 = t1.tags;
+ return O.Metadata$_(_this.chainStackTraces, t1.forTag, _this.onPlatform, _this.retry, _this.skip, _this.skipReason, t2, _this.testOn, _this.timeout, _this.verboseTrace);
+ },
+ $signature: 77
+ };
+ O.Metadata_Metadata_closure.prototype = {
+ call$2: function(merged, selector) {
+ var t1, t2;
+ type$.Metadata._check(merged);
+ type$.BooleanSelector._check(selector);
+ t1 = this._box_0;
+ t2 = t1.tags;
+ if (!H.boolConversionCheck(selector.evaluate$1(t2.get$contains(t2))))
+ return merged;
+ return merged.merge$1(t1.forTag.remove$1(0, selector));
+ },
+ $signature: 78
+ };
+ O.Metadata$deserialize_closure.prototype = {
+ call$2: function(key, nested) {
+ return new P.MapEntry(new Y.BooleanSelectorImpl(new G.Parser(new O.Scanner(S.SpanScanner$(H._asStringNullable(key)))).parse$0()), O.Metadata$deserialize(nested), type$.MapEntry_BooleanSelector_Metadata);
+ },
+ $signature: 79
+ };
+ O.Metadata__validateTags_closure.prototype = {
+ call$1: function(tag) {
+ return !J.contains$1$asx(H._checkStringNullable(tag), $.$get$anchoredHyphenatedIdentifier());
+ },
+ $signature: 4
+ };
+ O.Metadata__validateTags_closure0.prototype = {
+ call$1: function(tag) {
+ return '"' + H.S(H._checkStringNullable(tag)) + '"';
+ },
+ $signature: 7
+ };
+ O.Metadata_validatePlatformSelectors_closure.prototype = {
+ call$2: function(selector, metadata) {
+ var t1;
+ type$.PlatformSelector._check(selector);
+ type$.Metadata._check(metadata);
+ t1 = this.validVariables;
+ selector.validate$1(t1);
+ metadata.validatePlatformSelectors$1(t1);
+ },
+ $signature: 19
+ };
+ O.Metadata_merge_closure.prototype = {
+ call$2: function(metadata1, metadata2) {
+ var t1 = type$.Metadata;
+ return t1._check(metadata1).merge$1(t1._check(metadata2));
+ },
+ $signature: 44
+ };
+ O.Metadata_merge_closure0.prototype = {
+ call$2: function(metadata1, metadata2) {
+ var t1 = type$.Metadata;
+ return t1._check(metadata1).merge$1(t1._check(metadata2));
+ },
+ $signature: 44
+ };
+ O.Metadata_forPlatform_closure.prototype = {
+ call$2: function(platformSelector, platformMetadata) {
+ var t1;
+ type$.PlatformSelector._check(platformSelector);
+ type$.Metadata._check(platformMetadata);
+ if (!H.boolConversionCheck(platformSelector.evaluate$1(this.platform)))
+ return;
+ t1 = this._box_0;
+ t1.metadata = t1.metadata.merge$1(platformMetadata);
+ },
+ $signature: 19
+ };
+ O.Metadata_serialize_closure.prototype = {
+ call$2: function(key, value) {
+ type$.PlatformSelector._check(key);
+ type$.Metadata._check(value);
+ C.JSArray_methods.add$1(this.serializedOnPlatform, [J.toString$0$(key), value.serialize$0()]);
+ },
+ $signature: 19
+ };
+ O.Metadata_serialize_closure0.prototype = {
+ call$2: function(selector, metadata) {
+ type$.BooleanSelector._check(selector);
+ type$.Metadata._check(metadata);
+ return new P.MapEntry(J.toString$0$(selector), metadata.serialize$0(), type$.MapEntry_of_String_and_Map_String_dynamic);
+ },
+ $signature: 82
+ };
+ N.OperatingSystem.prototype = {
+ toString$0: function(_) {
+ return this.name;
+ }
+ };
+ N.OperatingSystem_find_closure.prototype = {
+ call$1: function(platform) {
+ return type$.OperatingSystem._check(platform).identifier === this.identifier;
+ },
+ $signature: 83
+ };
+ N.OperatingSystem_find_closure0.prototype = {
+ call$0: function() {
+ return null;
+ },
+ $signature: 0
+ };
+ E.PlatformSelector.prototype = {
+ validate$1: function(validVariables) {
+ type$.Set_String._check(validVariables);
+ if (this === C.PlatformSelector_All)
+ return;
+ E.PlatformSelector__wrapFormatException(new E.PlatformSelector_validate_closure(this, validVariables), null, type$.void);
+ },
+ evaluate$1: function(platform) {
+ return this._platform_selector$_inner.evaluate$1(new E.PlatformSelector_evaluate_closure(platform));
+ },
+ intersection$1: function(other) {
+ var t1 = other._platform_selector$_inner,
+ t2 = J.$eq$(t1, C.C_All);
+ if (t2)
+ return this;
+ return new E.PlatformSelector(this._platform_selector$_inner.intersection$1(t1));
+ },
+ toString$0: function(_) {
+ return J.toString$0$(this._platform_selector$_inner);
+ },
+ $eq: function(_, other) {
+ if (other == null)
+ return false;
+ return other instanceof E.PlatformSelector && J.$eq$(this._platform_selector$_inner, other._platform_selector$_inner);
+ },
+ get$hashCode: function(_) {
+ return J.get$hashCode$(this._platform_selector$_inner);
+ }
+ };
+ E.PlatformSelector$parse_closure.prototype = {
+ call$0: function() {
+ return new Y.BooleanSelectorImpl(new G.Parser(new O.Scanner(S.SpanScanner$(this.selector))).parse$0());
+ },
+ $signature: 84
+ };
+ E.PlatformSelector_validate_closure.prototype = {
+ call$0: function() {
+ return this.$this._platform_selector$_inner.validate$1(new E.PlatformSelector_validate__closure(this.validVariables));
+ },
+ $signature: 1
+ };
+ E.PlatformSelector_validate__closure.prototype = {
+ call$1: function($name) {
+ return $.$get$_universalValidVariables().contains$1(0, $name) || this.validVariables.contains$1(0, $name);
+ },
+ $signature: 4
+ };
+ E.PlatformSelector_evaluate_closure.prototype = {
+ call$1: function(variable) {
+ var t1, t2, t3;
+ H._checkStringNullable(variable);
+ t1 = this.platform;
+ t2 = t1.runtime;
+ if (variable == t2.identifier)
+ return true;
+ t3 = t2.parent;
+ if (variable == (t3 == null ? null : t3.identifier))
+ return true;
+ t3 = t1.os;
+ if (variable === t3.identifier)
+ return true;
+ switch (variable) {
+ case "dart-vm":
+ return t2.isDartVM;
+ case "browser":
+ return t2.isBrowser;
+ case "js":
+ return t2.isJS;
+ case "blink":
+ return t2.isBlink;
+ case "posix":
+ return t3 !== C.OperatingSystem_Windows_windows && t3 !== C.OperatingSystem_none_none;
+ case "google":
+ return t1.inGoogle;
+ default:
+ return false;
+ }
+ },
+ $signature: 4
+ };
+ B.Runtime.prototype = {
+ toString$0: function(_) {
+ return this.name;
+ }
+ };
+ B.Runtime_Runtime$deserialize_closure.prototype = {
+ call$1: function(platform) {
+ return type$.Runtime._check(platform).identifier === this.serialized;
+ },
+ $signature: 85
+ };
+ U.StackTraceFormatter.prototype = {
+ configure$3$except$mapper$only: function(except, mapper, only) {
+ var t1 = type$.Set_String;
+ t1._check(except);
+ t1._check(only);
+ if (mapper != null)
+ this._mapper = mapper;
+ if (except != null)
+ this.set$_except(except);
+ if (only != null)
+ this.set$_only(only);
+ },
+ configure$2$except$only: function(except, only) {
+ return this.configure$3$except$mapper$only(except, null, only);
+ },
+ configure$1$mapper: function(mapper) {
+ return this.configure$3$except$mapper$only(null, mapper, null);
+ },
+ formatStackTrace$2$verbose: function(stackTrace, verbose) {
+ var t2, t3, chain,
+ t1 = this._mapper;
+ if (t1 == null)
+ t1 = null;
+ else {
+ t2 = t1._mapping;
+ if (t2 == null) {
+ t2 = t1._mapContents;
+ t3 = t1._mapUrl;
+ t3 = t1._mapping = T.parseJsonExtended(C.C_JsonCodec.decode$2$reviver(t2, null), t3, null);
+ t2 = t3;
+ }
+ t1 = O.mapStackTrace(t2, stackTrace, false, t1._packageResolver, t1._sdkRoot);
+ }
+ chain = U.Chain_Chain$forTrace(t1 == null ? stackTrace : t1);
+ if (verbose)
+ return chain;
+ return chain.foldFrames$2$terse(new U.StackTraceFormatter_formatStackTrace_closure(this), true);
+ },
+ set$_except: function(_except) {
+ this._except = type$.Set_String._check(_except);
+ },
+ set$_only: function(_only) {
+ this._only = type$.Set_String._check(_only);
+ }
+ };
+ U.StackTraceFormatter_formatStackTrace_closure.prototype = {
+ call$1: function(frame) {
+ var t1 = this.$this,
+ t2 = t1._only;
+ if (t2._collection$_length !== 0)
+ return !t2.contains$1(0, frame.get$$package());
+ return t1._except.contains$1(0, frame.get$$package());
+ },
+ $signature: 21
+ };
+ G.State.prototype = {
+ $eq: function(_, other) {
+ if (other == null)
+ return false;
+ return other instanceof G.State && this.status === other.status && this.result === other.result;
+ },
+ get$hashCode: function(_) {
+ return (H.Primitives_objectHashCode(this.status) ^ 7 * H.Primitives_objectHashCode(this.result)) >>> 0;
+ },
+ toString$0: function(_) {
+ var t1 = this.status;
+ if (t1 === C.Status_pending)
+ return "pending";
+ if (t1 === C.Status_complete)
+ return this.result.name;
+ t1 = this.result;
+ if (t1 === C.Result_success)
+ return "running";
+ return "running with " + t1.toString$0(0);
+ }
+ };
+ G.Status.prototype = {
+ toString$0: function(_) {
+ return this.name;
+ }
+ };
+ G.Result0.prototype = {
+ toString$0: function(_) {
+ return this.name;
+ }
+ };
+ U.Suite.prototype = {};
+ E.SuitePlatform.prototype = {};
+ V.Test.prototype = {$isGroupEntry: 1};
+ G.TestFailure.prototype = {
+ toString$0: function(_) {
+ return this.message;
+ },
+ get$message: function(receiver) {
+ return this.message;
+ }
+ };
+ G._expect_closure0.prototype = {
+ call$5: function(actual, matcher, reason, matchState, verbose) {
+ var t1 = new P.StringBuffer("");
+ matcher.describeMismatch$4(true, new E.StringDescription(t1), matchState, false);
+ t1 = t1._contents;
+ return G.formatFailure(matcher, true, t1.charCodeAt(0) == 0 ? t1 : t1, reason);
+ },
+ $signature: 86
+ };
+ G._expect_closure.prototype = {
+ call$0: function() {
+ },
+ $signature: 0
+ };
+ R.Timeout.prototype = {
+ merge$1: function(other) {
+ var t1, t2;
+ if (this.$eq(0, C.Timeout_null_null) || other.$eq(0, C.Timeout_null_null))
+ return C.Timeout_null_null;
+ t1 = other.duration;
+ if (t1 != null)
+ return new R.Timeout(t1, null);
+ t1 = this.duration;
+ if (t1 != null) {
+ t2 = other.scaleFactor;
+ t1 = t1._duration;
+ if (typeof t2 !== "number")
+ return H.iae(t2);
+ return new R.Timeout(new P.Duration(C.JSNumber_methods.round$0(t1 * t2)), null);
+ }
+ t1 = this.scaleFactor;
+ t2 = other.scaleFactor;
+ if (typeof t1 !== "number")
+ return t1.$mul();
+ if (typeof t2 !== "number")
+ return H.iae(t2);
+ return new R.Timeout(null, t1 * t2);
+ },
+ apply$1: function(base) {
+ var t1;
+ if (this.$eq(0, C.Timeout_null_null))
+ return null;
+ t1 = this.duration;
+ if (t1 == null) {
+ t1 = this.scaleFactor;
+ if (typeof t1 !== "number")
+ return H.iae(t1);
+ t1 = new P.Duration(C.JSNumber_methods.round$0(base._duration * t1));
+ }
+ return t1;
+ },
+ get$hashCode: function(_) {
+ return (J.get$hashCode$(this.duration) ^ 5 * J.get$hashCode$(this.scaleFactor)) >>> 0;
+ },
+ $eq: function(_, other) {
+ if (other == null)
+ return false;
+ return other instanceof R.Timeout && J.$eq$(other.duration, this.duration) && other.scaleFactor == this.scaleFactor;
+ },
+ toString$0: function(_) {
+ var t1 = this.duration;
+ if (t1 != null)
+ return t1.toString$0(0);
+ t1 = this.scaleFactor;
+ if (t1 != null)
+ return H.S(t1) + "x";
+ return "none";
+ }
+ };
+ S.RemoteListener.prototype = {
+ _serializeGroup$3: function(channel, group, parents) {
+ var t2, t3, t4, t5, t6, t1 = {};
+ t1.parents = parents;
+ type$.Iterable_Group._check(parents);
+ parents = H.setRuntimeTypeInfo(parents.slice(0), H._arrayInstanceType(parents));
+ C.JSArray_methods.add$1(parents, group);
+ t1.parents = parents;
+ t2 = group.metadata.serialize$0();
+ t3 = group.trace;
+ t3 = t3 == null ? null : J.toString$0$(t3.get$_lazy_trace$_trace());
+ t4 = group.entries;
+ t5 = H._arrayInstanceType(t4);
+ t6 = type$.dynamic;
+ return P.LinkedHashMap_LinkedHashMap$_literal(["type", "group", "name", group.name, "metadata", t2, "trace", t3, "setUpAll", this._serializeTest$3(channel, group.setUpAll, parents), "tearDownAll", this._serializeTest$3(channel, group.tearDownAll, parents), "entries", new H.MappedListIterable(t4, t5._eval$1("Map<@,@>(1)")._check(new S.RemoteListener__serializeGroup_closure(t1, this, channel)), t5._eval$1("MappedListIterable<1,Map<@,@>>")).toList$0(0)], t6, t6);
+ },
+ _serializeTest$3: function(channel, test, groups) {
+ var testChannel, t1, t2, t3, t4;
+ type$.Iterable_Group._check(groups);
+ if (test == null)
+ return null;
+ testChannel = channel.virtualChannel$0();
+ testChannel.stream.listen$1(new S.RemoteListener__serializeTest_closure(this, test, groups, channel));
+ t1 = test.name;
+ t2 = test.metadata.serialize$0();
+ t3 = test.trace;
+ t3 = t3 == null ? null : J.toString$0$(t3.get$_lazy_trace$_trace());
+ t4 = type$.dynamic;
+ return P.LinkedHashMap_LinkedHashMap$_literal(["type", "test", "name", t1, "metadata", t2, "trace", t3, "channel", testChannel.id], t4, t4);
+ },
+ _runLiveTest$2: function(liveTest, channel) {
+ var t1, t2;
+ channel.stream.listen$1(new S.RemoteListener__runLiveTest_closure(liveTest));
+ t1 = liveTest._live_test_controller$_controller;
+ t2 = t1._onStateChangeController;
+ new P._BroadcastStream(t2, H._instanceType(t2)._eval$1("_BroadcastStream<1>")).listen$1(new S.RemoteListener__runLiveTest_closure0(channel));
+ t2 = t1._onErrorController;
+ new P._BroadcastStream(t2, H._instanceType(t2)._eval$1("_BroadcastStream<1>")).listen$1(new S.RemoteListener__runLiveTest_closure1(channel, liveTest));
+ t1 = t1._onMessageController;
+ new P._BroadcastStream(t1, H._instanceType(t1)._eval$1("_BroadcastStream<1>")).listen$1(new S.RemoteListener__runLiveTest_closure2(this, channel));
+ t1 = type$.dynamic;
+ P.runZoned(new S.RemoteListener__runLiveTest_closure3(liveTest, channel), null, null, P.LinkedHashMap_LinkedHashMap$_literal([C.Symbol_MAi, channel], t1, t1), type$.Null);
+ }
+ };
+ S.RemoteListener_start_closure.prototype = {
+ call$4: function(_, __, ___, line) {
+ var t1;
+ H._checkStringNullable(line);
+ t1 = this.printZone;
+ if (t1 != null)
+ t1.print$1(0, line);
+ t1 = type$.String;
+ this.channel._mainController._foreign._sink.add$1(0, P.LinkedHashMap_LinkedHashMap$_literal(["type", "print", "line", line], t1, t1));
+ },
+ $signature: 87
+ };
+ S.RemoteListener_start_closure0.prototype = {
+ call$1: function(_) {
+ },
+ $signature: 3
+ };
+ S.RemoteListener_start_closure1.prototype = {
+ call$0: function() {
+ var _this = this,
+ t1 = type$.String,
+ t2 = P.LinkedHashSet_LinkedHashSet$_literal(["test", "stream_channel", "test_api"], t1),
+ t3 = type$.dynamic;
+ P.runZoned(type$.Null_Function._check(new S.RemoteListener_start__closure(_this._box_0, _this.getMain, _this.channel, _this.controller, _this.beforeLoad, _this.printZone, _this.spec)), null, null, P.LinkedHashMap_LinkedHashMap$_literal([$.$get$_currentKey0(), new U.StackTraceFormatter(t2, P.LinkedHashSet_LinkedHashSet$_empty(t1))], t3, t3), type$.Null);
+ },
+ $signature: 0
+ };
+ S.RemoteListener_start__closure.prototype = {
+ call$0: function() {
+ var _this = this,
+ t1 = _this._box_0,
+ t2 = _this.channel;
+ P.runZoned(new S.RemoteListener_start___closure(t1, _this.getMain, t2, _this.controller, _this.beforeLoad, _this.printZone), new S.RemoteListener_start___closure0(t1, t2), _this.spec, null, type$.Future_Null);
+ },
+ $signature: 0
+ };
+ S.RemoteListener_start___closure.prototype = {
+ call$0: function() {
+ var $async$goto = 0,
+ $async$completer = P._makeAsyncAwaitCompleter(type$.Null),
+ $async$returnValue, $async$next = [], $async$self = this, error, stackTrace, exception, t1, t2, queue, message, t3, metadata, declarer, t4, map, t5, t6, main;
+ var $async$call$0 = P._wrapJsFunctionForAsync(function($async$errorCode, $async$result) {
+ if ($async$errorCode === 1)
+ return P._asyncRethrow($async$result, $async$completer);
+ while (true)
+ switch ($async$goto) {
+ case 0:
+ // Function start
+ main = null;
+ try {
+ main = $async$self.getMain.call$0();
+ } catch (exception) {
+ t1 = H.unwrapException(exception);
+ if (type$.NoSuchMethodError._is(t1)) {
+ S.RemoteListener__sendLoadException($async$self.channel, "No top-level main() function defined.");
+ // goto return
+ $async$goto = 1;
+ break;
+ } else {
+ error = t1;
+ stackTrace = H.getTraceFromException(exception);
+ S.RemoteListener__sendError($async$self.channel, error, stackTrace, $async$self._box_0.verboseChain);
+ // goto return
+ $async$goto = 1;
+ break;
+ }
+ }
+ if (!type$.Function._is(main)) {
+ S.RemoteListener__sendLoadException($async$self.channel, "Top-level main getter is not a function.");
+ // goto return
+ $async$goto = 1;
+ break;
+ } else if (!type$.dynamic_Function._is(main)) {
+ S.RemoteListener__sendLoadException($async$self.channel, "Top-level main() function takes arguments.");
+ // goto return
+ $async$goto = 1;
+ break;
+ }
+ t1 = $async$self.channel;
+ t2 = t1._mainController._foreign._streamController;
+ t2.toString;
+ queue = new G.StreamQueue(new P._ControllerStream(t2, H._instanceType(t2)._eval$1("_ControllerStream<1>")), Q.QueueList$(type$.Result_dynamic), P.ListQueue$(type$._EventRequest_dynamic), type$.StreamQueue_dynamic);
+ $async$goto = 3;
+ return P._asyncAwait(queue.get$next(), $async$call$0);
+ case 3:
+ // returning from await.
+ message = $async$result;
+ t2 = J.getInterceptor$asx(message);
+ H.assertHelper(J.$eq$(t2.$index(message, "type"), "initial"));
+ if (queue._isClosed)
+ H.throwExpression(queue._failClosed$0());
+ t3 = new Y._CompleterStream(type$._CompleterStream_dynamic);
+ queue._isClosed = true;
+ queue._addRequest$1(new G._RestRequest(new Y.StreamCompleter(t3, type$.StreamCompleter_dynamic), queue, type$._RestRequest_dynamic));
+ t3.listen$1(new S.RemoteListener_start____closure($async$self.controller, t1));
+ t3 = H._asBoolNullable(t2.$index(message, "asciiGlyphs"));
+ if (t3 === true)
+ $._glyphs = C.C_AsciiGlyphSet;
+ metadata = O.Metadata$deserialize(t2.$index(message, "metadata"));
+ $async$self._box_0.verboseChain = metadata._verboseTrace === true;
+ t3 = P.LinkedHashSet_LinkedHashSet$from(type$.Iterable_dynamic._as(t2.$index(message, "platformVariables")), type$.String);
+ declarer = X.Declarer$(H._asBoolNullable(t2.$index(message, "collectTraces")), metadata, H._asBoolNullable(t2.$index(message, "noRetry")), t3);
+ t3 = type$.List_dynamic;
+ type$.StackTraceFormatter._as($.Zone__current.$index(0, $.$get$_currentKey0())).configure$2$except$only(S.RemoteListener__deserializeSet(t3._as(t2.$index(message, "foldTraceExcept"))), S.RemoteListener__deserializeSet(t3._as(t2.$index(message, "foldTraceOnly"))));
+ $async$goto = 4;
+ return P._asyncAwait($async$self.beforeLoad.call$0(), $async$call$0);
+ case 4:
+ // returning from await.
+ t3 = type$.dynamic;
+ $async$goto = 5;
+ return P._asyncAwait(P.runZoned(type$.void_Function._check(main), null, null, P.LinkedHashMap_LinkedHashMap$_literal([C.Symbol_Drw, declarer], t3, t3), type$.void), $async$call$0);
+ case 5:
+ // returning from await.
+ t4 = declarer.build$0();
+ map = type$.Map_dynamic_dynamic._as(t2.$index(message, "platform"));
+ t5 = B.Runtime_Runtime$deserialize(map.$index(0, "runtime"));
+ t6 = N.OperatingSystem_find(H._asStringNullable(map.$index(0, "os")));
+ t6 = E.SuitePlatform$(t5, H._asBoolNullable(map.$index(0, "inGoogle")), t6);
+ P.runZoned(new S.RemoteListener_start____closure0(new U.Suite(t6, H._asStringNullable(t2.$index(message, "path")), U.Suite__filterGroup(t4, t6)), $async$self.printZone, t1), null, null, P.LinkedHashMap_LinkedHashMap$_literal([C.Symbol_Drw, declarer], t3, t3), type$.Null);
+ case 1:
+ // return
+ return P._asyncReturn($async$returnValue, $async$completer);
+ }
+ });
+ return P._asyncStartSync($async$call$0, $async$completer);
+ },
+ $signature: 2
+ };
+ S.RemoteListener_start____closure.prototype = {
+ call$1: function(message) {
+ var t2, t3, t4,
+ t1 = J.getInterceptor$asx(message);
+ if (J.$eq$(t1.$index(message, "type"), "close")) {
+ this.controller._local._sink.close$0(0);
+ return;
+ }
+ H.assertHelper(J.$eq$(t1.$index(message, "type"), "suiteChannel"));
+ t2 = type$.SuiteChannelManager._as($.Zone__current.$index(0, $.$get$_currentKey()));
+ t3 = H._asStringNullable(t1.$index(message, "name"));
+ t1 = this.channel.virtualChannel$1(H._asIntNullable(t1.$index(message, "id")));
+ t4 = t2._outgoingConnections;
+ if (t4.containsKey$1(t3)) {
+ t2 = t4.remove$1(0, t3);
+ t2.toString;
+ H.instanceType(t2)._eval$1("StreamChannel<1>")._check(t1);
+ if (t2._stream_channel_completer$_set)
+ H.throwExpression(P.StateError$("The channel has already been set."));
+ t2._stream_channel_completer$_set = true;
+ t2._streamCompleter.setSourceStream$1(t1.stream);
+ t2 = t2._sinkCompleter;
+ t3 = t2.$ti;
+ t1 = t3._eval$1("StreamSink<1>")._check(t1.sink);
+ t2 = t3._eval$1("_CompleterSink<1>")._check(t2.sink);
+ if (t2._destinationSink != null)
+ H.throwExpression(P.StateError$("Destination sink already set"));
+ t2._setDestinationSink$1(t1);
+ } else {
+ t2 = t2._incomingConnections;
+ if (t2.containsKey$1(t3))
+ H.throwExpression(P.StateError$('Duplicate RunnerSuite.channel() connection "' + H.S(t3) + '".'));
+ else
+ t2.$indexSet(0, t3, t1);
+ }
+ },
+ $signature: 3
+ };
+ S.RemoteListener_start____closure0.prototype = {
+ call$0: function() {
+ U.Invoker_guard(new S.RemoteListener_start_____closure(this.suite, this.printZone, this.channel), type$.void);
+ },
+ $signature: 0
+ };
+ S.RemoteListener_start_____closure.prototype = {
+ call$0: function() {
+ var t1 = this.suite,
+ t2 = this.channel;
+ t2._mainController._foreign._sink.add$1(0, P.LinkedHashMap_LinkedHashMap$_literal(["type", "success", "root", new S.RemoteListener(t1, this.printZone)._serializeGroup$3(t2, t1.group, H.setRuntimeTypeInfo([], type$.JSArray_Group))], type$.String, type$.Object));
+ return null;
+ },
+ $signature: 1
+ };
+ S.RemoteListener_start___closure0.prototype = {
+ call$2: function(error, stackTrace) {
+ S.RemoteListener__sendError(this.channel, error, type$.StackTrace._check(stackTrace), this._box_0.verboseChain);
+ },
+ $signature: 5
+ };
+ S.RemoteListener__serializeGroup_closure.prototype = {
+ call$1: function(entry) {
+ var t1, t2, t3;
+ type$.GroupEntry._check(entry);
+ t1 = this.$this;
+ t2 = this.channel;
+ t3 = this._box_0.parents;
+ return entry instanceof O.Group ? t1._serializeGroup$3(t2, entry, t3) : t1._serializeTest$3(t2, type$.Test._as(entry), t3);
+ },
+ $signature: 88
+ };
+ S.RemoteListener__serializeTest_closure.prototype = {
+ call$1: function(message) {
+ var t2, _this = this,
+ t1 = J.getInterceptor$asx(message);
+ H.assertHelper(J.$eq$(t1.$index(message, "command"), "run"));
+ t2 = _this.$this;
+ t2._runLiveTest$2(_this.test.load$2$groups(t2._suite, _this.groups), _this.channel.virtualChannel$1(H._asIntNullable(t1.$index(message, "channel"))));
+ },
+ $signature: 3
+ };
+ S.RemoteListener__runLiveTest_closure.prototype = {
+ call$1: function(message) {
+ H.assertHelper(J.$eq$(J.$index$asx(message, "command"), "close"));
+ this.liveTest._live_test_controller$_controller._live_test_controller$_close$0();
+ },
+ $signature: 3
+ };
+ S.RemoteListener__runLiveTest_closure0.prototype = {
+ call$1: function(state) {
+ var t1;
+ type$.State._check(state);
+ t1 = type$.String;
+ this.channel.sink.add$1(0, P.LinkedHashMap_LinkedHashMap$_literal(["type", "state-change", "status", state.status.name, "result", state.result.name], t1, t1));
+ },
+ $signature: 23
+ };
+ S.RemoteListener__runLiveTest_closure1.prototype = {
+ call$1: function(asyncError) {
+ var t1, t2, t3, t4;
+ type$.AsyncError._check(asyncError);
+ t1 = asyncError.error;
+ t2 = type$.StackTraceFormatter._as($.Zone__current.$index(0, $.$get$_currentKey0()));
+ t3 = asyncError.stackTrace;
+ t4 = this.liveTest._live_test_controller$_controller;
+ this.channel.sink.add$1(0, P.LinkedHashMap_LinkedHashMap$_literal(["type", "error", "error", U.RemoteException_serialize(t1, t2.formatStackTrace$2$verbose(t3, t4._test.metadata._verboseTrace === true))], type$.String, type$.Object));
+ },
+ $signature: 90
+ };
+ S.RemoteListener__runLiveTest_closure2.prototype = {
+ call$1: function(message) {
+ var t1;
+ type$.Message._check(message);
+ t1 = this.$this._printZone;
+ if (t1 != null)
+ t1.print$1(0, message.text);
+ t1 = type$.String;
+ this.channel.sink.add$1(0, P.LinkedHashMap_LinkedHashMap$_literal(["type", "message", "message-type", message.type.name, "text", message.text], t1, t1));
+ },
+ $signature: 27
+ };
+ S.RemoteListener__runLiveTest_closure3.prototype = {
+ call$0: function() {
+ this.liveTest._live_test_controller$_controller._live_test_controller$_run$0().then$1$1(new S.RemoteListener__runLiveTest__closure(this.channel), type$.void);
+ },
+ $signature: 0
+ };
+ S.RemoteListener__runLiveTest__closure.prototype = {
+ call$1: function(_) {
+ var t1 = type$.String;
+ return this.channel.sink.add$1(0, P.LinkedHashMap_LinkedHashMap$_literal(["type", "complete"], t1, t1));
+ },
+ $signature: 15
+ };
+ N.SuiteChannelManager.prototype = {
+ connectOut$1: function($name) {
+ var t2, completer,
+ t1 = this._incomingConnections;
+ if (t1.containsKey$1($name))
+ return t1.$index(0, $name);
+ else {
+ t1 = this._names;
+ if (t1.contains$1(0, $name))
+ throw H.wrapException(P.StateError$('Duplicate suiteChannel() connection "' + $name + '".'));
+ else {
+ t1.add$1(0, $name);
+ t1 = new Y._CompleterStream(type$._CompleterStream_dynamic);
+ t2 = new T._CompleterSink(type$._CompleterSink_dynamic);
+ completer = new N.StreamChannelCompleter(new Y.StreamCompleter(t1, type$.StreamCompleter_dynamic), new T.StreamSinkCompleter(t2, type$.StreamSinkCompleter_dynamic), type$.StreamChannelCompleter_dynamic);
+ completer.set$_stream_channel_completer$_channel(new R._StreamChannel(t1, t2, type$._StreamChannel_dynamic));
+ this._outgoingConnections.$indexSet(0, $name, completer);
+ return completer._stream_channel_completer$_channel;
+ }
+ }
+ }
+ };
+ O.IterableSet.prototype = {
+ get$length: function(_) {
+ var t1 = this._iterable_set$_base._collection$_source;
+ return t1.get$length(t1);
+ },
+ get$iterator: function(_) {
+ var t1 = this._iterable_set$_base;
+ return new H.ListIterator(t1, t1.get$length(t1), t1.$ti._eval$1("ListIterator<ListMixin.E>"));
+ },
+ toSet$0: function(_) {
+ var t1 = this._iterable_set$_base;
+ return t1.toSet$0(t1);
+ }
+ };
+ O._IterableSet_SetMixin_UnmodifiableSetMixin.prototype = {};
+ E.StackTraceMapper.prototype = {};
+ V.errorsDontStopTest_closure.prototype = {
+ call$0: function() {
+ P.Future_Future$sync(this.body, type$.dynamic).whenComplete$1(this.completer.get$complete());
+ },
+ $signature: 0
+ };
+ V.errorsDontStopTest_closure0.prototype = {
+ call$1: function(_) {
+ var t1 = type$.Invoker._as($.Zone__current.$index(0, C.Symbol_cQL));
+ t1.heartbeat$0();
+ t1.get$_outstandingCallbacks().decrement$0();
+ return null;
+ },
+ $signature: 92
+ };
+ B.closure0.prototype = {
+ call$0: function() {
+ var t1 = $.$get$context().style;
+ if (t1 == $.$get$Style_url())
+ return C.OperatingSystem_none_none;
+ if (t1 == $.$get$Style_windows())
+ return C.OperatingSystem_Windows_windows;
+ if ($._macOSDirectories.any$1(0, J.get$startsWith$s(D.current())))
+ return C.OperatingSystem_RkP;
+ return C.OperatingSystem_Linux_linux;
+ },
+ $signature: 115
+ };
+ O.Engine.prototype = {
+ get$_onUnpaused: function() {
+ var t1 = new P._Future($.Zone__current, type$._Future_dynamic);
+ t1._asyncComplete$1(null);
+ return t1;
+ },
+ get$success: function() {
+ var $async$goto = 0,
+ $async$completer = P._makeAsyncAwaitCompleter(type$.bool),
+ $async$returnValue, $async$self = this;
+ var $async$get$success = P._wrapJsFunctionForAsync(function($async$errorCode, $async$result) {
+ if ($async$errorCode === 1)
+ return P._asyncRethrow($async$result, $async$completer);
+ while (true)
+ switch ($async$goto) {
+ case 0:
+ // Function start
+ $async$goto = 3;
+ return P._asyncAwait(P.Future_wait(H.setRuntimeTypeInfo([$async$self._group._future_group$_completer.future, $async$self._loadPool._pool$_closeMemo._async_memoizer$_completer.future], type$.JSArray_Future_dynamic), true, type$.dynamic), $async$get$success);
+ case 3:
+ // returning from await.
+ if (H.boolConversionCheck($async$self._closedBeforeDone)) {
+ $async$returnValue = null;
+ // goto return
+ $async$goto = 1;
+ break;
+ }
+ $async$returnValue = $async$self.get$liveTests().every$1(0, new O.Engine_success_closure());
+ // goto return
+ $async$goto = 1;
+ break;
+ case 1:
+ // return
+ return P._asyncReturn($async$returnValue, $async$completer);
+ }
+ });
+ return P._asyncStartSync($async$get$success, $async$completer);
+ },
+ get$liveTests: function() {
+ var _this = this;
+ return new M.UnionSet(P.LinkedHashSet_LinkedHashSet$from(H.setRuntimeTypeInfo([_this._passedGroup._union_set_controller$_set, _this._skippedGroup._union_set_controller$_set, _this._failedGroup._union_set_controller$_set, new O.IterableSet(new P.UnmodifiableListView(_this._active, type$.UnmodifiableListView_LiveTest), type$.IterableSet_LiveTest)], type$.JSArray_Set_LiveTest), type$.Set_LiveTest), true, type$.UnionSet_LiveTest);
+ },
+ Engine$3$concurrency$coverage$maxSuites: function(concurrency, coverage, maxSuites) {
+ this._group._future_group$_completer.future.then$1$1(new O.Engine_closure(this), type$.Null).catchError$1(new O.Engine_closure0());
+ },
+ run$0: function() {
+ var t2, subscription, _this = this, t1 = {};
+ if (_this._engine$_runCalled)
+ throw H.wrapException(P.StateError$("Engine.run() may not be called more than once."));
+ _this._engine$_runCalled = true;
+ t1.subscription = null;
+ t2 = _this._suiteController;
+ subscription = new P._ControllerStream(t2, H._instanceType(t2)._eval$1("_ControllerStream<1>")).listen$2$onDone(new O.Engine_run_closure(_this), new O.Engine_run_closure0(t1, _this));
+ t1.subscription = subscription;
+ _this._engine$_subscriptions.add$1(0, subscription);
+ return _this.get$success();
+ },
+ _runGroup$3: function(suiteController, group, parents) {
+ type$.List_Group._check(parents);
+ return this._runGroup$body$Engine(suiteController, group, parents);
+ },
+ _runGroup$body$Engine: function(suiteController, group, parents) {
+ var $async$goto = 0,
+ $async$completer = P._makeAsyncAwaitCompleter(type$.dynamic),
+ $async$returnValue, $async$handler = 2, $async$currentError, $async$next = [], $async$self = this, suiteConfig, skipGroup, setUpAllSucceeded, liveTest, entries, entry, test, liveTest0, t1, skipGroup0, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, _i, t16, t17, t18, invoker, t19, t20, result, t21;
+ var $async$_runGroup$3 = P._wrapJsFunctionForAsync(function($async$errorCode, $async$result) {
+ if ($async$errorCode === 1) {
+ $async$currentError = $async$result;
+ $async$goto = $async$handler;
+ }
+ while (true)
+ switch ($async$goto) {
+ case 0:
+ // Function start
+ C.JSArray_methods.add$1(parents, group);
+ $async$handler = 3;
+ t1 = suiteController._liveSuite._live_suite_controller$_controller._live_suite_controller$_suite;
+ suiteConfig = t1._runner_suite$_controller._config;
+ suiteConfig.toString;
+ skipGroup0 = group.metadata._skip === true;
+ skipGroup = skipGroup0;
+ setUpAllSucceeded = true;
+ $async$goto = !H.boolConversionCheck(skipGroup) && group.setUpAll != null ? 6 : 7;
+ break;
+ case 6:
+ // then
+ liveTest = group.setUpAll.load$2$groups(t1, parents);
+ $async$goto = 8;
+ return P._asyncAwait($async$self._engine$_runLiveTest$3$countSuccess(suiteController, liveTest, false), $async$_runGroup$3);
+ case 8:
+ // returning from await.
+ t1 = liveTest._live_test_controller$_controller._live_test_controller$_state.result;
+ setUpAllSucceeded = t1 === C.Result_success || t1 === C.Result_skipped;
+ case 7:
+ // join
+ $async$goto = !$async$self._engine$_closed && H.boolConversionCheck(setUpAllSucceeded) ? 9 : 10;
+ break;
+ case 9:
+ // then
+ t1 = group.entries;
+ t1 = H.setRuntimeTypeInfo(t1.slice(0), H._arrayInstanceType(t1)._eval$1("JSArray<1>"));
+ entries = t1;
+ suiteConfig.toString;
+ t1 = entries, t2 = t1.length, t3 = type$.Group, t4 = type$.List_Group, t5 = type$._Future_void, t6 = type$._AsyncCompleter_void, t7 = type$._SyncBroadcastStreamController_Message, t8 = type$._SyncBroadcastStreamController_AsyncError, t9 = type$._SyncBroadcastStreamController_State, t10 = type$.Test, t11 = type$.Iterable_Group, t12 = type$.JSArray_Zone, t13 = type$.JSArray_of_dynamic_Function, t14 = type$.JSArray_String, t15 = type$.JSArray_AsyncError, _i = 0;
+ case 11:
+ // for condition
+ if (!(_i < t1.length)) {
+ // goto after for
+ $async$goto = 13;
+ break;
+ }
+ entry = t1[_i];
+ if ($async$self._engine$_closed) {
+ $async$next = [1];
+ // goto finally
+ $async$goto = 4;
+ break;
+ }
+ $async$goto = entry instanceof O.Group ? 14 : 16;
+ break;
+ case 14:
+ // then
+ $async$goto = 17;
+ return P._asyncAwait($async$self._runGroup$3(suiteController, entry, parents), $async$_runGroup$3);
+ case 17:
+ // returning from await.
+ // goto join
+ $async$goto = 15;
+ break;
+ case 16:
+ // else
+ suiteConfig.toString;
+ t16 = entry.get$metadata();
+ t16 = t16._skip === true;
+ $async$goto = t16 ? 18 : 20;
+ break;
+ case 18:
+ // then
+ $async$goto = 21;
+ return P._asyncAwait($async$self._runSkippedTest$3(suiteController, t10._as(entry), parents), $async$_runGroup$3);
+ case 21:
+ // returning from await.
+ // goto join
+ $async$goto = 19;
+ break;
+ case 20:
+ // else
+ test = t10._as(entry);
+ t16 = test;
+ t17 = suiteController._liveSuite._live_suite_controller$_controller;
+ t16.toString;
+ t11._check(parents);
+ t18 = new P._AsyncCompleter(new P._Future($.Zone__current, t5), t6);
+ invoker = new U.Invoker(t16._guarded, new P.Object(), t18, H.setRuntimeTypeInfo([], t12), new P.Object(), H.setRuntimeTypeInfo([], t13), H.setRuntimeTypeInfo([], t14));
+ t19 = H.setRuntimeTypeInfo([], t15);
+ t20 = $.Zone__current;
+ result = P.List_List$from(parents, false, t3);
+ result.fixed$length = Array;
+ result.immutable$list = Array;
+ t21 = t4._check(result);
+ t16 = new V.LiveTestController(t17._live_suite_controller$_suite, t21, t16, invoker.get$_invoker$_onRun(), t18.get$complete(), t19, C.State_Status_pending_Result_success, new P._SyncBroadcastStreamController(null, null, t9), new P._SyncBroadcastStreamController(null, null, t8), new P._SyncBroadcastStreamController(null, null, t7), new P._AsyncCompleter(new P._Future(t20, t5), t6));
+ t17 = new V._LiveTest(t16);
+ t16._liveTest = t17;
+ invoker._invoker$_controller = t16;
+ $async$goto = 22;
+ return P._asyncAwait($async$self._engine$_runLiveTest$2(suiteController, t17), $async$_runGroup$3);
+ case 22:
+ // returning from await.
+ case 19:
+ // join
+ case 15:
+ // join
+ case 12:
+ // for update
+ t1.length === t2 || (0, H.throwConcurrentModificationError)(t1), ++_i;
+ // goto for condition
+ $async$goto = 11;
+ break;
+ case 13:
+ // after for
+ case 10:
+ // join
+ $async$goto = !H.boolConversionCheck(skipGroup) && group.tearDownAll != null ? 23 : 24;
+ break;
+ case 23:
+ // then
+ liveTest0 = group.tearDownAll.load$2$groups(suiteController._liveSuite._live_suite_controller$_controller._live_suite_controller$_suite, parents);
+ $async$goto = 25;
+ return P._asyncAwait($async$self._engine$_runLiveTest$3$countSuccess(suiteController, liveTest0, false), $async$_runGroup$3);
+ case 25:
+ // returning from await.
+ $async$goto = $async$self._engine$_closed ? 26 : 27;
+ break;
+ case 26:
+ // then
+ $async$goto = 28;
+ return P._asyncAwait(liveTest0._live_test_controller$_controller._live_test_controller$_close$0(), $async$_runGroup$3);
+ case 28:
+ // returning from await.
+ case 27:
+ // join
+ case 24:
+ // join
+ $async$next.push(5);
+ // goto finally
+ $async$goto = 4;
+ break;
+ case 3:
+ // uncaught
+ $async$next = [2];
+ case 4:
+ // finally
+ $async$handler = 2;
+ C.JSArray_methods.remove$1(parents, group);
+ // goto the next finally handler
+ $async$goto = $async$next.pop();
+ break;
+ case 5:
+ // after finally
+ case 1:
+ // return
+ return P._asyncReturn($async$returnValue, $async$completer);
+ case 2:
+ // rethrow
+ return P._asyncRethrow($async$currentError, $async$completer);
+ }
+ });
+ return P._asyncStartSync($async$_runGroup$3, $async$completer);
+ },
+ _engine$_runLiveTest$3$countSuccess: function(suiteController, liveTest, countSuccess) {
+ return this._runLiveTest$body$Engine(suiteController, liveTest, countSuccess);
+ },
+ _engine$_runLiveTest$2: function(suiteController, liveTest) {
+ return this._engine$_runLiveTest$3$countSuccess(suiteController, liveTest, true);
+ },
+ _runLiveTest$body$Engine: function(suiteController, liveTest, countSuccess) {
+ var $async$goto = 0,
+ $async$completer = P._makeAsyncAwaitCompleter(type$.dynamic),
+ $async$returnValue, $async$self = this, t2, t3, subscription, t1;
+ var $async$_engine$_runLiveTest$3$countSuccess = P._wrapJsFunctionForAsync(function($async$errorCode, $async$result) {
+ if ($async$errorCode === 1)
+ return P._asyncRethrow($async$result, $async$completer);
+ while (true)
+ switch ($async$goto) {
+ case 0:
+ // Function start
+ t1 = {};
+ $async$goto = 3;
+ return P._asyncAwait($async$self.get$_onUnpaused(), $async$_engine$_runLiveTest$3$countSuccess);
+ case 3:
+ // returning from await.
+ t2 = $async$self._active;
+ t2._queue_list$_add$1(t2.$ti._precomputed1._check(liveTest));
+ t2.get$first(t2).toString;
+ t1.subscription = null;
+ t2 = liveTest._live_test_controller$_controller;
+ t3 = t2._onStateChangeController;
+ subscription = new P._BroadcastStream(t3, H._instanceType(t3)._eval$1("_BroadcastStream<1>")).listen$2$onDone(new O.Engine__runLiveTest_closure($async$self, liveTest), new O.Engine__runLiveTest_closure0(t1, $async$self));
+ t1.subscription = subscription;
+ $async$self._engine$_subscriptions.add$1(0, subscription);
+ suiteController.reportLiveTest$2$countSuccess(liveTest, countSuccess);
+ $async$goto = 4;
+ return P._asyncAwait(P.Future_Future$microtask(liveTest.get$run(), type$.dynamic), $async$_engine$_runLiveTest$3$countSuccess);
+ case 4:
+ // returning from await.
+ $async$goto = 5;
+ return P._asyncAwait(P.Future_Future(new O.Engine__runLiveTest_closure1(), type$.Null), $async$_engine$_runLiveTest$3$countSuccess);
+ case 5:
+ // returning from await.
+ t1 = $async$self._restarted;
+ if (!t1.contains$1(0, liveTest)) {
+ // goto return
+ $async$goto = 1;
+ break;
+ }
+ $async$goto = 6;
+ return P._asyncAwait($async$self._engine$_runLiveTest$3$countSuccess(suiteController, t2._test.load$2$groups(t2._live_test_controller$_suite, t2._groups), countSuccess), $async$_engine$_runLiveTest$3$countSuccess);
+ case 6:
+ // returning from await.
+ t1.remove$1(0, liveTest);
+ case 1:
+ // return
+ return P._asyncReturn($async$returnValue, $async$completer);
+ }
+ });
+ return P._asyncStartSync($async$_engine$_runLiveTest$3$countSuccess, $async$completer);
+ },
+ _runSkippedTest$3: function(suiteController, test, parents) {
+ return this._runSkippedTest$body$Engine(suiteController, test, type$.List_Group._check(parents));
+ },
+ _runSkippedTest$body$Engine: function(suiteController, test, parents) {
+ var $async$goto = 0,
+ $async$completer = P._makeAsyncAwaitCompleter(type$.dynamic),
+ $async$returnValue, $async$self = this, skipped, controller, t1;
+ var $async$_runSkippedTest$3 = P._wrapJsFunctionForAsync(function($async$errorCode, $async$result) {
+ if ($async$errorCode === 1)
+ return P._asyncRethrow($async$result, $async$completer);
+ while (true)
+ switch ($async$goto) {
+ case 0:
+ // Function start
+ t1 = {};
+ $async$goto = 3;
+ return P._asyncAwait($async$self.get$_onUnpaused(), $async$_runSkippedTest$3);
+ case 3:
+ // returning from await.
+ skipped = new U.LocalTest(test.name, test.metadata, test.trace, false, new O.Engine__runSkippedTest_closure(), true);
+ t1.controller = null;
+ controller = V.LiveTestController$(suiteController._liveSuite._live_suite_controller$_controller._live_suite_controller$_suite, skipped, new O.Engine__runSkippedTest_closure0(t1, skipped), new O.Engine__runSkippedTest_closure1(), parents);
+ t1.controller = controller;
+ $async$goto = 4;
+ return P._asyncAwait($async$self._engine$_runLiveTest$2(suiteController, controller._liveTest), $async$_runSkippedTest$3);
+ case 4:
+ // returning from await.
+ $async$returnValue = $async$result;
+ // goto return
+ $async$goto = 1;
+ break;
+ case 1:
+ // return
+ return P._asyncReturn($async$returnValue, $async$completer);
+ }
+ });
+ return P._asyncStartSync($async$_runSkippedTest$3, $async$completer);
+ },
+ _addLiveSuite$1: function(liveSuite) {
+ var t1, t2, t3, _this = this;
+ _this._liveSuites.add$1(0, liveSuite);
+ _this._onSuiteStartedController.add$1(0, liveSuite);
+ t1 = liveSuite._live_suite_controller$_controller;
+ t2 = t1._onTestStartedController;
+ _this._onTestStartedGroup.add$1(0, new P._BroadcastStream(t2, H._instanceType(t2)._eval$1("_BroadcastStream<1>")));
+ t2 = _this._passedGroup;
+ t3 = type$.UnmodifiableSetView_LiveTest;
+ t2._union_set_controller$_sets.add$1(0, t2.$ti._eval$1("Set<1>")._check(new L.UnmodifiableSetView(t1._passed, t3)));
+ t2 = _this._skippedGroup;
+ t2._union_set_controller$_sets.add$1(0, t2.$ti._eval$1("Set<1>")._check(new L.UnmodifiableSetView(t1._skipped, t3)));
+ t2 = _this._failedGroup;
+ t2._union_set_controller$_sets.add$1(0, t2.$ti._eval$1("Set<1>")._check(new L.UnmodifiableSetView(t1._failed, t3)));
+ }
+ };
+ O.Engine_success_closure.prototype = {
+ call$1: function(liveTest) {
+ var t1 = type$.LiveTest._check(liveTest)._live_test_controller$_controller._live_test_controller$_state,
+ t2 = t1.result;
+ return (t2 === C.Result_success || t2 === C.Result_skipped) && t1.status === C.Status_complete;
+ },
+ $signature: 95
+ };
+ O.Engine_closure.prototype = {
+ call$1: function(_) {
+ var t1;
+ type$.List_dynamic._check(_);
+ t1 = this.$this;
+ t1._onTestStartedGroup.close$0(0);
+ t1._onSuiteStartedController.close$0(0);
+ if (t1._closedBeforeDone == null)
+ t1._closedBeforeDone = false;
+ },
+ $signature: 48
+ };
+ O.Engine_closure0.prototype = {
+ call$1: function(_) {
+ },
+ $signature: 3
+ };
+ O.Engine_run_closure.prototype = {
+ call$1: function(suite) {
+ var t1;
+ type$.RunnerSuite._check(suite);
+ t1 = this.$this;
+ t1._addedSuites.add$1(0, suite);
+ t1._onSuiteAddedController.add$1(0, suite);
+ t1._group.add$1(0, new O.Engine_run__closure(t1, suite).call$0());
+ },
+ $signature: 97
+ };
+ O.Engine_run__closure.prototype = {
+ call$0: function() {
+ return this.$call$body$Engine_run__closure();
+ },
+ $call$body$Engine_run__closure: function() {
+ var $async$goto = 0,
+ $async$completer = P._makeAsyncAwaitCompleter(type$.Null),
+ $async$self = this, controller, t1, t2, loadResource;
+ var $async$call$0 = P._wrapJsFunctionForAsync(function($async$errorCode, $async$result) {
+ if ($async$errorCode === 1)
+ return P._asyncRethrow($async$result, $async$completer);
+ while (true)
+ switch ($async$goto) {
+ case 0:
+ // Function start
+ t1 = {};
+ t2 = $async$self.$this;
+ $async$goto = 2;
+ return P._asyncAwait(t2._loadPool.request$0(0), $async$call$0);
+ case 2:
+ // returning from await.
+ loadResource = $async$result;
+ t1.controller = null;
+ controller = B.LiveSuiteController$($async$self.suite);
+ t1.controller = controller;
+ t2._addLiveSuite$1(controller._liveSuite);
+ $async$goto = 3;
+ return P._asyncAwait(t2._runPool.withResource$1$1(new O.Engine_run___closure(t1, t2, loadResource), type$.Null), $async$call$0);
+ case 3:
+ // returning from await.
+ // implicit return
+ return P._asyncReturn(null, $async$completer);
+ }
+ });
+ return P._asyncStartSync($async$call$0, $async$completer);
+ },
+ $signature: 2
+ };
+ O.Engine_run___closure.prototype = {
+ call$0: function() {
+ var $async$goto = 0,
+ $async$completer = P._makeAsyncAwaitCompleter(type$.Null),
+ $async$returnValue, $async$self = this, t2, t3, t1;
+ var $async$call$0 = P._wrapJsFunctionForAsync(function($async$errorCode, $async$result) {
+ if ($async$errorCode === 1)
+ return P._asyncRethrow($async$result, $async$completer);
+ while (true)
+ switch ($async$goto) {
+ case 0:
+ // Function start
+ t1 = $async$self.$this;
+ if (t1._engine$_closed) {
+ // goto return
+ $async$goto = 1;
+ break;
+ }
+ t2 = $async$self._box_0;
+ t3 = t2.controller;
+ $async$goto = 3;
+ return P._asyncAwait(t1._runGroup$3(t3, t3._liveSuite._live_suite_controller$_controller._live_suite_controller$_suite.group, H.setRuntimeTypeInfo([], type$.JSArray_Group)), $async$call$0);
+ case 3:
+ // returning from await.
+ t3 = t2.controller;
+ t3._onTestStartedController.close$0(0);
+ t3._onCompleteGroup.close$0(0);
+ t1 = $async$self.loadResource;
+ t1.toString;
+ t2 = type$.dynamic_Function._check(new O.Engine_run____closure(t2));
+ if (t1._released)
+ H.throwExpression(P.StateError$("A PoolResource may only be released once."));
+ t1._released = true;
+ t1._pool._onResourceReleaseAllowed$1(t2);
+ case 1:
+ // return
+ return P._asyncReturn($async$returnValue, $async$completer);
+ }
+ });
+ return P._asyncStartSync($async$call$0, $async$completer);
+ },
+ $signature: 2
+ };
+ O.Engine_run____closure.prototype = {
+ call$0: function() {
+ return this._box_0.controller.close$0(0);
+ },
+ $signature: 14
+ };
+ O.Engine_run_closure0.prototype = {
+ call$0: function() {
+ var t1 = this.$this;
+ t1._engine$_subscriptions.remove$1(0, this._box_1.subscription);
+ t1._onSuiteAddedController.close$0(0);
+ t1._group.close$0(0);
+ t1._loadPool.close$0(0);
+ },
+ $signature: 0
+ };
+ O.Engine__runLiveTest_closure.prototype = {
+ call$1: function(state) {
+ var t1, t2;
+ if (type$.State._check(state).status !== C.Status_complete)
+ return;
+ t1 = this.$this;
+ t2 = t1._active;
+ t2.remove$1(t2, this.liveTest);
+ if (t2.get$length(t2) === 0 && t1._activeLoadTests._collection$_length !== 0) {
+ t1 = t1._activeLoadTests;
+ t2._queue_list$_add$1(t2.$ti._precomputed1._check(t1.get$first(t1)));
+ }
+ },
+ $signature: 23
+ };
+ O.Engine__runLiveTest_closure0.prototype = {
+ call$0: function() {
+ this.$this._engine$_subscriptions.remove$1(0, this._box_0.subscription);
+ },
+ $signature: 0
+ };
+ O.Engine__runLiveTest_closure1.prototype = {
+ call$0: function() {
+ },
+ $signature: 0
+ };
+ O.Engine__runSkippedTest_closure.prototype = {
+ call$0: function() {
+ },
+ $signature: 0
+ };
+ O.Engine__runSkippedTest_closure0.prototype = {
+ call$0: function() {
+ var t2,
+ t1 = this._box_0;
+ t1.controller.setState$1(C.State_Status_running_Result_success);
+ t1.controller.setState$1(C.State_Status_running_Result_skipped);
+ t2 = this.skipped.metadata.skipReason;
+ if (t2 != null)
+ t1.controller.message$1(0, new D.Message(C.MessageType_skip, "Skip: " + t2));
+ t1.controller.setState$1(C.State_Status_complete_Result_skipped);
+ t1.controller.completer.complete$0();
+ },
+ $signature: 0
+ };
+ O.Engine__runSkippedTest_closure1.prototype = {
+ call$0: function() {
+ },
+ $signature: 0
+ };
+ E.LiveSuite.prototype = {};
+ B._LiveSuite.prototype = {};
+ B.LiveSuiteController.prototype = {
+ LiveSuiteController$1: function(_suite) {
+ var _this = this;
+ _this._liveSuite = new B._LiveSuite(_this);
+ _this._onCompleteGroup._future_group$_completer.future.then$1$2$onError(new B.LiveSuiteController_closure(_this), new B.LiveSuiteController_closure0(), type$.Null);
+ },
+ reportLiveTest$2$countSuccess: function(liveTest, countSuccess) {
+ var t2, t3, _this = this,
+ t1 = _this._onTestStartedController;
+ if ((t1._state & 4) !== 0)
+ throw H.wrapException(P.StateError$("Can't call reportLiveTest() after noMoreTests()."));
+ t2 = liveTest._live_test_controller$_controller;
+ H.assertHelper(t2._live_test_controller$_suite == _this._live_suite_controller$_suite);
+ H.assertHelper(_this._live_suite_controller$_active == null);
+ _this._live_suite_controller$_active = liveTest;
+ t3 = t2._onStateChangeController;
+ new P._BroadcastStream(t3, H._instanceType(t3)._eval$1("_BroadcastStream<1>")).listen$1(new B.LiveSuiteController_reportLiveTest_closure(_this, liveTest, countSuccess));
+ t1.add$1(0, liveTest);
+ _this._onCompleteGroup.add$1(0, t2.completer.future);
+ },
+ close$0: function(_) {
+ return this._live_suite_controller$_closeMemo.runOnce$1(new B.LiveSuiteController_close_closure(this));
+ }
+ };
+ B.LiveSuiteController_closure.prototype = {
+ call$1: function(_) {
+ type$.List_dynamic._check(_);
+ },
+ $signature: 48
+ };
+ B.LiveSuiteController_closure0.prototype = {
+ call$1: function(_) {
+ },
+ $signature: 3
+ };
+ B.LiveSuiteController_reportLiveTest_closure.prototype = {
+ call$1: function(state) {
+ var t1, t2, _this = this;
+ type$.State._check(state);
+ if (state.status !== C.Status_complete)
+ return;
+ t1 = _this.$this;
+ t1._live_suite_controller$_active = null;
+ t2 = state.result;
+ if (t2 === C.Result_skipped)
+ t1._skipped.add$1(0, _this.liveTest);
+ else if (t2 !== C.Result_success) {
+ t2 = _this.liveTest;
+ t1._passed.remove$1(0, t2);
+ t1._failed.add$1(0, t2);
+ } else if (_this.countSuccess) {
+ t2 = _this.liveTest;
+ t1._passed.add$1(0, t2);
+ t1._failed.remove$1(0, t2);
+ }
+ },
+ $signature: 23
+ };
+ B.LiveSuiteController_close_closure.prototype = {
+ call$0: function() {
+ var $async$goto = 0,
+ $async$completer = P._makeAsyncAwaitCompleter(type$.Null),
+ $async$handler = 1, $async$currentError, $async$next = [], $async$self = this;
+ var $async$call$0 = P._wrapJsFunctionForAsync(function($async$errorCode, $async$result) {
+ if ($async$errorCode === 1) {
+ $async$currentError = $async$result;
+ $async$goto = $async$handler;
+ }
+ while (true)
+ switch ($async$goto) {
+ case 0:
+ // Function start
+ $async$handler = 2;
+ $async$goto = 5;
+ return P._asyncAwait($async$self.$this._live_suite_controller$_suite._runner_suite$_controller._runner_suite$_close$0(), $async$call$0);
+ case 5:
+ // returning from await.
+ $async$next.push(4);
+ // goto finally
+ $async$goto = 3;
+ break;
+ case 2:
+ // uncaught
+ $async$next = [1];
+ case 3:
+ // finally
+ $async$handler = 1;
+ $async$self.$this._live_suite_controller$_onCloseCompleter.complete$0();
+ // goto the next finally handler
+ $async$goto = $async$next.pop();
+ break;
+ case 4:
+ // after finally
+ // implicit return
+ return P._asyncReturn(null, $async$completer);
+ case 1:
+ // rethrow
+ return P._asyncRethrow($async$currentError, $async$completer);
+ }
+ });
+ return P._asyncStartSync($async$call$0, $async$completer);
+ },
+ $signature: 2
+ };
+ R.ExpandedReporter.prototype = {
+ _onTestStarted$1: function(liveTest) {
+ var t1, t2, t3, t4, _this = this;
+ type$.LiveTest._check(liveTest);
+ liveTest.toString;
+ t1 = _this._stopwatch;
+ t2 = t1._stop != null;
+ if (t2)
+ if (t2) {
+ t2 = t1._core$_start;
+ t3 = H._checkIntNullable($.Primitives_timerTicks.call$0());
+ t4 = t1._stop;
+ if (typeof t3 !== "number")
+ return t3.$sub();
+ if (typeof t4 !== "number")
+ return H.iae(t4);
+ t1._core$_start = t2 + (t3 - t4);
+ t1._stop = null;
+ }
+ t1 = _this._engine._active;
+ if (t1.get$length(t1) === 1)
+ _this._progressLine$1(_this._description$1(liveTest));
+ t1 = liveTest._live_test_controller$_controller._onStateChangeController;
+ _this._subscriptions.add$1(0, new P._BroadcastStream(t1, H._instanceType(t1)._eval$1("_BroadcastStream<1>")).listen$1(new R.ExpandedReporter__onTestStarted_closure(_this, liveTest)));
+ t1 = _this._subscriptions;
+ t2 = liveTest._live_test_controller$_controller;
+ t3 = t2._onErrorController;
+ t1.add$1(0, new P._BroadcastStream(t3, H._instanceType(t3)._eval$1("_BroadcastStream<1>")).listen$1(new R.ExpandedReporter__onTestStarted_closure0(_this, liveTest)));
+ t2 = t2._onMessageController;
+ t1.add$1(0, new P._BroadcastStream(t2, H._instanceType(t2)._eval$1("_BroadcastStream<1>")).listen$1(new R.ExpandedReporter__onTestStarted_closure1(_this, liveTest)));
+ },
+ _onStateChange$2: function(liveTest, state) {
+ var t1, t2, t3;
+ if (state.status !== C.Status_complete)
+ return;
+ t1 = this._engine._active;
+ t2 = type$.UnmodifiableListView_LiveTest;
+ t3 = new P.UnmodifiableListView(t1, t2);
+ if (t3.get$length(t3) !== 0) {
+ t1 = new P.UnmodifiableListView(t1, t2);
+ this._progressLine$1(this._description$1(t1.get$first(t1)));
+ }
+ },
+ _expanded$_onError$3: function(liveTest, error, stackTrace) {
+ var t1, _this = this;
+ if (liveTest._live_test_controller$_controller._live_test_controller$_state.status !== C.Status_complete)
+ return;
+ _this._progressLine$2$suffix(_this._description$1(liveTest), " " + _this._bold + _this._red + "[E]" + _this._noColor);
+ t1 = _this._expanded$_sink;
+ t1.writeln$1(B.indent(H.S(error), null));
+ t1.writeln$1(B.indent(H.S(stackTrace), null));
+ return;
+ },
+ _expanded$_onDone$1: function(success) {
+ var t1, t2, t3, t4, _this = this;
+ H._checkBoolNullable(success);
+ if (success == null)
+ return;
+ t1 = _this._engine;
+ t2 = t1.get$liveTests();
+ if (t2.get$length(t2) === 0)
+ _this._expanded$_sink.writeln$1("No tests ran.");
+ else if (!success) {
+ for (t2 = type$.UnmodifiableListView_LiveTest, t1 = new P.UnmodifiableListView(t1._active, t2), t2 = new H.ListIterator(t1, t1.get$length(t1), t2._eval$1("ListIterator<ListMixin.E>")), t1 = _this._bold, t3 = _this._red, t4 = _this._noColor; t2.moveNext$0();)
+ _this._progressLine$2$suffix(_this._description$1(t2.__internal$_current), " - did not complete " + t1 + t3 + "[E]" + t4);
+ _this._progressLine$2$color("Some tests failed.", t3);
+ } else {
+ t1 = t1._passedGroup._union_set_controller$_set;
+ if (t1.get$length(t1) === 0)
+ _this._progressLine$1("All tests skipped.");
+ else
+ _this._progressLine$1("All tests passed!");
+ }
+ },
+ _progressLine$3$color$suffix: function(message, color, suffix) {
+ var t4, t5, _this = this,
+ t1 = _this._engine,
+ t2 = t1._passedGroup,
+ t3 = t2._union_set_controller$_set;
+ if (t3.get$length(t3) == _this._lastProgressPassed) {
+ t3 = t1._skippedGroup._union_set_controller$_set;
+ if (t3.get$length(t3) == _this._lastProgressSkipped) {
+ t3 = t1._failedGroup._union_set_controller$_set;
+ if (t3.get$length(t3) == _this._lastProgressFailed)
+ if (message == _this._lastProgressMessage)
+ t3 = suffix == null || suffix === _this._lastProgressSuffix;
+ else
+ t3 = false;
+ else
+ t3 = false;
+ } else
+ t3 = false;
+ } else
+ t3 = false;
+ if (t3)
+ return;
+ t3 = t2._union_set_controller$_set;
+ _this._lastProgressPassed = t3.get$length(t3);
+ t3 = t1._skippedGroup;
+ t4 = t3._union_set_controller$_set;
+ _this._lastProgressSkipped = t4.get$length(t4);
+ t1 = t1._failedGroup;
+ t4 = t1._union_set_controller$_set;
+ _this._lastProgressFailed = t4.get$length(t4);
+ _this._lastProgressMessage = message;
+ _this._lastProgressSuffix = suffix;
+ if (suffix != null)
+ message = J.$add$ansx(message, suffix);
+ if (color == null)
+ color = "";
+ t4 = P.Duration$(_this._stopwatch.get$elapsedMicroseconds(), 0)._duration;
+ t4 = C.JSString_methods.padLeft$2(C.JSInt_methods.toString$0(C.JSInt_methods._tdivFast$1(t4, 60000000)), 2, "0") + ":" + C.JSString_methods.padLeft$2(C.JSInt_methods.toString$0(C.JSInt_methods.$mod(C.JSInt_methods._tdivFast$1(t4, 1000000), 60)), 2, "0") + " " + _this._green + "+";
+ t2 = t2._union_set_controller$_set;
+ t5 = _this._noColor;
+ t2 = t4 + H.S(t2.get$length(t2)) + t5;
+ t4 = t3._union_set_controller$_set;
+ if (t4.get$length(t4) !== 0) {
+ t2 = t2 + _this._yellow + " ~";
+ t3 = t3._union_set_controller$_set;
+ t3 = t2 + H.S(t3.get$length(t3)) + t5;
+ t2 = t3;
+ }
+ t3 = t1._union_set_controller$_set;
+ if (t3.get$length(t3) !== 0) {
+ t2 = t2 + _this._red + " -";
+ t1 = t1._union_set_controller$_set;
+ t1 = t2 + H.S(t1.get$length(t1)) + t5;
+ } else
+ t1 = t2;
+ t5 = t1 + ": " + color + H.S(message) + t5;
+ _this._expanded$_sink.writeln$1(t5.charCodeAt(0) == 0 ? t5 : t5);
+ },
+ _progressLine$2$suffix: function(message, suffix) {
+ return this._progressLine$3$color$suffix(message, null, suffix);
+ },
+ _progressLine$2$color: function(message, color) {
+ return this._progressLine$3$color$suffix(message, color, null);
+ },
+ _progressLine$1: function(message) {
+ return this._progressLine$3$color$suffix(message, null, null);
+ },
+ _description$1: function(liveTest) {
+ var t1 = liveTest._live_test_controller$_controller;
+ return t1._test.name;
+ }
+ };
+ R.ExpandedReporter__onTestStarted_closure.prototype = {
+ call$1: function(state) {
+ return this.$this._onStateChange$2(this.liveTest, type$.State._check(state));
+ },
+ $signature: 100
+ };
+ R.ExpandedReporter__onTestStarted_closure0.prototype = {
+ call$1: function(error) {
+ type$.AsyncError._check(error);
+ return this.$this._expanded$_onError$3(this.liveTest, error.error, error.stackTrace);
+ },
+ $signature: 101
+ };
+ R.ExpandedReporter__onTestStarted_closure1.prototype = {
+ call$1: function(message) {
+ var t1, text;
+ type$.Message._check(message);
+ t1 = this.$this;
+ t1._progressLine$1(t1._description$1(this.liveTest));
+ text = message.text;
+ if (message.type === C.MessageType_skip)
+ text = " " + t1._yellow + text + t1._noColor;
+ t1._expanded$_sink.writeln$1(text);
+ },
+ $signature: 27
+ };
+ Y.RunnerSuite.prototype = {};
+ Y.RunnerSuiteController.prototype = {
+ _runner_suite$_close$0: function() {
+ return this._closeMemo.runOnce$1(new Y.RunnerSuiteController__close_closure(this));
+ },
+ set$_runner_suite$_suite: function(_suite) {
+ type$.Future_RunnerSuite._check(_suite);
+ }
+ };
+ Y.RunnerSuiteController__close_closure.prototype = {
+ call$0: function() {
+ var $async$goto = 0,
+ $async$completer = P._makeAsyncAwaitCompleter(type$.Null),
+ $async$self = this;
+ var $async$call$0 = P._wrapJsFunctionForAsync(function($async$errorCode, $async$result) {
+ if ($async$errorCode === 1)
+ return P._asyncRethrow($async$result, $async$completer);
+ while (true)
+ switch ($async$goto) {
+ case 0:
+ // Function start
+ $async$goto = 2;
+ return P._asyncAwait($async$self.$this._onDebuggingController.close$0(0), $async$call$0);
+ case 2:
+ // returning from await.
+ // implicit return
+ return P._asyncReturn(null, $async$completer);
+ }
+ });
+ return P._asyncStartSync($async$call$0, $async$completer);
+ },
+ $signature: 2
+ };
+ T.RuntimeSelection.prototype = {};
+ U.SuiteConfiguration.prototype = {};
+ X.PrintSink.prototype = {
+ writeln$1: function(obj) {
+ this._print_sink$_buffer._contents += obj + "\n";
+ this._flush$0();
+ },
+ _flush$0: function() {
+ var t1 = this._print_sink$_buffer;
+ if (C.JSString_methods.endsWith$1(t1.toString$0(0), "\n")) {
+ P.print(t1);
+ t1._contents = "";
+ }
+ },
+ $isStringSink: 1
+ };
+ E.JSStackTraceMapper.prototype = {};
+ E.JSStackTraceMapper__deserializePackageConfigMap_closure.prototype = {
+ call$2: function(key, value) {
+ return new P.MapEntry(H._checkStringNullable(key), P.Uri_parse(H._checkStringNullable(value)), type$.MapEntry_String_Uri);
+ },
+ $signature: 102
+ };
+ R._declarer_closure.prototype = {
+ call$0: function() {
+ var $async$goto = 0,
+ $async$completer = P._makeAsyncAwaitCompleter(type$.Null),
+ $async$returnValue, controller, suite, engine, t1, t2, t3, t4, $async$temp1;
+ var $async$call$0 = P._wrapJsFunctionForAsync(function($async$errorCode, $async$result) {
+ if ($async$errorCode === 1)
+ return P._asyncRethrow($async$result, $async$completer);
+ while (true)
+ switch ($async$goto) {
+ case 0:
+ // Function start
+ t1 = $.$get$SuiteConfiguration_empty();
+ t2 = $._globalDeclarer.build$0();
+ t3 = E.SuitePlatform$(C.Runtime_ql0, false, $.$get$currentOSGuess());
+ t4 = P.Uri_base();
+ t4 = $.$get$context().prettyUri$1(t4);
+ controller = new Y.RunnerSuiteController(t1, null, new P._AsyncBroadcastStreamController(null, null, type$._AsyncBroadcastStreamController_bool), P.LinkedHashSet_LinkedHashSet$_empty(type$.String), new S.AsyncMemoizer(new P._AsyncCompleter(new P._Future($.Zone__current, type$._Future_dynamic), type$._AsyncCompleter_dynamic), type$.AsyncMemoizer_dynamic));
+ suite = new Y.RunnerSuite(controller, t3, t4, U.Suite__filterGroup(t2, t3));
+ t1 = new P._Future($.Zone__current, type$._Future_RunnerSuite);
+ t1._asyncComplete$1(suite);
+ controller.set$_runner_suite$_suite(t1);
+ engine = O.Engine$();
+ t1 = engine._suiteController;
+ t1.add$1(0, H._instanceType(t1)._precomputed1._check(type$.RunnerSuite._check(suite)));
+ t1.close$0(0);
+ if ($.Stopwatch__frequency == null) {
+ H.Primitives_initTicker();
+ $.Stopwatch__frequency = $.Primitives_timerFrequency;
+ }
+ t1 = P.LinkedHashSet_LinkedHashSet$_empty(type$.StreamSubscription_dynamic);
+ t2 = new R.ExpandedReporter(true, "\x1b[32m", "\x1b[31m", "\x1b[33m", "\x1b[1;30m", "\x1b[1m", "\x1b[0m", engine, false, false, new P.Stopwatch(), t1, new X.PrintSink(new P.StringBuffer("")));
+ t3 = engine._onTestStartedGroup._stream_group$_controller;
+ t3.toString;
+ t1.add$1(0, new P._BroadcastStream(t3, H._instanceType(t3)._eval$1("_BroadcastStream<1>")).listen$1(t2.get$_onTestStarted()));
+ t3 = engine.get$success();
+ t3.toString;
+ t1.add$1(0, P.Stream_Stream$fromFuture(t3, t3.$ti._precomputed1).listen$1(t2.get$_expanded$_onDone()));
+ t2 = type$.dynamic;
+ $async$temp1 = H;
+ $async$goto = 3;
+ return P._asyncAwait(P.runZoned(new R._declarer__closure(engine), null, null, P.LinkedHashMap_LinkedHashMap$_literal([C.Symbol_Drw, $._globalDeclarer], t2, t2), type$.Future_bool), $async$call$0);
+ case 3:
+ // returning from await.
+ if ($async$temp1.boolConversionCheck($async$result)) {
+ $async$returnValue = null;
+ // goto return
+ $async$goto = 1;
+ break;
+ }
+ P.print("");
+ P.Future_Future$error("Dummy exception to set exit code.", null, type$.void);
+ case 1:
+ // return
+ return P._asyncReturn($async$returnValue, $async$completer);
+ }
+ });
+ return P._asyncStartSync($async$call$0, $async$completer);
+ },
+ $signature: 2
+ };
+ R._declarer__closure.prototype = {
+ call$0: function() {
+ return U.Invoker_guard(this.engine.get$run(), type$.Future_bool);
+ },
+ $signature: 31
+ };
+ G.main_closure0.prototype = {
+ call$0: function() {
+ R.test("sample test", new G.main__closure());
+ },
+ $signature: 0
+ };
+ G.main__closure.prototype = {
+ call$0: function() {
+ var $async$goto = 0,
+ $async$completer = P._makeAsyncAwaitCompleter(type$.Null),
+ res;
+ var $async$call$0 = P._wrapJsFunctionForAsync(function($async$errorCode, $async$result) {
+ if ($async$errorCode === 1)
+ return P._asyncRethrow($async$result, $async$completer);
+ while (true)
+ switch ($async$goto) {
+ case 0:
+ // Function start
+ res = G.method1();
+ if (res === 0)
+ G.method2();
+ G.expect(true, C.C__IsTrue, null);
+ // implicit return
+ return P._asyncReturn(null, $async$completer);
+ }
+ });
+ return P._asyncStartSync($async$call$0, $async$completer);
+ },
+ $signature: 2
+ };
+ R.main_closure.prototype = {
+ call$0: function() {
+ return G.main_test__main$closure();
+ },
+ $signature: 103
+ };
+ (function aliases() {
+ var _ = J.JavaScriptObject.prototype;
+ _.super$JavaScriptObject$toString = _.toString$0;
+ _ = P._BroadcastStreamController.prototype;
+ _.super$_BroadcastStreamController$_addEventError = _._addEventError$0;
+ _ = P.Iterable.prototype;
+ _.super$Iterable$where = _.where$1;
+ _.super$Iterable$skipWhile = _.skipWhile$1;
+ _ = W.EventTarget.prototype;
+ _.super$EventTarget$addEventListener = _.addEventListener$3;
+ _ = Y.DelegatingStreamSubscription.prototype;
+ _.super$DelegatingStreamSubscription$onError = _.onError$1;
+ _.super$DelegatingStreamSubscription$cancel = _.cancel$0;
+ _ = M.TypeMatcher.prototype;
+ _.super$TypeMatcher$describe = _.describe$1;
+ _.super$TypeMatcher$matches = _.matches$2;
+ _ = Y.SourceSpanMixin.prototype;
+ _.super$SourceSpanMixin$$eq = _.$eq;
+ _ = X.StringScanner.prototype;
+ _.super$StringScanner$matches = _.matches$1;
+ })();
+ (function installTearOffs() {
+ var _instance = hunkHelpers.installInstanceTearOff,
+ _static_0 = hunkHelpers._static_0,
+ _static_1 = hunkHelpers._static_1,
+ _static = hunkHelpers.installStaticTearOff,
+ _instance_0_u = hunkHelpers._instance_0u,
+ _instance_1_i = hunkHelpers._instance_1i,
+ _instance_0_i = hunkHelpers._instance_0i,
+ _instance_1_u = hunkHelpers._instance_1u,
+ _instance_2_u = hunkHelpers._instance_2u;
+ _instance(J.JSString.prototype, "get$startsWith", 1, 1, null, ["call$2", "call$1"], ["startsWith$2", "startsWith$1"], 57, 0);
+ _static_0(H, "_js_helper_Primitives_dateNow$closure", "Primitives_dateNow", 36);
+ _static_1(P, "async__AsyncRun__scheduleImmediateJsOverride$closure", "_AsyncRun__scheduleImmediateJsOverride", 20);
+ _static_1(P, "async__AsyncRun__scheduleImmediateWithSetImmediate$closure", "_AsyncRun__scheduleImmediateWithSetImmediate", 20);
+ _static_1(P, "async__AsyncRun__scheduleImmediateWithTimer$closure", "_AsyncRun__scheduleImmediateWithTimer", 20);
+ _static_1(P, "async_Future__kTrue$closure", "Future__kTrue", 9);
+ _static_0(P, "async___startMicrotaskLoop$closure", "_startMicrotaskLoop", 1);
+ _static_1(P, "async___nullDataHandler$closure", "_nullDataHandler", 11);
+ _static(P, "async___nullErrorHandler$closure", 1, null, ["call$2", "call$1"], ["_nullErrorHandler", function(error) {
+ return P._nullErrorHandler(error, null);
+ }], 12, 0);
+ _static_0(P, "async___nullDoneHandler$closure", "_nullDoneHandler", 1);
+ _static(P, "async___rootHandleUncaughtError$closure", 5, null, ["call$5"], ["_rootHandleUncaughtError"], 105, 0);
+ _static(P, "async___rootRun$closure", 4, null, ["call$1$4", "call$4"], ["_rootRun", function($self, $parent, zone, f) {
+ return P._rootRun($self, $parent, zone, f, type$.dynamic);
+ }], 106, 0);
+ _static(P, "async___rootRunUnary$closure", 5, null, ["call$2$5", "call$5"], ["_rootRunUnary", function($self, $parent, zone, f, arg) {
+ return P._rootRunUnary($self, $parent, zone, f, arg, type$.dynamic, type$.dynamic);
+ }], 107, 0);
+ _static(P, "async___rootRunBinary$closure", 6, null, ["call$3$6"], ["_rootRunBinary"], 108, 0);
+ _static(P, "async___rootRegisterCallback$closure", 4, null, ["call$1$4", "call$4"], ["_rootRegisterCallback", function($self, $parent, zone, f) {
+ return P._rootRegisterCallback($self, $parent, zone, f, type$.dynamic);
+ }], 35, 0);
+ _static(P, "async___rootRegisterUnaryCallback$closure", 4, null, ["call$2$4", "call$4"], ["_rootRegisterUnaryCallback", function($self, $parent, zone, f) {
+ return P._rootRegisterUnaryCallback($self, $parent, zone, f, type$.dynamic, type$.dynamic);
+ }], 33, 0);
+ _static(P, "async___rootRegisterBinaryCallback$closure", 4, null, ["call$3$4", "call$4"], ["_rootRegisterBinaryCallback", function($self, $parent, zone, f) {
+ return P._rootRegisterBinaryCallback($self, $parent, zone, f, type$.dynamic, type$.dynamic, type$.dynamic);
+ }], 109, 0);
+ _static(P, "async___rootErrorCallback$closure", 5, null, ["call$5"], ["_rootErrorCallback"], 32, 0);
+ _static(P, "async___rootScheduleMicrotask$closure", 4, null, ["call$4"], ["_rootScheduleMicrotask"], 110, 0);
+ _static(P, "async___rootCreateTimer$closure", 5, null, ["call$5"], ["_rootCreateTimer"], 111, 0);
+ _static(P, "async___rootCreatePeriodicTimer$closure", 5, null, ["call$5"], ["_rootCreatePeriodicTimer"], 112, 0);
+ _static(P, "async___rootPrint$closure", 4, null, ["call$4"], ["_rootPrint"], 37, 0);
+ _static_1(P, "async___printToZone$closure", "_printToZone", 113);
+ _static(P, "async___rootFork$closure", 5, null, ["call$5"], ["_rootFork"], 114, 0);
+ var _;
+ _instance_0_u(_ = P._BroadcastSubscription.prototype, "get$_onPause", "_onPause$0", 1);
+ _instance_0_u(_, "get$_onResume", "_onResume$0", 1);
+ _instance_1_i(_ = P._BroadcastStreamController.prototype, "get$add", "add$1", 11);
+ _instance(_, "get$addError", 0, 1, null, ["call$2", "call$1"], ["addError$2", "addError$1"], 12, 0);
+ _instance(P._AsyncCompleter.prototype, "get$complete", 0, 0, null, ["call$1", "call$0"], ["complete$1", "complete$0"], 47, 0);
+ _instance(P._SyncCompleter.prototype, "get$complete", 0, 0, null, ["call$1", "call$0"], ["complete$1", "complete$0"], 47, 0);
+ _instance(P._Future.prototype, "get$_completeError", 0, 1, null, ["call$2", "call$1"], ["_completeError$2", "_completeError$1"], 12, 0);
+ _instance_1_i(_ = P._StreamController.prototype, "get$add", "add$1", 11);
+ _instance(_, "get$addError", 0, 1, null, ["call$2", "call$1"], ["addError$2", "addError$1"], 12, 0);
+ _instance_0_i(_, "get$close", "close$0", 14);
+ _instance_1_u(_, "get$_add", "_add$1", 11);
+ _instance_2_u(_, "get$_async$_addError", "_async$_addError$2", 70);
+ _instance_0_u(_, "get$_close", "_close$0", 1);
+ _instance_0_u(_ = P._ControllerSubscription.prototype, "get$_onPause", "_onPause$0", 1);
+ _instance_0_u(_, "get$_onResume", "_onResume$0", 1);
+ _instance_1_i(P._StreamSinkWrapper.prototype, "get$add", "add$1", 11);
+ _instance_0_u(_ = P._BufferingStreamSubscription.prototype, "get$_onPause", "_onPause$0", 1);
+ _instance_0_u(_, "get$_onResume", "_onResume$0", 1);
+ _instance_0_u(P._DoneStreamSubscription.prototype, "get$_sendDone", "_sendDone$0", 1);
+ _instance_1_i(P._LinkedHashSet.prototype, "get$contains", "contains$1", 26);
+ _static_1(P, "core_Uri_decodeComponent$closure", "Uri_decodeComponent", 7);
+ _instance_0_i(S.NullStreamSink.prototype, "get$close", "close$0", 14);
+ _instance_0_u(_ = L.StreamGroup.prototype, "get$_onListen", "_onListen$0", 1);
+ _instance_0_u(_, "get$_onCancelBroadcast", "_onCancelBroadcast$0", 1);
+ _instance_1_i(M._DelegatingIterableBase.prototype, "get$contains", "contains$1", 26);
+ _instance(D._DeepMatcher.prototype, "get$_recursiveMatch", 0, 4, null, ["call$4"], ["_recursiveMatch$4"], 58, 0);
+ _static_1(Z, "pretty_print___escapeString$closure", "_escapeString", 7);
+ _static_1(M, "util___getHexLiteral$closure", "_getHexLiteral", 7);
+ _instance(Y.SourceSpanMixin.prototype, "get$message", 1, 1, null, ["call$2$color", "call$1"], ["message$2$color", "message$1"], 71, 0);
+ _instance(_ = O.StackZoneSpecification.prototype, "get$_stack_zone_specification$_registerCallback", 0, 4, null, ["call$1$4", "call$4"], ["_stack_zone_specification$_registerCallback$1$4", "_stack_zone_specification$_registerCallback$4"], 35, 0);
+ _instance(_, "get$_stack_zone_specification$_registerUnaryCallback", 0, 4, null, ["call$2$4", "call$4"], ["_stack_zone_specification$_registerUnaryCallback$2$4", "_stack_zone_specification$_registerUnaryCallback$4"], 33, 0);
+ _instance(_, "get$_stack_zone_specification$_registerBinaryCallback", 0, 4, null, ["call$3$4", "call$4"], ["_stack_zone_specification$_registerBinaryCallback$3$4", "_stack_zone_specification$_registerBinaryCallback$4"], 63, 0);
+ _instance(_, "get$_stack_zone_specification$_errorCallback", 0, 5, null, ["call$5"], ["_stack_zone_specification$_errorCallback$5"], 32, 0);
+ _instance(_ = K._GuaranteeSink.prototype, "get$addError", 0, 1, null, ["call$2", "call$1"], ["addError$2", "addError$1"], 12, 0);
+ _instance(_, "get$_addError", 0, 1, null, ["call$2", "call$1"], ["_addError$2", "_addError$1"], 66, 0);
+ _instance_0_i(_, "get$close", "close$0", 13);
+ _instance_0_u(D._MultiChannel.prototype, "get$_closeInnerChannel", "_closeInnerChannel$0", 1);
+ _instance_0_u(_ = U.Invoker.prototype, "get$_invoker$_onRun", "_invoker$_onRun$0", 1);
+ _instance_0_u(_, "get$_runTearDowns", "_runTearDowns$0", 13);
+ _instance_0_u(V._LiveTest.prototype, "get$run", "run$0", 13);
+ _instance_1_i(V.LiveTestController.prototype, "get$message", "message$1", 96);
+ _instance_0_u(O.Engine.prototype, "get$run", "run$0", 31);
+ _instance_1_u(_ = R.ExpandedReporter.prototype, "get$_onTestStarted", "_onTestStarted$1", 98);
+ _instance_1_u(_, "get$_expanded$_onDone", "_expanded$_onDone$1", 99);
+ _static_0(G, "main_test__main$closure", "main0", 34);
+ _static(P, "math__max$closure", 2, null, ["call$1$2", "call$2"], ["max", function(a, b) {
+ return P.max(a, b, type$.num);
+ }], 76, 0);
+ })();
+ (function inheritance() {
+ var _mixin = hunkHelpers.mixin,
+ _inherit = hunkHelpers.inherit,
+ _inheritMany = hunkHelpers.inheritMany;
+ _inherit(P.Object, null);
+ _inheritMany(P.Object, [H.JS_CONST, J.Interceptor, J.JSObject, J.ArrayIterator, P.Iterable, H.CastIterator, P.MapMixin, H.Closure, P._ListBase_Object_ListMixin, H.ListIterator, P.Iterator, H.ExpandIterator, H.EmptyIterator, H.FixedLengthListMixin, H.UnmodifiableListMixin, H.Symbol, H.ConstantMap, H.TypeErrorDecoder, P.Error, H.ExceptionAndStackTrace, H._StackTrace, H.LinkedHashMapCell, H.LinkedHashMapKeyIterator, H.JSSyntaxRegExp, H._MatchImplementation, H._AllMatchesIterator, H.StringMatch, H._StringAllMatchesIterator, H.Rti, H._FunctionParameters, H._Type, P._TimerImpl, P._AsyncAwaitCompleter, P.Stream, P._BufferingStreamSubscription, P._BroadcastStreamController, P.Future, P.TimeoutException, P.Completer, P._Completer, P._FutureListener, P._Future, P._AsyncCallbackEntry, P.StreamSubscription, P.StreamTransformerBase, P._StreamController, P._SyncStreamControllerDispatch, P._AsyncStreamControllerDispatch, P._StreamSinkWrapper, P._AddStreamState, P._PendingEvents, P._DelayedEvent, P._DelayedDone, P._DoneStreamSubscription, P._StreamIterator, P.Timer, P.AsyncError, P._ZoneFunction, P.ZoneSpecification, P._ZoneSpecification, P.ZoneDelegate, P.Zone, P._ZoneDelegate, P._Zone, P._HashMapKeyIterator, P._SetBase, P._LinkedHashSetCell, P._LinkedHashSetIterator, P.ListMixin, P._UnmodifiableMapMixin, P.MapView, P._ListQueueIterator, P.SetMixin, P._SetBase_Object_SetMixin, P.Codec, P._Utf8Encoder, P._Utf8Decoder, P.bool, P.DateTime, P.num, P.Duration, P.OutOfMemoryError, P.StackOverflowError, P._Exception, P.FormatException, P.Expando, P.Function, P.List, P.Map, P.MapEntry, P.Null, P.Pattern, P.Match, P.RegExpMatch, P.StackTrace, P._StringStackTrace, P.Stopwatch, P.String, P.RuneIterator, P.StringBuffer, P.Uri, P._Uri, P.UriData, P._SimpleUri, W.EventStreamProvider, P._StructuredClone, P._AcceptStructuredClone, P.ByteBuffer, P.ByteData, P.Int8List, P.Uint8List, P.Uint8ClampedList, P.Int16List, P.Uint16List, P.Int32List, P.Uint32List, P.Float32List, P.Float64List, S.AsyncMemoizer, O.DelegatingSink, Y.DelegatingStreamSubscription, F.FutureGroup, S.NullStreamSink, V.ErrorResult, E.Result, F.ValueResult, Y.StreamCompleter, L.StreamGroup, L._StreamGroupState, G.StreamQueue, G._EventRequest, G._NextRequest, G._RestRequest, T.StreamSinkCompleter, T._CompleterSink, X.BooleanSelector, X.All, U.VariableNode, U.NotNode, U.OrNode, U.AndNode, U.ConditionalNode, T.Evaluator, Y.BooleanSelectorImpl, R.IntersectionSelector, O.None, G.Parser, O.Scanner, L.Token, L.IdentifierToken, L.TokenType, B.RecursiveVisitor, Q._QueueList_Object_ListMixin, Y.UnionSetController, M._DelegatingIterableBase, L.UnmodifiableSetMixin, G.Matcher, E.StringDescription, F.PackageConfigResolver, D.PackageRootResolver, M.Context, M._PathDirection, M._PathRelation, O.Style, X.ParsedPath, X.PathException, O.Pool, O.PoolResource, T.Mapping, T.TargetLineEntry, T.TargetEntry, T._MappingTokenizer, T._TokenKind, Y.SourceSpanMixin, Y.SourceFile, D.SourceLocationMixin, U.Highlighter, V.SourceLocation, V.SourceSpan, G.SourceSpanException, U.Chain, A.Frame, X.LazyChain, T.LazyTrace, O.StackZoneSpecification, O._Node, Y.Trace, N.UnparsedFrame, R.StreamChannelMixin, K._GuaranteeSink, N.StreamChannelCompleter, B.StreamChannelController, R.StreamChannel, X.StringScanner, S._SpanScannerState, A.AsciiGlyphSet, K.UnicodeGlyphSet, K.ClosedException, X.Declarer, O.Group, V.GroupEntry, V.Test, U.Invoker, U._AsyncCounter, Z.LiveTest, V.LiveTestController, D.Message, D.MessageType, O.Metadata, N.OperatingSystem, E.PlatformSelector, B.Runtime, U.StackTraceFormatter, G.State, G.Status, G.Result0, U.Suite, E.SuitePlatform, G.TestFailure, R.Timeout, S.RemoteListener, N.SuiteChannelManager, E.StackTraceMapper, O.Engine, E.LiveSuite, B.LiveSuiteController, R.ExpandedReporter, Y.RunnerSuiteController, T.RuntimeSelection, U.SuiteConfiguration, X.PrintSink]);
+ _inheritMany(J.Interceptor, [J.JSBool, J.JSNull, J.JavaScriptObject, J.JSArray, J.JSNumber, J.JSString, H.NativeByteBuffer, H.NativeTypedData, W.Event, W.Blob, W.DomError, W.DomException, W.EventTarget, W.Location, W.MediaError, W.NavigatorUserMediaError, W.OverconstrainedError, W.PositionError, P.SqlError]);
+ _inheritMany(J.JavaScriptObject, [J.PlainJavaScriptObject, J.UnknownJavaScriptObject, J.JavaScriptFunction]);
+ _inherit(J.JSUnmodifiableArray, J.JSArray);
+ _inheritMany(J.JSNumber, [J.JSInt, J.JSDouble]);
+ _inheritMany(P.Iterable, [H._CastIterableBase, H.EfficientLengthIterable, H.MappedIterable, H.WhereIterable, H.ExpandIterable, H.SkipWhileIterable, H._ConstantMapKeyIterable, P.IterableBase, H._StringAllMatchesIterable, P.Runes]);
+ _inherit(H.CastIterable, H._CastIterableBase);
+ _inherit(H._EfficientLengthCastIterable, H.CastIterable);
+ _inherit(P.MapBase, P.MapMixin);
+ _inheritMany(P.MapBase, [H.CastMap, H.JsLinkedHashMap, P._HashMap, P._JsonMap]);
+ _inheritMany(H.Closure, [H.CastMap_forEach_closure, H.ConstantMap_map_closure, H.Instantiation, H.Primitives_initTicker_closure, H.unwrapException_saveStackTrace, H.TearOffClosure, H.JsLinkedHashMap_values_closure, H.JsLinkedHashMap_addAll_closure, H.initHooks_closure, H.initHooks_closure0, H.initHooks_closure1, P._AsyncRun__initializeScheduleImmediate_internalCallback, P._AsyncRun__initializeScheduleImmediate_closure, P._AsyncRun__scheduleImmediateJsOverride_internalCallback, P._AsyncRun__scheduleImmediateWithSetImmediate_internalCallback, P._TimerImpl_internalCallback, P._TimerImpl$periodic_closure, P._awaitOnObject_closure, P._awaitOnObject_closure0, P._wrapJsFunctionForAsync_closure, P._SyncBroadcastStreamController__sendData_closure, P._SyncBroadcastStreamController__sendError_closure, P._SyncBroadcastStreamController__sendDone_closure, P.Future_Future_closure, P.Future_Future$microtask_closure, P.Future_wait_handleError, P.Future_wait_closure, P.Future_forEach_closure, P.Future_doWhile_closure, P._Future__addListener_closure, P._Future__prependListeners_closure, P._Future__chainForeignFuture_closure, P._Future__chainForeignFuture_closure0, P._Future__chainForeignFuture_closure1, P._Future__asyncComplete_closure, P._Future__chainFuture_closure, P._Future__asyncCompleteError_closure, P._Future__propagateToListeners_handleWhenCompleteCallback, P._Future__propagateToListeners_handleWhenCompleteCallback_closure, P._Future__propagateToListeners_handleValueCallback, P._Future__propagateToListeners_handleError, P.Stream_Stream$fromFuture_closure, P.Stream_Stream$fromFuture_closure0, P.Stream_Stream$fromIterable_closure, P.Stream_pipe_closure, P.Stream_length_closure, P.Stream_length_closure0, P.Stream_first_closure, P.Stream_first_closure0, P.Stream_last_closure, P.Stream_last_closure0, P.Stream_firstWhere_closure, P.Stream_firstWhere__closure, P.Stream_firstWhere__closure0, P.Stream_firstWhere_closure0, P._StreamController__subscribe_closure, P._StreamController__recordCancel_complete, P._AddStreamState_makeErrorHandler_closure, P._AddStreamState_cancel_closure, P._BufferingStreamSubscription__sendError_sendError, P._BufferingStreamSubscription__sendDone_sendDone, P._PendingEvents_schedule_closure, P._cancelAndError_closure, P._cancelAndErrorClosure_closure, P._cancelAndValue_closure, P._CustomZone_bindCallback_closure, P._CustomZone_bindUnaryCallback_closure, P._CustomZone_bindCallbackGuarded_closure, P._CustomZone_bindUnaryCallbackGuarded_closure, P._rootHandleUncaughtError_closure, P._RootZone_bindCallback_closure, P._RootZone_bindCallbackGuarded_closure, P._RootZone_bindUnaryCallbackGuarded_closure, P.runZoned_closure, P.HashMap_HashMap$from_closure, P.LinkedHashMap_LinkedHashMap$from_closure, P.MapBase_mapToString_closure, P.Duration_toString_sixDigits, P.Duration_toString_twoDigits, P.Uri__parseIPv4Address_error, P.Uri_parseIPv6Address_error, P.Uri_parseIPv6Address_parseHex, P._Uri__Uri$notSimple_closure, P._Uri__checkNonWindowsPathReservedCharacters_closure, P._Uri__makePath_closure, P._createTables_closure, P._createTables_build, P._createTables_setChars, P._createTables_setRange, W._EventStreamSubscription_closure, P._StructuredClone_walk_closure, P._StructuredClone_walk_closure0, P._AcceptStructuredClone_walk_closure, P._convertDataTree__convert, P.promiseToFuture_closure, P.promiseToFuture_closure0, F.FutureGroup_add_closure, F.FutureGroup_add_closure0, S.NullStreamSink_addStream_closure, L.StreamGroup_add_closure, L.StreamGroup_add_closure0, L.StreamGroup__onListen_closure, L.StreamGroup__onCancelBroadcast_closure, L.StreamGroup__listenToStream_closure, G.StreamQueue__ensureListening_closure, G.StreamQueue__ensureListening_closure1, G.StreamQueue__ensureListening_closure0, T._CompleterSink__setDestinationSink_closure, T._CancelOnErrorSubscriptionWrapper_onError_closure, T._CancelOnErrorSubscriptionWrapper_onError__closure, Y.mapMap_closure, Y.mapMap_closure0, Y.mergeMaps_closure, M.UnionSet_length_closure, M.UnionSet__iterable_closure, D._DeepMatcher__compareSets_closure, Z.prettyPrint__prettyPrint, Z.prettyPrint__prettyPrint_pp, Z.prettyPrint__prettyPrint_closure, Z.prettyPrint__prettyPrint_closure0, Z.prettyPrint__prettyPrint_closure1, M.wrapMatcher_closure, M.escape_closure, F.PackageConfigResolver__normalizeMap_closure, M.Context_join_closure, M.Context_joinAll_closure, M.Context_split_closure, M._validateArgList_closure, X.ParsedPath_normalize_closure, L.WindowsStyle_absolutePathToUri_closure, O.Pool_close_closure, O.Pool__onResourceReleaseAllowed_closure, O.Pool__runOnRelease_closure, O.Pool__runOnRelease_closure0, O.mapStackTrace_closure, O.mapStackTrace_closure0, O.mapStackTrace_closure1, O._prettifyMember_closure, O._prettifyMember_closure0, T.SingleMapping$fromJson_closure, T.SingleMapping__findLine_closure, T.SingleMapping__findColumn_closure, L.closure, U.Highlighter__writeFirstLine_closure, U.Highlighter__writeFirstLine_closure0, U.Highlighter__writeFirstLine_closure1, U.Highlighter__writeFirstLine_closure2, U.Highlighter__writeIntermediateLines_closure, U.Highlighter__writeLastLine_closure, U.Highlighter__writeLastLine_closure0, U.Highlighter__writeLastLine_closure1, U.Highlighter__writeSidebar_closure, U.Chain_capture_closure, U.Chain_Chain$current_closure, U.Chain_Chain$forTrace_closure, U.Chain_Chain$parse_closure, U.Chain_Chain$parse_closure0, U.Chain_foldFrames_closure, U.Chain_foldFrames_closure0, U.Chain_toTrace_closure, U.Chain_toString_closure0, U.Chain_toString__closure0, U.Chain_toString_closure, U.Chain_toString__closure, A.Frame_Frame$parseVM_closure, A.Frame_Frame$parseV8_closure, A.Frame_Frame$parseV8_closure_parseLocation, A.Frame_Frame$parseFirefox_closure, A.Frame_Frame$parseFriendly_closure, X.LazyChain_foldFrames_closure, X.LazyChain_toTrace_closure, T.LazyTrace_foldFrames_closure, O.StackZoneSpecification_chainFor_closure, O.StackZoneSpecification_chainFor_closure0, O.StackZoneSpecification__registerCallback_closure, O.StackZoneSpecification__registerUnaryCallback_closure, O.StackZoneSpecification__registerUnaryCallback__closure, O.StackZoneSpecification__registerBinaryCallback_closure, O.StackZoneSpecification__registerBinaryCallback__closure, O.StackZoneSpecification__currentTrace_closure, Y.Trace_Trace$current_closure, Y.Trace_Trace$from_closure, Y.Trace__parseVM_closure, Y.Trace$parseV8_closure, Y.Trace$parseV8_closure0, Y.Trace$parseJSCore_closure, Y.Trace$parseJSCore_closure0, Y.Trace$parseFirefox_closure, Y.Trace$parseFirefox_closure0, Y.Trace$parseFriendly_closure, Y.Trace$parseFriendly_closure0, Y.Trace_foldFrames_closure, Y.Trace_foldFrames_closure0, Y.Trace_toString_closure0, Y.Trace_toString_closure, K.GuaranteeChannel_closure, K.GuaranteeChannel__closure, K._GuaranteeSink__addError_closure, K._GuaranteeSink_addStream_closure, D._MultiChannel_closure, D._MultiChannel_closure0, D._MultiChannel_closure1, D._MultiChannel__closure, D._MultiChannel_virtualChannel_closure, D._MultiChannel_virtualChannel_closure0, L.internalBootstrapBrowserTest_closure, N.postMessageChannel_closure, N.postMessageChannel_closure0, N.postMessageChannel__closure, N.postMessageChannel__closure0, N.postMessageChannel__closure1, X.Declarer_test_closure, X.Declarer_test__closure, X.Declarer_test___closure, X.Declarer_group_closure, X.Declarer_build_closure, X.Declarer__runSetUps_closure, X.Declarer__tearDownAll_closure, X.Declarer__tearDownAll__closure, X.Declarer__tearDownAll___closure, O.Group_forPlatform_closure, O.Group__map_closure, O.Group__map_closure0, U.Invoker_guard_closure, U.Invoker_guard__closure, U.Invoker_waitForOutstandingCallbacks_closure, U.Invoker_waitForOutstandingCallbacks_closure0, U.Invoker_heartbeat_message, U.Invoker_heartbeat_closure, U.Invoker_heartbeat__closure, U.Invoker__handleError_closure, U.Invoker__handleError_closure0, U.Invoker__onRun_closure, U.Invoker__onRun__closure, U.Invoker__onRun___closure, U.Invoker__onRun____closure, U.Invoker__onRun___closure0, O.Metadata_Metadata__unresolved, O.Metadata_Metadata_closure, O.Metadata$deserialize_closure, O.Metadata__validateTags_closure, O.Metadata__validateTags_closure0, O.Metadata_validatePlatformSelectors_closure, O.Metadata_merge_closure, O.Metadata_merge_closure0, O.Metadata_forPlatform_closure, O.Metadata_serialize_closure, O.Metadata_serialize_closure0, N.OperatingSystem_find_closure, N.OperatingSystem_find_closure0, E.PlatformSelector$parse_closure, E.PlatformSelector_validate_closure, E.PlatformSelector_validate__closure, E.PlatformSelector_evaluate_closure, B.Runtime_Runtime$deserialize_closure, U.StackTraceFormatter_formatStackTrace_closure, G._expect_closure0, G._expect_closure, S.RemoteListener_start_closure, S.RemoteListener_start_closure0, S.RemoteListener_start_closure1, S.RemoteListener_start__closure, S.RemoteListener_start___closure, S.RemoteListener_start____closure, S.RemoteListener_start____closure0, S.RemoteListener_start_____closure, S.RemoteListener_start___closure0, S.RemoteListener__serializeGroup_closure, S.RemoteListener__serializeTest_closure, S.RemoteListener__runLiveTest_closure, S.RemoteListener__runLiveTest_closure0, S.RemoteListener__runLiveTest_closure1, S.RemoteListener__runLiveTest_closure2, S.RemoteListener__runLiveTest_closure3, S.RemoteListener__runLiveTest__closure, V.errorsDontStopTest_closure, V.errorsDontStopTest_closure0, B.closure0, O.Engine_success_closure, O.Engine_closure, O.Engine_closure0, O.Engine_run_closure, O.Engine_run__closure, O.Engine_run___closure, O.Engine_run____closure, O.Engine_run_closure0, O.Engine__runLiveTest_closure, O.Engine__runLiveTest_closure0, O.Engine__runLiveTest_closure1, O.Engine__runSkippedTest_closure, O.Engine__runSkippedTest_closure0, O.Engine__runSkippedTest_closure1, B.LiveSuiteController_closure, B.LiveSuiteController_closure0, B.LiveSuiteController_reportLiveTest_closure, B.LiveSuiteController_close_closure, R.ExpandedReporter__onTestStarted_closure, R.ExpandedReporter__onTestStarted_closure0, R.ExpandedReporter__onTestStarted_closure1, Y.RunnerSuiteController__close_closure, E.JSStackTraceMapper__deserializePackageConfigMap_closure, R._declarer_closure, R._declarer__closure, G.main_closure0, G.main__closure, R.main_closure]);
+ _inherit(P.ListBase, P._ListBase_Object_ListMixin);
+ _inherit(H.UnmodifiableListBase, P.ListBase);
+ _inheritMany(H.UnmodifiableListBase, [H.CodeUnits, P.UnmodifiableListView]);
+ _inheritMany(H.EfficientLengthIterable, [H.ListIterable, H.LinkedHashMapKeyIterable, P._HashMapKeyIterable, P.Set]);
+ _inheritMany(H.ListIterable, [H.SubListIterable, H.MappedListIterable, H.ReversedListIterable, P.ListQueue, P._JsonMapKeyIterable]);
+ _inherit(H.EfficientLengthMappedIterable, H.MappedIterable);
+ _inheritMany(P.Iterator, [H.MappedIterator, H.WhereIterator, H.SkipWhileIterator]);
+ _inherit(H.ConstantStringMap, H.ConstantMap);
+ _inherit(H.Instantiation1, H.Instantiation);
+ _inheritMany(P.Error, [H.NullError, H.JsNoSuchMethodError, H.UnknownJsTypeError, H.TypeErrorImplementation, H.RuntimeError, P.AssertionError, H._Error, P.NullThrownError, P.ArgumentError, P.UnsupportedError, P.UnimplementedError, P.StateError, P.ConcurrentModificationError, P.CyclicInitializationError]);
+ _inheritMany(H.TearOffClosure, [H.StaticClosure, H.BoundClosure]);
+ _inherit(H._AssertionError, P.AssertionError);
+ _inheritMany(P.IterableBase, [H._AllMatchesIterable, O.EmptyUnmodifiableSet]);
+ _inheritMany(H.NativeTypedData, [H.NativeByteData, H.NativeTypedArray]);
+ _inheritMany(H.NativeTypedArray, [H._NativeTypedArrayOfDouble_NativeTypedArray_ListMixin, H._NativeTypedArrayOfInt_NativeTypedArray_ListMixin]);
+ _inherit(H._NativeTypedArrayOfDouble_NativeTypedArray_ListMixin_FixedLengthListMixin, H._NativeTypedArrayOfDouble_NativeTypedArray_ListMixin);
+ _inherit(H.NativeTypedArrayOfDouble, H._NativeTypedArrayOfDouble_NativeTypedArray_ListMixin_FixedLengthListMixin);
+ _inherit(H._NativeTypedArrayOfInt_NativeTypedArray_ListMixin_FixedLengthListMixin, H._NativeTypedArrayOfInt_NativeTypedArray_ListMixin);
+ _inherit(H.NativeTypedArrayOfInt, H._NativeTypedArrayOfInt_NativeTypedArray_ListMixin_FixedLengthListMixin);
+ _inheritMany(H.NativeTypedArrayOfDouble, [H.NativeFloat32List, H.NativeFloat64List]);
+ _inheritMany(H.NativeTypedArrayOfInt, [H.NativeInt16List, H.NativeInt32List, H.NativeInt8List, H.NativeUint16List, H.NativeUint32List, H.NativeUint8ClampedList, H.NativeUint8List]);
+ _inheritMany(H._Error, [H._CastError, H._TypeError]);
+ _inheritMany(P.Stream, [P._StreamImpl, P._EmptyStream, W._EventStream, Y._CompleterStream, T.SubscriptionStream]);
+ _inheritMany(P._StreamImpl, [P._ControllerStream, P._GeneratedStreamImpl]);
+ _inherit(P._BroadcastStream, P._ControllerStream);
+ _inherit(P._ControllerSubscription, P._BufferingStreamSubscription);
+ _inherit(P._BroadcastSubscription, P._ControllerSubscription);
+ _inheritMany(P._BroadcastStreamController, [P._SyncBroadcastStreamController, P._AsyncBroadcastStreamController]);
+ _inheritMany(P._Completer, [P._AsyncCompleter, P._SyncCompleter]);
+ _inheritMany(P._StreamController, [P._AsyncStreamController, P._SyncStreamController]);
+ _inherit(P._StreamControllerAddStreamState, P._AddStreamState);
+ _inheritMany(P._PendingEvents, [P._IterablePendingEvents, P._StreamImplEvents]);
+ _inheritMany(P._DelayedEvent, [P._DelayedData, P._DelayedError]);
+ _inheritMany(P._Zone, [P._CustomZone, P._RootZone]);
+ _inherit(P._IdentityHashMap, P._HashMap);
+ _inherit(P._LinkedHashSet, P._SetBase);
+ _inherit(P._UnmodifiableMapView_MapView__UnmodifiableMapMixin, P.MapView);
+ _inherit(P.UnmodifiableMapView, P._UnmodifiableMapView_MapView__UnmodifiableMapMixin);
+ _inherit(P.SetBase, P._SetBase_Object_SetMixin);
+ _inheritMany(P.Codec, [P.Encoding, P.Base64Codec, P._FusedCodec, P.JsonCodec]);
+ _inheritMany(P.Encoding, [P.AsciiCodec, P.Utf8Codec]);
+ _inherit(P.Converter, P.StreamTransformerBase);
+ _inheritMany(P.Converter, [P._UnicodeSubsetEncoder, P.Base64Encoder, P.JsonDecoder, P.Utf8Encoder, P.Utf8Decoder]);
+ _inherit(P.AsciiEncoder, P._UnicodeSubsetEncoder);
+ _inheritMany(P.num, [P.double, P.int]);
+ _inheritMany(P.ArgumentError, [P.RangeError, P.IndexError]);
+ _inherit(P._DataUri, P._Uri);
+ _inheritMany(W.Event, [W.ApplicationCacheErrorEvent, W.ErrorEvent, W.MediaKeyMessageEvent, W.MessageEvent, W.PresentationConnectionCloseEvent, W.SpeechRecognitionError]);
+ _inherit(W.File, W.Blob);
+ _inherit(W.MessagePort, W.EventTarget);
+ _inherit(W._EventStreamSubscription, P.StreamSubscription);
+ _inherit(P._StructuredCloneDart2Js, P._StructuredClone);
+ _inherit(P._AcceptStructuredCloneDart2Js, P._AcceptStructuredClone);
+ _inherit(T._CancelOnErrorSubscriptionWrapper, Y.DelegatingStreamSubscription);
+ _inherit(S.Validator, B.RecursiveVisitor);
+ _inherit(Q.QueueList, Q._QueueList_Object_ListMixin);
+ _inherit(M._UnionSet_SetBase_UnmodifiableSetMixin, P.SetBase);
+ _inherit(M.UnionSet, M._UnionSet_SetBase_UnmodifiableSetMixin);
+ _inherit(M.DelegatingIterable, M._DelegatingIterableBase);
+ _inherit(M.DelegatingSet, M.DelegatingIterable);
+ _inherit(L._UnmodifiableSetView_DelegatingSet_UnmodifiableSetMixin, M.DelegatingSet);
+ _inherit(L.UnmodifiableSetView, L._UnmodifiableSetView_DelegatingSet_UnmodifiableSetMixin);
+ _inheritMany(G.Matcher, [Y._IsTrue, M.TypeMatcher, D._DeepMatcher]);
+ _inherit(E.FeatureMatcher, M.TypeMatcher);
+ _inheritMany(E.FeatureMatcher, [Y._Predicate, D._StringEqualsMatcher]);
+ _inherit(B.InternalStyle, O.Style);
+ _inheritMany(B.InternalStyle, [E.PosixStyle, F.UrlStyle, L.WindowsStyle]);
+ _inheritMany(T.Mapping, [T.MultiSectionMapping, T.MappingBundle, T.SingleMapping]);
+ _inheritMany(Y.SourceSpanMixin, [V.SourceSpanBase, Y._FileSpan]);
+ _inheritMany(V.SourceSpanBase, [G.SourceMapSpan, X.SourceSpanWithContext]);
+ _inherit(Y.FileLocation, D.SourceLocationMixin);
+ _inherit(G.SourceSpanFormatException, G.SourceSpanException);
+ _inheritMany(R.StreamChannelMixin, [K.GuaranteeChannel, D._MultiChannel, D.VirtualChannel, R._StreamChannel]);
+ _inherit(E.StringScannerException, G.SourceSpanFormatException);
+ _inherit(S.SpanScanner, X.StringScanner);
+ _inherit(U.LocalTest, V.Test);
+ _inherit(V._LiveTest, Z.LiveTest);
+ _inherit(O._IterableSet_SetMixin_UnmodifiableSetMixin, P.SetMixin);
+ _inherit(O.IterableSet, O._IterableSet_SetMixin_UnmodifiableSetMixin);
+ _inherit(B._LiveSuite, E.LiveSuite);
+ _inherit(Y.RunnerSuite, U.Suite);
+ _inherit(E.JSStackTraceMapper, E.StackTraceMapper);
+ _mixin(H.UnmodifiableListBase, H.UnmodifiableListMixin);
+ _mixin(H._NativeTypedArrayOfDouble_NativeTypedArray_ListMixin, P.ListMixin);
+ _mixin(H._NativeTypedArrayOfDouble_NativeTypedArray_ListMixin_FixedLengthListMixin, H.FixedLengthListMixin);
+ _mixin(H._NativeTypedArrayOfInt_NativeTypedArray_ListMixin, P.ListMixin);
+ _mixin(H._NativeTypedArrayOfInt_NativeTypedArray_ListMixin_FixedLengthListMixin, H.FixedLengthListMixin);
+ _mixin(P._AsyncStreamController, P._AsyncStreamControllerDispatch);
+ _mixin(P._SyncStreamController, P._SyncStreamControllerDispatch);
+ _mixin(P._ListBase_Object_ListMixin, P.ListMixin);
+ _mixin(P._SetBase_Object_SetMixin, P.SetMixin);
+ _mixin(P._UnmodifiableMapView_MapView__UnmodifiableMapMixin, P._UnmodifiableMapMixin);
+ _mixin(Q._QueueList_Object_ListMixin, P.ListMixin);
+ _mixin(M._UnionSet_SetBase_UnmodifiableSetMixin, L.UnmodifiableSetMixin);
+ _mixin(L._UnmodifiableSetView_DelegatingSet_UnmodifiableSetMixin, L.UnmodifiableSetMixin);
+ _mixin(O._IterableSet_SetMixin_UnmodifiableSetMixin, L.UnmodifiableSetMixin);
+ })();
+ var init = {typeUniverse: {eC: new Map(), tR: {}, eT: {}, tPV: {}, sEA: []}, mangledGlobalNames: {int: "int", double: "double", num: "num", String: "String", bool: "bool", Null: "Null", List: "List"}, mangledNames: {}, getTypeFromName: getGlobalFromName, metadata: [], types: ["Null()", "~()", "Future<Null>()", "Null(@)", "bool(String)", "Null(@,StackTrace)", "Null(@,@)", "String(String)", "Trace()", "bool(@)", "Frame(String)", "~(Object)", "~(Object[StackTrace])", "Future<~>()", "Future<@>()", "~(@)", "Chain()", "Frame()", "@(@)", "Null(PlatformSelector,Metadata)", "~(~())", "bool(Frame)", "GroupEntry(GroupEntry)", "Null(State)", "String(Match)", "String(int)", "bool(Object)", "Null(Message)", "Null(Zone,ZoneDelegate,Zone,Object,StackTrace)", "Null(MessageEvent)", "Null(String)", "Future<bool>()", "AsyncError(Zone,ZoneDelegate,Zone,Object,StackTrace)", "0^(1^)(Zone,ZoneDelegate,Zone,0^(1^))<Object,Object>", "@()", "0^()(Zone,ZoneDelegate,Zone,0^())<Object>", "int()", "~(Zone,ZoneDelegate,Zone,String)", "String(Frame)", "int(Frame)", "String(@)", "~(Uint8List,String,int)", "Trace(String)", "Null(bool)", "Metadata(Metadata,Metadata)", "Trace(Trace)", "Frame(Frame)", "~([Object])", "Null(List<@>)", "bool()", "Future<List<@>>()", "Uri(@,@)", "bool(Trace)", "List<Frame>(Trace)", "int(Trace)", "String(@,int,Set<@>,bool)", "String(Trace)", "bool(Pattern[int])", "List<String>(Object,Object,String,int)", "Frame(@,@)", "@(@,@)", "@(Event)", "Uint8List(@,@)", "0^(1^,2^)(Zone,ZoneDelegate,Zone,Function)<Object,Object,Object>", "Uint8List(int)", "int(int,int)", "~(@[StackTrace])", "~(String[@])", "~(String,int)", "bool(MessageEvent)", "~(Object,StackTrace)", "String(String{color:@})", "bool(GroupEntry)", "Future<@>(@)", "String()", "_Future<@>(@)", "0^(0^,0^)<num>", "Metadata()", "Metadata(Metadata,BooleanSelector)", "MapEntry<BooleanSelector,Metadata>(@,@)", "Null(@[StackTrace])", "bool/()", "MapEntry<String,Map<String,@>>(BooleanSelector,Metadata)", "bool(OperatingSystem)", "BooleanSelector()", "bool(Runtime)", "String(@,Matcher,String,Map<@,@>,bool)", "Null(Zone,ZoneDelegate,Zone,String)", "Map<@,@>(GroupEntry)", "Null(int,@)", "Null(AsyncError)", "Null(~())", "~(~)", "Map<String,int>()", "@(String)", "bool(LiveTest)", "~(Message)", "Null(RunnerSuite)", "~(LiveTest)", "~(bool)", "~(State)", "~(AsyncError)", "MapEntry<String,Uri>(String,String)", "@()()", "@(@,String)", "~(Zone,ZoneDelegate,Zone,@,StackTrace)", "0^(Zone,ZoneDelegate,Zone,0^())<Object>", "0^(Zone,ZoneDelegate,Zone,0^(1^),1^)<Object,Object>", "0^(Zone,ZoneDelegate,Zone,0^(1^,2^),1^,2^)<Object,Object,Object>", "0^(1^,2^)(Zone,ZoneDelegate,Zone,0^(1^,2^))<Object,Object,Object>", "~(Zone,ZoneDelegate,Zone,~())", "Timer(Zone,ZoneDelegate,Zone,Duration,~())", "Timer(Zone,ZoneDelegate,Zone,Duration,~(Timer))", "~(String)", "Zone(Zone,ZoneDelegate,Zone,ZoneSpecification,Map<@,@>)", "OperatingSystem()"], interceptorsByTag: null, leafTags: null};
+ H._Universe_addRules(init.typeUniverse, JSON.parse('{"JavaScriptFunction":"JavaScriptObject","PlainJavaScriptObject":"JavaScriptObject","UnknownJavaScriptObject":"JavaScriptObject","AbortPaymentEvent":"Event","ExtendableEvent":"Event","Window":"EventTarget","JSBool":{"bool":[]},"JSNull":{"Null":[]},"JavaScriptObject":{"JSObject":[],"Function":[]},"JSArray":{"List":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"JSUnmodifiableArray":{"JSArray":["1"],"List":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"ArrayIterator":{"Iterator":["1"]},"JSNumber":{"double":[],"num":[]},"JSInt":{"int":[],"double":[],"num":[]},"JSDouble":{"double":[],"num":[]},"JSString":{"String":[],"Pattern":[]},"_CastIterableBase":{"Iterable":["2"]},"CastIterator":{"Iterator":["2"]},"CastIterable":{"_CastIterableBase":["1","2"],"Iterable":["2"],"Iterable.E":"2"},"_EfficientLengthCastIterable":{"CastIterable":["1","2"],"EfficientLengthIterable":["2"],"_CastIterableBase":["1","2"],"Iterable":["2"],"Iterable.E":"2"},"CastMap":{"MapMixin":["3","4"],"Map":["3","4"],"MapMixin.K":"3","MapMixin.V":"4"},"CodeUnits":{"UnmodifiableListMixin":["int"],"ListMixin":["int"],"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"],"ListMixin.E":"int","UnmodifiableListMixin.E":"int"},"EfficientLengthIterable":{"Iterable":["1"]},"ListIterable":{"EfficientLengthIterable":["1"],"Iterable":["1"]},"SubListIterable":{"ListIterable":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1","ListIterable.E":"1"},"ListIterator":{"Iterator":["1"]},"MappedIterable":{"Iterable":["2"],"Iterable.E":"2"},"EfficientLengthMappedIterable":{"MappedIterable":["1","2"],"EfficientLengthIterable":["2"],"Iterable":["2"],"Iterable.E":"2"},"MappedIterator":{"Iterator":["2"]},"MappedListIterable":{"ListIterable":["2"],"EfficientLengthIterable":["2"],"Iterable":["2"],"Iterable.E":"2","ListIterable.E":"2"},"WhereIterable":{"Iterable":["1"],"Iterable.E":"1"},"WhereIterator":{"Iterator":["1"]},"ExpandIterable":{"Iterable":["2"],"Iterable.E":"2"},"ExpandIterator":{"Iterator":["2"]},"SkipWhileIterable":{"Iterable":["1"],"Iterable.E":"1"},"SkipWhileIterator":{"Iterator":["1"]},"EmptyIterator":{"Iterator":["1"]},"UnmodifiableListBase":{"UnmodifiableListMixin":["1"],"ListMixin":["1"],"List":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"ReversedListIterable":{"ListIterable":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1","ListIterable.E":"1"},"ConstantMap":{"Map":["1","2"]},"ConstantStringMap":{"ConstantMap":["1","2"],"Map":["1","2"]},"_ConstantMapKeyIterable":{"Iterable":["1"],"Iterable.E":"1"},"Instantiation":{"Closure":[],"Function":[]},"Instantiation1":{"Closure":[],"Function":[]},"NullError":{"NoSuchMethodError":[],"Error":[]},"JsNoSuchMethodError":{"NoSuchMethodError":[],"Error":[]},"UnknownJsTypeError":{"Error":[]},"_StackTrace":{"StackTrace":[]},"Closure":{"Function":[]},"TearOffClosure":{"Closure":[],"Function":[]},"StaticClosure":{"Closure":[],"Function":[]},"BoundClosure":{"Closure":[],"Function":[]},"TypeErrorImplementation":{"Error":[]},"RuntimeError":{"Error":[]},"_AssertionError":{"Error":[]},"JsLinkedHashMap":{"LinkedHashMap":["1","2"],"MapMixin":["1","2"],"Map":["1","2"],"MapMixin.K":"1","MapMixin.V":"2"},"LinkedHashMapKeyIterable":{"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1"},"LinkedHashMapKeyIterator":{"Iterator":["1"]},"JSSyntaxRegExp":{"RegExp":[],"Pattern":[]},"_MatchImplementation":{"RegExpMatch":[],"Match":[]},"_AllMatchesIterable":{"Iterable":["RegExpMatch"],"Iterable.E":"RegExpMatch"},"_AllMatchesIterator":{"Iterator":["RegExpMatch"]},"StringMatch":{"Match":[]},"_StringAllMatchesIterable":{"Iterable":["Match"],"Iterable.E":"Match"},"_StringAllMatchesIterator":{"Iterator":["Match"]},"NativeByteBuffer":{"ByteBuffer":[]},"NativeByteData":{"NativeTypedData":[]},"NativeTypedArray":{"JavaScriptIndexingBehavior":["@"],"NativeTypedData":[]},"NativeTypedArrayOfDouble":{"ListMixin":["double"],"JavaScriptIndexingBehavior":["@"],"List":["double"],"NativeTypedData":[],"EfficientLengthIterable":["double"],"FixedLengthListMixin":["double"],"Iterable":["double"]},"NativeTypedArrayOfInt":{"ListMixin":["int"],"List":["int"],"JavaScriptIndexingBehavior":["@"],"NativeTypedData":[],"EfficientLengthIterable":["int"],"FixedLengthListMixin":["int"],"Iterable":["int"]},"NativeFloat32List":{"ListMixin":["double"],"JavaScriptIndexingBehavior":["@"],"List":["double"],"NativeTypedData":[],"EfficientLengthIterable":["double"],"FixedLengthListMixin":["double"],"Iterable":["double"],"ListMixin.E":"double"},"NativeFloat64List":{"ListMixin":["double"],"JavaScriptIndexingBehavior":["@"],"List":["double"],"NativeTypedData":[],"EfficientLengthIterable":["double"],"FixedLengthListMixin":["double"],"Iterable":["double"],"ListMixin.E":"double"},"NativeInt16List":{"ListMixin":["int"],"List":["int"],"JavaScriptIndexingBehavior":["@"],"NativeTypedData":[],"EfficientLengthIterable":["int"],"FixedLengthListMixin":["int"],"Iterable":["int"],"ListMixin.E":"int"},"NativeInt32List":{"ListMixin":["int"],"List":["int"],"JavaScriptIndexingBehavior":["@"],"NativeTypedData":[],"EfficientLengthIterable":["int"],"FixedLengthListMixin":["int"],"Iterable":["int"],"ListMixin.E":"int"},"NativeInt8List":{"ListMixin":["int"],"List":["int"],"JavaScriptIndexingBehavior":["@"],"NativeTypedData":[],"EfficientLengthIterable":["int"],"FixedLengthListMixin":["int"],"Iterable":["int"],"ListMixin.E":"int"},"NativeUint16List":{"ListMixin":["int"],"List":["int"],"JavaScriptIndexingBehavior":["@"],"NativeTypedData":[],"EfficientLengthIterable":["int"],"FixedLengthListMixin":["int"],"Iterable":["int"],"ListMixin.E":"int"},"NativeUint32List":{"Uint32List":[],"ListMixin":["int"],"List":["int"],"JavaScriptIndexingBehavior":["@"],"NativeTypedData":[],"EfficientLengthIterable":["int"],"FixedLengthListMixin":["int"],"Iterable":["int"],"ListMixin.E":"int"},"NativeUint8ClampedList":{"ListMixin":["int"],"List":["int"],"JavaScriptIndexingBehavior":["@"],"NativeTypedData":[],"EfficientLengthIterable":["int"],"FixedLengthListMixin":["int"],"Iterable":["int"],"ListMixin.E":"int"},"NativeUint8List":{"Uint8List":[],"ListMixin":["int"],"List":["int"],"JavaScriptIndexingBehavior":["@"],"NativeTypedData":[],"EfficientLengthIterable":["int"],"FixedLengthListMixin":["int"],"Iterable":["int"],"ListMixin.E":"int"},"_Type":{"Type":[]},"_Error":{"Error":[]},"_CastError":{"Error":[]},"_TypeError":{"Error":[]},"_TimerImpl":{"Timer":[]},"_AsyncAwaitCompleter":{"Completer":["1"]},"_BroadcastStream":{"_ControllerStream":["1"],"_StreamImpl":["1"],"Stream":["1"],"Stream.T":"1"},"_BroadcastSubscription":{"_ControllerSubscription":["1"],"_BufferingStreamSubscription":["1"],"_EventDispatch":["1"],"StreamSubscription":["1"],"_BufferingStreamSubscription.T":"1"},"_BroadcastStreamController":{"StreamController":["1"],"StreamSink":["1"],"EventSink":["1"],"_EventDispatch":["1"],"_StreamControllerLifecycle":["1"],"StreamConsumer":["1"],"Sink":["1"]},"_SyncBroadcastStreamController":{"_BroadcastStreamController":["1"],"StreamController":["1"],"StreamSink":["1"],"EventSink":["1"],"_EventDispatch":["1"],"_StreamControllerLifecycle":["1"],"StreamConsumer":["1"],"Sink":["1"]},"_AsyncBroadcastStreamController":{"_BroadcastStreamController":["1"],"StreamController":["1"],"StreamSink":["1"],"EventSink":["1"],"_EventDispatch":["1"],"_StreamControllerLifecycle":["1"],"StreamConsumer":["1"],"Sink":["1"]},"TimeoutException":{"Exception":[]},"_Completer":{"Completer":["1"]},"_AsyncCompleter":{"_Completer":["1"],"Completer":["1"]},"_SyncCompleter":{"_Completer":["1"],"Completer":["1"]},"_Future":{"Future":["1"]},"StreamTransformerBase":{"StreamTransformer":["1","2"]},"_StreamController":{"StreamController":["1"],"StreamSink":["1"],"EventSink":["1"],"_EventDispatch":["1"],"_StreamControllerLifecycle":["1"],"StreamConsumer":["1"],"Sink":["1"]},"_AsyncStreamController":{"_AsyncStreamControllerDispatch":["1"],"_StreamController":["1"],"StreamController":["1"],"StreamSink":["1"],"EventSink":["1"],"_EventDispatch":["1"],"_StreamControllerLifecycle":["1"],"StreamConsumer":["1"],"Sink":["1"]},"_SyncStreamController":{"_SyncStreamControllerDispatch":["1"],"_StreamController":["1"],"StreamController":["1"],"StreamSink":["1"],"EventSink":["1"],"_EventDispatch":["1"],"_StreamControllerLifecycle":["1"],"StreamConsumer":["1"],"Sink":["1"]},"_ControllerStream":{"_StreamImpl":["1"],"Stream":["1"],"Stream.T":"1"},"_ControllerSubscription":{"_BufferingStreamSubscription":["1"],"_EventDispatch":["1"],"StreamSubscription":["1"],"_BufferingStreamSubscription.T":"1"},"_StreamSinkWrapper":{"StreamSink":["1"],"EventSink":["1"],"StreamConsumer":["1"],"Sink":["1"]},"_StreamControllerAddStreamState":{"_AddStreamState":["1"]},"_BufferingStreamSubscription":{"_EventDispatch":["1"],"StreamSubscription":["1"],"_BufferingStreamSubscription.T":"1"},"_StreamImpl":{"Stream":["1"]},"_GeneratedStreamImpl":{"_StreamImpl":["1"],"Stream":["1"],"Stream.T":"1"},"_IterablePendingEvents":{"_PendingEvents":["1"]},"_DelayedData":{"_DelayedEvent":["1"]},"_DelayedError":{"_DelayedEvent":["@"]},"_DelayedDone":{"_DelayedEvent":["@"]},"_StreamImplEvents":{"_PendingEvents":["1"]},"_DoneStreamSubscription":{"StreamSubscription":["1"]},"_EmptyStream":{"Stream":["1"],"Stream.T":"1"},"AsyncError":{"Error":[]},"_ZoneSpecification":{"ZoneSpecification":[]},"_ZoneDelegate":{"ZoneDelegate":[]},"_Zone":{"Zone":[]},"_CustomZone":{"_Zone":[],"Zone":[]},"_RootZone":{"_Zone":[],"Zone":[]},"_HashMap":{"MapMixin":["1","2"],"Map":["1","2"],"MapMixin.K":"1","MapMixin.V":"2"},"_IdentityHashMap":{"_HashMap":["1","2"],"MapMixin":["1","2"],"Map":["1","2"],"MapMixin.K":"1","MapMixin.V":"2"},"_HashMapKeyIterable":{"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1"},"_HashMapKeyIterator":{"Iterator":["1"]},"_LinkedHashSet":{"_SetBase":["1"],"LinkedHashSet":["1"],"Set":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"_LinkedHashSetIterator":{"Iterator":["1"]},"UnmodifiableListView":{"UnmodifiableListMixin":["1"],"ListMixin":["1"],"List":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"ListMixin.E":"1","UnmodifiableListMixin.E":"1"},"IterableBase":{"Iterable":["1"]},"ListBase":{"ListMixin":["1"],"List":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"MapBase":{"MapMixin":["1","2"],"Map":["1","2"]},"MapMixin":{"Map":["1","2"]},"MapView":{"Map":["1","2"]},"UnmodifiableMapView":{"_UnmodifiableMapView_MapView__UnmodifiableMapMixin":["1","2"],"MapView":["1","2"],"_UnmodifiableMapMixin":["1","2"],"Map":["1","2"]},"ListQueue":{"ListIterable":["1"],"Queue":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1","ListIterable.E":"1"},"_ListQueueIterator":{"Iterator":["1"]},"SetMixin":{"Set":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"SetBase":{"SetMixin":["1"],"Set":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"_SetBase":{"Set":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"_JsonMap":{"MapMixin":["String","@"],"Map":["String","@"],"MapMixin.K":"String","MapMixin.V":"@"},"_JsonMapKeyIterable":{"ListIterable":["String"],"EfficientLengthIterable":["String"],"Iterable":["String"],"Iterable.E":"String","ListIterable.E":"String"},"AsciiCodec":{"Codec":["String","List<int>"],"Codec.S":"String"},"_UnicodeSubsetEncoder":{"Converter":["String","List<int>"],"StreamTransformer":["String","List<int>"]},"AsciiEncoder":{"Converter":["String","List<int>"],"StreamTransformer":["String","List<int>"]},"Base64Codec":{"Codec":["List<int>","String"],"Codec.S":"List<int>"},"Base64Encoder":{"Converter":["List<int>","String"],"StreamTransformer":["List<int>","String"]},"_FusedCodec":{"Codec":["1","3"],"Codec.S":"1"},"Converter":{"StreamTransformer":["1","2"]},"Encoding":{"Codec":["String","List<int>"]},"JsonCodec":{"Codec":["Object","String"],"Codec.S":"Object"},"JsonDecoder":{"Converter":["String","Object"],"StreamTransformer":["String","Object"]},"Utf8Codec":{"Codec":["String","List<int>"],"Codec.S":"String"},"Utf8Encoder":{"Converter":["String","List<int>"],"StreamTransformer":["String","List<int>"]},"Utf8Decoder":{"Converter":["List<int>","String"],"StreamTransformer":["List<int>","String"]},"double":{"num":[]},"AssertionError":{"Error":[]},"NullThrownError":{"Error":[]},"ArgumentError":{"Error":[]},"RangeError":{"Error":[]},"IndexError":{"Error":[]},"UnsupportedError":{"Error":[]},"UnimplementedError":{"Error":[]},"StateError":{"Error":[]},"ConcurrentModificationError":{"Error":[]},"OutOfMemoryError":{"Error":[]},"StackOverflowError":{"Error":[]},"CyclicInitializationError":{"Error":[]},"_Exception":{"Exception":[]},"FormatException":{"Exception":[]},"int":{"num":[]},"List":{"EfficientLengthIterable":["1"],"Iterable":["1"]},"RegExpMatch":{"Match":[]},"Set":{"EfficientLengthIterable":["1"],"Iterable":["1"]},"_StringStackTrace":{"StackTrace":[]},"String":{"Pattern":[]},"Runes":{"Iterable":["int"],"Iterable.E":"int"},"RuneIterator":{"Iterator":["int"]},"StringBuffer":{"StringSink":[]},"_Uri":{"Uri":[]},"_SimpleUri":{"Uri":[]},"_DataUri":{"Uri":[]},"ApplicationCacheErrorEvent":{"Event":[]},"ErrorEvent":{"Event":[]},"File":{"Blob":[]},"MediaKeyMessageEvent":{"Event":[]},"MessageEvent":{"Event":[]},"MessagePort":{"EventTarget":[]},"PresentationConnectionCloseEvent":{"Event":[]},"SpeechRecognitionError":{"Event":[]},"_EventStream":{"Stream":["1"],"Stream.T":"1"},"_EventStreamSubscription":{"StreamSubscription":["1"]},"Int8List":{"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"]},"Uint8List":{"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"]},"Uint8ClampedList":{"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"]},"Int16List":{"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"]},"Uint16List":{"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"]},"Int32List":{"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"]},"Uint32List":{"List":["int"],"EfficientLengthIterable":["int"],"Iterable":["int"]},"Float32List":{"List":["double"],"EfficientLengthIterable":["double"],"Iterable":["double"]},"Float64List":{"List":["double"],"EfficientLengthIterable":["double"],"Iterable":["double"]},"DelegatingSink":{"Sink":["1"]},"DelegatingStreamSubscription":{"StreamSubscription":["1"]},"FutureGroup":{"Sink":["Future<1>"]},"NullStreamSink":{"StreamSink":["1"],"EventSink":["1"],"StreamConsumer":["1"],"Sink":["1"]},"ErrorResult":{"Result":["Null"]},"ValueResult":{"Result":["1"]},"_CompleterStream":{"Stream":["1"],"Stream.T":"1"},"StreamGroup":{"Sink":["Stream<1>"]},"_NextRequest":{"_EventRequest":["1"]},"_RestRequest":{"_EventRequest":["1"]},"_CompleterSink":{"StreamSink":["1"],"EventSink":["1"],"StreamConsumer":["1"],"Sink":["1"]},"SubscriptionStream":{"Stream":["1"],"Stream.T":"1"},"_CancelOnErrorSubscriptionWrapper":{"DelegatingStreamSubscription":["1"],"StreamSubscription":["1"]},"All":{"BooleanSelector":[]},"VariableNode":{"Node":[]},"NotNode":{"Node":[]},"OrNode":{"Node":[]},"AndNode":{"Node":[]},"ConditionalNode":{"Node":[]},"Evaluator":{"Visitor":["bool"]},"BooleanSelectorImpl":{"BooleanSelector":[]},"IntersectionSelector":{"BooleanSelector":[]},"None":{"BooleanSelector":[]},"IdentifierToken":{"Token":[]},"Validator":{"Visitor":["@"]},"RecursiveVisitor":{"Visitor":["@"]},"EmptyUnmodifiableSet":{"Set":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"Iterable.E":"1"},"QueueList":{"ListMixin":["1"],"Queue":["1"],"List":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"],"ListMixin.E":"1"},"UnionSet":{"UnmodifiableSetMixin":["1"],"SetMixin":["1"],"Set":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"UnmodifiableSetView":{"_UnmodifiableSetView_DelegatingSet_UnmodifiableSetMixin":["1"],"DelegatingSet":["1"],"UnmodifiableSetMixin":["1"],"DelegatingIterable":["1"],"Set":["1"],"_DelegatingIterableBase":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"_DelegatingIterableBase":{"Iterable":["1"]},"DelegatingIterable":{"_DelegatingIterableBase":["1"],"Iterable":["1"]},"DelegatingSet":{"DelegatingIterable":["1"],"Set":["1"],"_DelegatingIterableBase":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"_IsTrue":{"Matcher":[]},"_Predicate":{"FeatureMatcher":["1"],"TypeMatcher":["1"],"Matcher":[],"TypeMatcher.T":"1","FeatureMatcher.T":"1"},"StringDescription":{"Description":[]},"_StringEqualsMatcher":{"FeatureMatcher":["String"],"TypeMatcher":["String"],"Matcher":[],"TypeMatcher.T":"String","FeatureMatcher.T":"String"},"_DeepMatcher":{"Matcher":[]},"FeatureMatcher":{"TypeMatcher":["1"],"Matcher":[]},"TypeMatcher":{"Matcher":[],"TypeMatcher.T":"1"},"PackageConfigResolver":{"SyncPackageResolver":[]},"PackageRootResolver":{"SyncPackageResolver":[]},"PathException":{"Exception":[]},"PosixStyle":{"InternalStyle":[]},"UrlStyle":{"InternalStyle":[]},"WindowsStyle":{"InternalStyle":[]},"MultiSectionMapping":{"Mapping":[]},"MappingBundle":{"Mapping":[]},"SingleMapping":{"Mapping":[]},"_MappingTokenizer":{"Iterator":["String"]},"SourceMapSpan":{"SourceSpan":[]},"FileLocation":{"SourceLocation":[]},"_FileSpan":{"FileSpan":[],"SourceSpanWithContext":[],"SourceSpan":[]},"SourceLocationMixin":{"SourceLocation":[]},"SourceSpanBase":{"SourceSpan":[]},"SourceSpanException":{"Exception":[]},"SourceSpanFormatException":{"FormatException":[],"Exception":[]},"SourceSpanMixin":{"SourceSpan":[]},"SourceSpanWithContext":{"SourceSpan":[]},"Chain":{"StackTrace":[]},"LazyChain":{"Chain":[],"StackTrace":[]},"LazyTrace":{"Trace":[],"StackTrace":[]},"Trace":{"StackTrace":[]},"UnparsedFrame":{"Frame":[]},"GuaranteeChannel":{"StreamChannelMixin":["1"],"StreamChannel":["1"]},"_GuaranteeSink":{"StreamSink":["1"],"EventSink":["1"],"StreamConsumer":["1"],"Sink":["1"]},"_MultiChannel":{"StreamChannelMixin":["1"],"MultiChannel":["1"],"StreamChannel":["1"]},"VirtualChannel":{"StreamChannelMixin":["1"],"MultiChannel":["1"],"StreamChannel":["1"]},"_StreamChannel":{"StreamChannelMixin":["1"],"StreamChannel":["1"]},"StreamChannelMixin":{"StreamChannel":["1"]},"StringScannerException":{"FormatException":[],"Exception":[]},"_SpanScannerState":{"LineScannerState":[]},"ClosedException":{"Exception":[]},"Group":{"GroupEntry":[]},"LocalTest":{"Test":[],"GroupEntry":[]},"_LiveTest":{"LiveTest":[]},"Test":{"GroupEntry":[]},"IterableSet":{"SetMixin":["1"],"UnmodifiableSetMixin":["1"],"Set":["1"],"EfficientLengthIterable":["1"],"Iterable":["1"]},"_LiveSuite":{"LiveSuite":[]},"RunnerSuite":{"Suite":[]},"PrintSink":{"StringSink":[]},"JSStackTraceMapper":{"StackTraceMapper":[]}}'));
+ H._Universe_addErasedTypes(init.typeUniverse, JSON.parse('{"UnmodifiableListBase":1,"StreamTransformerBase":2,"IterableBase":1,"ListBase":1,"MapBase":2,"SetBase":1,"_ListBase_Object_ListMixin":1,"_SetBase_Object_SetMixin":1,"_QueueList_Object_ListMixin":1,"_UnionSet_SetBase_UnmodifiableSetMixin":1,"_IterableSet_SetMixin_UnmodifiableSetMixin":1}'));
+ var type$ = (function rtii() {
+ var findType = H.findType;
+ return {
+ A_Function_2_B_and_C_Function_A_and_B_and_C_4_Zone_and_ZoneDelegate_and_Zone_and_A_Function_2_B_and_C: findType("0^(1^,2^)(Zone,ZoneDelegate,Zone,0^(1^,2^))<Object,Object,Object>"),
+ A_Function_A_4_Zone_and_ZoneDelegate_and_Zone_and_A_Function: findType("0^(Zone,ZoneDelegate,Zone,0^())<Object>"),
+ A_Function_A_and_B_5_Zone_and_ZoneDelegate_and_Zone_and_A_Function_B_and_B: findType("0^(Zone,ZoneDelegate,Zone,0^(1^),1^)<Object,Object>"),
+ A_Function_A_and_B_and_C_6_Zone_and_ZoneDelegate_and_Zone_and_A_Function_2_B_and_C_and_B_and_C: findType("0^(Zone,ZoneDelegate,Zone,0^(1^,2^),1^,2^)<Object,Object,Object>"),
+ A_Function_B_Function_A_and_B_4_Zone_and_ZoneDelegate_and_Zone_and_A_Function_B: findType("0^(1^)(Zone,ZoneDelegate,Zone,0^(1^))<Object,Object>"),
+ A_Function_Function_A_4_Zone_and_ZoneDelegate_and_Zone_and_A_Function: findType("0^()(Zone,ZoneDelegate,Zone,0^())<Object>"),
+ AsyncError: findType("AsyncError"),
+ AsyncMemoizer_dynamic: findType("AsyncMemoizer<@>"),
+ Blob: findType("Blob"),
+ BooleanSelector: findType("BooleanSelector"),
+ Chain: findType("Chain"),
+ CodeUnits: findType("CodeUnits"),
+ Completer_PoolResource: findType("Completer<PoolResource>"),
+ Declarer: findType("Declarer"),
+ Duration: findType("Duration"),
+ EfficientLengthIterable_dynamic: findType("EfficientLengthIterable<@>"),
+ Error: findType("Error"),
+ Event: findType("Event"),
+ Exception: findType("Exception"),
+ Expando__Node: findType("Expando<_Node>"),
+ File: findType("File"),
+ FileSpan: findType("FileSpan"),
+ FormatException: findType("FormatException"),
+ Frame: findType("Frame"),
+ Frame_Function_Frame: findType("Frame(Frame)"),
+ Frame_Function_String: findType("Frame(String)"),
+ Function: findType("Function"),
+ FutureGroup_dynamic: findType("FutureGroup<@>"),
+ FutureOr_void_Function: findType("~/()"),
+ Future_Null: findType("Future<Null>"),
+ Future_RunnerSuite: findType("Future<RunnerSuite>"),
+ Future_bool: findType("Future<bool>"),
+ Future_dynamic: findType("Future<@>"),
+ Future_void: findType("Future<~>"),
+ Group: findType("Group"),
+ GroupEntry: findType("GroupEntry"),
+ GroupEntry_Function_GroupEntry: findType("GroupEntry(GroupEntry)"),
+ IdentifierToken: findType("IdentifierToken"),
+ Invoker: findType("Invoker"),
+ IterableSet_LiveTest: findType("IterableSet<LiveTest>"),
+ Iterable_Group: findType("Iterable<Group>"),
+ Iterable_String: findType("Iterable<String>"),
+ Iterable_dynamic: findType("Iterable<@>"),
+ Iterator_Match: findType("Iterator<Match>"),
+ JSArray_AsyncError: findType("JSArray<AsyncError>"),
+ JSArray_Declarer: findType("JSArray<Declarer>"),
+ JSArray_Frame: findType("JSArray<Frame>"),
+ JSArray_Future_dynamic: findType("JSArray<Future<@>>"),
+ JSArray_Group: findType("JSArray<Group>"),
+ JSArray_GroupEntry: findType("JSArray<GroupEntry>"),
+ JSArray_Mapping: findType("JSArray<Mapping>"),
+ JSArray_Set_LiveTest: findType("JSArray<Set<LiveTest>>"),
+ JSArray_SourceFile: findType("JSArray<SourceFile>"),
+ JSArray_String: findType("JSArray<String>"),
+ JSArray_TargetEntry: findType("JSArray<TargetEntry>"),
+ JSArray_TargetLineEntry: findType("JSArray<TargetLineEntry>"),
+ JSArray_Trace: findType("JSArray<Trace>"),
+ JSArray_Zone: findType("JSArray<Zone>"),
+ JSArray_dynamic: findType("JSArray<@>"),
+ JSArray_int: findType("JSArray<int>"),
+ JSArray_of_dynamic_Function: findType("JSArray<@()>"),
+ JSObject: findType("JSObject"),
+ JavaScriptFunction: findType("JavaScriptFunction"),
+ JavaScriptIndexingBehavior_dynamic: findType("JavaScriptIndexingBehavior<@>"),
+ JsLinkedHashMap_of_Stream_LiveTest_and_StreamSubscription_LiveTest: findType("JsLinkedHashMap<Stream<LiveTest>,StreamSubscription<LiveTest>>"),
+ List_Group: findType("List<Group>"),
+ List_Object: findType("List<Object>"),
+ List_String: findType("List<String>"),
+ List_String_Function_dynamic_dynamic_String_int: findType("List<String>(@,@,String,int)"),
+ List_dynamic: findType("List<@>"),
+ List_int: findType("List<int>"),
+ LiveSuite: findType("LiveSuite"),
+ LiveTest: findType("LiveTest"),
+ MapEntry_BooleanSelector_Metadata: findType("MapEntry<BooleanSelector,Metadata>"),
+ MapEntry_String_Uri: findType("MapEntry<String,Uri>"),
+ MapEntry_of_String_and_Map_String_dynamic: findType("MapEntry<String,Map<String,@>>"),
+ Map_BooleanSelector_Metadata: findType("Map<BooleanSelector,Metadata>"),
+ Map_PlatformSelector_Metadata: findType("Map<PlatformSelector,Metadata>"),
+ Map_String_SourceFile: findType("Map<String,SourceFile>"),
+ Map_String_dynamic: findType("Map<String,@>"),
+ Map_dynamic_dynamic: findType("Map<@,@>"),
+ MappedIterable_String_Frame: findType("MappedIterable<String,Frame>"),
+ MappedListIterable_Frame_Frame: findType("MappedListIterable<Frame,Frame>"),
+ MappedListIterable_String_String: findType("MappedListIterable<String,String>"),
+ MappedListIterable_String_Trace: findType("MappedListIterable<String,Trace>"),
+ MappedListIterable_String_dynamic: findType("MappedListIterable<String,@>"),
+ Message: findType("Message"),
+ MessageEvent: findType("MessageEvent"),
+ MessagePort: findType("MessagePort"),
+ Metadata: findType("Metadata"),
+ NativeByteBuffer: findType("NativeByteBuffer"),
+ NativeTypedData: findType("NativeTypedData"),
+ NativeUint8List: findType("NativeUint8List"),
+ NoSuchMethodError: findType("NoSuchMethodError"),
+ Null: findType("Null"),
+ Null_Function: findType("Null()"),
+ Object: findType("Object"),
+ OperatingSystem: findType("OperatingSystem"),
+ Pattern: findType("Pattern"),
+ PlatformSelector: findType("PlatformSelector"),
+ RegExp: findType("RegExp"),
+ Result_dynamic: findType("Result<@>"),
+ ReversedListIterable_Declarer: findType("ReversedListIterable<Declarer>"),
+ RunnerSuite: findType("RunnerSuite"),
+ Runtime: findType("Runtime"),
+ Set_LiveTest: findType("Set<LiveTest>"),
+ Set_String: findType("Set<String>"),
+ Set_dynamic: findType("Set<@>"),
+ SingleMapping: findType("SingleMapping"),
+ SourceLocation: findType("SourceLocation"),
+ SourceSpan: findType("SourceSpan"),
+ SourceSpanWithContext: findType("SourceSpanWithContext"),
+ StackTrace: findType("StackTrace"),
+ StackTraceFormatter: findType("StackTraceFormatter"),
+ StackZoneSpecification: findType("StackZoneSpecification"),
+ State: findType("State"),
+ StreamChannelCompleter_dynamic: findType("StreamChannelCompleter<@>"),
+ StreamChannel_dynamic: findType("StreamChannel<@>"),
+ StreamCompleter_dynamic: findType("StreamCompleter<@>"),
+ StreamGroup_LiveTest: findType("StreamGroup<LiveTest>"),
+ StreamQueue_dynamic: findType("StreamQueue<@>"),
+ StreamSinkCompleter_dynamic: findType("StreamSinkCompleter<@>"),
+ StreamSubscription_dynamic: findType("StreamSubscription<@>"),
+ String: findType("String"),
+ String_Function_Match: findType("String(Match)"),
+ String_Function_String: findType("String(String)"),
+ SuiteChannelManager: findType("SuiteChannelManager"),
+ Test: findType("Test"),
+ Timer: findType("Timer"),
+ Trace: findType("Trace"),
+ Trace_Function_String: findType("Trace(String)"),
+ Type: findType("Type"),
+ Uint8List: findType("Uint8List"),
+ UnionSet_LiveTest: findType("UnionSet<LiveTest>"),
+ UnknownJavaScriptObject: findType("UnknownJavaScriptObject"),
+ UnmodifiableListView_LiveTest: findType("UnmodifiableListView<LiveTest>"),
+ UnmodifiableMapView_BooleanSelector_Metadata: findType("UnmodifiableMapView<BooleanSelector,Metadata>"),
+ UnmodifiableMapView_PlatformSelector_Metadata: findType("UnmodifiableMapView<PlatformSelector,Metadata>"),
+ UnmodifiableMapView_String_Uri: findType("UnmodifiableMapView<String,Uri>"),
+ UnmodifiableSetView_LiveTest: findType("UnmodifiableSetView<LiveTest>"),
+ UnmodifiableSetView_String: findType("UnmodifiableSetView<String>"),
+ Uri: findType("Uri"),
+ WhereIterable_String: findType("WhereIterable<String>"),
+ Zone: findType("Zone"),
+ ZoneDelegate: findType("ZoneDelegate"),
+ ZoneSpecification: findType("ZoneSpecification"),
+ _AsyncBroadcastStreamController_LiveSuite: findType("_AsyncBroadcastStreamController<LiveSuite>"),
+ _AsyncBroadcastStreamController_RunnerSuite: findType("_AsyncBroadcastStreamController<RunnerSuite>"),
+ _AsyncBroadcastStreamController_bool: findType("_AsyncBroadcastStreamController<bool>"),
+ _AsyncCompleter_List_dynamic: findType("_AsyncCompleter<List<@>>"),
+ _AsyncCompleter_PoolResource: findType("_AsyncCompleter<PoolResource>"),
+ _AsyncCompleter_dynamic: findType("_AsyncCompleter<@>"),
+ _AsyncCompleter_void: findType("_AsyncCompleter<~>"),
+ _AsyncCounter: findType("_AsyncCounter"),
+ _CompleterSink_dynamic: findType("_CompleterSink<@>"),
+ _CompleterStream_dynamic: findType("_CompleterStream<@>"),
+ _DelayedEvent_dynamic: findType("_DelayedEvent<@>"),
+ _EventRequest_dynamic: findType("_EventRequest<@>"),
+ _EventStream_MessageEvent: findType("_EventStream<MessageEvent>"),
+ _FutureListener_dynamic_dynamic: findType("_FutureListener<@,@>"),
+ _Future_List_dynamic: findType("_Future<List<@>>"),
+ _Future_PoolResource: findType("_Future<PoolResource>"),
+ _Future_RunnerSuite: findType("_Future<RunnerSuite>"),
+ _Future_dynamic: findType("_Future<@>"),
+ _Future_int: findType("_Future<int>"),
+ _Future_void: findType("_Future<~>"),
+ _IdentityHashMap_dynamic_dynamic: findType("_IdentityHashMap<@,@>"),
+ _LinkedHashSetCell: findType("_LinkedHashSetCell"),
+ _Node: findType("_Node"),
+ _Predicate_Object: findType("_Predicate<Object>"),
+ _Predicate_dynamic: findType("_Predicate<@>"),
+ _RestRequest_dynamic: findType("_RestRequest<@>"),
+ _StreamChannel_dynamic: findType("_StreamChannel<@>"),
+ _SyncBroadcastStreamController_AsyncError: findType("_SyncBroadcastStreamController<AsyncError>"),
+ _SyncBroadcastStreamController_LiveTest: findType("_SyncBroadcastStreamController<LiveTest>"),
+ _SyncBroadcastStreamController_Message: findType("_SyncBroadcastStreamController<Message>"),
+ _SyncBroadcastStreamController_State: findType("_SyncBroadcastStreamController<State>"),
+ _SyncCompleter_PoolResource: findType("_SyncCompleter<PoolResource>"),
+ _SyncCompleter_dynamic: findType("_SyncCompleter<@>"),
+ _ZoneFunction_Function: findType("_ZoneFunction<Function>"),
+ _ZoneFunction_of_AsyncError_Function_Zone_ZoneDelegate_Zone_Object_StackTrace: findType("_ZoneFunction<AsyncError(Zone,ZoneDelegate,Zone,Object,StackTrace)>"),
+ _ZoneFunction_of_Timer_Function_5_Zone_and_ZoneDelegate_and_Zone_and_Duration_and_void_Function: findType("_ZoneFunction<Timer(Zone,ZoneDelegate,Zone,Duration,~())>"),
+ _ZoneFunction_of_Timer_Function_5_Zone_and_ZoneDelegate_and_Zone_and_Duration_and_void_Function_Timer: findType("_ZoneFunction<Timer(Zone,ZoneDelegate,Zone,Duration,~(Timer))>"),
+ _ZoneFunction_of_Zone_Function_5_Zone_and_ZoneDelegate_and_Zone_and_ZoneSpecification_and_Map_dynamic_dynamic: findType("_ZoneFunction<Zone(Zone,ZoneDelegate,Zone,ZoneSpecification,Map<@,@>)>"),
+ _ZoneFunction_of_void_Function_4_Zone_and_ZoneDelegate_and_Zone_and_void_Function: findType("_ZoneFunction<~(Zone,ZoneDelegate,Zone,~())>"),
+ _ZoneFunction_of_void_Function_Zone_ZoneDelegate_Zone_Object_StackTrace: findType("_ZoneFunction<~(Zone,ZoneDelegate,Zone,Object,StackTrace)>"),
+ _ZoneFunction_of_void_Function_Zone_ZoneDelegate_Zone_String: findType("_ZoneFunction<~(Zone,ZoneDelegate,Zone,String)>"),
+ bool: findType("bool"),
+ bool_Function_Frame: findType("bool(Frame)"),
+ bool_Function_Null: findType("bool(Null)"),
+ bool_Function_Object: findType("bool(Object)"),
+ bool_Function_String: findType("bool(String)"),
+ bool_Function_dynamic: findType("bool(@)"),
+ dynamic: findType("@"),
+ dynamic_Function: findType("@()"),
+ dynamic_Function_Event: findType("@(Event)"),
+ dynamic_Function_Object: findType("@(Object)"),
+ dynamic_Function_Object_Object: findType("@(Object,Object)"),
+ dynamic_Function_Object_StackTrace: findType("@(Object,StackTrace)"),
+ dynamic_Function_String: findType("@(String)"),
+ dynamic_Function_dynamic_dynamic: findType("@(@,@)"),
+ int: findType("int"),
+ num: findType("num"),
+ void: findType("~"),
+ void_Function: findType("~()"),
+ void_Function_MessageEvent: findType("~(MessageEvent)"),
+ void_Function_Object: findType("~(Object)"),
+ void_Function_Object_StackTrace: findType("~(Object,StackTrace)"),
+ void_Function_String_dynamic: findType("~(String,@)"),
+ void_Function_Timer: findType("~(Timer)")
+ };
+ })();
+ (function constants() {
+ var makeConstList = hunkHelpers.makeConstList;
+ C.Interceptor_methods = J.Interceptor.prototype;
+ C.JSArray_methods = J.JSArray.prototype;
+ C.JSInt_methods = J.JSInt.prototype;
+ C.JSNumber_methods = J.JSNumber.prototype;
+ C.JSString_methods = J.JSString.prototype;
+ C.JavaScriptFunction_methods = J.JavaScriptFunction.prototype;
+ C.Location_methods = W.Location.prototype;
+ C.MessagePort_methods = W.MessagePort.prototype;
+ C.NativeUint32List_methods = H.NativeUint32List.prototype;
+ C.NativeUint8List_methods = H.NativeUint8List.prototype;
+ C.PlainJavaScriptObject_methods = J.PlainJavaScriptObject.prototype;
+ C.UnknownJavaScriptObject_methods = J.UnknownJavaScriptObject.prototype;
+ C.AsciiEncoder_127 = new P.AsciiEncoder(127);
+ C.List_empty = H.setRuntimeTypeInfo(makeConstList([]), type$.JSArray_String);
+ C.C_All = new X.All();
+ C.C_AsciiCodec = new P.AsciiCodec();
+ C.C_AsciiGlyphSet = new A.AsciiGlyphSet();
+ C.C_Base64Encoder = new P.Base64Encoder();
+ C.C_Base64Codec = new P.Base64Codec();
+ C.C_EmptyIterator = new H.EmptyIterator(H.findType("EmptyIterator<Null>"));
+ C.C_EmptyUnmodifiableSet = new O.EmptyUnmodifiableSet(H.findType("EmptyUnmodifiableSet<String>"));
+ C.C_JS_CONST = function getTagFallback(o) {
+ var s = Object.prototype.toString.call(o);
+ return s.substring(8, s.length - 1);
+};
+ C.C_JS_CONST0 = function() {
+ var toStringFunction = Object.prototype.toString;
+ function getTag(o) {
+ var s = toStringFunction.call(o);
+ return s.substring(8, s.length - 1);
+ }
+ function getUnknownTag(object, tag) {
+ if (/^HTML[A-Z].*Element$/.test(tag)) {
+ var name = toStringFunction.call(object);
+ if (name == "[object Object]") return null;
+ return "HTMLElement";
+ }
+ }
+ function getUnknownTagGenericBrowser(object, tag) {
+ if (self.HTMLElement && object instanceof HTMLElement) return "HTMLElement";
+ return getUnknownTag(object, tag);
+ }
+ function prototypeForTag(tag) {
+ if (typeof window == "undefined") return null;
+ if (typeof window[tag] == "undefined") return null;
+ var constructor = window[tag];
+ if (typeof constructor != "function") return null;
+ return constructor.prototype;
+ }
+ function discriminator(tag) { return null; }
+ var isBrowser = typeof navigator == "object";
+ return {
+ getTag: getTag,
+ getUnknownTag: isBrowser ? getUnknownTagGenericBrowser : getUnknownTag,
+ prototypeForTag: prototypeForTag,
+ discriminator: discriminator };
+};
+ C.C_JS_CONST6 = function(getTagFallback) {
+ return function(hooks) {
+ if (typeof navigator != "object") return hooks;
+ var ua = navigator.userAgent;
+ if (ua.indexOf("DumpRenderTree") >= 0) return hooks;
+ if (ua.indexOf("Chrome") >= 0) {
+ function confirm(p) {
+ return typeof window == "object" && window[p] && window[p].name == p;
+ }
+ if (confirm("Window") && confirm("HTMLElement")) return hooks;
+ }
+ hooks.getTag = getTagFallback;
+ };
+};
+ C.C_JS_CONST1 = function(hooks) {
+ if (typeof dartExperimentalFixupGetTag != "function") return hooks;
+ hooks.getTag = dartExperimentalFixupGetTag(hooks.getTag);
+};
+ C.C_JS_CONST2 = function(hooks) {
+ var getTag = hooks.getTag;
+ var prototypeForTag = hooks.prototypeForTag;
+ function getTagFixed(o) {
+ var tag = getTag(o);
+ if (tag == "Document") {
+ if (!!o.xmlVersion) return "!Document";
+ return "!HTMLDocument";
+ }
+ return tag;
+ }
+ function prototypeForTagFixed(tag) {
+ if (tag == "Document") return null;
+ return prototypeForTag(tag);
+ }
+ hooks.getTag = getTagFixed;
+ hooks.prototypeForTag = prototypeForTagFixed;
+};
+ C.C_JS_CONST5 = function(hooks) {
+ var userAgent = typeof navigator == "object" ? navigator.userAgent : "";
+ if (userAgent.indexOf("Firefox") == -1) return hooks;
+ var getTag = hooks.getTag;
+ var quickMap = {
+ "BeforeUnloadEvent": "Event",
+ "DataTransfer": "Clipboard",
+ "GeoGeolocation": "Geolocation",
+ "Location": "!Location",
+ "WorkerMessageEvent": "MessageEvent",
+ "XMLDocument": "!Document"};
+ function getTagFirefox(o) {
+ var tag = getTag(o);
+ return quickMap[tag] || tag;
+ }
+ hooks.getTag = getTagFirefox;
+};
+ C.C_JS_CONST4 = function(hooks) {
+ var userAgent = typeof navigator == "object" ? navigator.userAgent : "";
+ if (userAgent.indexOf("Trident/") == -1) return hooks;
+ var getTag = hooks.getTag;
+ var quickMap = {
+ "BeforeUnloadEvent": "Event",
+ "DataTransfer": "Clipboard",
+ "HTMLDDElement": "HTMLElement",
+ "HTMLDTElement": "HTMLElement",
+ "HTMLPhraseElement": "HTMLElement",
+ "Position": "Geoposition"
+ };
+ function getTagIE(o) {
+ var tag = getTag(o);
+ var newTag = quickMap[tag];
+ if (newTag) return newTag;
+ if (tag == "Object") {
+ if (window.DataView && (o instanceof window.DataView)) return "DataView";
+ }
+ return tag;
+ }
+ function prototypeForTagIE(tag) {
+ var constructor = window[tag];
+ if (constructor == null) return null;
+ return constructor.prototype;
+ }
+ hooks.getTag = getTagIE;
+ hooks.prototypeForTag = prototypeForTagIE;
+};
+ C.C_JS_CONST3 = function(hooks) { return hooks; }
+;
+ C.C_JsonCodec = new P.JsonCodec();
+ C.C_None = new O.None();
+ C.C_OutOfMemoryError = new P.OutOfMemoryError();
+ C.C_UnicodeGlyphSet = new K.UnicodeGlyphSet();
+ C.C_Utf8Codec = new P.Utf8Codec();
+ C.C_Utf8Encoder = new P.Utf8Encoder();
+ C.C__DelayedDone = new P._DelayedDone();
+ C.C__IsTrue = new Y._IsTrue();
+ C.C__RootZone = new P._RootZone();
+ C.Duration_0 = new P.Duration(0);
+ C.Duration_30000000 = new P.Duration(30000000);
+ C.JsonDecoder_null = new P.JsonDecoder(null);
+ C.List_127_2047_65535_1114111 = H.setRuntimeTypeInfo(makeConstList([127, 2047, 65535, 1114111]), type$.JSArray_int);
+ C.List_2Vk = H.setRuntimeTypeInfo(makeConstList([0, 0, 32776, 33792, 1, 10240, 0, 0]), type$.JSArray_int);
+ C.List_CVk = H.setRuntimeTypeInfo(makeConstList([0, 0, 65490, 45055, 65535, 34815, 65534, 18431]), type$.JSArray_int);
+ C.List_JYB = H.setRuntimeTypeInfo(makeConstList([0, 0, 26624, 1023, 65534, 2047, 65534, 2047]), type$.JSArray_int);
+ C.List_empty1 = H.setRuntimeTypeInfo(makeConstList([]), H.findType("JSArray<Null>"));
+ C.List_empty0 = H.setRuntimeTypeInfo(makeConstList([]), type$.JSArray_dynamic);
+ C.List_gRj = H.setRuntimeTypeInfo(makeConstList([0, 0, 32722, 12287, 65534, 34815, 65534, 18431]), type$.JSArray_int);
+ C.Runtime_ql0 = new B.Runtime("VM", "vm", null, true, false, false, false, false);
+ C.Runtime_4e8 = new B.Runtime("Chrome", "chrome", null, false, true, true, true, false);
+ C.Runtime_IBZ = new B.Runtime("PhantomJS", "phantomjs", null, false, true, true, true, true);
+ C.Runtime_8Rg = new B.Runtime("Firefox", "firefox", null, false, true, true, false, false);
+ C.Runtime_ivT = new B.Runtime("Safari", "safari", null, false, true, true, false, false);
+ C.Runtime_Mzn = new B.Runtime("Internet Explorer", "ie", null, false, true, true, false, false);
+ C.Runtime_R5O = new B.Runtime("Node.js", "node", null, false, false, true, false, false);
+ C.List_m7e = H.setRuntimeTypeInfo(makeConstList([C.Runtime_ql0, C.Runtime_4e8, C.Runtime_IBZ, C.Runtime_8Rg, C.Runtime_ivT, C.Runtime_Mzn, C.Runtime_R5O]), H.findType("JSArray<Runtime>"));
+ C.List_nxB = H.setRuntimeTypeInfo(makeConstList([0, 0, 24576, 1023, 65534, 34815, 65534, 18431]), type$.JSArray_int);
+ C.OperatingSystem_Windows_windows = new N.OperatingSystem("Windows", "windows");
+ C.OperatingSystem_RkP = new N.OperatingSystem("OS X", "mac-os");
+ C.OperatingSystem_Linux_linux = new N.OperatingSystem("Linux", "linux");
+ C.OperatingSystem_Android_android = new N.OperatingSystem("Android", "android");
+ C.OperatingSystem_iOS_ios = new N.OperatingSystem("iOS", "ios");
+ C.List_opx = H.setRuntimeTypeInfo(makeConstList([C.OperatingSystem_Windows_windows, C.OperatingSystem_RkP, C.OperatingSystem_Linux_linux, C.OperatingSystem_Android_android, C.OperatingSystem_iOS_ios]), H.findType("JSArray<OperatingSystem>"));
+ C.List_qFt = H.setRuntimeTypeInfo(makeConstList([0, 0, 27858, 1023, 65534, 51199, 65535, 32767]), type$.JSArray_int);
+ C.List_qNA = H.setRuntimeTypeInfo(makeConstList([0, 0, 32754, 11263, 65534, 34815, 65534, 18431]), type$.JSArray_int);
+ C.List_qg40 = H.setRuntimeTypeInfo(makeConstList([0, 0, 32722, 12287, 65535, 34815, 65534, 18431]), type$.JSArray_int);
+ C.List_qg4 = H.setRuntimeTypeInfo(makeConstList([0, 0, 65490, 12287, 65535, 34815, 65534, 18431]), type$.JSArray_int);
+ C.List_F9h = H.setRuntimeTypeInfo(makeConstList(["\n", "\r", "\f", "\b", "\t", "\v", "\x7f"]), type$.JSArray_String);
+ C.Map_F9GZw = new H.ConstantStringMap(7, {"\n": "\\n", "\r": "\\r", "\f": "\\f", "\b": "\\b", "\t": "\\t", "\v": "\\v", "\x7f": "\\x7F"}, C.List_F9h, H.findType("ConstantStringMap<String,String>"));
+ C.List_empty2 = H.setRuntimeTypeInfo(makeConstList([]), H.findType("JSArray<BooleanSelector>"));
+ C.Map_empty0 = new H.ConstantStringMap(0, {}, C.List_empty2, H.findType("ConstantStringMap<BooleanSelector,Metadata>"));
+ C.Map_empty1 = new H.ConstantStringMap(0, {}, C.List_empty1, H.findType("ConstantStringMap<Null,Null>"));
+ C.List_empty3 = H.setRuntimeTypeInfo(makeConstList([]), H.findType("JSArray<PlatformSelector>"));
+ C.Map_empty = new H.ConstantStringMap(0, {}, C.List_empty3, H.findType("ConstantStringMap<PlatformSelector,Metadata>"));
+ C.MessageType_print = new D.MessageType("print");
+ C.MessageType_skip = new D.MessageType("skip");
+ C.OperatingSystem_none_none = new N.OperatingSystem("none", "none");
+ C.PlatformSelector_All = new E.PlatformSelector(C.C_All);
+ C.Result_error = new G.Result0("error");
+ C.Result_skipped = new G.Result0("skipped");
+ C.Result_success = new G.Result0("success");
+ C.Status_complete = new G.Status("complete");
+ C.State_Status_complete_Result_error = new G.State(C.Status_complete, C.Result_error);
+ C.Result_failure = new G.Result0("failure");
+ C.State_Status_complete_Result_failure = new G.State(C.Status_complete, C.Result_failure);
+ C.State_Status_complete_Result_skipped = new G.State(C.Status_complete, C.Result_skipped);
+ C.Status_pending = new G.Status("pending");
+ C.State_Status_pending_Result_success = new G.State(C.Status_pending, C.Result_success);
+ C.Status_running = new G.Status("running");
+ C.State_Status_running_Result_skipped = new G.State(C.Status_running, C.Result_skipped);
+ C.State_Status_running_Result_success = new G.State(C.Status_running, C.Result_success);
+ C.Symbol_Drw = new H.Symbol("test.declarer");
+ C.Symbol_MAi = new H.Symbol("test.runner.test_channel");
+ C.Symbol_cQL = new H.Symbol("test.invoker");
+ C.Symbol_runCount = new H.Symbol("runCount");
+ C.Timeout_null_1 = new R.Timeout(null, 1);
+ C.Timeout_null_null = new R.Timeout(null, null);
+ C.TokenType_31K = new L.TokenType("right paren");
+ C.TokenType_69P = new L.TokenType("question mark");
+ C.TokenType_and = new L.TokenType("and");
+ C.TokenType_colon = new L.TokenType("colon");
+ C.TokenType_e7P = new L.TokenType("left paren");
+ C.TokenType_identifier = new L.TokenType("identifier");
+ C.TokenType_not = new L.TokenType("not");
+ C.TokenType_or = new L.TokenType("or");
+ C.TokenType_wwi = new L.TokenType("end of file");
+ C.Type_ByteBuffer_RkP = H.typeLiteral("ByteBuffer");
+ C.Type_ByteData_zNC = H.typeLiteral("ByteData");
+ C.Type_Float32List_LB7 = H.typeLiteral("Float32List");
+ C.Type_Float64List_LB7 = H.typeLiteral("Float64List");
+ C.Type_Int16List_uXf = H.typeLiteral("Int16List");
+ C.Type_Int32List_O50 = H.typeLiteral("Int32List");
+ C.Type_Int8List_ekJ = H.typeLiteral("Int8List");
+ C.Type_JSObject_8k0 = H.typeLiteral("JSObject");
+ C.Type_Null_Yyn = H.typeLiteral("Null");
+ C.Type_String_k8F = H.typeLiteral("String");
+ C.Type_Uint16List_2bx = H.typeLiteral("Uint16List");
+ C.Type_Uint32List_2bx = H.typeLiteral("Uint32List");
+ C.Type_Uint8ClampedList_Jik = H.typeLiteral("Uint8ClampedList");
+ C.Type_Uint8List_WLA = H.typeLiteral("Uint8List");
+ C.Type_bool_lhE = H.typeLiteral("bool");
+ C.Type_double_K1J = H.typeLiteral("double");
+ C.Type_int_tHn = H.typeLiteral("int");
+ C.Type_num_cv7 = H.typeLiteral("num");
+ C._PathDirection_8Gl = new M._PathDirection("at root");
+ C._PathDirection_988 = new M._PathDirection("below root");
+ C._PathDirection_FIw = new M._PathDirection("reaches root");
+ C._PathDirection_ZGD = new M._PathDirection("above root");
+ C._PathRelation_different = new M._PathRelation("different");
+ C._PathRelation_equal = new M._PathRelation("equal");
+ C._PathRelation_inconclusive = new M._PathRelation("inconclusive");
+ C._PathRelation_within = new M._PathRelation("within");
+ C._StreamGroupState_canceled = new L._StreamGroupState("canceled");
+ C._StreamGroupState_dormant = new L._StreamGroupState("dormant");
+ C._StreamGroupState_listening = new L._StreamGroupState("listening");
+ C._StreamGroupState_paused = new L._StreamGroupState("paused");
+ C._TokenKind_false_false_false = new T._TokenKind(false, false, false);
+ C._TokenKind_false_false_true = new T._TokenKind(false, false, true);
+ C._TokenKind_false_true_false = new T._TokenKind(false, true, false);
+ C._TokenKind_true_false_false = new T._TokenKind(true, false, false);
+ C._ZoneFunction_3bB = new P._ZoneFunction(C.C__RootZone, P.async___rootCreatePeriodicTimer$closure(), type$._ZoneFunction_of_Timer_Function_5_Zone_and_ZoneDelegate_and_Zone_and_Duration_and_void_Function_Timer);
+ C._ZoneFunction_7G2 = new P._ZoneFunction(C.C__RootZone, P.async___rootRegisterBinaryCallback$closure(), type$._ZoneFunction_Function);
+ C._ZoneFunction_Eeh = new P._ZoneFunction(C.C__RootZone, P.async___rootRegisterUnaryCallback$closure(), type$._ZoneFunction_Function);
+ C._ZoneFunction_NMc = new P._ZoneFunction(C.C__RootZone, P.async___rootHandleUncaughtError$closure(), type$._ZoneFunction_of_void_Function_Zone_ZoneDelegate_Zone_Object_StackTrace);
+ C._ZoneFunction__RootZone__rootCreateTimer = new P._ZoneFunction(C.C__RootZone, P.async___rootCreateTimer$closure(), type$._ZoneFunction_of_Timer_Function_5_Zone_and_ZoneDelegate_and_Zone_and_Duration_and_void_Function);
+ C._ZoneFunction__RootZone__rootErrorCallback = new P._ZoneFunction(C.C__RootZone, P.async___rootErrorCallback$closure(), type$._ZoneFunction_of_AsyncError_Function_Zone_ZoneDelegate_Zone_Object_StackTrace);
+ C._ZoneFunction__RootZone__rootFork = new P._ZoneFunction(C.C__RootZone, P.async___rootFork$closure(), type$._ZoneFunction_of_Zone_Function_5_Zone_and_ZoneDelegate_and_Zone_and_ZoneSpecification_and_Map_dynamic_dynamic);
+ C._ZoneFunction__RootZone__rootPrint = new P._ZoneFunction(C.C__RootZone, P.async___rootPrint$closure(), type$._ZoneFunction_of_void_Function_Zone_ZoneDelegate_Zone_String);
+ C._ZoneFunction__RootZone__rootRegisterCallback = new P._ZoneFunction(C.C__RootZone, P.async___rootRegisterCallback$closure(), type$._ZoneFunction_Function);
+ C._ZoneFunction__RootZone__rootRun = new P._ZoneFunction(C.C__RootZone, P.async___rootRun$closure(), type$._ZoneFunction_Function);
+ C._ZoneFunction__RootZone__rootRunBinary = new P._ZoneFunction(C.C__RootZone, P.async___rootRunBinary$closure(), type$._ZoneFunction_Function);
+ C._ZoneFunction__RootZone__rootRunUnary = new P._ZoneFunction(C.C__RootZone, P.async___rootRunUnary$closure(), type$._ZoneFunction_Function);
+ C._ZoneFunction__RootZone__rootScheduleMicrotask = new P._ZoneFunction(C.C__RootZone, P.async___rootScheduleMicrotask$closure(), type$._ZoneFunction_of_void_Function_4_Zone_and_ZoneDelegate_and_Zone_and_void_Function);
+ C._ZoneSpecification_ALf = new P._ZoneSpecification(null, null, null, null, null, null, null, null, null, null, null, null, null);
+ })();
+ (function staticFields() {
+ $.printToZone = null;
+ $.Primitives_timerFrequency = null;
+ $.Primitives_timerTicks = null;
+ $.Closure_functionCounter = 0;
+ $.BoundClosure_selfFieldNameCache = null;
+ $.BoundClosure_receiverFieldNameCache = null;
+ $.getTagFunction = null;
+ $.alternateTagFunction = null;
+ $.prototypeForTagFunction = null;
+ $.dispatchRecordsForInstanceTags = null;
+ $.interceptorsForUncacheableTags = null;
+ $.initNativeDispatchFlag = null;
+ $._nextCallback = null;
+ $._lastCallback = null;
+ $._lastPriorityCallback = null;
+ $._isInCallbackLoop = false;
+ $.Zone__current = C.C__RootZone;
+ $._RootZone__rootDelegate = null;
+ $._toStringVisiting = [];
+ $.Expando__keyCount = 0;
+ $.Stopwatch__frequency = null;
+ $._currentUriBase = null;
+ $._current = null;
+ $._glyphs = C.C_UnicodeGlyphSet;
+ $._macOSDirectories = P.LinkedHashSet_LinkedHashSet$_literal(["/Applications", "/Library", "/Network", "/System", "/Users"], type$.String);
+ $._globalDeclarer = null;
+ $.x = 0;
+ })();
+ (function lazyInitializers() {
+ var _lazy = hunkHelpers.lazy;
+ _lazy($, "DART_CLOSURE_PROPERTY_NAME", "$get$DART_CLOSURE_PROPERTY_NAME", function() {
+ return H.getIsolateAffinityTag("_$dart_dartClosure");
+ });
+ _lazy($, "JS_INTEROP_INTERCEPTOR_TAG", "$get$JS_INTEROP_INTERCEPTOR_TAG", function() {
+ return H.getIsolateAffinityTag("_$dart_js");
+ });
+ _lazy($, "TypeErrorDecoder_noSuchMethodPattern", "$get$TypeErrorDecoder_noSuchMethodPattern", function() {
+ return H.TypeErrorDecoder_extractPattern(H.TypeErrorDecoder_provokeCallErrorOn({
+ toString: function() {
+ return "$receiver$";
+ }
+ }));
+ });
+ _lazy($, "TypeErrorDecoder_notClosurePattern", "$get$TypeErrorDecoder_notClosurePattern", function() {
+ return H.TypeErrorDecoder_extractPattern(H.TypeErrorDecoder_provokeCallErrorOn({$method$: null,
+ toString: function() {
+ return "$receiver$";
+ }
+ }));
+ });
+ _lazy($, "TypeErrorDecoder_nullCallPattern", "$get$TypeErrorDecoder_nullCallPattern", function() {
+ return H.TypeErrorDecoder_extractPattern(H.TypeErrorDecoder_provokeCallErrorOn(null));
+ });
+ _lazy($, "TypeErrorDecoder_nullLiteralCallPattern", "$get$TypeErrorDecoder_nullLiteralCallPattern", function() {
+ return H.TypeErrorDecoder_extractPattern(function() {
+ var $argumentsExpr$ = '$arguments$';
+ try {
+ null.$method$($argumentsExpr$);
+ } catch (e) {
+ return e.message;
+ }
+ }());
+ });
+ _lazy($, "TypeErrorDecoder_undefinedCallPattern", "$get$TypeErrorDecoder_undefinedCallPattern", function() {
+ return H.TypeErrorDecoder_extractPattern(H.TypeErrorDecoder_provokeCallErrorOn(void 0));
+ });
+ _lazy($, "TypeErrorDecoder_undefinedLiteralCallPattern", "$get$TypeErrorDecoder_undefinedLiteralCallPattern", function() {
+ return H.TypeErrorDecoder_extractPattern(function() {
+ var $argumentsExpr$ = '$arguments$';
+ try {
+ (void 0).$method$($argumentsExpr$);
+ } catch (e) {
+ return e.message;
+ }
+ }());
+ });
+ _lazy($, "TypeErrorDecoder_nullPropertyPattern", "$get$TypeErrorDecoder_nullPropertyPattern", function() {
+ return H.TypeErrorDecoder_extractPattern(H.TypeErrorDecoder_provokePropertyErrorOn(null));
+ });
+ _lazy($, "TypeErrorDecoder_nullLiteralPropertyPattern", "$get$TypeErrorDecoder_nullLiteralPropertyPattern", function() {
+ return H.TypeErrorDecoder_extractPattern(function() {
+ try {
+ null.$method$;
+ } catch (e) {
+ return e.message;
+ }
+ }());
+ });
+ _lazy($, "TypeErrorDecoder_undefinedPropertyPattern", "$get$TypeErrorDecoder_undefinedPropertyPattern", function() {
+ return H.TypeErrorDecoder_extractPattern(H.TypeErrorDecoder_provokePropertyErrorOn(void 0));
+ });
+ _lazy($, "TypeErrorDecoder_undefinedLiteralPropertyPattern", "$get$TypeErrorDecoder_undefinedLiteralPropertyPattern", function() {
+ return H.TypeErrorDecoder_extractPattern(function() {
+ try {
+ (void 0).$method$;
+ } catch (e) {
+ return e.message;
+ }
+ }());
+ });
+ _lazy($, "_AsyncRun__scheduleImmediateClosure", "$get$_AsyncRun__scheduleImmediateClosure", function() {
+ return P._AsyncRun__initializeScheduleImmediate();
+ });
+ _lazy($, "Future__nullFuture", "$get$Future__nullFuture", function() {
+ return P._Future$zoneValue(null, C.C__RootZone, type$.Null);
+ });
+ _lazy($, "_RootZone__rootMap", "$get$_RootZone__rootMap", function() {
+ var t1 = type$.dynamic;
+ return P.HashMap_HashMap(t1, t1);
+ });
+ _lazy($, "Utf8Decoder__decoder", "$get$Utf8Decoder__decoder", function() {
+ return P.Utf8Decoder__makeDecoder();
+ });
+ _lazy($, "_Base64Decoder__inverseAlphabet", "$get$_Base64Decoder__inverseAlphabet", function() {
+ return H.NativeInt8List__create1(H._ensureNativeList(H.setRuntimeTypeInfo([-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -2, -2, -2, -2, -2, 62, -2, 62, -2, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -2, -2, -2, -1, -2, -2, -2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -2, -2, -2, -2, 63, -2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -2, -2, -2, -2, -2], type$.JSArray_int)));
+ });
+ _lazy($, "_Uri__isWindowsCached", "$get$_Uri__isWindowsCached", function() {
+ return typeof process != "undefined" && Object.prototype.toString.call(process) == "[object process]" && process.platform == "win32";
+ });
+ _lazy($, "_Uri__needsNoEncoding", "$get$_Uri__needsNoEncoding", function() {
+ return P.RegExp_RegExp("^[\\-\\.0-9A-Z_a-z~]*$", false);
+ });
+ _lazy($, "_hasErrorStackProperty", "$get$_hasErrorStackProperty", function() {
+ return new Error().stack != void 0;
+ });
+ _lazy($, "_scannerTables", "$get$_scannerTables", function() {
+ return P._createTables();
+ });
+ _lazy($, "_whitespaceAndSingleLineComments", "$get$_whitespaceAndSingleLineComments", function() {
+ return P.RegExp_RegExp("([ \\t\\n]+|//[^\\n]*(\\n|$))+", false);
+ });
+ _lazy($, "_multiLineCommentBody", "$get$_multiLineCommentBody", function() {
+ return P.RegExp_RegExp("([^/*]|/[^*]|\\*[^/])+", false);
+ });
+ _lazy($, "_hyphenatedIdentifier", "$get$_hyphenatedIdentifier0", function() {
+ return P.RegExp_RegExp("[a-zA-Z_-][a-zA-Z0-9_-]*", false);
+ });
+ _lazy($, "_dart2DynamicArgs", "$get$_dart2DynamicArgs", function() {
+ return P.RegExp_RegExp("<dynamic(, dynamic)*>", false);
+ });
+ _lazy($, "_escapeRegExp", "$get$_escapeRegExp", function() {
+ return P.RegExp_RegExp("[\\x00-\\x07\\x0E-\\x1F" + C.Map_F9GZw.get$keys().map$1$1(0, M.util___getHexLiteral$closure(), type$.String).join$0(0) + "]", false);
+ });
+ _lazy($, "windows", "$get$windows", function() {
+ return M.Context_Context($.$get$Style_windows());
+ });
+ _lazy($, "url", "$get$url", function() {
+ return M.Context_Context($.$get$Style_url());
+ });
+ _lazy($, "context", "$get$context", function() {
+ return new M.Context($.$get$Style_platform(), null);
+ });
+ _lazy($, "Style_posix", "$get$Style_posix", function() {
+ return new E.PosixStyle(P.RegExp_RegExp("/", false), P.RegExp_RegExp("[^/]$", false), P.RegExp_RegExp("^/", false));
+ });
+ _lazy($, "Style_windows", "$get$Style_windows", function() {
+ return new L.WindowsStyle(P.RegExp_RegExp("[/\\\\]", false), P.RegExp_RegExp("[^/\\\\]$", false), P.RegExp_RegExp("^(\\\\\\\\[^\\\\]+\\\\[^\\\\/]+|[a-zA-Z]:[/\\\\])", false), P.RegExp_RegExp("^[/\\\\](?![/\\\\])", false));
+ });
+ _lazy($, "Style_url", "$get$Style_url", function() {
+ return new F.UrlStyle(P.RegExp_RegExp("/", false), P.RegExp_RegExp("(^[a-zA-Z][-+.a-zA-Z\\d]*://|[^/])$", false), P.RegExp_RegExp("[a-zA-Z][-+.a-zA-Z\\d]*://[^/]*", false), P.RegExp_RegExp("^/", false));
+ });
+ _lazy($, "Style_platform", "$get$Style_platform", function() {
+ return O.Style__getPlatformStyle();
+ });
+ _lazy($, "_digits", "$get$_digits", function() {
+ return new L.closure().call$0();
+ });
+ _lazy($, "MAX_INT32", "$get$MAX_INT32", function() {
+ return H._checkIntNullable(P.pow(2, 31) - 1);
+ });
+ _lazy($, "MIN_INT32", "$get$MIN_INT32", function() {
+ return H._checkIntNullable(-P.pow(2, 31));
+ });
+ _lazy($, "_specKey", "$get$_specKey", function() {
+ return new P.Object();
+ });
+ _lazy($, "_vmFrame", "$get$_vmFrame", function() {
+ return P.RegExp_RegExp("^#\\d+\\s+(\\S.*) \\((.+?)((?::\\d+){0,2})\\)$", false);
+ });
+ _lazy($, "_v8Frame", "$get$_v8Frame", function() {
+ return P.RegExp_RegExp("^\\s*at (?:(\\S.*?)(?: \\[as [^\\]]+\\])? \\((.*)\\)|(.*))$", false);
+ });
+ _lazy($, "_v8UrlLocation", "$get$_v8UrlLocation", function() {
+ return P.RegExp_RegExp("^(.*):(\\d+):(\\d+)|native$", false);
+ });
+ _lazy($, "_v8EvalLocation", "$get$_v8EvalLocation", function() {
+ return P.RegExp_RegExp("^eval at (?:\\S.*?) \\((.*)\\)(?:, .*?:\\d+:\\d+)?$", false);
+ });
+ _lazy($, "_firefoxSafariFrame", "$get$_firefoxSafariFrame", function() {
+ return P.RegExp_RegExp("^(?:([^@(/]*)(?:\\(.*\\))?((?:/[^/]*)*)(?:\\(.*\\))?@)?(.*?):(\\d*)(?::(\\d*))?$", false);
+ });
+ _lazy($, "_friendlyFrame", "$get$_friendlyFrame", function() {
+ return P.RegExp_RegExp("^(\\S+)(?: (\\d+)(?::(\\d+))?)?\\s+([^\\d].*)$", false);
+ });
+ _lazy($, "_asyncBody", "$get$_asyncBody", function() {
+ return P.RegExp_RegExp("<(<anonymous closure>|[^>]+)_async_body>", false);
+ });
+ _lazy($, "_initialDot", "$get$_initialDot", function() {
+ return P.RegExp_RegExp("^\\.", false);
+ });
+ _lazy($, "Frame__uriRegExp", "$get$Frame__uriRegExp", function() {
+ return P.RegExp_RegExp("^[a-zA-Z][-+.a-zA-Z\\d]*://", false);
+ });
+ _lazy($, "Frame__windowsRegExp", "$get$Frame__windowsRegExp", function() {
+ return P.RegExp_RegExp("^([a-zA-Z]:[\\\\/]|\\\\\\\\)", false);
+ });
+ _lazy($, "StackZoneSpecification_disableKey", "$get$StackZoneSpecification_disableKey", function() {
+ return new P.Object();
+ });
+ _lazy($, "_terseRegExp", "$get$_terseRegExp", function() {
+ return P.RegExp_RegExp("(-patch)?([/\\\\].*)?$", false);
+ });
+ _lazy($, "_v8Trace", "$get$_v8Trace", function() {
+ return P.RegExp_RegExp("\\n ?at ", false);
+ });
+ _lazy($, "_v8TraceLine", "$get$_v8TraceLine", function() {
+ return P.RegExp_RegExp(" ?at ", false);
+ });
+ _lazy($, "_firefoxSafariTrace", "$get$_firefoxSafariTrace", function() {
+ return P.RegExp_RegExp("^(([.0-9A-Za-z_$/<]|\\(.*\\))*@)?[^\\s]*:\\d*$", true);
+ });
+ _lazy($, "_friendlyTrace", "$get$_friendlyTrace", function() {
+ return P.RegExp_RegExp("^[^\\s<][^\\s]*( \\d+(:\\d+)?)?[ \\t]+[^\\s]+$", true);
+ });
+ _lazy($, "Metadata_empty", "$get$Metadata_empty", function() {
+ var _null = null;
+ return O.Metadata$_(_null, _null, _null, _null, _null, _null, _null, _null, _null, _null);
+ });
+ _lazy($, "_universalValidVariables", "$get$_universalValidVariables", function() {
+ var _i,
+ t1 = P.LinkedHashSet_LinkedHashSet(type$.String);
+ t1.add$1(0, "posix");
+ t1.add$1(0, "dart-vm");
+ t1.add$1(0, "browser");
+ t1.add$1(0, "js");
+ t1.add$1(0, "blink");
+ t1.add$1(0, "google");
+ for (_i = 0; _i < 7; ++_i)
+ t1.add$1(0, C.List_m7e[_i].identifier);
+ for (_i = 0; _i < 5; ++_i)
+ t1.add$1(0, C.List_opx[_i].identifier);
+ return t1;
+ });
+ _lazy($, "_currentKey", "$get$_currentKey0", function() {
+ return new P.Object();
+ });
+ _lazy($, "_currentKey0", "$get$_currentKey", function() {
+ return new P.Object();
+ });
+ _lazy($, "currentOSGuess", "$get$currentOSGuess", function() {
+ return new B.closure0().call$0();
+ });
+ _lazy($, "_hyphenatedIdentifier0", "$get$_hyphenatedIdentifier", function() {
+ return P.RegExp_RegExp("[a-zA-Z_-][a-zA-Z0-9_-]*", false);
+ });
+ _lazy($, "anchoredHyphenatedIdentifier", "$get$anchoredHyphenatedIdentifier", function() {
+ return P.RegExp_RegExp("^" + $.$get$_hyphenatedIdentifier().pattern + "$", false);
+ });
+ _lazy($, "SuiteConfiguration_empty", "$get$SuiteConfiguration_empty", function() {
+ var t1, _null = null;
+ U.SuiteConfiguration__list(_null, type$.String);
+ t1 = type$.Pattern;
+ L.UnmodifiableSetView$(P.LinkedHashSet_LinkedHashSet$_empty(t1), t1);
+ U.SuiteConfiguration__list(_null, H.findType("RuntimeSelection"));
+ t1 = H.findType("SuiteConfiguration");
+ U.SuiteConfiguration__map(_null, type$.BooleanSelector, t1);
+ U.SuiteConfiguration__map(_null, type$.PlatformSelector, t1);
+ $.$get$Metadata_empty();
+ return new U.SuiteConfiguration();
+ });
+ })();
+ (function nativeSupport() {
+ !function() {
+ var intern = function(s) {
+ var o = {};
+ o[s] = 1;
+ return Object.keys(hunkHelpers.convertToFastObject(o))[0];
+ };
+ init.getIsolateTag = function(name) {
+ return intern("___dart_" + name + init.isolateTag);
+ };
+ var tableProperty = "___dart_isolate_tags_";
+ var usedProperties = Object[tableProperty] || (Object[tableProperty] = Object.create(null));
+ var rootProperty = "_ZxYxX";
+ for (var i = 0;; i++) {
+ var property = intern(rootProperty + "_" + i + "_");
+ if (!(property in usedProperties)) {
+ usedProperties[property] = 1;
+ init.isolateTag = property;
+ break;
+ }
+ }
+ init.dispatchPropertyName = init.getIsolateTag("dispatch_record");
+ }();
+ hunkHelpers.setOrUpdateInterceptorsByTag({ArrayBuffer: H.NativeByteBuffer, ArrayBufferView: H.NativeTypedData, DataView: H.NativeByteData, Float32Array: H.NativeFloat32List, Float64Array: H.NativeFloat64List, Int16Array: H.NativeInt16List, Int32Array: H.NativeInt32List, Int8Array: H.NativeInt8List, Uint16Array: H.NativeUint16List, Uint32Array: H.NativeUint32List, Uint8ClampedArray: H.NativeUint8ClampedList, CanvasPixelArray: H.NativeUint8ClampedList, Uint8Array: H.NativeUint8List, ApplicationCacheErrorEvent: W.ApplicationCacheErrorEvent, Blob: W.Blob, DOMError: W.DomError, DOMException: W.DomException, ErrorEvent: W.ErrorEvent, AbortPaymentEvent: W.Event, AnimationEvent: W.Event, AnimationPlaybackEvent: W.Event, BackgroundFetchClickEvent: W.Event, BackgroundFetchEvent: W.Event, BackgroundFetchFailEvent: W.Event, BackgroundFetchedEvent: W.Event, BeforeInstallPromptEvent: W.Event, BeforeUnloadEvent: W.Event, BlobEvent: W.Event, CanMakePaymentEvent: W.Event, ClipboardEvent: W.Event, CloseEvent: W.Event, CompositionEvent: W.Event, CustomEvent: W.Event, DeviceMotionEvent: W.Event, DeviceOrientationEvent: W.Event, ExtendableEvent: W.Event, ExtendableMessageEvent: W.Event, FetchEvent: W.Event, FocusEvent: W.Event, FontFaceSetLoadEvent: W.Event, ForeignFetchEvent: W.Event, GamepadEvent: W.Event, HashChangeEvent: W.Event, InstallEvent: W.Event, KeyboardEvent: W.Event, MediaEncryptedEvent: W.Event, MediaQueryListEvent: W.Event, MediaStreamEvent: W.Event, MediaStreamTrackEvent: W.Event, MIDIConnectionEvent: W.Event, MIDIMessageEvent: W.Event, MouseEvent: W.Event, DragEvent: W.Event, MutationEvent: W.Event, NotificationEvent: W.Event, PageTransitionEvent: W.Event, PaymentRequestEvent: W.Event, PaymentRequestUpdateEvent: W.Event, PointerEvent: W.Event, PopStateEvent: W.Event, PresentationConnectionAvailableEvent: W.Event, ProgressEvent: W.Event, PromiseRejectionEvent: W.Event, PushEvent: W.Event, RTCDataChannelEvent: W.Event, RTCDTMFToneChangeEvent: W.Event, RTCPeerConnectionIceEvent: W.Event, RTCTrackEvent: W.Event, SecurityPolicyViolationEvent: W.Event, SensorErrorEvent: W.Event, SpeechRecognitionEvent: W.Event, SpeechSynthesisEvent: W.Event, StorageEvent: W.Event, SyncEvent: W.Event, TextEvent: W.Event, TouchEvent: W.Event, TrackEvent: W.Event, TransitionEvent: W.Event, WebKitTransitionEvent: W.Event, UIEvent: W.Event, VRDeviceEvent: W.Event, VRDisplayEvent: W.Event, VRSessionEvent: W.Event, WheelEvent: W.Event, MojoInterfaceRequestEvent: W.Event, ResourceProgressEvent: W.Event, USBConnectionEvent: W.Event, IDBVersionChangeEvent: W.Event, AudioProcessingEvent: W.Event, OfflineAudioCompletionEvent: W.Event, WebGLContextEvent: W.Event, Event: W.Event, InputEvent: W.Event, Window: W.EventTarget, DOMWindow: W.EventTarget, EventTarget: W.EventTarget, File: W.File, Location: W.Location, MediaError: W.MediaError, MediaKeyMessageEvent: W.MediaKeyMessageEvent, MessageEvent: W.MessageEvent, MessagePort: W.MessagePort, NavigatorUserMediaError: W.NavigatorUserMediaError, OverconstrainedError: W.OverconstrainedError, PositionError: W.PositionError, PresentationConnectionCloseEvent: W.PresentationConnectionCloseEvent, SpeechRecognitionError: W.SpeechRecognitionError, SQLError: P.SqlError});
+ hunkHelpers.setOrUpdateLeafTags({ArrayBuffer: true, ArrayBufferView: false, DataView: true, Float32Array: true, Float64Array: true, Int16Array: true, Int32Array: true, Int8Array: true, Uint16Array: true, Uint32Array: true, Uint8ClampedArray: true, CanvasPixelArray: true, Uint8Array: false, ApplicationCacheErrorEvent: true, Blob: false, DOMError: true, DOMException: true, ErrorEvent: true, AbortPaymentEvent: true, AnimationEvent: true, AnimationPlaybackEvent: true, BackgroundFetchClickEvent: true, BackgroundFetchEvent: true, BackgroundFetchFailEvent: true, BackgroundFetchedEvent: true, BeforeInstallPromptEvent: true, BeforeUnloadEvent: true, BlobEvent: true, CanMakePaymentEvent: true, ClipboardEvent: true, CloseEvent: true, CompositionEvent: true, CustomEvent: true, DeviceMotionEvent: true, DeviceOrientationEvent: true, ExtendableEvent: true, ExtendableMessageEvent: true, FetchEvent: true, FocusEvent: true, FontFaceSetLoadEvent: true, ForeignFetchEvent: true, GamepadEvent: true, HashChangeEvent: true, InstallEvent: true, KeyboardEvent: true, MediaEncryptedEvent: true, MediaQueryListEvent: true, MediaStreamEvent: true, MediaStreamTrackEvent: true, MIDIConnectionEvent: true, MIDIMessageEvent: true, MouseEvent: true, DragEvent: true, MutationEvent: true, NotificationEvent: true, PageTransitionEvent: true, PaymentRequestEvent: true, PaymentRequestUpdateEvent: true, PointerEvent: true, PopStateEvent: true, PresentationConnectionAvailableEvent: true, ProgressEvent: true, PromiseRejectionEvent: true, PushEvent: true, RTCDataChannelEvent: true, RTCDTMFToneChangeEvent: true, RTCPeerConnectionIceEvent: true, RTCTrackEvent: true, SecurityPolicyViolationEvent: true, SensorErrorEvent: true, SpeechRecognitionEvent: true, SpeechSynthesisEvent: true, StorageEvent: true, SyncEvent: true, TextEvent: true, TouchEvent: true, TrackEvent: true, TransitionEvent: true, WebKitTransitionEvent: true, UIEvent: true, VRDeviceEvent: true, VRDisplayEvent: true, VRSessionEvent: true, WheelEvent: true, MojoInterfaceRequestEvent: true, ResourceProgressEvent: true, USBConnectionEvent: true, IDBVersionChangeEvent: true, AudioProcessingEvent: true, OfflineAudioCompletionEvent: true, WebGLContextEvent: true, Event: false, InputEvent: false, Window: true, DOMWindow: true, EventTarget: false, File: true, Location: true, MediaError: true, MediaKeyMessageEvent: true, MessageEvent: true, MessagePort: true, NavigatorUserMediaError: true, OverconstrainedError: true, PositionError: true, PresentationConnectionCloseEvent: true, SpeechRecognitionError: true, SQLError: true});
+ H.NativeTypedArray.$nativeSuperclassTag = "ArrayBufferView";
+ H._NativeTypedArrayOfDouble_NativeTypedArray_ListMixin.$nativeSuperclassTag = "ArrayBufferView";
+ H._NativeTypedArrayOfDouble_NativeTypedArray_ListMixin_FixedLengthListMixin.$nativeSuperclassTag = "ArrayBufferView";
+ H.NativeTypedArrayOfDouble.$nativeSuperclassTag = "ArrayBufferView";
+ H._NativeTypedArrayOfInt_NativeTypedArray_ListMixin.$nativeSuperclassTag = "ArrayBufferView";
+ H._NativeTypedArrayOfInt_NativeTypedArray_ListMixin_FixedLengthListMixin.$nativeSuperclassTag = "ArrayBufferView";
+ H.NativeTypedArrayOfInt.$nativeSuperclassTag = "ArrayBufferView";
+ })();
+ Function.prototype.call$0 = function() {
+ return this();
+ };
+ Function.prototype.call$1 = function(a) {
+ return this(a);
+ };
+ Function.prototype.call$2 = function(a, b) {
+ return this(a, b);
+ };
+ Function.prototype.call$3$3 = function(a, b, c) {
+ return this(a, b, c);
+ };
+ Function.prototype.call$2$2 = function(a, b) {
+ return this(a, b);
+ };
+ Function.prototype.call$1$1 = function(a) {
+ return this(a);
+ };
+ Function.prototype.call$2$1 = function(a) {
+ return this(a);
+ };
+ Function.prototype.call$3 = function(a, b, c) {
+ return this(a, b, c);
+ };
+ Function.prototype.call$4 = function(a, b, c, d) {
+ return this(a, b, c, d);
+ };
+ Function.prototype.call$3$1 = function(a) {
+ return this(a);
+ };
+ Function.prototype.call$2$3 = function(a, b, c) {
+ return this(a, b, c);
+ };
+ Function.prototype.call$1$2 = function(a, b) {
+ return this(a, b);
+ };
+ Function.prototype.call$5 = function(a, b, c, d, e) {
+ return this(a, b, c, d, e);
+ };
+ Function.prototype.call$3$4 = function(a, b, c, d) {
+ return this(a, b, c, d);
+ };
+ Function.prototype.call$2$4 = function(a, b, c, d) {
+ return this(a, b, c, d);
+ };
+ Function.prototype.call$1$4 = function(a, b, c, d) {
+ return this(a, b, c, d);
+ };
+ Function.prototype.call$3$6 = function(a, b, c, d, e, f) {
+ return this(a, b, c, d, e, f);
+ };
+ Function.prototype.call$2$5 = function(a, b, c, d, e) {
+ return this(a, b, c, d, e);
+ };
+ Function.prototype.call$2$0 = function() {
+ return this();
+ };
+ convertAllToFastObject(holders);
+ convertToFastObject($);
+ (function(callback) {
+ if (typeof document === "undefined") {
+ callback(null);
+ return;
+ }
+ if (typeof document.currentScript != 'undefined') {
+ callback(document.currentScript);
+ return;
+ }
+ var scripts = document.scripts;
+ function onLoad(event) {
+ for (var i = 0; i < scripts.length; ++i)
+ scripts[i].removeEventListener("load", onLoad, false);
+ callback(event.target);
+ }
+ for (var i = 0; i < scripts.length; ++i)
+ scripts[i].addEventListener("load", onLoad, false);
+ })(function(currentScript) {
+ init.currentScript = currentScript;
+ if (typeof dartMainRunner === "function")
+ dartMainRunner(R.main, []);
+ else
+ R.main([]);
+ });
+})();
+
+//# sourceMappingURL=main_test.dart.browser_test.dart.js.map
diff --git a/pkgs/coverage/test/test_files/main_test.js.map b/pkgs/coverage/test/test_files/main_test.js.map
new file mode 100644
index 0000000..38669ba
--- /dev/null
+++ b/pkgs/coverage/test/test_files/main_test.js.map
@@ -0,0 +1 @@
+{"version":3,"engine":"v2","file":"main_test.dart.browser_test.dart.js","sourceRoot":"","sources":["google3:///third_party/dart_lang/v2/sdk/lib/internal/cast.dart","google3:///third_party/dart_lang/v2/sdk/lib/internal/internal.dart","google3:///third_party/dart_lang/v2/sdk/lib/internal/iterable.dart","google3:///third_party/dart_lang/v2/sdk/lib/core/errors.dart","google3:///third_party/dart_lang/v2/sdk/lib/_internal/js_runtime/lib/constant_map.dart","google3:///third_party/dart_lang/v2/sdk/lib/_internal/js_runtime/lib/instantiation.dart","google3:///third_party/dart_lang/v2/sdk/lib/_internal/js_runtime/lib/js_helper.dart","google3:///third_party/dart_lang/v2/sdk/lib/_internal/js_runtime/lib/rti.dart","google3:///third_party/dart_lang/v2/sdk/lib/_internal/js_runtime/lib/native_helper.dart","google3:///third_party/dart_lang/v2/sdk/lib/_internal/js_runtime/lib/core_patch.dart","google3:///third_party/dart_lang/v2/sdk/lib/_internal/js_runtime/lib/js_rti.dart","google3:///third_party/dart_lang/v2/sdk/lib/core/exceptions.dart","google3:///third_party/dart_lang/v2/sdk/lib/_internal/js_runtime/lib/interceptors.dart","google3:///third_party/dart_lang/v2/sdk/lib/_internal/js_runtime/lib/regexp_helper.dart","google3:///third_party/dart_lang/v2/sdk/lib/_internal/js_runtime/lib/string_helper.dart","google3:///third_party/dart_lang/v2/sdk/lib/core/iterable.dart","google3:///third_party/dart_lang/v2/sdk/lib/_internal/js_runtime/lib/native_typed_data.dart","google3:///third_party/dart_lang/v2/sdk/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart","google3:///third_party/dart_lang/v2/sdk/lib/_internal/js_runtime/lib/js_names.dart","google3:///third_party/dart_lang/v2/sdk/lib/_internal/js_runtime/lib/js_primitives.dart","google3:///third_party/dart_lang/v2/sdk/lib/_internal/js_runtime/lib/js_array.dart","google3:///third_party/dart_lang/v2/sdk/lib/_internal/js_runtime/lib/js_string.dart","google3:///third_party/dart_lang/v2/sdk/lib/_internal/js_runtime/lib/async_patch.dart","google3:///third_party/dart_lang/v2/sdk/lib/core/duration.dart","google3:///third_party/dart_lang/v2/sdk/lib/async/future_impl.dart","google3:///third_party/dart_lang/v2/sdk/lib/async/zone.dart","google3:///third_party/dart_lang/v2/sdk/lib/async/future.dart","google3:///third_party/dart_lang/v2/sdk/lib/async/timer.dart","google3:///third_party/dart_lang/v2/sdk/lib/async/schedule_microtask.dart","google3:///third_party/dart_lang/v2/sdk/lib/async/stream.dart","google3:///third_party/dart_lang/v2/sdk/lib/async/stream_controller.dart","google3:///third_party/dart_lang/v2/sdk/lib/async/stream_impl.dart","google3:///third_party/dart_lang/v2/sdk/lib/async/stream_pipe.dart","google3:///third_party/dart_lang/v2/sdk/lib/_internal/js_runtime/lib/internal_patch.dart","google3:///third_party/dart_lang/v2/sdk/lib/_internal/js_runtime/lib/collection_patch.dart","google3:///third_party/dart_lang/v2/sdk/lib/_internal/js_runtime/lib/linked_hash_map.dart","google3:///third_party/dart_lang/v2/sdk/lib/collection/hash_map.dart","google3:///third_party/dart_lang/v2/sdk/lib/collection/iterable.dart","google3:///third_party/dart_lang/v2/sdk/lib/collection/linked_hash_map.dart","google3:///third_party/dart_lang/v2/sdk/lib/collection/linked_hash_set.dart","google3:///third_party/dart_lang/v2/sdk/lib/collection/maps.dart","google3:///third_party/dart_lang/v2/sdk/lib/collection/queue.dart","google3:///third_party/dart_lang/v2/sdk/lib/_internal/js_runtime/lib/convert_patch.dart","google3:///third_party/dart_lang/v2/sdk/lib/convert/base64.dart","google3:///third_party/dart_lang/v2/sdk/lib/convert/codec.dart","google3:///third_party/dart_lang/v2/sdk/lib/core/date_time.dart","google3:///third_party/dart_lang/v2/sdk/lib/core/list.dart","google3:///third_party/dart_lang/v2/sdk/lib/core/map.dart","google3:///third_party/dart_lang/v2/sdk/lib/core/print.dart","google3:///third_party/dart_lang/v2/sdk/lib/core/string.dart","google3:///third_party/dart_lang/v2/sdk/lib/core/uri.dart","google3:///third_party/dart_lang/v2/sdk/lib/convert/utf.dart","google3:///third_party/dart_lang/v2/sdk/lib/js_util/js_util.dart","google3:///third_party/dart_lang/v2/sdk/lib/_internal/js_runtime/lib/math_patch.dart","google3:///third_party/dart_lang/v2/sdk/lib/html/dart2js/html_dart2js.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.0.5/lib/src/span_scanner.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/source_span-1.5.5/lib/src/file.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_api/lib/src/remote_listener.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.0.0/lib/src/multi_channel.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.0.0/lib/src/stream_channel_controller.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_api/lib/src/suite_channel_manager.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.0.0/lib/src/guarantee_channel.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_api/lib/src/backend/stack_trace_formatter.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/path-1.6.4/lib/src/style.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/pool-1.4.0/lib/pool.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/async-2.4.0/lib/src/async_memoizer.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/source_map_stack_trace-1.1.5/lib/source_map_stack_trace.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.9.3/lib/src/chain.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.9.3/lib/src/trace.dart","google3:///third_party/dart_lang/v2/sdk/lib/core/stacktrace.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_api/lib/src/backend/group.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_api/lib/src/backend/metadata.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/collection-1.14.12/lib/src/unmodifiable_wrappers.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_api/lib/src/frontend/timeout.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_core/lib/src/runner/engine.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/async-2.4.0/lib/src/future_group.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/async-2.4.0/lib/src/stream_group.dart","google3:///third_party/dart_lang/v2/sdk/lib/async/broadcast_stream_controller.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/source_maps-0.10.8/lib/src/utils.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/collection-1.14.12/lib/src/functions.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/collection-1.14.12/lib/src/union_set_controller.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/collection-1.14.12/lib/src/union_set.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.9.3/lib/src/lazy_trace.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/package_resolver-1.0.10/lib/src/package_config_resolver.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/source_span-1.5.5/lib/src/location.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_api/lib/src/backend/live_test_controller.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_api/lib/src/util/test.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_api/lib/src/backend/invoker.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.0.5/lib/src/exception.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_api/lib/src/backend/platform_selector.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_api/lib/src/backend/suite_platform.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_core/lib/src/util/stack_trace_mapper.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/package_resolver-1.0.10/lib/src/package_root_resolver.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/source_maps-0.10.8/lib/src/vlq.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/source_maps-0.10.8/lib/parser.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test/lib/src/bootstrap/browser.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_core/lib/src/runner/plugin/remote_platform_helpers.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.0.0/lib/stream_channel.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/source_span-1.5.5/lib/src/span_exception.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_api/lib/src/frontend/expect.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.6/lib/src/description.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_api/lib/src/utils.dart","file:///usr/local/google/home/grouma/Projects/sample-test/test/main_test.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/path-1.6.4/lib/src/parsed_path.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/path-1.6.4/lib/src/path_exception.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/source_span-1.5.5/lib/src/span_with_context.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_api/lib/src/backend/declarer.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/boolean_selector-1.0.5/lib/src/ast.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/source_span-1.5.5/lib/src/highlighter.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.9.3/lib/src/stack_zone_specification.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.9.3/lib/src/lazy_chain.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_api/lib/src/backend/suite.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_core/lib/src/runner/suite.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_api/lib/src/util/remote_exception.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_core/lib/test_core.dart","","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_api/lib/src/backend/runtime.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_core/lib/src/runner/live_suite_controller.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/package_resolver-1.0.10/lib/src/utils.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/path-1.6.4/lib/src/utils.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/source_span-1.5.5/lib/src/utils.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.0.5/lib/src/utils.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/collection-1.14.12/lib/src/queue_list.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.6/lib/src/util.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.6/lib/src/core_matchers.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.6/lib/src/equals_matcher.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/path-1.6.4/lib/src/context.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/path-1.6.4/lib/path.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.6/lib/src/pretty_print.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.9.3/lib/src/frame.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.9.3/lib/src/unparsed_frame.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test/lib/src/runner/browser/post_message_channel.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_api/lib/src/backend/operating_system.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_api/lib/src/backend/closed_exception.dart","google3:///third_party/dart_lang/v2/sdk/lib/collection/list.dart","google3:///third_party/dart_lang/v2/sdk/lib/_internal/js_runtime/lib/js_number.dart","google3:///third_party/dart_lang/v2/sdk/lib/internal/list.dart","google3:///third_party/dart_lang/v2/sdk/lib/internal/symbol.dart","google3:///third_party/dart_lang/v2/sdk/lib/collection/collections.dart","google3:///third_party/dart_lang/v2/sdk/lib/collection/set.dart","google3:///third_party/dart_lang/v2/sdk/lib/convert/ascii.dart","google3:///third_party/dart_lang/v2/sdk/lib/convert/json.dart","google3:///third_party/dart_lang/v2/sdk/lib/core/object.dart","google3:///third_party/dart_lang/v2/sdk/lib/core/expando.dart","google3:///third_party/dart_lang/v2/sdk/lib/core/null.dart","google3:///third_party/dart_lang/v2/sdk/lib/core/stopwatch.dart","google3:///third_party/dart_lang/v2/sdk/lib/html/html_common/conversions_dart2js.dart","google3:///third_party/dart_lang/v2/sdk/lib/html/html_common/conversions.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/async-2.4.0/lib/src/delegate/stream_subscription.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/async-2.4.0/lib/src/null_stream_sink.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/async-2.4.0/lib/src/result/error.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/async-2.4.0/lib/src/result/value.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/async-2.4.0/lib/src/stream_completer.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/async-2.4.0/lib/src/stream_queue.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/async-2.4.0/lib/src/subscription_stream.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/async-2.4.0/lib/src/stream_sink_completer.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/boolean_selector-1.0.5/lib/src/all.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/boolean_selector-1.0.5/lib/src/evaluator.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/boolean_selector-1.0.5/lib/src/impl.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/boolean_selector-1.0.5/lib/src/intersection_selector.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/boolean_selector-1.0.5/lib/src/validator.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/boolean_selector-1.0.5/lib/src/none.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/boolean_selector-1.0.5/lib/src/parser.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/boolean_selector-1.0.5/lib/src/scanner.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.0.5/lib/src/string_scanner.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/boolean_selector-1.0.5/lib/src/token.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/boolean_selector-1.0.5/lib/src/visitor.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/collection-1.14.12/lib/src/empty_unmodifiable_set.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/collection-1.14.12/lib/src/wrappers.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.6/lib/src/feature_matcher.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.6/lib/src/interfaces.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.6/lib/src/type_matcher.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/path-1.6.4/lib/src/internal_style.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/path-1.6.4/lib/src/style/posix.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/path-1.6.4/lib/src/style/url.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/path-1.6.4/lib/src/style/windows.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/async-2.4.0/lib/src/restartable_timer.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/source_maps-0.10.8/lib/src/source_map_span.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.1.0/lib/src/generated/top_level.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.1.0/lib/term_glyph.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/source_span-1.5.5/lib/src/location_mixin.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/source_span-1.5.5/lib/src/span.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/source_span-1.5.5/lib/src/span_mixin.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.0.0/lib/src/stream_channel_completer.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.1.0/lib/src/generated/ascii_glyph_set.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.1.0/lib/src/generated/unicode_glyph_set.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_api/lib/src/backend/live_test.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_api/lib/src/backend/state.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_api/lib/src/backend/message.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_api/lib/src/util/iterable_set.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_core/lib/src/runner/runner_suite.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_core/lib/src/runner/reporter/expanded.dart","file:///usr/local/google/home/grouma/Projects/test/pkgs/test_core/lib/src/util/print_sink.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/async-2.4.0/lib/src/delegate/sink.dart","file:///usr/local/google/home/grouma/.pub-cache/hosted/pub.dartlang.org/async-2.4.0/lib/src/result/result.dart"],"names":["CastIterable","hexDigitValue","SubListIterable","MappedIterable","IterableElementError.noElement","IterableElementError.tooMany","IterableElementError.tooFew","ConstantMap._throwUnmodifiable","instantiate1","Instantiation1","unminifyOrTag","isJsIndexable","S","Primitives.objectHashCode","Primitives.parseInt","Primitives.objectTypeName","Primitives._objectTypeNameNewRti","Primitives._saneNativeClassName","Primitives.dateNow","Primitives.initTicker","Primitives.currentUri","Primitives._fromCharCodeApply","Primitives.stringFromCodePoints","Primitives.stringFromCharCodes","Primitives.stringFromNativeUint8List","Primitives.stringFromCharCode","Primitives.lazyAsJsDate","Primitives.getYear","Primitives.getMonth","Primitives.getDay","Primitives.getHours","Primitives.getMinutes","Primitives.getSeconds","Primitives.getMilliseconds","Primitives.getProperty","Primitives.setProperty","iae","ioore","diagnoseIndexError","diagnoseRangeError","argumentErrorValue","checkNum","wrapException","toStringWrapper","throwExpression","throwConcurrentModificationError","TypeErrorDecoder.extractPattern","TypeErrorDecoder.provokeCallErrorOn","TypeErrorDecoder.provokePropertyErrorOn","NullError","JsNoSuchMethodError","unwrapException","getTraceFromException","objectHashCode","fillLiteralMap","getLength","fillLiteralSet","invokeClosure","Exception","convertDartClosureToJS","Closure.fromTearOff","Closure._computeSignatureFunctionNewRti","Closure.cspForwardCall","Closure.forwardCallTo","Closure.cspForwardInterceptedCall","Closure.forwardInterceptedCallTo","closureFromTearOff","BoundClosure.evalRecipe","evalInInstance","BoundClosure.evalRecipeIntercepted","BoundClosure.selfOf","BoundClosure.receiverOf","BoundClosure.computeFieldNamed","boolConversionCheck","extractFunctionTypeObjectFromInternal","TypeErrorImplementation","_typeDescription","assertTest","assertThrow","assertHelper","throwCyclicInit","RuntimeError","getIsolateAffinityTag","setRuntimeTypeInfo","getRuntimeTypeInfo","getRuntimeTypeArguments","runtimeTypeToString","_runtimeTypeToString","_getRuntimeTypeAsString","getFutureOrArgument","_functionRtiToString","isInterestingBound","_joinArguments","getRuntimeType","_isClosure","substitute","computeSignature","invokeOn","defineProperty","lookupAndCacheInterceptor","patchProto","patchInteriorProto","makeLeafDispatchRecord","makeDefaultDispatchRecord","initNativeDispatch","initNativeDispatchContinue","lookupInterceptor","initHooks","applyHooksTransformer","JSSyntaxRegExp.makeNative","_MatchImplementation","stringContainsUnchecked","escapeReplacement","stringReplaceFirstRE","quoteStringForRegExp","stringReplaceAllUnchecked","stringReplaceAllUncheckedString","_stringIdentity","stringReplaceAllFuncUnchecked","_AllMatchesIterable.iterator","stringReplaceFirstUnchecked","stringReplaceRangeUnchecked","_ensureNativeList","NativeInt8List._create1","_checkValidIndex","_checkValidRange","Rti._getFutureFromFutureOr","Rti._isUnionOfFunctionType","Rti._getInterfaceTypeArguments","Rti._getBindingArguments","Rti._getFunctionParameters","Rti._getGenericFunctionBounds","Rti._getCanonicalRecipe","findType","instantiatedGenericFunctionType","_instantiate","_Universe._canonicalRecipeOfStar","_Universe._canonicalRecipeOfQuestion","_Universe._canonicalRecipeOfFutureOr","_instantiateArray","_instantiateNamed","_instantiateFunctionParameters","_FunctionParameters.allocate","closureFunctionType","instanceOrFunctionType","instanceType","_isDartObject","_arrayInstanceType","_instanceType","_instanceTypeFromConstructor","_instanceTypeFromConstructorMiss","getTypeFromTypesTable","createRuntimeType","typeLiteral","_installSpecializedIsTest","Rti._getInterfaceName","_generalIsTestImplementation","_isTestViaProperty","_generalAsCheckImplementation","_generalTypeCheckImplementation","checkTypeBound","_Error.compose","_CastError.fromMessage","_CastError.forType","_TypeError.fromMessage","_TypeError.forType","_isTop","_asTop","_isBool","_asBoolNullable","_checkBoolNullable","_asDoubleNullable","_checkDoubleNullable","_isInt","_asIntNullable","_checkIntNullable","_isNum","_asNumNullable","_checkNumNullable","_isString","_asStringNullable","_checkStringNullable","_rtiArrayToString","Rti._getReturnType","_rtiToString","Rti._getGenericFunctionParameterIndex","_unminifyOrTag","_Universe.findRule","_Universe.findErasedType","_Universe.addRules","_Universe.addErasedTypes","_Universe.eval","_Universe.evalInEnvironment","_Universe.bind","_Universe._parseRecipe","_Universe._finishRti","_Universe._lookupTerminalRti","Rti.allocate","_Universe._createTerminalRti","_Universe._lookupUnaryRti","_Universe._createUnaryRti","_Universe._lookupGenericFunctionParameterRti","_Universe._createGenericFunctionParameterRti","_Universe._canonicalRecipeJoin","_Universe._canonicalRecipeJoinNamed","_Universe._lookupInterfaceRti","_Universe._createInterfaceRti","_Universe._lookupBindingRti","_Universe._canonicalRecipeOfBinding","_Universe._createBindingRti","_Universe._lookupFunctionRti","_Universe._canonicalRecipeOfFunction","_Universe._createFunctionRti","_Universe._lookupGenericFunctionRti","_Universe._canonicalRecipeOfGenericFunction","_Universe._createGenericFunctionRti","_Parser.create","_Parser.parse","_Parser.pushStackFrame","_Parser.handleTypeArguments","_Parser.collectArray","_Parser.handleFunctionArguments","_Parser.handleOptionalGroup","_Parser.handleNamedGroup","_Parser.collectNamed","_Parser.handleDigit","_Parser.handleIdentifier","_Universe.evalTypeVariable","_Parser.handleExtendedOperations","_Parser.toType","_Parser.toTypes","_Parser.toTypesNamed","_Parser.indexToType","_isSubtype","Rti._getStarArgument","Rti._getGenericFunctionBase","_isFunctionSubtype","_isInterfaceSubtype","typeEqual","Rti._getBindingBase","typesEqual","namedTypesEqual","isLegacyTopType","isTopType","_Utils.objectAssign","extractKeys","unmangleGlobalNameIfPreservedAnyways","printString","makeDispatchRecord","getNativeInterceptor","JSArray.fixed","JSArray.markFixed","JSArray.markFixedList","JSString._isWhitespace","JSString._skipLeadingWhitespace","JSString._skipTrailingWhitespace","_AsyncRun._initializeScheduleImmediate","_AsyncRun._scheduleImmediateJsOverride","_AsyncRun._scheduleImmediateWithSetImmediate","_AsyncRun._scheduleImmediateWithTimer","Timer._createTimer","_TimerImpl","_TimerImpl.periodic","_makeAsyncAwaitCompleter","_AsyncAwaitCompleter._future","_Future","_asyncStartSync","_asyncAwait","_asyncReturn","_asyncRethrow","_awaitOnObject","_wrapJsFunctionForAsync","Future","Future.microtask","Future.sync","_Future.value","_Future.zoneValue","_nonNullError","Future.error","_Future.immediateError","Future.wait","Future.value","_Future.immediate","Future.forEach","JSArray.iterator","Future._kTrue","Future.doWhile","_completeWithErrorCallback","_Future._chainForeignFuture","_Future._setPendingComplete","_Future._chainCoreFuture","_Future._setChained","_Future._propagateToListeners","_Future._error","_Future._removeListeners","_Future._cloneResult","_Future._setErrorObject","_registerErrorHandler","_microtaskLoop","_startMicrotaskLoop","_scheduleAsyncCallback","_schedulePriorityAsyncCallback","scheduleMicrotask","Stream.fromFuture","_StreamController.stream","Stream.fromIterable","StreamIterator","StreamController","_runGuarded","_AddStreamState.makeErrorHandler","_BufferingStreamSubscription","_BufferingStreamSubscription._zone","_nullDataHandler","_nullErrorHandler","_nullDoneHandler","_runUserCode","_cancelAndError","_cancelAndErrorClosure","_cancelAndValue","Timer","_ZoneSpecification","Zone._enter","_parentDelegate","_rootHandleUncaughtError","_rootRun","_rootRunUnary","_rootRunBinary","_rootRegisterCallback","_rootRegisterUnaryCallback","_rootRegisterBinaryCallback","_rootErrorCallback","_rootScheduleMicrotask","_rootCreateTimer","_rootCreatePeriodicTimer","Timer._createPeriodicTimer","_rootPrint","_printToZone","_rootFork","_CustomZone","runZoned","_runZoned","HashMap","_HashMap._getTableEntry","_HashMap._setTableEntry","_HashMap._newHashTable","JsLinkedHashMap.es6","LinkedHashMap","LinkedHashMap._literal","LinkedHashMap._empty","LinkedHashSet","LinkedHashSet._empty","LinkedHashSet._literal","_LinkedHashSet._newHashTable","_LinkedHashSetIterator","HashMap.from","IterableBase.iterableToShortString","IterableBase.iterableToFullString","_isToStringVisiting","_iterablePartsToStrings","LinkedHashMap.from","LinkedHashSet.from","MapBase.mapToString","ListQueue","_ListQueueIterator","_parseJson","_convertJsonToDartLazy","Utf8Decoder._convertIntercepted","Utf8Decoder._convertInterceptedUint8List","Utf8Decoder._useTextDecoderChecked","Utf8Decoder._useTextDecoderUnchecked","Utf8Decoder._unsafe","Utf8Decoder._makeDecoder","_scanOneByteCharacters","Base64Codec._checkPadding","int.parse","Error._objectToString","List.filled","List.from","List.unmodifiable","String.fromCharCodes","String.fromCharCode","String._stringFromIterable","RegExp","StringBuffer._writeAll","Uri.base","_Uri._uriEncode","JSSyntaxRegExp.hasMatch","StringBuffer.writeCharCode","StackTrace.current","DateTime._fourDigits","DateTime._threeDigits","DateTime._twoDigits","Duration","Error.safeToString","AssertionError","ArgumentError","ArgumentError.value","ArgumentError.notNull","RangeError","RangeError.value","RangeError.range","RangeError.checkValueInInterval","RangeError.checkValidRange","RangeError.checkNotNegative","IndexError","UnsupportedError","UnimplementedError","StateError","ConcurrentModificationError","FormatException","List.generate","Map.castFrom","print","_combineSurrogatePair","Uri.parse","Uri.decodeComponent","Uri._parseIPv4Address","Uri.parseIPv6Address","NativeUint8List","_Uri.notSimple","_Uri","JSString.isNotEmpty","_Uri._defaultPort","_Uri._fail","_Uri.file","_Uri._checkNonWindowsPathReservedCharacters","_Uri._checkWindowsPathReservedCharacters","ListIterable.iterator","_Uri._checkWindowsDriveLetter","_Uri._makeFileUri","_Uri._makeWindowsFileUrl","_Uri._makePort","_Uri._makeHost","_Uri._checkZoneID","_Uri._normalizeZoneID","StringBuffer.write","_Uri._normalizeRegName","_Uri._makeScheme","_Uri._canonicalizeScheme","_Uri._makeUserInfo","_Uri._makePath","JSArray.map","_Uri._normalizePath","_Uri._makeQuery","_Uri._makeFragment","_Uri._normalizeEscape","_Uri._escapeChar","_Uri._normalizeOrSubstring","_Uri._normalize","_Uri._mayContainDotSegments","_Uri._removeDotSegments","JSArray.isNotEmpty","_Uri._normalizeRelativePath","_Uri._escapeScheme","_Uri._toWindowsFilePath","_Uri._hexCharPairToByte","_Uri._uriDecode","JSString.codeUnits","Utf8Codec.decode","_Uri._isAlphabeticCharacter","UriData._writeUri","UriData._validateMimeType","UriData._parse","UriData._uriEncodeBytes","_createTables","_scan","_convertDataTree","promiseToFuture","_Completer.future","Completer","max","pow","_EventStreamSubscription","_wrapZone","SpanScanner","SourceFile.decoded","SourceFile.fromString","RemoteListener.start","SuiteChannelManager","RemoteListener._deserializeSet","RemoteListener._sendLoadException","_MultiChannel.sink","RemoteListener._sendError","StackTraceFormatter.current","Style._getPlatformStyle","Pool","Pool._closeMemo","mapStackTrace","Trace","_prettifyMember","Group","Metadata._parseOnPlatform","Metadata._parseTags","Metadata","Metadata._","Metadata.parse","Metadata.deserialize","Metadata._deserializeTimeout","Engine","FutureGroup","Engine._onTestStartedGroup","StreamGroup.broadcast","StreamController.broadcast","Engine._group","binarySearch","mapMap","mergeMaps","UnionSetController","FileLocation._","_FileSpan","Trace.current","Trace.from","Trace.parse","Trace.parseVM","Trace._parseVM","ListIterable.map","Trace.parseV8","Trace.parseJSCore","WhereIterable.map","JSArray.where","Trace.parseFirefox","Trace.parseFriendly","PackageConfigResolver._normalizeMap","SourceLocation","LiveTestController","errorsDontStopTest","Invoker.current","StringScannerException","PlatformSelector.parse","PlatformSelector._wrapFormatException","SuitePlatform","JSStackTraceMapper.deserialize","JSStackTraceMapper._deserializePackageConfigMap","UnmodifiableSetView","decodeVlq","internalBootstrapBrowserTest","StreamChannelMixin.pipe","GuaranteeChannel.stream","SourceSpanFormatException","expect","_expect","Invoker.closed","Invoker._closable","_Completer.isCompleted","fail","formatFailure","prettyPrint","StringDescription._out","StringDescription.toString","StringBuffer.writeln","method1","method2","main","parseJsonExtended","parseJson","MultiSectionMapping.fromJson","MappingBundle.fromJson","SingleMapping.fromJson","ParsedPath.parse","PathException","SourceSpanWithContext","Declarer","Declarer._","Declarer._timeout","_expandSafe","Highlighter._normalizeNewlines","Highlighter._normalizeTrailingNewline","Highlighter._normalizeEndOfLine","Highlighter._lastLineLength","Chain.capture","Expando","StackZoneSpecification._chains","Chain.current","Chain._currentSpec","StackZoneSpecification.currentChain","StackZoneSpecification._createNode","Chain.forTrace","Chain.parse","Invoker.guard","Suite._filterGroup","Group.root","SuiteConfiguration._list","SuiteConfiguration._map","RemoteException.serialize","_declarer","Declarer.current","test","group","StreamChannelController","_StreamController.sink","Runtime.deserialize","indent","toSentence","pluralize","prefixLines","LiveSuiteController","LiveSuiteController._onCompleteGroup","LiveSuiteController._closeMemo","asUri","ensureTrailingSlash","JSArray.toList","isAlphabetic","isDriveLetter","countCodeUnits","ListMixin.iterator","findLineStart","validateErrorArgs","QueueList","QueueList._nextPowerOf2","wrapMatcher","predicate","equals","escape","_getHexLiteral","JSString.runes","Context","_parseUri","_validateArgList","_StringEqualsMatcher._writeLeading","_StringEqualsMatcher._writeTrailing","_MultiChannel","current","_typeName","_escapeString","Frame.parseVM","Frame.parseV8","Frame.parseFirefox","Frame.parseFriendly","Frame._uriOrPathToUri","Frame._catchFormatException","UnparsedFrame","postMessageChannel","EventStreamProvider.forTarget","OperatingSystem.find","GuaranteeChannel","ClosedException","Interceptor.hashCode","Interceptor.==","Interceptor.toString","Interceptor.runtimeType","JSBool.toString","JSBool.hashCode","JSBool.runtimeType","JSNull.==","JSNull.toString","JSNull.hashCode","JSNull.runtimeType","JavaScriptObject.hashCode","JavaScriptObject.runtimeType","JavaScriptObject.toString","JavaScriptFunction.toString","JSArray.add","JSArray.removeAt","JSArray.insert","JSArray.insertAll","JSArray.removeLast","JSArray.remove","JSArray.addAll","JSArray.forEach","JSArray.join","JSArray.join[function-entry$0]","JSArray.fold","JSArray.firstWhere","JSArray.firstWhere[function-entry$1]","JSArray.elementAt","JSArray.sublist","JSArray.first","JSArray.last","JSArray.single","JSArray.setRange","JSArray.setRange[function-entry$3]","JSArray.fillRange","JSArray.replaceRange","JSArray.contains","JSArray.isEmpty","JSArray.toString","JSArray.toSet","JSArray.hashCode","JSArray.length","JSArray.[]","JSArray.[]=","ArrayIterator.current","ArrayIterator.moveNext","ArrayIterator._current","JSNumber.floor","JSNumber.round","JSNumber.toRadixString","JSNumber.toString","JSNumber.hashCode","JSNumber.%","JSNumber.~/","JSNumber._tdivFast","JSNumber._tdivSlow","JSNumber._shlPositive","JSNumber._shrOtherPositive","JSNumber._shrReceiverPositive","JSNumber._shrBothPositive","JSNumber.runtimeType","JSInt.runtimeType","JSDouble.runtimeType","JSString.codeUnitAt","JSString._codeUnitAt","JSString.allMatches","allMatchesInStringUnchecked","JSString.allMatches[function-entry$1]","JSString.matchAsPrefix","JSString.+","JSString.endsWith","JSString.splitMapJoin","JSString.replaceFirst","JSString.replaceRange","JSString.startsWith","JSString.startsWith[function-entry$1]","JSString.substring","JSString.substring[function-entry$1]","JSString.trim","JSString.*","JSString.padLeft","JSString.padRight","JSString.indexOf","JSString.indexOf[function-entry$1]","JSString.lastIndexOf","JSString.lastIndexOf[function-entry$1]","JSString.contains","JSString.toString","JSString.hashCode","JSString.runtimeType","JSString.length","JSString.[]","_CastIterableBase.iterator","_CastIterableBase.length","_CastIterableBase.isEmpty","_CastIterableBase.first","_CastIterableBase.last","_CastIterableBase.contains","_CastIterableBase.toString","CastIterator.moveNext","CastIterator.current","CastMap.cast","CastMap.containsKey","CastMap.[]","CastMap.remove","CastMap.forEach","CastMap.keys","CastMap.length","CastMap.isEmpty","CastMap.forEach.<anonymous function>","CastMap_forEach_closure","CodeUnits.[]","CodeUnits.length","ListIterable.isEmpty","ListIterable.first","ListIterable.last","ListIterable.contains","ListIterable.join","ListIterable.join[function-entry$0]","ListIterable.fold","ListIterable.toList","ListIterable.toList[function-entry$0]","ListIterable.toSet","SubListIterable._endIndex","SubListIterable._startIndex","SubListIterable.length","SubListIterable.elementAt","SubListIterable.take","ListIterator.current","ListIterator.moveNext","ListIterator._current","MappedIterable.iterator","MappedIterable.length","MappedIterable.isEmpty","MappedIterable.first","MappedIterable.last","MappedIterator.moveNext","MappedIterator.current","MappedIterator._current","MappedListIterable.length","MappedListIterable.elementAt","WhereIterable.iterator","WhereIterator.moveNext","WhereIterator.current","ExpandIterable.iterator","ExpandIterator","ExpandIterator.current","ExpandIterator.moveNext","ExpandIterator._currentExpansion","ExpandIterator._current","SkipWhileIterable.iterator","SkipWhileIterator.moveNext","SkipWhileIterator.current","EmptyIterator.moveNext","EmptyIterator.current","FixedLengthListMixin.length","UnmodifiableListMixin.[]=","UnmodifiableListMixin.length","ReversedListIterable.length","ReversedListIterable.elementAt","Symbol.hashCode","Symbol.toString","Symbol.==","ConstantMap.cast","ConstantMap.isEmpty","ConstantMap.toString","ConstantMap.remove","ConstantMap.map","ConstantMap.map.<anonymous function>","ConstantMap_map_closure","ConstantStringMap.length","ConstantStringMap.containsKey","ConstantStringMap.[]","ConstantStringMap._fetch","ConstantStringMap.forEach","ConstantStringMap.keys","_ConstantMapKeyIterable.iterator","_ConstantMapKeyIterable.length","Instantiation","Instantiation.toString","Primitives.initTicker.<anonymous function>","TypeErrorDecoder.matchTypeError","NullError.toString","JsNoSuchMethodError.toString","UnknownJsTypeError.toString","unwrapException.saveStackTrace","_StackTrace.toString","Closure.toString","StaticClosure.toString","BoundClosure.==","BoundClosure.hashCode","BoundClosure.toString","TypeErrorImplementation.toString","RuntimeError.toString","_AssertionError.toString","JsLinkedHashMap.keys","JsLinkedHashMap.length","JsLinkedHashMap.isEmpty","JsLinkedHashMap.values","JsLinkedHashMap.containsKey","JsLinkedHashMap.internalContainsKey","JsLinkedHashMap.addAll","JsLinkedHashMap.[]","JsLinkedHashMap.internalGet","JsLinkedHashMap.[]=","JsLinkedHashMap.internalSet","JsLinkedHashMap.putIfAbsent","JsLinkedHashMap.remove","JsLinkedHashMap.internalRemove","JsLinkedHashMap.clear","JsLinkedHashMap.forEach","JsLinkedHashMap._addHashTableEntry","JsLinkedHashMap._removeHashTableEntry","JsLinkedHashMap._modified","JsLinkedHashMap._newLinkedCell","JsLinkedHashMap._unlinkCell","JsLinkedHashMap.internalComputeHashCode","JsLinkedHashMap.internalFindBucketIndex","JsLinkedHashMap.toString","JsLinkedHashMap._getTableCell","JsLinkedHashMap._getTableBucket","JsLinkedHashMap._setTableEntry","JsLinkedHashMap._deleteTableEntry","JsLinkedHashMap._containsTableEntry","JsLinkedHashMap._newHashTable","JsLinkedHashMap.values.<anonymous function>","JsLinkedHashMap_values_closure","JsLinkedHashMap.addAll.<anonymous function>","JsLinkedHashMap_addAll_closure","LinkedHashMapKeyIterable.length","LinkedHashMapKeyIterable.isEmpty","LinkedHashMapKeyIterable.iterator","LinkedHashMapKeyIterable.contains","LinkedHashMapKeyIterator","LinkedHashMapKeyIterator.current","LinkedHashMapKeyIterator.moveNext","LinkedHashMapKeyIterator._current","initHooks.<anonymous function>","JSSyntaxRegExp.toString","JSSyntaxRegExp._nativeGlobalVersion","JSSyntaxRegExp._nativeAnchoredVersion","JSSyntaxRegExp.firstMatch","JSSyntaxRegExp.allMatches","JSSyntaxRegExp.allMatches[function-entry$1]","JSSyntaxRegExp._execGlobal","JSSyntaxRegExp._execAnchored","JSSyntaxRegExp.matchAsPrefix","_MatchImplementation.start","_MatchImplementation.end","_MatchImplementation.[]","_AllMatchesIterator.current","_AllMatchesIterator.moveNext","JSSyntaxRegExp.isUnicode","StringMatch.end","StringMatch.[]","_StringAllMatchesIterable.iterator","_StringAllMatchesIterable.first","_StringAllMatchesIterator.moveNext","_StringAllMatchesIterator.current","NativeByteBuffer.runtimeType","NativeByteData.runtimeType","NativeTypedArray.length","NativeTypedArrayOfDouble.[]","NativeTypedArrayOfDouble.[]=","NativeTypedArrayOfInt.[]=","NativeFloat32List.runtimeType","NativeFloat64List.runtimeType","NativeInt16List.runtimeType","NativeInt16List.[]","NativeInt32List.runtimeType","NativeInt32List.[]","NativeInt8List.runtimeType","NativeInt8List.[]","NativeUint16List.runtimeType","NativeUint16List.[]","NativeUint32List.runtimeType","NativeUint32List.[]","NativeUint32List.sublist","NativeUint8ClampedList.runtimeType","NativeUint8ClampedList.length","NativeUint8ClampedList.[]","NativeUint8List.runtimeType","NativeUint8List.length","NativeUint8List.[]","NativeUint8List.sublist","Rti._eval","Rti._bind","_Type.hashCode","_Type.==","_Type.toString","_Error.toString","_TypeError.message","_AsyncRun._initializeScheduleImmediate.internalCallback","_AsyncRun._initializeScheduleImmediate.<anonymous function>","_AsyncRun._scheduleImmediateJsOverride.internalCallback","_AsyncRun._scheduleImmediateWithSetImmediate.internalCallback","_TimerImpl.cancel","_TimerImpl.internalCallback","_TimerImpl.periodic.<anonymous function>","_AsyncAwaitCompleter.complete","_AsyncAwaitCompleter.completeError","_awaitOnObject.<anonymous function>","_wrapJsFunctionForAsync.<anonymous function>","_BroadcastStream.isBroadcast","_BroadcastSubscription._onPause","_BroadcastSubscription._onResume","_BroadcastSubscription._next","_BroadcastSubscription._previous","_BroadcastStreamController._mayAddEvent","_BroadcastStreamController._ensureDoneFuture","_BroadcastStreamController._removeListener","_BroadcastStreamController._subscribe","_DoneStreamSubscription","_BroadcastSubscription","_BroadcastStreamController._recordCancel","_BroadcastStreamController._recordPause","_BroadcastStreamController._recordResume","_BroadcastStreamController._addEventError","_BroadcastStreamController.add","_BroadcastStreamController.addError","_BroadcastStreamController.addError[function-entry$1]","_BroadcastStreamController.close","_BroadcastStreamController._addError","_BroadcastStreamController._close","_BroadcastStreamController._forEachListener","_BroadcastStreamController._callOnCancel","_BroadcastStreamController._firstSubscription","_BroadcastStreamController._lastSubscription","_BroadcastStreamController._addStreamState","_SyncBroadcastStreamController._mayAddEvent","_SyncBroadcastStreamController._addEventError","_SyncBroadcastStreamController._sendData","_SyncBroadcastStreamController._sendError","_SyncBroadcastStreamController._sendDone","_SyncBroadcastStreamController._sendData.<anonymous function>","_SyncBroadcastStreamController__sendData_closure","_SyncBroadcastStreamController._sendError.<anonymous function>","_SyncBroadcastStreamController__sendError_closure","_SyncBroadcastStreamController._sendDone.<anonymous function>","_SyncBroadcastStreamController__sendDone_closure","_AsyncBroadcastStreamController._sendData","_AsyncBroadcastStreamController._sendError","_AsyncBroadcastStreamController._sendDone","Future.<anonymous function>","Future.microtask.<anonymous function>","Future.wait.handleError","Future.wait.<anonymous function>","Future_wait_closure","Future.forEach.<anonymous function>","Future.doWhile.<anonymous function>","_asyncCompleteWithErrorCallback","TimeoutException.toString","_Completer.completeError","_Completer.completeError[function-entry$1]","_AsyncCompleter.complete","_AsyncCompleter.complete[function-entry$0]","_AsyncCompleter._completeError","_SyncCompleter.complete","_SyncCompleter.complete[function-entry$0]","_SyncCompleter._completeError","_FutureListener.matchesErrorTest","_FutureListener.handleError","_FutureListener.hasErrorCallback","_Future.then","_Future.then[function-entry$1]","_Future._thenAwait","_Future.catchError","_Future.whenComplete","_Future._addListener","_Future._prependListeners","_Future._reverseListeners","_Future._complete","_Future._setValue","_Future._completeWithValue","_Future._completeError","_Future._setError","_Future._completeError[function-entry$1]","_Future._asyncComplete","_Future._chainFuture","_Future._asyncCompleteError","_Future._addListener.<anonymous function>","_Future._prependListeners.<anonymous function>","_Future._chainForeignFuture.<anonymous function>","_Future._clearPendingComplete","_Future._chainForeignFuture[function-entry$1].<anonymous function>","_Future._asyncComplete.<anonymous function>","_Future._chainFuture.<anonymous function>","_Future._asyncCompleteError.<anonymous function>","_Future._propagateToListeners.handleWhenCompleteCallback","_FutureListener.handleWhenComplete","_Future._propagateToListeners.handleWhenCompleteCallback.<anonymous function>","_Future._propagateToListeners.handleValueCallback","_FutureListener.handleValue","_FutureListener._onValue","_Future._propagateToListeners.handleError","Stream.isBroadcast","Stream.pipe","Stream.length","Stream.first","Stream.last","Stream.firstWhere","Stream.fromFuture.<anonymous function>","Stream_Stream$fromFuture_closure","Stream.fromIterable.<anonymous function>","_IterablePendingEvents","Stream_Stream$fromIterable_closure","Stream.pipe.<anonymous function>","Stream.length.<anonymous function>","Stream_length_closure","Stream.first.<anonymous function>","Stream_first_closure","Stream.last.<anonymous function>","Stream_last_closure","Stream.firstWhere.<anonymous function>","Stream_firstWhere_closure","Stream.firstWhere.<anonymous function>.<anonymous function>","_StreamController._pendingEvents","_StreamController._ensurePendingEvents","_StreamController._subscription","_StreamController._badEventState","_StreamController.addStream","_AddStreamState","_StreamControllerAddStreamState","_StreamController.isPaused","_StreamController._ensureDoneFuture","_StreamController.add","_StreamController.addError","_StreamController.addError[function-entry$1]","_StreamController.close","_StreamController._closeUnchecked","_StreamController._add","_StreamController._addError","_StreamController._close","_StreamController._subscribe","_ControllerSubscription","_StreamController._recordCancel","_StreamController._recordPause","_StreamController._recordResume","_StreamController._subscribe.<anonymous function>","_StreamController._recordCancel.complete","_SyncStreamControllerDispatch._sendData","_SyncStreamControllerDispatch._sendError","_SyncStreamControllerDispatch._sendDone","_AsyncStreamControllerDispatch._sendData","_AsyncStreamControllerDispatch._sendError","_AsyncStreamControllerDispatch._sendDone","_ControllerStream._createSubscription","_ControllerStream.hashCode","_ControllerStream.==","_ControllerSubscription._onCancel","_ControllerSubscription._onPause","_ControllerSubscription._onResume","_StreamSinkWrapper.add","_AddStreamState.cancel","_AddStreamState.makeErrorHandler.<anonymous function>","_AddStreamState.cancel.<anonymous function>","_BufferingStreamSubscription._setPendingEvents","_BufferingStreamSubscription.onData","_BufferingStreamSubscription.onError","_BufferingStreamSubscription.onDone","_BufferingStreamSubscription.pause","_BufferingStreamSubscription.pause[function-entry$0]","_BufferingStreamSubscription.resume","_BufferingStreamSubscription.cancel","_BufferingStreamSubscription._mayResumeInput","_BufferingStreamSubscription.isPaused","_BufferingStreamSubscription._cancel","_BufferingStreamSubscription._add","_BufferingStreamSubscription._addError","_BufferingStreamSubscription._close","_BufferingStreamSubscription._onPause","_BufferingStreamSubscription._onResume","_BufferingStreamSubscription._onCancel","_BufferingStreamSubscription._addPending","_BufferingStreamSubscription._sendData","_BufferingStreamSubscription._sendError","_BufferingStreamSubscription._sendDone","_BufferingStreamSubscription._guardCallback","_BufferingStreamSubscription._checkState","_BufferingStreamSubscription._onData","_BufferingStreamSubscription._onDone","_BufferingStreamSubscription._pending","_BufferingStreamSubscription._sendError.sendError","_BufferingStreamSubscription._sendDone.sendDone","_StreamImpl.listen","_StreamImpl.listen[function-entry$1$onDone]","_StreamImpl.listen[function-entry$1$onDone$onError]","_StreamImpl.listen[function-entry$1]","_StreamImpl._createSubscription","_GeneratedStreamImpl._createSubscription","_IterablePendingEvents.isEmpty","_IterablePendingEvents.handleNext","_IterablePendingEvents._iterator","_DelayedEvent.next","_DelayedData.perform","_DelayedError.perform","_DelayedDone.perform","_DelayedDone.next","_PendingEvents.schedule","_PendingEvents.schedule.<anonymous function>","_StreamImplEvents.isEmpty","_StreamImplEvents.add","_StreamImplEvents.handleNext","_DoneStreamSubscription.isPaused","_DoneStreamSubscription._schedule","_DoneStreamSubscription.onData","_DoneStreamSubscription.onError","_DoneStreamSubscription.onDone","_DoneStreamSubscription.pause","_DoneStreamSubscription.pause[function-entry$0]","_DoneStreamSubscription.resume","_DoneStreamSubscription.cancel","_DoneStreamSubscription._sendDone","_DoneStreamSubscription._onDone","_EmptyStream.isBroadcast","_EmptyStream.listen","_EmptyStream.listen[function-entry$1$onDone$onError]","_EmptyStream.listen[function-entry$1]","_cancelAndError.<anonymous function>","_cancelAndErrorClosure.<anonymous function>","_cancelAndValue.<anonymous function>","AsyncError.toString","_ZoneDelegate.handleUncaughtError","_ZoneDelegate.registerCallback","_ZoneDelegate.registerUnaryCallback","_ZoneDelegate.registerBinaryCallback","_ZoneDelegate.errorCallback","_CustomZone._delegate","_CustomZone.errorZone","_CustomZone.runGuarded","_CustomZone.runUnaryGuarded","_CustomZone.runBinaryGuarded","_CustomZone.bindCallback","_CustomZone.bindUnaryCallback","_CustomZone.bindCallbackGuarded","_CustomZone.bindUnaryCallbackGuarded","_CustomZone.[]","_CustomZone.handleUncaughtError","_CustomZone.fork","_CustomZone.run","_CustomZone.runUnary","_CustomZone.runBinary","_CustomZone.registerCallback","_CustomZone.registerUnaryCallback","_CustomZone.registerBinaryCallback","_CustomZone.errorCallback","_CustomZone.scheduleMicrotask","_CustomZone.createTimer","_CustomZone.print","_CustomZone._run","_CustomZone._runUnary","_CustomZone._runBinary","_CustomZone._registerCallback","_CustomZone._registerUnaryCallback","_CustomZone._registerBinaryCallback","_CustomZone._errorCallback","_CustomZone._scheduleMicrotask","_CustomZone._createTimer","_CustomZone._createPeriodicTimer","_CustomZone._print","_CustomZone._fork","_CustomZone._handleUncaughtError","_CustomZone.bindCallback.<anonymous function>","_CustomZone_bindCallback_closure","_CustomZone.bindUnaryCallback.<anonymous function>","_CustomZone_bindUnaryCallback_closure","_CustomZone.bindCallbackGuarded.<anonymous function>","_CustomZone.bindUnaryCallbackGuarded.<anonymous function>","_CustomZone_bindUnaryCallbackGuarded_closure","_rootHandleUncaughtError.<anonymous function>","_RootZone._map","_RootZone._run","_RootZone._runUnary","_RootZone._runBinary","_RootZone._registerCallback","_RootZone._registerUnaryCallback","_RootZone._registerBinaryCallback","_RootZone._errorCallback","_RootZone._scheduleMicrotask","_RootZone._createTimer","_RootZone._createPeriodicTimer","_RootZone._print","_RootZone._fork","_RootZone._handleUncaughtError","_RootZone.parent","_RootZone._delegate","_RootZone.errorZone","_RootZone.runGuarded","_RootZone.runUnaryGuarded","_RootZone.runBinaryGuarded","_RootZone.bindCallback","_RootZone.bindCallbackGuarded","_RootZone.bindUnaryCallbackGuarded","_RootZone.[]","_RootZone.handleUncaughtError","_RootZone.fork","_RootZone.run","_RootZone.runUnary","_RootZone.runBinary","_RootZone.registerCallback","_RootZone.registerUnaryCallback","_RootZone.registerBinaryCallback","_RootZone.errorCallback","_RootZone.scheduleMicrotask","_RootZone.createTimer","_RootZone.print","_RootZone.bindCallback.<anonymous function>","_RootZone_bindCallback_closure","_RootZone.bindCallbackGuarded.<anonymous function>","_RootZone.bindUnaryCallbackGuarded.<anonymous function>","_RootZone_bindUnaryCallbackGuarded_closure","runZoned.<anonymous function>","_HashMap.keys","_HashMap.length","_HashMap.isEmpty","_HashMap.containsKey","_HashMap._containsKey","_HashMap.[]","_HashMap._get","_HashMap.[]=","_HashMap._set","_HashMap.remove","_HashMap._remove","_HashMap.forEach","_HashMap._computeKeys","_HashMap._addHashTableEntry","_HashMap._computeHashCode","_HashMap._getBucket","_HashMap._findBucketIndex","_IdentityHashMap._computeHashCode","_IdentityHashMap._findBucketIndex","_HashMapKeyIterable.length","_HashMapKeyIterable.isEmpty","_HashMapKeyIterable.iterator","_HashMapKeyIterable.contains","_HashMapKeyIterator.current","_HashMapKeyIterator.moveNext","_HashMapKeyIterator._current","_LinkedHashSet._newSet","_LinkedHashSet.iterator","_LinkedHashSet.length","_LinkedHashSet.isEmpty","_LinkedHashSet.contains","_LinkedHashSet._contains","_LinkedHashSet.first","_LinkedHashSet.last","_LinkedHashSet.add","_LinkedHashSet._add","_LinkedHashSet.remove","_LinkedHashSet._remove","_LinkedHashSet._addHashTableEntry","_LinkedHashSet._removeHashTableEntry","_LinkedHashSet._modified","_LinkedHashSet._newLinkedCell","_LinkedHashSet._unlinkCell","_LinkedHashSet._computeHashCode","_LinkedHashSet._findBucketIndex","_LinkedHashSetIterator.current","_LinkedHashSetIterator.moveNext","_LinkedHashSetIterator._current","UnmodifiableListView.length","UnmodifiableListView.[]","HashMap.from.<anonymous function>","LinkedHashMap.from.<anonymous function>","ListMixin.elementAt","ListMixin.isEmpty","ListMixin.first","ListMixin.last","ListMixin.map","ListMixin.toList","ListMixin.toList[function-entry$0]","ListMixin.toSet","ListMixin.remove","ListMixin._closeGap","ListMixin.fillRange","ListMixin.toString","MapBase.mapToString.<anonymous function>","MapMixin.cast","MapMixin.forEach","MapMixin.map","MapMixin.containsKey","MapMixin.length","MapMixin.isEmpty","MapMixin.toString","_UnmodifiableMapMixin.remove","MapView.cast","MapView.[]","MapView.containsKey","MapView.forEach","MapView.isEmpty","MapView.length","MapView.keys","MapView.remove","MapView.toString","MapView.map","UnmodifiableMapView.cast","ListQueue.iterator","ListQueue.isEmpty","ListQueue.length","ListQueue.first","ListQueue.last","ListQueue.elementAt","ListQueue.clear","ListQueue.toString","ListQueue.removeFirst","ListQueue._add","ListQueue._table","_ListQueueIterator.current","_ListQueueIterator.moveNext","_ListQueueIterator._current","SetMixin.isEmpty","SetMixin.map","SetMixin.toString","SetMixin.every","SetMixin.first","SetMixin.last","_SetBase.toSet","_SetBase.isEmpty","_SetBase.addAll","_SetBase.union","_SetBase.toList","_SetBase.toList[function-entry$0]","_SetBase.map","_SetBase.toString","_SetBase.where","_SetBase.fold","_SetBase.every","_SetBase.any","_SetBase.first","_SetBase.last","_JsonMap.[]","_JsonMap.length","_JsonMap.isEmpty","_JsonMap.keys","_JsonMap.containsKey","_JsonMap.remove","_JsonMap.forEach","_JsonMap._upgradedMap","_JsonMap._computeKeys","_JsonMap._upgrade","_JsonMap._process","_JsonMapKeyIterable.length","_JsonMapKeyIterable.elementAt","_JsonMapKeyIterable.iterator","_JsonMapKeyIterable.contains","AsciiCodec.encode","_UnicodeSubsetEncoder.convert","Base64Codec.normalize","JsonCodec.decode","JsonCodec.decoder","Utf8Codec.encoder","Utf8Encoder.convert","_Utf8Encoder._writeSurrogate","_Utf8Encoder._fillBuffer","Utf8Decoder.convert","_Utf8Decoder.flush","_Utf8Decoder.convert","DateTime.==","DateTime.hashCode","DateTime.toString","Duration.==","Duration.hashCode","Duration.toString","Duration.unary-","Duration.toString.sixDigits","Duration.toString.twoDigits","AssertionError.toString","NullThrownError.toString","ArgumentError._errorName","ArgumentError._errorExplanation","ArgumentError.toString","RangeError._errorName","RangeError._errorExplanation","IndexError._errorName","IndexError._errorExplanation","UnsupportedError.toString","UnimplementedError.toString","StateError.toString","ConcurrentModificationError.toString","OutOfMemoryError.toString","StackOverflowError.toString","CyclicInitializationError.toString","_Exception.toString","FormatException.toString","Expando.[]","Expando.[]=","Expando._setOnObject","Expando.toString","Iterable.map","Iterable.where","Iterable.contains","Iterable.join","Iterable.join[function-entry$0]","Iterable.toList","Iterable.toList[function-entry$0]","Iterable.toSet","Iterable.length","Iterable.isEmpty","Iterable.skipWhile","Iterable.first","Iterable.last","Iterable.elementAt","Iterable.toString","MapEntry.toString","Null.hashCode","Null.toString","Object.hashCode","Object.==","Object.toString","Object.runtimeType","_StringStackTrace.toString","Stopwatch.elapsedMicroseconds","Stopwatch.elapsedTicks","Runes.iterator","Runes.last","RuneIterator.current","RuneIterator.moveNext","StringBuffer.length","StringBuffer.toString","Uri._parseIPv4Address.error","Uri.parseIPv6Address.error","Uri.parseIPv6Address[function-entry$1].error","Uri.parseIPv6Address.parseHex","_Uri.userInfo","_Uri.host","_Uri.port","_Uri.query","_Uri.fragment","_Uri.replace","_Uri.replace[function-entry$0$path]","_Uri.replace[function-entry$0$pathSegments]","_Uri.pathSegments","_Uri._mergePaths","_Uri.resolve","_Uri.resolveUri","_Uri.hasEmptyPath","_Uri.hasAuthority","_Uri.hasPort","_Uri.hasQuery","_Uri.hasFragment","_Uri.hasAbsolutePath","_Uri.toFilePath","_Uri._toFilePath","_Uri.toString","_Uri._initializeText","_Uri._writeAuthority","_Uri.==","_Uri.hashCode","_Uri._pathSegments","_Uri.notSimple.<anonymous function>","_Uri._checkNonWindowsPathReservedCharacters.<anonymous function>","_Uri._makePath.<anonymous function>","UriData.uri","UriData.toString","_createTables.<anonymous function>","_createTables.build","_createTables.setChars","_createTables.setRange","_SimpleUri._isFile","_SimpleUri.hasAuthority","_SimpleUri.hasPort","_SimpleUri.hasQuery","_SimpleUri.hasFragment","_SimpleUri._isHttp","_SimpleUri._isHttps","_SimpleUri.hasAbsolutePath","_SimpleUri.scheme","_SimpleUri.userInfo","_SimpleUri.host","_SimpleUri.port","_SimpleUri.path","_SimpleUri.query","_SimpleUri.fragment","_SimpleUri.pathSegments","_SimpleUri._isPort","_SimpleUri.removeFragment","_SimpleUri.replace","_SimpleUri.replace[function-entry$0$path]","_SimpleUri.replace[function-entry$0$pathSegments]","_SimpleUri.resolve","_SimpleUri.resolveUri","_SimpleUri._simpleMerge","_SimpleUri.toFilePath","_SimpleUri._toFilePath","_SimpleUri.hashCode","_SimpleUri.==","_SimpleUri._toNonSimple","_SimpleUri.toString","DomException.toString","EventTarget.addEventListener","EventTarget._addEventListener","EventTarget._removeEventListener","Location.origin","Location.toString","MessagePort.addEventListener","MessagePort.postMessage","convertDartToNative_PrepareForStructuredClone","_EventStream.isBroadcast","_EventStream.listen","_EventStream.listen[function-entry$1$onDone$onError]","_EventStream.listen[function-entry$1]","_EventStreamSubscription.cancel","_EventStreamSubscription.pause","_EventStreamSubscription.pause[function-entry$0]","_EventStreamSubscription.resume","_EventStreamSubscription._tryResume","_EventStreamSubscription._unlisten","_EventStreamSubscription._onData","_EventStreamSubscription.<anonymous function>","_StructuredClone.findSlot","_StructuredClone.walk","convertDartToNative_DateTime","_StructuredClone.copyList","_StructuredClone.walk.<anonymous function>","_AcceptStructuredClone.findSlot","_AcceptStructuredClone.walk","DateTime._withValue","convertNativeToDart_DateTime","_AcceptStructuredClone.convertNativeToDart_AcceptStructuredClone","_AcceptStructuredClone.walk.<anonymous function>","_StructuredCloneDart2Js.forEachObjectKey","_AcceptStructuredCloneDart2Js.forEachJsField","_convertDataTree._convert","promiseToFuture.<anonymous function>","AsyncMemoizer.runOnce","AsyncMemoizer.hasRun","DelegatingStreamSubscription.onData","DelegatingStreamSubscription.onError","DelegatingStreamSubscription.onDone","DelegatingStreamSubscription.pause","DelegatingStreamSubscription.pause[function-entry$0]","DelegatingStreamSubscription.resume","DelegatingStreamSubscription.cancel","FutureGroup.add","FutureGroup.close","FutureGroup.add.<anonymous function>","FutureGroup_add_closure","NullStreamSink.add","NullStreamSink.addStream","NullStreamSink._checkEventAllowed","NullStreamSink.close","NullStreamSink.addStream.<anonymous function>","ErrorResult.complete","ErrorResult.addTo","ErrorResult.hashCode","ErrorResult.==","ValueResult.complete","ValueResult.addTo","ValueResult.hashCode","ValueResult.==","StreamCompleter.setSourceStream","_CompleterStream.listen","_CompleterStream.listen[function-entry$1$onDone$onError]","_CompleterStream.listen[function-entry$1]","_CompleterStream._linkStreamToController","_CompleterStream._createController","_CompleterStream._controller","_CompleterStream._sourceStream","StreamGroup.add","StreamGroup._onListen","StreamGroup._onCancelBroadcast","StreamGroup._listenToStream","StreamGroup.close","StreamGroup._controller","StreamGroup.add.<anonymous function>","StreamGroup_add_closure","StreamGroup._onListen.<anonymous function>","StreamGroup__onListen_closure","StreamGroup._onCancelBroadcast.<anonymous function>","StreamGroup__onCancelBroadcast_closure","StreamGroup._listenToStream.<anonymous function>","_StreamGroupState.toString","StreamQueue.next","StreamQueue._updateRequests","StreamQueue._extractStream","SubscriptionStream","StreamQueue._ensureListening","StreamQueue._addResult","StreamQueue._failClosed","StreamQueue._addRequest","StreamQueue._subscription","StreamQueue._ensureListening.<anonymous function>","StreamQueue__ensureListening_closure","Result.error","_NextRequest.update","ListMixin.isNotEmpty","_RestRequest.update","StreamCompleter.setEmpty","_CompleterStream._setEmpty","_CompleterSink._canSendDirectly","_CompleterSink.done","Completer.sync","_CompleterSink.addStream","_CompleterSink.close","_CompleterSink._ensureController","_CompleterSink._setDestinationSink","_CompleterSink._controller","_CompleterSink._destinationSink","_CompleterSink._setDestinationSink.<anonymous function>","SubscriptionStream.listen","SubscriptionStream.listen[function-entry$1$onDone$onError]","SubscriptionStream.listen[function-entry$1]","SubscriptionStream._source","_CancelOnErrorSubscriptionWrapper.onError","_CancelOnErrorSubscriptionWrapper.onError.<anonymous function>","_CancelOnErrorSubscriptionWrapper.onError.<anonymous function>.<anonymous function>","All.evaluate","All.intersection","All.validate","All.toString","VariableNode.accept","VariableNode.toString","VariableNode.==","VariableNode.hashCode","NotNode.accept","NotNode.toString","NotNode.==","NotNode.hashCode","OrNode.span","OrNode.accept","OrNode.toString","OrNode.==","OrNode.hashCode","AndNode.span","AndNode.accept","AndNode.toString","AndNode.==","AndNode.hashCode","ConditionalNode.span","ConditionalNode.accept","ConditionalNode.toString","ConditionalNode.==","ConditionalNode.hashCode","Evaluator.visitVariable","Evaluator.visitNot","Evaluator.visitOr","Evaluator.visitAnd","Evaluator.visitConditional","BooleanSelectorImpl.evaluate","BooleanSelectorImpl.intersection","BooleanSelectorImpl.validate","BooleanSelectorImpl.toString","BooleanSelectorImpl.==","BooleanSelectorImpl.hashCode","IntersectionSelector.evaluate","IntersectionSelector.intersection","IntersectionSelector.validate","IntersectionSelector.toString","IntersectionSelector.==","IntersectionSelector.hashCode","None.evaluate","None.intersection","None.validate","None.toString","Parser.parse","Parser._conditional","Parser._or","Parser._and","Parser._simpleExpression","Scanner.peek","Scanner.next","Scanner.scan","Scanner._getNext","StringScanner.isDone","SpanScanner.state","Scanner._scanOr","Scanner._scanAnd","Scanner._scanIdentifier","Scanner._scanOperator","StringScanner.readChar","Scanner._consumeWhitespace","Scanner._multiLineComment","IdentifierToken.toString","TokenType.toString","Validator.visitVariable","RecursiveVisitor.visitNot","RecursiveVisitor.visitOr","RecursiveVisitor.visitAnd","RecursiveVisitor.visitConditional","EmptyUnmodifiableSet.toSet","EmptyUnmodifiableSet.iterator","EmptyUnmodifiableSet.length","EmptyUnmodifiableSet.contains","mapMap.<anonymous function>","mapMap_closure","mergeMaps.<anonymous function>","mergeMaps_closure","QueueList.toString","QueueList.removeFirst","QueueList.length","QueueList.[]","QueueList.[]=","QueueList._add","QueueList._writeToList","QueueList._preGrow","QueueList._table","UnionSet.length","UnionSet.iterator","UnionSet._iterable","_SetBase.expand","UnionSet.toSet","UnionSet.length.<anonymous function>","UnionSet_length_closure","UnionSet._iterable.<anonymous function>","UnionSet__iterable_closure","UnionSetController._set","_DelegatingIterableBase.contains","_DelegatingIterableBase.every","_DelegatingIterableBase.first","_DelegatingIterableBase.isEmpty","_DelegatingIterableBase.iterator","_DelegatingIterableBase.last","_DelegatingIterableBase.length","_DelegatingIterableBase.map","_DelegatingIterableBase.toList","_DelegatingIterableBase.toList[function-entry$0]","_DelegatingIterableBase.toSet","_DelegatingIterableBase.where","_DelegatingIterableBase.toString","DelegatingSet.union","DelegatingSet.toSet","_IsTrue.matches","_IsTrue.describe","_Predicate.typedMatches","_Predicate.describe","StringDescription.length","StringDescription.addDescriptionOf","_StringEqualsMatcher.typedMatches","_StringEqualsMatcher.describe","_StringEqualsMatcher.describeTypedMismatch","_DeepMatcher._compareIterables","_DeepMatcher._compareSets","_DeepMatcher._recursiveMatch","_DeepMatcher._match","_DeepMatcher.matches","_DeepMatcher.describe","_DeepMatcher.describeMismatch","_DeepMatcher._compareSets.<anonymous function>","FeatureMatcher.matches","FeatureMatcher.describeMismatch","FeatureMatcher.describeTypedMismatch","Matcher.describeMismatch","prettyPrint._prettyPrint","prettyPrint._prettyPrint.pp","prettyPrint._prettyPrint.<anonymous function>","TypeMatcher.describe","_stripDynamic","TypeMatcher.matches","wrapMatcher.<anonymous function>","escape.<anonymous function>","PackageConfigResolver._normalizeMap.<anonymous function>","Context.absolute","Context.absolute[function-entry$1]","Context.join","Context.join[function-entry$2]","Context.joinAll","Context.split","Context.normalize","Context._needsNormalization","Context.relative","Context.isRelative","Context.relative[function-entry$1]","Context._isWithinOrEquals","Context._isWithinOrEqualsFast","Context._pathDirection","Context.toUri","Context.prettyUri","Context.join.<anonymous function>","Context.joinAll.<anonymous function>","Context.split.<anonymous function>","_validateArgList.<anonymous function>","_PathDirection.toString","_PathRelation.toString","InternalStyle.getRoot","InternalStyle.relativePathToUri","InternalStyle.codeUnitsEqual","InternalStyle.pathsEqual","ParsedPath.hasTrailingSeparator","ParsedPath.removeTrailingSeparators","ParsedPath.normalize","ParsedPath.toString","ParsedPath.parts","ParsedPath.separators","ParsedPath.normalize.<anonymous function>","PathException.toString","Style.toString","PosixStyle.containsSeparator","PosixStyle.isSeparator","PosixStyle.needsSeparator","PosixStyle.rootLength","PosixStyle.rootLength[function-entry$1]","PosixStyle.isRootRelative","PosixStyle.pathFromUri","PosixStyle.absolutePathToUri","UrlStyle.containsSeparator","UrlStyle.isSeparator","UrlStyle.needsSeparator","UrlStyle.rootLength","UrlStyle.rootLength[function-entry$1]","UrlStyle.isRootRelative","UrlStyle.pathFromUri","UrlStyle.relativePathToUri","UrlStyle.absolutePathToUri","WindowsStyle.containsSeparator","WindowsStyle.isSeparator","WindowsStyle.needsSeparator","WindowsStyle.rootLength","WindowsStyle.rootLength[function-entry$1]","WindowsStyle.isRootRelative","WindowsStyle.pathFromUri","WindowsStyle.absolutePathToUri","WindowsStyle.codeUnitsEqual","WindowsStyle.pathsEqual","WindowsStyle.absolutePathToUri.<anonymous function>","Pool.request","Pool.isClosed","Pool.withResource","Pool.close","Pool._onResourceReleaseAllowed","Pool._runOnRelease","Pool._resetTimer","Pool.close.<anonymous function>","Pool._onResourceReleaseAllowed.<anonymous function>","Pool._runOnRelease.<anonymous function>","PoolResource.release","Pool._onResourceReleased","mapStackTrace.<anonymous function>","_prettifyMember.<anonymous function>","MultiSectionMapping._indexFor","MultiSectionMapping.spanFor","MultiSectionMapping.spanFor[function-entry$2$uri]","MultiSectionMapping.spanFor[function-entry$2$files]","MultiSectionMapping.toString","MappingBundle.toString","MappingBundle.spanFor","SourceMapSpan","MappingBundle.spanFor[function-entry$2$uri]","SingleMapping._segmentError","SingleMapping._findLine","SingleMapping._findColumn","SingleMapping.spanFor","SourceMapSpan.identifier","SingleMapping.spanFor[function-entry$2$uri]","SingleMapping.spanFor[function-entry$2$files]","SingleMapping.toString","SingleMapping.fromJson.<anonymous function>","SingleMapping._findLine.<anonymous function>","SingleMapping._findColumn.<anonymous function>","TargetLineEntry.toString","TargetEntry.toString","_MappingTokenizer.moveNext","_MappingTokenizer.current","_MappingTokenizer.hasTokens","_MappingTokenizer.nextKind","_MappingTokenizer.toString","_digits.<anonymous function>","SourceFile.length","SourceFile.lines","SourceFile.span","SourceFile.getLine","SourceFile._isNearCachedLine","SourceFile._binarySearch","SourceFile.getColumn","SourceFile.getOffset","SourceFile.getOffset[function-entry$1]","FileLocation.line","FileLocation.sourceUrl","FileLocation.column","_FileSpan.start","_FileSpan.sourceUrl","_FileSpan.length","_FileSpan.end","_FileSpan.text","_FileSpan.context","_FileSpan.==","_FileSpan.hashCode","_FileSpan.expand","Highlighter.highlight","downEnd","upEnd","Highlighter._writeFirstLine","Highlighter._writeIntermediateLines","Highlighter._writeLastLine","Highlighter._writeTrailingLines","Highlighter._writeText","Highlighter._writeSidebar","Highlighter._writeSidebar[function-entry$0$end]","Highlighter._writeSidebar[function-entry$0$line]","Highlighter._writeSidebar[function-entry$0]","Highlighter._countTabs","Highlighter._isOnlyWhitespace","Highlighter._colorize","Highlighter._colorize[function-entry$1]","Highlighter._writeFirstLine.<anonymous function>","glyphOrAscii","topLeftCorner","horizontalLine","Highlighter._writeIntermediateLines.<anonymous function>","verticalLine","Highlighter._writeLastLine.<anonymous function>","bottomLeftCorner","Highlighter._writeSidebar.<anonymous function>","SourceLocation.distance","SourceLocation.==","SourceLocation.hashCode","SourceLocation.toString","SourceLocationMixin.distance","SourceLocationMixin.==","SourceLocationMixin.hashCode","SourceLocationMixin.toString","SourceLocationMixin.toolString","SourceSpanBase","SourceSpanException.message","SourceSpanException.toString","SourceSpanException.toString[function-entry$0]","SourceSpanMixin.sourceUrl","SourceSpanMixin.length","SourceSpanMixin.message","SourceSpanMixin.message[function-entry$1]","SourceSpanMixin.highlight","Highlighter","Highlighter._buffer","SourceSpanMixin.==","SourceSpanMixin.hashCode","SourceSpanMixin.toString","SourceSpanWithContext.context","Chain.foldFrames","Chain.toTrace","JSArray.expand","Chain.toString","Chain.capture.<anonymous function>","Chain_capture_closure","Chain.current.<anonymous function>","Chain.forTrace.<anonymous function>","Chain.parse.<anonymous function>","Chain.foldFrames.<anonymous function>","Chain.toTrace.<anonymous function>","Chain.toString.<anonymous function>","Chain.toString.<anonymous function>.<anonymous function>","Frame.isCore","Frame.library","Frame.package","Frame.location","Frame.toString","Frame.parseVM.<anonymous function>","Frame.parseV8.<anonymous function>","Frame.parseV8.<anonymous function>.parseLocation","Frame.parseFirefox.<anonymous function>","Frame.parseFriendly.<anonymous function>","UriData.fromString","Uri.dataFromString","fromUri","LazyChain._chain","LazyChain.traces","LazyChain.foldFrames","LazyChain.toTrace","LazyChain.toString","LazyChain._inner","LazyChain.foldFrames.<anonymous function>","LazyChain.toTrace.<anonymous function>","LazyTrace._trace","LazyTrace.frames","LazyTrace.original","LazyTrace.foldFrames","LazyTrace.toString","LazyTrace._inner","LazyTrace.foldFrames.<anonymous function>","StackZoneSpecification.chainFor","StackZoneSpecification._registerCallback","StackZoneSpecification._disabled","StackZoneSpecification._registerCallback[function-entry$4]","StackZoneSpecification._registerUnaryCallback","StackZoneSpecification._registerUnaryCallback[function-entry$4]","StackZoneSpecification._registerBinaryCallback","StackZoneSpecification._registerBinaryCallback[function-entry$4]","StackZoneSpecification._errorCallback","StackZoneSpecification._run","StackZoneSpecification._currentTrace","StackZoneSpecification._trimVMChain","StackZoneSpecification._currentNode","StackZoneSpecification.chainFor.<anonymous function>","StackZoneSpecification._registerCallback.<anonymous function>","StackZoneSpecification__registerCallback_closure","StackZoneSpecification._registerUnaryCallback.<anonymous function>","StackZoneSpecification__registerUnaryCallback_closure","StackZoneSpecification._registerUnaryCallback.<anonymous function>.<anonymous function>","StackZoneSpecification__registerUnaryCallback__closure","StackZoneSpecification._registerBinaryCallback.<anonymous function>","StackZoneSpecification__registerBinaryCallback_closure","StackZoneSpecification._registerBinaryCallback.<anonymous function>.<anonymous function>","StackZoneSpecification__registerBinaryCallback__closure","StackZoneSpecification._currentTrace.<anonymous function>","_Node.toChain","Trace.foldFrames","JSArray.reversed","Trace.toString","Trace.current.<anonymous function>","Trace.from.<anonymous function>","Trace._parseVM.<anonymous function>","Trace.parseV8.<anonymous function>","Trace.parseJSCore.<anonymous function>","Trace.parseFirefox.<anonymous function>","Trace.parseFriendly.<anonymous function>","Trace.foldFrames.<anonymous function>","Trace.toString.<anonymous function>","UnparsedFrame.toString","GuaranteeChannel.sink","GuaranteeChannel._onSinkDisconnected","GuaranteeChannel._sink","GuaranteeChannel._streamController","GuaranteeChannel._subscription","GuaranteeChannel.<anonymous function>","GuaranteeChannel.<anonymous function>.<anonymous function>","_GuaranteeSink.done","_GuaranteeSink.add","_GuaranteeSink.addError","_GuaranteeSink.addError[function-entry$1]","_GuaranteeSink._addError","_GuaranteeSink._addError[function-entry$1]","_GuaranteeSink.addStream","_GuaranteeSink.close","_GuaranteeSink._onStreamDisconnected","_GuaranteeSink._addStreamSubscription","_GuaranteeSink._addError.<anonymous function>","_GuaranteeSink.addStream.<anonymous function>","_MultiChannel.virtualChannel","_MultiChannel.virtualChannel[function-entry$0]","_MultiChannel._closeChannel","_MultiChannel._closeInnerChannel","_MultiChannel.<anonymous function>","_MultiChannel_closure","_MultiChannel.<anonymous function>.<anonymous function>","_MultiChannel__closure","_MultiChannel.virtualChannel.<anonymous function>","_MultiChannel_virtualChannel_closure","StreamChannelCompleter._channel","StreamChannelController.local","StreamChannelController._local","StreamChannelController._foreign","SpanScanner.spanFrom","SpanScanner.matches","SpanScanner.error","StringScanner.lastMatch","StringScanner.peekChar","StringScanner.scan","StringScanner.expect","StringScanner._fail","StringScanner.expect[function-entry$1]","StringScanner.matches","AsciiGlyphSet.glyphOrAscii","AsciiGlyphSet.horizontalLine","AsciiGlyphSet.verticalLine","AsciiGlyphSet.topLeftCorner","AsciiGlyphSet.bottomLeftCorner","AsciiGlyphSet.upEnd","AsciiGlyphSet.downEnd","UnicodeGlyphSet.glyphOrAscii","UnicodeGlyphSet.horizontalLine","UnicodeGlyphSet.verticalLine","UnicodeGlyphSet.topLeftCorner","UnicodeGlyphSet.bottomLeftCorner","UnicodeGlyphSet.upEnd","UnicodeGlyphSet.downEnd","internalBootstrapBrowserTest.<anonymous function>","suiteChannel","setStackTraceMapper","postMessageChannel.<anonymous function>","convertNativeToDart_AcceptStructuredClone","convertNativeToDart_SerializedScriptValue","postMessageChannel.<anonymous function>.<anonymous function>","ClosedException.toString","Declarer.test","Declarer.group","Declarer.build","Declarer._checkNotBuilt","Declarer._runSetUps","Declarer._setUpAll","Declarer._tearDownAll","Declarer.test.<anonymous function>","Invoker.addTearDown","Declarer.test.<anonymous function>.<anonymous function>","Declarer.test.<anonymous function>.<anonymous function>.<anonymous function>","Declarer.group.<anonymous function>","Declarer.build.<anonymous function>","Declarer._runSetUps.<anonymous function>","Declarer._tearDownAll.<anonymous function>","Declarer._tearDownAll.<anonymous function>.<anonymous function>","Declarer._tearDownAll.<anonymous function>.<anonymous function>.<anonymous function>","Group.forPlatform","Group._map","Group.forPlatform.<anonymous function>","Group._map.<anonymous function>","LocalTest.load","Invoker._closableKey","Invoker._","Invoker._counterKey","Invoker.liveTest","LocalTest.forPlatform","Invoker._outstandingCallbacks","Invoker.addOutstandingCallback","Invoker.waitForOutstandingCallbacks","Invoker.unclosable","Invoker.heartbeat","LiveTest.isComplete","Invoker._handleError","State.shouldBeDone","Invoker._handleError[function-entry$2]","Invoker._onRun","Invoker._runTearDowns","Invoker.guard.<anonymous function>","Invoker.guard.<anonymous function>.<anonymous function>","Invoker.waitForOutstandingCallbacks.<anonymous function>","Invoker.heartbeat.message","niceDuration","Invoker.heartbeat.<anonymous function>","Invoker.heartbeat.<anonymous function>.<anonymous function>","Invoker._handleError.<anonymous function>","_AsyncCounter.complete","Invoker._onRun.<anonymous function>","Invoker._onRun.<anonymous function>.<anonymous function>","Invoker._onRun.<anonymous function>.<anonymous function>.<anonymous function>","Invoker._onRun.<anonymous function>.<anonymous function>.<anonymous function>.<anonymous function>","Invoker._print","_AsyncCounter.decrement","_LiveTest.run","LiveTestController._run","LiveTestController._isClosed","_LiveTest.onComplete","LiveTestController.addError","LiveTestController.setState","LiveTestController.message","_BroadcastStreamController.hasListener","LiveTestController._close","MessageType.toString","Metadata._validateTags","Metadata.validatePlatformSelectors","Metadata.merge","Metadata.change","Metadata.change[function-entry$0$onPlatform]","Metadata.change[function-entry$0$timeout]","Metadata.change[function-entry$0$skip$skipReason]","Metadata.forPlatform","Metadata.serialize","Metadata._serializeTimeout","Metadata._unresolved","Metadata.<anonymous function>","Metadata.deserialize.<anonymous function>","BooleanSelectorImpl.parse","Parser","Metadata._validateTags.<anonymous function>","Metadata.validatePlatformSelectors.<anonymous function>","Metadata.merge.<anonymous function>","Metadata.forPlatform.<anonymous function>","Metadata.serialize.<anonymous function>","OperatingSystem.toString","OperatingSystem.find.<anonymous function>","PlatformSelector.validate","PlatformSelector.evaluate","PlatformSelector.intersection","PlatformSelector.toString","PlatformSelector.==","PlatformSelector.hashCode","PlatformSelector.parse.<anonymous function>","PlatformSelector.validate.<anonymous function>","PlatformSelector.validate.<anonymous function>.<anonymous function>","PlatformSelector.evaluate.<anonymous function>","Runtime.toString","Runtime.deserialize.<anonymous function>","StackTraceFormatter.configure","StackTraceFormatter.configure[function-entry$0$except$only]","StackTraceFormatter.configure[function-entry$0$mapper]","StackTraceFormatter.formatStackTrace","parseExtended","JSStackTraceMapper.mapStackTrace","StackTraceFormatter._except","StackTraceFormatter._only","StackTraceFormatter.formatStackTrace.<anonymous function>","_LinkedHashSet.isNotEmpty","State.==","State.hashCode","State.toString","Status.toString","Result.toString","TestFailure.toString","_expect.<anonymous function>","Timeout.merge","Duration.*","Timeout.apply","Timeout.hashCode","Timeout.==","Timeout.toString","RemoteListener._serializeGroup","RemoteListener._serializeTest","RemoteListener._runLiveTest","_BroadcastStreamController.stream","_LiveTest.onStateChange","_LiveTest.onError","_LiveTest.onMessage","RemoteListener.start.<anonymous function>","StackTraceFormatter","RemoteListener.start.<anonymous function>.<anonymous function>","RemoteListener.start.<anonymous function>.<anonymous function>.<anonymous function>","StreamQueue._","RemoteListener.start.<anonymous function>.<anonymous function>.<anonymous function>.<anonymous function>","SuiteChannelManager.current","SuiteChannelManager.connectIn","StreamChannelCompleter.setChannel","StreamSinkCompleter.setDestinationSink","RemoteListener.start.<anonymous function>.<anonymous function>.<anonymous function>.<anonymous function>.<anonymous function>","RemoteListener._listen","RemoteListener._serializeGroup.<anonymous function>","RemoteListener._serializeTest.<anonymous function>","RemoteListener._runLiveTest.<anonymous function>","RemoteListener._runLiveTest.<anonymous function>.<anonymous function>","SuiteChannelManager.connectOut","StreamCompleter._stream","StreamSinkCompleter.sink","StreamChannelCompleter._streamCompleter","StreamChannelCompleter._sinkCompleter","StreamChannelCompleter","StreamChannel","IterableSet.length","IterableSet.iterator","IterableSet.toSet","errorsDontStopTest.<anonymous function>","currentOSGuess.<anonymous function>","Engine._onUnpaused","Engine.success","Engine.liveTests","UnionSet.from","Engine.passed","Engine.skipped","Engine.failed","Engine.active","Engine.run","Engine._runGroup","JSArray._toListGrowable","Engine._runLiveTest","Engine._runLiveTest[function-entry$2]","Engine._runSkippedTest","Engine._addLiveSuite","_LiveSuite.onTestStarted","_LiveSuite.passed","_LiveSuite.skipped","_LiveSuite.failed","Engine.success.<anonymous function>","Engine.<anonymous function>","Engine.run.<anonymous function>","Engine.run.<anonymous function>.<anonymous function>","Engine_run__closure","Engine.run.<anonymous function>.<anonymous function>.<anonymous function>","Engine.run.<anonymous function>.<anonymous function>.<anonymous function>.<anonymous function>","Engine._runLiveTest.<anonymous function>","Engine._runSkippedTest.<anonymous function>","LiveSuiteController.reportLiveTest","LiveSuiteController.close","LiveSuiteController.<anonymous function>","LiveSuiteController.reportLiveTest.<anonymous function>","LiveSuiteController.close.<anonymous function>","ExpandedReporter._onTestStarted","Stopwatch.start","ExpandedReporter._onStateChange","ExpandedReporter._onError","ExpandedReporter._onDone","ExpandedReporter._progressLine","ExpandedReporter._timeString","ExpandedReporter._progressLine[function-entry$1$suffix]","ExpandedReporter._progressLine[function-entry$1$color]","ExpandedReporter._progressLine[function-entry$1]","ExpandedReporter._description","ExpandedReporter._onTestStarted.<anonymous function>","RunnerSuiteController._close","RunnerSuiteController._suite","RunnerSuiteController._close.<anonymous function>","PrintSink.writeln","PrintSink._flush","JSStackTraceMapper._deserializePackageConfigMap.<anonymous function>","_declarer.<anonymous function>","RunnerSuiteController._local","RunnerSuite._","DelegatingSink.add","Engine.suiteSink","DelegatingSink.close","Stopwatch","ExpandedReporter._","StreamGroup.stream","_declarer.<anonymous function>.<anonymous function>","main.<anonymous function>","main.<anonymous function>.<anonymous function>","_nullErrorHandler[function-entry$1]","_rootRun[function-entry$4]","_rootRunUnary[function-entry$5]","_rootRegisterCallback[function-entry$4]","_rootRegisterUnaryCallback[function-entry$4]","_rootRegisterBinaryCallback[function-entry$4]","max[function-entry$2]","DART_CLOSURE_PROPERTY_NAME","JS_INTEROP_INTERCEPTOR_TAG","TypeErrorDecoder.noSuchMethodPattern","TypeErrorDecoder.notClosurePattern","TypeErrorDecoder.nullCallPattern","TypeErrorDecoder.nullLiteralCallPattern","TypeErrorDecoder.undefinedCallPattern","TypeErrorDecoder.undefinedLiteralCallPattern","TypeErrorDecoder.nullPropertyPattern","TypeErrorDecoder.nullLiteralPropertyPattern","TypeErrorDecoder.undefinedPropertyPattern","TypeErrorDecoder.undefinedLiteralPropertyPattern","_AsyncRun._scheduleImmediateClosure","Future._nullFuture","_RootZone._rootMap","Utf8Decoder._decoder","_Base64Decoder._inverseAlphabet","_Uri._isWindowsCached","_Uri._needsNoEncoding","_hasErrorStackProperty","_scannerTables","_whitespaceAndSingleLineComments","_multiLineCommentBody","_hyphenatedIdentifier","_dart2DynamicArgs","_escapeRegExp","windows","url","context","createInternal","Style.posix","PosixStyle","Style.windows","WindowsStyle","Style.url","UrlStyle","Style.platform","_digits","MAX_INT32","MIN_INT32","_specKey","_vmFrame","_v8Frame","_v8UrlLocation","_v8EvalLocation","_firefoxSafariFrame","_friendlyFrame","_asyncBody","_initialDot","Frame._uriRegExp","Frame._windowsRegExp","StackZoneSpecification.disableKey","_terseRegExp","_v8Trace","_v8TraceLine","_firefoxSafariTrace","_friendlyTrace","Metadata.empty","_universalValidVariables","_currentKey","currentOSGuess","anchoredHyphenatedIdentifier","SuiteConfiguration.empty","patchInstance","main_closure","fromTearOff","StaticClosure","BoundClosure","functionCounter","forwardCallTo","_computeSignatureFunctionNewRti","CyclicInitializationError","NullThrownError","safeToString","_objectToString","Closure","objectTypeName","_objectTypeNameNewRti","Object","_saneNativeClassName","_getInterfaceTypeArguments","_getGenericFunctionBounds","","value","_getFunctionParameters","markFixed","JSArray","markFixedList","StringBuffer","iterableToFullString","_toStringVisiting","_writeAll","noElement","ArrayIterator","ListIterator","ListMixin","Iterable","initNativeDispatchFlag","getTagFunction","dispatchRecordsForInstanceTags","interceptorsForUncacheableTags","alternateTagFunction","JavaScriptIndexingBehavior","prototypeForTagFunction","initHooks_closure","forType","_TypeError","compose","_CastError","fromMessage","_isUnionOfFunctionType","eval","_parseRecipe","create","parse","handleDigit","handleIdentifier","toType","_lookupGenericFunctionParameterRti","_lookupTerminalRti","toTypes","_lookupInterfaceRti","_lookupGenericFunctionRti","_lookupBindingRti","handleExtendedOperations","_lookupUnaryRti","_FunctionParameters","_lookupFunctionRti","toTypesNamed","_canonicalRecipeJoin","_canonicalRecipeJoinNamed","Rti","_finishRti","int","double","num","String","bool","_AssertionError","_getBindingArguments","indexToType","findRule","_getCanonicalRecipe","evalInEnvironment","_getFutureFromFutureOr","bind","findErasedType","evalRecipeIntercepted","evalRecipe","forwardInterceptedCallTo","cspForwardCall","selfFieldNameCache","computeFieldNamed","selfOf","receiverFieldNameCache","cspForwardInterceptedCall","receiverOf","internalBootstrapBrowserTest_closure","start","_ControllerStream","_current","Null","Stream","AsyncError","_propagateToListeners","_Future__propagateToListeners_handleWhenCompleteCallback","_Future__propagateToListeners_handleValueCallback","_Future__propagateToListeners_handleError","_chainCoreFuture","_Future__prependListeners_closure","ExceptionAndStackTrace","_StackTrace","unwrapException_saveStackTrace","UnknownJsTypeError","StackOverflowError","extractPattern","TypeErrorDecoder","provokePropertyErrorOn","provokeCallErrorOn","_Future__propagateToListeners_handleWhenCompleteCallback_closure","_FutureListener","_RootZone_bindCallbackGuarded_closure","_rootHandleUncaughtError_closure","_nextCallback","_lastPriorityCallback","_lastCallback","_AsyncCallbackEntry","_enter","_isInCallbackLoop","_initializeScheduleImmediate","_AsyncRun__initializeScheduleImmediate_internalCallback","_AsyncRun__initializeScheduleImmediate_closure","_createTimer","Duration_toString_twoDigits","Duration_toString_sixDigits","_TimerImpl_internalCallback","_AsyncRun__scheduleImmediateWithSetImmediate_internalCallback","_AsyncRun__scheduleImmediateJsOverride_internalCallback","_Exception","_Future__addListener_closure","_PendingEvents","_chainForeignFuture","_Future__chainForeignFuture_closure","_StreamControllerLifecycle","StreamConsumer","Stream_pipe_closure","_GuaranteeSink","_EventStream","postMessageChannel_closure","_literal","_EventStreamSubscription_closure","_convertDataTree__convert","_IdentityHashMap","mapToString","MapBase_mapToString_closure","MapMixin","_getTableEntry","_HashMapKeyIterable","iterableToShortString","checkNotNegative","range","_HashMapKeyIterator","MappedIterator","Iterator","EfficientLengthMappedIterable","MappedListIterable","ListIterable","_newHashTable","_setTableEntry","JsLinkedHashMap","LinkedHashMapKeyIterable","LinkedHashMapCell","postMessageChannel__closure","_StructuredCloneDart2Js","DateTime","_StructuredClone_walk_closure","_AcceptStructuredCloneDart2Js","StreamSink","StreamSubscription","_empty","_AcceptStructuredClone_walk_closure","getYear","_fourDigits","getMonth","_twoDigits","getDay","getHours","getMinutes","getSeconds","getMilliseconds","_threeDigits","lazyAsJsDate","_AsyncCompleter","promiseToFuture_closure","_Future__asyncCompleteError_closure","_Future__asyncComplete_closure","_Future__chainFuture_closure","Stream_firstWhere__closure","_cancelAndErrorClosure_closure","_cancelAndError_closure","zoneValue","_cancelAndValue_closure","_StreamSinkWrapper","GuaranteeChannel_closure","_StreamImplEvents","_SyncCompleter","_GuaranteeSink_addStream_closure","_GuaranteeSink__addError_closure","GuaranteeChannel__closure","_SyncStreamController","_AsyncStreamController","_EventDispatch","_PendingEvents_schedule_closure","_BufferingStreamSubscription__sendDone_sendDone","_StreamController__subscribe_closure","_StreamController__recordCancel_complete","_AddStreamState_cancel_closure","_DelayedError","_BufferingStreamSubscription__sendError_sendError","_DelayedData","RemoteListener_start_closure","fromIterable","Map","runZoned_closure","_rootDelegate","_ZoneDelegate","printToZone","from","_ZoneFunction","_CustomZone_bindCallbackGuarded_closure","periodic","_TimerImpl$periodic_closure","_HashMap","HashMap_HashMap$from_closure","_LinkedHashSet","RemoteListener_start__closure","RemoteListener_start___closure","_sendError","serialize","TestFailure","forTrace","Chain_toString_closure","Chain_toString__closure","_Type","Chain","unmodifiable","LazyChain","Chain_Chain$forTrace_closure","Chain_Chain$parse_closure","Trace_toString_closure","parseFriendly","WhereIterable","Trace$parseFriendly_closure","_StringStackTrace","WhereIterator","Context_split_closure","List","ParsedPath","filled","ParsedPath_normalize_closure","generate","JSSyntaxRegExp","makeNative","_uriDecode","StringMatch","CodeUnits","_hexCharPairToByte","Utf8Decoder","UnmodifiableListMixin","_convertIntercepted","checkValidRange","fromCharCodes","_Utf8Decoder","stringFromCharCode","stringFromCharCodes","stringFromNativeUint8List","_stringFromIterable","stringFromCodePoints","_fromCharCodeApply","_convertInterceptedUint8List","_useTextDecoderChecked","_unsafe","_useTextDecoderUnchecked","_makeDecoder","checkValueInInterval","_StringAllMatchesIterable","_StringAllMatchesIterator","_AllMatchesIterable","_AllMatchesIterator","tooFew","fixed","Context_join_closure","Context_joinAll_closure","_validateArgList_closure","base","_currentUriBase","currentUri","_parse","_SimpleUri","notSimple","parseInt","_defaultPort","_toWindowsFilePath","_checkNonWindowsPathReservedCharacters","_Uri__checkNonWindowsPathReservedCharacters_closure","_checkWindowsDriveLetter","_checkWindowsPathReservedCharacters","fromCharCode","_removeDotSegments","_makePort","_normalizeRelativePath","_mayContainDotSegments","_escapeScheme","_isAlphabeticCharacter","_makeScheme","_fail","_makeUserInfo","_makeHost","_Uri__Uri$notSimple_closure","_makePath","_makeQuery","_makeFragment","_normalizeOrSubstring","_normalize","_normalizeEscape","_escapeChar","_Uri__makePath_closure","_normalizePath","_uriEncode","Codec","_Utf8Encoder","_checkZoneID","_normalizeZoneID","parseIPv6Address","_normalizeRegName","Uri_parseIPv6Address_error","Uri_parseIPv6Address_parseHex","_parseIPv4Address","Uri__parseIPv4Address_error","_canonicalizeScheme","_createTables_closure","_createTables_build","_createTables_setChars","_createTables_setRange","_DataUri","UriData","_checkPadding","_create1","_getPlatformStyle","Frame_Frame$parseFriendly_closure","_catchFormatException","_writeUri","_uriEncodeBytes","Frame","WindowsStyle_absolutePathToUri_closure","_validateMimeType","_skipLeadingWhitespace","_skipTrailingWhitespace","_isWhitespace","parseV8","parseJSCore","parseFirefox","_parseVM","Trace__parseVM_closure","parseVM","Frame_Frame$parseVM_closure","ExpandIterable","Chain_toTrace_closure","Trace$parseFirefox_closure","Frame_Frame$parseFirefox_closure","_uriOrPathToUri","file","_makeWindowsFileUrl","_makeFileUri","Trace$parseJSCore_closure","Frame_Frame$parseV8_closure","Frame_Frame$parseV8_closure_parseLocation","Trace$parseV8_closure","SkipWhileIterable","SkipWhileIterator","StackZoneSpecification_chainFor_closure","_Node","LazyTrace","Trace_Trace$from_closure","LazyChain_toTrace_closure","getProperty","StackTraceFormatter_formatStackTrace_closure","LazyChain_foldFrames_closure","Chain_foldFrames_closure","tooMany","LazyTrace_foldFrames_closure","Trace_foldFrames_closure","ReversedListIterable","mapStackTrace_closure","_prettifyMember_closure","fromJson","notNull","_lastLineLength","_normalizeNewlines","_normalizeTrailingNewline","_normalizeEndOfLine","_glyphs","Highlighter__writeSidebar_closure","Highlighter__writeLastLine_closure","Highlighter__writeIntermediateLines_closure","Highlighter__writeFirstLine_closure","SingleMapping__findColumn_closure","SingleMapping__findLine_closure","SingleMapping","SourceFile","_MappingTokenizer","TargetLineEntry","TargetEntry","SingleMapping$fromJson_closure","closure","MultiSectionMapping","MappingBundle","_JsonMap","_JsonMapKeyIterable","_sendLoadException","StreamQueue","_CompleterStream","_RestRequest","StreamCompleter","RemoteListener_start____closure","deserialize","_deserializeSet","find","Suite","_filterGroup","Symbol","makeErrorHandler","_AddStreamState_makeErrorHandler_closure","Result","_wrapJsFunctionForAsync_closure","_StreamIterator","_awaitOnObject_closure","_AsyncAwaitCompleter","RemoteListener_start_____closure","guard","Invoker_guard_closure","Invoker_guard__closure","RemoteListener","RemoteListener__serializeGroup_closure","RemoteListener__serializeTest_closure","VirtualChannel","_EmptyStream","NullStreamSink","MultiChannel","NullStreamSink_addStream_closure","_LinkedHashSetCell","RemoteListener__runLiveTest_closure","_BroadcastStream","RemoteListener__runLiveTest__closure","Invoker","State","Invoker__onRun_closure","_AsyncCounter","capture","_keyCount","StackZoneSpecification","setProperty","StackZoneSpecification__currentTrace_closure","Invoker__onRun__closure","Invoker__onRun___closure","Message","Invoker__onRun____closure","Future_Future_closure","errorsDontStopTest_closure","Invoker_waitForOutstandingCallbacks_closure","sync","Invoker_heartbeat_closure","Invoker_heartbeat_message","Invoker_heartbeat__closure","TimeoutException","Timeout","Invoker__handleError_closure","Chain_Chain$current_closure","_SyncBroadcastStreamController","_LiveTest","_BroadcastStreamController","Metadata_serialize_closure","MapEntry","PlatformSelector","Group_forPlatform_closure","GroupEntry","Group__map_closure","Metadata_forPlatform_closure","Metadata_Metadata__unresolved","_","Metadata_Metadata_closure","Metadata_merge_closure","Set","UnmodifiableMapView","_throwUnmodifiable","_ConstantMapKeyIterable","ConstantStringMap","DelegatingSet","Metadata__validateTags_closure","LinkedHashMap_LinkedHashMap$from_closure","PlatformSelector_evaluate_closure","OperatingSystem_find_closure","Runtime_Runtime$deserialize_closure","Runtime","Declarer_build_closure","LocalTest","Declarer__tearDownAll_closure","Declarer__tearDownAll__closure","Declarer__tearDownAll___closure","_deserializeTimeout","Metadata$deserialize_closure","BooleanSelectorImpl","Scanner","AndNode","IntersectionSelector","OrNode","ConditionalNode","Evaluator","Token","_SpanScannerState","IdentifierToken","SourceSpanMixin","FileLocation","NotNode","VariableNode","PlatformSelector$parse_closure","_wrapFormatException","_CompleterSink","_CompleterSink__setDestinationSink_closure","StreamSinkCompleter","_EventRequest","_CancelOnErrorSubscriptionWrapper","_CancelOnErrorSubscriptionWrapper_onError_closure","_CancelOnErrorSubscriptionWrapper_onError__closure","ErrorResult","ValueResult","EventSink","_NextRequest","_GeneratedStreamImpl","PackageRootResolver","_deserializePackageConfigMap","_normalizeMap","PackageConfigResolver","JSStackTraceMapper","castFrom","CastMap","CastIterator","EfficientLengthIterable","_EfficientLengthCastIterable","PackageConfigResolver__normalizeMap_closure","JSStackTraceMapper__deserializePackageConfigMap_closure","_StreamChannel","Declarer_group_closure","Trace_Trace$current_closure","Metadata_validatePlatformSelectors_closure","PlatformSelector_validate_closure","PlatformSelector_validate__closure","Validator","_parseOnPlatform","_parseTags","_globalDeclarer","_declarer_closure","RunnerSuiteController","_AsyncBroadcastStreamController","AsyncMemoizer","RunnerSuite","_frequency","initTicker","timerFrequency","ExpandedReporter","PrintSink","fromFuture","_declarer__closure","error","UnmodifiableListView","timerTicks","UnionSet","IterableSet","ExpandedReporter__onTestStarted_closure","Engine_run_closure","Pool_close_closure","Engine_run___closure","Engine_run____closure","Pool__onResourceReleaseAllowed_closure","Pool__runOnRelease_closure","PoolResource","LiveSuiteController_close_closure","RunnerSuiteController__close_closure","Engine__runSkippedTest_closure","Engine__runLiveTest_closure","microtask","Future_Future$microtask_closure","LiveSuiteController_reportLiveTest_closure","_nextPowerOf2","StreamGroup__listenToStream_closure","_LiveSuite","LiveSuiteController_closure","wait","Engine_success_closure","Future_wait_handleError","Primitives_initTicker_closure","StreamGroup","Engine_closure","_macOSDirectories","_list","_map","SuiteConfiguration","main__closure","Declarer_test_closure","Declarer_test__closure","Declarer_test___closure","Declarer__runSetUps_closure","forEach","Future_forEach_closure","doWhile","Future_doWhile_closure","_expect_closure","StringDescription","Matcher","prettyPrint__prettyPrint","prettyPrint__prettyPrint_pp","prettyPrint__prettyPrint_closure","escape_closure","Runes","RuneIterator","_Predicate","wrapMatcher_closure","_StringEqualsMatcher","_DeepMatcher","_DeepMatcher__compareSets_closure","TypeMatcher","FeatureMatcher","_writeTrailing","_writeLeading","x","objectAssign","JS_CONST","Interceptor","JSBool","JSNull","JSObject","JavaScriptObject","PlainJavaScriptObject","UnknownJavaScriptObject","Function","JavaScriptFunction","JSUnmodifiableArray","JSNumber","JSInt","JSDouble","Pattern","JSString","_CastIterableBase","EmptyIterator","FixedLengthListMixin","UnmodifiableListBase","ConstantMap","noSuchMethodPattern","notClosurePattern","nullCallPattern","nullLiteralCallPattern","undefinedCallPattern","undefinedLiteralCallPattern","nullPropertyPattern","nullLiteralPropertyPattern","undefinedPropertyPattern","undefinedLiteralPropertyPattern","NoSuchMethodError","StackTrace","TearOffClosure","RegExpMatch","Match","NativeByteBuffer","ByteBuffer","NativeTypedData","NativeByteData","NativeTypedArray","NativeTypedArrayOfDouble","NativeTypedArrayOfInt","NativeFloat32List","NativeFloat64List","NativeInt16List","NativeInt32List","NativeInt8List","NativeUint16List","Uint32List","NativeUint32List","NativeUint8ClampedList","Uint8List","Type","_Error","Sink","_Completer","StreamTransformer","StreamTransformerBase","_StreamController","_SyncStreamControllerDispatch","_AsyncStreamControllerDispatch","_StreamImpl","_DelayedEvent","_DelayedDone","Error","ZoneSpecification","ZoneDelegate","Zone","_Zone","_rootMap","_RootZone","IterableBase","ListBase","MapBase","_UnmodifiableMapMixin","MapView","Queue","SetMixin","SetBase","_SetBase","AsciiCodec","_UnicodeSubsetEncoder","AsciiEncoder","Base64Codec","Base64Encoder","_FusedCodec","Converter","Encoding","JsonCodec","JsonDecoder","Utf8Codec","Utf8Encoder","_decoder","OutOfMemoryError","StringSink","Uri","_isWindowsCached","_needsNoEncoding","AbortPaymentEvent","AnimationEvent","AnimationPlaybackEvent","ApplicationCacheErrorEvent","BackgroundFetchClickEvent","BackgroundFetchEvent","BackgroundFetchFailEvent","BackgroundFetchedEvent","BeforeInstallPromptEvent","BeforeUnloadEvent","Blob","BlobEvent","CanMakePaymentEvent","ClipboardEvent","CloseEvent","CompositionEvent","CustomEvent","DeviceMotionEvent","DeviceOrientationEvent","DomError","DomException","ErrorEvent","Event","EventTarget","ExtendableEvent","ExtendableMessageEvent","FetchEvent","File","FocusEvent","FontFaceSetLoadEvent","ForeignFetchEvent","GamepadEvent","HashChangeEvent","InstallEvent","KeyboardEvent","Location","MediaEncryptedEvent","MediaError","MediaKeyMessageEvent","MediaQueryListEvent","MediaStreamEvent","MediaStreamTrackEvent","MessageEvent","MessagePort","MidiConnectionEvent","MidiMessageEvent","MouseEvent","MutationEvent","NavigatorUserMediaError","NotificationEvent","OverconstrainedError","PageTransitionEvent","PaymentRequestEvent","PaymentRequestUpdateEvent","PointerEvent","PopStateEvent","PositionError","PresentationConnectionAvailableEvent","PresentationConnectionCloseEvent","ProgressEvent","PromiseRejectionEvent","PushEvent","RtcDataChannelEvent","RtcDtmfToneChangeEvent","RtcPeerConnectionIceEvent","RtcTrackEvent","SecurityPolicyViolationEvent","SensorErrorEvent","SpeechRecognitionError","SpeechRecognitionEvent","SpeechSynthesisEvent","StorageEvent","SyncEvent","TextEvent","TouchEvent","TrackEvent","TransitionEvent","UIEvent","VRDeviceEvent","VRDisplayEvent","VRSessionEvent","WheelEvent","Window","_MojoInterfaceRequestEvent","_ResourceProgressEvent","_USBConnectionEvent","EventStreamProvider","_StructuredClone","_AcceptStructuredClone","VersionChangeEvent","ByteData","Int8List","Uint8ClampedList","Int16List","Uint16List","Int32List","Float32List","Float64List","AudioProcessingEvent","OfflineAudioCompletionEvent","ContextEvent","SqlError","DelegatingSink","DelegatingStreamSubscription","_StreamGroupState","BooleanSelector","All","Node","Visitor","None","TokenType","RecursiveVisitor","EmptyUnmodifiableSet","UnmodifiableSetMixin","_DelegatingIterableBase","DelegatingIterable","_IsTrue","Description","SyncPackageResolver","_PathDirection","_PathRelation","InternalStyle","Style","Mapping","_TokenKind","FileSpan","SourceLocationMixin","SourceSpan","SourceSpanException","_uriRegExp","_windowsRegExp","disableKey","StreamChannelMixin","LineScannerState","StringScanner","AsciiGlyphSet","UnicodeGlyphSet","LiveTest","MessageType","empty","OperatingSystem","Status","Test","StackTraceMapper","LiveSuite","RuntimeSelection","_NativeTypedArrayOfDouble&NativeTypedArray&ListMixin","_NativeTypedArrayOfDouble&NativeTypedArray&ListMixin&FixedLengthListMixin","_NativeTypedArrayOfInt&NativeTypedArray&ListMixin","_NativeTypedArrayOfInt&NativeTypedArray&ListMixin&FixedLengthListMixin","_ListBase&Object&ListMixin","_SetBase&Object&SetMixin","_UnmodifiableMapView&MapView&_UnmodifiableMapMixin","_QueueList&Object&ListMixin","_UnionSet&SetBase&UnmodifiableSetMixin","_UnmodifiableSetView&DelegatingSet&UnmodifiableSetMixin","_IterableSet&SetMixin&UnmodifiableSetMixin","dateNow","addRules","addErasedTypes","_scheduleImmediateJsOverride","_scheduleImmediateWithSetImmediate","_scheduleImmediateWithTimer","_kTrue","decodeComponent","_scheduleImmediateClosure","_nullFuture","_inverseAlphabet","posix","platform","getInterceptor$","getInterceptor$asx","async___startMicrotaskLoop$closure","async__AsyncRun__scheduleImmediateJsOverride$closure","async__AsyncRun__scheduleImmediateWithSetImmediate$closure","async__AsyncRun__scheduleImmediateWithTimer$closure","async___nullDoneHandler$closure","async___nullErrorHandler$closure","async___nullDataHandler$closure","getInterceptor$ax","async___printToZone$closure","math__max$closure","getInterceptor$s","core_Uri_decodeComponent$closure","main_test__main$closure","_js_helper_Primitives_dateNow$closure","async_Future__kTrue$closure","pretty_print___escapeString$closure","util___getHexLiteral$closure","getInterceptor$x","getInterceptor$ansx","getInterceptor$n","async___rootHandleUncaughtError$closure","async___rootRun$closure","async___rootRunUnary$closure","async___rootRunBinary$closure","async___rootRegisterCallback$closure","async___rootRegisterUnaryCallback$closure","async___rootRegisterBinaryCallback$closure","async___rootErrorCallback$closure","async___rootScheduleMicrotask$closure","async___rootCreateTimer$closure","async___rootCreatePeriodicTimer$closure","async___rootPrint$closure","async___rootFork$closure","_captured_K1_1","_captured_this_1","dart.async#_box_0","_captured_matcher_0","future","_captured_V1_2","_captured_listener_2","_captured_frame_0","_captured_expectedElement_1","_captured_getMain_1","location","channel","_captured_depth_3","controller","matches","_captured_beforeLoad_4","_captured_f_1","line","_captured_printZone_5","_captured_R_3","end","_captured_transform_1","result","_captured_selector_0","handleError","_captured_body_1","_captured_elements_0","_captured_x_0","suite","_captured_T_3","index","_captured_validVariables_0","_captured_terse_2","addEventListener","stackTrace","timeout","_withValue","message","immediate","_captured_performance_0","trace","_captured_div_1","level","span","_captured_registered_1","where","toString","callback","decoded","groups","liveTest","_captured_engine_0","_captured_chain_0","completer","_captured_longest_0","dart.async#_box_1","skipWhile","_captured_fn_2","call","_captured_oldPredicate_0","_captured_counter_3","_captured_hasError_3","_captured_loadResource_2","describe","id","_captured_milliseconds_1","_captured_originalSource_0","stream","immediateError","_captured_outstandingCallbacksForBody_1","_captured_sourceResult_2","_captured_K_1","_captured_serializedOnPlatform_0","_captured_V_2","broadcast","onData","_captured_target_0","_captured_sourceMap_1","_captured_invoker_0","_captured_minified_4","zone","_captured_sdkRoot_2","_captured_streamConsumer_0","_captured_e_1","_captured_s_2","_captured_sdkLib_3","_addEventError","column","_captured_cleanUp_3","_captured_eagerError_4","iterator","identifier","port","_captured_action_1","_captured_node_2","_captured_T1_3","_captured_T2_4","withResource","_captured_portSubscription_1","_captured_serialized_0","_captured_doneSignal_2","_captured_arg1_1","_captured_pos_1","_captured_arg2_2","_captured_dispatch_1","_captured_getTag_0","testOn","_captured_getUnknownTag_0","skip","verboseTrace","_captured_prototypeForTag_0","chainStackTraces","_captured_argumentError_0","==","retry","_captured_arg_1","skipReason","_captured__convertedObjects_0","onPlatform","uri","_captured_portStart_1","skipped","_captured_textInside_1","_captured_maxItems_0","_captured_maxLineLength_1","original","_runGroup","host","_captured__prettyPrint_1","_runLiveTest","_captured_indent_0","_runSkippedTest","_captured_computation_1","_captured_orElse_1","_captured_countSuccess_2","_captured_K2_0","_captured_protected_0","_captured_spec_6","_captured_pp_0","onError","_captured_object_1","_captured_ex_0","subscription","cancel","_captured_bodyFunction_0","_captured_tables_0","data","stream_channel_controller.dart#_foreign","stack_zone_specification.dart#_disabled","expanded.dart#_onTestStarted","newDartList","configure","elapsedMicroseconds","dart.core#_captured_argumentError_0","platform_selector.dart#_captured_this_0","dart.async#_completeWithValue","source_maps.parser#_captured_this_0","dart.async#_isScheduled","hashMapCellKey","dart.async#_captured_future_1","multi_channel.dart#_closeChannel","encode","dart.async#_error","dart.core#_start","onClose","dart.async#_captured_callback_1","dart.async#_completeError","dart.async#_captured_doneSignal_2","_js_helper#_captured_result_2","separators","async_memoizer.dart#_completer","invoker.dart#_counterKey","functions.dart#_captured_V1_2","prettyUri","metadata.dart#_captured_serializedOnPlatform_0","equals_matcher.dart#_compareSets","fold","getRoot","dart.collection#_newSet","invoker.dart#_captured_stackTrace_3","dart.core#_isPort","catchError","*","parser.dart#_and","metadata.dart#_captured_verboseTrace_4","scanner.dart#_scanOperator","highlighter.dart#_writeFirstLine","dart.async#_handleUncaughtError","engine.dart#_failedGroup","rti#_kind","isOdd","source_maps.parser#_findLine","functions.dart#_captured_V_3","stack_zone_specification.dart#_currentNode","engine.dart#_onSuiteStartedController","stack_zone_specification.dart#_captured_f_0","pool.dart#_requestedResources","indexOf","rti#_precomputed4","source_maps.parser#_consumeValue","replaceAll","stream_queue.dart#_completer","tags","source_map_stack_trace.dart#_captured_sdkRoot_3","_js_helper#_previous","needsSeparatorPattern","dart.async#_run","replace","dart.collection#_add","_interceptors#_shlPositive","stream_sink_completer.dart#_ensureController","dart.dom.html#_location","dart.async#_mayAddListener","lazy_chain.dart#_captured_terse_2","queue_list.dart#_preGrow","evaluate","wrappers.dart#_base","context.dart#_isWithinOrEqualsFast","_js_helper#_modified","shouldBeDone","isBlink","dart.core#_currentCodePoint","stream_queue.dart#_addResult","source_map_stack_trace.dart#_box_0","typedMatches","moveNext","_js_helper#_execAnchored","duration","guarantee_channel.dart#_onSinkDisconnected","isCompleted","query","visitVariable","bindCallback","stack_zone_specification.dart#_currentTrace","sourceRoot","take","expanded.dart#_progressLine","listenerHasError","liveTests","createPeriodicTimer","live_suite_controller.dart#_onCloseCompleter","remote_listener.dart#_captured_controller_0","dart.async#_onCancel","pathsEqual","distance","dart.core#_position","asStream","abs","listenerValueOrError","dart.async#_decrementPauseCount","html_common#_captured_this_1","hasTrailingSeparator","stack_trace_formatter.dart#_captured_this_0","declarer.dart#_name","stack_zone_specification.dart#_registerBinaryCallback","dart.collection#_tail","asUint8List","isScaffoldAll","remote_listener.dart#_captured_test_1","isWithin","platform_selector.dart#_captured_validVariables_0","functions.dart#_box_0","live_suite_controller.dart#_passed","addTearDown","dart._internal#_iterator","hashMapCellValue","functions.dart#_captured_K1_1","lastSpan","runner_suite.dart#_environment","registerCallback","handleUncaughtError","stack_zone_specification.dart#_captured_this_1","allMatches","dart.collection#_position","_js_helper#_expr","dart.convert#_data","runner_suite.dart#_suiteChannel","engine.dart#_captured_suite_1","onListen","equals_matcher.dart#_recursiveMatch","highlighter.dart#_writeSidebar","stream_group.dart#_onCancelBroadcast","dart._internal#_iterable","dart.convert#_buffer","print_sink.dart#_flush","operating_system.dart#_captured_identifier_0","invoker.dart#_print","scan","onCancel","dart.async#_schedule","declarer.dart#_metadata","highlighter.dart#_colorize","source_map_stack_trace.dart#_captured_sdkRoot_2","_js_helper#_target","highlighter.dart#_multiline","highlighter.dart#_paddingBeforeSidebar","dart._internal#_startIndex","rti#_specializedTestResource","_interceptors#_isInt32","dart.collection#_contains","invoker.dart#_handleError","engine.dart#_runPool","dart.async#_setPendingComplete","parser.dart#_simpleExpression","dart.async#_rootRunUnary","dart.async#_cloneResult","stack_zone_specification.dart#_trimVMChain","live_test_controller.dart#_run","dart.collection#_first","metadata.dart#_serializeTimeout","relative","declarer.dart#_collectTraces","span_exception.dart#_message","live_test_controller.dart#_onRun","join","stack_zone_specification.dart#_errorCallback","stack_zone_specification.dart#_registerUnaryCallback","runner_suite.dart#_closeMemo","change","addAll","dart.async#_isPaused","previous","dart.async#_addError","source_map_stack_trace.dart#_captured_minified_4","dart.core#_queryStart","dart.async#_captured_eagerError_4","dart.async#_captured_T_2","whenComplete","position","_js_helper#_newLinkedCell","asCurrent","addDescriptionOf","dart.async#_captured_orElse_1","dart.async#_captured_subscription_0","invoker.dart#_count","rti#_eval","dart.async#_addEventError","rti#_optionalPositional","queue_list.dart#_writeToList","dart.async#_hasPending","live_test_controller.dart#_test","runner_suite.dart#_captured_this_0","pool.dart#_captured_zone_0","invoker.dart#_controller","setRange","write","pretty_print.dart#_captured_maxItems_0","stream_queue.dart#_isClosed","multi_channel.dart#_closeInnerChannel","invoker.dart#_closable","update","test.src.runner.browser.post_message_channel#_captured_controller_0","dart.collection#_current=","dart.async#_thenAwait","dart.convert#_upgrade","_js_helper#_fetch","isNewSegment","evaluator.dart#_semantics","internalFindBucketIndex","stack_zone_specification.dart#_registerCallback","file.dart#_cachedLine","live_suite_controller.dart#_controller","dart.async#_cancel","isPassing","source_maps.parser#_lineStart","expanded.dart#_noColor","dart.async#_forEachListener","runner_suite.dart#_isDebugging","fillRange","dart.convert#_second","removeTrailingSeparators","dart.core#_errorName","union_set_controller.dart#_set","visitAnd","pool.dart#_closeMemo","dart.async#_chainFuture","declare","needsSeparator","second","dart.async#_isCanceled","handleNext","union_set.dart#_disjoint","live_test_controller.dart#_liveTest","dart.async#_ensurePendingEvents","failed","context.dart#_parse","string_scanner.dart#_lastMatch","replaceRange","dart.convert#_carry","expand","stack_zone_specification.dart#_captured_this_0","isAbsolute","peek","pretty_print.dart#_captured_object_1","dart.async#_rootRegisterCallback","guarantee_channel.dart#_doneCompleter","isValue","_interceptors#_defaultSplit","_js_helper#_execGlobal","pool.dart#_onResourceReleaseAllowed","_interceptors#_shrBothPositive","chain.dart#_captured_longest_0","dart.core#_captured_error_0","dart.collection#_remove","dart._internal#_string","padRight","dart.async#_iterator","success","stack_zone_specification.dart#_captured_stackTrace_2","multi_channel.dart#_pendingIds","dart.core#_toNonSimple","remote_listener.dart#_captured_spec_6","readChar","scaleFactor","_js_helper#_string","stream_group.dart#_controller","remote_listener.dart#_serializeGroup","microsecond","declarer.dart#_checkNotBuilt","dart.collection#_computeKeys","binaryOnError","parser.dart#_or","dart.async#_captured_computation_1","dart.collection#_findBucketIndex","release","runner_suite.dart#_close","union","_interceptors#_iterable","dart.typed_data.implementation#_setRangeFast","live_suite_controller.dart#_captured_countSuccess_2","dart.collection#_map","internalSet","dart.collection#_checkModification","single","functions.dart#_captured_K_2","joinAll","dart.async#_isEmpty","load","pipe","identicalInJs","dart.async#_asyncCompleteError","lazy_trace.dart#_trace","hashCode","pool.dart#_pool","decrement","registerUnaryCallback","pool.dart#_maxAllocatedResources","isComplete","indexable","hasTokens","dart.dom.html#_onData","_js_helper#_strings","pathSegments","expanded.dart#_green","dart.async#_captured_registered_1","describeTypedMismatch","equals_matcher.dart#_expected","whenFalse","decode","dart._internal#_captured_f_1","any","convert","[]=","future_group.dart#_completer","dart.async#_add","matchTypeError","_js_helper#_last","unclosable","containsKey","engine.dart#_runGroup","queue_list.dart#_grow","chain.dart#_captured_predicate_0","minute","source_maps.parser#_length","declarer.dart#_setUpAllTrace","codeUnitAt","modifiedObject","dart.js_util#_captured_completer_0","newJsObject","active","expanded.dart#_lastProgressSuffix","future_group.dart#_captured_index_1","union_set.dart#_dedupIterable","live_suite_controller.dart#_captured_this_0","endsWith","dart.async#_captured_streamConsumer_0","removeLast","urls","dart.async#_captured_hasError_3","remote_listener.dart#_captured_this_1","dart.async#_varData","_js_helper#_name","engine.dart#_coverage","dart._internal#_endIndex","codeUnitsEqual","dart.async#_captured_s_2","toTrace","source_maps.parser#_segmentError","pool.dart#_closeGroup","bindUnaryCallback","dart.collection#_length","runner_suite.dart#_controller","dart.js_util#_captured_T_1","dart.async#_delegationTarget","storedCallback","declarer.dart#_solo","round","rti#_bind","errorCallback","functions.dart#_captured_V1_3","dart.convert#_allowMalformed","lastIndexOf","expanded.dart#_onError","declarer.dart#_setUpAll","core_matchers.dart#_description","restartable_timer.dart#_callback","metadata.dart#_skip","dart2jsArgs","subscription_stream.dart#_captured_error_1","dart.async#_resultOrListeners","relativeRootPattern","dart.async#_onError","stream_completer.dart#_createController","dart.collection#_previous","dart.async#_setError","file.dart#_isNearCachedLine","wrappers.dart#_setBase","equals_matcher.dart#_compareIterables","add","stream_group.dart#_listenToStream","html_common#_box_0","visitNot","complete","cast","engine.dart#_skippedGroup","type_matcher.dart#_name","dart.core#_errorExplanation","close","highlight","source_maps.parser#_mappings","putIfAbsent","_js_helper#_captured_performance_0","isFinite","runSkipped","isUnicode","addError","toChain","_js_helper#_map","dart.async#_captured_this_1","setUpAll","declarer.dart#_noRetry","spanFor","dart.async#_errorCallback=","dart.dom.html#_captured_onData_0","count","dart.async#_isComplete","dart.async#_captured_span_2","remote_listener.dart#_captured_groups_2","setAll","dart.async#_onValue","setDestinationSink","scanner.dart#_getNext","packageConfigMap","dart.core#_captured_tables_0","writeln","expanded.dart#_printPlatform","_js_helper#_trace","dart.async#_mayResumeInput","invalidValue","dart.async#_recordPause","stack_zone_specification.dart#_captured_T1_3","span_scanner.dart#_scanner","expanded.dart#_bold","file.dart#_start","noMoreLiveTests","dart.dom.html#_unlisten","engine.dart#_runCalled","string_scanner.dart#_position","removeFragment","pool.dart#_released","dart.async#_setValue","firstMatch","dart.async#_captured_originalSource_0","liveSuite","_js_helper#_next","source_maps.parser#_internal","dart.core#_isFile","isLoadSuite","guarantee_channel.dart#_streamController","dart.dom.html#_addEventListener","dart._internal#_endOrLength","resolveUri","_js_helper#_addHashTableEntry","whenTrue","isEmpty","scanner.dart#_multiLineComment","iterable_set.dart#_base","dart.async#_checkState","dart.async#_captured_future_3","dart.async#_inCallback","expanded.dart#_captured_this_0","files","splitMapJoin","toFilePath","internalRemove","toolString","stream_queue.dart#_failClosed","_interceptors#_toListFixed","group.dart#_captured_platform_0","lazy_trace.dart#_captured_this_0","remaining","dart.core#_captured_portStart_1","parser.dart#_conditional","equals_matcher.dart#_match","dart.core#_pathSegments","firstWhere","floor","padLeft","stack_zone_specification.dart#_captured_R_5","trace.dart#_captured_longest_0","onMessage","engine.dart#_addedSuites","dart.core#_captured_host_0","engine.dart#_captured_skipped_1","expanded.dart#_color","stack_zone_specification.dart#_run","dart.core#_mergePaths","getText","declarer.dart#_trace","subscription_stream.dart#_captured_handleError_1","dart.core#_isHttp","expanded.dart#_lastProgressPassed","month","apply","invoker.dart#_captured_outstandingCallbacksForBody_1","dart.async#_badEventState","metadata.dart#_captured_validVariables_0","canonicalizePart","toRadixString","dart.collection#_cell","dart.core#_simpleMerge","remote_listener.dart#_runLiveTest","stream_queue.dart#_addRequest","dart.collection#_removeHashTableEntry","validate","queue_list.dart#_table","future_group.dart#_pending","matchesErrorTest","dart.async#_removeListener","hasErrorTest","expanded.dart#_onDone","dart.async#_onPause","packageConfigUri","expanded.dart#_lastProgressSkipped","engine.dart#_box_0","rti#_check","isRelative","platform_selector.dart#_captured_selector_0","metadata.dart#_retry","_js_helper#_input","nextIteration","expanded.dart#_timeString","pointSpan","variableName","dart.core#_schemeCache","insert","day","lazy_trace.dart#_captured_predicate_1","putIntoMap","live_test_controller.dart#_state","lines","dart.async#_recordCancel","dart.async#_sendError","_js_helper#_newHashTable","removeFirst","pool.dart#_runOnRelease","source_maps.parser#_findColumn","dart.async#_removeListeners","trim","stream_queue.dart#_close","queue_list.dart#_head","_js_helper#_index","isDartVM","stream_sink_completer.dart#_sink","virtualChannel","listeners","dart.core#_host","stream_queue.dart#_subscription","bindCallbackGuarded","containsSeparator","inMinutes","endColumn","stream_channel_completer.dart#_streamCompleter","right","hasAbsolutePath","_js_helper#_re","varData","onComplete","dart.collection#_get","toUri","dart.core#_fragmentStart","suite_channel_manager.dart#_outgoingConnections","hasPort","dart.collection#_modified","runtime","getLine","highlighter.dart#_countTabs","_js_helper#_nativeAnchoredRegExp","dart.async#_waitsForCancel","run","_js_helper#_captured_ex_0","errorZone","foundResult","engine.dart#_onSuiteAddedController","dart.async#_captured_future_2","stream_completer.dart#_setSourceStream","suite_channel_manager.dart#_incomingConnections","declarer.dart#_setUpAlls","getColumn","dart.collection#_element","dart.async#_errorTest","_js_helper#_argumentsExpr","schedule","dart.collection#_captured_result_0","stream_channel_completer.dart#_sinkCompleter","dart.async#_eventScheduled","highlighter.dart#_writeTrailingLines","rootLength","live_suite_controller.dart#_captured_liveTest_1","normalize","invoker.dart#_closableKey","live_test_controller.dart#_controller","isSync","dart.convert#_parent","source","engine.dart#_runLiveTest","dart.async#_isPendingComplete","source_maps.parser#_captured_line_0","copyList","dart.convert#_writeSurrogate","remote_listener.dart#_serializeTest","dart.convert#_fillBuffer","toJson","highlighter.dart#_writeLastLine","addOutstandingCallback","_interceptors#_codeUnitAt","chainFor","~/","dart.collection#_addHashTableEntry","package","isHeadless","completeError","verboseChain","declarer.dart#_parent","stream_group.dart#_subscriptions","listen","describeMismatch","closed","stream_queue.dart#_streamQueue","declarer.dart#_runSetUps","pretty_print.dart#_captured_indent_0","dart.typed_data.implementation#_checkPosition","declarer.dart#_prefix","stream_completer.dart#_linkStreamToController","setSourceStream","targetUrl","_js_helper#_message","inMilliseconds","dart.async#_previous","dart.js_util#_captured__convertedObjects_0","declarer.dart#_entries","dart.async#_setPendingEvents","stack_zone_specification.dart#_captured_node_2","dart._internal#_length","invoker.dart#_guardIfGuarded","done","declarer.dart#_platformVariables","highlighter.dart#_isOnlyWhitespace","isJS","isEof","sourceLine","dart._internal#_f","isBroadcast","invoker.dart#_captured_invoker_0","remote_listener.dart#_box_0","declarer.dart#_tearDowns","dart.async#_close","multi_channel.dart#_nextId","remote_listener.dart#_captured_liveTest_0","engine.dart#_closed","highlighter.dart#_writeText","matchAsPrefix","invoker.dart#_guarded","lazy_trace.dart#_inner","_js_helper#_unlinkCell","live_suite_controller.dart#_failed","stack_zone_specification.dart#_box_0","lazy_chain.dart#_captured_this_0","relativePathToUri","dart.async#_isChained","newJsMap","pool.dart#_allocatedResources","highlighter.dart#_color","dart.async#_mayAddEvent","group.dart#_map","multi_channel.dart#_captured_this_1","dart.collection#_computeHashCode","dart.async#_complete","dart.async#_captured_result_2","dart.async#_captured_e_1","null_stream_sink.dart#_captured_this_0","remote_listener.dart#_captured_printZone_0","dart.async#_isAddingStream","dart.collection#_newLinkedCell","_interceptors#_shrReceiverPositive","fragment","dart.async#_sendData","dart.dom.html#_pauseCount","runUnary","dart.convert#_upgradedMap","scanner.dart#_scanner","precompiledPath","dart.dom.html#_target","dart.core#_hashCodeCache","runGuarded","span_scanner.dart#_lastSpan","toList","metadata.dart#_verboseTrace","dart.async#_whenCompleteAction","replaceAllMapped","rti#_as","invoker.dart#_captured_counter_3","_js_helper#_nativeGlobalRegExp","declarer.dart#_soloEntries","addSubscription","increment","stack_zone_specification.dart#_captured_R_4","pool.dart#_onResourceReleased","dart.collection#_strings","dart.async#_handle","hasListener","dart.async#_ensureDoneFuture","stack_zone_specification.dart#_handleUncaughtError","remote_listener.dart#_captured_printZone_1","invoker.dart#_invokerZone","_js_helper#_captured_transform_1","pause","runUnaryGuarded","spanFrom","runner_suite.dart#_config","runner_suite.dart#_onClose","dart.async#_zone","stream_sink_completer.dart#_controller","highlighter.dart#_captured_textInside_1","[]","expanded.dart#_lastProgressMessage","invoker.dart#_captured_fn_2","lastPendingEvent","inMicroseconds","visitConditional","dart._internal#_index","stream_sink_completer.dart#_doneCompleter","inSeconds","live_test_controller.dart#_onStateChangeController","rti#_cachedRuntimeType","dart.async#_captured_controller_0","packageResolver","dart.async#_captured_eagerError_2","stack_zone_specification.dart#_captured_T2_4","live_test_controller.dart#_onClose","live_test_controller.dart#_groups","dart.core#_duration","file.dart#_decodedChars","parents","parent","_js_helper#_jsObject","dart.async#_captured_test_0","stream_group.dart#_state","startsWith","dart.collection#_set","absolute","foreign","dart.async#_hasError","merge","handleValue","resolve","rti#_message","stream_queue.dart#_updateRequests","dart.async#_delegateCache","hasFragment","traces","isScheduled","union_set.dart#_iterable","invoker.dart#_onCloseCompleter","isNotEmpty","test.dart#_captured_body_0","hasScheme","engine.dart#_closedBeforeDone","span_exception.dart#_span","dart.async#_captured_cleanUp_1","dart._internal#_source","fuse","live_suite_controller.dart#_suite","invoker.dart#_runTearDowns","dart.async#_captured_elements_0","addStream","rti#_precomputed3","null_stream_sink.dart#_checkEventAllowed","chain.dart#_captured_terse_0","patterns","stream_completer.dart#_setEmpty","dart.core#_fragment","createTimer","variables","runner_suite.dart#_onDebuggingController","dart.async#_captured_protected_0","every","trace.dart#_captured_trace_0","perform","dart.async#_captured_bodyFunction_0","dart.convert#_allowInvalid","pool.dart#_captured_this_0","outputId","dart.async#_onResume","dart.convert#_extraUnits","toUpperCase","equals_matcher.dart#_value","dart.async#_controller","multi_channel.dart#_captured_this_0","engine.dart#_group","guarantee_channel.dart#_addStreamSubscription","queue_list.dart#_add","forEachJsField","_js_helper#_regExp","_js_helper#_nums","_js_helper#_getTableBucket","dart.convert#_computeKeys","stack_trace_mapper.dart#_mapping","millisecondsSinceEpoch","_js_helper#_cell","connectOut","union_set.dart#_sets","engine.dart#_onUnpaused","_js_helper#_genericClosure","stack_trace_mapper.dart#_mapContents","pretty_print.dart#_captured_indent_2","multi_channel.dart#_innerStreamSubscription","substring","entries","multi_channel.dart#_inner","hasRun","stack_zone_specification.dart#_onError","elapsedTicks","engine.dart#_onTestStartedGroup","tearDownAll","core_matchers.dart#_matcher","expanded.dart#_engine","dart.async#_captured_future_0","_js_helper#_captured_getTag_0","names","internalContainsKey","dart.async#_captured_start_2","dart.async#_addStreamState","stream_queue.dart#_extractStream","setState","clear","dart.core#_stop","stream_group.dart#_closed","os","hasPartialInput","dart.collection#_getBucket","declarer.dart#_timeout","parts","context.dart#_pathDirection","findSlot","dart.async#_scheduleMicrotask","engine.dart#_loadPool","stream_sink_completer.dart#_canSendDirectly","local","hour","packageRoot","scanner.dart#_endOfFileEmitted","dart.async#_captured_callback_0","chain.dart#_captured_terse_1","future_group.dart#_closed","dart.convert#_value","readSlot","fork","elementAt","dart.async#_runUnary","writeAll","dart.async#_captured_callback_3","stack_zone_specification.dart#_captured_arg_1","writeSlot","dart.async#_next","rti#_hashCode","stream_group.dart#_onListen","dart.async#_captured_sourceResult_2","runOnce","dart.convert#_reviver","invoker.dart#_captured_this_1","innerStream","lazy_chain.dart#_thunk","stream_queue.dart#_ensureListening","stack_zone_specification.dart#_chains","dart.async#_captured_listener_1","startColumn","status","dart.async#_removeAfterFiring","multi_channel.dart#_box_0","dart.dom.html#_eventType","dart.collection#_head","resume","_js_helper#_removeHashTableEntry","_js_helper#_match","dart.async#_isFiring","includeTags","_interceptors#_current=","intersection_selector.dart#_selector2","rti#_rti","dart.async#_asyncComplete","request","expanded.dart#_gray","stack_trace_formatter.dart#_except","engine.dart#_subscriptions","subscription_stream.dart#_source","stack_trace_mapper.dart#_sdkRoot","dart.async#_recordResume","scheme","dart.convert#_expectedUnits","source_maps.parser#_captured_column_0","dart.collection#_closeGap","highlighter.dart#_buffer","sink.dart#_sink","map","parser.dart#_scanner","rti#_bindCache","dart._internal#_name","stack_trace_formatter.dart#_only","removeEventListener","_js_helper#_setTableEntry","live_test_controller.dart#_close","dart.core#_queryParameters","_js_helper#_length","engine.dart#_captured_this_1","pretty_print.dart#_box_0","addMapping","description.dart#_out","dart.async#_captured_R_3","dart.async#_isClosed","flush","remote_listener.dart#_captured_getMain_1","expanded.dart#_onStateChange","functions.dart#_captured_K1_2","toLowerCase","heartbeat","registerBinaryCallback","_js_helper#_method","dart.collection#_writeToList","contains","removeOutstandingCallback","functions.dart#_captured_value_1","dart.async#_prependListeners","dart.core#_data","chain.dart#_captured_callback_0","guarantee_channel.dart#_inner","dart.async#_fork","_js_helper#_nextIndex","dart.core#_captured_uri_0","source_maps.parser#_maps","dart.convert#_bufferIndex","expanded.dart#_red","dart.collection#_unlinkCell","forEachObjectKey","isRootRelative","engine.dart#_restarted","platform_selector.dart#_captured_validVariables_1","dart.async#_doneFuture","dart.convert#_original","dart.async#_registerCallback=","foldFrames","remote_listener.dart#_captured_channel_3","live_test_controller.dart#_onMessageController","separatorPattern","dart.convert#_isFirstCharacter","stack_zone_specification.dart#_errorZone","addStreamFuture","declarer.dart#_built","rti#_requiredPositional","dart.async#_captured_test_2","dart.collection#_table","_js_helper#_deleteTableEntry","split","group.dart#_captured_callback_0","remote_listener.dart#_listen","source_maps.parser#_mapUrl","validatePlatformSelectors","dart.async#_map","hasEmptyPath","sublist","stream_completer.dart#_stream","invoker.dart#_onRun","dart.async#_subscribe","util.dart#_captured_x_0","stream_completer.dart#_sourceStream","metadata.dart#_chainStackTraces","stream_sink_completer.dart#_setDestinationSink","addTearDownAll","live_suite_controller.dart#_isComplete","dart.async#_captured_result_0","equals_matcher.dart#_captured_expectedElement_1","package_config_resolver.dart#_uri","dart.async#_reverseListeners","dart.collection#_last","invoker.dart#_captured_timeout_0","walk","dart.core#_userInfo","formatStackTrace","remove","dart.async#_captured_listener_2","_js_helper#_keys","dart.convert#_encoder","runBinary","dart.async#_cancelFuture","future_group.dart#_captured_this_0","handlesComplete","trace.dart#_box_0","dart.async#_captured_pos_1","invoker.dart#_test","metadata.dart#_captured_timeout_2","guarantee_channel.dart#_box_0","cancelSchedule","sourceNameId","runtimeType","dart.collection#_modifications","then","pretty_print.dart#_captured_maxLineLength_1","dart.convert#_subsetMask","testRandomizeOrderingSeed","visitOr","expanded.dart#_lastProgressFailed","dart.convert#_first","millisecond","highlighter.dart#_captured_this_1","dart.async#_rootRegisterUnaryCallback","dart.async#_captured_f_1","remote_listener.dart#_captured_this_0","reversed","dart.core#_queryParameterLists","hasErrorCallback","metadata.dart#_captured_testOn_1","left","live_test_controller.dart#_isClosed","highlighter.dart#_captured_this_0","dart.dom.html#_start","lazy_chain.dart#_chain","null_stream_sink.dart#_addingStream","_js_helper#_getTableCell","forTarget","source_map_stack_trace.dart#_captured_minified_2","peekChar","dart.collection#_next","build","dart.convert#_process","rti#_precomputed2","lastMatch","expanded.dart#_description","metadata.dart#_captured_chainStackTraces_5","remote_listener.dart#_captured_printZone_5","decoder","hasAuthority","unaryOnError","context.dart#_needsNormalization","onResume","expanded.dart#_printPath","_interceptors#_tdivSlow","_js_helper#_rest","expanded.dart#_paused","declarer.dart#_tearDownAll","dart.async#_captured_result_3","lazy_trace.dart#_thunk","waitForOutstandingCallbacks","dart.async#_mayComplete","dart.async#_captured_T_5","function","dart.collection#_offset","dart.async#_captured_value_1","bindUnaryCallbackGuarded","dart.async#_sendDone","invoker.dart#_outstandingCallbacks","extensions","dart.async#_closeUnchecked","_interceptors#_toListGrowable","highlighter.dart#_captured_end_2","invoker.dart#_captured_this_0","codeUnits","rti#_precomputed1","stack_zone_specification.dart#_captured_f_1","internalGet","suite_channel_manager.dart#_names","pattern","dart.async#_captured_stackTrace_1","live_suite_controller.dart#_liveSuite","source_maps.parser#_consumeNewLine","metadata.dart#_box_0","suiteSink","dart.core#_port","engine.dart#_passedGroup","dart.core#_hostStart","context.dart#_isWithinOrEquals","expanded.dart#_captured_liveTest_1","live_suite_controller.dart#_closeMemo","dart.async#_captured_target_0","dart.core#_captured_host_1","dart.core#_uriCache","_js_helper#_nativeAnchoredVersion","scanner.dart#_consumeWhitespace","scanner.dart#_scanOr","dart.dom.html#_tryResume","runner_suite.dart#_suite=","toSet","chain.dart#_captured_level_1","sourceColumn","dart.async#_nextListener","connectIn","_js_helper#_isCaseSensitive","invoker.dart#_body","encoder","metadata","dart.async#_isInputPaused","inHours","allowRelease","_js_helper#_captured_getUnknownTag_0","invoker.dart#_completer","intersection","state","dart.async#_state","reportLiveTest","dart.async#_clearPendingComplete","invoker.dart#_captured_timeout_2","stack_trace_mapper.dart#_mapUrl","multi_channel.dart#_controllers","declarer.dart#_tearDownAllTrace","chain.dart#_captured_T_1","highlighter.dart#_box_0","multi_channel.dart#_captured_T_2","expanded.dart#_subscriptions","dart.collection#_captured_V_2","stack_zone_specification.dart#_captured_original_1","subscription_stream.dart#_captured_this_0","stream_queue.dart#_captured_this_0","live_test_controller.dart#_runCalled","group.dart#_testCount","onDone","dart.async#_isInitialState","isEven","_js_helper#_types","root","highlighter.dart#_writeIntermediateLines","library","dart.core#_hasValue","member","dart.async#_lastSubscription=","dartException","dart.core#_schemeEnd","_js_helper#_captured_this_0","isPosix","dart._internal#_hasSkipped","dart.convert#_isUpgraded","dart.async#_print=","dart.async#_rootRegisterBinaryCallback","dart.dom.html#_useCapture","test.src.runner.browser.post_message_channel#_captured_port_0","type","scanner.dart#_scanIdentifier","dart.async#_onDone","origin","multi_channel.dart#_parent","%","_js_helper#_keysArray","span_scanner.dart#_sourceFile","metadata.dart#_captured_skip_3","insertAll","platform_selector.dart#_inner","pretty_print.dart#_captured_pp_0","engine.dart#_captured_this_0","dart.async#_eventState","child","forTag","guarantee_channel.dart#_channel","dart.async#_captured_iterator_0","checkMutable","remote_listener.dart#_captured_controller_3","replaceFirst","file.dart#_binarySearch","transform","stack_trace_formatter.dart#_mapper","_interceptors#_tdivFast","trace.dart#_captured_oldPredicate_0","_js_helper#_exception","stack_zone_specification.dart#_captured_arg2_2","remote_listener.dart#_suite","isIdentifier","rti#_primary","removeAt","dart.async#_captured_div_1","dart._internal#_current=","_js_helper#_current=","dart.dom.html#_removeEventListener","rti#_optionalNamed","dart.async#_isSent","_js_helper#_receiver","forPlatform","dart.async#_delegate","firstPendingEvent","inSameErrorZone","frames","highlighter.dart#_span","remote_listener.dart#_captured_channel_2","dart._internal#_currentExpansion","union_set_controller.dart#_sets","dart.async#_captured_this_0","_js_helper#_isUnicode","lazy_trace.dart#_captured_terse_2","span_exception.dart#_source","dart._internal#_start","_js_helper#_modifications","dart.core#_nextPosition","dart.convert#_toEncodable","hasMatch","dart.async#_canFire","postMessage","internalComputeHashCode","invoker.dart#_outstandingCallbackZones","invoker.dart#_captured_zone_1","rootPattern","multi_channel.dart#_captured_id_1","platform_selector.dart#_span","isUtc","dart.dom.html#_postMessage_2","set","pathFromUri","dart.async#_hasOneListener","engine.dart#_activeLoadTests","_js_helper#_containsTableEntry","restartable_timer.dart#_timer","dart.async#_pendingEvents","guarantee_channel.dart#_addError","_js_helper#_captured_prototypeForTag_0","dart.async#_nullErrorHandler","dart.async#_captured_cleanUp_3","+","dart.async#_chainSource","dart.core#_portStart","remote_listener.dart#_printZone","multi_channel.dart#_captured_T_1","frame.dart#_captured_frame_0","source_maps.parser#_columnStart","functions.dart#_captured_result_0","engine.dart#_addLiveSuite","_js_helper#_pattern","guarantee_channel.dart#_onStreamDisconnected","dart.core#_stackTrace","elapsed","accept","dart.async#_subscription","stack_trace_mapper.dart#_packageResolver","stream_queue.dart#_eventsReceived","_js_helper#_isMultiLine","live_test_controller.dart#_errors","_interceptors#_index","onZero","chain.dart#_captured_chain_0","engine.dart#_runSkippedTest","pretty_print.dart#_captured__prettyPrint_1","removeAll","stack_zone_specification.dart#_captured_arg1_1","dart.async#_callOnCancel","live_suite_controller.dart#_onCompleteGroup","last","runner_suite.dart#_channelNames","sourceUrl","dart.async#_onListen","pool.dart#_resetTimer","engine.dart#_liveSuites","stream_channel_completer.dart#_set","file.dart#_end","dart.async#_captured_value_2","runner_suite.dart#_gatherCoverage","dart.core#_isHttps","dart.collection#_captured_result_1","multi_channel.dart#_closedIds","remote_listener.dart#_captured_channel_0","isNewLine","invoker.dart#_runCount","union_set.dart#_captured_this_0","suite.dart#_runSkipped","live_suite_controller.dart#_skipped","stack_zone_specification.dart#_captured_R_2","dart.core#_isPackage","dart.async#_expectsEvent","metadata.dart#_validateTags","copy","invoker.dart#_captured_error_2","dart.async#_addPending","dart.convert#_stringSink","remainder","guarantee_channel.dart#_inAddStream","pool.dart#_captured_registered_1","runtime.dart#_captured_serialized_0","pool.dart#_onReleaseCompleters","functions.dart#_captured_result_1","inGoogle","runBinaryGuarded","guarantee_channel.dart#_allowErrors","declarer.dart#_captured_body_0","dart.async#_createSubscription","condition","checkGrowable","absolutePathToUri","suite.dart#_runtimes","engine.dart#_captured_loadResource_2","dart.collection#_rest","dart.async#_setRemoveAfterFiring","guarantee_channel.dart#_sink","metadata.dart#_captured_retry_6","context.dart#_current","dart.async#_registerBinaryCallback=","stream_completer.dart#_controller","isCore","highlighter.dart#_captured_line_1","getOffset","dart.async#_createPeriodicTimer","pool.dart#_timeout","mustCopy","dart.async#_firstSubscription","scanner.dart#_next","onTestStarted","scanner.dart#_scanAnd","dart.async#_once","dart.core#_query","config","dart.async#_future","next","style","invoker.dart#_tearDowns","_js_helper#_getBucket","expanded.dart#_stopwatch","engine.dart#_active","dart.async#_rootRun","dart.async#_guardCallback","live_suite_controller.dart#_onTestStartedController","path","dart.async#_target","functions.dart#_captured_K2_0","suite.dart#_knownTags","dart.async#_tick","pool.dart#_onReleaseCallbacks","remote_listener.dart#_captured_suite_0","dart.core#_pathStart","platform_selector.dart#_captured_platform_0","restartable_timer.dart#_duration","test.src.runner.browser.post_message_channel#_captured_portSubscription_1","guarantee_channel.dart#_captured_this_0","setEmpty","dart.typed_data.implementation#_invalidPosition","dart.collection#_containsKey","string_scanner.dart#_lastMatchPosition","metadata.dart#_captured_onPlatform_8","lazy_chain.dart#_captured_predicate_1","dart.async#_addListener","multi_channel.dart#_mainController","guarantee_channel.dart#_captured_this_1","invoker.dart#_box_0","_interceptors#_length","nextKind","dart.collection#_box_0","guarantee_channel.dart#_subscription","addTo","dart.core#_uri","isDone","dart.async#_stateData","setChannel","dart.async#_captured_R_2","stream_channel_completer.dart#_channel=","runes","dart.core#_jsWeakMapOrKey","dart.collection#_queue","null_stream_sink.dart#_closed","file.dart#_lineStarts","stream_queue.dart#_eventQueue","isSeparator","_js_helper#_arguments","guarantee_channel.dart#_disconnected","span_with_context.dart#_context","stream_group.dart#_captured_stream_1","source_maps.parser#_indexFor","dart.async#_cancelOnError","rest","rti#_rest","dart.async#_captured_stackTrace_2","stream_subscription.dart#_source","dart.core#_toFilePath","sourceUrlId","_interceptors#_shrOtherPositive","guarantee_channel.dart#_closed","future_group.dart#_onIdleController","dart.core#_value","dart.async#_captured_error_1","writeCharCode","declarer.dart#_tearDownAlls","source_map_stack_trace.dart#_captured_sourceMap_1","_js_helper#_self","onStateChange","invoker.dart#_timeoutTimer","currentChain","print_sink.dart#_buffer","live_test_controller.dart#_suite","string","engine.dart#_captured_liveTest_1","isBrowser","engine.dart#_suiteController","rti#_canonicalRecipe","dart.dom.html#_canceled","_js_helper#_nativeGlobalVersion","dart.async#_pending","queue_list.dart#_tail","dart.async#_createTimer","passed","dart.async#_onData","dart.async#_captured_action_1","declarer.dart#_captured_body_1","stream_group.dart#_captured_this_0","remote_listener.dart#_captured_liveTest_1","remote_listener.dart#_captured_beforeLoad_4","invoker.dart#_printsOnFailure","dart.core#_writeAuthority","pool.dart#_onTimeout","startChunkedConversion","handleWhenComplete","guarantee_channel.dart#_addStreamCompleter","dart.collection#_captured_K_1","inputId","cloneNotRequired","first","shuffle","engine.dart#_pauseCompleter","newJsList","dart.async#_registerUnaryCallback=","key","_js_helper#_first","dart.async#_captured_T_1","name","dart.dom.html#_postMessage_1","dart.collection#_keys","onPause","dart.async#_captured_data_1","hasQuery","dart.collection#_nums","dart.async#_setErrorObject","dart.collection#_source","handlesValue","stack_zone_specification.dart#_captured_R_3","remote_listener.dart#_captured_channel_1","seen","lazy_chain.dart#_inner","intersection_selector.dart#_selector1","source_maps.parser#_consumeNewSegment","dart.convert#_urlSafe","input","subscription_stream.dart#_captured_stackTrace_2","isRunning","trace.dart#_captured_level_1","impl.dart#_selector","stream_queue.dart#_pause","dart.core#_isScheme","parsed_path.dart#_captured_this_0","declarer.dart#_captured_this_0","stream_completer.dart#_isSourceStreamSet","stream_channel_controller.dart#_local","length","separator","stack_zone_specification.dart#_captured_T_3","subscription_stream.dart#_captured_handleError_0","dart.async#_setChained","expanded.dart#_yellow","equals_matcher.dart#_captured_location_2","cleanupSlots","equals_matcher.dart#_captured_depth_3","suite.dart#_jsTrace","dart.async#_captured_dispatch_1","dart.collection#_end","equals_matcher.dart#_captured_matcher_0","dart.collection#_modificationCount","dart.convert#_processed","pool.dart#_timer","dart.core#_writeString","metadata.dart#_captured_platform_1","string_scanner.dart#_fail","isClosed","keys","isPaused","test_core#_captured_engine_0","declarer.dart#_setUps","expanded.dart#_sink","dart.collection#_grow","text","live_test_controller.dart#_onErrorController","dart.core#_text","dart._internal#_captured_this_0","handlesError","dart.core#_contents","dart.async#_captured_milliseconds_1","source_map_stack_trace.dart#_captured_sdkLib_3","dart.core#_initializeText","chain.dart#_captured_trace_0","rti#_evalCache","equals_matcher.dart#_limit","dart.async#_toggleEventId","live_suite_controller.dart#_active","stack_zone_specification.dart#_createNode","toSpec","userInfo","excludeTags","dart.core#_separatorIndices","test.dart#_captured_completer_1","rti#_is","dart.async#_isUsed","highlighter.dart#_paddingAfterSidebar","code","sink","metadata.dart#_captured_skipReason_7","stream_sink_completer.dart#_destinationSink","future_group.dart#_values","suite.dart#_metadata","engine.dart#_addLoadSuite","invoker.dart#_captured_message_1","values","_js_helper#_nativeRegExp","validator.dart#_isDefined","stream_queue.dart#_isDone","_js_helper#_isDotAll","offset","putIntoObject","copies","dart.async#_runBinary","_js_helper#_start","stream_queue.dart#_source","year","stream_queue.dart#_requestQueue","$le","$indexSet","$index","$xor","$or","$eq","$mod","$shr","$and","$ge","$gt","$lt","$mul","$not","$shl","$div","$sub","$add","$negate","$tdiv","checkString","instanceTypeName","constructorNameFallback","isJsArray","getIndex","selfFieldName","receiverFieldName","_rtiEval","extractFunctionTypeObjectFrom","rawRtiToJsConstructorName","isGenericFunctionTypeParameter","isDartFunctionType","isDartFutureOrType","isNotIdentical","_instanceFunctionType","instanceOf","invoke","setDispatchProperty","propertyGet","regExpGetGlobalNative","stringReplaceJS","checkNull","regExpGetNative","_getFutureOrArgument","_lookupFutureRti","_setPrecomputed1","_getBindCache","_setBindCache","_getGenericFunctionBase","_getKind","_lookupStarRti","_canonicalRecipeOfStar","_Universe._lookupStarRti","_lookupQuestionRti","_canonicalRecipeOfQuestion","_Universe._lookupQuestionRti","_lookupFutureOrRti","_canonicalRecipeOfFutureOr","_Universe._lookupFutureOrRti","_getInterfaceName","_getBindingBase","_getReturnType","_getGenericFunctionParameterIndex","asString","allocate","_setRequiredPositional","_setOptionalPositional","_setOptionalNamed","_setCachedRuntimeType","_setTypeCheckFunction","_setAsCheckFunction","_getPrimary","_setSpecializedTestResource","_setIsTestFunction","isLegacySubtype","_getSpecializedTestResource","_getStarArgument","_getQuestionArgument","_lookupErasedRti","_getEvalCache","_setEvalCache","_cacheSet","_createTerminalRti","_setKind","_setCanonicalRecipe","_createUnaryRti","_setPrimary","_createGenericFunctionParameterRti","_canonicalRecipeOfInterface","_createInterfaceRti","_setRest","_canonicalRecipeOfBinding","_createBindingRti","_canonicalRecipeOfFunction","_canonicalRecipeOfFunctionParameters","_createFunctionRti","_canonicalRecipeOfGenericFunction","_createGenericFunctionRti","charCodeAt","toGenericFunctionParameter","_lookupDynamicRti","_lookupVoidRti","pushStackFrame","push","setPosition","handleTypeArguments","collectArray","arraySplice","handleFunctionArguments","handleOptionalGroup","handleNamedGroup","collectNamed","isDigit","evalTypeVariable","_lookupNeverRti","_lookupAnyRti","_castToRti","stringLessThan","functionParametersEqual","lookupInterceptorByConstructor","cacheInterceptorOnConstructor","_future","_setValue","_isComplete","_setPendingComplete","_mayComplete","_mayAddListener","_chainSource","_setChained","_hasError","_error","_zone","_removeListeners","_cloneResult","_setErrorObject","_scheduleImmediate","_leave","_createPeriodicTimer","printToConsole","es6","tryParse","objectToHumanReadableString","makeListFixedLength","makeFixedListUnmodifiable","_stringFromJSArray","_stringFromUint8List","_writeOne","_startsWithData","_checkLength","_internal","_stringOrNullLength","_writeString","_isZoneIDChar","_isRegNameChar","_isGeneralDelimiter","_isSchemeCharacter","_isUnreservedChar","fromString","_lineStarts","fromList","_incomingConnections","_outgoingConnections","_names","_requestedResources","_onReleaseCallbacks","_onReleaseCompleters","_closeMemo","_completer","AsyncMemoizer._completer","factor","_group","_values","FutureGroup._completer","_suiteController","_onTestStartedGroup","_state","_subscriptions","StreamGroup._subscriptions","_passedGroup","_skippedGroup","_failedGroup","_active","_addedSuites","_onSuiteAddedController","Engine._onSuiteAddedController","_liveSuites","_onSuiteStartedController","Engine._onSuiteStartedController","_restarted","_activeLoadTests","_sets","_errors","LiveTestController.completer","_onStateChangeController","LiveTestController._onStateChangeController","_onErrorController","LiveTestController._onErrorController","_onMessageController","LiveTestController._onMessageController","serializeSuite","_closable","_out","myInlinedMethod","_lineStart","_columnStart","_maps","_mappings","_setUps","_tearDowns","_setUpAlls","_timeout","_tearDownAlls","_entries","_soloEntries","_isTextAtEndOfContext","_chains","_createKey","_currentSpec","_createNode","withGuarantees","_child","_onCompleteGroup","_onCloseCompleter","LiveSuiteController._onCloseCompleter","_onTestStartedController","LiveSuiteController._onTestStartedController","_passed","_skipped","_failed","_toListGrowable","_mainController","_controllers","_pendingIds","_closedIds","Window.onMessage","jsify","listToString","_handleIEtoString","_codeUnitAt","_currentExpansion","_types","_getBucket","_isMultiLine","_isUnicode","_isTrailSurrogate","_rtiBind","_addListener","_isFiring","_setRemoveAfterFiring","_isEmpty","_isAddingStream","_expectsEvent","_hasOneListener","_errorTest","_onError","thenAwait","_setError","_isPendingComplete","_clearPendingComplete","_whenCompleteAction","_onValue","_isInitialState","_mayAddEvent","_isCanceled","_isPaused","_isClosed","_isInputPaused","_hasPending","_inCallback","_waitsForCancel","_eventScheduled","_isScheduled","_rethrow","_hasTableEntry","identityHashCode","checkValidIndex","_grow","_checkModification","_isUpgraded","parseHexByte","withBufferSize","unary-","_microseconds","_checkType","_getFromObject","_setOnObject","_now","_isWindows","_toFilePath","_initializeText","_writeAuthority","_isPackage","convertDartToNative_SerializedScriptValue","_canceled","fromMillisecondsSinceEpoch","isJavaScriptSimpleObject","_isSourceStreamSet","_setSourceStream","_NextRequest._completer","_pause","_close","_setEmpty","_scanOr","_scanAnd","_scanIdentifier","_setBase","StringDescription.add","addStateInfo","_indent","reset","_onResourceReleased","_consumeValue","glyphs","_paddingAfterSidebar","_normalizeContext","_buffer","Highlighter._","dataFromString","_disabled","_doneCompleter","_GuaranteeSink._doneCompleter","_inAddStream","MessageEvent.data","_prefix","_solo","Declarer._solo","Invoker._onCloseCompleter","_closableKey","_outstandingCallbackZones","_counterKey","_printsOnFailure","_AsyncCounter._completer","_guardIfGuarded","_print","_run","jsonDecode","_except","_only","_MultiChannel.stream","_eventQueue","_requestQueue","ascii","_sink","_listen","_streamCompleter","_stream","_sinkCompleter","markGrowable","_timeString","_local","_channelNames","watch","ExpandedReporter.watch","_stopwatch","ExpandedReporter._stopwatch","_initTicker","Engine.onTestStarted","provokeCallErrorOnNull","provokeCallErrorOnUndefined","provokePropertyErrorOnNull","provokePropertyErrorOnUndefined"],"mappings":"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","x_org_dartlang_dart2js":{"minified_names":{"global":"main_closure,2397,internalBootstrapBrowserTest,535,Closure_fromTearOff,2398,StaticClosure,2399,BoundClosure,2400,Closure_functionCounter,2401,Closure_forwardCallTo,2402,Closure__computeSignatureFunctionNewRti,2403,_checkStringNullable,181,wrapException,42,CyclicInitializationError,2404,toStringWrapper,43,NullThrownError,2405,S,12,argumentErrorValue,40,ArgumentError,395,Error_safeToString,2406,_isBool,168,Error__objectToString,2407,Closure,2408,Primitives_objectTypeName,2409,Primitives__objectTypeNameNewRti,2410,Object,2411,instanceType,145,_rtiToString,184,Primitives__saneNativeClassName,2412,assertHelper,79,_unminifyOrTag,186,Rti__getInterfaceTypeArguments,2413,_rtiArrayToString,182,_functionRtiToString,90,Rti__getGenericFunctionBounds,2414,ioore,37,diagnoseIndexError,38,_isInt,173,_checkIntNullable,175,iae,36,IndexError$,2415,RangeError$value,2416,_checkNumNullable,178,RangeError,398,IndexError,404,setRuntimeTypeInfo,83,isTopType,243,Rti__getFunctionParameters,2417,ArgumentError$value,2416,_arrayInstanceType,147,UnsupportedError$,2415,throwExpression,44,UnsupportedError,405,unmangleGlobalNameIfPreservedAnyways,246,assertTest,77,AssertionError$,2415,AssertionError,394,TypeErrorImplementation$,2415,TypeErrorImplementation,75,_typeDescription,76,extractFunctionTypeObjectFromInternal,74,runtimeTypeToString,86,_runtimeTypeToString,87,unminifyOrTag,10,_joinArguments,92,_functionRtiToString0,90,extractKeys,245,JSArray_JSArray$markFixed,2418,JSArray,2419,JSArray_markFixedList,2420,StringBuffer,2421,_checkBoolNullable,170,getIsolateAffinityTag,82,IterableBase_iterableToFullString,2422,_isToStringVisiting,357,_toStringVisiting,2423,StringBuffer__writeAll,2424,IterableElementError_noElement,2425,StateError,407,ArrayIterator,2426,throwConcurrentModificationError,45,ConcurrentModificationError$,2415,ConcurrentModificationError,408,ListIterator,2427,ListMixin,2428,_checkValidIndex,124,Iterable,2429,initNativeDispatchFlag,2430,initNativeDispatch,104,UnimplementedError$,2415,lookupAndCacheInterceptor,99,getTagFunction,2431,dispatchRecordsForInstanceTags,2432,interceptorsForUncacheableTags,2433,alternateTagFunction,2434,makeLeafDispatchRecord,102,patchInteriorProto,101,makeDispatchRecord,248,JavaScriptIndexingBehavior,2435,UnimplementedError,406,initNativeDispatchContinue,105,initHooks,107,prototypeForTagFunction,2436,makeDefaultDispatchRecord,103,applyHooksTransformer,108,initHooks_closure,2437,initHooks_closure0,2437,initHooks_closure1,2437,_TypeError__TypeError$forType,2438,_TypeError,2439,_Error_compose,2440,_CastError__CastError$forType,2438,_CastError,2441,instanceOrFunctionType,144,_TypeError$fromMessage,2442,Rti__isUnionOfFunctionType,2443,closureFunctionType,143,getTypeFromTypesTable,151,_Universe_eval,2444,_Universe__parseRecipe,2445,_Parser_create,2446,_Parser_parse,2447,_Parser_handleDigit,2448,_Parser_handleIdentifier,2449,_Parser_toType,2450,_Universe__lookupGenericFunctionParameterRti,2451,_Universe__lookupTerminalRti,2452,_Parser_toTypes,2453,_Universe__lookupInterfaceRti,2454,_Universe__lookupGenericFunctionRti,2455,_Universe__lookupBindingRti,2456,_Parser_handleExtendedOperations,2457,assertThrow,78,_Universe__lookupUnaryRti,2458,_FunctionParameters,2459,_Universe__lookupFunctionRti,2460,_Parser_toTypesNamed,2461,_Universe__canonicalRecipeJoin,2462,_Universe__canonicalRecipeJoinNamed,2463,Rti,2464,_Universe__finishRti,2465,_generalTypeCheckImplementation,159,_generalAsCheckImplementation,158,_installSpecializedIsTest,154,_generalIsTestImplementation,156,_isTop,166,_asTop,167,int,2466,double,2467,_isNum,176,num,2468,String,2469,_isString,179,bool,2470,isLegacyTopType,242,_isTestViaProperty,157,_AssertionError,2471,Rti__getBindingArguments,2472,_Parser_indexToType,2473,_Universe_findRule,2474,Rti__getCanonicalRecipe,2475,_Universe_evalInEnvironment,2476,_CastError$fromMessage,2442,_isSubtype,233,Rti__getFutureFromFutureOr,2477,typesEqual,240,_isFunctionSubtype,236,_isInterfaceSubtype,237,typeEqual,238,namedTypesEqual,241,Future,272,_Universe_bind,2478,_instanceTypeFromConstructor,149,_instanceTypeFromConstructorMiss,150,_Universe_findErasedType,2479,BoundClosure_evalRecipeIntercepted,2480,BoundClosure_evalRecipe,2481,Closure_forwardInterceptedCallTo,2482,Closure_cspForwardCall,2483,BoundClosure_selfFieldNameCache,2484,BoundClosure_computeFieldNamed,2485,BoundClosure_selfOf,2486,BoundClosure_receiverFieldNameCache,2487,Closure_cspForwardInterceptedCall,2488,BoundClosure_receiverOf,2489,RuntimeError$,2415,RuntimeError,81,getRuntimeTypeInfo,84,substitute,95,invokeOn,97,internalBootstrapBrowserTest_closure,2490,RemoteListener_start,2491,postMessageChannel,631,StreamChannel,2257,_ControllerStream,2492,_instanceType,148,_Future,265,Zone__current,2493,Stream_length_closure,1045,Stream_length_closure0,1045,Null,2494,Stream,2495,AsyncError,2496,_Future__propagateToListeners,2497,_Future__propagateToListeners_handleWhenCompleteCallback,2498,_Future__propagateToListeners_handleValueCallback,2499,_Future__propagateToListeners_handleError,2500,_Future__chainCoreFuture,2501,_Future__prependListeners_closure,2502,boolConversionCheck,73,unwrapException,51,getTraceFromException,52,ExceptionAndStackTrace,2503,_StackTrace,2504,unwrapException_saveStackTrace,2505,JsNoSuchMethodError$,2415,NullError$,2415,UnknownJsTypeError,2506,StackOverflowError,2507,TypeErrorDecoder_extractPattern,2508,quoteStringForRegExp,114,TypeErrorDecoder,2509,TypeErrorDecoder_provokePropertyErrorOn,2510,TypeErrorDecoder_provokeCallErrorOn,2511,NullError,49,JsNoSuchMethodError,50,_Future__propagateToListeners_handleWhenCompleteCallback_closure,2512,_registerErrorHandler,297,_FutureListener,2513,_rootScheduleMicrotask,331,_scheduleAsyncCallback,300,_RootZone_bindCallback_closure,1244,_RootZone_bindCallbackGuarded_closure,2514,_rootRun,324,_rootHandleUncaughtError,323,_rootHandleUncaughtError_closure,2515,_schedulePriorityAsyncCallback,301,_nextCallback,2516,_lastPriorityCallback,2517,_lastCallback,2518,_AsyncCallbackEntry,2519,Zone__enter,2520,_isInCallbackLoop,2521,_microtaskLoop,298,_AsyncRun__initializeScheduleImmediate,2522,_AsyncRun__initializeScheduleImmediate_internalCallback,2523,convertDartClosureToJS,59,_AsyncRun__initializeScheduleImmediate_closure,2524,Timer__createTimer,2525,Duration_toString_twoDigits,2526,Duration,392,Duration_toString_sixDigits,2527,_TimerImpl$,2415,_TimerImpl,261,_TimerImpl_internalCallback,2528,_AsyncRun__scheduleImmediateWithSetImmediate_internalCallback,2529,_AsyncRun__scheduleImmediateJsOverride_internalCallback,2530,invokeClosure,57,_Exception,2531,_rootRunBinary,326,_rootRunUnary,325,_Future__addListener_closure,2532,_BufferingStreamSubscription$,2415,_PendingEvents,2533,_BufferingStreamSubscription,310,ArgumentError$,2415,_Future__chainForeignFuture,2534,_Future__chainForeignFuture_closure,2535,_Future__chainForeignFuture_closure0,2535,_Future__chainForeignFuture_closure1,2535,scheduleMicrotask,302,get$scheduleMicrotask,302,_StreamControllerLifecycle,2536,StreamController,307,StreamConsumer,2537,Stream_pipe_closure,2538,_GuaranteeSink,2539,StreamChannelController$,2415,_EventStream,2540,postMessageChannel_closure,2541,postMessageChannel_closure0,2541,LinkedHashMap_LinkedHashMap$_literal,2542,_convertDataTree,466,_EventStreamSubscription$,2415,_EventStreamSubscription_closure,2543,_wrapZone,473,_EventStreamSubscription,472,_RootZone_bindUnaryCallbackGuarded_closure,1247,_convertDataTree__convert,2544,_IdentityHashMap,2545,MapBase_mapToString,2546,MapBase_mapToString_closure,2547,MapMixin,2548,_HashMap__getTableEntry,2549,Primitives_objectHashCode,53,objectHashCode,53,_HashMapKeyIterable,2550,IterableBase_iterableToShortString,2551,_iterablePartsToStrings,358,RangeError_checkNotNegative,2552,RangeError$range,2553,_HashMapKeyIterator,2554,MappedIterable_MappedIterable,2415,MappedIterator,2555,Iterator,2556,EfficientLengthMappedIterable,2557,MappedIterable,3,MappedListIterable,2558,ListIterable,2559,_HashMap__newHashTable,2560,_HashMap__setTableEntry,2561,LinkedHashMap,346,JsLinkedHashMap,2562,fillLiteralMap,54,LinkedHashMapKeyIterable,2563,LinkedHashMapKeyIterator,870,LinkedHashMapCell,2564,postMessageChannel__closure,2565,postMessageChannel__closure0,2565,postMessageChannel__closure1,2565,_StructuredCloneDart2Js,2566,DateTime,2567,_StructuredClone_walk_closure,2568,_StructuredClone_walk_closure0,2568,_AcceptStructuredCloneDart2Js,2569,StateError$,2415,StreamSink,2570,StreamSubscription,2571,promiseToFuture,467,LinkedHashMap_LinkedHashMap$_empty,2572,_AcceptStructuredClone_walk_closure,2573,Primitives_getYear,2574,DateTime__fourDigits,2575,Primitives_getMonth,2576,DateTime__twoDigits,2577,Primitives_getDay,2578,Primitives_getHours,2579,Primitives_getMinutes,2580,Primitives_getSeconds,2581,Primitives_getMilliseconds,2582,DateTime__threeDigits,2583,Primitives_lazyAsJsDate,2584,_checkDoubleNullable,172,_AsyncCompleter,2585,promiseToFuture_closure,2586,promiseToFuture_closure0,2586,_Future__asyncCompleteError_closure,2587,_Future__asyncComplete_closure,2588,_Future__chainFuture_closure,2589,Stream_firstWhere_closure,1051,Stream_firstWhere_closure0,1051,_completeWithErrorCallback,287,Stream_firstWhere__closure,2590,Stream_firstWhere__closure0,2590,_cancelAndErrorClosure,317,_runUserCode,315,_cancelAndErrorClosure_closure,2591,_cancelAndError,316,_cancelAndError_closure,2592,_Future$zoneValue,2593,_cancelAndValue,318,_cancelAndValue_closure,2594,StreamChannelController,588,StreamController_StreamController,2415,_StreamSinkWrapper,2595,GuaranteeChannel$,2415,GuaranteeChannel,634,GuaranteeChannel_closure,2596,_StreamImplEvents,2597,_StreamControllerAddStreamState,1059,_SyncCompleter,2598,_GuaranteeSink_addStream_closure,2599,_GuaranteeSink__addError_closure,2600,GuaranteeChannel__closure,2601,_SyncStreamController,2602,_AsyncStreamController,2603,_EventDispatch,2604,_PendingEvents_schedule_closure,2605,_BufferingStreamSubscription__sendDone_sendDone,2606,_ControllerSubscription,1071,_StreamController__subscribe_closure,2607,_StreamController__recordCancel_complete,2608,_AddStreamState_cancel_closure,2609,_runGuarded,308,_DelayedError,2610,_BufferingStreamSubscription__sendError_sendError,2611,_DelayedData,2612,_MultiChannel$,2415,RemoteListener_start_closure,2613,_ZoneSpecification$,2415,Stream_Stream$fromIterable,2614,RemoteListener_start_closure0,2613,RemoteListener_start_closure1,2613,SuiteChannelManager,478,LinkedHashSet_LinkedHashSet$_empty,2572,runZoned,339,Map,2615,_runZoned,340,runZoned_closure,2616,_parentDelegate,322,_RootZone__rootDelegate,2617,_ZoneDelegate,2618,_rootFork,337,printToZone,2619,HashMap_HashMap$from,2620,_CustomZone,338,_ZoneFunction,2621,printString,247,_CustomZone_bindUnaryCallbackGuarded_closure,1205,_CustomZone_bindCallbackGuarded_closure,2622,_CustomZone_bindCallback_closure,1200,_TimerImpl$periodic,2623,_TimerImpl$periodic_closure,2624,_CustomZone_bindUnaryCallback_closure,1202,HashMap_HashMap,2415,_HashMap,2625,HashMap_HashMap$from_closure,2626,_LinkedHashSet,2627,_LinkedHashSetIterator,353,LinkedHashSet_LinkedHashSet$_literal,2542,RemoteListener_start__closure,2628,StackTraceFormatter,2236,RemoteListener_start___closure,2629,RemoteListener_start___closure0,2629,RemoteListener__sendError,2630,RemoteException_serialize,2631,TestFailure,2632,Chain_Chain$forTrace,2633,Chain_toString_closure,2634,Chain_toString_closure0,2634,instantiate1,8,checkTypeBound,160,checkNum,41,Chain_toString__closure,2635,Instantiation1,9,createRuntimeType,152,_Type,2636,instantiatedGenericFunctionType,134,_instantiate,135,_instantiateArray,139,_instantiateFunctionParameters,141,_instantiateNamed,140,Chain_toString__closure0,2635,getRuntimeType,93,Chain,2637,List_List$unmodifiable,2638,LazyChain,2639,Chain_Chain$forTrace_closure,2640,Chain_Chain$parse,2447,Chain_Chain$parse_closure,2641,Trace_Trace$parse,2447,Chain_Chain$parse_closure0,2641,Trace_toString_closure,2642,Trace_toString_closure0,2642,UnparsedFrame,630,Trace$parseFriendly,2643,WhereIterable,2644,Trace$parseFriendly_closure,2645,Trace$parseFriendly_closure0,2645,Trace,488,_StringStackTrace,2646,WhereIterator,2647,Frame_Frame$parseFriendly,2643,_parseUri,616,ParsedPath_ParsedPath$parse,2447,Context_split_closure,2648,List_List$from,2620,List,2649,ParsedPath,2650,List_List$filled,2651,ParsedPath_normalize_closure,2652,List_List$generate,2653,stringReplaceAllUnchecked,115,stringReplaceAllUncheckedString,116,JSSyntaxRegExp,2654,escapeReplacement,112,JSSyntaxRegExp_makeNative,2655,FormatException$,2415,FormatException,409,WindowsStyle,2366,RegExp_RegExp,2415,isDriveLetter,602,_Uri__uriDecode,2656,StringMatch,2657,CodeUnits,2658,_Uri__hexCharPairToByte,2659,Utf8Decoder,2660,UnmodifiableListMixin,2661,Utf8Decoder__convertIntercepted,2662,RangeError_checkValidRange,2663,_scanOneByteCharacters,372,String_String$fromCharCodes,2664,_Utf8Decoder,2665,Primitives_stringFromCharCode,2666,Primitives_stringFromCharCodes,2667,Primitives_stringFromNativeUint8List,2668,String__stringFromIterable,2669,Primitives_stringFromCodePoints,2670,Primitives__fromCharCodeApply,2671,Utf8Decoder__convertInterceptedUint8List,2672,Utf8Decoder__useTextDecoderChecked,2673,Utf8Decoder__unsafe,2674,Utf8Decoder__useTextDecoderUnchecked,2675,Utf8Decoder__makeDecoder,2676,RangeError_checkValueInInterval,2677,stringReplaceFirstUnchecked,120,stringReplaceRangeUnchecked,121,stringReplaceFirstRE,113,_StringAllMatchesIterable,2678,_StringAllMatchesIterator,2679,_MatchImplementation$,2415,_MatchImplementation,110,isAlphabetic,601,_AllMatchesIterable,2680,_AllMatchesIterator,2681,IterableElementError_tooFew,2682,JSArray_JSArray$fixed,2683,UrlStyle,2368,Context,615,current,621,get$current,621,PathException$,2415,_validateArgList,617,Context_join_closure,2684,Context_joinAll_closure,2685,SubListIterable$,2415,_validateArgList_closure,2686,SubListIterable,2,PathException,559,Uri_base,2687,_current,2493,set$_current,2493,_currentUriBase,2688,Primitives_currentUri,2689,Uri_parse,2447,UriData__parse,2690,_scan,465,_SimpleUri,2691,_Uri__Uri$notSimple,2692,int_parse,2447,Primitives_parseInt,2693,_Uri__defaultPort,2694,_Uri__toWindowsFilePath,2695,_Uri__checkNonWindowsPathReservedCharacters,2696,_Uri__checkNonWindowsPathReservedCharacters_closure,2697,_Uri__checkWindowsDriveLetter,2698,_Uri__checkWindowsPathReservedCharacters,2699,String_String$fromCharCode,2700,_Uri__removeDotSegments,2701,_Uri__makePort,2702,_Uri__normalizeRelativePath,2703,_Uri,420,_Uri__mayContainDotSegments,2704,_Uri__escapeScheme,2705,_Uri__isAlphabeticCharacter,2706,_Uri__makeScheme,2707,_Uri__fail,2708,_Uri__makeUserInfo,2709,_Uri__makeHost,2710,_Uri__Uri$notSimple_closure,2711,_Uri__makePath,2712,_Uri__makeQuery,2713,_Uri__makeFragment,2714,_Uri__normalizeOrSubstring,2715,_Uri__normalize,2716,_Uri__normalizeEscape,2717,_Uri__escapeChar,2718,hexDigitValue,1,_Uri__makePath_closure,2719,_Uri__normalizePath,2720,_Uri__uriEncode,2721,Codec,2722,_Utf8Encoder,2723,_checkValidRange,125,diagnoseRangeError,39,_Uri__checkZoneID,2724,_Uri__normalizeZoneID,2725,Uri_parseIPv6Address,2726,_Uri__normalizeRegName,2727,Uri_parseIPv6Address_error,2728,Uri_parseIPv6Address_parseHex,2729,Uri__parseIPv4Address,2730,Uri__parseIPv4Address_error,2731,_Uri__canonicalizeScheme,2732,_createTables,464,_createTables_closure,2733,_createTables_build,2734,_createTables_setChars,2735,_createTables_setRange,2736,_DataUri,2737,UriData,2738,Base64Codec__checkPadding,2739,_ensureNativeList,122,NativeInt8List__create1,2740,Style__getPlatformStyle,2741,_Uri__Uri,2415,PosixStyle,2364,Frame_Frame$parseFriendly_closure,2742,Frame__catchFormatException,2743,UriData__writeUri,2744,UriData__uriEncodeBytes,2745,Frame,2746,WindowsStyle_absolutePathToUri_closure,2747,Context_Context,2415,UriData__validateMimeType,2748,JSString__skipLeadingWhitespace,2749,JSString__skipTrailingWhitespace,2750,JSString__isWhitespace,2751,Trace$parseV8,2752,Trace$parseJSCore,2753,Trace$parseFirefox,2754,Trace__parseVM,2755,Trace__parseVM_closure,2756,Frame_Frame$parseVM,2757,Frame_Frame$parseVM_closure,2758,ExpandIterable,2759,Chain_toTrace_closure,2760,ExpandIterator,782,Trace$parseFirefox_closure,2761,Trace$parseFirefox_closure0,2761,Frame_Frame$parseFirefox,2754,Frame_Frame$parseFirefox_closure,2762,Frame__uriOrPathToUri,2763,_Uri__Uri$file,2764,_Uri__makeWindowsFileUrl,2765,_Uri__makeFileUri,2766,Trace$parseJSCore_closure,2767,Trace$parseJSCore_closure0,2767,Frame_Frame$parseV8,2752,Frame_Frame$parseV8_closure,2768,Frame_Frame$parseV8_closure_parseLocation,2769,Trace$parseV8_closure,2770,Trace$parseV8_closure0,2770,SkipWhileIterable,2771,SkipWhileIterator,2772,stringContainsUnchecked,111,StackTrace_current,621,StackZoneSpecification_chainFor_closure,2773,_Node,2774,LazyTrace,2775,StackZoneSpecification_chainFor_closure0,2773,Trace_Trace$from,2620,Trace_Trace$from_closure,2776,LazyChain_toTrace_closure,2777,Primitives_getProperty,2778,parseJsonExtended,553,mapStackTrace,487,StackTraceFormatter_formatStackTrace_closure,2779,LazyChain_foldFrames_closure,2780,Chain_foldFrames_closure,2781,Chain_foldFrames_closure0,2781,IterableElementError_tooMany,2782,LazyTrace_foldFrames_closure,2783,Trace_foldFrames_closure,2784,ReversedListIterable,2785,Trace_foldFrames_closure0,2784,mapStackTrace_closure,2786,mapStackTrace_closure0,2786,mapStackTrace_closure1,2786,_prettifyMember,489,_prettifyMember_closure,2787,_prettifyMember_closure0,2787,stringReplaceAllFuncUnchecked,118,_stringIdentity,117,MappingBundle$fromJson,2788,parseJson,554,ArgumentError$notNull,2789,SourceLocation$,2415,SourceMapSpan,1872,findLineStart,605,countCodeUnits,603,Highlighter__lastLineLength,2790,SourceSpanWithContext$,2415,Highlighter__normalizeNewlines,2791,Highlighter__normalizeTrailingNewline,2792,Highlighter__normalizeEndOfLine,2793,Highlighter,1957,_glyphs,2794,Highlighter__writeSidebar_closure,2795,Highlighter__writeLastLine_closure,2796,Highlighter__writeLastLine_closure0,2796,Highlighter__writeLastLine_closure1,2796,Highlighter__writeIntermediateLines_closure,2797,Highlighter__writeFirstLine_closure,2798,Highlighter__writeFirstLine_closure0,2798,Highlighter__writeFirstLine_closure1,2798,Highlighter__writeFirstLine_closure2,2798,SourceSpanWithContext,560,RangeError$,2415,SourceLocation,523,SingleMapping__findColumn_closure,2799,binarySearch,504,SingleMapping__findLine_closure,2800,JsLinkedHashMap_values_closure,863,MultiSectionMapping$fromJson,2788,SingleMapping$fromJson,2788,SingleMapping,2801,SourceFile,2802,_MappingTokenizer,2803,TargetLineEntry,2804,decodeVlq,534,TargetEntry,2805,SingleMapping$fromJson_closure,2806,pow,471,closure,2807,MultiSectionMapping,2808,MappingBundle,2809,_parseJson,364,_convertJsonToDartLazy,365,_JsonMap,2810,_JsonMapKeyIterable,2811,RemoteListener__sendLoadException,2812,StreamQueue,2813,QueueList$,2415,ListQueue$,2415,_CompleterStream,2814,_RestRequest,2815,StreamCompleter,2816,RemoteListener_start____closure,2817,_asBoolNullable,169,Metadata$deserialize,2818,LinkedHashSet_LinkedHashSet$from,2620,Declarer$,2415,RemoteListener__deserializeSet,2819,Runtime_Runtime$deserialize,2818,_asStringNullable,180,OperatingSystem_find,2820,SuitePlatform$,2415,RemoteListener_start____closure0,2817,Suite,2821,Suite__filterGroup,2822,_asyncStartSync,266,_asyncAwait,267,_asyncReturn,268,_asyncRethrow,269,_wrapJsFunctionForAsync,271,_makeAsyncAwaitCompleter,263,Symbol,2823,_AddStreamState_makeErrorHandler,2824,_AddStreamState_makeErrorHandler_closure,2825,_ListQueueIterator,363,ListQueue,362,QueueList,607,Result,2826,_wrapJsFunctionForAsync_closure,2827,_StreamIterator,2828,_awaitOnObject,270,_awaitOnObject_closure,2829,_awaitOnObject_closure0,2829,_AsyncAwaitCompleter,2830,RemoteListener_start_____closure,2831,Invoker_guard,2832,Invoker_guard_closure,2833,Invoker_guard__closure,2834,RemoteListener,2835,RemoteListener__serializeGroup_closure,2836,Group,490,RemoteListener__serializeTest_closure,2837,VirtualChannel,2838,_EmptyStream,2839,NullStreamSink,2840,_MultiChannel_virtualChannel_closure,2071,_MultiChannel_virtualChannel_closure0,2071,MultiChannel,2841,_DoneStreamSubscription,949,NullStreamSink_addStream_closure,2842,_LinkedHashSet__newHashTable,2560,_LinkedHashSetCell,2843,_asIntNullable,174,RemoteListener__runLiveTest_closure,2844,_BroadcastStream,2845,RemoteListener__runLiveTest_closure0,2844,RemoteListener__runLiveTest_closure1,2844,RemoteListener__runLiveTest_closure2,2844,RemoteListener__runLiveTest_closure3,2844,RemoteListener__runLiveTest__closure,2846,Invoker,2847,LiveTestController$,2415,_BroadcastSubscription,950,State,2848,Invoker__onRun_closure,2849,_AsyncCounter,2850,Chain_capture,2851,Expando__keyCount,2852,StackZoneSpecification,2853,Expando,570,Chain_capture_closure,1968,Primitives_setProperty,2854,StackZoneSpecification__currentTrace_closure,2855,StackZoneSpecification__registerBinaryCallback_closure,2025,StackZoneSpecification__registerBinaryCallback__closure,2027,StackZoneSpecification__registerUnaryCallback_closure,2021,StackZoneSpecification__registerUnaryCallback__closure,2023,StackZoneSpecification__registerCallback_closure,2019,Invoker__onRun__closure,2856,Invoker__onRun___closure,2857,Invoker__onRun___closure0,2857,Message,2858,Invoker__onRun____closure,2859,Future_Future,2415,Future_Future_closure,2860,Timer_Timer,2415,errorsDontStopTest,525,errorsDontStopTest_closure,2861,errorsDontStopTest_closure0,2861,Invoker_waitForOutstandingCallbacks_closure,2862,Invoker_waitForOutstandingCallbacks_closure0,2862,Future_Future$sync,2863,ClosedException$,2415,ClosedException,635,Invoker_heartbeat_closure,2864,Invoker_heartbeat_message,2865,Invoker_heartbeat__closure,2866,TimeoutException,2867,Timeout,2868,Invoker__handleError_closure,2869,Invoker__handleError_closure0,2869,print,412,get$print,412,Chain_Chain$current,621,Chain_Chain$current_closure,2870,LiveTestController,524,_SyncBroadcastStreamController,2871,_LiveTest,2872,_SyncBroadcastStreamController__sendError_closure,974,_AddStreamState,1058,_SyncBroadcastStreamController__sendDone_closure,976,_SyncBroadcastStreamController__sendData_closure,972,_BroadcastStreamController,2873,Metadata_serialize_closure,2874,Metadata_serialize_closure0,2874,MapEntry,2875,_LinkedHashSetIterator$,2415,PlatformSelector,2876,Group_forPlatform_closure,2877,Group$,2415,GroupEntry,2878,Group__map_closure,2879,Group__map_closure0,2879,Metadata_forPlatform_closure,2880,Metadata_Metadata,2415,Metadata_Metadata__unresolved,2881,LinkedHashMap_LinkedHashMap$from,2620,Metadata$_,2882,Metadata_Metadata_closure,2883,Metadata_merge_closure,2884,mergeMaps,506,Metadata_merge_closure0,2884,Set,2885,mergeMaps_closure,1723,UnmodifiableMapView,2886,Metadata,493,UnmodifiableSetView,533,ConstantMap_map_closure,806,ConstantMap__throwUnmodifiable,2887,_ConstantMapKeyIterable,2888,ConstantStringMap,2889,DelegatingSet,2890,Metadata__validateTags_closure,2891,Metadata__validateTags_closure0,2891,pluralize,593,toSentence,592,LinkedHashMap_LinkedHashMap,2415,LinkedHashMap_LinkedHashMap$from_closure,2892,PlatformSelector_evaluate_closure,2893,SuitePlatform,530,OperatingSystem_find_closure,2894,OperatingSystem_find_closure0,2894,Runtime_Runtime$deserialize_closure,2895,Runtime,2896,Declarer_build_closure,2897,LocalTest,2898,Declarer__tearDownAll_closure,2899,Declarer__tearDownAll__closure,2900,Declarer__tearDownAll___closure,2901,Declarer,561,Duration$,2415,LinkedHashSet_LinkedHashSet,2415,PlatformSelector$parse,2447,Metadata__deserializeTimeout,2902,Metadata$deserialize_closure,2903,Stream_last_closure,1049,Stream_last_closure0,1049,Stream_first_closure,1047,Stream_first_closure0,1047,BooleanSelectorImpl,2904,Parser,2185,Scanner,2905,SpanScanner$,2415,AndNode,2906,IntersectionSelector,2907,OrNode,2908,ConditionalNode,2909,Evaluator,2910,SourceSpanFormatException$,2415,SourceSpanFormatException,538,Token,2911,_SpanScannerState,2912,IdentifierToken,2913,validateErrorArgs,606,StringScannerException$,2415,StringScannerException,527,_FileSpan$,2415,SourceSpanMixin,2914,_FileSpan,509,FileLocation$_,2882,FileLocation,2915,NotNode,2916,VariableNode,2917,_expandSafe,564,SpanScanner,474,_asNumNullable,177,PlatformSelector$parse_closure,2918,PlatformSelector__wrapFormatException,2919,_CompleterSink,2920,_CompleterSink__setDestinationSink_closure,2921,StreamSinkCompleter,2922,_EventRequest,2923,SubscriptionStream,1612,_CancelOnErrorSubscriptionWrapper,2924,_CancelOnErrorSubscriptionWrapper_onError_closure,2925,_CancelOnErrorSubscriptionWrapper_onError__closure,2926,StreamQueue__ensureListening_closure,1619,StreamQueue__ensureListening_closure0,1619,StreamQueue__ensureListening_closure1,1619,ErrorResult,2927,ValueResult,2928,EventSink,2929,_NextRequest,2930,Completer,469,LinkedHashSet,349,fillLiteralSet,56,_GeneratedStreamImpl,2931,Stream_Stream$fromIterable_closure,1042,_IterablePendingEvents,1041,_ZoneSpecification,320,_MultiChannel,620,_MultiChannel_closure,2067,_MultiChannel_closure0,2067,_MultiChannel_closure1,2067,_MultiChannel__closure,2069,JSStackTraceMapper_deserialize,2818,PackageRootResolver,2932,asUri,598,ensureTrailingSlash,599,JSStackTraceMapper__deserializePackageConfigMap,2933,PackageConfigResolver__normalizeMap,2934,PackageConfigResolver,2935,JSStackTraceMapper,2936,Map_castFrom,2937,CastMap,2938,CastIterable_CastIterable,2415,CastIterator,2939,EfficientLengthIterable,2940,_EfficientLengthCastIterable,2941,CastIterable,0,CastMap_forEach_closure,747,PackageConfigResolver__normalizeMap_closure,2942,mapMap,505,mapMap_closure,1721,mapMap_closure0,1721,JSStackTraceMapper__deserializePackageConfigMap_closure,2943,StreamChannelCompleter,2256,_StreamChannel,2944,main_closure0,2397,group,587,get$group,587,_declarer,584,Metadata$parse,2447,Trace_Trace$current,621,Declarer_group_closure,2945,Trace_Trace$current_closure,2946,Metadata_validatePlatformSelectors_closure,2947,PlatformSelector_validate_closure,2948,PlatformSelector_validate__closure,2949,Validator,2950,Metadata__parseOnPlatform,2951,Metadata__parseTags,2952,_globalDeclarer,2953,_declarer_closure,2954,RunnerSuiteController,2955,_AsyncBroadcastStreamController,2956,AsyncMemoizer,2957,RunnerSuite,2958,Engine$,2415,Stopwatch__frequency,2959,Primitives_initTicker,2960,Primitives_timerFrequency,2961,ExpandedReporter,2962,Stopwatch,2320,PrintSink,2963,Stream_Stream$fromFuture,2964,_declarer__closure,2965,Future_Future$error,2966,UnmodifiableListView,2967,Primitives_timerTicks,2968,UnionSet,2969,UnionSet_length_closure,1739,IterableSet,2970,UnionSet__iterable_closure,1741,ExpandedReporter__onTestStarted_closure,2971,ExpandedReporter__onTestStarted_closure0,2971,ExpandedReporter__onTestStarted_closure1,2971,indent,591,prefixLines,594,Engine_run_closure,2972,Engine_run_closure0,2972,Pool_close_closure,2973,FutureGroup,499,_ListQueueIterator$,2415,FutureGroup_add_closure,1573,FutureGroup_add_closure0,1573,Engine_run__closure,2286,LiveSuiteController$,2415,Engine_run___closure,2974,Engine_run____closure,2975,Pool__onResourceReleaseAllowed_closure,2976,Pool__runOnRelease_closure,2977,Pool__runOnRelease_closure0,2977,PoolResource,2978,LiveSuiteController_close_closure,2979,RunnerSuiteController__close_closure,2980,Engine__runSkippedTest_closure,2981,Engine__runSkippedTest_closure0,2981,Engine__runSkippedTest_closure1,2981,Engine__runLiveTest_closure,2982,Engine__runLiveTest_closure0,2982,Future_Future$microtask,2983,Engine__runLiveTest_closure1,2982,Future_Future$microtask_closure,2984,LiveSuiteController_reportLiveTest_closure,2985,QueueList__nextPowerOf2,2986,StreamGroup_add_closure,1602,StreamGroup_add_closure0,1602,StreamGroup__listenToStream_closure,2987,LiveSuiteController,595,_LiveSuite,2988,LiveSuiteController_closure,2989,LiveSuiteController_closure0,2989,Stream_Stream$fromFuture_closure,1039,Stream_Stream$fromFuture_closure0,1039,Future_wait,2990,Engine_success_closure,2991,Future_wait_handleError,2992,Future_wait_closure,984,Primitives_initTicker_closure,2993,StreamGroup,2994,UnionSetController$,2415,Pool$,2415,Engine,498,StreamGroup__onCancelBroadcast_closure,1606,StreamGroup__onListen_closure,1604,Engine_closure,2995,Engine_closure0,2995,Pool,485,UnionSetController,507,closure0,2807,_macOSDirectories,2996,SuiteConfiguration__list,2997,UnmodifiableSetView$,2415,SuiteConfiguration__map,2998,SuiteConfiguration,2999,main__closure,3000,test,586,get$test,586,Declarer_test_closure,3001,Declarer_test__closure,3002,Declarer_test___closure,3003,Declarer__runSetUps_closure,3004,Future_forEach,3005,Future_forEach_closure,3006,Future_doWhile,3007,Future_doWhile_closure,3008,method1,550,method2,551,expect,539,get$expect,539,_expect,540,wrapMatcher,609,_expect_closure,3009,_expect_closure0,3009,fail,544,StringDescription,3010,formatFailure,545,Matcher,3011,prettyPrint,546,prettyPrint__prettyPrint,3012,prettyPrint__prettyPrint_pp,3013,_typeName,622,prettyPrint__prettyPrint_closure,3014,prettyPrint__prettyPrint_closure0,3014,prettyPrint__prettyPrint_closure1,3014,escape,612,escape_closure,3015,_getHexLiteral,613,Runes,3016,_combineSurrogatePair,413,RuneIterator,3017,_Predicate,3018,wrapMatcher_closure,3019,_StringEqualsMatcher,3020,_DeepMatcher,3021,JsLinkedHashMap_addAll_closure,865,_DeepMatcher__compareSets_closure,3022,TypeMatcher,3023,FeatureMatcher,3024,_StringEqualsMatcher__writeTrailing,3025,_StringEqualsMatcher__writeLeading,3026,x,3027,_Utils_objectAssign,3028,JS_CONST,3029,Interceptor,3030,JSBool,3031,JSNull,3032,JSObject,3033,JavaScriptObject,3034,PlainJavaScriptObject,3035,UnknownJavaScriptObject,3036,Function,3037,JavaScriptFunction,3038,JSUnmodifiableArray,3039,JSNumber,3040,JSInt,3041,JSDouble,3042,Pattern,3043,JSString,3044,_CastIterableBase,3045,EmptyIterator,3046,FixedLengthListMixin,3047,UnmodifiableListBase,3048,ConstantMap,3049,Instantiation,815,TypeErrorDecoder_noSuchMethodPattern,3050,TypeErrorDecoder_notClosurePattern,3051,TypeErrorDecoder_nullCallPattern,3052,TypeErrorDecoder_nullLiteralCallPattern,3053,TypeErrorDecoder_undefinedCallPattern,3054,TypeErrorDecoder_undefinedLiteralCallPattern,3055,TypeErrorDecoder_nullPropertyPattern,3056,TypeErrorDecoder_nullLiteralPropertyPattern,3057,TypeErrorDecoder_undefinedPropertyPattern,3058,TypeErrorDecoder_undefinedLiteralPropertyPattern,3059,NoSuchMethodError,3060,StackTrace,3061,TearOffClosure,3062,RegExp,382,RegExpMatch,3063,Match,3064,NativeByteBuffer,3065,ByteBuffer,3066,NativeTypedData,3067,NativeByteData,3068,NativeTypedArray,3069,NativeTypedArrayOfDouble,3070,NativeTypedArrayOfInt,3071,NativeFloat32List,3072,NativeFloat64List,3073,NativeInt16List,3074,NativeInt32List,3075,NativeInt8List,3076,NativeUint16List,3077,Uint32List,3078,NativeUint32List,3079,NativeUint8ClampedList,3080,NativeUint8List,418,Uint8List,3081,Type,3082,_Error,3083,Timer,319,Sink,3084,Exception,58,_Completer,3085,StreamTransformer,3086,StreamTransformerBase,3087,_StreamController,3088,_SyncStreamControllerDispatch,3089,_AsyncStreamControllerDispatch,3090,_StreamImpl,3091,_DelayedEvent,3092,_DelayedDone,3093,Error,3094,ZoneSpecification,3095,ZoneDelegate,3096,Zone,3097,_Zone,3098,_RootZone__rootMap,3099,_RootZone,3100,IterableBase,3101,ListBase,3102,MapBase,3103,_UnmodifiableMapMixin,3104,MapView,3105,Queue,3106,SetMixin,3107,SetBase,3108,_SetBase,3109,AsciiCodec,3110,_UnicodeSubsetEncoder,3111,AsciiEncoder,3112,Base64Codec,3113,Base64Encoder,3114,_FusedCodec,3115,Converter,3116,Encoding,3117,JsonCodec,3118,JsonDecoder,3119,Utf8Codec,3120,Utf8Encoder,3121,Utf8Decoder__decoder,3122,OutOfMemoryError,3123,StringSink,3124,Uri,3125,_Uri__isWindowsCached,3126,_Uri__needsNoEncoding,3127,AbortPaymentEvent,3128,AnimationEvent,3129,AnimationPlaybackEvent,3130,ApplicationCacheErrorEvent,3131,BackgroundFetchClickEvent,3132,BackgroundFetchEvent,3133,BackgroundFetchFailEvent,3134,BackgroundFetchedEvent,3135,BeforeInstallPromptEvent,3136,BeforeUnloadEvent,3137,Blob,3138,BlobEvent,3139,CanMakePaymentEvent,3140,ClipboardEvent,3141,CloseEvent,3142,CompositionEvent,3143,CustomEvent,3144,DeviceMotionEvent,3145,DeviceOrientationEvent,3146,DomError,3147,DomException,3148,ErrorEvent,3149,Event,3150,EventTarget,3151,ExtendableEvent,3152,ExtendableMessageEvent,3153,FetchEvent,3154,File,3155,FocusEvent,3156,FontFaceSetLoadEvent,3157,ForeignFetchEvent,3158,GamepadEvent,3159,HashChangeEvent,3160,InstallEvent,3161,KeyboardEvent,3162,Location,3163,MediaEncryptedEvent,3164,MediaError,3165,MediaKeyMessageEvent,3166,MediaQueryListEvent,3167,MediaStreamEvent,3168,MediaStreamTrackEvent,3169,MessageEvent,3170,MessagePort,3171,MidiConnectionEvent,3172,MidiMessageEvent,3173,MouseEvent,3174,MutationEvent,3175,NavigatorUserMediaError,3176,NotificationEvent,3177,OverconstrainedError,3178,PageTransitionEvent,3179,PaymentRequestEvent,3180,PaymentRequestUpdateEvent,3181,PointerEvent,3182,PopStateEvent,3183,PositionError,3184,PresentationConnectionAvailableEvent,3185,PresentationConnectionCloseEvent,3186,ProgressEvent,3187,PromiseRejectionEvent,3188,PushEvent,3189,RtcDataChannelEvent,3190,RtcDtmfToneChangeEvent,3191,RtcPeerConnectionIceEvent,3192,RtcTrackEvent,3193,SecurityPolicyViolationEvent,3194,SensorErrorEvent,3195,SpeechRecognitionError,3196,SpeechRecognitionEvent,3197,SpeechSynthesisEvent,3198,StorageEvent,3199,SyncEvent,3200,TextEvent,3201,TouchEvent,3202,TrackEvent,3203,TransitionEvent,3204,UIEvent,3205,VRDeviceEvent,3206,VRDisplayEvent,3207,VRSessionEvent,3208,WheelEvent,3209,Window,3210,_MojoInterfaceRequestEvent,3211,_ResourceProgressEvent,3212,_USBConnectionEvent,3213,EventStreamProvider,3214,_StructuredClone,3215,_AcceptStructuredClone,3216,VersionChangeEvent,3217,ByteData,3218,Int8List,3219,Uint8ClampedList,3220,Int16List,3221,Uint16List,3222,Int32List,3223,Float32List,3224,Float64List,3225,AudioProcessingEvent,3226,OfflineAudioCompletionEvent,3227,ContextEvent,3228,SqlError,3229,DelegatingSink,3230,DelegatingStreamSubscription,3231,_StreamGroupState,3232,BooleanSelector,3233,All,3234,Node,3235,Visitor,3236,None,3237,TokenType,3238,RecursiveVisitor,3239,EmptyUnmodifiableSet,3240,UnmodifiableSetMixin,3241,_DelegatingIterableBase,3242,DelegatingIterable,3243,_IsTrue,3244,Description,3245,SyncPackageResolver,3246,_PathDirection,3247,_PathRelation,3248,InternalStyle,3249,Style,3250,Mapping,3251,_TokenKind,3252,FileSpan,3253,SourceLocationMixin,3254,SourceSpan,3255,SourceSpanBase,1948,SourceSpanException,3256,Frame__uriRegExp,3257,Frame__windowsRegExp,3258,StackZoneSpecification_disableKey,3259,StreamChannelMixin,3260,LineScannerState,3261,StringScanner,3262,AsciiGlyphSet,3263,UnicodeGlyphSet,3264,LiveTest,3265,MessageType,3266,Metadata_empty,3267,OperatingSystem,3268,Status,3269,Result0,2826,Test,3270,StackTraceMapper,3271,LiveSuite,3272,RuntimeSelection,3273,SuiteConfiguration_empty,3267,_NativeTypedArrayOfDouble_NativeTypedArray_ListMixin,3274,_NativeTypedArrayOfDouble_NativeTypedArray_ListMixin_FixedLengthListMixin,3275,_NativeTypedArrayOfInt_NativeTypedArray_ListMixin,3276,_NativeTypedArrayOfInt_NativeTypedArray_ListMixin_FixedLengthListMixin,3277,_ListBase_Object_ListMixin,3278,_SetBase_Object_SetMixin,3279,_UnmodifiableMapView_MapView__UnmodifiableMapMixin,3280,_QueueList_Object_ListMixin,3281,_UnionSet_SetBase_UnmodifiableSetMixin,3282,_UnmodifiableSetView_DelegatingSet_UnmodifiableSetMixin,3283,_IterableSet_SetMixin_UnmodifiableSetMixin,3284,main,552,getNativeInterceptor,249,isJsIndexable,11,Primitives_dateNow,3285,closureFromTearOff,66,throwCyclicInit,80,getRuntimeTypeArguments,85,computeSignature,96,defineProperty,98,findType,133,typeLiteral,153,_asDoubleNullable,171,_Universe_addRules,3286,_Universe_addErasedTypes,3287,_AsyncRun__scheduleImmediateJsOverride,3288,_AsyncRun__scheduleImmediateWithSetImmediate,3289,_AsyncRun__scheduleImmediateWithTimer,3290,Future__kTrue,3291,_startMicrotaskLoop,299,StreamIterator_StreamIterator,2415,_nullDataHandler,312,_nullErrorHandler,313,_nullDoneHandler,314,_rootRegisterCallback,327,_rootRegisterUnaryCallback,328,_rootRegisterBinaryCallback,329,_rootErrorCallback,330,_rootCreateTimer,332,_rootCreatePeriodicTimer,333,_rootPrint,335,_printToZone,336,Uri_decodeComponent,3292,_escapeString,623,main0,552,max,470,DART_CLOSURE_PROPERTY_NAME,2333,JS_INTEROP_INTERCEPTOR_TAG,2334,_AsyncRun__scheduleImmediateClosure,3293,Future__nullFuture,3294,_Base64Decoder__inverseAlphabet,3295,_hasErrorStackProperty,2352,_scannerTables,2353,_whitespaceAndSingleLineComments,2354,_multiLineCommentBody,2355,_hyphenatedIdentifier,2356,_dart2DynamicArgs,2357,_escapeRegExp,2358,windows,2359,url,2360,context,2361,get$context,2361,Style_posix,3296,Style_windows,2359,Style_url,2360,Style_platform,3297,_digits,2370,MAX_INT32,2371,MIN_INT32,2372,_specKey,2373,_vmFrame,2374,_v8Frame,2375,_v8UrlLocation,2376,_v8EvalLocation,2377,_firefoxSafariFrame,2378,_friendlyFrame,2379,_asyncBody,2380,_initialDot,2381,_terseRegExp,2385,_v8Trace,2386,_v8TraceLine,2387,_firefoxSafariTrace,2388,_friendlyTrace,2389,_universalValidVariables,2391,_currentKey,2392,_currentKey0,2392,currentOSGuess,2393,_hyphenatedIdentifier0,2356,anchoredHyphenatedIdentifier,2394,$get$DART_CLOSURE_PROPERTY_NAME,2333,$get$JS_INTEROP_INTERCEPTOR_TAG,2334,$get$TypeErrorDecoder_noSuchMethodPattern,3050,$get$TypeErrorDecoder_notClosurePattern,3051,$get$TypeErrorDecoder_nullCallPattern,3052,$get$TypeErrorDecoder_nullLiteralCallPattern,3053,$get$TypeErrorDecoder_undefinedCallPattern,3054,$get$TypeErrorDecoder_undefinedLiteralCallPattern,3055,$get$TypeErrorDecoder_nullPropertyPattern,3056,$get$TypeErrorDecoder_nullLiteralPropertyPattern,3057,$get$TypeErrorDecoder_undefinedPropertyPattern,3058,$get$TypeErrorDecoder_undefinedLiteralPropertyPattern,3059,$get$_AsyncRun__scheduleImmediateClosure,3293,$get$Future__nullFuture,3294,$get$_currentKey,2392,$get$_RootZone__rootMap,3099,$get$_currentKey0,2392,$get$_specKey,2373,$get$context,2361,$get$Style_url,2360,$get$Style_windows,2359,$get$Utf8Decoder__decoder,3122,$get$Style_platform,3297,$get$_Uri__isWindowsCached,3126,$get$_Uri__needsNoEncoding,3127,$get$_scannerTables,2353,$get$_Base64Decoder__inverseAlphabet,3295,$get$Style_posix,3296,$get$_friendlyFrame,2379,$get$_v8Trace,2386,$get$_firefoxSafariTrace,2388,$get$_friendlyTrace,2389,$get$_vmFrame,2374,$get$_asyncBody,2380,$get$_firefoxSafariFrame,2378,$get$_initialDot,2381,$get$Frame__uriRegExp,3257,$get$Frame__windowsRegExp,3258,$get$windows,2359,$get$_v8Frame,2375,$get$_v8EvalLocation,2377,$get$_v8UrlLocation,2376,$get$_v8TraceLine,2387,$get$_hasErrorStackProperty,2352,$get$_terseRegExp,2385,$get$url,2360,$get$_digits,2370,$get$MIN_INT32,2372,$get$MAX_INT32,2371,$get$StackZoneSpecification_disableKey,3259,$get$anchoredHyphenatedIdentifier,2394,$get$_hyphenatedIdentifier,2356,$get$_hyphenatedIdentifier0,2356,$get$_whitespaceAndSingleLineComments,2354,$get$_multiLineCommentBody,2355,$get$_universalValidVariables,2391,$get$SuiteConfiguration_empty,3267,$get$currentOSGuess,2393,$get$Metadata_empty,3267,$get$_escapeRegExp,2358,$get$_dart2DynamicArgs,2357,getInterceptor$,3298,getInterceptor$asx,3299,async___startMicrotaskLoop$closure,3300,async__AsyncRun__scheduleImmediateJsOverride$closure,3301,async__AsyncRun__scheduleImmediateWithSetImmediate$closure,3302,async__AsyncRun__scheduleImmediateWithTimer$closure,3303,async___nullDoneHandler$closure,3304,async___nullErrorHandler$closure,3305,async___nullDataHandler$closure,3306,getInterceptor$ax,3307,async___printToZone$closure,3308,math__max$closure,3309,getInterceptor$s,3310,core_Uri_decodeComponent$closure,3311,main_test__main$closure,3312,_js_helper_Primitives_dateNow$closure,3313,async_Future__kTrue$closure,3314,pretty_print___escapeString$closure,3315,util___getHexLiteral$closure,3316,getInterceptor$x,3317,getInterceptor$ansx,3318,getInterceptor$n,3319,async___rootHandleUncaughtError$closure,3320,async___rootRun$closure,3321,async___rootRunUnary$closure,3322,async___rootRunBinary$closure,3323,async___rootRegisterCallback$closure,3324,async___rootRegisterUnaryCallback$closure,3325,async___rootRegisterBinaryCallback$closure,3326,async___rootErrorCallback$closure,3327,async___rootScheduleMicrotask$closure,3328,async___rootCreateTimer$closure,3329,async___rootCreatePeriodicTimer$closure,3330,async___rootPrint$closure,3331,async___rootFork$closure,3332","instance":"K1,3333,$this,3334,_box_0,3335,matcher,3336,future,3337,get$future,3337,V1,3338,listener,3339,frame,3340,expectedElement,3341,getMain,3342,value,2416,location,3343,get$location,3343,channel,3344,get$channel,3344,depth,3345,controller,3346,super$StringScanner$matches,3347,beforeLoad,3348,f,3349,line,3350,get$line,3350,printZone,3351,R,3352,end,3353,get$end,3353,transform,3354,result,3355,selector,3356,handleError,3357,get$handleError,3357,body,3358,elements,3359,x,3360,suite,3361,get$suite,3361,T,3362,index,3363,predicate,610,error,2966,get$error,2966,validVariables,3364,terse,3365,super$EventTarget$addEventListener,3366,_TimerImpl$2,2415,stackTrace,3367,_BufferingStreamSubscription$4,2415,_EventStreamSubscription$4,2415,LinkedHashMapKeyIterator$2,2415,timeout,3368,DateTime$_withValue$2$isUtc,3369,_Future$zoneValue$2,2593,StreamChannelController$2$allowForeignErrors$sync,2415,GuaranteeChannel$3$allowSinkErrors,2415,message,3370,get$message,3370,_Future$immediate$1,3371,_CustomZone$3,2415,performance,3372,trace,3373,div,3374,_TimerImpl$periodic$2,2623,level,3375,span,3376,get$span,3376,_LinkedHashSetIterator$2,2415,registered,3377,Instantiation$1,2415,_MatchImplementation$2,2415,SubListIterable$3,2415,super$Iterable$where,3378,SourceSpanBase$3,2415,SourceSpanWithContext$4,2415,SourceLocation$4$column$line$sourceUrl,2415,super$JavaScriptObject$toString,3379,SingleMapping$fromJson$2$mapUrl,2788,callback,3380,SourceFile$decoded$2$url,3381,test,586,get$test,586,MultiSectionMapping$fromJson$3$mapUrl,2788,groups,3382,get$groups,3382,liveTest,3383,get$liveTest,3383,engine,3384,MappingBundle$fromJson$2$mapUrl,2788,_StreamControllerAddStreamState$4,2415,_DoneStreamSubscription$1,2415,Invoker$_$4$groups$guarded,2882,chain,3385,LiveTestController$5$groups,2415,_BroadcastSubscription$5,2415,Metadata$_$10$chainStackTraces$forTag$onPlatform$retry$skip$skipReason$tags$testOn$timeout$verboseTrace,2882,completer,3386,longest,3387,SuitePlatform$3$inGoogle$os,2415,FileLocation$_$2,2882,_FileSpan$3,2415,StringScanner$3$position$sourceUrl,2415,_box_1,3388,SubscriptionStream$1,2415,super$Iterable$skipWhile,3389,fn,3390,$call$body$Engine_run__closure,3391,oldPredicate,3392,ListQueue$1,2415,counter,3393,QueueList$1,2415,hasError,3394,_MultiChannel$1,2415,loadResource,3395,StreamChannelCompleter$0,2415,super$TypeMatcher$describe,3396,id,3397,Metadata$parse$8$chainStackTraces$onPlatform$retry$skip$tags$testOn$timeout$verboseTrace,2447,milliseconds,3398,super$TypeMatcher$matches,3347,originalSource,3399,Stopwatch$0,2415,start,2491,get$start,2491,stream,3400,get$stream,3400,ExpandedReporter$_$5$color$printPath$printPlatform,2882,_Future$immediateError$2,3401,outstandingCallbacksForBody,3402,sourceResult,3403,K,3404,serializedOnPlatform,3405,V,3406,LiveSuiteController$1,2415,StreamGroup$broadcast$0,3407,onData,3408,get$onData,3408,Engine$3$concurrency$coverage$maxSuites,2415,Pool$2$timeout,2415,UnionSetController$1$disjoint,2415,target,3409,StringDescription$1,2415,sourceMap,3410,invoker,3411,minified,3412,zone,3413,sdkRoot,3414,streamConsumer,3415,e,3416,platform,3297,s,3417,sdkLib,3418,super$_BroadcastStreamController$_addEventError,3419,column,3420,get$column,3420,cleanUp,3421,eagerError,3422,iterator,3423,get$iterator,3423,identifier,3424,port,3425,get$port,3425,action,3426,node,3427,T1,3428,T2,3429,withResource$body$Pool,3430,portSubscription,3431,serialized,3432,doneSignal,3433,arg1,3434,pos,3435,arg2,3436,dispatch,3437,getTag,3438,testOn,3439,getUnknownTag,3440,skip,3441,get$skip,3441,verboseTrace,3442,get$verboseTrace,3442,prototypeForTag,3443,chainStackTraces,3444,get$chainStackTraces,3444,argumentError,3445,super$SourceSpanMixin$$eq,3446,retry,3447,get$retry,3447,arg,3448,skipReason,3449,_convertedObjects,3450,onPlatform,3451,uri,3452,get$uri,3452,portStart,3453,skipped,3454,get$skipped,3454,textInside,3455,maxItems,3456,maxLineLength,3457,original,3458,get$original,3458,_runGroup$body$Engine,3459,host,3460,get$host,3460,_prettyPrint,3461,_runLiveTest$body$Engine,3462,indent,3463,_runSkippedTest$body$Engine,3464,computation,3465,orElse,3466,countSuccess,3467,K2,3468,$protected,3469,spec,3470,pp,3471,super$DelegatingStreamSubscription$onError,3472,object,3473,ex,3474,subscription,3475,super$DelegatingStreamSubscription$cancel,3476,bodyFunction,3477,tables,3478,data,3479,get$data,3479,_foreign,3480,set$_foreign,3480,_disabled,3481,get$_disabled,3481,test$9$onPlatform$retry$skip$solo$tags$testOn$timeout,586,_onTestStarted,3482,get$_onTestStarted,3482,newDartList$1,3483,configure$1$mapper,3484,elapsedMicroseconds,3485,get$elapsedMicroseconds,3485,_captured_argumentError_0,3486,_platform_selector$_captured_this_0,3487,_completeWithValue,3488,get$_completeWithValue,3488,_parser$_captured_this_0,3489,_isScheduled,3490,get$_isScheduled,3490,hashMapCellKey,3491,_captured_future_1,3492,_closeChannel,3493,get$_closeChannel,3493,encode$1,3494,_error,3495,get$_error,3495,_core$_start,3496,onClose,3497,get$onClose,3497,_captured_callback_1,3498,_completeError,3499,get$_completeError,3499,onData$1,3408,_captured_doneSignal_2,3500,_captured_result_2,3501,configure$3$except$mapper$only,3484,separators,3502,set$separators,3502,_async_memoizer$_completer,3503,_counterKey,3504,_captured_V1_2,3505,prettyUri,3506,get$prettyUri,3506,_captured_serializedOnPlatform_0,3507,_compareSets,3508,get$_compareSets,3508,fold$1$2,3509,getRoot,3510,get$getRoot,3510,_newSet$0,3511,_captured_stackTrace_3,3512,_isPort$1,3513,catchError$1,3514,*,3515,get$*,3515,_and$0,3516,_captured_verboseTrace_4,3517,_scanOperator$1,3518,_writeFirstLine$1,3519,_handleUncaughtError,3520,get$_handleUncaughtError,3520,set$_handleUncaughtError,3520,_failedGroup,3521,_kind,3522,isOdd,3523,get$isOdd,3523,_findLine,3524,get$_findLine,3524,_captured_V_3,3525,_currentNode,3526,set$_currentNode,3526,_onSuiteStartedController,3527,_captured_f_0,3528,_requestedResources,3529,indexOf$2,3530,_precomputed4,3531,_consumeValue$0,3532,replaceAll$2,3533,_completer,3534,tags,3535,_captured_sdkRoot_3,3536,_previous,3537,needsSeparatorPattern,3538,_run,3539,get$_run,3539,set$_run,3539,replace$1$path,3540,_collection$_add,3541,get$_collection$_add,3541,_shlPositive$1,3542,_ensureController,3543,get$_ensureController,3543,_location,3544,get$_location,3544,_mayAddListener,3545,get$_mayAddListener,3545,_captured_terse_2,3546,_preGrow,3547,get$_preGrow,3547,evaluate$1,3548,_base,3549,_isWithinOrEqualsFast,3550,get$_isWithinOrEqualsFast,3550,_modified$0,3551,shouldBeDone,3552,get$shouldBeDone,3552,isBlink,3553,_currentCodePoint,3554,_addResult,3555,get$_addResult,3555,_source_map_stack_trace$_box_0,3556,typedMatches$2,3557,moveNext$0,3558,_execAnchored$2,3559,duration,3560,_onSinkDisconnected$0,3561,isCompleted,3562,get$isCompleted,3562,query,3563,get$query,3563,visitVariable$1,3564,bindCallback,3565,get$bindCallback,3565,_currentTrace,3566,get$_currentTrace,3566,sourceRoot,3567,take,3568,get$take,3568,_progressLine$2$suffix,3569,listenerHasError,3570,liveTests,3571,get$liveTests,3571,createPeriodicTimer,3572,_live_suite_controller$_onCloseCompleter,3573,_remote_listener$_captured_controller_0,3574,_onCancel$0,3575,pathsEqual,3576,get$pathsEqual,3576,distance,3577,get$distance,3577,_core$_position,3578,asStream$0,3579,abs$0,3580,verticalLine,1935,get$verticalLine,1935,listenerValueOrError,3581,_decrementPauseCount$0,3582,_html_common$_captured_this_1,3583,hasTrailingSeparator,3584,get$hasTrailingSeparator,3584,_stack_trace_formatter$_captured_this_0,3585,_declarer$_name,3586,_stack_zone_specification$_registerBinaryCallback$4,3587,_tail,3588,asUint8List$2,3589,isScaffoldAll,3590,_captured_test_1,3591,isWithin$2,3592,_platform_selector$_captured_validVariables_0,3593,_functions$_box_0,3594,_passed,3595,addTearDown$1,3596,_iterator,3597,hashMapCellValue,3598,_captured_K1_1,3599,lastSpan,3600,get$lastSpan,3600,_environment,3601,registerCallback$1$1,3602,handleUncaughtError$3,3603,_stack_zone_specification$_captured_this_1,3604,allMatches$2,3605,_position,3606,_expr,3607,_data,3608,_suiteChannel,3609,_captured_suite_1,3610,onListen,3611,_recursiveMatch$4,3612,_writeSidebar$2$end$line,3613,_onCancelBroadcast$0,3614,__internal$_iterable,3615,_buffer,3616,_flush$0,3617,_captured_identifier_0,3618,_invoker$_print$1,3619,handleUncaughtError,3603,get$handleUncaughtError,3603,scan,3620,get$scan,3620,onCancel,3621,_schedule$0,3622,_metadata,3623,_colorize$1,3624,_captured_sdkRoot_2,3625,_target,3626,_multiline,3627,_paddingBeforeSidebar,3628,_startIndex,3629,get$_startIndex,3629,_specializedTestResource,3630,_isInt32$1,3631,_contains,3632,get$_contains,3632,_handleError$3,3633,_modified,3551,get$_modified,3551,_runPool,3634,_setPendingComplete$0,3635,_simpleExpression$0,3636,_rootRunUnary$5,3637,_cloneResult$1,3638,_trimVMChain,3639,get$_trimVMChain,3639,_live_test_controller$_run,3640,get$_live_test_controller$_run,3640,_collection$_first,3641,_serializeTimeout,3642,get$_serializeTimeout,3642,relative$1,3643,_collectTraces,3644,_span_exception$_message,3645,_onRun,3646,join,3647,get$join,3647,_stack_zone_specification$_errorCallback$5,3648,_stack_zone_specification$_registerUnaryCallback$4,3649,_closeMemo,3650,change$4$onPlatform$skip$skipReason$timeout,3651,addAll$1,3652,_isPaused,3653,get$_isPaused,3653,previous,3654,_async$_addError$2,3655,_captured_minified_4,3656,_queryStart,3657,_captured_eagerError_4,3658,_captured_T_2,3659,join$8,3647,whenComplete$1,3660,position,3661,get$position,3661,set$position,3661,_newLinkedCell$2,3662,asCurrent$1$1,3663,addDescriptionOf$1,3664,_captured_orElse_1,3665,_captured_subscription_0,3666,_count,3667,_isPort,3513,get$_isPort,3513,_eval,3668,get$_eval,3668,_addEventError,3669,get$_addEventError,3669,_optionalPositional,3670,encode,3494,get$encode,3494,_writeToList$1,3671,getRoot$1,3510,_hasPending,3672,get$_hasPending,3672,_test,3673,_runner_suite$_captured_this_0,3674,_captured_zone_0,3675,_invoker$_controller,3676,setRange$4,3677,write$1,3678,_captured_maxItems_0,3679,_isClosed,3680,_closeInnerChannel$0,3681,_closable,3682,get$_closable,3682,update,3683,get$update,3683,_newSet,3511,get$_newSet,3511,_post_message_channel$_captured_controller_0,3684,_collection$_current,3685,set$_collection$_current,3685,_thenAwait$1$2,3686,_upgrade$0,3687,_fetch,3688,get$_fetch,3688,isNewSegment,3689,where$1,3378,_semantics,3690,internalFindBucketIndex,3691,get$internalFindBucketIndex,3691,_stack_zone_specification$_registerCallback$4,3692,_cachedLine,3693,_live_suite_controller$_controller,3694,_cancel,3695,get$_cancel,3695,isPassing,3696,get$isPassing,3696,_lineStart,3697,_noColor,3698,_forEachListener$1,3699,_isDebugging,3700,fillRange$3,3701,_second,3702,removeTrailingSeparators,3703,get$removeTrailingSeparators,3703,_errorName,3704,get$_errorName,3704,_union_set_controller$_set,3705,set$_union_set_controller$_set,3705,visitAnd$1,3706,_pool$_closeMemo,3707,_chainFuture,3708,get$_chainFuture,3708,declare$1,3709,needsSeparator$1,3710,second,3711,get$second,3711,_isCanceled,3712,get$_isCanceled,3712,handleNext$1,3713,_disjoint,3714,_liveTest,3715,_ensurePendingEvents$0,3716,failed,3717,get$failed,3717,_parse$1,3718,_lastMatch,3719,replaceRange$3,3720,_carry,3721,expand$1$1,3722,_stack_zone_specification$_captured_this_0,3723,isAbsolute,3724,get$isAbsolute,3724,peek,3725,get$peek,3725,_captured_object_1,3726,_rootRegisterCallback$4,3727,_doneCompleter,3728,isValue,3729,get$isValue,3729,distance$1,3577,_defaultSplit$1,3730,_execGlobal$2,3731,_simpleExpression,3636,get$_simpleExpression,3636,_onResourceReleaseAllowed$1,3732,topLeftCorner,1932,get$topLeftCorner,1932,_shrBothPositive$1,3733,_captured_longest_0,3734,_stack_zone_specification$_registerCallback,3692,get$_stack_zone_specification$_registerCallback,3692,_captured_error_0,3735,_remove$1,3736,_string,3737,padRight$1,3738,_async$_iterator,3739,set$_async$_iterator,3739,success,3740,get$success,3740,_stack_zone_specification$_captured_stackTrace_2,3741,_pendingIds,3742,_toNonSimple,3743,get$_toNonSimple,3743,_captured_spec_6,3744,readChar$0,3745,scaleFactor,3746,__js_helper$_string,3747,_stream_group$_controller,3748,set$_stream_group$_controller,3748,_serializeGroup,3749,get$_serializeGroup,3749,microsecond,3750,get$microsecond,3750,_checkNotBuilt,3751,get$_checkNotBuilt,3751,_computeKeys$0,3752,binaryOnError,3753,_or$0,3754,_captured_computation_1,3755,_execAnchored,3559,get$_execAnchored,3559,_findBucketIndex,3756,get$_findBucketIndex,3756,release,3757,get$release,3757,_runner_suite$_close$0,3758,union,3759,get$union,3759,_iterable,3760,_setRangeFast$4,3761,_captured_countSuccess_2,3762,_map,3763,internalSet$2,3764,_checkModification$1,3765,single,3766,get$single,3766,_captured_K_2,3767,joinAll$1,3768,configure,3484,get$configure,3484,_isEmpty,3769,get$_isEmpty,3769,load,3770,get$load,3770,pipe,3771,get$pipe,3771,identicalInJs$2,3772,_asyncCompleteError,3773,get$_asyncCompleteError,3773,_lazy_trace$_trace,3774,get$_lazy_trace$_trace,3774,hashCode,3775,get$hashCode,3775,_pool,3776,onError$1,3472,decrement$0,3777,registerUnaryCallback,3778,get$registerUnaryCallback,3778,_maxAllocatedResources,3779,isComplete,3780,get$isComplete,3780,indexable,3781,hasTokens,3782,get$hasTokens,3782,_html$_onData,3783,set$_html$_onData,3783,__js_helper$_strings,3784,pathSegments,3785,get$pathSegments,3785,_green,3786,_captured_registered_1,3787,describeTypedMismatch$4,3788,_expected,3789,parse,2447,get$parse,2447,whenFalse,3790,decode$2$reviver,3791,_captured_f_1,3792,any$1,3793,convert,3794,get$convert,3794,[]=,3795,get$[]=,3795,_future_group$_completer,3796,_add$1,3797,_fetch$1,3688,matchTypeError$1,3798,_last,3799,unclosable,3800,get$unclosable,3800,replace,3540,get$replace,3540,containsKey$1,3801,_runGroup$3,3802,_queue_list$_grow$0,3803,_captured_predicate_0,3804,minute,3805,get$minute,3805,_parser$_length,3806,_setUpAllTrace,3807,codeUnitAt,3808,get$codeUnitAt,3808,modifiedObject,3809,_captured_completer_0,3810,newJsObject$0,3811,active,3812,get$active,3812,_lastProgressSuffix,3813,_captured_index_1,3814,padRight,3738,get$padRight,3738,_dedupIterable,3815,get$_dedupIterable,3815,_eval$1,3668,_live_suite_controller$_captured_this_0,3816,endsWith,3817,get$endsWith,3817,_captured_streamConsumer_0,3818,removeLast$0,3819,urls,3820,_captured_hasError_3,3821,_remote_listener$_captured_this_1,3822,_varData,3823,_name,3824,_coverage,3825,_endIndex,3826,get$_endIndex,3826,codeUnitsEqual,3827,get$codeUnitsEqual,3827,_captured_s_2,3828,toTrace,3829,get$toTrace,3829,_segmentError$2,3830,_closeGroup,3831,bindUnaryCallback,3832,get$bindUnaryCallback,3832,_collection$_length,3833,_runner_suite$_controller,3834,_js_util$_captured_T_1,3835,_delegationTarget,3836,storedCallback,3837,_solo,3838,get$_solo,3838,round$0,3839,_bind$1,3840,errorCallback$2,3841,_captured_V1_3,3842,_allowMalformed,3843,lastIndexOf,3844,get$lastIndexOf,3844,_expanded$_onError,3845,get$_expanded$_onError,3845,_setUpAll,3846,get$_setUpAll,3846,_core_matchers$_description,3847,_callback,3848,_skip,3849,dart2jsArgs,3850,cancel,3476,get$cancel,3476,skipWhile$1,3389,group$1,587,_subscription_stream$_captured_error_1,3851,_resultOrListeners,3852,relativeRootPattern,3853,_onError,3854,get$_onError,3854,_createController$0,3855,_collection$_previous,3856,_setError$2,3857,_isNearCachedLine,3858,get$_isNearCachedLine,3858,convert$3,3794,_setBase,3859,get$_setBase,3859,_compareIterables$5,3860,add$1,3861,bindUnaryCallback$2$1,3832,_listenToStream,3862,get$_listenToStream,3862,_html_common$_box_0,3863,visitNot$1,3864,upEnd,1916,get$upEnd,1916,complete,3865,get$complete,3865,cast,3866,get$cast,3866,_skippedGroup,3867,_type_matcher$_name,3868,lastIndexOf$1,3844,_errorExplanation,3869,get$_errorExplanation,3869,close$0,3870,highlight$1$color,3871,_onCancelBroadcast,3614,get$_onCancelBroadcast,3614,_mappings,3872,putIfAbsent,3873,get$putIfAbsent,3873,_captured_performance_0,3874,_completeError$2,3499,isFinite,3875,get$isFinite,3875,runSkipped,3876,get$runSkipped,3876,isUnicode,3877,get$isUnicode,3877,_upgrade,3687,get$_upgrade,3687,span$2,3376,addError$1,3878,toChain$0,3879,__js_helper$_map,3880,_captured_this_1,3881,setUpAll,3882,_noRetry,3883,spanFor$4$files$uri,3884,_errorCallback,3885,get$_errorCallback,3885,set$_errorCallback,3885,_captured_onData_0,3886,count,3887,whenComplete,3660,get$whenComplete,3660,_isComplete,3888,get$_isComplete,3888,_captured_span_2,3889,_captured_groups_2,3890,setAll$2,3891,_onValue,3892,get$_onValue,3892,setDestinationSink$1,3893,_getNext$0,3894,packageConfigMap,3895,get$packageConfigMap,3895,_captured_tables_0,3896,writeln$1,3897,registerUnaryCallback$2$2,3778,_printPlatform,3898,skip$1,3441,_trace,3899,_mayResumeInput,3900,get$_mayResumeInput,3900,invalidValue,3901,_recordPause,3902,get$_recordPause,3902,_captured_T1_3,3903,_span_scanner$_scanner,3904,_bold,3905,_file$_start,3906,noMoreLiveTests$0,3907,change,3651,get$change,3651,_unlisten$0,3908,_engine$_runCalled,3909,_string_scanner$_position,3910,removeFragment$0,3911,_released,3912,_setValue$1,3913,firstMatch$1,3914,_captured_originalSource_0,3915,union$1,3759,liveSuite,3916,get$liveSuite,3916,_next,3917,_internal,3918,_isFile,3919,get$_isFile,3919,isLoadSuite,3920,get$isLoadSuite,3920,where,3378,get$where,3378,_streamController,3921,set$_streamController,3921,unclosable$1$1,3800,_addEventListener,3922,get$_addEventListener,3922,_endOrLength,3923,resolveUri$1,3924,__js_helper$_addHashTableEntry,3925,get$__js_helper$_addHashTableEntry,3925,whenTrue,3926,serialize$0,2631,highlight$0,3871,isEmpty,3927,get$isEmpty,3927,_multiLineComment,3928,get$_multiLineComment,3928,_iterable_set$_base,3929,_checkState,3930,get$_checkState,3930,_captured_future_3,3931,addAll$4,3652,_thenAwait,3686,get$_thenAwait,3686,_inCallback,3932,get$_inCallback,3932,_expanded$_captured_this_0,3933,files,3934,splitMapJoin,3935,get$splitMapJoin,3935,visitNot,3864,get$visitNot,3864,toFilePath$0,3936,internalRemove$1,3937,toolString,3938,get$toolString,3938,toString,3379,get$toString,3379,_failClosed$0,3939,_toListFixed$0,3940,glyphOrAscii,1931,get$glyphOrAscii,1931,_captured_platform_0,3941,_lazy_trace$_captured_this_0,3942,remaining,3943,_captured_portStart_1,3944,_conditional,3945,get$_conditional,3945,_equals_matcher$_match,3946,get$_equals_matcher$_match,3946,_pathSegments,3947,set$_pathSegments,3947,firstWhere,3948,get$firstWhere,3948,floor,3949,get$floor,3949,padLeft$2,3950,_captured_R_5,3951,_trace$_captured_longest_0,3952,onMessage,3953,get$onMessage,3953,_addedSuites,3954,_captured_host_0,3955,_captured_skipped_1,3956,_expanded$_color,3957,_stack_zone_specification$_run,3958,get$_stack_zone_specification$_run,3958,change$1$onPlatform,3651,_mergePaths$2,3959,getText$2,3960,_declarer$_trace,3961,_captured_handleError_1,3962,_isHttp,3963,get$_isHttp,3963,_lastProgressPassed,3964,month,3965,get$month,3965,apply$1,3966,_captured_outstandingCallbacksForBody_1,3967,_createController,3855,get$_createController,3855,_badEventState$0,3968,_captured_validVariables_0,3969,canonicalizePart$1,3970,forEach,3005,get$forEach,3005,toRadixString$1,3971,message$2$color,3370,_asyncCompleteError$2,3773,join$2,3647,update$2,3683,_collection$_cell,3972,_simpleMerge,3973,get$_simpleMerge,3973,_runLiveTest$2,3974,_addRequest$1,3975,_removeHashTableEntry,3976,get$_removeHashTableEntry,3976,_onResourceReleaseAllowed,3732,get$_onResourceReleaseAllowed,3732,validate$1,3977,_queue_list$_table,3978,set$_queue_list$_table,3978,_future_group$_pending,3979,matchesErrorTest,3980,get$matchesErrorTest,3980,_removeListener,3981,get$_removeListener,3981,hasErrorTest,3982,get$hasErrorTest,3982,_expanded$_onDone$1,3983,_onPause$0,3984,packageConfigUri,3985,_lastProgressSkipped,3986,_engine$_box_0,3987,_check,3988,isRelative$1,3989,_captured_selector_0,3990,_retry,3991,_input,3992,addEventListener$3,3366,nextIteration,3993,_timeString$1,3994,pointSpan$0,3995,variableName,3996,_schemeCache,3997,insert,3998,get$insert,3998,day,3999,get$day,3999,_lazy_trace$_captured_predicate_1,4000,putIntoMap$3,4001,_live_test_controller$_state,4002,lines,4003,get$lines,4003,_recordCancel$1,4004,_sendError$2,4005,_newHashTable,4006,get$_newHashTable,4006,removeFirst$0,4007,_runOnRelease$1,4008,_findColumn,4009,get$_findColumn,4009,_removeListeners$0,4010,trim,4011,get$trim,4011,_stream_queue$_close$0,4012,_queue_list$_head,4013,indexOf$1,3530,__js_helper$_index,4014,isDartVM,4015,_stream_sink_completer$_sink,4016,get$_stream_sink_completer$_sink,4016,_flush,3617,get$_flush,3617,virtualChannel$0,4017,listeners,4018,_host,4019,_stream_queue$_subscription,4020,set$_stream_queue$_subscription,4020,_addRequest,3975,get$_addRequest,3975,bindCallbackGuarded,4021,get$bindCallbackGuarded,4021,handleError$1,3357,containsSeparator$1,4022,inMinutes,4023,get$inMinutes,4023,endColumn,4024,_streamCompleter,4025,right,4026,setRange$3,3677,hasAbsolutePath,4027,get$hasAbsolutePath,4027,_mergePaths,3959,get$_mergePaths,3959,_re,4028,varData,4029,expand$1,3722,onComplete,4030,get$onComplete,4030,_get,4031,get$_get,4031,toUri,4032,get$toUri,4032,_fragmentStart,4033,_outgoingConnections,4034,hasPort,4035,get$hasPort,4035,_collection$_modified,4036,get$_collection$_modified,4036,runtime,4037,getLine,4038,get$getLine,4038,_countTabs$1,4039,_nativeAnchoredRegExp,4040,_waitsForCancel,4041,get$_waitsForCancel,4041,file,2764,run$1$1,4042,_captured_ex_0,4043,errorZone,4044,get$errorZone,4044,foundResult,4045,relative$2$from,3643,_onSuiteAddedController,4046,_captured_future_2,4047,run$0,4042,virtualChannel,4017,get$virtualChannel,4017,_setSourceStream$1,4048,_incomingConnections,4049,_setUpAlls,4050,getColumn$1,4051,_element,4052,_errorTest,4053,get$_errorTest,4053,_argumentsExpr,4054,schedule$1,4055,_collection$_captured_result_0,4056,_sinkCompleter,4057,_eventScheduled,4058,get$_eventScheduled,4058,_writeTrailingLines,4059,get$_writeTrailingLines,4059,removeTrailingSeparators$0,3703,rootLength$2$withDrive,4060,_live_suite_controller$_captured_liveTest_1,4061,normalize$1,4062,_closableKey,4063,_live_test_controller$_controller,4064,isSync,4065,_parent,4066,source,4067,scheduleMicrotask,302,get$scheduleMicrotask,302,_engine$_runLiveTest$3$countSuccess,4068,_isPendingComplete,4069,get$_isPendingComplete,4069,message$1,3370,_captured_line_0,4070,copyList$2,4071,_writeSurrogate$2,4072,_serializeTest,4073,get$_serializeTest,4073,_fillBuffer$3,4074,toJson$0,4075,_writeLastLine,4076,get$_writeLastLine,4076,_schedule,3622,get$_schedule,3622,addOutstandingCallback,4077,get$addOutstandingCallback,4077,_codeUnitAt$1,4078,chainFor$1,4079,_serializeTimeout$1,3642,~/,4080,get$~/,4080,print$1,412,_addHashTableEntry$2,4081,$package,4082,get$$package,4082,_stack_zone_specification$_registerBinaryCallback,3587,get$_stack_zone_specification$_registerBinaryCallback,3587,isHeadless,4083,completeError,4084,get$completeError,4084,verboseChain,4085,containsSeparator,4022,get$containsSeparator,4022,_addHashTableEntry,4081,get$_addHashTableEntry,4081,_declarer$_parent,4086,_stream_group$_subscriptions,4087,listen$4$cancelOnError$onDone$onError,4088,describeMismatch$4,4089,closed,4090,get$closed,4090,_streamQueue,4091,_runSetUps$0,4092,_captured_indent_0,4093,_checkPosition$3,4094,_prefix$1,4095,_linkStreamToController,4096,get$_linkStreamToController,4096,setSourceStream,4097,get$setSourceStream,4097,targetUrl,4098,_and,3516,get$_and,3516,peek$0,3725,__js_helper$_message,4099,inMilliseconds,4100,get$inMilliseconds,4100,_async$_previous,4101,set$_async$_previous,4101,_captured__convertedObjects_0,4102,_entries,4103,_setPendingEvents,4104,get$_setPendingEvents,4104,listen$2$onDone,4088,_captured_node_2,4105,addDescriptionOf,3664,get$addDescriptionOf,3664,__internal$_length,4106,_guardIfGuarded$1,4107,scan$1,3620,_runOnRelease,4008,get$_runOnRelease,4008,done,4108,get$done,4108,_platformVariables,4109,_isOnlyWhitespace$1,4110,isJS,4111,isEof,4112,sourceLine,4113,_runSetUps,4092,get$_runSetUps,4092,matchesErrorTest$1,3980,_f,4114,isBroadcast,4115,get$isBroadcast,4115,_captured_invoker_0,4116,_remote_listener$_box_0,4117,_conditional$0,3945,_tearDowns,4118,_close,4119,get$_close,4119,endsWith$1,3817,_nextId,4120,addAll,3652,get$addAll,3652,_captured_liveTest_0,4121,_engine$_closed,4122,_writeText,4123,get$_writeText,4123,matchAsPrefix,4124,get$matchAsPrefix,4124,_guarded,4125,_lazy_trace$_inner,4126,set$_lazy_trace$_inner,4126,_runGroup,3802,get$_runGroup,3802,__js_helper$_unlinkCell$1,4127,describe,3396,get$describe,3396,setSourceStream$1,4097,_failed,4128,_stack_zone_specification$_box_0,4129,_lazy_chain$_captured_this_0,4130,_colorize,3624,get$_colorize,3624,relativePathToUri,4131,get$relativePathToUri,4131,_isChained,4132,get$_isChained,4132,newJsMap$0,4133,_allocatedResources,4134,_color,4135,_mayAddEvent,4136,get$_mayAddEvent,4136,_group$_map$1,4137,_multi_channel$_captured_this_1,4138,_computeHashCode$1,4139,_complete$1,4140,_async$_captured_result_2,4141,_ensurePendingEvents,3716,get$_ensurePendingEvents,3716,_captured_e_1,4142,_null_stream_sink$_captured_this_0,4143,_captured_printZone_0,4144,_isAddingStream,4145,get$_isAddingStream,4145,_collection$_newLinkedCell,4146,get$_collection$_newLinkedCell,4146,_shrReceiverPositive,4147,get$_shrReceiverPositive,4147,fragment,4148,get$fragment,4148,_sendData,4149,get$_sendData,4149,_pauseCount,4150,runUnary$2$2,4151,_upgradedMap,4152,get$_upgradedMap,4152,_scanner,4153,precompiledPath,4154,_html$_target,4155,_hashCodeCache,4156,runGuarded,4157,get$runGuarded,4157,_lastSpan,4158,toList,4159,get$toList,4159,_verboseTrace,4160,_whenCompleteAction,4161,get$_whenCompleteAction,4161,relativePathToUri$1,4131,replaceAllMapped$2,4162,_as,4163,_captured_counter_3,4164,_nativeGlobalRegExp,4165,allMatches,3605,get$allMatches,3605,_soloEntries,4166,_writeTrailingLines$1,4059,addSubscription,4167,_writeSurrogate,4072,get$_writeSurrogate,4072,increment$0,4168,_captured_R_4,4169,_onResourceReleased$0,4170,_strings,4171,_handle,4172,hasListener,4173,get$hasListener,4173,_ensureDoneFuture$0,4174,_stack_zone_specification$_handleUncaughtError$5,4175,_captured_printZone_1,4176,_invokerZone,4177,_captured_transform_1,4178,evaluate,3548,get$evaluate,3548,_findBucketIndex$2,3756,pause$0,4179,_compareSets$5,3508,runUnaryGuarded$1$2,4180,spanFrom,4181,get$spanFrom,4181,fold,3509,get$fold,3509,_config,4182,_runner_suite$_onClose,4183,_zone,4184,get$_zone,4184,_stream_sink_completer$_controller,4185,set$_stream_sink_completer$_controller,4185,_captured_textInside_1,4186,pipe$1,3771,[],4187,get$[],4187,_lastProgressMessage,4188,matches$2,3347,_captured_fn_2,4189,_ensureController$0,3543,lastPendingEvent,4190,inMicroseconds,4191,get$inMicroseconds,4191,joinAll,3768,get$joinAll,3768,visitConditional$1,4192,__internal$_index,4193,_stream_sink_completer$_doneCompleter,4194,inSeconds,4195,get$inSeconds,4195,_onStateChangeController,4196,_cachedRuntimeType,4197,_captured_controller_0,4198,packageResolver,4199,_captured_eagerError_2,4200,_captured_T2_4,4201,_onClose,4202,_groups,4203,_addEventError$0,3669,convertNativeToDart_AcceptStructuredClone$2$mustCopy,2104,_duration,4204,_addHashTableEntry$3,4081,_decodedChars,4205,parents,4206,parent,4207,get$parent,4207,skipWhile,3389,get$skipWhile,3389,runGuarded$1,4157,join$1,3647,_jsObject,4208,_captured_test_0,4209,_stream_group$_state,4210,startsWith$2,4211,_set,4212,get$_set,4212,absolute$1,4213,foreign,4214,get$foreign,4214,_collection$_add$1,3541,_hasError,4215,get$_hasError,4215,merge,4216,get$merge,4216,registerUnaryCallback$2$1,3778,firstWhere$2$orElse,3948,handleValue$1,4217,resolve,4218,get$resolve,4218,_message,4219,bindCallbackGuarded$1,4021,_updateRequests,4220,get$_updateRequests,4220,_delegateCache,4221,_recordCancel,4004,get$_recordCancel,4004,hasFragment,4222,get$hasFragment,4222,traces,4223,get$traces,4223,isScheduled,4224,get$isScheduled,4224,_union_set$_iterable,4225,get$_union_set$_iterable,4225,parse$0,2447,_onCloseCompleter,4226,isNotEmpty,4227,get$isNotEmpty,4227,_test$_captured_body_0,4228,hasScheme,4229,get$hasScheme,4229,_closedBeforeDone,4230,_span_exception$_span,4231,_captured_cleanUp_1,4232,_source,4233,fuse$1$1,4234,_isNearCachedLine$1,3858,_live_suite_controller$_suite,4235,_runTearDowns,4236,get$_runTearDowns,4236,rootLength,4060,get$rootLength,4060,trim$0,4011,_captured_elements_0,4237,addStream$2$cancelOnError,4238,_precomputed3,4239,_completeError$1,3499,_checkEventAllowed,4240,get$_checkEventAllowed,4240,_captured_terse_0,4241,patterns,4242,_setEmpty$0,4243,_fragment,4244,createTimer,4245,get$createTimer,4245,variables,4246,_chainFuture$1,3708,_onDebuggingController,4247,_captured_protected_0,4248,every,4249,get$every,4249,_trace$_captured_trace_0,4250,location$1,3343,perform,4251,get$perform,4251,completeError$1,4084,_captured_bodyFunction_0,4252,_allowInvalid,4253,change$1$timeout,3651,_countTabs,4039,get$_countTabs,4039,_pool$_captured_this_0,4254,outputId,4255,_onResume$0,4256,_extraUnits,4257,toUpperCase$0,4258,__js_helper$_addHashTableEntry$3,3925,_equals_matcher$_value,4259,_controller,4260,_multi_channel$_captured_this_0,4261,_group,4262,_addStreamSubscription,4263,set$_addStreamSubscription,4263,_queue_list$_add$1,4264,forEachJsField,4265,get$forEachJsField,4265,glyphOrAscii$2,1931,_writeLastLine$1,4076,_regExp,4266,__js_helper$_nums,4267,_getTableBucket,4268,get$_getTableBucket,4268,_convert$_computeKeys,4269,get$_convert$_computeKeys,4269,_mapping,4270,millisecondsSinceEpoch,4271,get$millisecondsSinceEpoch,4271,_cell,4272,_checkNotBuilt$1,3751,connectOut$1,4273,_sets,4274,_onUnpaused,4275,get$_onUnpaused,4275,_genericClosure,4276,_mapContents,4277,_captured_indent_2,4278,_innerStreamSubscription,4279,startsWith,4211,get$startsWith,4211,context,2361,get$context,2361,substring$1,4280,matchAsPrefix$2,4124,entries,4281,_multi_channel$_inner,4282,_fillBuffer,4074,get$_fillBuffer,4074,hasRun,4283,get$hasRun,4283,forEachJsField$2,4265,_stack_zone_specification$_onError,4284,elapsedTicks,4285,get$elapsedTicks,4285,_onTestStartedGroup,4286,tearDownAll,4287,_matcher,4288,_engine,4289,_onSinkDisconnected,3561,get$_onSinkDisconnected,3561,containsKey,3801,get$containsKey,3801,_captured_future_0,4290,_captured_getTag_0,4291,error$3$length$position,2966,names,4292,internalContainsKey$1,4293,_runTearDowns$0,4236,_captured_start_2,4294,_addStreamState,4295,set$_addStreamState,4295,_extractStream,4296,get$_extractStream,4296,cancel$0,3476,setState$1,4297,substring,4280,get$substring,4280,clear,4298,get$clear,4298,errorCallback$3,3841,_stop,4299,_stream_group$_closed,4300,os,4301,hasPartialInput,4302,get$hasPartialInput,4302,_getBucket,4303,get$_getBucket,4303,_timeout,4304,parts,4305,set$parts,4305,_pathDirection,4306,get$_pathDirection,4306,describeTypedMismatch,3788,get$describeTypedMismatch,3788,findSlot$1,4307,_scheduleMicrotask,4308,get$_scheduleMicrotask,4308,set$_scheduleMicrotask,4308,_loadPool,4309,_canSendDirectly,4310,get$_canSendDirectly,4310,local,4311,get$local,4311,hour,4312,get$hour,4312,packageRoot,4313,get$packageRoot,4313,_endOfFileEmitted,4314,_captured_callback_0,4315,_captured_terse_1,4316,_future_group$_closed,4317,_convert$_value,4318,readSlot$1,4319,fork,4320,get$fork,4320,elementAt$1,4321,_runUnary,4322,get$_runUnary,4322,set$_runUnary,4322,writeAll$2,4323,_captured_callback_3,4324,_captured_arg_1,4325,_progressLine$2$color,3569,writeSlot$2,4326,_async$_next,4327,set$_async$_next,4327,toChain,3879,get$toChain,3879,_hashCode,4328,_onListen,4329,get$_onListen,4329,_captured_sourceResult_2,4330,runOnce$1,4331,_reviver,4332,_invoker$_captured_this_1,4333,toList$1$growable,4159,innerStream,4334,expect$2$name,539,_thunk,4335,_writeToList,3671,get$_writeToList,3671,_ensureListening$0,4336,_chains,4337,visitConditional,4192,get$visitConditional,4192,_captured_listener_1,4338,_failClosed,3939,get$_failClosed,3939,startColumn,4339,matchTypeError,3798,get$matchTypeError,3798,status,4340,toString$0,3379,_runLiveTest,3974,get$_runLiveTest,3974,_removeAfterFiring,4341,get$_removeAfterFiring,4341,_multi_channel$_box_0,4342,_eventType,4343,_head,4344,url,2360,resume,4345,get$resume,4345,__js_helper$_removeHashTableEntry$2,4346,_removeListeners,4010,get$_removeListeners,4010,codeUnitsEqual$2,3827,_match,4347,_isFiring,4348,get$_isFiring,4348,includeTags,4349,_pathDirection$2,4306,_stack_zone_specification$_registerBinaryCallback$3$4,3587,add,3861,get$add,3861,_current,4350,set$_current,4350,_selector2,4351,toString$1$color,3379,_rti,4352,_asyncComplete,4353,get$_asyncComplete,4353,request,4354,get$request,4354,_sendData$1,4149,_gray,4355,listen$3$onDone$onError,4088,matches,3347,get$matches,3347,_stack_zone_specification$_errorCallback,3648,get$_stack_zone_specification$_errorCallback,3648,toFilePath,3936,get$toFilePath,3936,setRange,3677,get$setRange,3677,_except,4356,set$_except,4356,_engine$_subscriptions,4357,_subscription_stream$_source,4358,set$_subscription_stream$_source,4358,_sdkRoot,4359,_recordResume$1,4360,scheme,4361,get$scheme,4361,_expectedUnits,4362,_captured_column_0,4363,convertDartToNative_PrepareForStructuredClone$1,1533,_closeGap$2,4364,_highlighter$_buffer,4365,_sink$_sink,4366,$call,3391,get$$call,3391,map$2$1,4367,_parser0$_scanner,4368,_bindCache,4369,__internal$_name,4370,_only,4371,set$_only,4371,removeEventListener$3,4372,_setTableEntry,4373,get$_setTableEntry,4373,_live_test_controller$_close$0,4374,toTrace$0,3829,_queryParameters,4375,resolveUri,3924,get$resolveUri,3924,__js_helper$_length,4376,_engine$_captured_this_1,4377,_pretty_print$_box_0,4378,addMapping$1,4379,absolute,4213,get$absolute,4213,_out,4380,_captured_R_3,4381,_async$_isClosed,4382,get$_async$_isClosed,4382,flush,4383,get$flush,4383,_captured_getMain_1,4384,_onStateChange,4385,get$_onStateChange,4385,_captured_K1_2,4386,toLowerCase$0,4387,heartbeat$0,4388,_writeFirstLine,3519,get$_writeFirstLine,3519,registerBinaryCallback$3$1,4389,_method,4390,_collection$_writeToList$1,4391,contains$1,4392,_writeSidebar$1$line,3613,removeOutstandingCallback$0,4393,_functions$_captured_value_1,4394,_prependListeners,4395,get$_prependListeners,4395,_core$_data,4396,_chain$_captured_callback_0,4397,_inner,4398,_fork,4399,get$_fork,4399,set$_fork,4399,_extractStream$0,4296,catchError,3514,get$catchError,3514,_nextIndex,4400,_captured_uri_0,4401,_maps,4402,_async$_addError,3655,get$_async$_addError,3655,_bufferIndex,4403,_red,4404,_unlinkCell,4405,get$_unlinkCell,4405,forEachObjectKey,4406,get$forEachObjectKey,4406,isRootRelative$1,4407,addStream,4238,get$addStream,4238,_restarted,4408,_captured_validVariables_1,4409,_doneFuture,4410,_original,4411,_registerCallback,4412,get$_registerCallback,4412,set$_registerCallback,4412,foldFrames$2$terse,4413,normalize$0,4062,_captured_channel_3,4414,_onMessageController,4415,separatorPattern,4416,_isFirstCharacter,4417,_errorZone,4418,contains,4392,get$contains,4392,addStreamFuture,4419,_built,4420,_requiredPositional,4421,_captured_test_2,4422,_table,4423,set$_table,4423,_deleteTableEntry$2,4424,split$1,4425,padLeft,3950,get$padLeft,3950,_group$_captured_callback_0,4426,_listen$1,4427,_parser$_mapUrl,4428,validatePlatformSelectors$1,4429,_shrBothPositive,3733,get$_shrBothPositive,3733,_async$_map,4430,get$_async$_map,4430,hasEmptyPath,4431,get$hasEmptyPath,4431,sublist,4432,get$sublist,4432,_stream,4433,_invoker$_onRun$0,4434,complete$1,3865,_subscribe,4435,get$_subscribe,4435,_captured_x_0,4436,_sourceStream,4437,set$_sourceStream,4437,_completeWithValue$1,3488,_chainStackTraces,4438,_setDestinationSink$1,4439,internalFindBucketIndex$2,3691,addTearDownAll$1,4440,_live_suite_controller$_isComplete,4441,_captured_result_0,4442,_captured_expectedElement_1,4443,getColumn,4051,get$getColumn,4051,_package_config_resolver$_uri,4444,_reverseListeners$1,4445,_collection$_last,4446,findSlot,4307,get$findSlot,4307,_captured_timeout_0,4447,walk$1,4448,_userInfo,4449,formatStackTrace$2$verbose,4450,replaceRange,3720,get$replaceRange,3720,_addResult$1,3555,remove,4451,get$remove,4451,_queue_list$_add,4264,get$_queue_list$_add,4264,_captured_listener_2,4452,__js_helper$_keys,4453,_encoder,4454,runBinary,4455,get$runBinary,4455,_cancelFuture,4456,_future_group$_captured_this_0,4457,handlesComplete,4458,get$handlesComplete,4458,_trace$_box_0,4459,_captured_pos_1,4460,sublist$2,4432,_invoker$_test,4461,get$_invoker$_test,4461,_metadata$_captured_timeout_2,4462,_guarantee_channel$_box_0,4463,cancelSchedule$0,4464,sourceNameId,4465,runtimeType,4466,get$runtimeType,4466,_collection$_modifications,4467,then,4468,get$then,4468,absolute$7,4213,_captured_maxLineLength_1,4469,_subsetMask,4470,_recordResume,4360,get$_recordResume,4360,_forEachListener,3699,get$_forEachListener,3699,testRandomizeOrderingSeed,4471,visitOr,4472,get$visitOr,4472,expect,539,get$expect,539,_lastProgressFailed,4473,internalContainsKey,4293,get$internalContainsKey,4293,splitMapJoin$2$onMatch,3935,_getTableBucket$2,4268,writeln,3897,get$writeln,3897,_convert$_first,4474,_expanded$_onError$3,3845,_removeListener$1,3981,millisecond,4475,get$millisecond,4475,_highlighter$_captured_this_1,4476,validatePlatformSelectors,4429,get$validatePlatformSelectors,4429,_preGrow$1,3547,configure$2$except$only,3484,request$0,4354,_rootRegisterUnaryCallback$4,4477,_async$_captured_f_1,4478,_remote_listener$_captured_this_0,4479,reversed,4480,get$reversed,4480,_queryParameterLists,4481,hasErrorCallback,4482,get$hasErrorCallback,4482,_scanOperator,3518,get$_scanOperator,3518,_captured_testOn_1,4483,split,4425,get$split,4425,left,4484,_listenToStream$1,3862,_live_test_controller$_isClosed,4485,get$_live_test_controller$_isClosed,4485,_codeUnitAt,4078,get$_codeUnitAt,4078,_highlighter$_captured_this_0,4486,_html$_start$0,4487,_chain,4488,get$_chain,4488,_addingStream,4489,_getTableCell$2,4490,forTarget$1,4491,_captured_minified_2,4492,connectOut,4273,get$connectOut,4273,peekChar,4493,get$peekChar,4493,_collection$_next,4494,_equals_matcher$_match$3,3946,cast$2$0,3866,build,4495,get$build,4495,_engine$_runLiveTest$2,4068,_segmentError,3830,get$_segmentError,3830,_process$1,4496,_precomputed2,4497,lastMatch,4498,get$lastMatch,4498,_description,4499,get$_description,4499,_captured_chainStackTraces_5,4500,startsWith$1,4211,_captured_printZone_5,4501,decoder,4502,get$decoder,4502,hasAuthority,4503,get$hasAuthority,4503,unaryOnError,4504,_needsNormalization$1,4505,_collection$_modified$0,4036,onResume,4506,build$0,4495,_or,3754,get$_or,3754,_printPath,4507,_tdivSlow$1,4508,withResource$1$1,3430,_writeText$1,4123,handleNext,3713,get$handleNext,3713,__js_helper$_rest,4509,_paused,4510,_tearDownAll,4511,get$_tearDownAll,4511,_captured_result_3,4512,_lazy_trace$_thunk,4513,waitForOutstandingCallbacks,4514,get$waitForOutstandingCallbacks,4514,_mayComplete,4515,get$_mayComplete,4515,_captured_T_5,4516,$function,4517,_offset,4518,_asyncComplete$1,4353,load$2$groups,3770,_captured_value_1,4519,runUnaryGuarded,4180,get$runUnaryGuarded,4180,bindUnaryCallbackGuarded$1$1,4520,_sendDone$0,4521,_outstandingCallbacks,4522,get$_outstandingCallbacks,4522,extensions,4523,_closeUnchecked,4524,get$_closeUnchecked,4524,_toListGrowable$0,4525,_captured_end_2,4526,_invoker$_captured_this_0,4527,_convert$_computeKeys$0,4269,codeUnits,4528,get$codeUnits,4528,mapStackTrace$1,487,_precomputed1,4529,_stack_zone_specification$_captured_f_1,4530,insert$2,3998,floor$0,3949,internalGet$1,4531,_names,4532,internalGet,4531,get$internalGet,4531,pattern,4533,_captured_stackTrace_1,4534,_liveSuite,4535,_collection$_newLinkedCell$1,4146,then$1$2$onError,4468,_consumeNewLine$0,4536,_live_test_controller$_close,4374,get$_live_test_controller$_close,4374,_newHashTable$0,4006,_metadata$_box_0,4537,suiteSink,4538,get$suiteSink,4538,_port,4539,_passedGroup,4540,_hostStart,4541,_isWithinOrEquals$2,4542,_unlisten,3908,get$_unlisten,3908,_expanded$_captured_liveTest_1,4543,_live_suite_controller$_closeMemo,4544,_captured_target_0,4545,_captured_host_1,4546,_uriCache,4547,_nativeAnchoredVersion,4548,get$_nativeAnchoredVersion,4548,relative,3643,get$relative,3643,_consumeWhitespace,4549,get$_consumeWhitespace,4549,_scanOr$0,4550,_tryResume,4551,get$_tryResume,4551,_runner_suite$_suite,4552,set$_runner_suite$_suite,4552,bind$1,2478,toSet,4553,get$toSet,4553,_captured_level_1,4554,sourceColumn,4555,_nextListener,4556,connectIn$2,4557,_isCaseSensitive,4558,get$_isCaseSensitive,4558,_progressLine,3569,get$_progressLine,3569,_body,4559,waitForOutstandingCallbacks$1,4514,_description$1,4499,encoder,4560,get$encoder,4560,metadata,4561,get$metadata,4561,_isInputPaused,4562,get$_isInputPaused,4562,inHours,4563,get$inHours,4563,allowRelease$1,4564,serialize,2631,get$serialize,2631,_captured_getUnknownTag_0,4565,_invoker$_completer,4566,intersection$1,4567,_ensureDoneFuture,4174,get$_ensureDoneFuture,4174,state,4568,get$state,4568,_state,4569,reportLiveTest$2$countSuccess,4570,_clearPendingComplete$0,4571,_captured_timeout_2,4572,_mapUrl,4573,_controllers,4574,forEachObjectKey$2,4406,fromUri$1,1988,_tearDownAllTrace,4575,_chain$_captured_T_1,4576,_highlighter$_box_0,4577,_multi_channel$_captured_T_2,4578,_subscriptions,4579,every$1,4249,_captured_V_2,4580,_captured_original_1,4581,formatStackTrace,4450,get$formatStackTrace,4450,_subscription_stream$_captured_this_0,4582,_newLinkedCell,3662,get$_newLinkedCell,3662,_stream_queue$_captured_this_0,4583,_runCalled,4584,_testCount,4585,onDone$1,4586,_isInitialState,4587,get$_isInitialState,4587,_stack_zone_specification$_registerUnaryCallback$2$4,3649,isEven,4588,get$isEven,4588,completeError$2,4084,_checkState$1,3930,_types,4589,get$_types,4589,_stack_zone_specification$_registerUnaryCallback,3649,get$_stack_zone_specification$_registerUnaryCallback,3649,_closeInnerChannel,3681,get$_closeInnerChannel,3681,root,4590,_writeIntermediateLines$1,4591,library,4592,get$library,4592,_multiLineComment$0,3928,_hasValue,4593,member,4594,get$member,4594,addStream$1,4238,_lastSubscription,4595,set$_lastSubscription,4595,_onListen$0,4329,dartException,4596,==,3446,get$==,3446,_schemeEnd,4597,__js_helper$_captured_this_0,4598,isPosix,4599,get$isPosix,4599,_hasSkipped,4600,heartbeat,4388,get$heartbeat,4388,_cancel$0,3695,_isUpgraded,4601,get$_isUpgraded,4601,_writeSidebar$0,3613,_print,4602,get$_print,4602,set$_print,4602,_tryResume$0,4551,_rootRegisterBinaryCallback$4,4603,_recordPause$1,3902,_useCapture,4604,firstMatch,3914,get$firstMatch,3914,_captured_port_0,4605,pause$1,4179,type,4606,get$type,4606,_scanIdentifier$0,4607,substring$2,4280,_onDone,4608,set$_onDone,4608,_computeKeys,3752,get$_computeKeys,3752,origin,4609,get$origin,4609,bindUnaryCallbackGuarded,4520,get$bindUnaryCallbackGuarded,4520,convert$1,3794,_multi_channel$_parent,4610,%,4611,get$%,4611,_keysArray,4612,get$_keysArray,4612,runUnary,4151,get$runUnary,4151,_sourceFile,4613,_captured_skip_3,4614,registerBinaryCallback,4389,get$registerBinaryCallback,4389,insertAll$2,4615,_platform_selector$_inner,4616,_captured_pp_0,4617,_engine$_captured_this_0,4618,_eventState,4619,child,4620,forTag,4621,_channel,4622,_captured_iterator_0,4623,checkMutable$1,4624,_captured_controller_3,4625,flush$2,4383,replaceFirst$2,4626,_binarySearch$1,4627,transform$1$1,4628,_mapper,4629,start$0,2491,replace$2$path$pathSegments,3540,_tdivFast$1,4630,_captured_oldPredicate_0,4631,_exception,4632,replace$1$pathSegments,3540,_captured_arg2_2,4633,toUri$1,4032,_suite,4634,isIdentifier,4635,get$isIdentifier,4635,convertNativeToDart_AcceptStructuredClone,2104,get$convertNativeToDart_AcceptStructuredClone,2104,_primary,4636,then$1$1,4468,removeAt,4637,get$removeAt,4637,_captured_div_1,4638,__internal$_current,4639,set$__internal$_current,4639,__js_helper$_current,4640,set$__js_helper$_current,4640,_removeEventListener,4641,get$_removeEventListener,4641,_optionalNamed,4642,onDone,4586,get$onDone,4586,reportLiveTest,4570,get$reportLiveTest,4570,_isSent,4643,get$_isSent,4643,_receiver,4644,forPlatform$1,4645,_runner_suite$_close,3758,get$_runner_suite$_close,3758,_delegate,4646,get$_delegate,4646,firstPendingEvent,4647,inSameErrorZone$1,4648,expect$1,539,intersection,4567,get$intersection,4567,horizontalLine,1933,get$horizontalLine,1933,frames,4649,get$frames,4649,onError,3472,get$onError,3472,_span,4650,_captured_channel_2,4651,group,587,get$group,587,_currentExpansion,4652,set$_currentExpansion,4652,_union_set_controller$_sets,4653,_async$_captured_this_0,4654,_serializeTest$3,4073,_isUnicode,4655,get$_isUnicode,4655,_shlPositive,3542,get$_shlPositive,3542,_lazy_trace$_captured_terse_2,4656,spanFor,3884,get$spanFor,3884,peekChar$0,4493,_writeSidebar,3613,get$_writeSidebar,3613,_expanded$_onDone,3983,get$_expanded$_onDone,3983,_span_exception$_source,4657,__internal$_start,4658,_modifications,4659,_nextPosition,4660,_toEncodable,4661,hasMatch$1,4662,_bind,3840,get$_bind,3840,_canFire,4663,get$_canFire,4663,postMessage$1,4664,_setPendingEvents$1,4104,internalComputeHashCode,4665,get$internalComputeHashCode,4665,_isOnlyWhitespace,4110,get$_isOnlyWhitespace,4110,_outstandingCallbackZones,4666,_captured_zone_1,4667,_isWithinOrEqualsFast$2,3550,rootPattern,4668,_captured_id_1,4669,pause,4179,get$pause,4179,_platform_selector$_span,4670,decode$1,3791,replaceFirst,4626,get$replaceFirst,4626,isUtc,4671,_postMessage_2$1,4672,set,4673,get$set,4673,pathFromUri,4674,get$pathFromUri,4674,_hasOneListener,4675,get$_hasOneListener,4675,_activeLoadTests,4676,_containsTableEntry$2,4677,_restartable_timer$_timer,4678,_recursiveMatch,3612,get$_recursiveMatch,3612,_pendingEvents,4679,get$_pendingEvents,4679,_addError$2,4680,_captured_prototypeForTag_0,4681,_nullErrorHandler$1,4682,_captured_cleanUp_3,4683,+,4684,get$+,4684,_chainSource,4685,get$_chainSource,4685,_complete,4140,get$_complete,4140,_portStart,4686,_isWithinOrEquals,4542,get$_isWithinOrEquals,4542,_printZone,4687,_multi_channel$_captured_T_1,4688,_captured_frame_0,4689,_columnStart,4690,_functions$_captured_result_0,4691,_addLiveSuite$1,4692,_pattern,4693,_onStreamDisconnected$0,4694,describeMismatch,4089,get$describeMismatch,4089,_stackTrace,4695,elapsed,4696,get$elapsed,4696,_process,4496,get$_process,4496,_closeChannel$2,3493,accept$1,4697,_containsTableEntry,4677,get$_containsTableEntry,4677,_async$_subscription,4698,get$_async$_subscription,4698,_packageResolver,4699,_eventsReceived,4700,_isMultiLine,4701,get$_isMultiLine,4701,_errors,4702,_index,4703,onZero,4704,get$onZero,4704,internalRemove,3937,get$internalRemove,3937,_captured_chain_0,4705,_runSkippedTest,4706,get$_runSkippedTest,4706,take$1,3568,visitAnd,3706,get$visitAnd,3706,_captured__prettyPrint_1,4707,_shrReceiverPositive$1,4147,removeAll$1,4708,apply,3966,get$apply,3966,_captured_arg1_1,4709,_callOnCancel$0,4710,firstWhere$1,3948,spanFrom$1,4181,_binarySearch,4627,get$_binarySearch,4627,_computeHashCode,4139,get$_computeHashCode,4139,_onCompleteGroup,4711,last,4712,get$last,4712,_getNext,3894,get$_getNext,3894,_channelNames,4713,sourceUrl,4714,get$sourceUrl,4714,_async$_onListen$1,4715,_resetTimer,4716,get$_resetTimer,4716,runBinary$3$3,4455,pathsEqual$2,3576,_currentTrace$1,3566,perform$1,4251,_liveSuites,4717,_stream_channel_completer$_set,4718,_file$_end,4719,forPlatform,4645,get$forPlatform,4645,_captured_value_2,4720,remove$1,4451,_gatherCoverage,4721,_isHttps,4722,get$_isHttps,4722,_closeUnchecked$0,4524,_captured_result_1,4723,removeFragment,3911,get$removeFragment,3911,_closedIds,4724,_captured_channel_0,4725,isNewLine,4726,handleUncaughtError$2,3603,elementAt,4321,get$elementAt,4321,highlight,3871,get$highlight,3871,_runCount,4727,close,3870,get$close,3870,_add,3797,get$_add,3797,_union_set$_captured_this_0,4728,_runSkipped,4729,_skipped,4730,_stack_zone_specification$_captured_R_2,4731,_writeIntermediateLines,4591,get$_writeIntermediateLines,4591,_isPackage,4732,get$_isPackage,4732,_findLine$1,3524,_expectsEvent$1,4733,_validateTags,4734,get$_validateTags,4734,copy,4735,_captured_error_2,4736,bottomLeftCorner,1937,get$bottomLeftCorner,1937,_addPending$1,4737,_stringSink,4738,expand,3722,get$expand,3722,_get$1,4031,_progressLine$1,3569,toRadixString,3971,get$toRadixString,3971,resolve$1,4218,insertAll,4615,get$insertAll,4615,remainder$1,4739,_inAddStream,4740,get$_inAddStream,4740,_pool$_captured_registered_1,4741,_captured_serialized_0,4742,_addError$1,4680,_onReleaseCompleters,4743,_functions$_captured_result_1,4744,inGoogle,4745,runBinaryGuarded$2$3,4746,_allowErrors,4747,_captured_body_0,4748,registerBinaryCallback$3$2,4389,_createSubscription$4,4749,condition,4750,map,4367,get$map,4367,checkGrowable$1,4751,moveNext,3558,get$moveNext,3558,absolutePathToUri$1,4752,_runtimes,4753,_captured_loadResource_2,4754,_collection$_rest,4755,_addError,4680,get$_addError,4680,registerCallback$1$2,3602,_setRemoveAfterFiring$0,4756,_sink,4757,set$_sink,4757,_captured_retry_6,4758,internalComputeHashCode$1,4665,_linkStreamToController$0,4096,_context$_current,4759,_onResume,4256,get$_onResume,4256,_registerBinaryCallback,4760,get$_registerBinaryCallback,4760,set$_registerBinaryCallback,4760,_ensureListening,4336,get$_ensureListening,4336,_stream_completer$_controller,4761,set$_stream_completer$_controller,4761,isCore,4762,get$isCore,4762,_setDestinationSink,4439,get$_setDestinationSink,4439,_captured_line_1,4763,_invoker$_onRun,4434,get$_invoker$_onRun,4434,getOffset,4764,get$getOffset,4764,listen$1,4088,indexOf,3530,get$indexOf,3530,_createPeriodicTimer,4765,get$_createPeriodicTimer,4765,set$_createPeriodicTimer,4765,_pool$_timeout,4766,mustCopy,4767,_firstSubscription,4768,set$_firstSubscription,4768,_scanner$_next,4769,foldFrames,4413,get$foldFrames,4413,_callOnCancel,4710,get$_callOnCancel,4710,onTestStarted,4770,get$onTestStarted,4770,_scanAnd$0,4771,__js_helper$_removeHashTableEntry,4346,get$__js_helper$_removeHashTableEntry,4346,_sendDone,4521,get$_sendDone,4521,_once,4772,absolutePathToUri,4752,get$absolutePathToUri,4752,_query,4773,config,4774,get$config,4774,_future,4775,removeFirst,4007,get$removeFirst,4007,_subscribe$4,4435,next,4776,get$next,4776,set$next,4776,_removeEventListener$3,4641,style,4777,_invoker$_tearDowns,4778,map$1$1,4367,_contains$1,3632,__js_helper$_getBucket$2,4779,_execGlobal,3731,get$_execGlobal,3731,_removeHashTableEntry$2,3976,complete$0,3865,_stopwatch,4780,decode,3791,get$decode,3791,addOutstandingCallback$0,4077,internalSet,3764,get$internalSet,3764,_getBucket$2,4303,join$0,3647,toSet$0,4553,_active,4781,_rootRun$4,4782,_remove,3736,get$_remove,3736,decrement,3777,get$decrement,3777,_guardCallback,4783,get$_guardCallback,4783,_onTestStartedController,4784,isAbsolute$1,3724,path,4785,get$path,4785,_async$_target,4786,_handleError,3633,get$_handleError,3633,_captured_K2_0,4787,_knownTags,4788,_tick,4789,_onReleaseCallbacks,4790,schedule,4055,get$schedule,4055,_captured_suite_0,4791,_pathStart,4792,_platform_selector$_captured_platform_0,4793,_restartable_timer$_duration,4794,_captured_portSubscription_1,4795,_badEventState,3968,get$_badEventState,3968,_guarantee_channel$_captured_this_0,4796,setEmpty$0,4797,_invalidPosition$3,4798,visitVariable,3564,get$visitVariable,3564,_containsKey$1,4799,_lastMatchPosition,4800,_captured_onPlatform_8,4801,_captured_predicate_1,4802,_addListener$1,4803,_mainController,4804,_colorize$2$color,3624,_guarantee_channel$_captured_this_1,4805,_invoker$_box_0,4806,_length,4807,typedMatches,3557,get$typedMatches,3557,_sendError,4005,get$_sendError,4005,nextKind,4808,get$nextKind,4808,_collection$_box_0,4809,isRootRelative,4407,get$isRootRelative,4407,_subscription,4810,set$_subscription,4810,addTo$1,4811,_tdivFast,4630,get$_tdivFast,4630,_uri,4812,isDone,4813,get$isDone,4813,_stateData,4814,setChannel$1,4815,_writeSidebar$1$end,3613,_captured_R_2,4816,_stream_channel_completer$_channel,4817,set$_stream_channel_completer$_channel,4817,runes,4818,get$runes,4818,_jsWeakMapOrKey,4819,_containsKey,4799,get$_containsKey,4799,_trimVMChain$1,3639,_queue,4820,_null_stream_sink$_closed,4821,_lineStarts,4822,listen,4088,get$listen,4088,_eventQueue,4823,bindCallback$1$1,3565,_engine$_runLiveTest,4068,get$_engine$_runLiveTest,4068,isSeparator$1,4824,_arguments,4825,_disconnected,4826,_validateTags$0,4734,_context,4827,_createSubscription,4749,get$_createSubscription,4749,_captured_stream_1,4828,_indexFor$2,4829,scheduleMicrotask$1,302,_cancelOnError,4830,get$_cancelOnError,4830,runOnce,4331,get$runOnce,4331,_tdivSlow,4508,get$_tdivSlow,4508,needsSeparator,3710,get$needsSeparator,3710,rest,4831,get$rest,4831,_rest,4832,errorCallback,3841,get$errorCallback,3841,rootLength$1,4060,_captured_stackTrace_2,4833,downEnd,1915,get$downEnd,1915,group$9$onPlatform$retry$skip$solo$tags$testOn$timeout,587,_onPause,3984,get$_onPause,3984,release$0,3757,_guardCallback$1,4783,forEach$1,3005,_stream_subscription$_source,4834,_checkEventAllowed$0,4240,_stack_zone_specification$_run$1$2,3958,_toFilePath$0,4835,sourceUrlId,4836,_shrOtherPositive,4837,get$_shrOtherPositive,4837,_closed,4838,_onIdleController,4839,_value,4840,_captured_error_1,4841,writeCharCode$1,4842,_close$0,4119,_tearDownAlls,4843,addError,3878,get$addError,3878,_captured_sourceMap_1,4844,walk,4448,get$walk,4448,_self,4845,onStateChange,4846,get$onStateChange,4846,addError$2,3878,_timeoutTimer,4847,currentChain$1,4848,_print_sink$_buffer,4849,_live_test_controller$_suite,4850,string,4851,_engine$_captured_liveTest_1,4852,isBrowser,4853,getOffset$1,4764,_suiteController,4854,_canonicalRecipe,4855,_canceled,4856,get$_canceled,4856,_nativeGlobalVersion,4857,get$_nativeGlobalVersion,4857,_pending,4858,set$_pending,4858,_queue_list$_tail,4859,_createTimer,4860,get$_createTimer,4860,set$_createTimer,4860,passed,4861,get$passed,4861,_onData,4862,set$_onData,4862,change$2$skip$skipReason,3651,_getTableCell,4490,get$_getTableCell,4490,_captured_action_1,4863,_captured_body_1,4864,_stream_group$_captured_this_0,4865,_captured_liveTest_1,4866,addEventListener,3366,get$addEventListener,3366,_captured_beforeLoad_4,4867,spanFor$3$files,3884,_printsOnFailure,4868,merge$1,4216,_writeAuthority$1,4869,_runSkippedTest$3,4706,spanFor$3$uri,3884,current,621,get$current,621,_onTimeout$0,4870,_onStateChange$2,4385,startChunkedConversion$1,4871,next$0,4776,accept,4697,get$accept,4697,handleWhenComplete$0,4872,_addStreamCompleter,4873,_group$_map,4137,get$_group$_map,4137,_captured_K_1,4874,runBinaryGuarded,4746,get$runBinaryGuarded,4746,_toNonSimple$0,3743,normalize$3,4062,getOffset$2,4764,clear$0,4298,inputId,4875,cloneNotRequired$1,4876,first,4877,get$first,4877,matches$1,3347,_handleError$2,3633,shuffle$1,4878,_pauseCompleter,4879,newJsList$1,4880,createTimer$2,4245,_registerUnaryCallback,4881,get$_registerUnaryCallback,4881,set$_registerUnaryCallback,4881,key,4882,_first,4883,_captured_T_1,4884,name,4885,get$name,4885,_simpleMerge$2,3973,_postMessage_1$2,4886,_addEventListener$3,3922,_resetTimer$0,4716,_consumeWhitespace$0,4549,_keys,4887,_live_test_controller$_run$0,3640,allMatches$1,3605,onPause,4888,fork$2$specification$zoneValues,4320,_captured_data_1,4889,isSeparator,4824,get$isSeparator,4824,withResource,3430,get$withResource,3430,hasQuery,4890,get$hasQuery,4890,_nums,4891,_setErrorObject$1,4892,_collection$_source,4893,handlesValue,4894,get$handlesValue,4894,_progressLine$3$color$suffix,3569,_stack_zone_specification$_captured_R_3,4895,_captured_channel_1,4896,run,4042,get$run,4042,getLine$1,4038,_stack_zone_specification$_registerCallback$1$4,3692,seen,4897,_lazy_chain$_inner,4898,set$_lazy_chain$_inner,4898,_selector1,4899,_consumeNewSegment$0,4900,lastIndexOf$2,3844,_urlSafe,4901,input,4902,_subscription_stream$_captured_stackTrace_2,4903,_reverseListeners,4445,get$_reverseListeners,4445,normalize,4062,get$normalize,4062,isRunning,4904,get$isRunning,4904,postMessage,4664,get$postMessage,4664,round,3839,get$round,3839,_deleteTableEntry,4424,get$_deleteTableEntry,4424,prettyUri$1,3506,_trace$_captured_level_1,4905,_selector,4906,virtualChannel$1,4017,_pause$0,4907,_isScheme$1,4908,_onStreamDisconnected,4694,get$_onStreamDisconnected,4694,_parsed_path$_captured_this_0,4909,_declarer$_captured_this_0,4910,_isSourceStreamSet,4911,get$_isSourceStreamSet,4911,_local,4912,set$_local,4912,length,4913,get$length,4913,set$length,4913,separator,4914,get$separator,4914,_captured_T_3,4915,_captured_handleError_0,4916,toList$0,4159,_serializeGroup$3,3749,fillRange,3701,get$fillRange,3701,_setChained$1,4917,_yellow,4918,visitOr$1,4472,_captured_location_2,4919,describe$1,3396,removeLast,3819,get$removeLast,3819,registerCallback,3602,get$registerCallback,3602,validate,3977,get$validate,3977,cleanupSlots$0,4920,max$2,470,_captured_depth_3,4921,_jsTrace,4922,codeUnitAt$1,3808,_captured_dispatch_1,4923,_end,4924,__js_helper$_unlinkCell,4127,get$__js_helper$_unlinkCell,4127,_captured_matcher_0,4925,addTo,4811,get$addTo,4811,_modificationCount,4926,_processed,4927,_timer,4928,_writeString$1,4929,_cloneResult,3638,get$_cloneResult,3638,_captured_platform_1,4930,_fail$1,4931,isClosed,4932,get$isClosed,4932,keys,4933,get$keys,4933,isPaused,4934,get$isPaused,4934,pathFromUri$1,4674,_onCancel,3575,get$_onCancel,3575,_captured_engine_0,4935,_set$2,4212,_setUps,4936,_expanded$_sink,4937,_grow$0,4938,text,4939,get$text,4939,any,3793,get$any,3793,_findColumn$3,4009,_onErrorController,4940,_text,4941,_captured_this_0,4942,copyList,4071,get$copyList,4071,_prependListeners$1,4395,handlesError,4943,get$handlesError,4943,_contents,4944,_captured_milliseconds_1,4945,_updateRequests$0,4220,_captured_sdkLib_3,4946,_initializeText$0,4947,_captured_trace_0,4948,_evalCache,4949,_closeGap,4364,get$_closeGap,4364,_limit,4950,_toggleEventId$0,4951,_live_suite_controller$_active,4952,_addLiveSuite,4692,get$_addLiveSuite,4692,_createNode$1,4953,copy$0,4735,toSpec$0,4954,userInfo,4955,get$userInfo,4955,_addListener,4803,get$_addListener,4803,excludeTags,4956,_indexFor,4829,get$_indexFor,4829,_separatorIndices,4957,setState,4297,get$setState,4297,_captured_completer_1,4958,_is,4959,_shrOtherPositive$1,4837,_isUsed,4960,putIfAbsent$2,3873,_paddingAfterSidebar,4961,get$_paddingAfterSidebar,4961,code,4962,sink,4963,get$sink,4963,_captured_skipReason_7,4964,_destinationSink,4965,set$_destinationSink,4965,_values,4966,_suite$_metadata,4967,_addLoadSuite$1,4968,_captured_message_1,4969,_compareIterables,3860,get$_compareIterables,3860,values,4970,get$values,4970,_nativeRegExp,4971,chainFor,4079,get$chainFor,4079,_setTableEntry$3,4373,removeAt$1,4637,_isDefined,4972,_isDone,4973,resume$0,4345,_isDotAll,4974,get$_isDotAll,4974,_unlinkCell$1,4405,offset,4975,get$offset,4975,putIntoObject$3,4976,copies,4977,print,412,get$print,412,_runBinary,4978,get$_runBinary,4978,set$_runBinary,4978,_addPending,4737,get$_addPending,4737,_start,4979,_onTestStarted$1,3482,_stream_queue$_source,4980,year,4981,get$year,4981,_requestQueue,4982,_needsNormalization,4505,get$_needsNormalization,4505,$le,4983,$indexSet,4984,$index,4985,$xor,4986,$or,4987,$eq,4988,$mod,4989,$shr,4990,$and,4991,$ge,4992,$gt,4993,$lt,4994,$mul,4995,$not,4996,$shl,4997,$div,4998,$sub,4999,$add,5000,$negate,5001,$tdiv,5002"},"frames":"qsTAyEiB+2EuH;eAEFmduF;mXEqKbndAAAAAwR,A;iQAuHeAsI;eAEFmdwG;uEAohBwBnd8B;qEAEFAqC;oEAEDAoC;w7GGrpBvBAyEAhOXA6B,A;u1CC+YE4hF8F;qxCA0MSCuB;uCAAAA6B;wIAqBeC6B;0YAYjBD4C;uyHA4NQ7tBgB;+5DA8Ya/zD4C;igBAmBjByIyD;oFAOEAyD;eAIJzI2C;iEASAA6C;uPAmCcDoC;urCA4QZA+S;wnJAgSHAoE;iJAKKA0B;qLAWaAwH;oLASbA0B;sOAiCmBA4B;6HAGtBA4B;iRAmCCxzEAIn4BNu1JkF,gE;wEJq4BKC+C;6CACEA4B;0IAUDx1JAIh5BNu1J8D,yD;oDJk5BMC4B;2kBAmBHhiFAKj9D0BA8E,A;q1BLqlEtBA6D;AAEAA0Q;w+IAwPmCiiF0C;8EAAAA+E;wZAYXAwC;8EAAAAuD;49DAkGJA+J;AACICyL;w6CAsI7B70JACnsEF80JiD,sB;0GDusEE90JACvsEF80JiD,sB;qQDyuEcniF+G;0iCAgbMoiFgG;+dA6BjBpiFqC;qNAqBAAkD;m4BIt6FN+hFgC;OAEKtzJmBArBwB4zJY,wC;wEAyBVAM;wDAKnBCqC;sYAOACwF;AAhBK9zJAAtBFszJiB,A;AAsCHQ2B;sFAIACgE;AApBK/zJAAtBFszJiB,A;AA0CHS2B;iCACiB9zJAAwYd8zJsE,A;AA7ZE/zJAAtBFszJmB,A;AA2CcrzJAAwYd8zJ6B,2C;8xCA9VC5zJAAq2BN6zJqB,A;4zDAhxBKViC;0BAGmB/hFuC;4DACWxzE0C;4EAGpBw1J4C;8PAqDsBlzJAHmW7B4zJ6BAjBR3zJAA3I8B4zJuD,A,A,A;OGvMO7zJ+D;6NAWXizJkC;AACbaiE;qDAEXbyC;iFASKa0C;gJA0HLt0Ja;0BAAAA2D;oKAygBwByzJkC;gnEF/1BnB1yJAA2BTwzJoI,A;kTAZSxzJAAYTwzJoI,A;6yCApEuBlzJAAzChBmzJwE,A;0zDA+QSjzJsL;0gCKjNhBmwEAAAAAqG,A;+WCpESusEwB;+IAGyBnbkB;0bA0BhBxsDO;qfAuBPm+E+F;sCACFCiC;gBAGTCqF;6vBA2CODiC;0YAyBPhkDADKQh/B4B,mE;2CCLRlwDsC;wCACEi/Fc;+EACAAI;2EAGFAc;kmBA8DkCm0CgB;AAA1BFoC;0EAGRCqF;grPP/KkDEyC;AAA3BCY;AACfCyE;AADeD2B;m8CAySPEmB;qDAGVCmD;AAEW3/E0H;4FAIT4/EuD;yiBAcOCiC;+WAaMCAAqnCiBCAA/C9B//EiH,A,A;OAtkCa8/EuE;2PAMAGAAqnCjBCAAnDIlgFiH,A,A;OAlkCaigFuE;2PAMAGAAqnCjBCAAvDIrgFiH,A,A;OA9jCaogFuE;uUAQkCG2C;+HAGpCC+C;geAUMCqD;wvBAiBNbsD;mUAOCcgD;qiCAgCGC6B;ymCA+B0BCAA5ORxkFkD,A;AA6OrBykFmE;AAEACmE;AAEACmD;ycAgCd51JAAzB0B4zJsB,A;+NAgD5BxwJAAnD+BwwJmB,A;AAoD1BtwJ0B;mhCA8EkBtDAA/HK4zJoM,A;8MAoJpBrxJqF;2LAoBRszJsB;AADG5kFgB;8EAOkB1uE4C;iHAsCVmyJ6D;AAKXtrJ0E;AAIE0sJiB;AADACQ;yDAGalhFgI;+UAaGugF2DAxlBGYqB,A;6FAkmBfC4H;AAMNCmB;+HAWGCgC;6IAQOCiC;uBAKVhzJAAvR+BwwJiB,A;83BA8T/BuC8E;u2BA6BgBvjFiC;sOAQAAiC;+1IAmKXxpE8C;oPAUYksJkEAp1BDUiB,A;mnDAk5BLtBiC;gQASU2BkC;wGAKICkC;wGAKAlCkC;sHAKTgBkC;8VAcSXmC;4IAOXc2CA36BISsC,A;+4BA0mCLO4F;u4BAwCCCmB;8CAGVC+B;+UAUUlCmB;8CAGVC+C;AAEuB3/E0H;6jBAgDZAkI;AACjB6hF0B;AASIXQ;yCACADW;2CACAIQ;yPAyDGSAAIOlBAArvCHxkF4C,A,AAsvCP2lFqB,GACAC2C,A;gQAwBGCAAKOrBAApxCHxkF4C,A,AAqxCP2lFwB,AACAG4B,GACAF2C,A;qSASGGAAKOvBAAryCHxkF4C,A,AAsyCP2lFsB,AACAGyB,GACAF2C,A;2QASqBhiFiI;wTAYF2gF4B;OAEE3gFiI;mKAqBZoiF2K;iFAINCAAKOzBAA71CHxkF4C,A,AA81CP2lFqB,AACAG4B,AACAIyC,wBAGE7CsC,GAEFuC6B,A;8LAuBInCc;yBACQWoE;uKAIH+BAAlBEviF0H,kF;iFAsBRwiFAAKO5BAA14CHxkF4C,A,AA24CP2lFsB,AACAG8B,AACAI6B,GACAN6B,A;6TA8CSSAAxCPziFyJ,AACJ0iF2xB,gC;mFA2CKCAAKO/BAAr8CHxkF4C,A,AAs8CP2lFsB,AACAGiC,AACAI2B,GACAN+B,A;oMAaSYAAPP5iF0H,sE;mFAWC6iFAAKOjCAA/9CHxkF4C,A,AAg+CP2lFsB,AACAGuC,AACAIuB,GACAN+B,A;4ZAoKOcoD;itBAuBCCyL;qDAIkBrBiE;qDAIAsBiE;sDAIACiE;2DAItBCAAqERCmC,AACACuB,A;2DAlEQCkBA4GWC2BAmFACmB,4DAEnBHsC,A,imB;sPAtLsBtDAAjccCAA/C9B//EwI,A,+D;2IAwfgBigFAAncpBCAAnDIlgFwI,A,+D;2IA8fgBogFAArcpBCAAvDIrgFwI,A,+D;2DAigBEkjFAAiCRCmC,AACACuB,A;2DA9BQIkBAiG6C5CAApyDdxkFqJ,A,meA6zDvBknF2BAiCGCmB,4DAEnBHgD,A,AApCoBvCsD,AAEACmE,AACAC0D,wH;2DAxHZmCAAyBRCmC,AACACuB,A;0CAtBQKAA0HYH2BAyBDCmB,4DAEnBHqG,A,A;4DAjJQFAAiBRCmC,AACACuB,A;2CAdQMAAwHYC2BA0BDJmB,iEAEnBHqG,A,A;o9BAhHoDQsD;wJAUpCC4DAroBDhEgB,2BAEKW2F,AAGODiD,2X;0JAktBHuD4D;2DAIAC4D;uhCAsDTlEiC;wDAEcWqC;+OAQTA4D;w7BAuGJEwC;8GAKFbc;6CA6BI2BuC;yGAUJAkC;MAAAAAAxoEILmB,A;iGAipEA5BuC;sOAYIkCuC;0HAWKlCkC;oOAYIkCkC;4rBA4BS7B8CAvrEtBuBmB,A;AAwrEVvBwC;s9BAsBYa4CAxtEFUiB,A;AAytEEVsC;gkCA4BHuDa;iMAQAAa;+NASAAuC;oZAoBDC4B;+NAEJDiB;mSASKzD8C;iBACAA8C;gSAkBJyDyB;AACAAe;80BA0ECnEc;4NAYJU0CAp7EaYqB,A;AAo7EeZyC;2LAMxBC2CA96EIWqB,A;AA86EoBX0C;yJAMxBC2CA35EIUqB,A;AA25EmBV0C;yJAC/ByD6O;4DAIiBtE2CAt5ELuBqB,A;AAu5EJvB0C;qrCAqDDCc;+JAMON0C;w2FK1kFJ4EqG;oiBA+BhBC8C;grZUpF4B3+BuD;sMAmB9BrpD+C;4HAeAgNwD;4EAiFWhN2BA7BSioFAAAAjoFeE0BKlwDgB,2B,A,sC;2JFkBR4pFQ;y1BA2DM15BwBE7EElwDwD,A;AF6EFo4IqE;mdAiCXp4I0C;sJI9JckwD4BFgDDlwDgB,iC;AE/CjB61G4B;8IAyBkB3lD4BFsBDlwDgB,iC;saEORmwDoBFUmCnwDgB,uCAVpDo7DAAUAAAATEg9E6D,A,A,A;sKEEmBloFAFVIlwDwB,8D;gKEcfxVAAsrBuC0lEwC,A;0QA9oB3BlwDkC;8LAGRxVAA2oBmC0lEmE,A;qCAvoBpC09BoBFjDM5tFgB,iCADnB4tFAAAAAmD,A,A;6EE4HsC19B0KFvIblwD6D,A;kkBEuMRmwDAAlKJ27BoBFnCwC9rF+B,AAArD8rFAAAAAqB,A,A,A;uhBE0Q0BoDANsHMh/BiC,+BAAAAsC,A;iHMnFLA0CF/SFlwDoH,A;4TEgrBKAyD;mGAEpBxVAAkBuC0lEiE,A;uMF7rBjDkLAAAAAAACEg9EkF,A,A;oIAiOeCoB;sDAIfCqBArIOC4B,iC;6dAqKOCiE;uCAEICyF;uRAQhBCqBAvOKF6B,iE;ycAmUSHkC;8BACSMuB;+DAGYC2D;yjBA8BV3NkB;iEAaNt0EmB;kCAZIkiF8C;uDACGldiG;AAWPhlEsB;sDATgBiiFiBAvS9BD4B,2D;oIA8SiB34I0B;+BAEH22DqH;yFAoEJk5DkB;+lBAuBOwoB8B;AACFSiBA5SdT4B,iK;AA6SEUiBA/WFV4B,iBACMA+B,sG;gMA2XASqBA1TNTsB,sK;gFA+TJWAA9YIXsB,A;qBA2YJDsK;yBAGAYoH;mqCIrrBQCoD;+GAYqB/oF+D;4HAIrB+oFoD;yXAsBkB/oFyD;qZAwCPlwD2B;gNASrB27HM;iCAAAAgD;qLAKC37HsB;8HCuBKkwD+J;+JAQUy9BAC4SQz9BuE,A;+ED7OfA2B;wDAAAAsC;qGAs6DLA4D;OAAAAuD;qIClkEIAwG;AACAAuG;6TAwtBLlwDwD;0PChtBiB64IAAAA74I0D,A;sGAgBxBkwDqF;wKA+cKlwD6D;qXChjB2BA8C;wHAIhBxVAN84BiC0lE6F,A;u9BCj3BtClwDsB;2pDFwjCJk5IsE;weAYAAsE;wiBAYAAsE;2vBA0BmBvdc;iCAAAAwB;uoBA0BbwdAH/jCiB5/BmD,yB;OG+jCjB4/BoE;sEAIbCc;gFAIKp5IqC;4hBA0BMkwD8CArXXAAAAAAgQAcYA4D,gIAGAA4D,uIAGAA4D,sHAIAAmH,kUAeAAkG,sKAMAA6G,wC,A,A;u/BA4kBc6Mie;ygBAkBnB/8D0E;6/gBSr8CYkwD8C;+CAAAAwD;0cA4dAmpFAC/cPnpF4C,A;4GD+cOmpFAC/cPnpF+D,A;sMD4e+BmpFAC5e/BnpFuF,A;iFDofCmpFACpfDnpFqF,A;sEDupCOAqD;6EA8BmBAqD;sJAKPAuD;qGAqU7BkJ8H;2MA2GFlJAAAAAoD,A;u8BGz6CUo3DiH;wQAqBcp3DkD;iGAGpBo3DiG;oRAMKh7BkB;4gHGrPMp8BqD;gdAoBNo8BkB;uJCwdTp8BAAAAA4H,A;+kIC7ZaA2C;26IjCkDCopFwD;gVAwDMC8C;mmBAiOXC2D;iKAYACqC;6BAAAAc;qMAoBEC8E;OAAAAyH;yEAGACoH;yrCAoEHzpFuG;yMA+DQw+CsC;AAEDkrCc;uFAGFAc;0EAGEAkC;qhBA+GoBndAI3lBcqVuI,A;kGJkmBnCr+CyF;0TAKRo0CAA/Ja9lEiI,A;+7IsCnZf7RyG;+HClKFkpFwC;kZEixBkBSgQ;usGAAAA8D;8CAAAAqD;ovEA8NT3pFoG;82FAuUSAAlCrS4B4pFkD,A;sIkCqS5B5pFAlCrS4B4pFuC,A;24FkC6blCC4E;8RAcoBCgB;4GAENAuB;gOAOI14BA7B/jCR5S4D,A;8J6BokCTsrC+D;AACFtrCqB;8MASCqrCmC;y1BAgMQ3pD+G;AAApBlBAhD7pD8Bh/B2F,A;mCgD6pD9BlwD8B;00DAsDSg2FoE;szFAkNSzyBiI;6sBAsCPrTgK;uZAeIA2C;8TASX+uCAzC18CJg7CyC,A;sGyC88CaCoH;qBAAAA4F;wHAGIhqF+C;2rBAiBFA6C;2cAaRo8BkB;+nBA8BQp8B2C;icAWX+uCAzCxhDJg7CyC,A;iHyC4hDaEoH;qBAAAA4F;wHAGIjqF+C;uRAQJkqF0H;uBAAAAkG;+hBAWElqF+C;ymBAeRo8BkB;ggBAiBA+tDsH;mBAAAA0F;w6CAyCInwBA9B/6DAh6DwE,O;iC8B+6DAg6DA9B/6DAh6D4C,A;wC8Bm7DAw+CyB;gkDA0FP4rC4I;iBAAAAiF;uBAIYv4EqG;q+FAmGoBq4EgI;yBAAAAyH;w0BAiBrBlqF2C;8FAEX+uCgD;0VAWG3SkB;qbAoEKg1BA7B5iEU5SsB,A;4O6BkjEP4SA9Bt5DO5SmB,A;mI8Bw5DLA6B;osBAgCL4SA7BplEU5SsB,A;oO6B0lENA4E;obAYLAe;knEAiMX4YiH;s7CAwKuC6MA7BvgFVjkEwB,A;yoB6B6hFtBg2CoC;OAAAAAC31FAh2CyB,gB;2SDoyGL+uCAzCpyFFg7CoD,A;+KyC0yFEh7C6B;uHAEAAAzC5yFFg7C+B,A;AyC6yFEh7CwB;49EAgXa5xBuC;gpBAkBXw6DAzC1qGJoSoB,A;kByC0qGIpSAzC1qGa9lEM,AAAjBk4EkF,A;AyC4qGIpSAzC5qGa9lE+D,AAAjBk4E2B,A;AyC6qGIpSAzC7qGa9lEsC,A;wGyC6qGb8lEAzC7qGJoS2B,A;AyC8qGIpSAzC9qGa9lEM,AAAjBk4EkD,A;gxX2C3hB8B/pFgE;0EA6GdAA1BooBSAAFjvBvBAAAtB0B05BAAAA15BwBA4MLlwDgB,+C,A,A,kF,A;uoD8B0plCzBkwDAAAAAyB,A;0EA44GSlwDsB;wwECvssCsBu6IiBCEPpmBAnC6TOjkEoC,A,AmC7TpBs8BAA7BcguDyD,A,gDA6BdhuDAAaeiuDoB,0B,AAF1BjuD6C,A;urBCnBgBt8B2B;AAAwBw2DsB;yCAIG1mHsB;gTAUzCk+FsC;mHAAAA8D;AAAAhuC0BGpDkDwqFuE,AAISCgF,AAGtCCwE,A;iBH0HHn6BS;6VAcV6uBgBC/DgC7uBS,AAAQ6uBgB,A;wMDqExCAgBCrEgC7uBS,AAAQ6uBgB,A;qGDyEtBtvI+BKtInBAyB,wB;m8HEXmB66I+F;AAMACyC;AAOCCmC;AA4NVCAAAA9qFAC/NA+qFAAAA/qFAvCsvBQAAFjvBvBAAAtB0B05BAAAA15BAA4MLlwDsB,A,A,A,A,A,A,A,A;AwC5IzBkwDAAAAAwK,A;sDAgLmB8qFAAAA9qFoBC/NA+qFAAAA/qFAvCsvBQAsBFjvBvBAAAtB0B05BAAAA15BuG,A,A,A,A,A,A,A;yqC0CuBjBAqC;AAAiBg6DA9CiOjBh6DoD,O;6D8CjOiBg6DA9CiOjBh6DyD,A;+M8CjNUg6DA9CiNVh6DsD,A;O8CjNFAqC;AAAYg6DA9CiNVh6DoD,O;0E8CjNiBm8BkE;gDAAnBn8BAEmLUA8B,A;6IF9Hd8lCwD;0GAIFqnB+C;AAFArnByC;mDAEAqnBU;wFAEArnBoD;+CAMAAoD;uDAEAAoD;2EAKAqnB0C;AAHArnByC;2CAGAqnBU;m4IK8CiBH8E;giBA+BoBhtD2H;cACCA6F;8EAH9BAuF;AAjBbmdAAAAA4G,A;ibA6BAnbAAAAAuH,A;gxDAuD0CipFoB;6CACjCjrFc;89DGnKMkrFAAAAlrFACnDCmrF0D,AAvBGJAAAA/qFAjDsvBQAAFjvBvBAAAtB0B05BAAAA15BAA4MLlwD2H,A,A,A,A,A,A,A,A;AkDpGAu7I2E;AAwDCCAAAAttDmBEzIKutD4B,AAURCAAAArCAzCEXnpFoI,A,A,AyCiCZg+BAAAAAiCACcAA9C2DFh+BqC,A,mI,A,A,A;A4CoCS0rF4C;AAICC4C;AAIDC4C;AAILC8B;2DArFDXAAAAlrFkBC1EI+qFAAAA/qFAjDsvBQAsBFjvBvBAAAtB0B05BAAAA15BoH,A,A,A,A,A,A,A;AkD8FawrF4E;AAiBTM0C;AAUJCAAAA/tDA5CQlBh+BwG,A,A;A4CGmBisFuD;AAQCCAAAAluDA5CXpBh+B2H,A,A;A4CqDiBosF0C;AAMMCiD;AAgBnCrsFuE;6xIM/LcssF2E;yEAOdtsFAAAAAkCACSA4D,A,A;wbxBqMTmdAAAAAyIAG2B++D+B,+J,A;qGA0F3Bl8EAAAAAoJAGyBk8E+B,iR,A;qbYnPZl8E+G;4aAsBAAgB;gLAUqBA8B;8EAAAAgBAmHbA8B,A;gyBArGNsVAAOetV8B,+C;OAPfsVgBAOetVAA8FTA+B,A,A;ucAzFD8lCmE;0CACLmCuC;qDACR+xBAlE8BmCh6D2E,O;iCkE9BnCg6DAlE8BmCh6DwD,A;8PkEd3BkgC4C;6FACApDkF;qGAHT98ByB;AAOSg6D2E;iCAAAAoC;AAPTh6DAAyEeA+B,A;2EA5DfAyB;AAGSg6DAlE6P2B78CqB,A;AkE9P3BgfAhDuDFn8BoB,A;+DgDvDEm8BkC;iEACA69BmC;uFAHTh6DAA4DeA+B,A;4EA7CfAyB;AAISg6DAlE6O2B78CqB,A;AkE9O3BgfAhDuCFn8BoB,A;0FgDvCEm8BkC;kEACA69BmC;wFAJTh6DAA6CeA+B,A;wIAPFg6DAlE2MuB78CqB,A;AkE7MvBgfAhDMNn8BoB,A;0FgDNMm8BkC;mEAEA69BmC;oGAPbh6D2CAceA+B,A;2hFe9LbAqD;s/BCARAAAAAAqX,A;2cC6C4BusFiG;AAyBV5vDAAAA38BA3DqqBSAAFjvBvBAAAtB0B05BAAAA15BAA4MLlwD6B,A,A,A,A,A,A;0H6DhINy7IsC;AAMYkBAAAAzuDAvD8CnBh+BgG,A,A;AuDvCa2sFAAAA3uDAvDuCbh+BqG,A,A;AuDjCe6sFAAAA7uDAvDiCfh+BkG,A,A;AuD9BM28BAAAA38BA3DqqBSAsBFjvBvBAAAtB0B05BAAAA15B2E,A,A,A,A,A;A6D0H9BAAAAAAAAOcAE,wC,A;gsBCjIEAA5DuwBWAAFjvBvBAAAtB0B05BAAAA15BUA4MLlwDyG,A,A,A,A,A;A8D1MjBAmC;kCACAAQC0HMA0B,A;AD3HNAc;qEAFQkwDA5DuwBWA2D,A;8+DgE7vB3BAAAAAAuB,A;oCAAAAAAAAAkH,A;isBCoCmCoxDAtEoXX5SuB,A;AsEnXQx+C6D;yHAEAA2C;yJAAAAoD;OALvBAqC;iqFEWFunC4B;AACYz3FkD;8KAAAAiE;qBAAAA+B;80BE5Dfi9I0D;oIAMJn4CuDEsIoBwqC2B,AACZ3hD6CpC1IkCAA/Bgddz9B4B,oBAAAAiC,A,A,2B;4oEqEvYhBlwDYZqDEA0B,+B;0FYjDFAaZiDEA0B,A;AYrDFA+C;AAIQ64GAZODqkCmBAdQl9I2B,A,A;sBYOP64GkBZO8BhhBO/DhElB0gDuB,A,A;wsB2EsHCroF2B;8EAMX70DAE6JpB60D6CDjTwBitFAAAAjtFwB,A,A,4BCiTJo8BKDrSDAkB,A,A;2EDyICjxFAE4JpB60D6BDjTwBitFAAAAjtFwB,A,A,wBCiTJo8BKDrSDAkB,A,A;4FD0IXg1BA9EiRc5SwE,A;4B8EhRJ9BA1FyalBqtC2B,A;6R6FhkBFmDM;uDAMAAM;u+ER8EkCC8B;AAGEC8B;AAICCwD;AAGrCh2E6E;0GA0EuCi2EgF;AAIvCj2EwD;08BA4JAAuD;olGS1QoB8FgD;qlB8EkBpBnd6C;A5EpEAAAAAAA0Z,A;mmCC2FWmdAA9DyBowE8B,AAGGC8B,AAGAC8B,AAGtBCAAAA1tFc,4B,AAUiB2tF8B,AASLC8B,AAMIC6B,A;05FEqB3B/nD4D;2EACKA8C;gjBAmBuBgoDoM;UAAAA4E;+6CAgCvBtvCe;inEzC9DMx+CA0C7CG+tFAAAA/tFApGyDRguF0G,A,A,oCoGzDQDAAAA/tF6E,A,A;8F1CuDK2+E8T;sLAgCnBsPUA1FiDn+IiG,mD;AA0FpBm+IgBA1FoBn+IuC,A;AA0FpBmoIA0CvDIiWoCAgH/BluFO,uB,A;mB1CzD2Bi4EA0CvDIiWAAgH/BluF4B,A,W;uB1CtDKAgB;oOAoBPiuFAAjHiDn+IsB,wH;OAiHpBm+IWAjHoBn+I8B,A;mFAkHtBkwDqC;uEACpBAgB;2NASmBAS;0CAAAAyB;oIAEjBAqC;AACDg6DA/CwFDh6DyB,A;gE+CxFCg6DmC;kKAE8Bh6DqC;qGAE/BAqC;AACDg6DA/CmFCh6DyB,A;gE+CnFDg6DmC;kmJ4C1IG+NAzCdT/nE8B,A;oFyCcS+nEwB;urFGCSj4H+CRgDYA0B,qB;40C/CtCpCkwDAAAAA0KAI+By9BwD,AAAiC2hDiD,cADvD+OoB,AACsB1wDA7BqaHz9BuF,A,A6BraoCo/EA7B0alCp/E2G,A,gB6BzanBmuFoB,AACoB1wDA7BmaHz9BuF,A,A6BnaoCo/EA7BwalCp/EyH,A,A,A;6uBsFtXXouFwF;uBAIVpuFc;6lCfOIioCuF;mnBAuLI/H2D;kCAAjBlBAnG7QgCh/B2F,A;+CmG6QhClwDoC;0MgBvOyBu+IAAAAruFA1CjBTmrFU,AAvBGJAAAA/qFAjDsvBQAAFjvBvBAAAtB0B05BAAAA15BAA4MLlwD4F,A,A,A,A,A,A,A,A;A6F3ICw+IAAAAtuFA3FssBCAAFjvBvBAAAtB0B05BAAAA15BAA4MLlwDmI,A,A,A,A,A,A;uC6FnJAu+IAAAAruFkB1CxCN+qFAAAA/qFAjDsvBQAsBFjvBvBAAAtB0B05BAAAA15BoH,A,A,A,A,A,A,A;A6FiEJsuFAAAAtuFA3FssBCAsBFjvBvBAAAtB0B05BAAAA15B4B,A,A,A,A,A;A6FoECwuFAAAAxwDAvF4DnBh+BiG,A,A;AuFxDc0uF0C;AAGCC0C;AAGDC0C;AAwEP9DAAAA9qFoBpDrIA+qFAAAA/qFAvCsvBQAsBFjvBvBAAAtB0B05BAAAA15BiE,A,A,A,A,A,A,A;A6FyF9BAwC;21CC1BqBw+CuB;2HACKAwC;4FACWwOAlGkgBtB6hCuD,A;0wBoGlkBoB5qBAnGyWJjkEwC,A;AmGzW/Bg/BAcyC4Bh/B4G,A;gCdzC5BlwD6C;oJAaS0uGuB;g2CEMTx+CAAAAAwI,A;s7CCOS7wDAC0QP6wDmD,A;iEDrQO7wDACqQP6wDiB,A;iHDnQO5wDAE/BL4wDgC,AACAA0B,A;2CFwCGmtDG;kEADDrnBgD;wBACCqnBmC;kKASUgpBAtGuTMn2E+B,A;AsGvTAu0CoP;qaG1BNp3B6B;6kBA4gCDnd0C;AACd+uCkCrH5fAg7CyB,A;AqH6fc9hDkH;AACT+xBA5Hz4BmCh6D4E,O;mC4Hy4BnCg6DA5Hz4BmCh6DyD,A;gC4Hw4BxC+uCArH7fAg7CgC,A;AqHigBAh7CArHjgBAg7C6F,A;ktBoHteEh7CApHseFg7CkB,A;0BoHzeEh7C0BpHyeFg7CyB,A;IoHxeEh7CApHweFg7C6F,A;IoHteEh7CApHseFg7CmE,A;mHoHheEh7CApHgeFg7C4B,A;qBoHheEh7CApHgeFg7CiF,A;oEoH9dEh7CApH8dFg7C6B,A;AoH7dEh7CApH6dFg7CsC,A;usBiD1dsB+E4C;AAI8BCoF;AAIlCCmC;AAIDCmC;uCAwBnBjvFsC;i9FsEIqC8lC2C;yoECmKtB9lCoBCnSK6gCgD,A;k1CCgBbqfA7Eor+B+B0hBAA49G9B5hE8E,A,A;0L6EznlCiCg6BS;0DAAtBm1D8C;AACRn1D+E;wCAEOu2BS;y8CtElBlBvwDiF;ulDjDsSgCqpFgD;8qDQrM9BrX+E;wGAKAAuE;8TASAAqE;kWASAAwE;saAqBAAwE;0NAMAAwD;4YA2DAAwD;wsBAwBWhyEkE;WAAAAkE;srGA8JXiqE0D;09BAwCAA4D;4YASA+H2E;ygCAyH4BoduD;+MAcEpvF+C;+BAAAA4B;8SAO9BgyE8F;suBAoBA/H2F;2kEmH7ZOolBgQ;sBAAAAwD;yBAAAAqH;2gGlHzMACiF;6TASP1NyG;yHAKO5sIAPyBEgrDwD,A;2mBOXEAkC;k2JA0XXijFiF;smCrB5Z8BjjFmB;qBAAAA6B;WAAAA6B;8hCAuPEAyB;mCAAAA6B;mCAAAA4B;i/CEjOFAmD;uBAAAAwC;w/BAiHfw+CyB;6QASXzP0B;2RASAAU;uYAWoC/uC2E;WAAAA+E;q/HA6LVAqB;uDAAAA6B;WAAAA+B;4uCA6DAAgD;sGAAAAqC;iDAGUmdyB;4EAAAA8D;yaA6BVndyB;oFAAAAAASMuvFkB,6B;WATNvvF+B;y+BAmMnBAoD;0GAAAAyC;2nIE/fAAoC;sBAAAAsC;6FA8B+Bg/BAgBibZh/Ba,A;iBhBjbYg/B0B;iCAAAAAgBibZh/BS,yBAAAA4B,A;yVf5jBdwvFiE;6xECitDYhxCwC;wuEAo2BV6qCiD;2hB6B5hFPrpFgD;kPAAAAuC;48BAwBEyvF8E;qhCAiCAAoF;opJA8HgBzvFwB;85FA0JlBAa;sFAAAAwD;EAAAAAA0BbAAAAAA0B,A,A;knDtBzWe0vFsB;yTAU4CAsB;mNA4CrD9N8F;kUAqBO5hF8C;qtCAyDT4Ee;uIAQ6Bh3DwE;+EA0CzBoyDsD;6oBA4BQ4EiD;AAII02CAA5GEq0CkD,A;gUA+GVC0E;4iBCrPiBhiJ2E;WAAAAQ;4FAoCrBoyD4D;0RAKOA4B;wnBA0BEAK;urJPZRmiFiC;yJAMiB0NqB;AA+vBnB3KiC;oMA/E+BthFgI;0hIehf5B5DoC;+6BuDjIiBAerD+DFlwDsC,A;igCqDfnButI4D;sDAESr9EoC9C6gBsClwDwB,mDAArDkwDAAAAA0B,A,A;+B8C3gB2CAAApLrCAA/CizBAAAC/uBkB2oFAAAA74IwD,A,A,A,0HAgBxBkwDsF,A;uB8CkG2CAAAtL3CAAAAAA0G,A,A;AAwLE8vF8d;gZAYiBC+B;kBACfCyE;gDAKKD2B;AAAaEuC;gYAahB5Se;mCACSr9E6D;qDAGFAkE;8YASH1lEAnDiqBuC0lEuC,A;2GmD/pBjBlwDyD;mGAEpBxVAnD6pBqC0lEiE,A;2OmDtpB3Cq9E8B;ihBA8BG6S2C;iGAIPx1CQ;0PAMIq1Ce;4JAIAE2B;yJAaEEsB;meAgBFFqC;oHAMGA8C;AACH5S2B;8+BAe0C0SkB;kDAIjC/vFS;AADT+vF4B;8RAQAEqC;wBACAGmG;sEAKEHuC;2NAWFAqC;qMAOCAqC;m8CAsB0BjwFwB;4JAAAAmC;iOAQAA6C;qFAK1BiwF2B;u/EnD4D0BngJkB;gvBA8CzB8WeA8XsB9W+D,+GAEpBxVAAOuC0lEqE,A,6H;43BF34BvC1lEAE24BuC0lE+C,A;OF14BnCqoFuB;uFACkBv4IyD;mGAEpBxVAEu4BqC0lEiE,A;qWFx3BnCqoFuB;+cAWAAuB;oYA4FPtmC4B;8BACE4mC2B;AAA6B0H4D;0JAI7BrSyB;kBAAgB7csCAbhBmvB6C,A;wLAkBE3HqB;wkBAyHe74I2C;wNAUAkwDwBAhEDlwDgB,qE;oBAiENuwHsH;6PAYOrgEwBA7EDlwDgB,iC;oBA8ENygJkJ;uKAKOvwFAAnFDlwDsB,kD;gGAwFN60F6E;gBAAAAyC;qKAKO3kCAA7FDlwDsB,kD;yGAiGN+9F4E;gBAAAAyC;sFA+CTs6CoB;qBACMAyB;8OAOVGe;sNAQiBCqF;0KAOZJuB;0UAULGe;oaAeiBCqF;gLAOZJuB;yQAWDAoB;2mBA2EAAgD;4QASNDoBAzKMC2B,+D;yOA+KAAoB;yGAIRDoBAnLQCyB,2D;sNAwLAAoB;8CAGRqIAA/KA1HoBANQXyB,mB,AAMYnoFK,AAApB8oFiE,A;kTAoLQXgD;iFAgBRCoBArOOC2B,mB;2QA6OKI2B;AAERLoBA/OGC+B,uB;8XA6PCFoB;AAERCoBA/POC2B,mB;umBAwIWoIsB;AAIdCiBAvIGDwB,mB;8PA+IWAsB;0iCA+KK1Vc;sCACAiD2B;qEAGEvE4BAxeRkXyC,mBAAVhIsB,AAAUgIgG,A;8JA0ewBjIiBA/TlCD0B,mD;iOAgUiCCiBAhUjCD0B,E;kDAgUiCC+C;AAEH1oFE;mOAMmBmoF4C;AAC3BM6B;iCACqBCiBA1U3CD2D,E;kDA0U2CCoC;iyBAiBnBh4BoB;wBAAAAAA9hBOkgCkBAxB/B7V4B,A,Y;0BAsjBwBrqBAA9hBxBi4B2B,AAA+BiIwG,A;qHAgiBH5wFE;8UAOI0oFiBApWhCDwB,+E;6FAsWctnBkBA9iBd6cqC,AACAsSiD,A;+VAkjBsB5HiBA3WtBDuD,qC;0IA4WiCCiBA5WjCD0B,E;oCA4WiCC+C;AAEH1oFE;ohBK+RXA6CL/vBHlwD4C,A;iPKogCCkwD6CLpgCDlwDgB,A;sBKogCCkwDmE;kPA6BAA6CLjiCDlwDgB,A;sBKiiCCkwD+D;4aA+FAAwBLhoCDlwDgB,sE;u1BKuBTkwDa;qDAAAAAEsR4Cg/BAXqF5Bh/B2B,yBAAAA8B,A,I;yxHUxFvB6wF2B;UACFX4B;8WASEWqC;AACFXwC;6CACclwFU;2DAAAA0C;oQAI4BAU;mCAAAA2C;+JAQxC8tDqC;AACHoiC8B;qVAaA7Se;mCACSr9EkD;qDAGFA0D;qNAKN8wFe;0GACuBl1DoBNxVuB9rFgD,AAArD8rFAAAAAmC,A,A;oDM0VU57BmCAyXJAAArDsBAoBNhqBHlwD8C,A,2M,AMmtBzBkwDAAAAAAAGiBu9EAA3bbzvBe,mG,oB,A,K;8DAiEM9tDkF;oJAiBQ+wFmD;AAAuC/wFeN7WhClwD8C,A;mJMqXlBghJsB;iNAQAAsB;iFACGx2JAJsUuC0lEuC,A;eIrUjBlwDyD;mGAEpBxVAJmUqC0lEiE,A;uOI9S3Cq9Ee;slBAqBAvvBe;qIAG6B9tD+D;iIAK7B8tDe;gJAG6B9tD6C;2FAM1BkwF2B;yLAIPx1CqD;uRAOKm2C4B;0FAGyC7wFAAwK1CAAC/uBkB2oFAAAA74IwD,A,A,6GAgBxBkwDsF,A;0QD+jBI04D+D;6bAsBEw3B4B;wdAkBelwFyBN1fIlwDoD,A;wgBMkhBnBogJ4B;wFAEF9hCiB;gOAME8hC4B;wFAEFx3BkB;wgBAzBuC2vBuB;qpBAoDXroF8D;uGAIAA6C;6gBAyCAg1CgC;unHC7pB1B+7Ce;oNAMgC9wB2B;2OAKhC8wBe;86BA2DDCsC;mKAGgBAc;0NAKjB/wB2B;ySAqBMgxBqC;AACJFe;+HAIc/wF2F;4EAKd+wFe;2IAIc/wF6C;qFAKVixFqC;AACJFe;gQAcGGyB;2DAICAyB;2DAIDH2B;sQAeoB/wF+C;qFAGtBmxFe;gWAWGJ2B;oBACACsB;qBACAIsC;AACcFoB;2VAQdH2B;oBACACsB;qBACAIsC;AACcFe;qhBAmCdH2B;oBACACsB;qBACAI4B;4bA6BAAsC;AACcFoB;kRAkBdEsC;AACJDyC;8WASEJiB;8FAIiBGwC;sRAWnBCe;mtBAzGEJe;2sBAqCCMe;q0HA6QHpgCuB;yEAEAqgCe;mhCA2CIrgCoC;qXAsCJsgC4B;6iBAiBAhUe;6+BAiTOv9EoCA3UwClwDwB,iDAArDkwDAAAAAwB,A,A;mgHNgIuBAyB;8rYA4PPAoB;kIAEdwxF0F;mhDA6K2BxxFyB;qdAqBzBoqC2F;2cAYAA2F;giBAYAA2F;m3EAgFF8+CyB;6iDSvyCWlpFyC;6OAAAAkC;iNAU0ByxFa;gJAGHAa;wiKAuL7BAiE;kiBAuGqBCyD;+nBAiEf1xFa;uEAAAA2C;+1BAg1BWA8C;qEAAAA6B;+CASXAwE;oDAAAA+CA2XbAAAAAAqD,A,A;u5BAjWeyvF8C;2jDAiEXvmF4E;y1DA4F4BlJqG;w9EwGj8CJk3DI;wiBJkCAl3D4C;+DAAAA2B;yBAAAAqC;6rBA2IUA4E;WAAAA4E;0kE9F9JhC+uCqC;AACAAA/BohBJg7C8B,A;A+BnhBIh7C4B;+lFAiVF/uCkD;4FAAAAmE;8GCyMwBA+H;k2BA+Bf2xFkN;m8CA0KSC0gB;qXAmGpBCoG;yrBkGjvBE7xFyE;WAAAA6E;gsCAmOgBk8E0B;wpBA2D2BA6B;AAE7Cl9CuG;gGAAAlvFsC;4MAKEkwDyE;WAAAA6E;iMAYoCAgD;WAAAA+B;oNAuBtCg/BoH;0DAAAlvF8B;sIAKAkvF8F;gEAAAlvFmC;6JAyBAkvF8F;kEAAAlvFmC;2EAuBiBkvFsH;wGAIPlvFqB;2CAIOkvFsI;qHAMHlvFoC;wXjG5XVgiJmB;gUAWYA+B;gRAMZA6B;wDACO9xF+B;0DAwCP8xF6B;yOAaCAyD;qNAoBDA6B;0jBA+BGA4B;4HAQCA4B;sSASJA6B;+XAiBFn8BkD;yiBAyCam8B6B;qTASAA+B;wHAEc9yDAtBiQCh/BwC,yBAAAA4C,A;0LwHpjBGimEmC;4+CjGyEpB8rB6Q;+sBAqBmB7V6F;0TAQfl8E6C;4FAEX23EAlC+aW9lEM,AAAjBk4EkG,A;kQkCja6B7NiB;uWASvBntC6BlCmZNg7C6B,A;sDkC/YyC3tDoB;w5BkGrBb+Z0B;kBAAAAkB;6kB1FlED67CwC;0pBA0DdlvJgF;0mHAiLFk9DgD;0BAKGAiD;6GADHAuC;AACGA0D;+IAIPo8BkB;2LAkFH25B+B;4jEAsEE4hBA1C+FW9lE2E,A;wiEAnNCmiDe;mPoC2MKssB0C;sBACDx/B2C;sBACAkCyC;sBACAyT6C;sBACE3f+C;sBACA9F8C;wBACC4vBmI;6NtBrWiB5RU;oQAyCtCAkB;iCACSijCAAiCmBCoC,A;oCA/BG1tCuD;4BACA4KsD;yFAG1BgXoD;0qPdxJP+rByR;qCAGKC4I;uTAQLC0FAYaryFmC,4H;ycM2E0BAyD;cAAAAwC;oZAwJnBA8B;gpCA8IfA6D;cAAAA4C;qvDN9buBqpF4C;wiBAkVlBv0BsCwIjTKw9B2E,yE;QxIiTLx9B6B;0LwCqPe90DwC;62HC4sCXwiEc;0PAQYsnB+E;+DAIYtrCsC;4HAkB5BqrCoD;wfAaIz4BA7Bx8CM5SkF,A;0I6B88CFwbA9BxnDTh6DyB,A;oE8BwnDSg6DqC;4jGAiuBHgE2BA+CWxf+B,A;mEA7CN8SgD;yTAcHA+B;AAAuC1M6F;2UAiB9CilC0F;suBAsCRjiDe;uKAIAykBkB;gKAIQkmC4F;4DACgCCSAIxChwB0D,yPAUJpL8B,AADIxS6I,A;wJA2Da6tCyEAObjwByC,0EAIFkwBsLA1BA3jD8E,A,8L;0UAsCEyzByD;SACAockD;oNAIAjEkE;2LAEA5pB6E;yiFAqsBQ/wD4C;y4FA8xBD2yFkF;kzEA4FN5hCgD;AACE/wDY;AADF+wDiB;k5BA2CeKA7B/8HE5S4D,A;mJ6Bq9HWsrCmE;gJAIOtrCsC;iaAmB5BqrC+D;0vBAoBJv4BmB;8CACAkRmB;+BACIlRqB;2FAGQ0M8C;uNAUTh+DiB;sVAcHg+D+C;uCACE2cyB;4FAIC36EiB;2OAUD+wD+C;AAIC/wDS;gVAYH4kDwF;2DAIC5kDiB;kPAUAg+DsF;AAAqBwEkC;yIAUrBxiEiB;k6BA4D4C4kDkC;AAAnB0MyF;8DAmB3BtxDmC;s4BAuBUuyF4F;qEACgCCsKAUrCte6E,A;siBAmBH1RkB;mHAEA0RgI;AACAyGuB;uDANGkP0C;AAOH94BU;y5EI89eO6hCA6F3koBX9pHADgBDk3BsC,AAAAl3BwB,A,A;kgD5F80lCA+pHgC;6LA4BAAgC;uMAYAA+B;AAActV2B;4LAMMA2B;qQAOtBljBsG;89B6Ft1lCOxwFADjDuBmqFQ,A;yNCqE5B6lBuG;8GAIS7iB0E;6BAAAAgB;4FAGXOqD;6LAckDP0E;uNAQvCA0E;6BAAAAgB;4FAGXOqD;+WAeFA4D;+oCAsESptFwCD9LA2oHArG2VXp3DApC/IAAuF,A,mBoC+IAAApC/IAAuH,A,A,A;O0IdWvxDAD9LA2oHsC,A;wPC0MLCoG;8CAIS/7B0E;iCAAAAgB;sKAIXOqD;8NAQwDP0E;sNAOxDOqD;qjHlFhOG3C0CANuBjtBqBzCDE0gDuB,A,A;2qDmDyDf1gDOnDzDe0gDuB,A;wRmDmCb1gDOnDnCa0gDuB,A;wgBmD+Cb1gDOnD/Ca0gDuB,A;0hB6HiCsBpoFA3H6LzC27BwBFnCwC9rFgD,AAArD8rFAAAAA6C,A,A,A;glEgIlJco3DgC;yEAGZCwK;kuBAqDmBx1DA1H2VOz9BE,A;oD0H3VPy9BoB1H2VOz9BiC,A;i5F8CtQM6pDS;sRAKbAK;4qDAjB8BuVa;uBAAAA4G;0DAAAA0I;0S6EhC7Bp/DAAugBH+qFAAAA/qFA/HmGQAAFjvBvBAAAtB0B05BAAAA15BoBA4MLlwDgB,mC,A,A,A,A,A,A;oBiI/CHkwDmBAugBH+qFAAAA/qFA/HmGQA6D,A,A,yC;uN+H/WJoxDuC;AACD0oB2L;gBAAAAuB;kHAQlBqZiD;wIAaAnzFS;4CAAAAqC;6OAYWAAC3afAAAAAAsG,A,A;mDD2aeAwE;wpBAsDbs6CkE;+EAmBOt6CqC;qLAQWw+C+B;4HAIlBlEiE;iVA5DsBt6CkB;+BAAAAoC;2NAEAuiBAyCtZpBviByB,A;yOzCyZEozFmD;yMAmNOhiCAnB7mBW5S+C,A;6ImBknBKx+CiC;qTAyLhBw+CyD;yFAEPs2B2BDpyBQkekC,8FAGZKyNAoF4B51DA1HiTFz9B4B,oBAAAA6C,A,sE,A;mK2HoaxBg/BAnBz0BwBh/BkH,A;8BmBy0BxBlwDkD;gLAMsC2tFA3H1adz9BoC,4BAAAAiD,A;+c6HxXGgcAjIouBChcAF1xB5BAAAjC0B05BAAAA15BoBA4MLlwDgD,A,A,A,I,A;60CmIvDM2tFA7H0THz9B4B,oBAAAAkC,A;gxC4H7apBAuJ;irOIlBqCA0N;+BAAAAoB;8PAMjBmd0B;AAAEndkB;gCACtBAuC;6EAYWAgB;mtBC5BfAuC;qyDG4BKA2C;oLAUAAmB;yLAUAAoB;oRAcIAc;oZAWAAwB;2/BCtBE81EACtBIhoCkC,A;ADuBR9tCa;AADI81EwB;kDACkDrPA5GnDnCzmEiC,A;0b4GkEjBszFAAsBU7sBA5GxF+B34BsC,A,6B;O4GkEzCwlDAAwBJtzFa,6BAFcymEA5GxFOzmEiC,A,A;oC4GoEjBuzFAA6BU9sBA5GjG+B34BsC,A,6B;O4GoEzCylDAA+BJvzFa,8BAFcymEA5GjGOzmEiC,A,A;6B4GsEjBwzF2HAmC4CvpD4C,AAAhDjqCE,AAAgDiqC6B,A;+BAnC5CupDAAmC4CvpDe,A;oGA1BlCw8BA5G/E+B34B2C,A;A4GgFpDoFAClCI4iC6C,AAAQzjEoE,4D;ODmCLrSkB;cAFcymEA5G/EOzmEiC,A;4H4G+GrBqrC0B;oDAAAA+G;kPAYAA0B;yCAAAA+G;+8CIlIuCrMgB;miJ7C6L1B4yDwkB;sjEzCxJNjgD+G;sDAAAAA0D4XZ3xC2F,A;gI1DhWFg/Bc;6CAAAAiE;+CAAAlvF8B;oqFuFsO4B2jJsB;wDAEKAsC;OAAjBzzFoB;AAAiByzFwC;YAAjBzzF+B;yO5CtP+Bs6CiC;qPAgQ7CAuB;2JxBjTmB4hCiB;+DAIF9/CkB;sLAyBjBkeuD;gjByBPSt6CyC;AACX+uCApHkhBAg7CoC,A;+doHpgBIh7CApHogBJg7CoB,A;4CoHpgBIh7CApHogBJg7C+H,A;qGoHhgBIh7CApHggBJg7CiI,A;klBoHnfIh7CyBpHmfJg7C6G,A;AoH9e+B3tDqC;AAAxBke0D;67FAwFat6CsCzB3JIitFAAAAjtFiC,A,A;6wEyB6MNAAzB7MMitFAAAAjtFmC,A,A;2ByBkNtBs6CAzBjMFvLA3FgiBAg7C6B,A,A;AoHpWkB/pFiC;sCAOXs6C2C;gDAGGleAzB3MSAoB,A;2eyBsNTg1BAxGqMY5S0C,A;oDwGpMV4SAxGoMU5SsC,A;qOwG3LtBm1C8L;6fAoBWn1CoC;AAA+B09BKzBxPrBAqD,A;AyByPnB5hCoBzBhPFvLA3FgiBAg7CkB,A,A;oBoHhTEzvCAzBhPFvLA3FgiBAg7CiC,A,A;qEoH9SEzvCAzBlPFvLA3FgiBAg7CgC,A,A;s0BgKjiBsBzvCoC;urBzCNFt6CsC5BVIitFAAAAjtFiC,A,A;ygC4ByClBg6DA5GoNKh6D0D,O;iD4GpNLg6DA5GoNKh6D4C,A;0B4GhNL4zFuE;8qBAwBA55BA5GwLKh6D0D,O;kD4GxLLg6DA5GwLKh6D4C,A;0B4GpLL4zFuE;0GAMA55BA5G8KKh6DyB,A;gE4G9KLg6DoC;uGAAuC45BkF;iEAGIA2F;qBAA5B9tD6D;i1BAxCN8tDgD;wcA4BAAgD;yJ2CMKp7GAAiBpB4jDuC,A;mEAjBoB5jDAAiBpB4jD2B,qDAAK0JkE,A;AAhBEwU0D;k5C7CFczIkD;AAAsB2qBkC;6CAI/B1sH0B;wCAAAA6D;gaA6IGqsFA1GAJn8B2B,kC;2b0GsBMm8BO;uCAAjB6CgC5H8K8Bh/B+E,A;2G4H9K9BlwD+B;AACM0sHyE;AAGWrrD4G;+RASJ0gCyC;AACuB2qBmE;AAGhCztBgD;2PAKeotCgE;8IAiCNhrEiF;4DAESgrBA1G/EXn8BsC,A;iB0G+EiBgtDiB;AAAN7wBA1G/EXn8B8C,O;2C0G+EiBgtD6C;oPAqCf77CgE;gYAwBHy9CoE;mIAhBWqVAzGuBQjkE+B,A;AyGFKk8E8D;yEACjBttB2D;w8BA2EGtMAAzQWzQuD,A;kEA2QT/hGuF;kDAGlBwyGAA9Q2BzQgD,A;AA8QFAmC;sCAMzByQAApR2BzQkC,A;AAoRF2qBmC;wCAMzBlaAA1R2BzQkC,A;AA0RFAmC;kGAIZ1gC4D;gCACAA4D;oEAEIigDA1GkHC5Se,A;ue0GnGE4SA1GmGF5SiB,A;kE0GlGD4SA1GkGC5SmB,A;8nB0GvFD4SA1GuFC5Se,A;onB0G9EDAe;slBA4CE3M+N;AACDA0D;2qCA8BjByQAAhZ0BzQoB,+C;qmMAgzB3ByQAAhzB2BzQsD,A;mEAmzBO/hG4B;+DAAAAmB;8aAuCjBu1CyD;k3C8C19BNqXuC;2erE8BP00DAnFqfc5SuB,A;gTmFlfT4SAnFkfS5SwB,A;wNmF9eP4SAnF8eO5Se,A;0kBmFleL4SAnFkeK5SqB,A;uQmFtdjB3MuB;sHAKQ2MsB;AAAY3MuB;oLAUrBAa;mEAAuBufAnFucL5SiB,A;wQmF7bb1YK;yXASPiJgB;qGACAAgB;oBAEFAU;umDsEpHalYyD;0QAOI2nBuB;u4IEyCU1YyD;OAAhBjPyD;oNAUmBsFA3JoInBn8BgC,A;4D2JpImBm8BkC;qYAkBXqiB8D;6HAOK1YuD;kCAAKAoD;6vC/G1BzBu3CiBAjC0BzoB2BC7BFjtBOzCDE0gDuB,A,A,A;gOwCqEdpoFAtCyJL27BoBFnCwC9rFqD,AAArD8rFAAAAAoB,A,A,A;AwCtHqCzeoC;0EACJi0CmC;2EAGbpxDAtC2qBOAAFjvBvBAAAtB0B05BAAAA15BoBA4MLlwDiE,A,A,A,A,A;gCwC/GrBwqGkD;AADgBt6CAtC2qBOA2E,A;+vFsCngBDoxDiC;2HAGbisBiBAtNmBzoB2BC7BFjtBOzCDE0gD2B,A,A,A;+LwCyPZv4IoC;gCAEhBwqGkD;oYAgBYt+BAtC6hBgBhcAF1xB5BAAAjC0B05BAAAA15BoBA4MLlwD4D,A,A,A,A,A;6BwCmFvBwqGkD;AADct+BAtC6hBgBhcqE,A;iLsCphBNw+C6B;AACtBnc8D;AAEAwxD0J;8LAzE8Cn6DgC;kCAI9B15BE;iCAAAAAWpND+qFAAAA/qFAjDsvBQAsBFjvBvBAAAtB0B05BAAAA15BeA4MLlwDkF,A,A,A,A,A,A,AmDpKTq7ImF,A;AX8LVnsDY;2DAAAAqC;yCAAAlvF+B;oSAQmB4pFO;6WA2CoCvc6B;ihBAwD3D22E6DA3FwB1iCiC,8BAEQj0C2F,AAG1BkgEiBA1MwBzoB2BC7BFjtBOzCDE0gDqC,A,A,A,uC;mhC0CsCL5+CyB;yBAAAA+B;iQAIjBAoB;qEAJiBAmC;0RASgC6zCiB;sKAClB1uB8B;iCAC1BnlBuD;AAXYAuC;mhBAoBdzpCmC;wxH4BqEmBmgEmH;2RAE5BpxBY;uCASFAiB;2RAYE6rBY;yGAAAA+C;2nCA8DS56DiEuF5JbAqD,A;gnCvFuQmBqqFAtCrSKpmBAnC6TOjkEwC,A,AmC7TpBs8BAA7BcguD8C,A,sBA6BdhuD6EAaeiuDoB,8B,AAF1BjuD+C,A;kJsCmSsBt8BwG;sEAGHu1CgD;uKAAAA8D;iEAEAiJ+B;4BACGx+CqD;sSAqBR+zF4C;kDACc7hD0D;iCACNlyCqF;AAEJ+zFkE;+MAKY7hD4D;mEACb6hD+C;oDACa7hD4D;mEACX6hDiD;oDACW7hD4D;iCACNlyCkG;AAEH+zFsE;2LAML/zFyG;6GAKDw+CuB;4BACGx+C6C;+HA4EVAgH;2zDAmDSi/B2KuFtcjBj/B4C,A;kCvFwciBA2DuFxcjBA+C,A;oTvF8c6BmgE4E;AAAfngEmB;AAAA+uCuC;iCAAAAS;4BAAAAS;uBAAAAS;wBAAAAS;imBAoDSoxBgD;oRAiBAAqD;y7CA4CrBpxBwB;AACAAc;wxDtCtjBoBmtC+B;siEAiEAA+B;otBA8BD94B8C;2NAQN84BiC;kiCAwFIz7BuE;KAAAAoB;iTAYXy7BmD;AAGqB94B2E;4HAEjB3C8F;kHAKiB2C+C;AAGR84B4C;wIAOZz7BqF;uYA2CoBkvBW;uIAKvBAgB;AAAmBAU;4MAWnBAa;cAAAAW;KAAmBAe;6iBoDlME/uFCsEzDDozGyC,A;0mBtE4EACqB;8sBAWTz1CuC;yQAQWteiD;+OAGNAyE;0BAEKr/CCsE1GHmzGoC,A;AtE4Gf53DkB;ytEA+DP4CA1GtQ8Bh/B2H,A;0D0GsQ9BlwD8B;snDAmEAkvFA1GzU8Bh/B2H,A;iC0G2URi0Fa;mCAFtBnkJ8B;iSAYsBm0HAvFEOjkEkC,A;AuFF7Bg/BA0B9T0Bh/BqH,A;uE1B8T1BlwD8B;gGAII6nIAnGqMa9lEiE,A;khBmG9KKoyDAvFzBOjkEsC,A;AuFyB7Bg/BA0BzV0Bh/B4G,A;gC1ByV1BlwDsC;sGAQsBm0HAvFjCOjkEsC,A;AuFiC7Bg/BA0BjW0Bh/BiG,A;mC1BiW1BlwD8B;6QAWoBi/F6C;kVA3KFntDa;4EAAAAAuEvNlBoyGgD,A;AvEwNIjlDAnGgUJg7C6B,A;iXmGrSwBloGiBsE/MMmyGoC,A;6CtEgNNlyGCsE5NOkyG0C,A;2BtE6N3BjlDAnGmSJg7C2B,A;iZmG9QwB/nGa;4EAAAAAsE5OKgyGqC,A;AtE6OzBjlDAnG6QJg7C6B,A;8ImGvPkBnoGa;4EAAAAAuEjSlBoyGiD,A;AvEkSIjlDAnGsPJg7C6B,A;+ImG5OsB/nGa;4EAAAAAsE9QOgyGqC,A;AtE+Q3BjlDAnG2OFg7C6B,A;iNmG3NsB7nGiBsE7QW8xGuC,A;6CtE8QXlyGCsEtSSkyG0C,A;qBtEuS7BjlDAnGyNFg7C2B,A;0bmGhL6B/nG8BsE1UAgyGsC,A;6tB9FwBP7zByF;qCAAsBhhBkB;aAAAA0G;6WgGpExCwwBW;gYAmBFAW;2IAGgBAiB;oDAEIxPa;qGAAsBhhBAA7B/BwwB6C,oEACKp1CwB,oD;4CA4B0B4kBAA5BdtgB8B,A;qqClFY1B5C8B;mCAAqBNyB;uDACSAiC;m3BoFkBSwImE;gGAI5BqayD;qXAUJx+CA1EHGk0FglB,kI;O0EGHl0FA1EEAmd0JA3BOg3EAAAAn0FwB,A,A,A;gf0EiCImgEoD;sZnHgJlBnGA/CiDOh6DsH,O;kH+ChDUm8B+E;+CAcFqiBkE;AAAwB4SgD;OAC9BpxDqC;8GAGFAkE;qHAOUAqC;AAAM2xCA/CNhB3xC0D,O;gC+CMgB2xCA/CNhB3xCsD,A;A+CMUAACPFA8B,A;+IDmBZg6DA/CWIh6DqD,O;6B+CnBGg6DA/CmBHh6DkD,O;kC+CnBGg6DA/CmBHh6DyC,A;iE+CXJg6DA/CWIh6D4C,A;+d+CjKFlwDiE;oSA2CgBowFgC;kBAAAA+C;mGADPlgCuDCyFCA0B,A;ADvFgBo8B6C;2DACM8DgF;OAA5BlgCsD;iUA4BoCsVYCpCrBtVyB,uCAAAAAA8FTA+B,A,A;klBDfAw+CuB;ihBA2BJwbA/CkBJh6DkD,O;mC+ClBIg6DA/CkBJh6DyC,A;wc+CVIg6DA/CUJh6DqD,O;8C+CVIg6DA/CUJh6D4C,A;ghB6GtKJmkCgC;+jCAoCUnkCY;yJAIiBAoBChIhB6gCiD,A;kBDoID+tBApH2DchhHgE,A;6EoH3DTk4F2D;AACbA+E;AAEe8oBApHwDOhhHiD,A;wCoHtDPghHApHsDOhhHiD,A;mKoHjDhBoyDgC;8TAMmBAoBCpJhB6gC8C,A;kFD2KV+tBApHoBuBhhH+E,A;eoHpBvBghHApHoBuBhhHW,A;mEoHdhBk4FmE;AACAA0E;qBACAA8D;yBAKY8oBApHOIhhH4C,A;gXoHpCZghHApHoCYhhHoE,A;sIoH/BZoyDY;2JAIoBAoBCpKrB6gCkD,A;4BDsKqB+tBApHyBRhhHgE,A;mDoHzBgCghHApHyBhChhHiD,A;qDoHxBXghHApHwBWhhHiD,A;eoHzBdoyDoB;yUAkCiBAoBCxMhB6gCiD,A;kBD2MY+tBApHZChhHgE,A;0EoHevBghHApHfuBhhH0C,A;eoHevBghHApHfuBhhHW,A;0BoHkBUghHApHlBVhhH4C,A;8WoH4BhBghHApH5BgBhhHiD,A;eoH4BhBghHApH5BgBhhHW,A;gEoH8BvBghHApH9BuBhhHiD,A;QoH+BhBoyDO;AADP4uDApH9BuBhhHW,A;2hBoHsDjBghHApHtDiBhhHgE,A;eoHsDjBghHApHtDiBhhH4C,A;AoHuDjBymJA/EiDShKAAi9FDrqFyC,2KAeHk8E6D,+FASF9/CoB,AAAFjfqE,A,gC;oE+ErhGsB93B+B;AAAzB4/DiB;AAAWqLiB;AAAcjrEAF8JlBAE,qBAAAA6E,A;AE3JJupEApH/DgBhhHiD,A;eoH+DhBghHApH/DgBhhHW,A;iEoHgEdghHApHhEchhHiD,A;eoHgEdghHApHhEchhHW,A;mEoHiESghHApHjEThhHiD,A;eoHiEhBoyDqC;4ZnB7OTAgB;8IACeAgB;inC5BDfAgB;2kC2BuE2BAqC;sEACpBAgB;gFAOAAgC;iCAHGAgB;uPAWCs0FyBA1EQxkJyB,4D;wDA2Edo+IoC;SAAAAqB;0GAAAAAA+ELluFiD,A;gZAvEWs0FyBAnFQxkJyB,4D;iEAoFdo+IoC;SAAAAqB;oHAAAAAAsELluFyD,A;8YA5DWs0FyBA9FQxkJyB,4D;2IAgGdo+IoC;SAAAAqB;sHAAAAAA0DLluFiE,A;icApBFs0FYAtIqBxkJyB,4D;iGA0IVo+IwEAgBTluFqD,A;kHAdmDkuF4E;4BAAAAAAcnDluFkE,A;iGAV0BAgD;stBAuCrBAwB;wzFAKEAqC;AAAYkgC4F;AAAZlgCAzCIMA8B,A;wQyC4BRAW;4CAAAA6C;qVzCgCcihEc;uCAAAAAhDmOKjhEkF,A;AgDnO9Bg/BAlEnQ8Bh/BuF,A;mCkEmQ9BlwD0F;0GAGuB0uGwC;8GAENx+CY;+EAKHg6DAhDxCHh6DgD,kC;wRgDmDAAqC;AAAgBihEAhD8MGjhEsC,gCAAAAmD,A;AgD9MnBAAAjFQA4B,A;SAiFiCo8Bc;+IAU7C49BAhD7DIh6DqD,O;6BgD0DPg6DAhD1DOh6DkD,O;kCgD0DPg6DAhD1DOh6DyC,A;iEgD6DJg6DAhD7DIh6D4C,A;kTgD9KckgCgC;kBAAAA+C;qCAAZlgCuDAgJMA0B,A;AA/IGo8Bc;i+EAwNPp8BE;gDADS8lCsD;yuCPnSgBrIA/Bgddz9BE,A;oD+Bhdcy9BoB/Bgddz9BgC,A;6M+B3blBAuCAgDau0FAAAAv0FAnCmsBIAsBFjvBvBAAAtB0B05BAAAA15BeA4MLlwDyF,A,A,A,A,A,A,yC;opDqCtGnB2kJyC;6JAKJn6CmE;6OAMIm6CyC;+ZAcFl5CK;OAAAAuD;0KAYFRK;OAAAA2B;wYAMI05CyC;yHAG6Bx0FAnC6FtB27BoBFnCwC9rF6C,AAArD8rFAAAAAmC,A,A,A;yBqCxDkC5fAnCqqBFhc0BF1xB5BAAAjC0B05BAAAA15BeA4MLlwDkF,A,A,A,A,A;kXqC3CnB2kJyC;6HAIgB5qCsB;wJAKM9OK;OAAAA2C;YAGnB8OsB;8JASaliBOrCnKU0gDuB,A;iCqCqKzBoM+B;i9BH9DWj+BO;AAAM/4B6CG3HkBAA/Bgddz9B4B,oBAAAAiC,A,A;gK4BjVQy9BiBG/HMAA/Bgddz9BK,A,A;wD4BjVQy9BAG/HMAoB/Bgddz9BiC,A,A;mG4BvTGw2DO;AAAM4oB4B;qdAyBsBp/EA2FrJLCA3HqNzC27BoBFnCwC9rFgD,AAArD8rFAAAAAmC,A,A,A,A;OkC7B0BzegC;AAAwBndmD;AAASA2D;AAAjCmdgC;ohBAgBPsgB6CGlMuBAA/Bgddz9B4B,oBAAAAiC,A,A;6K4B1QKuwDwB;AAAQ9yB0B;AADjBtgBE;AACiBsgBiB;uCAAAAAGtMCAA/Bgddz9B4B,oBAAAAoC,A,A;A4B1QwCo/EQ;AAD5CjiEuC;6RASLiiEO;kGAMVAgB;ykBAaYAO;2/BAlFEAgB;uEAMAAuB;82DH7EgBtxCkC;uTAURA4B;orB6GdjBAkC;gpBAkEIhI8D;AAAWAiF;AAI3BzzBkEA2DmCy7BiC,A;uNA5CQAwC;moDrE1JjCxhDACiCsBx8C6I,2K;ygBD/BhCy8CAC6CkCz8CkJ,8M;uWmC9BFkqFiB;kEAA2BwIA7E4+nBzC91CA6Fp+nBbDADcDuT4C,4D,A,qB;oSfnBwByoD6C;sFAAAA6F;AAIjB+NO;AAAM/4B6CtEvBuBAA/Bgddz9B4B,oBAAAAiC,A,A;mSqG5bbw2DO;AAAM4oBgB;AAAiB58CA7Ew+nBlB91CA6Fp+nBbDADcDuT4C,4D,A,A;m0CxCoGmB20FwB;AAAV30FkF;kGAAAAyC;i3BAoDmB20FwB;AAARx3EgGAzJUowEyC,AAGGCyC,AAGACyC,AAGtBCgC,AAUiBC+E,AASLC2C,AAMIC2C,8EAzBhBHAAAA1tF2E,A,A;AAkJf8wCqB;mDAAAA0G;iFASqB8jDAA/HQxjCAtFqfP5Se,A,A;oVsFvURwbAtFCHh6DyD,O;sCsFDGg6DAtFCHh6DgD,A;qsDsFmD6Bw+Ce;mDAGpCm2CwB;AADG30FiE;OAAAAoB;wnCA3JLg/BAxG/H4Bh/BsI,A;8YwGiIhBlwD2G;AAAA+5FmEnB0BV8eAA3FaqkCkI,A,gLA8FNvuBwB,AAAA3uHyH,mI;gLmB7BG+5FAnB6BH/5FmE,A;uTmBxBSAmD;4CAAAACnB5BRA0B,c;ghDmB2HN8kJqB;SAAAAAA/KuBxjCAtFqfP5S4D,A,A;AsFrUVx+CgB;mnBAuDOlwD2D;4CAAAACnBnLPA0B,c;w9DjBhFC0uGsB;QAAmB4SAlDihBV5SuB,A;uPkD1ffwbAlDoLIh6DoH,O;sFkDnLNm8BkE;4CACA6wBwD;8yBiB7BiB7vCAAkDEmxEAAAAtuFA7D4qBCA2BFjvBvBAAAtB0B05BAAAA15BeA4MLlwDwE,A,A,A,A,A,A,4B;W+DnKDqtEAAmCH43EAAAA/0FoB,A,AAgCmBg1F8C,AAOpBCAAAAj1FgB,A,AAyCWwtF6D,AAGE0HuD,AAEjC/3EAAAAAkJ,A,A;SAvHiBqfAAoBoBAU,A;0MAdlBrfqB;qWAkDErtE6B;sQAgGf64GAA/GaqkCmBAdQl9I6B,wB,kBAcuB63FO/DhElB0gDuB,A,A;+S+D8MhBroFAA2NG+qFAAAA/qFA7D2UQAAFjvBvBAAAtB0B05BAAAA15BoBA4MLlwD2C,A,A,A,A,A,A,8B+DgPNi7IAAAA/qFA7D2UQAwF,A,A,A;yoB6DzgBrBw8B+B;kCAAS6YAmGlNQoxB6B,uC;0GnGsNPjqC+B;kCAAS7uFM;kkBAkEJ6uF8C;kCAASiqC2C;AAAMx/BwFoG3TyBgJiE,2E;gUpGsUtDzT+B;gDAAS7uFM;SAAc0yFsC;yOAMP+wBAnEyOC5SyB,A;uDmEvOpBmXmD;8CASEn5B+B;kCAAStB6B;udAcqBl7BAA8EjB+qFAAAA/qFA7D2UQAAFjvBvBAAAtB0B05BAAAA15BAA4MLlwDyD,A,A,A,A,A,A,A;A+DkNd0sF+B;8FAhDyBx8BoBA8EjB+qFAAAA/qFA7D2UQAsBFjvBvBAAAtB0B05BAAAA15B+E,A,A,A,A,A,A;A+D8ZVryDM;SAAc0yF+C;++GAzJQ9wCAc7EnBi1D8B,A;Qd6EmBj1DAc7EnBi1D2F,qBACA4KqE,iDACK/FwI,2R;4fdoFlB7sB+B;kCAAS6YAmGlOIoxB6B,uC;iCnGmOC32HgB;AAASkwDuB;ueA8DhB06CkCAgIC/SO/D1bc0gDuB,A,uB;mH+D+V5B+Ma;kIAAAAwF;uoEAwBkCvyJgC;0+CAR5B64H6H;0SA0BmD25BI;MAAAAmCAeLxyJyC,A;mMA0BvC8kGO/Dlbe0gDuB,A;8L6DcViN6HA6ITrEmBAtE4B5T4B,A,qJ;SAvEnBiYAAoJb94DU,kCAASuoBAAvJyBAiB,A,A;uIA4GrCksCkCAlCmC5T4B,A;cAoCtBr9EqC;iNAWbixFmBA/CmC5T4B,A;wSAwDdvvBARxCFmiCqC,A;yCQ6ChBptJA5D+sCPqmJqB,A;yO4DtsCW+HmBAtE4B5T4B,A;2KA6EhC7gDU;kCAASuoBAAvJyBAiB,A;oGAiKrCksCkCAvFmC5T4B,A;YAuFjBt4BiB;wMAWfAiB;oTd2DFiVArEyJmC78C8D,A;AqExJnC6vCiB;AADAgNArEyJmC78CiD,O;qDqExJnC6vCiD;AAGWxOe;snGA+FJjeoG;AAAwCnE0C;8qBAmBK4yBkB;k5BAtIO7xCyD;oDACxCnb0BuF5ORhCaINmBA6B,A,A;4B3FkPXgCY;+mEA4HlBmbe;oiCkBvRFojBkF;0CACoBpjBuB;wdA/D2Bnb2D;oDAAAAAqEnBnChCaINmBAiC,A,A;azEyBgBgCU;krCAkD1BwmEsE;8pC3B5BNhhIA6B9BN0rDAGHKqiGuC,A,0GHGLriGO,gCAAAAAGHKqiG0F,A,6F;kjBhCqCNnkCA5BguCU5SoC,A;6YyJrwCGxJgC;eAAuBAgC;6MAKV5YK;qsBxF0CZp8BACtEFitFAAAAjtFuC,A,A;iCDsEEAuD;OAGYo8BAC7DnBAkB,A;wc3B8GgBp8BuB;mGACE4kC0E;iBAAR5kCc;AAAQ4kCAlDErBstDe,2C;0MkDDDjH4B;+MAQIrmDsD;UAAAAAlDPHstDoB,gE;20BkCqDNllCArCsZG6hCsC,A;4IqCjZIzyDqF;2VAGE49BArCmERh6DuD,O;kEqCnEQg6DArCmERh6D8C,A;6cqCzCKo8B2E;0YAYP27CiC4BzM8Bt6CARuFbz9B2B,oBAAAAgC,A,A;4EpB0HjBiiC2B4B3MsDxEARiFrCz9B2B,oBAAAAgC,A,A;sFpBoIjBkgD6B4BlNuDziBAR8EtCz9B2B,oBAAAAgC,A,A;+hBpB7DhBo/EgBCmC8B7uBS,AAAQ6uBgB,A;wSD3B9Cp/EAK3CUw1FgL,A;AL2CVxnDsC;+JAAAA+D;AAAAhuC8BKvCgBy1FsE,A;+jFL+DoBh4DACCQAAG9ENAoB/Bgddz9BkC,A,A,A;A2BnYRAAgGyBiCmdAARZw4EoC,AAKECqF,A,A;0WhGlB7B5e6T;qNAW+C6egC;ifAUjC/lJgF;2cAObghG8J;kHAG6B33BoC;+CAAAA4P;mHADxBnZuE;yCAFL8wCwG;sZA1BQ0lBO;AAAM4oB2B;gGAKCtvIoCG5ErBAyB,8B;sLH4EqBg2HyIGlDLkQsV2HKvB15BS,gBAAAAA5BEIw5CoE,2K,A,kO;iYlGwE6BCEA8CzB3WgBCnFgC7uBS,AAAQ6uBgB,A,mE;ADqCfjiE6B;YAAA44EqH;4vCAoG/Bh7CI;gpBAgB0BjrGoCKtNrBAyB,8C;gPLuNuBnCM;SAAcwyF8D;gjBAc1CwlBI;k3BG3NgB3lDA2H3BKg2FAAAAh2FA/BSTi2FAAAAj2FuE,A,A,A,A+BNOk2FAAAAl2FA5BMIo/EAAAAp/EmE,A,A,A,yC4BTFg2FAAAAh2F0D,A,AAGFk2FAAAAl2FmH,A,AAuBvBAAAAAAiDACaAAtF6BTAuE,A,A,A,A;oFrC3BiBi6BmC;iGiIxBGiiDa;oBAAAA4B;uEAGUl9CAvDiCNh/Ba,A;0DuDjCMg/BAvDiCNh/B+D,A;+ehDrCLlwD4BCwHTA0B,qB;ADxHS4rH4E;sGeuCjBgYuC;ga3B8B+BzzEAhDuKxB27BwBFnCwC9rF8C,AAArD8rFAAAAAiC,A,A,A;qhDkDrDa/uBeO7HF64DmC,A;2BP6HQoTaAUsB5LkC,A;AAVdnsCcAcgBmsCkC,A;AAdP57BaAkBK47B6B,A;AAlBGltEkB;AAAYq3CAAsB3Br3CgC,8J;oHAiCpB05B0C;mZAsCyB+DA5CyNNz9B2C,oBAAAAiC,A;qnD4CtKKq7CyI;ueAMepLmN;iGAKtB+cAtD+QX6hCAAIPsHuC,4tB,A;i9CsDnQMxhDiLa3RUx3BAAmEgB63E+C,AAgDTxH+B,AAGE0H8C,AAEjC/3EAAAAAAAGgBndAF3FYusFwF,AAuD0Bx+EqJ5EmT7Cw7EmH,A,A,yD8E/QOvpFAFxFGurFyY,A,A,A,A,A;q0CXmQMxwCiG;spEAcvBT4E;wOAQwBy9BAWnVet6CoBRuFbz9BgC,A,A;umCHoRUgxE+H;2hFA8GFmCiC;mCAAAAA2CtdK11CAxCoFbz9B2B,oBAAAAkD,A,A;oEHmY1Bs6CwE;AAA2Bw+BA2CpdD94E4B,iC;sB3Cqd1Bs6CwE;AAA4BvZA2CldD/gC4B,kC;qB3Cmd3Bs6CwE;AAA2BhJA2ChdDtxC4B,qB;iK3CwDbymE8C;+BAAax2BiD;k6GAwLpBmN4K;AAEAipByV;m3BA0FQ7nBiC;iBAA4B4SAxC66BpB5S6C,A;2BwC56BlBlEkD;qyBAwCqBpayD;oa2CzTZlgCK;mEAEI05BkD;oQAaY2jD4B;6GAIbniD0C;iBAAAAsC;yKAKP68CiChChG8Bt6CARuFbz9B2B,oBAAAAgC,A,A;gKwC2BI+kDAhCtGWAwB,A;wwDgCmH7BhKkH;0nC0EPM0gCsB;gBAAW72EoD9ClGjB0tF6E,0E;Y8CkGiB1tFwD;cAAAAqF;QAIfyyCgB;AAAO6kCqC;0EAKSnEmE;8BAAAAA1GjISt6CARuFbz9B2B,oBAAAAgC,A,A;+HkHoDEiiC4E;YAAAAA1GrImCxEARiFrCz9B2B,oBAAAAgC,A,A;yFkHuDEkgD6B;YAAAAA1GrIoCziBAR8EtCz9B2B,oBAAAAgC,A,A;gPkHqEdq3CgErHCer3C+C,A;AqHDRoxDAzDhHG5SuC,A;AyDiHenHArHAVr3CiD,A;4LqHMdymE+D;4iBA4BSjoBqC;qFAGSnHArHrCJr3CiF,oB;AqHqCzBg/BAzD1KwBh/B8F,A;8HyD0KxBlwD+E;qFAKiBgpIarHtDoB5LqC,A;AqHsDb1uBuC;+QAcds6B8BrHpE2B5LmC,A;qEqHqE3BnsCcrHjE6BmsCqC,A;wEqHkE7B57BarH9D2B47BuC,A;yXqHqET4LArH7ES5LmC,A;4DqH8ERnsC6BrH1EUmsCmC,A;6DqH2EX57B4BrHvES47BmC,A;gPqH8E1BltEkB;AADayuEsB;yCAIV2nBAA8BG5xCkB,6DAAAA4D,6EACF4KqE,A;4BA5BI0pBArH5FkB5L6C,A;iBqH4FvCn+Bc;sCAGYhOArH3F6BmsCmC,A;AqH2FrB9bsD;gCAGGrwBArH9FkBmsCqC,A;AqH8FvCn+Bc;+DAIUuCArH9F2B47BmC,A;AqH8FpB9bsD;6BAGI9fArHjGgB47BqC,A;AqHiGrCn+Bc;6DAMFAkD;0jBAiBoBphGM;09EChRlBgoH6B;sErGiDoCx4CoF;k8BuB5B5BgnBuM;AAFEnkCA4EKcq2FAAqDECgR,A,AApDJn5EAAOpBnd2H,A,AANuBCApKoMhB27BAFnCbAAAAAA0C,A,A,A,uD;gF0FnKS0eA+EjCPAY,A;A/EiCOqqBAxC4D0DyakC,A;AwC5D1D9kCA+EjCPAO,iD;A/EkCOSA+E9BPAmF,A;A/E+BiBw7CA6EsCOp5EAAvCPs5EAAAAz2FA9C1BnBAAAAAAAAC0B22F+H,A,A,A,A,A8CiDiBnL8Y,AAmB3CruEAAAAAuCAW6Bg2DArH6D6B11CAEjJtBAoBC2FRz9BgC,A,A,A,kIkHHC4oCqD,uH,A,A,A;i5qFzL2zCViuDoL;oZAUACwL;kZAUACsH;waAUAC0H;+tBqCn8BgCzM8C;6xEoFpc7B5tFAD3DYktF4C,A;oF/DAP7pFiB8GKFi9D6B,AACK92BiC,AACV0mC6B,A;wF9GAS7sEmBgHGJi9DmC,AACK92BqC,AACV0mC6E,AACQ/yB8C,A;gFhHEH95Ce+GVAi9D6B,AACK92B+D,AACV0mC2D,AACQ/yB6B,A;8gB3GHT95Cc;spD0CqBWAc;09C/C3BZAc;qFFHAAc;ilBoDesBmdyb;OAAAA0B;kwBxGmIbteAAqE3BgkF4B,A;"}}
\ No newline at end of file
diff --git a/pkgs/coverage/test/test_files/test_app.dart b/pkgs/coverage/test/test_files/test_app.dart
new file mode 100644
index 0000000..1e50703
--- /dev/null
+++ b/pkgs/coverage/test/test_files/test_app.dart
@@ -0,0 +1,61 @@
+// 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.
+
+// coverage:ignore-file
+
+import 'dart:async';
+import 'dart:developer';
+import 'dart:isolate';
+
+import 'package:coverage/src/util.dart';
+
+import 'test_app_isolate.dart';
+
+part 'test_app.g.dart';
+
+Future<void> main() async {
+ for (var i = 0; i < 10; i++) {
+ for (var j = 0; j < 10; j++) {
+ final sum = usedMethod(i, j);
+ if (sum != (i + j)) {
+ throw 'bad method!';
+ }
+
+ final multiplication = usedGeneratedMethod(i, j);
+ if (multiplication != i * j) {
+ throw 'bad generated method!';
+ }
+ }
+ }
+
+ final port = ReceivePort();
+
+ final isolate =
+ await Isolate.spawn(isolateTask, [port.sendPort, 1, 2], paused: true);
+ await Service.controlWebServer(enable: true);
+ final isolateID = Service.getIsolateID(isolate);
+ print('isolateId = $isolateID');
+
+ isolate.addOnExitListener(port.sendPort);
+ isolate.resume(isolate.pauseCapability!);
+
+ final value = await port.first as int;
+ if (value != 3) {
+ throw 'expected 3!';
+ }
+
+ final result = await retry(() async => 42, const Duration(seconds: 1)) as int;
+ print(result);
+}
+
+int usedMethod(int a, int b) {
+ return a + b;
+}
+
+int unusedMethod(int a, int b) {
+ return a - b;
+}
+
+// ignore_for_file: unreachable_from_main, only_throw_errors
+// ignore_for_file: deprecated_member_use
diff --git a/pkgs/coverage/test/test_files/test_app.g.dart b/pkgs/coverage/test/test_files/test_app.g.dart
new file mode 100644
index 0000000..c80718a
--- /dev/null
+++ b/pkgs/coverage/test/test_files/test_app.g.dart
@@ -0,0 +1,5 @@
+part of 'test_app.dart';
+
+int usedGeneratedMethod(int a, int b) {
+ return a * b;
+}
diff --git a/pkgs/coverage/test/test_files/test_app_isolate.dart b/pkgs/coverage/test/test_files/test_app_isolate.dart
new file mode 100644
index 0000000..8bbc6be
--- /dev/null
+++ b/pkgs/coverage/test/test_files/test_app_isolate.dart
@@ -0,0 +1,73 @@
+// 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 'dart:async';
+import 'dart:io';
+import 'dart:isolate';
+
+const int answer = 42;
+
+String fooSync(int x) {
+ if (x == answer) {
+ return '*' * x;
+ }
+ return List.generate(x, (_) => 'xyzzy').join(' ');
+}
+
+class BarClass {
+ BarClass(this.x);
+
+ int x;
+
+ void baz() {
+ print(x);
+ }
+}
+
+Future<String> fooAsync(int x) async {
+ if (x == answer) {
+ return '*' * x;
+ }
+ return List.generate(x, (_) => 'xyzzy').join(' ');
+}
+
+/// The number of covered lines is tested and expected to be 4.
+///
+/// If you modify this method, you may have to update the tests!
+void isolateTask(List threeThings) async {
+ sleep(const Duration(milliseconds: 500));
+
+ fooSync(answer);
+ unawaited(fooAsync(answer).then((_) {
+ final port = threeThings.first as SendPort;
+ final sum = (threeThings[1] as int) + (threeThings[2] as int);
+ port.send(sum);
+ }));
+
+ final bar = BarClass(123);
+ bar.baz();
+
+ print('678'); // coverage:ignore-line
+
+ // coverage:ignore-start
+ print('1');
+ print('2');
+ print('3');
+ // coverage:ignore-end
+
+ print('4 // coverage:ignore-line');
+ print('5 // coverage:ignore-file');
+
+ print('6'); // coverage:ignore-start
+ print('7');
+ print('8');
+ // coverage:ignore-end
+ print('9'); // coverage:ignore-start
+ print('10');
+ print('11'); // coverage:ignore-line
+
+ // Regression test for https://github.com/dart-lang/tools/issues/520.
+ await Isolate.run(() => print('Isolate.run'), debugName: 'Grandchild');
+ // coverage:ignore-end
+}
diff --git a/pkgs/coverage/test/test_files/test_library.dart b/pkgs/coverage/test/test_files/test_library.dart
new file mode 100644
index 0000000..d2fe49f
--- /dev/null
+++ b/pkgs/coverage/test/test_files/test_library.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part 'test_library_part.dart';
+
+int libraryFunction() {
+ return 123;
+}
diff --git a/pkgs/coverage/test/test_files/test_library_part.dart b/pkgs/coverage/test/test_files/test_library_part.dart
new file mode 100644
index 0000000..c99876d
--- /dev/null
+++ b/pkgs/coverage/test/test_files/test_library_part.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of 'test_library.dart';
+
+int otherLibraryFunction() {
+ return 123;
+}
diff --git a/pkgs/coverage/test/test_util.dart b/pkgs/coverage/test/test_util.dart
new file mode 100644
index 0000000..e0a3edb
--- /dev/null
+++ b/pkgs/coverage/test/test_util.dart
@@ -0,0 +1,91 @@
+// 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 'dart:async';
+import 'dart:io';
+
+import 'package:path/path.dart' as p;
+import 'package:test/test.dart';
+import 'package:test_process/test_process.dart';
+
+final String testAppPath = p.join('test', 'test_files', 'test_app.dart');
+
+const Duration timeout = Duration(seconds: 20);
+
+Future<TestProcess> runTestApp(int openPort) => TestProcess.start(
+ Platform.resolvedExecutable,
+ [
+ '--enable-vm-service=$openPort',
+ '--pause_isolates_on_exit',
+ '--branch-coverage',
+ testAppPath
+ ],
+ );
+
+List<Map<String, dynamic>> coverageDataFromJson(Map<String, dynamic> json) {
+ expect(json.keys, unorderedEquals(<String>['type', 'coverage']));
+ expect(json, containsPair('type', 'CodeCoverage'));
+
+ return (json['coverage'] as List).cast<Map<String, dynamic>>();
+}
+
+final _versionPattern = RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)');
+
+bool platformVersionCheck(int minMajor, int minMinor) {
+ final match = _versionPattern.matchAsPrefix(Platform.version);
+ if (match == null) return false;
+ if (match.groupCount < 3) return false;
+ final major = int.parse(match.group(1)!);
+ final minor = int.parse(match.group(2)!);
+ return major > minMajor || (major == minMajor && minor >= minMinor);
+}
+
+/// Returns a mapping of (URL: (function_name: hit_count)) from [sources].
+Map<String, Map<String, int>> functionInfoFromSources(
+ Map<String, List<Map<dynamic, dynamic>>> sources,
+) {
+ Map<int, String> getFuncNames(List list) {
+ return {
+ for (var i = 0; i < list.length; i += 2)
+ list[i] as int: list[i + 1] as String,
+ };
+ }
+
+ Map<int, int> getFuncHits(List list) {
+ return {
+ for (var i = 0; i < list.length; i += 2)
+ list[i] as int: list[i + 1] as int,
+ };
+ }
+
+ return {
+ for (var entry in sources.entries)
+ entry.key: entry.value.fold(
+ {},
+ (previousValue, element) {
+ expect(element['source'], entry.key);
+ final names = getFuncNames(element['funcNames'] as List);
+ final hits = getFuncHits(element['funcHits'] as List);
+
+ for (var pair in hits.entries) {
+ previousValue[names[pair.key]!] =
+ (previousValue[names[pair.key]!] ?? 0) + pair.value;
+ }
+
+ return previousValue;
+ },
+ ),
+ };
+}
+
+extension ListTestExtension on List {
+ Map<String, List<Map<dynamic, dynamic>>> sources() => cast<Map>().fold(
+ <String, List<Map>>{},
+ (Map<String, List<Map>> map, value) {
+ final sourceUri = value['source'] as String;
+ map.putIfAbsent(sourceUri, () => <Map>[]).add(value);
+ return map;
+ },
+ );
+}
diff --git a/pkgs/coverage/test/test_with_coverage_package/lib/validate_lib.dart b/pkgs/coverage/test/test_with_coverage_package/lib/validate_lib.dart
new file mode 100644
index 0000000..771c040
--- /dev/null
+++ b/pkgs/coverage/test/test_with_coverage_package/lib/validate_lib.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2024, 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.
+
+int sum(Iterable<int> values) {
+ var val = 0;
+ for (var value in values) {
+ val += value;
+ }
+ return val;
+}
+
+int product(Iterable<int> values) {
+ var val = 1;
+ for (var value in values) {
+ val *= value;
+ }
+ return val;
+}
diff --git a/pkgs/coverage/test/test_with_coverage_package/pubspec.yaml b/pkgs/coverage/test/test_with_coverage_package/pubspec.yaml
new file mode 100644
index 0000000..3fa7ee0
--- /dev/null
+++ b/pkgs/coverage/test/test_with_coverage_package/pubspec.yaml
@@ -0,0 +1,12 @@
+name: coverage_integration_test_for_test_with_coverage
+publish_to: none
+
+environment:
+ sdk: '>=2.15.0 <3.0.0'
+
+dev_dependencies:
+ test: ^1.16.0
+
+dependency_overrides:
+ coverage:
+ path: ../../
diff --git a/pkgs/coverage/test/test_with_coverage_package/test/product_test.dart b/pkgs/coverage/test/test_with_coverage_package/test/product_test.dart
new file mode 100644
index 0000000..91eac53
--- /dev/null
+++ b/pkgs/coverage/test/test_with_coverage_package/test/product_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test/test.dart';
+
+// ignore: avoid_relative_lib_imports
+import '../lib/validate_lib.dart';
+
+void main() {
+ test('product', () {
+ expect(product([2, 3]), 6);
+ });
+}
diff --git a/pkgs/coverage/test/test_with_coverage_package/test/sum_test.dart b/pkgs/coverage/test/test_with_coverage_package/test/sum_test.dart
new file mode 100644
index 0000000..f5b1ea4
--- /dev/null
+++ b/pkgs/coverage/test/test_with_coverage_package/test/sum_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test/test.dart';
+
+// ignore: avoid_relative_lib_imports
+import '../lib/validate_lib.dart';
+
+void main() {
+ test('sum', () {
+ expect(sum([1, 2]), 3);
+ });
+}
diff --git a/pkgs/coverage/test/test_with_coverage_test.dart b/pkgs/coverage/test/test_with_coverage_test.dart
new file mode 100644
index 0000000..689452d
--- /dev/null
+++ b/pkgs/coverage/test/test_with_coverage_test.dart
@@ -0,0 +1,157 @@
+// Copyright (c) 2022, 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.
+
+@Timeout(Duration(seconds: 60))
+library;
+
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:path/path.dart' as p;
+import 'package:test/test.dart';
+import 'package:test_descriptor/test_descriptor.dart' as d;
+import 'package:test_process/test_process.dart';
+
+import 'test_util.dart';
+
+// this package
+final _pkgDir = p.absolute('');
+final _testWithCoveragePath = p.join(_pkgDir, 'bin', 'test_with_coverage.dart');
+
+// test package
+final _testPkgDirPath = p.join(_pkgDir, 'test', 'test_with_coverage_package');
+
+/// Override PUB_CACHE
+///
+/// Use a subdirectory different from `test/` just in case there is a problem
+/// with the clean up. If other packages are present under the `test/`
+/// subdirectory their tests may accidentally get run when running `dart test`
+final _pubCachePathInTestPkgSubDir = p.join(_pkgDir, 'var', 'pub-cache');
+final _env = {'PUB_CACHE': _pubCachePathInTestPkgSubDir};
+
+const _testPackageName = 'coverage_integration_test_for_test_with_coverage';
+
+int _port = 9300;
+
+Iterable<File> _dartFiles(String dir) =>
+ Directory(p.join(_testPkgDirPath, dir)).listSync().whereType<File>();
+
+String _fixTestFile(String content) => content.replaceAll(
+ "import '../lib/",
+ "import 'package:$_testPackageName/",
+ );
+
+void main() {
+ setUpAll(() async {
+ for (var dir in const ['lib', 'test']) {
+ await d.dir(dir, [
+ for (var dartFile in _dartFiles(dir))
+ d.file(
+ p.basename(dartFile.path),
+ _fixTestFile(dartFile.readAsStringSync()),
+ ),
+ ]).create();
+ }
+
+ var pubspecContent =
+ File(p.join(_testPkgDirPath, 'pubspec.yaml')).readAsStringSync();
+
+ expect(
+ pubspecContent.replaceAll('\r\n', '\n'),
+ contains(r'''
+dependency_overrides:
+ coverage:
+ path: ../../
+'''),
+ );
+
+ pubspecContent =
+ pubspecContent.replaceFirst('path: ../../', 'path: $_pkgDir');
+
+ await d.file('pubspec.yaml', pubspecContent).create();
+
+ final localPub = await _run(['pub', 'get']);
+ await localPub.shouldExit(0);
+ });
+
+ test('dart run bin/test_with_coverage.dart -f', () async {
+ final list = await _runTest(['run', _testWithCoveragePath, '-f']);
+
+ final sources = list.sources();
+ final functionHits = functionInfoFromSources(sources);
+
+ expect(
+ functionHits['package:$_testPackageName/validate_lib.dart'],
+ {
+ 'product': 1,
+ 'sum': 1,
+ },
+ );
+ });
+
+ test('dart run bin/test_with_coverage.dart -f -- -N sum', () async {
+ final list = await _runTest(
+ ['run', _testWithCoveragePath, '-f'],
+ extraArgs: ['--', '-N', 'sum'],
+ );
+
+ final sources = list.sources();
+ final functionHits = functionInfoFromSources(sources);
+
+ expect(
+ functionHits['package:$_testPackageName/validate_lib.dart'],
+ {
+ 'product': 0,
+ 'sum': 1,
+ },
+ reason: 'only `sum` tests should be run',
+ );
+ });
+
+ test('dart run coverage:test_with_coverage', () async {
+ await _runTest(['run', 'coverage:test_with_coverage']);
+ });
+
+ test('dart pub global run coverage:test_with_coverage', () async {
+ final globalPub =
+ await _run(['pub', 'global', 'activate', '-s', 'path', _pkgDir]);
+ await globalPub.shouldExit(0);
+
+ await _runTest(
+ ['pub', 'global', 'run', 'coverage:test_with_coverage'],
+ );
+ });
+}
+
+Future<TestProcess> _run(List<String> args) => TestProcess.start(
+ Platform.executable,
+ args,
+ workingDirectory: d.sandbox,
+ environment: _env,
+ );
+
+Future<List<Map<String, dynamic>>> _runTest(
+ List<String> invokeArgs, {
+ List<String>? extraArgs,
+}) async {
+ final process = await _run([
+ ...invokeArgs,
+ '--port',
+ '${_port++}',
+ ...?extraArgs,
+ ]);
+
+ await process.shouldExit(0);
+
+ await d.dir(
+ 'coverage',
+ [d.file('coverage.json', isNotEmpty), d.file('lcov.info', isNotEmpty)],
+ ).validate();
+
+ final coverageDataFile = File(p.join(d.sandbox, 'coverage', 'coverage.json'));
+
+ final json = jsonDecode(coverageDataFile.readAsStringSync());
+
+ return coverageDataFromJson(json as Map<String, dynamic>);
+}
diff --git a/pkgs/coverage/test/util_test.dart b/pkgs/coverage/test/util_test.dart
new file mode 100644
index 0000000..6a4e556
--- /dev/null
+++ b/pkgs/coverage/test/util_test.dart
@@ -0,0 +1,358 @@
+// 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.
+
+// ignore_for_file: only_throw_errors
+
+import 'dart:async';
+
+import 'package:coverage/src/util.dart';
+import 'package:test/test.dart';
+
+const _failCount = 5;
+const _delay = Duration(milliseconds: 10);
+
+void main() {
+ test('retry', () async {
+ var count = 0;
+ final stopwatch = Stopwatch()..start();
+
+ Future failCountTimes() async {
+ expect(stopwatch.elapsed, greaterThanOrEqualTo(_delay * count));
+
+ while (count < _failCount) {
+ count++;
+ throw 'not yet!';
+ }
+ return 42;
+ }
+
+ final value = await retry(failCountTimes, _delay) as int;
+
+ expect(value, 42);
+ expect(count, _failCount);
+ expect(stopwatch.elapsed, greaterThanOrEqualTo(_delay * count));
+ });
+
+ group('retry with timeout', () {
+ test('if it finishes', () async {
+ var count = 0;
+ final stopwatch = Stopwatch()..start();
+
+ Future failCountTimes() async {
+ expect(stopwatch.elapsed, greaterThanOrEqualTo(_delay * count));
+
+ while (count < _failCount) {
+ count++;
+ throw 'not yet!';
+ }
+ return 42;
+ }
+
+ final safeTimoutDuration = _delay * _failCount * 10;
+ final value = await retry(
+ failCountTimes,
+ _delay,
+ timeout: safeTimoutDuration,
+ ) as int;
+
+ expect(value, 42);
+ expect(count, _failCount);
+ expect(stopwatch.elapsed, greaterThanOrEqualTo(_delay * count));
+ });
+
+ test('if it does not finish', () async {
+ var count = 0;
+ final stopwatch = Stopwatch()..start();
+
+ var caught = false;
+ var countAfterError = 0;
+
+ Future failCountTimes() async {
+ if (caught) {
+ countAfterError++;
+ }
+ expect(stopwatch.elapsed, greaterThanOrEqualTo(_delay * count));
+
+ count++;
+ throw 'never';
+ }
+
+ final unsafeTimeoutDuration = _delay * (_failCount / 2);
+
+ try {
+ await retry(failCountTimes, _delay, timeout: unsafeTimeoutDuration);
+ // ignore: avoid_catching_errors
+ } on StateError catch (e) {
+ expect(e.message, 'Failed to complete within 25ms');
+ caught = true;
+
+ expect(countAfterError, 0,
+ reason: 'Execution should stop after a timeout');
+
+ await Future<dynamic>.delayed(_delay * 3);
+
+ expect(countAfterError, 0, reason: 'Even after a delay');
+ }
+
+ expect(caught, isTrue);
+ });
+ });
+
+ group('extractVMServiceUri', () {
+ test('returns null when not found', () {
+ expect(extractVMServiceUri('foo bar baz'), isNull);
+ });
+
+ test('returns null for an incorrectly formatted URI', () {
+ const msg = 'Observatory listening on :://';
+ expect(extractVMServiceUri(msg), null);
+ });
+
+ test('returns URI at end of string', () {
+ const msg = 'Observatory listening on http://foo.bar:9999/';
+ expect(extractVMServiceUri(msg), Uri.parse('http://foo.bar:9999/'));
+ });
+
+ test('returns URI with auth token at end of string', () {
+ const msg = 'Observatory listening on http://foo.bar:9999/cG90YXRv/';
+ expect(
+ extractVMServiceUri(msg), Uri.parse('http://foo.bar:9999/cG90YXRv/'));
+ });
+
+ test('return URI embedded within string', () {
+ const msg = '1985-10-26 Observatory listening on http://foo.bar:9999/ **';
+ expect(extractVMServiceUri(msg), Uri.parse('http://foo.bar:9999/'));
+ });
+
+ test('return URI with auth token embedded within string', () {
+ const msg =
+ '1985-10-26 Observatory listening on http://foo.bar:9999/cG90YXRv/ **';
+ expect(
+ extractVMServiceUri(msg), Uri.parse('http://foo.bar:9999/cG90YXRv/'));
+ });
+
+ test('handles new Dart VM service message format', () {
+ const msg =
+ 'The Dart VM service is listening on http://foo.bar:9999/cG90YXRv/';
+ expect(
+ extractVMServiceUri(msg), Uri.parse('http://foo.bar:9999/cG90YXRv/'));
+ });
+ });
+
+ group('getIgnoredLines', () {
+ const invalidSources = [
+ '''final str = ''; // coverage:ignore-start
+ final str = '';
+ final str = ''; // coverage:ignore-start
+ ''',
+ '''final str = ''; // coverage:ignore-start
+ final str = '';
+ final str = ''; // coverage:ignore-start
+ final str = ''; // coverage:ignore-end
+ final str = '';
+ final str = ''; // coverage:ignore-end
+ ''',
+ '''final str = ''; // coverage:ignore-start
+ final str = '';
+ final str = ''; // coverage:ignore-end
+ final str = '';
+ final str = ''; // coverage:ignore-end
+ ''',
+ '''final str = ''; // coverage:ignore-end
+ final str = '';
+ final str = ''; // coverage:ignore-start
+ final str = '';
+ final str = ''; // coverage:ignore-end
+ ''',
+ '''final str = ''; // coverage:ignore-end
+ final str = '';
+ final str = ''; // coverage:ignore-end
+ ''',
+ '''final str = ''; // coverage:ignore-end
+ final str = '';
+ final str = ''; // coverage:ignore-start
+ ''',
+ '''final str = ''; // coverage:ignore-end
+ ''',
+ '''final str = ''; // coverage:ignore-start
+ ''',
+ ];
+
+ test('throws FormatException when the annotations are not balanced', () {
+ void runTest(int index, String errMsg) {
+ final content = invalidSources[index].split('\n');
+ expect(
+ () => getIgnoredLines('content-$index.dart', content),
+ throwsA(
+ allOf(
+ isFormatException,
+ predicate((FormatException e) => e.message == errMsg),
+ ),
+ ),
+ reason: 'expected FormatException with message "$errMsg"',
+ );
+ }
+
+ runTest(
+ 0,
+ 'coverage:ignore-start found at content-0.dart:'
+ '3 before previous coverage:ignore-start ended',
+ );
+ runTest(
+ 1,
+ 'coverage:ignore-start found at content-1.dart:'
+ '3 before previous coverage:ignore-start ended',
+ );
+ runTest(
+ 2,
+ 'unmatched coverage:ignore-end found at content-2.dart:5',
+ );
+ runTest(
+ 3,
+ 'unmatched coverage:ignore-end found at content-3.dart:1',
+ );
+ runTest(
+ 4,
+ 'unmatched coverage:ignore-end found at content-4.dart:1',
+ );
+ runTest(
+ 5,
+ 'unmatched coverage:ignore-end found at content-5.dart:1',
+ );
+ runTest(
+ 6,
+ 'unmatched coverage:ignore-end found at content-6.dart:1',
+ );
+ runTest(
+ 7,
+ 'coverage:ignore-start found at content-7.dart:'
+ '1 has no matching coverage:ignore-end',
+ );
+ });
+
+ test(
+ 'returns [[0,lines.length]] when the annotations are not '
+ 'balanced but the whole file is ignored', () {
+ for (final content in invalidSources) {
+ final lines = content.split('\n');
+ lines.add(' // coverage:ignore-file');
+ expect(getIgnoredLines('', lines), [
+ [0, lines.length]
+ ]);
+ }
+ });
+
+ test('returns [[0,lines.length]] when the whole file is ignored', () {
+ final lines = '''final str = ''; // coverage:ignore-start
+ final str = ''; // coverage:ignore-end
+ final str = ''; // coverage:ignore-file
+ '''
+ .split('\n');
+
+ expect(getIgnoredLines('', lines), [
+ [0, lines.length]
+ ]);
+ });
+
+ test('return the correct range of lines ignored', () {
+ final lines = '''
+ final str = ''; // coverage:ignore-start
+ final str = ''; // coverage:ignore-line
+ final str = ''; // coverage:ignore-end
+ final str = ''; // coverage:ignore-start
+ final str = ''; // coverage:ignore-line
+ final str = ''; // coverage:ignore-end
+ '''
+ .split('\n');
+
+ expect(getIgnoredLines('', lines), [
+ [1, 3],
+ [4, 6],
+ ]);
+ });
+
+ test('return the correct list of lines ignored', () {
+ final lines = '''
+ final str = ''; // coverage:ignore-line
+ final str = ''; // coverage:ignore-line
+ final str = ''; // coverage:ignore-line
+ '''
+ .split('\n');
+
+ expect(getIgnoredLines('', lines), [
+ [1, 1],
+ [2, 2],
+ [3, 3],
+ ]);
+ });
+
+ test('ignore comments have no effect inside string literals', () {
+ final lines = '''
+ final str = '// coverage:ignore-file';
+ final str = '// coverage:ignore-line';
+ final str = ''; // coverage:ignore-line
+ final str = '// coverage:ignore-start';
+ final str = '// coverage:ignore-end';
+ '''
+ .split('\n');
+
+ expect(getIgnoredLines('', lines), [
+ [3, 3],
+ ]);
+ });
+
+ test('allow white-space after ignore comments', () {
+ // Using multiple strings, rather than splitting a multi-line string,
+ // because many code editors remove trailing white-space.
+ final lines = [
+ "final str = ''; // coverage:ignore-start ",
+ "final str = ''; // coverage:ignore-line\t",
+ "final str = ''; // coverage:ignore-end \t \t ",
+ "final str = ''; // coverage:ignore-line \t ",
+ "final str = ''; // coverage:ignore-start \t ",
+ "final str = ''; // coverage:ignore-end \t \t ",
+ ];
+
+ expect(getIgnoredLines('', lines), [
+ [1, 3],
+ [4, 4],
+ [5, 6],
+ ]);
+ });
+
+ test('allow omitting space after //', () {
+ final lines = [
+ "final str = ''; //coverage:ignore-start",
+ "final str = ''; //coverage:ignore-line",
+ "final str = ''; //coverage:ignore-end",
+ "final str = ''; //coverage:ignore-line",
+ "final str = ''; //coverage:ignore-start",
+ "final str = ''; //coverage:ignore-end",
+ ];
+
+ expect(getIgnoredLines('', lines), [
+ [1, 3],
+ [4, 4],
+ [5, 6],
+ ]);
+ });
+
+ test('allow text after ignore comments', () {
+ final lines = [
+ "final str = ''; // coverage:ignore-start due to XYZ",
+ "final str = ''; // coverage:ignore-line",
+ "final str = ''; // coverage:ignore-end due to XYZ",
+ "final str = ''; // coverage:ignore-line due to 123",
+ "final str = ''; // coverage:ignore-start",
+ "final str = ''; // coverage:ignore-end it is done",
+ ];
+
+ expect(getIgnoredLines('', lines), [
+ [1, 3],
+ [4, 4],
+ [5, 6],
+ ]);
+ });
+ });
+}
diff --git a/pkgs/extension_discovery/.gitignore b/pkgs/extension_discovery/.gitignore
new file mode 100644
index 0000000..ddfdca1
--- /dev/null
+++ b/pkgs/extension_discovery/.gitignore
@@ -0,0 +1,5 @@
+.dart_tool/
+.packages
+.pub/
+build/
+pubspec.lock
diff --git a/pkgs/extension_discovery/CHANGELOG.md b/pkgs/extension_discovery/CHANGELOG.md
new file mode 100644
index 0000000..f35371e
--- /dev/null
+++ b/pkgs/extension_discovery/CHANGELOG.md
@@ -0,0 +1,24 @@
+## 2.1.0
+
+- Require Dart 3.4.
+- Update to the latest version of `package:dart_flutter_team_lints`.
+- Add `findPackageConfig()` allowing for automatic discovery of the
+ packageConfig based on a package directory.
+
+## 2.0.0
+
+- Use `extension/<package>/config.yaml` instead of
+ `extension/<package>/config.json` for better consistency with other tooling.
+- Require that the top-level value in `extension/<package>/config.yaml` is
+ always a `Map`, and that the structure can be converted to a JSON equivalent
+ structure.
+
+## 1.0.1
+
+- Support optional `packageUri`.
+- Improve error messaging for `package_config.json` parsing.
+- Update the package description.
+
+## 1.0.0
+
+- Initial version.
diff --git a/pkgs/extension_discovery/LICENSE b/pkgs/extension_discovery/LICENSE
new file mode 100644
index 0000000..ac90031
--- /dev/null
+++ b/pkgs/extension_discovery/LICENSE
@@ -0,0 +1,27 @@
+Copyright 2023, the Dart project authors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of Google LLC nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/pkgs/extension_discovery/README.md b/pkgs/extension_discovery/README.md
new file mode 100644
index 0000000..0214ae9
--- /dev/null
+++ b/pkgs/extension_discovery/README.md
@@ -0,0 +1,237 @@
+[](https://github.com/dart-lang/tools/actions/workflows/extension_discovery.yml)
+[](https://pub.dev/packages/extension_discovery)
+[](https://pub.dev/packages/extension_discovery/publisher)
+
+A convention and utilities for package extension discovery.
+
+## What's this?
+
+A convention to allow other packages to provide extensions for your package
+(or tool). Including logic for finding extensions that honor this convention.
+
+The convention implemented in this package is that if `foo` provides an
+extension for `<targetPackage>`.
+Then `foo` must contain a config file `extension/<targetPackage>/config.yaml`.
+This file indicates that `foo` provides an extension for `<targetPackage>`.
+
+If `<targetPackage>` accepts extensions from other packages it must:
+ * Find extensions using `findExtensions('<targetPackage>')` from this package.
+ * Document how extensions are implemented:
+ * What should the contents of the `extension/<targetPackage>/config.yaml` file be?
+ * Should packages providing extensions have a dependency constraint on `<targetPackage>`?
+ * What libraries/assets should packages that provide extensions include?
+ * Should packages providing extensions specify a [topic in `pubspec.yaml`][1]
+ for easy discovery on pub.dev.
+
+The `findExtensions(targetPackage, packageConfig: ...)` function will:
+ * Load `.dart_tool/package_config.json` and find all packages that contain a
+ valid YAML file: `extension/<targetPackage>/config.yaml`.
+ * Provide the package name, location and contents of the `config.yaml` file,
+ for all detected extensions (aimed at `targetPackage`).
+ * Cache the results for fast loading, comparing modification timestamps to
+ ensure consistent results.
+
+It is the responsibility package that can be extended to validate extensions,
+decide when they should be enabled, and documenting how such extensions are
+created.
+
+
+## Packages that extend tools
+
+You can also use this package (and associated convention), if you are developing
+a tool that can be extended by packages. In this case, you would call
+`findExtensions(<my_tool_package_name>, packageConfig: ...)` where
+`packageConfig` points to the `.dart_tool/package_config.json` in the workspace
+the tool is operating on.
+
+If you tool is not distributed through pub.dev, you might consider publishing
+a placeholder package in order to reserve a unique name (and avoid collisions).
+Using a placeholder package to reserve a unique is also recommended for tools
+that wish to cache files in `.dart_tool/<my_tool_package_name>/`.
+See [package layout documentation][2] for details.
+
+
+## Example: Hello World
+
+Imagine that we have a `hello_world` package that defines a single method
+`sayHello(String language)`, along the lines of:
+
+```dart
+void sayHello(String language) {
+ if (language == 'danish') {
+ print('Hej verden');
+ } else {
+ print('Hello world!');
+ }
+}
+```
+
+### Enabling packages to extend `hello_world`
+
+If we wanted to allow other packages to provide additional languages by
+extending the `hello_world` package. Then we could do:
+
+```dart
+import 'package:extension_discovery/extension_discovery.dart';
+
+Future<void> sayHello(String language) async {
+ // Find extensions for the "hello_world" package.
+ // WARNING: This only works when running in JIT-mode, if running in AOT-mode
+ // you must supply the `packageConfig` argument, and have a local
+ // `.dart_tool/package_config.json` and `$PUB_CACHE`.
+ // See "Runtime limitations" section further down.
+ final extensions = await findExtensions('hello_world');
+
+ // Search extensions to see if one provides a message for language
+ for (final ext in extensions) {
+ final config = ext.config;
+ if (config is! Map<String, Object?>) {
+ continue; // ignore extensions with invalid configation
+ }
+ if (config['language'] == language) {
+ print(config['message']);
+ return; // Don't print more messages!
+ }
+ }
+
+ if (language == 'danish') {
+ print('Hej verden');
+ } else {
+ print('Hello world!');
+ }
+}
+```
+
+The `findExtensions` function will search other packages for
+`extension/hello_world/config.yaml`, and provide the contents of this file as
+well as provide the location of the extending packages.
+As authors of the `hello_world` package we should also document how other
+packages can extend `hello_world`. This is typically done by adding a segment
+to the `README.md`.
+
+
+### Extending `hello_world` from another package
+
+If in another package `hello_world_german` we wanted to extend `hello_world`
+and provide a translation for German, then we would create a
+`hello_world_german` package containing an
+**`extension/hello_world/config.yaml`**:
+
+```yaml
+language: german
+message: "Hello Welt!"
+```
+
+Obviously, this is a contrived example. The authors of the `hello_world` package
+could specify all sorts configuration options that extension authors can
+specify in `extension/hello_world/config.yaml`.
+
+The authors of `hello_world` could also specify that extensions must provide
+certain assets in `extension/hello_world/` or that they must provide certain
+Dart libraries implementing a specified interface somewhere in `lib/src/...`.
+
+It is up to the authors of `hello_world` to specify what extension authors must
+provide. The `extension_discovery` package only provides a utility for finding
+extensions.
+
+
+### Using `hello_world` and `hello_world_german`
+
+If writing `my_hello_world_app` I can now take advantage of `hello_world` and
+`hello_world_german`. Simply write a `pubspec.yaml` as follows:
+
+```yaml
+# pubspec.yaml
+name: my_hello_world_app
+dependencies:
+ hello_world: ^1.0.0
+ hello_world_german: ^1.0.0
+environment:
+ sdk: ^3.4.0
+```
+
+Then I can write a `bin/hello.dart` as follows:
+
+```dart
+// bin/hello.dart
+import 'package:hello_world/hello_world.dart';
+
+Future<void> main() async {
+ await sayHello('german');
+}
+```
+
+
+## What can an extension provide?
+
+As far as the `extension_discovery` package is concerned an extension can
+provide anything. Naturally, it is the authors of the extendable package that
+decides what extensions can be provide.
+
+In the example above it is the authors of the `hello_world` package that decides
+what extension packages can provide. For this reason it is important that the
+authors of `hello_world` very explicitly document how an extension is written.
+
+Obviously, authors of `hello_world` should document what should be specified in
+`extension/hello_world/config.yaml`. They could also specify that other files
+should be provided in `extension/hello_world/`, or that certain Dart libraries
+should be provided in `lib/src/hello_world/...` or something like that.
+
+When authors of `hello_world` consumes the extensions discovered through
+`findExtensions` they would naturally also be wise to validate that the
+extension provides the required configuration and files.
+
+
+## Compatibility considerations
+
+When writing an extension it is strongly encouraged to have a dependency
+constraint on the package being extended. This ensures that the extending
+package will be incompatibility with new major versions of the extended package.
+
+In the example above, it is strongly encouraged for `hello_world_german` to
+have a dependency constraint `hello_world: ^1.0.0`. Even if `hello_world_german`
+doesn't import libraries from `package:hello_world`.
+
+Because the next major version of `hello_world` (version `2.0.0`) might change
+what is required of an extension. Thus, it's fair to assume that
+`hello_world_german` might not be compatible with newer versions of
+`hello_world`. Hence, adding a dependency constraint `hello_world: ^1.0.0` saves
+users from resolving dependencies that aren't compatible.
+
+Naturally, after a new major version of `hello_world` is published a new
+version of `hello_world_german` can then also be published, addressing any
+breaking changes and bumping the dependency constraint.
+
+**Tip:** Authors of packages that can be extended might want to force extension
+authors take dependency on their package, to ensure that they have the ability
+to do breaking changes in the future.
+
+
+## Runtime limitations
+
+The `findExtensions` function only works when running in JIT-mode, otherwise the
+`packageConfig` parameter must be used to provide the location of
+`.dart_tool/package_config.json`. Obviously, the `package_config.json` must be
+present, as must the pub-cache locations referenced here.
+
+Hence, `findExtensions` effectively **only works from project workspace!**.
+
+You can't use `findExtensions` in a compiled Flutter application or an
+AOT-compiled executable distributed to end-users. Because in these environments
+you don't have a `package_config.json` nor do you have a pub-cache. You don't
+even have access to your own source files.
+
+If your deployment target a compiled Flutter application or AOT-compiled
+executable, then you will have to create some code/asset-generation.
+You code/asset-generation scripts can use `findExtensions` to find extensions,
+and then use the assets or Dart libraries from here to generate assets or code
+that is embedded in the final Flutter application (or AOT-compiled executable).
+
+This makes `findExtensions` immediately useful, if you are writing development
+tools that users will install into their project workspace. But if you're
+writing a package for use in deployed applications, you'll likely need to figure
+out how to embed the extensions, `findExtensions` only helps
+you find the extensions during code-gen.
+
+[1]: https://dart.dev/tools/pub/pubspec#topics
+[2]: https://dart.dev/tools/pub/package-layout#project-specific-caching-for-tools
diff --git a/pkgs/extension_discovery/analysis_options.yaml b/pkgs/extension_discovery/analysis_options.yaml
new file mode 100644
index 0000000..aadd26e
--- /dev/null
+++ b/pkgs/extension_discovery/analysis_options.yaml
@@ -0,0 +1,5 @@
+include: package:dart_flutter_team_lints/analysis_options.yaml
+
+linter:
+ rules:
+ - avoid_catches_without_on_clauses
diff --git a/pkgs/extension_discovery/example/hello_world/README.md b/pkgs/extension_discovery/example/hello_world/README.md
new file mode 100644
index 0000000..39ec96d
--- /dev/null
+++ b/pkgs/extension_discovery/example/hello_world/README.md
@@ -0,0 +1,26 @@
+# `hello_world` package
+
+Example of a package that can be extended, and uses `extension_discovery` to
+find extensions.
+
+## Limitations
+
+The `sayHello` function in this package can only be used in a project workspace,
+where dependencies are resolved and you're running in JIT-mode.
+
+The `sayHello` function uses `findExtensions` and, thus, cannot be called in a
+compiled Flutter application or AOT-compiled executable. For this to work, we'd
+need to augment this package with code-generation, such that the code-generation
+uses `findExtensions` and compiles a `sayHello` function into your application.
+
+## Extending the `hello_world` package
+
+Other packages can extend this package by providing an `extension/hello_world/config.json` file the following form:
+
+```js
+// extension/hello_world/config.json
+{
+ "language": "<language>",
+ "message": "<message>"
+}
+```
diff --git a/pkgs/extension_discovery/example/hello_world/lib/hello_world.dart b/pkgs/extension_discovery/example/hello_world/lib/hello_world.dart
new file mode 100644
index 0000000..9e4a848
--- /dev/null
+++ b/pkgs/extension_discovery/example/hello_world/lib/hello_world.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2023, 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:extension_discovery/extension_discovery.dart';
+
+Future<void> sayHello(String language) async {
+ // Find extensions for the "hello_world" package.
+ // WARNING: This only works when running in JIT-mode, if running in AOT-mode
+ // you must supply the `packageConfig` argument, and have a local
+ // `.dart_tool/package_config.json` and `$PUB_CACHE`.
+ final extensions = await findExtensions('hello_world');
+
+ // Search extensions to see if one provides a message for language
+ for (final ext in extensions) {
+ final config = ext.config;
+ if (config['language'] == language) {
+ print(config['message']);
+ return; // Don't print more messages!
+ }
+ }
+
+ if (language == 'danish') {
+ print('Hej verden');
+ } else {
+ print('Hello world!');
+ }
+}
diff --git a/pkgs/extension_discovery/example/hello_world/pubspec.yaml b/pkgs/extension_discovery/example/hello_world/pubspec.yaml
new file mode 100644
index 0000000..40c68a3
--- /dev/null
+++ b/pkgs/extension_discovery/example/hello_world/pubspec.yaml
@@ -0,0 +1,10 @@
+name: hello_world
+version: 1.0.0
+publish_to: none # This is an example, don't publish!
+
+dependencies:
+ extension_discovery: # ^1.0.0
+ path: ../../
+
+environment:
+ sdk: ^3.4.0
diff --git a/pkgs/extension_discovery/example/hello_world_app/README.md b/pkgs/extension_discovery/example/hello_world_app/README.md
new file mode 100644
index 0000000..1d45229
--- /dev/null
+++ b/pkgs/extension_discovery/example/hello_world_app/README.md
@@ -0,0 +1,8 @@
+# `hello_world_app`
+
+An application that uses the `hello_world` package and has a dependency on
+`hello_world_german` such that when `hello_world` calls `findExtensions` it will
+find the extension in `hello_world_german`.
+
+**Notice**: This application only works when running from a project workspace.
+See "runtime limitation" in the README for `package:extension_discovery`.
diff --git a/pkgs/extension_discovery/example/hello_world_app/bin/hello.dart b/pkgs/extension_discovery/example/hello_world_app/bin/hello.dart
new file mode 100644
index 0000000..a4715ef
--- /dev/null
+++ b/pkgs/extension_discovery/example/hello_world_app/bin/hello.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2023, 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:hello_world/hello_world.dart';
+
+Future<void> main() async {
+ await sayHello('german');
+}
diff --git a/pkgs/extension_discovery/example/hello_world_app/pubspec.yaml b/pkgs/extension_discovery/example/hello_world_app/pubspec.yaml
new file mode 100644
index 0000000..30338d2
--- /dev/null
+++ b/pkgs/extension_discovery/example/hello_world_app/pubspec.yaml
@@ -0,0 +1,11 @@
+name: my_hello_world_app
+publish_to: none # applications should never be published!
+
+dependencies:
+ hello_world: # ^1.0.0
+ path: ../hello_world
+ hello_world_german: # ^1.0.0
+ path: ../hello_world_german
+
+environment:
+ sdk: ^3.4.0
diff --git a/pkgs/extension_discovery/example/hello_world_german/README.md b/pkgs/extension_discovery/example/hello_world_german/README.md
new file mode 100644
index 0000000..4a58703
--- /dev/null
+++ b/pkgs/extension_discovery/example/hello_world_german/README.md
@@ -0,0 +1,4 @@
+# `hello_world_german`
+
+Example of a simple package that provides an extension for the `hello_world`
+package.
diff --git a/pkgs/extension_discovery/example/hello_world_german/extension/hello_world/config.yaml b/pkgs/extension_discovery/example/hello_world_german/extension/hello_world/config.yaml
new file mode 100644
index 0000000..ef57087
--- /dev/null
+++ b/pkgs/extension_discovery/example/hello_world_german/extension/hello_world/config.yaml
@@ -0,0 +1,9 @@
+# This config file let's `package:extension_discovery` find out that
+# `package:hello_world_german` has an extension for `package:hello_world`.
+#
+# The root object must be a map, and the data structure must be representable
+# as JSON, but those are the only constraints. Beyond that it is the
+# responsibility of `package:hello_world` to define what this file should
+# contain, to validate the contents, and do something useful with it.
+language: german
+message: "Hello Welt!"
diff --git a/pkgs/extension_discovery/example/hello_world_german/pubspec.yaml b/pkgs/extension_discovery/example/hello_world_german/pubspec.yaml
new file mode 100644
index 0000000..39e80be
--- /dev/null
+++ b/pkgs/extension_discovery/example/hello_world_german/pubspec.yaml
@@ -0,0 +1,15 @@
+name: hello_world_german
+version: 1.0.0
+publish_to: none # This is an example, don't publish!
+
+dependencies:
+ # We keep a dependency on package `hello_world` because this package provides
+ # an extension for this package. Hence, a newer major version of hello_world
+ # might be incompatible with the extension options we've provided in
+ # extension/hello_world/config.json
+ # It is `hello_world` that specifies what is required in `config.json`.
+ hello_world: # ^1.0.0
+ path: ../hello_world
+
+environment:
+ sdk: ^3.4.0
diff --git a/pkgs/extension_discovery/lib/extension_discovery.dart b/pkgs/extension_discovery/lib/extension_discovery.dart
new file mode 100644
index 0000000..662435a
--- /dev/null
+++ b/pkgs/extension_discovery/lib/extension_discovery.dart
@@ -0,0 +1,285 @@
+// Copyright (c) 2023, 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.
+
+/// Find extensions with [findExtensions].
+library;
+
+import 'dart:collection' show UnmodifiableListView;
+import 'dart:io' show File, IOException;
+import 'dart:isolate' show Isolate;
+
+import 'src/io.dart';
+import 'src/package_config.dart';
+import 'src/registry.dart';
+import 'src/yaml_config_format.dart';
+
+export 'src/package_config.dart' show PackageConfigException, findPackageConfig;
+
+/// Information about an extension for target package.
+final class Extension {
+ /// Name of the package providing an extension.
+ final String package;
+
+ /// Absolute path to the package root.
+ ///
+ /// This folder usually contains a `lib/` folder and a `pubspec.yaml`
+ /// (assuming dependencies are fetched using the pub package manager).
+ ///
+ /// **Examples:** If `foo` is installed in pub-cache this would be:
+ /// * `/home/my_user/.pub-cache/hosted/pub.dev/foo-1.0.0/`
+ ///
+ /// See `rootUri` in the [specification for `package_config.json`][1],
+ /// for details.
+ ///
+ /// [1]: https://github.com/dart-lang/language/blob/main/accepted/2.8/language-versioning/package-config-file-v2.md
+ final Uri rootUri;
+
+ /// Path to the library import path relative to [rootUri].
+ ///
+ /// In Dart code the `package:<package>/<path>` will be resolved as
+ /// `<rootUri>/<packageUri>/<path>`.
+ ///
+ /// If dependencies are installed using `dart pub`, then this is
+ /// **always** `lib/`.
+ ///
+ /// See `packageUri` in the [specification for `package_config.json`][1],
+ /// for details.
+ ///
+ /// [1]: https://github.com/dart-lang/language/blob/main/accepted/2.8/language-versioning/package-config-file-v2.md
+ final Uri packageUri;
+
+ /// Contents of `extension/<targetPackage>/config.yaml` parsed as YAML and
+ /// converted to JSON compatible types.
+ ///
+ /// If parsing YAML from this file failed, then no [Extension] entry
+ /// will exist.
+ ///
+ /// This field is always a structure consisting of the following types:
+ /// * `null`,
+ /// * [bool] (`true` or `false`),
+ /// * [String],
+ /// * [num] ([int] or [double]),
+ /// * `List<Object?>`, and,
+ /// * `Map<String, Object?>`.
+ final Map<String, Object?> config;
+
+ Extension._({
+ required this.package,
+ required this.rootUri,
+ required this.packageUri,
+ required this.config,
+ });
+}
+
+/// Find extensions for [targetPackage] provided by packages in
+/// `.dart_tool/package_config.json`.
+///
+/// ## Locating `.dart_tool/package_config.json`
+///
+/// This method requires the location of the [packageConfig], unless the current
+/// isolate has been setup for package resolution.
+/// Notably, Dart programs compiled for AOT cannot find their own
+/// `package_config.json`.
+///
+/// If operating on a project that isn't the current project, for example, if
+/// you are developing a tool that users are globally activating and then
+/// running against their own projects, and you wish to detect extensions within
+/// their projects, then you must specify the path the
+/// `.dart_tool/package_config.json` for the users project as [packageConfig].
+///
+/// The [packageConfig] parameter must reference a file, absolute or
+/// relative-path, may use the `file://` scheme. This method throws, if
+/// [packageConfig] is not a valid [Uri] for a file-path.
+///
+/// ## Detection of extensions
+///
+/// An extension for [targetPackage] is detected in `package:foo` if `foo`
+/// contains `extension/<targetPackage>/config.yaml`, and the contents of this
+/// file is valid YAML, that can be represented as JSON.
+///
+/// ### Caching results
+///
+/// When [useCache] is `true` then the detected extensions will be cached
+/// in `.dart_tool/extension_discovery/<targetPackage>.json`.
+/// This function will compare modification timestamps of
+/// `.dart_tool/package_config.json` with the cache file, before reusing cached
+/// results.
+/// This function will also treat relative path-dependencies as mutable
+/// packages, and check such packages for extensions every time [findExtensions]
+/// is called. Notably, it'll compare the modification time of the
+/// `extension/<targetPackage>/config.yaml` file, to ensure that it's older than
+/// the extension cache file. Otherwise, it'll reload the extension
+/// configuration.
+///
+/// ## Exceptions
+///
+/// This method will throw [PackageConfigException], if the
+/// `.dart_tool/package_config.json` file specified in [packageConfig] could not
+/// be loaded or is invalid. This usually happens if dependencies are not
+/// resolved, and users can probably address it by running `dart pub get`.
+///
+/// But, **do consider catch** [PackageConfigException] and handling the failure
+/// to load extensions appropriately.
+///
+/// This method will throw an [Error] if [packageConfig] is not specified, and
+/// the current isolate isn't configured for package resolution.
+Future<List<Extension>> findExtensions(
+ String targetPackage, {
+ bool useCache = true,
+ Uri? packageConfig,
+}) async {
+ packageConfig ??= await Isolate.packageConfig;
+ if (packageConfig == null) {
+ throw UnsupportedError(
+ 'packageConfigUri must be provided, if not running in JIT mode',
+ );
+ }
+ if ((packageConfig.hasScheme && !packageConfig.isScheme('file')) ||
+ packageConfig.hasEmptyPath ||
+ packageConfig.hasFragment ||
+ packageConfig.hasPort ||
+ packageConfig.hasQuery) {
+ throw ArgumentError.value(
+ packageConfig,
+ 'packageConfig',
+ 'must be a file:// URI',
+ );
+ }
+ // Always normalize to an absolute URI
+ final packageConfigUri = File.fromUri(packageConfig).absolute.uri;
+
+ return await _findExtensions(
+ targetPackage: targetPackage,
+ useCache: useCache,
+ packageConfigUri: packageConfigUri,
+ );
+}
+
+/// Find extensions with normalized arguments.
+Future<List<Extension>> _findExtensions({
+ required String targetPackage,
+ required bool useCache,
+ required Uri packageConfigUri,
+}) async {
+ final packageConfigFile = File.fromUri(packageConfigUri);
+ final registryFile = File.fromUri(packageConfigFile.parent.uri.resolve(
+ 'extension_discovery/$targetPackage.json',
+ ));
+
+ Registry? registry;
+ final registryStat = registryFile.statSync();
+ if (registryStat.isFileOrLink && useCache) {
+ final packageConfigStat = packageConfigFile.statSync();
+ if (!packageConfigStat.isFileOrLink) {
+ throw packageConfigNotFound(packageConfigUri);
+ }
+ if (packageConfigStat.isPossiblyModifiedAfter(registryStat.modified)) {
+ await registryFile.tryDelete();
+ } else {
+ registry = await loadRegistry(registryFile);
+ }
+ }
+
+ final configFileName = 'extension/$targetPackage/config.yaml';
+ var registryUpdated = false;
+ if (registry != null) {
+ // Update mutable entries in registry
+ for (var i = 0; i < registry.length; i++) {
+ final p = registry[i];
+ if (p.rootUri.hasAbsolutePath) continue;
+
+ final rootUri = packageConfigUri.resolveUri(p.rootUri);
+ final configFile = File.fromUri(rootUri.resolve(configFileName));
+ final configStat = configFile.statSync();
+ if (configStat.isFileOrLink) {
+ if (configStat.isPossiblyModifiedAfter(registryStat.modified)) {
+ try {
+ registryUpdated = true;
+ registry[i] = (
+ package: p.package,
+ rootUri: p.rootUri,
+ packageUri: p.packageUri,
+ config: parseYamlFromConfigFile(await configFile.readAsString()),
+ );
+ continue;
+ } on FormatException {
+ // pass
+ } on IOException {
+ // pass
+ }
+ registryUpdated = true;
+ registry[i] = (
+ package: p.package,
+ rootUri: p.rootUri,
+ packageUri: p.packageUri,
+ config: null,
+ );
+ }
+ } else {
+ // If there is no file present, but registry says there is then we need
+ // to update the registry.
+ if (p.config != null) {
+ registryUpdated = true;
+ registry[i] = (
+ package: p.package,
+ rootUri: p.rootUri,
+ packageUri: p.packageUri,
+ config: null,
+ );
+ }
+ }
+ }
+ } else {
+ // Load packages from package_config.json
+ final packages = await loadPackageConfig(packageConfigFile);
+ registryUpdated = true;
+ registry = (await Future.wait(packages.map((p) async {
+ try {
+ final rootUri = packageConfigUri.resolveUri(p.rootUri);
+ final configFile = File.fromUri(rootUri.resolve(configFileName));
+ final configStat = configFile.statSync();
+ if (configStat.isFileOrLink) {
+ return (
+ package: p.name,
+ rootUri: p.rootUri,
+ packageUri: p.packageUri,
+ config: parseYamlFromConfigFile(await configFile.readAsString()),
+ );
+ }
+ } on FormatException {
+ // pass
+ } on IOException {
+ // pass
+ }
+ if (!p.rootUri.hasAbsolutePath) {
+ return (
+ package: p.name,
+ rootUri: p.rootUri,
+ packageUri: p.packageUri,
+ config: null,
+ );
+ }
+ return null;
+ })))
+ .whereType<RegistryEntry>()
+ .toList(growable: false);
+ }
+
+ // Save registry
+ if (registryUpdated && useCache) {
+ await saveRegistry(registryFile, registry);
+ }
+
+ return UnmodifiableListView(
+ registry
+ .where((e) => e.config != null)
+ .map((e) => Extension._(
+ package: e.package,
+ rootUri: packageConfigUri.resolveUri(e.rootUri),
+ packageUri: e.packageUri,
+ config: e.config!,
+ ))
+ .toList(growable: false),
+ );
+}
diff --git a/pkgs/extension_discovery/lib/src/expect_json.dart b/pkgs/extension_discovery/lib/src/expect_json.dart
new file mode 100644
index 0000000..c2784bc
--- /dev/null
+++ b/pkgs/extension_discovery/lib/src/expect_json.dart
@@ -0,0 +1,73 @@
+// Copyright (c) 2023, 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' show jsonDecode;
+
+Map<String, Object?> decodeJsonMap(String json) {
+ final root = jsonDecode(json);
+ if (root case Map<String, Object?> v) return v;
+ throw const FormatException('root must be a map');
+}
+
+extension ExpectJson on Map<String, Object?> {
+ bool expectBool(String key) {
+ if (this[key] case bool v) return v;
+ throw FormatException('The value at "$key" must be a bool:\n$toString()');
+ }
+
+ num expectNumber(String key) {
+ if (this[key] case num v) return v;
+ throw FormatException('The value at "$key" must be a number:\n$toString()');
+ }
+
+ String expectString(String key) {
+ if (this[key] case String v) return v;
+ throw FormatException('The value at "$key" must be a string:\n$toString()');
+ }
+
+ Uri expectUri(String key) {
+ try {
+ return Uri.parse(expectString(key));
+ } on FormatException {
+ throw FormatException('The value at "$key" must be a URI:\n$toString()');
+ }
+ }
+
+ Map<String, Object?> expectMap(String key) {
+ if (this[key] case Map<String, Object?> v) return v;
+ throw FormatException('The value at "$key" must be a map:\n$toString()');
+ }
+
+ Map<String, Object?>? optionalMap(String key) {
+ if (containsKey(key)) {
+ return expectMap(key);
+ }
+ return null;
+ }
+
+ Uri? optionalUri(String key) {
+ if (containsKey(key)) {
+ return expectUri(key);
+ }
+ return null;
+ }
+
+ List<Object?> expectList(String key) {
+ if (this[key] case List<Object?> v) return v;
+ throw FormatException('The value at "$key" must be a list:\n$toString()');
+ }
+
+ Iterable<Map<String, Object?>> expectListObjects(String key) sync* {
+ final list = expectList(key);
+ for (final entry in list) {
+ if (entry case Map<String, Object?> v) {
+ yield v;
+ } else {
+ throw FormatException(
+ 'The value at "$key" must be a list of map:\n$toString()',
+ );
+ }
+ }
+ }
+}
diff --git a/pkgs/extension_discovery/lib/src/io.dart b/pkgs/extension_discovery/lib/src/io.dart
new file mode 100644
index 0000000..9343ced
--- /dev/null
+++ b/pkgs/extension_discovery/lib/src/io.dart
@@ -0,0 +1,84 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io'
+ show
+ File,
+ FileStat,
+ FileSystemEntityType,
+ FileSystemException,
+ IOException,
+ Platform;
+
+const _maxAttempts = 20;
+
+/// When comparing modification timestamps of files to see if A is newer than B,
+/// such that data cached in A about B does not need to be recomputed, we
+/// required that A is at-least [modificationMaturityDelay] older than B.
+///
+/// This ensures that if `pub get` is racing with cache writing then we won't
+/// rely on the result.
+Duration modificationMaturityDelay = const Duration(seconds: 5);
+
+/// On windows some renaming files/folders recently created can be problematic
+/// as they may be locked by security scanning systems.
+///
+/// This function will retry [fn] a few times with a short delay, if running on
+/// Windows and the error appears to be related to permissions or file locking.
+Future<T> _attempt<T>(FutureOr<T> Function() fn) async {
+ if (!Platform.isWindows) {
+ return await fn();
+ }
+ var attempts = 0;
+ while (true) {
+ try {
+ await fn();
+ } on FileSystemException catch (e) {
+ attempts += 1;
+ if (attempts >= _maxAttempts) rethrow;
+
+ // Cargo culting error codes from:
+ // https://github.com/dart-lang/pub/blob/98565c3e5defcd80c59910795ba3548552102f2c/lib/src/io.dart#L419-L427
+ final code = e.osError?.errorCode;
+ if (code != 5 && code != 32) rethrow;
+
+ // Sleep a bit a try again.
+ await Future<void>.delayed(const Duration(milliseconds: 5));
+ }
+ }
+}
+
+extension FileExt on File {
+ /// Try to delete this file, ignore errors.
+ Future<void> tryDelete() async {
+ try {
+ await delete();
+ } on IOException {
+ // pass
+ }
+ }
+
+ Future<void> reliablyRename(String newPath) =>
+ _attempt(() => rename(newPath));
+}
+
+extension FileStatExt on FileStat {
+ /// Returns `false` if we're pretty certain that the current file was NOT
+ /// modified after [other].
+ ///
+ /// We do this by subtracting 5 seconds from [other], thus, making it more
+ /// likely that the current file was _possibly modified_ after [other].
+ ///
+ /// This, aims to ensure that file where modified within 5 seconds of
+ /// eachother then we don't trust the file modification stamps. This mostly
+ /// makes sense if someone is updating a file while we're writing the registry
+ /// cache file.
+ bool isPossiblyModifiedAfter(DateTime other) =>
+ modified.isAfter(other.subtract(modificationMaturityDelay));
+
+ /// True, if current [FileStat] is possibly a file (link or file)
+ bool get isFileOrLink =>
+ type == FileSystemEntityType.file || type == FileSystemEntityType.link;
+}
diff --git a/pkgs/extension_discovery/lib/src/package_config.dart b/pkgs/extension_discovery/lib/src/package_config.dart
new file mode 100644
index 0000000..f2eaffc
--- /dev/null
+++ b/pkgs/extension_discovery/lib/src/package_config.dart
@@ -0,0 +1,107 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io' show File, IOException;
+import 'expect_json.dart';
+
+typedef PackageConfigEntry = ({String name, Uri rootUri, Uri packageUri});
+typedef PackageConfig = List<PackageConfigEntry>;
+
+/// Searches in [packageDir] and all directories above for a
+/// `.dart_tool/package_config.json` file. Returns the Uri of that file if
+/// found.
+///
+/// Returns `null` if no file was found.
+Uri? findPackageConfig(Uri packageDir) {
+ if (!packageDir.isScheme('file')) {
+ throw ArgumentError(
+ 'Expected [packageDir] to be a file URI, got $packageDir',
+ );
+ }
+ if (!packageDir.path.endsWith('/')) {
+ packageDir = packageDir.replace(path: '${packageDir.path}/');
+ }
+ while (true) {
+ final packageConfigCandidate =
+ packageDir.resolve('.dart_tool/package_config.json');
+ try {
+ if (File.fromUri(packageConfigCandidate).existsSync()) {
+ return packageConfigCandidate;
+ }
+ } on IOException {
+ return null; // if we get a permission error, etc, we return null
+ }
+ final next = packageDir.resolve('..');
+ if (next == packageDir) return null;
+ packageDir = next;
+ }
+}
+
+/// Load list of packages and associated URIs from the
+/// `.dart_tool/package_config.json` file in [packageConfigFile].
+Future<PackageConfig> loadPackageConfig(
+ File packageConfigFile,
+) async {
+ try {
+ final packageConfig = decodeJsonMap(await packageConfigFile.readAsString());
+ if (packageConfig.expectNumber('configVersion') != 2) {
+ throw const FormatException('"configVersion" must be 2');
+ }
+ return packageConfig.expectListObjects('packages').map((p) {
+ final rootUri = p.expectUri('rootUri').asDirectory();
+ return (
+ name: p.expectString('name'),
+ rootUri: rootUri,
+ packageUri: p.optionalUri('packageUri')?.asDirectory() ?? rootUri,
+ );
+ }).toList();
+ } on IOException catch (e) {
+ if (!packageConfigFile.existsSync()) {
+ throw packageConfigNotFound(packageConfigFile.uri);
+ }
+ throw packageConfigIOException(e);
+ } on FormatException catch (e) {
+ throw packageConfigInvalid(packageConfigFile.uri, e);
+ }
+}
+
+/// Thrown, if the `.dart_tool/package_config.json` cannot be found or parsing
+/// it fails.
+///
+/// This could be because the `package_config.json` file is missing or simply
+/// invalid.
+///
+/// Mostly, this will happen if dependencies are not resolved, the solution is
+/// call `dart pub get`.
+final class PackageConfigException implements Exception {
+ final String message;
+ PackageConfigException._(this.message);
+
+ @override
+ String toString() => message;
+}
+
+PackageConfigException packageConfigNotFound(Uri packageConfigUri) =>
+ PackageConfigException._(
+ 'package_config.json not found at: "$packageConfigUri"',
+ );
+
+PackageConfigException packageConfigInvalid(
+ Uri packageConfigUri, FormatException e) =>
+ PackageConfigException._(
+ 'Invalid package_config.json found at "$packageConfigUri": $e',
+ );
+
+PackageConfigException packageConfigIOException(IOException e) =>
+ PackageConfigException._(
+ 'Failed to read package_config.json: $e',
+ );
+
+extension on Uri {
+ Uri asDirectory() => replace(
+ pathSegments: pathSegments.lastOrNull != ''
+ ? pathSegments.followedBy([''])
+ : pathSegments,
+ );
+}
diff --git a/pkgs/extension_discovery/lib/src/registry.dart b/pkgs/extension_discovery/lib/src/registry.dart
new file mode 100644
index 0000000..60efc75
--- /dev/null
+++ b/pkgs/extension_discovery/lib/src/registry.dart
@@ -0,0 +1,144 @@
+// Copyright (c) 2023, 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' show jsonEncode;
+import 'dart:io' show File, FileSystemEntityType, IOException;
+
+import 'expect_json.dart';
+import 'io.dart';
+
+// TODO: Convert the 'rootUri' reference below to a doc comment reference once
+// https://github.com/dart-lang/linter/issues/4645 is addressed.
+
+/// Entry in the `.dart_tool/extension_discovery/<package>.json` file.
+///
+/// If the `rootUri` is not an absolute path, then we will assume that the
+/// package is mutable (either it's the root package or a path dependency).
+/// If there is no extension config file for a mutable package, then we will
+/// still store a [RegistryEntry] with `config = null`. Because everytime we
+/// load the registry, we still need to check if a configuration file has been
+/// added to the mutable package.
+typedef RegistryEntry = ({
+ String package,
+ Uri rootUri,
+ Uri packageUri,
+ Map<String, Object?>? config,
+});
+
+typedef Registry = List<RegistryEntry>;
+
+Future<Registry?> loadRegistry(File registryFile) async {
+ try {
+ final registryJson = decodeJsonMap(await registryFile.readAsString());
+ if (registryJson.expectNumber('version') != 2) {
+ throw const FormatException('"version" must be 2');
+ }
+ return registryJson
+ .expectListObjects('entries')
+ .map((e) => (
+ package: e.expectString('package'),
+ rootUri: e.expectUri('rootUri'),
+ packageUri: e.expectUri('packageUri'),
+ config: e.optionalMap('config'),
+ ))
+ .toList(growable: false);
+ } on IOException {
+ return null; // pass
+ } on FormatException {
+ await registryFile.tryDelete();
+ return null;
+ }
+}
+
+Future<void> saveRegistry(
+ File registryFile,
+ Registry registry,
+) async {
+ try {
+ if (!registryFile.parent.existsSync()) {
+ await registryFile.parent.create();
+ }
+ final tmpFile = File('${registryFile.path}.tmp');
+ final tmpFileStat = tmpFile.statSync();
+ if (tmpFileStat.type != FileSystemEntityType.notFound) {
+ final tmpAge = DateTime.now().difference(tmpFileStat.modified);
+ if (tmpAge.inSeconds < 5) {
+ // Don't try to write registry, if there is an abandoned temporary file
+ // no older than 5 seconds. Otherwise, we could have race conditions!
+ // Note: That saving the registry is a performance improvement, not a
+ // strict necessity!
+ return;
+ } else {
+ await tmpFile.delete();
+ }
+ }
+
+ await tmpFile.writeAsString(jsonEncode({
+ 'version': 2,
+ 'entries': registry
+ .map((e) => {
+ 'package': e.package,
+ 'rootUri': e.rootUri.toString(),
+ 'packageUri': e.packageUri.toString(),
+ if (e.config != null) 'config': e.config,
+ })
+ .toList(),
+ }));
+ await tmpFile.reliablyRename(registryFile.path);
+ await _ensureReadme(
+ File.fromUri(registryFile.parent.uri.resolve('README.md')),
+ );
+ } on IOException {
+ // pass
+ }
+}
+
+Future<void> _ensureReadme(File readmeFile) async {
+ try {
+ final stat = readmeFile.statSync();
+ if (stat.type != FileSystemEntityType.notFound) {
+ final age = DateTime.now().difference(stat.modified);
+ if (age.inDays < 5) {
+ return; // don't update README.md, if it's less than 5 days old
+ }
+ }
+ await readmeFile.writeAsString(_readmeContents);
+ } on IOException {
+ // pass
+ }
+}
+
+const _readmeContents = '''
+Extension Discovery Cache
+=========================
+
+This folder is used by `package:extension_discovery` to cache lists of
+packages that contains extensions for other packages.
+
+DO NOT USE THIS FOLDER
+----------------------
+
+ * Do not read (or rely) the contents of this folder.
+ * Do write to this folder.
+
+If you're interested in the lists of extensions stored in this folder use the
+API offered by package `extension_discovery` to get this information.
+
+If this package doesn't work for your use-case, then don't try to read the
+contents of this folder. It may change, and will not remain stable.
+
+Use package `extension_discovery`
+---------------------------------
+
+If you want to access information from this folder.
+
+Feel free to delete this folder
+-------------------------------
+
+Files in this folder act as a cache, and the cache is discarded if the files
+are older than the modification time of `.dart_tool/package_config.json`.
+
+Hence, it should never be necessary to clear this cache manually, if you find a
+need to do please file a bug.
+''';
diff --git a/pkgs/extension_discovery/lib/src/yaml_config_format.dart b/pkgs/extension_discovery/lib/src/yaml_config_format.dart
new file mode 100644
index 0000000..a28b31b
--- /dev/null
+++ b/pkgs/extension_discovery/lib/src/yaml_config_format.dart
@@ -0,0 +1,85 @@
+// Copyright (c) 2023, 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.
+
+/// Utilities for loading and validating YAML from a config file.
+///
+/// When writing YAML config files it's often preferable to force a few
+/// constraints on the YAML files. Specifically:
+/// * Root value must be a map.
+/// * No anchors / aliases, this can't be represented in JSON and
+/// can be used to created cycles, which might crash someone trying to
+/// serialize the data as JSON.
+/// * Maps can only have string keys.
+///
+/// Basically, only allow value that can't be represented in JSON.
+///
+/// This library aims to provide a [parseYamlFromConfigFile] that throws
+/// a [FormatException] when parsing YAML files that doesn't satisfy this
+/// constraint.
+library;
+
+import 'package:yaml/yaml.dart'
+ show YamlList, YamlMap, YamlNode, YamlScalar, loadYamlNode;
+
+/// Parse YAML from a config file.
+///
+/// This will validate that:
+/// * Maps only have string keys.
+/// * Anchor and aliases are not used (to avoid cycles).
+/// * Values can be represented as JSON.
+/// * Root node is a map.
+///
+/// Throw will throw [FormatException], if the [yamlString] does not satisfy
+/// constraints above.
+///
+/// Returns a structure consisting of the following types:
+/// * `null`,
+/// * [bool] (`true` or `false`),
+/// * [String],
+/// * [num] ([int] or [double]),
+/// * `List<Object?>`, and,
+/// * `Map<String, Object?>`.
+Map<String, Object?> parseYamlFromConfigFile(String yamlString) {
+ final visited = <YamlNode>{};
+ Object? toPlainType(YamlNode n) {
+ if (!visited.add(n)) {
+ throw const FormatException(
+ 'Anchors/aliases are not supported in YAML config files',
+ );
+ }
+ if (n is YamlScalar) {
+ return switch (n.value) {
+ null => null,
+ String s => s,
+ num n => n,
+ bool b => b,
+ _ => throw const FormatException(
+ 'Only null, string, number, bool, map and lists are supported '
+ 'in YAML config files',
+ ),
+ };
+ }
+ if (n is YamlList) {
+ return n.nodes.map(toPlainType).toList();
+ }
+ if (n is YamlMap) {
+ return n.nodes.map((key, value) {
+ final k = toPlainType(key as YamlNode);
+ if (k is! String) {
+ throw const FormatException(
+ 'Only string keys are allowed in YAML config files',
+ );
+ }
+ return MapEntry(k, toPlainType(value));
+ });
+ }
+ throw UnsupportedError('Unknown YamlNode: $n');
+ }
+
+ final value = toPlainType(loadYamlNode(yamlString));
+ if (value is! Map<String, Object?>) {
+ throw const FormatException('The root of a YAML config file must be a map');
+ }
+ return value;
+}
diff --git a/pkgs/extension_discovery/pubspec.yaml b/pkgs/extension_discovery/pubspec.yaml
new file mode 100644
index 0000000..05acdbd
--- /dev/null
+++ b/pkgs/extension_discovery/pubspec.yaml
@@ -0,0 +1,17 @@
+name: extension_discovery
+description: >-
+ A convention and utilities for package extension discovery.
+version: 2.1.0
+repository: https://github.com/dart-lang/tools/tree/main/pkgs/extension_discovery
+
+environment:
+ sdk: ^3.4.0
+
+dependencies:
+ yaml: ^3.0.0
+
+dev_dependencies:
+ collection: ^1.18.0
+ dart_flutter_team_lints: ^3.0.0
+ test: ^1.21.0
+ test_descriptor: ^2.0.1
diff --git a/pkgs/extension_discovery/test/find_extensions_test.dart b/pkgs/extension_discovery/test/find_extensions_test.dart
new file mode 100644
index 0000000..33e8bf7
--- /dev/null
+++ b/pkgs/extension_discovery/test/find_extensions_test.dart
@@ -0,0 +1,350 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:isolate' show Isolate;
+
+import 'package:extension_discovery/extension_discovery.dart';
+import 'package:extension_discovery/src/io.dart';
+import 'package:test/test.dart';
+
+import 'test_descriptor.dart' as d;
+
+void main() {
+ test('findExtensions', () async {
+ // Override the maturity delay for reliable testing of caching logic.
+ modificationMaturityDelay = const Duration(milliseconds: 500);
+
+ final pkgLibDir = await Isolate.resolvePackageUri(
+ Uri.parse('package:extension_discovery/'),
+ );
+ final pkgDir = pkgLibDir!.resolve('..');
+
+ await d.dir('myapp', [
+ d.pubspec({
+ 'name': 'myapp',
+ 'dependencies': {
+ 'extension_discovery': {'path': pkgDir.toFilePath()},
+ },
+ 'environment': {'sdk': '^3.0.0'},
+ }),
+ ]).create();
+
+ // Get dependencies
+ await d.dartPubGet(d.path('myapp'));
+
+ // Check that we don't find any extensions
+ expect(
+ await findExtensions(
+ 'myapp',
+ packageConfig: d.fileUri('myapp/.dart_tool/package_config.json'),
+ ),
+ isEmpty);
+
+ // Check that there is a myapp.json cache file
+ await d
+ .file(
+ 'myapp/.dart_tool/extension_discovery/myapp.json',
+ isNotEmpty,
+ )
+ .validate();
+
+ // ################################## Create foo that provides extension
+ await d.dir('foo', [
+ d.pubspec({
+ 'name': 'foo',
+ 'environment': {'sdk': '^3.0.0'},
+ }),
+ // It has a config.yaml for myapp
+ d.dir('extension/myapp', [
+ d.json('config.yaml', {'fromFoo': true}),
+ ]),
+ ]).create();
+
+ // Update the pubspec.yaml with a dependency on foo
+ await d.dir('myapp', [
+ d.pubspec({
+ 'name': 'myapp',
+ 'dependencies': {
+ 'extension_discovery': {'path': pkgDir.toFilePath()},
+ 'foo': {'path': '../foo'},
+ },
+ 'environment': {'sdk': '^3.0.0'},
+ }),
+ ]).create();
+
+ // Get dependencies
+ await d.dartPubGet(d.path('myapp'));
+
+ // Check that we do find an extension
+ {
+ final ext = await findExtensions(
+ 'myapp',
+ packageConfig: d.fileUri('myapp/.dart_tool/package_config.json'),
+ );
+ expect(ext, isNotEmpty);
+ expect(
+ ext.any(
+ (e) =>
+ e.package == 'foo' &&
+ e.rootUri == d.directoryUri('foo/') &&
+ e.packageUri == Uri.parse('lib/') &&
+ e.config['fromFoo'] == true,
+ ),
+ isTrue,
+ );
+ }
+
+ // ################################## Modify the config
+ await d.json('foo/extension/myapp/config.yaml', {'fromFoo': 42}).create();
+
+ // Check that we do find an extension
+ {
+ final ext = await findExtensions(
+ 'myapp',
+ packageConfig: d.fileUri('myapp/.dart_tool/package_config.json'),
+ );
+ expect(ext, isNotEmpty);
+ expect(
+ ext.any(
+ (e) =>
+ e.package == 'foo' &&
+ e.rootUri == d.directoryUri('foo/') &&
+ e.packageUri == Uri.parse('lib/') &&
+ e.config['fromFoo'] == 42,
+ ),
+ isTrue,
+ );
+ }
+
+ // ################################## Make config invalid
+ await d.file('foo/extension/myapp/config.yaml', 'invalid YAML').create();
+
+ // Check that we do not find extensions
+ {
+ final ext = await findExtensions(
+ 'myapp',
+ packageConfig: d.fileUri('myapp/.dart_tool/package_config.json'),
+ );
+ expect(ext, isEmpty);
+ }
+
+ // ################################## Make config valid again
+ await d.json('foo/extension/myapp/config.yaml', {'fromFoo': true}).create();
+
+ // Check that we do find extensions
+ {
+ final ext = await findExtensions(
+ 'myapp',
+ packageConfig: d.fileUri('myapp/.dart_tool/package_config.json'),
+ );
+ expect(ext, isNotEmpty);
+ }
+
+ // ################################## Remove config file
+ await d.file('foo/extension/myapp/config.yaml').io.delete();
+ // Check that we do not find extensions
+ {
+ final ext = await findExtensions(
+ 'myapp',
+ packageConfig: d.fileUri('myapp/.dart_tool/package_config.json'),
+ );
+ expect(ext, isEmpty);
+ }
+
+ // ################################## Make config valid again
+ await d.json('foo/extension/myapp/config.yaml', {'fromFoo': true}).create();
+
+ // Check that we do find extensions
+ {
+ final ext = await findExtensions(
+ 'myapp',
+ packageConfig: d.fileUri('myapp/.dart_tool/package_config.json'),
+ );
+ expect(ext, isNotEmpty);
+ }
+
+ // ################################## Create bar as absolute path-dep
+ await d.dir('bar', [
+ d.pubspec({
+ 'name': 'bar',
+ 'environment': {'sdk': '^3.0.0'},
+ }),
+ // It has a config.yaml for myapp
+ d.dir('extension/myapp', [
+ d.json('config.yaml', {'fromFoo': false}),
+ ]),
+ ]).create();
+
+ // Update the pubspec.yaml with a dependency on foo
+ await d.dir('myapp', [
+ d.pubspec({
+ 'name': 'myapp',
+ 'dependencies': {
+ 'extension_discovery': {'path': pkgDir.toFilePath()},
+ 'foo': {'path': '../foo'},
+ 'bar': {'path': d.path('bar')},
+ },
+ 'environment': {'sdk': '^3.0.0'},
+ }),
+ ]).create();
+
+ // We won't find bar without running `dart pub get`
+ {
+ final ext = await findExtensions(
+ 'myapp',
+ packageConfig: d.fileUri('myapp/.dart_tool/package_config.json'),
+ );
+ expect(ext.any((e) => e.package == 'bar'), isFalse);
+ }
+
+ // Get dependencies
+ await d.dartPubGet(d.path('myapp'));
+
+ // Check that we do find both extensions
+ {
+ final ext = await findExtensions(
+ 'myapp',
+ packageConfig: d.fileUri('myapp/.dart_tool/package_config.json'),
+ );
+ expect(ext, isNotEmpty);
+ expect(
+ ext.any(
+ (e) =>
+ e.package == 'foo' &&
+ e.rootUri == d.directoryUri('foo/') &&
+ e.packageUri == Uri.parse('lib/') &&
+ e.config['fromFoo'] == true,
+ ),
+ isTrue,
+ );
+ expect(
+ ext.any(
+ (e) =>
+ e.package == 'bar' &&
+ e.rootUri == d.directoryUri('bar/') &&
+ e.packageUri == Uri.parse('lib/') &&
+ e.config['fromFoo'] == false,
+ ),
+ isTrue,
+ );
+ }
+
+ // ################################## Changes to bar are not detected
+
+ // Ensure that we wait long enough for the cache to be trusted,
+ // this delay is to make sure that the logic we have handling races isn't
+ // triggered. Think of it as waiting...
+ // If the modification time of package_config.json and the cache is no more
+ // than [modificationMaturityDelay] time apart, we'll ignore the cache.
+ // Under the assumption that there was a tiny risk of a race condition.
+ await Future<void>.delayed(modificationMaturityDelay * 2);
+ // Ensure that we have a cache value!
+ await findExtensions(
+ 'myapp',
+ packageConfig: d.fileUri('myapp/.dart_tool/package_config.json'),
+ );
+
+ // Delete config from package that has an absolute path, hence, a package
+ // we assume to be immutable.
+ await d.file('bar/extension/myapp/config.yaml').io.delete();
+
+ // Check that we do find both extensions
+ {
+ final ext = await findExtensions(
+ 'myapp',
+ packageConfig: d.fileUri('myapp/.dart_tool/package_config.json'),
+ );
+ expect(ext.any((e) => e.package == 'foo'), isTrue);
+ // This is the wrong result, but it is expected. Essentially, if we expect
+ // that if you have packages in package_config.json using an absolute path
+ // then these won't be modified. If you do modify the
+ // extension/<targetPackage>/config.yaml
+ // file, then the cache will give the wrong result. The workaround is to
+ // touch `package_config.json`, or run `dart pub get` (essentially).
+ expect(ext.any((e) => e.package == 'bar'), isTrue);
+ }
+
+ // Get dependencies
+ await d.dartPubGet(d.path('myapp'));
+
+ // We won't find bar after `dart pub get`, because we removed the config
+ {
+ final ext = await findExtensions(
+ 'myapp',
+ packageConfig: d.fileUri('myapp/.dart_tool/package_config.json'),
+ );
+ expect(ext.any((e) => e.package == 'foo'), isTrue);
+ expect(ext.any((e) => e.package == 'bar'), isFalse);
+ }
+
+ // ################################## Sanity check bar and foo
+ expect(
+ await findExtensions(
+ 'foo',
+ packageConfig: d.fileUri('myapp/.dart_tool/package_config.json'),
+ ),
+ isEmpty,
+ );
+ expect(
+ await findExtensions(
+ 'bar',
+ packageConfig: d.fileUri('myapp/.dart_tool/package_config.json'),
+ ),
+ isEmpty,
+ );
+
+ // ################################## What if foo has extensions for bar
+ await d.dir('foo/extension/bar', [
+ d.json('config.yaml', {'fromFoo': true}),
+ ]).create();
+
+ {
+ final ext = await findExtensions(
+ 'bar',
+ packageConfig: d.fileUri('myapp/.dart_tool/package_config.json'),
+ );
+ expect(ext.any((e) => e.package == 'foo'), isTrue);
+ expect(ext.any((e) => e.package == 'bar'), isFalse);
+ expect(ext.any((e) => e.package == 'myapp'), isFalse);
+ }
+
+ // ################################## myapp could also extend bar
+ await d.dir('myapp/extension/bar', [
+ d.json('config.yaml', {'fromFoo': false}),
+ ]).create();
+
+ {
+ final ext = await findExtensions(
+ 'bar',
+ packageConfig: d.fileUri('myapp/.dart_tool/package_config.json'),
+ );
+ expect(ext.any((e) => e.package == 'foo'), isTrue);
+ expect(ext.any((e) => e.package == 'bar'), isFalse);
+ expect(ext.any((e) => e.package == 'myapp'), isTrue);
+ }
+
+ // ################################## config could also be written in YAML
+ await d.dir('myapp/extension/bar', [
+ d.file('config.yaml', '''
+writtenAsYaml: true
+'''),
+ ]).create();
+
+ {
+ final ext = await findExtensions(
+ 'bar',
+ packageConfig: d.fileUri('myapp/.dart_tool/package_config.json'),
+ );
+ expect(ext.any((e) => e.package == 'foo'), isTrue);
+ expect(ext.any((e) => e.package == 'bar'), isFalse);
+ expect(ext.any((e) => e.package == 'myapp'), isTrue);
+ expect(
+ ext.any(
+ (e) => e.package == 'myapp' && e.config['writtenAsYaml'] == true,
+ ),
+ isTrue,
+ );
+ }
+ });
+}
diff --git a/pkgs/extension_discovery/test/integration_test.dart b/pkgs/extension_discovery/test/integration_test.dart
new file mode 100644
index 0000000..ec52265
--- /dev/null
+++ b/pkgs/extension_discovery/test/integration_test.dart
@@ -0,0 +1,134 @@
+// Copyright (c) 2023, 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' show jsonDecode;
+import 'dart:isolate' show Isolate;
+
+import 'package:test/test.dart';
+
+import 'test_descriptor.dart' as d;
+
+typedef Ext = ({
+ String package,
+ String rootUri,
+ String packageUri,
+ dynamic config
+});
+
+void main() {
+ test('findExtensions', () async {
+ final pkgLibDir = await Isolate.resolvePackageUri(
+ Uri.parse('package:extension_discovery/'),
+ );
+ final pkgDir = pkgLibDir!.resolve('..');
+
+ await d.dir('myapp', [
+ d.pubspec({
+ 'name': 'myapp',
+ 'dependencies': {
+ 'extension_discovery': {'path': pkgDir.toFilePath()},
+ },
+ 'environment': {'sdk': '^3.0.0'},
+ }),
+ d.dir('bin', [
+ d.file('find_extensions.dart', '''
+import 'dart:convert' show JsonEncoder;
+import 'package:extension_discovery/extension_discovery.dart';
+
+Future<void> main(List<String> args) async {
+ final extensions = await findExtensions(args.first);
+ print(JsonEncoder.withIndent(' ').convert([
+ for (final e in extensions)
+ {
+ 'package': e.package,
+ 'rootUri': e.rootUri.toString(),
+ 'packageUri': e.packageUri.toString(),
+ 'config': e.config,
+ },
+ ]));
+}
+ '''),
+ ])
+ ]).create();
+
+ Future<List<Ext>> findExtensionsInSandbox(String target) async {
+ final out = await d.dart(
+ d.path('myapp/bin/find_extensions.dart'),
+ target,
+ );
+ return (jsonDecode(out) as List<Object?>)
+ .cast<Map>()
+ .map((e) => (
+ package: e['package'] as String,
+ rootUri: e['rootUri'] as String,
+ packageUri: e['packageUri'] as String,
+ config: e['config'],
+ ))
+ .toList();
+ }
+
+ // Get dependencies
+ await d.dartPubGet(d.path('myapp'));
+
+ // Check that we don't find any extensions
+ expect(await findExtensionsInSandbox('myapp'), isEmpty);
+
+ // Check that there is a myapp.json cache file
+ await d
+ .file(
+ 'myapp/.dart_tool/extension_discovery/myapp.json',
+ isNotEmpty,
+ )
+ .validate();
+
+ // Check that there is README.md
+ await d
+ .file(
+ 'myapp/.dart_tool/extension_discovery/README.md',
+ isNotEmpty,
+ )
+ .validate();
+
+ // Create a foo package
+ await d.dir('foo', [
+ d.pubspec({
+ 'name': 'foo',
+ 'environment': {'sdk': '^3.0.0'},
+ }),
+ // It has a config.yaml for myapp
+ d.dir('extension/myapp', [
+ d.json('config.yaml', {'fromFoo': true}),
+ ]),
+ ]).create();
+
+ // Update the pubspec.yaml with a dependency on foo
+ await d.dir('myapp', [
+ d.pubspec({
+ 'name': 'myapp',
+ 'dependencies': {
+ 'extension_discovery': {'path': pkgDir.toFilePath()},
+ 'foo': {'path': '../foo'},
+ },
+ 'environment': {'sdk': '^3.0.0'},
+ }),
+ ]).create();
+
+ // Get dependencies
+ await d.dartPubGet(d.path('myapp'));
+
+ // Check that we do find an extension
+ final ext = await findExtensionsInSandbox('myapp');
+ expect(ext, isNotEmpty);
+ expect(
+ ext.any(
+ (e) =>
+ e.package == 'foo' &&
+ e.rootUri == d.directoryUri('foo/').toString() &&
+ e.packageUri == Uri.parse('lib/').toString() &&
+ (e.config as Map)['fromFoo'] == true,
+ ),
+ isTrue,
+ );
+ });
+}
diff --git a/pkgs/extension_discovery/test/package_config_test.dart b/pkgs/extension_discovery/test/package_config_test.dart
new file mode 100644
index 0000000..83c6c4d
--- /dev/null
+++ b/pkgs/extension_discovery/test/package_config_test.dart
@@ -0,0 +1,192 @@
+// Copyright (c) 2023, 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' show jsonDecode, jsonEncode;
+
+import 'package:extension_discovery/src/package_config.dart';
+import 'package:test/test.dart';
+
+import 'test_descriptor.dart' as d;
+
+void main() {
+ test('loadPackageConfig', () async {
+ await d.dir('myapp', [
+ d.pubspec({
+ 'name': 'myapp',
+ 'dependencies': {},
+ 'environment': {'sdk': '^3.0.0'},
+ }),
+ ]).create();
+
+ final packageConfigFile = d.file('myapp/.dart_tool/package_config.json').io;
+
+ // Loading before `dart pub get` throws PackageConfigException
+ expect(
+ loadPackageConfig(packageConfigFile),
+ throwsA(isA<PackageConfigException>()),
+ );
+
+ // Get dependencies
+ await d.dartPubGet(d.path('myapp'));
+
+ // Parse package_config
+ {
+ final packages = await loadPackageConfig(packageConfigFile);
+ expect(packages, isNotEmpty);
+ expect(packages.any((p) => p.name == 'myapp'), isTrue);
+ expect(packages.any((p) => p.name == 'foo'), isFalse);
+ expect(packages.any((p) => p.name == 'bar'), isFalse);
+ }
+
+ // ################################## Create foo as relative path-dep
+ await d.dir('foo', [
+ d.pubspec({
+ 'name': 'foo',
+ 'environment': {'sdk': '^3.0.0'},
+ }),
+ ]).create();
+
+ // Update the pubspec.yaml with a dependency on foo
+ await d.dir('myapp', [
+ d.pubspec({
+ 'name': 'myapp',
+ 'dependencies': {
+ 'foo': {'path': '../foo'},
+ },
+ 'environment': {'sdk': '^3.0.0'},
+ }),
+ ]).create();
+
+ // Get dependencies
+ await d.dartPubGet(d.path('myapp'));
+
+ // Parse package_config
+ {
+ final packages = await loadPackageConfig(packageConfigFile);
+ expect(packages, isNotEmpty);
+ expect(packages.any((p) => p.name == 'myapp'), isTrue);
+ expect(packages.any((p) => p.name == 'foo'), isTrue);
+ expect(packages.any((p) => p.name == 'bar'), isFalse);
+ }
+
+ // ################################## Create bar as absolute path-dep
+
+ await d.dir('bar', [
+ d.pubspec({
+ 'name': 'bar',
+ 'environment': {'sdk': '^3.0.0'},
+ }),
+ ]).create();
+
+ // Update the pubspec.yaml with a dependency on foo
+ await d.dir('myapp', [
+ d.pubspec({
+ 'name': 'myapp',
+ 'dependencies': {
+ 'foo': {'path': '../foo'},
+ 'bar': {'path': d.path('bar')},
+ },
+ 'environment': {'sdk': '^3.0.0'},
+ }),
+ ]).create();
+
+ // Get dependencies
+ await d.dartPubGet(d.path('myapp'));
+
+ // Parse package_config
+ {
+ final packages = await loadPackageConfig(packageConfigFile);
+ expect(packages, isNotEmpty);
+ expect(packages.any((p) => p.name == 'myapp'), isTrue);
+ expect(packages.any((p) => p.name == 'foo'), isTrue);
+ expect(packages.any((p) => p.name == 'bar'), isTrue);
+ }
+
+ // ################################## Cannot read version 99
+
+ {
+ final pkgcfg = jsonDecode(packageConfigFile.readAsStringSync()) as Map;
+ pkgcfg['configVersion'] = 99;
+ packageConfigFile.writeAsStringSync(jsonEncode(pkgcfg));
+ }
+
+ // Loading before `dart pub get` throws PackageConfigException
+ expect(
+ loadPackageConfig(packageConfigFile),
+ throwsA(isA<PackageConfigException>()),
+ );
+
+ // ################################## packageUri is optional
+
+ // Get dependencies
+ await d.dartPubGet(d.path('myapp'));
+
+ {
+ final pkgcfg = jsonDecode(packageConfigFile.readAsStringSync()) as Map;
+ for (final p in pkgcfg['packages'] as List) {
+ (p as Map).remove('packageUri');
+ }
+ packageConfigFile.writeAsStringSync(jsonEncode(pkgcfg));
+ }
+
+ // Parse package_config
+ {
+ final packages = await loadPackageConfig(packageConfigFile);
+ expect(packages, isNotEmpty);
+ expect(packages.any((p) => p.name == 'myapp'), isTrue);
+ expect(packages.any((p) => p.name == 'foo'), isTrue);
+ expect(packages.any((p) => p.name == 'bar'), isTrue);
+ expect(packages.every((p) => p.rootUri == p.packageUri), isTrue);
+ }
+
+ // ################################## packageUri is optional
+
+ // Get dependencies
+ await d.dartPubGet(d.path('myapp'));
+
+ {
+ final pkgcfg = jsonDecode(packageConfigFile.readAsStringSync()) as Map;
+ for (final p in pkgcfg['packages'] as List) {
+ (p as Map).remove('rootUri');
+ }
+ packageConfigFile.writeAsStringSync(jsonEncode(pkgcfg));
+ }
+
+ // Loading before `dart pub get` throws PackageConfigException
+ expect(
+ loadPackageConfig(packageConfigFile),
+ throwsA(isA<PackageConfigException>()),
+ );
+ });
+
+ test('`findPackageConfig()`', () async {
+ await d.dir('workspace', [
+ d.dir('.dart_tool', [
+ d.file('package_config.json'),
+ ]),
+ d.dir('myapp', [])
+ ]).create();
+
+ expect(
+ findPackageConfig(d.fileUri('workspace')),
+ d.fileUri('workspace/.dart_tool/package_config.json'),
+ );
+ expect(
+ findPackageConfig(d.fileUri('workspace/')),
+ d.fileUri('workspace/.dart_tool/package_config.json'),
+ );
+ expect(
+ findPackageConfig(d.fileUri('workspace/myapp')),
+ d.fileUri('workspace/.dart_tool/package_config.json'),
+ );
+ expect(
+ findPackageConfig(d.fileUri('.')),
+ isNull,
+ );
+ expect(
+ findPackageConfig(d.fileUri('foo')),
+ isNull,
+ );
+ });
+}
diff --git a/pkgs/extension_discovery/test/test_descriptor.dart b/pkgs/extension_discovery/test/test_descriptor.dart
new file mode 100644
index 0000000..0bd4a63
--- /dev/null
+++ b/pkgs/extension_discovery/test/test_descriptor.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2023, 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' show JsonEncoder;
+import 'dart:io' show Platform, Process;
+
+import 'package:test/test.dart';
+import 'package:test_descriptor/test_descriptor.dart' as d;
+export 'package:test_descriptor/test_descriptor.dart';
+
+d.FileDescriptor json(String fileName, Object? json) =>
+ d.file(fileName, const JsonEncoder.withIndent(' ').convert(json));
+
+d.FileDescriptor pubspec(Map<String, Object?> pubspec) =>
+ json('pubspec.yaml', pubspec);
+
+Uri fileUri(String path) => Uri.file(d.path(path));
+Uri directoryUri(String path) => Uri.directory(d.path(path));
+
+Future<String> dart([
+ String? arg1,
+ String? arg2,
+ String? arg3,
+ String? arg4,
+ String? arg5,
+ String? arg6,
+ String? arg7,
+ String? arg8,
+]) async {
+ final arguments = [
+ if (arg1 != null) arg1,
+ if (arg2 != null) arg2,
+ if (arg3 != null) arg3,
+ if (arg4 != null) arg4,
+ if (arg5 != null) arg5,
+ if (arg6 != null) arg6,
+ if (arg7 != null) arg7,
+ if (arg8 != null) arg8,
+ ];
+ final result = await Process.run(
+ Platform.executable,
+ arguments,
+ workingDirectory: d.sandbox,
+ );
+ if (result.exitCode != 0) {
+ print(result.stderr);
+ print(result.stdout);
+ }
+ expect(result.exitCode, 0,
+ reason: 'failed executing "dart ${arguments.join(' ')}"');
+ return result.stdout as String;
+}
+
+Future<String> dartPubGet(String folder) async =>
+ await dart('pub', 'get', '-C', folder);
diff --git a/pkgs/extension_discovery/test/yaml_config_format_test.dart b/pkgs/extension_discovery/test/yaml_config_format_test.dart
new file mode 100644
index 0000000..0e3f568
--- /dev/null
+++ b/pkgs/extension_discovery/test/yaml_config_format_test.dart
@@ -0,0 +1,149 @@
+// Copyright (c) 2023, 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:collection/collection.dart' show DeepCollectionEquality;
+
+import 'package:extension_discovery/src/yaml_config_format.dart';
+import 'package:test/test.dart';
+
+void _testInvalid(String name, String yaml, {String match = ''}) {
+ test(name, () {
+ expect(
+ () => parseYamlFromConfigFile(yaml),
+ throwsA(isFormatException.having(
+ (e) => e.message,
+ 'message',
+ contains(match),
+ )),
+ );
+ });
+}
+
+void _testValid(String name, String yaml) {
+ test(name, () {
+ parseYamlFromConfigFile(yaml);
+ });
+}
+
+void main() {
+ group('parseYamlFromConfigFile', () {
+ group('root must be a map', () {
+ _testInvalid('empty string', '', match: 'map');
+ _testInvalid('null', 'null', match: 'map');
+ _testInvalid('list', '[]', match: 'map');
+ _testInvalid('number (1)', '42', match: 'map');
+ _testInvalid('number (2)', '42.2', match: 'map');
+ _testInvalid('bool (1)', 'true', match: 'map');
+ _testInvalid('bool (2)', 'false', match: 'map');
+ _testInvalid('string', '"hello world"', match: 'map');
+ });
+
+ _testInvalid('must not have alias', match: 'alias', '''
+ keyA: &myref
+ - value 1
+ - value 2
+ KeyB: *myref
+ ''');
+
+ // it works without aliases
+ _testValid('listed inside a map is fine', '''
+ keyA:
+ - value 1
+ - value 2
+ KeyB:
+ - value 1
+ - value 2
+ ''');
+
+ _testValid('comments are cool', '''
+ keyA:
+ - value 1 # this is fine
+ - value 2
+ ''');
+
+ _testInvalid(
+ 'Top-level map with integer keys is not allowed', match: 'key', '''
+ 42: "value" # this is NOT fine
+ 43: true
+ ''');
+
+ _testValid('Map with quoted integer keys is fine', '''
+ "42": "value" # this is fine
+ '43': true
+ ''');
+
+ _testInvalid('Map with integer keys is not allowed', match: 'key', '''
+ keyA:
+ - value 1 # this is fine
+ - value 2
+ KeyB:
+ 42: value 3 # this is NOT fine
+ ''');
+
+ _testInvalid('Map with list keys is not allowed', match: 'key', '''
+ keyA:
+ - [1, 2, 3] # this is fine, crazy but fine!
+ keyB:
+ [1, 2, 3]: value 3 # this is NOT fine
+ ''');
+
+ _testInvalid('Map with boolean keys is not allowed (1)', match: 'key', '''
+ keyA: true
+ keyB:
+ true: value 3 # this is NOT fine
+ ''');
+
+ _testInvalid('Map with boolean keys is not allowed (2)', match: 'key', '''
+ keyA: true
+ keyB:
+ false: value 3 # this is NOT fine
+ ''');
+
+ _testInvalid('Map with null keys is not allowed', match: 'key', '''
+ keyA: null # fine
+ keyB:
+ null: value 3 # this is NOT fine
+ ''');
+
+ _testValid('complex structures is fine', '''
+ keyA: |
+ multi-line
+ string
+ keyB: 42 # number
+ keyC: 42.2 # double
+ keyD: [1, 2]
+ keyE:
+ - 1
+ - 2
+ keyF:
+ k: "v"
+ ''');
+
+ test('complex structures matches the same JSON', () {
+ final yaml = '''
+ keyA: "hello"
+ keyB: 42 # number
+ keyC: 42.2 # double
+ keyD: [1, 2]
+ keyE:
+ - 1
+ - 2
+ keyF:
+ k: "v"
+ ''';
+ final data = parseYamlFromConfigFile(yaml);
+ expect(
+ const DeepCollectionEquality().equals(data, {
+ 'keyA': 'hello',
+ 'keyB': 42,
+ 'keyC': 42.2,
+ 'keyD': [1, 2],
+ 'keyE': [1, 2],
+ 'keyF': {'k': 'v'},
+ }),
+ isTrue,
+ );
+ });
+ });
+}
diff --git a/pkgs/file/.gitignore b/pkgs/file/.gitignore
new file mode 100644
index 0000000..ddfdca1
--- /dev/null
+++ b/pkgs/file/.gitignore
@@ -0,0 +1,5 @@
+.dart_tool/
+.packages
+.pub/
+build/
+pubspec.lock
diff --git a/pkgs/file/CHANGELOG.md b/pkgs/file/CHANGELOG.md
new file mode 100644
index 0000000..50c96c4
--- /dev/null
+++ b/pkgs/file/CHANGELOG.md
@@ -0,0 +1,242 @@
+## 7.0.1
+
+* Update the pubspec repository field to reflect the new package repository.
+
+## 7.0.0
+
+* Dart 3 fixes for class modifiers.
+* Require Dart 3.0.
+* `MemoryFileSystem` now treats empty paths as non-existent.
+* Fix `FileSystem.isLink`/`FileSystem.isLinkSync` to not follow symbolic links.
+* Make the return type of `MemoryFile.openRead` and `_ChrootFile.openRead` again
+ match the return type from `dart:io`.
+
+## 6.1.4
+
+* Populate the pubspec `repository` field.
+
+## 6.1.3
+
+* In classes that implement `File` methods `create`, `createSync` now take `bool exclusive = true` parameter. No functional changes.
+
+## 6.1.2
+
+* `MemoryFileSystem` now provides `opHandle`s for exists operations.
+
+## 6.1.1
+
+* `MemoryFile` now provides `opHandle`s for copy and open operations.
+
+## 6.1.0
+
+* Reading invalid UTF8 with the `MemoryFileSystem` now correctly throws a `FileSystemException` instead of a `FormatError`.
+* `MemoryFileSystem` now provides an `opHandle` to inspect read/write operations.
+* `MemoryFileSystem` now creates the temporary directory before returning in `createTemp`/`createTempSync`.
+
+## 6.0.1
+
+* Fix sound type error in memory backend when reading non-existent `MemoryDirectory`.
+
+## 6.0.0
+
+* First stable null safe release.
+
+## 6.0.0-nullsafety.4
+
+* Update upper bound of SDK constraint.
+
+## 6.0.0-nullsafety.3
+
+* Update upper bound of SDK constraint.
+
+## 6.0.0-nullsafety.2
+
+* Make `ForwardingFile.openRead`'s return type again match the return type from
+ `dart:io`.
+* Remove some unnecessary `Uint8List` conversions in `ForwardingFile`.
+
+## 6.0.0-nullsafety.1
+
+* Update to null safety.
+* Remove record/replay functionality.
+* Made `MemoryRandomAccessFile` and `MemoryFile.openWrite` handle the file
+ being removed or renamed while open.
+* Fixed incorrect formatting in `NoMatchingInvocationError.toString()`.
+* Fixed more test flakiness.
+* Enabled more tests.
+* Internal cleanup.
+* Remove implicit dynamic in preparation for null safety.
+* Remove dependency on Intl.
+
+## 5.2.1
+
+* systemTemp directories created by `MemoryFileSystem` will allot names
+ based on the file system instance instead of globally.
+* `MemoryFile.readAsLines()`/`readAsLinesSync()` no longer treat a final newline
+ in the file as the start of a new, empty line.
+* `RecordingFile.readAsLine()`/`readAsLinesSync()` now always record a final
+ newline.
+* `MemoryFile.flush()` now returns `Future<void>` instead of `Future<dynamic>`.
+* Fixed some test flakiness.
+* Enabled more tests.
+* Internal cleanup.
+
+## 5.2.0
+
+* Added a `MemoryRandomAccessFile` class and implemented
+ `MemoryFile.open()`/`openSync()`.
+
+## 5.1.0
+
+* Added a new `MemoryFileSystem` constructor to use a test clock
+
+## 5.0.10
+
+* Added example
+
+## 5.0.9
+
+* Fix lints for project health
+
+## 5.0.8
+
+* Return `Uint8List` rather than `List<int>`.
+
+## 5.0.7
+
+* Dart 2 fixes for `RecordingProxyMixin` and `ReplayProxyMixin`.
+
+## 5.0.6
+
+* Dart 2 fixes for `RecordingFile.open()`
+
+## 5.0.5
+
+* Dart 2 fixes
+
+## 5.0.4
+
+* Update SDK constraint to 2.0.0-dev.67.0, remove workaround in
+ recording_proxy_mixin.dart.
+* Fix usage within Dart 2 runtime mode in Dart 2.0.0-dev.61.0 and later.
+* Relax constraints on `package:test`
+
+## 5.0.3
+
+* Update `package:test` dependency to 1.0
+
+## 5.0.2
+
+* Declare compatibility with Dart 2 stable
+
+## 5.0.1
+
+* Remove upper case constants
+* Update SDK constraint to 2.0.0-dev.54.0.
+
+## 5.0.0
+
+* Moved `testing` library into a dedicated `package:file_testing` so that
+ libraries don't need to take on a transitive dependency on `package:test`
+ in order to use `package:file`.
+
+## 4.0.1
+
+* General library cleanup
+* Add `style` support in `MemoryFileSystem`, so that callers can choose to
+ have a memory file system with windows-like paths. [#68]
+ (https://github.com/google/file.dart/issues/68)
+
+## 4.0.0
+
+* Change method signature for `RecordingRandomAccessFile._close` to return a
+ `Future<void>` instead of `Future<RandomAccessFile>`. This follows a change in
+ dart:io, Dart SDK `2.0.0-dev.40`.
+
+## 3.0.0
+
+* Import `dart:io` unconditionally. More recent Dart SDK revisions allow
+ `dart:io` to be imported in a browser context, though if methods are actually
+ invoked, they will fail. This matches well with `package:file`, where users
+ can use the `memory` library and get in-memory implementations of the
+ `dart:io` interfaces.
+* Bump minimum Dart SDK to `1.24.0`
+
+## 2.3.7
+
+* Fix Dart 2 error.
+
+## 2.3.6
+
+* Relax sdk upper bound constraint to '<2.0.0' to allow 'edge' dart sdk use.
+
+## 2.3.5
+
+* Fix internal use of a cast which fails on Dart 2.0 .
+
+## 2.3.4
+
+* Bumped maximum Dart SDK version to 2.0.0-dev.infinity
+
+## 2.3.3
+
+* Relaxes version requirements on `package:intl`
+
+## 2.3.2
+
+* Fixed `FileSystem.directory(Uri)`, `FileSystem.file(Uri)`, and
+ `FileSystem.link(Uri)` to consult the file system's path context when
+ converting the URI to a file path rather than using `Uri.toFilePath()`.
+
+## 2.3.1
+
+* Fixed `MemoryFileSystem` to make `File.writeAs...()` update the last modified
+ time of the file.
+
+## 2.3.0
+
+* Added the following convenience methods in `Directory`:
+ * `Directory.childDirectory(String basename)`
+ * `Directory.childFile(String basename)`
+ * `Directory.childLink(String basename)`
+
+## 2.2.0
+
+* Added `ErrorCodes` class, which holds errno values.
+
+## 2.1.0
+
+* Add support for new `dart:io` API methods added in Dart SDK 1.23
+
+## 2.0.1
+
+* Minor doc updates
+
+## 2.0.0
+
+* Improved `toString` implementations in file system entity classes
+* Added `ForwardingFileSystem` and associated forwarding classes to the
+ main `file` library
+* Removed `FileSystem.pathSeparator`, and added a more comprehensive
+ `FileSystem.path` property
+* Added `FileSystemEntity.basename` and `FileSystemEntity.dirname`
+* Added the `record_replay` library
+* Added the `testing` library
+
+## 1.0.1
+
+* Added `FileSystem.systemTempDirectory`
+* Added the ability to pass `Uri` and `FileSystemEntity` types to
+ `FileSystem.directory()`, `FileSystem.file()`, and `FileSystem.link()`
+* Added `FileSystem.pathSeparator`
+
+## 1.0.0
+
+* Unified interface to match dart:io API
+* Local file system implementation
+* In-memory file system implementation
+* Chroot file system implementation
+
+## 0.1.0
+
+* Initial version
diff --git a/pkgs/file/LICENSE b/pkgs/file/LICENSE
new file mode 100644
index 0000000..076334f
--- /dev/null
+++ b/pkgs/file/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2017, the Dart project authors. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of Google Inc. nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/pkgs/file/README.md b/pkgs/file/README.md
new file mode 100644
index 0000000..a63d6e6
--- /dev/null
+++ b/pkgs/file/README.md
@@ -0,0 +1,44 @@
+[](https://github.com/dart-lang/tools/actions/workflows/file.yml)
+[](https://pub.dev/packages/file)
+[](https://pub.dev/packages/file/publisher)
+
+A generic file system abstraction for Dart.
+
+## Features
+
+Like `dart:io`, `package:file` supplies a rich Dart-idiomatic API for accessing
+a file system.
+
+Unlike `dart:io`, `package:file`:
+
+- Can be used to implement custom file systems.
+- Comes with an in-memory implementation out-of-the-box, making it super-easy to
+ test code that works with the file system.
+- Allows using multiple file systems simultaneously. A file system is a
+ first-class object. Instantiate however many you want and use them all.
+
+## Usage
+
+Implement your own custom file system:
+
+```dart
+import 'package:file/file.dart';
+
+class FooBarFileSystem implements FileSystem { ... }
+```
+
+Use the in-memory file system:
+
+```dart
+import 'package:file/memory.dart';
+
+var fs = MemoryFileSystem();
+```
+
+Use the local file system (requires dart:io access):
+
+```dart
+import 'package:file/local.dart';
+
+var fs = const LocalFileSystem();
+```
diff --git a/pkgs/file/analysis_options.yaml b/pkgs/file/analysis_options.yaml
new file mode 100644
index 0000000..8fbd2e4
--- /dev/null
+++ b/pkgs/file/analysis_options.yaml
@@ -0,0 +1,6 @@
+include: package:lints/recommended.yaml
+
+analyzer:
+ errors:
+ # Allow having TODOs in the code
+ todo: ignore
diff --git a/pkgs/file/example/main.dart b/pkgs/file/example/main.dart
new file mode 100644
index 0000000..7ca0bc7
--- /dev/null
+++ b/pkgs/file/example/main.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:file/file.dart';
+import 'package:file/memory.dart';
+
+Future<void> main() async {
+ final FileSystem fs = MemoryFileSystem();
+ final Directory tmp = await fs.systemTempDirectory.createTemp('example_');
+ final File outputFile = tmp.childFile('output');
+ await outputFile.writeAsString('Hello world!');
+ print(outputFile.readAsStringSync());
+}
diff --git a/pkgs/file/lib/chroot.dart b/pkgs/file/lib/chroot.dart
new file mode 100644
index 0000000..56d2bd5
--- /dev/null
+++ b/pkgs/file/lib/chroot.dart
@@ -0,0 +1,6 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// A file system that provides a view into _another_ `FileSystem` via a path.
+export 'src/backends/chroot.dart';
diff --git a/pkgs/file/lib/file.dart b/pkgs/file/lib/file.dart
new file mode 100644
index 0000000..cdde9fe
--- /dev/null
+++ b/pkgs/file/lib/file.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Core interfaces containing the abstract `FileSystem` interface definition
+/// and all associated types used by `FileSystem`.
+export 'src/forwarding.dart';
+export 'src/interface.dart';
diff --git a/pkgs/file/lib/local.dart b/pkgs/file/lib/local.dart
new file mode 100644
index 0000000..74f506e
--- /dev/null
+++ b/pkgs/file/lib/local.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// A local file system implementation. This relies on the use of `dart:io`
+/// and is thus not suitable for use in the browser.
+export 'src/backends/local.dart';
diff --git a/pkgs/file/lib/memory.dart b/pkgs/file/lib/memory.dart
new file mode 100644
index 0000000..c5705ef
--- /dev/null
+++ b/pkgs/file/lib/memory.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// An implementation of `FileSystem` that exists entirely in memory with an
+/// internal representation loosely based on the Filesystem Hierarchy Standard.
+export 'src/backends/memory.dart';
+export 'src/backends/memory/operations.dart';
diff --git a/pkgs/file/lib/src/backends/chroot.dart b/pkgs/file/lib/src/backends/chroot.dart
new file mode 100644
index 0000000..6082e80
--- /dev/null
+++ b/pkgs/file/lib/src/backends/chroot.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library file.src.backends.chroot;
+
+import 'dart:convert';
+import 'dart:typed_data';
+
+import 'package:file/file.dart';
+import 'package:file/src/common.dart' as common;
+import 'package:file/src/io.dart' as io;
+import 'package:path/path.dart' as p;
+
+part 'chroot/chroot_directory.dart';
+part 'chroot/chroot_file.dart';
+part 'chroot/chroot_file_system.dart';
+part 'chroot/chroot_file_system_entity.dart';
+part 'chroot/chroot_link.dart';
+part 'chroot/chroot_random_access_file.dart';
diff --git a/pkgs/file/lib/src/backends/chroot/chroot_directory.dart b/pkgs/file/lib/src/backends/chroot/chroot_directory.dart
new file mode 100644
index 0000000..8fec7b1
--- /dev/null
+++ b/pkgs/file/lib/src/backends/chroot/chroot_directory.dart
@@ -0,0 +1,176 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of file.src.backends.chroot;
+
+class _ChrootDirectory extends _ChrootFileSystemEntity<Directory, io.Directory>
+ with ForwardingDirectory<Directory>, common.DirectoryAddOnsMixin {
+ _ChrootDirectory(ChrootFileSystem fs, String path) : super(fs, path);
+
+ factory _ChrootDirectory.wrapped(
+ ChrootFileSystem fs,
+ Directory delegate, {
+ bool relative = false,
+ }) {
+ String localPath = fs._local(delegate.path, relative: relative);
+ return _ChrootDirectory(fs, localPath);
+ }
+
+ @override
+ FileSystemEntityType get expectedType => FileSystemEntityType.directory;
+
+ @override
+ io.Directory _rawDelegate(String path) => fileSystem.delegate.directory(path);
+
+ @override
+ Uri get uri => Uri.directory(path);
+
+ @override
+ Future<Directory> rename(String newPath) async {
+ if (_isLink) {
+ if (await fileSystem.type(path) != expectedType) {
+ throw common.notADirectory(path);
+ }
+ FileSystemEntityType type = await fileSystem.type(newPath);
+ if (type != FileSystemEntityType.notFound) {
+ if (type != expectedType) {
+ throw common.notADirectory(newPath);
+ }
+ if (!(await fileSystem
+ .directory(newPath)
+ .list(followLinks: false)
+ .isEmpty)) {
+ throw common.directoryNotEmpty(newPath);
+ }
+ }
+ String target = await fileSystem.link(path).target();
+ await fileSystem.link(path).delete();
+ await fileSystem.link(newPath).create(target);
+ return fileSystem.directory(newPath);
+ } else {
+ return wrap(await getDelegate(followLinks: true)
+ .rename(fileSystem._real(newPath)));
+ }
+ }
+
+ @override
+ Directory renameSync(String newPath) {
+ if (_isLink) {
+ if (fileSystem.typeSync(path) != expectedType) {
+ throw common.notADirectory(path);
+ }
+ FileSystemEntityType type = fileSystem.typeSync(newPath);
+ if (type != FileSystemEntityType.notFound) {
+ if (type != expectedType) {
+ throw common.notADirectory(newPath);
+ }
+ if (fileSystem
+ .directory(newPath)
+ .listSync(followLinks: false)
+ .isNotEmpty) {
+ throw common.directoryNotEmpty(newPath);
+ }
+ }
+ String target = fileSystem.link(path).targetSync();
+ fileSystem.link(path).deleteSync();
+ fileSystem.link(newPath).createSync(target);
+ return fileSystem.directory(newPath);
+ } else {
+ return wrap(
+ getDelegate(followLinks: true).renameSync(fileSystem._real(newPath)));
+ }
+ }
+
+ @override
+ Directory get absolute => _ChrootDirectory(fileSystem, _absolutePath);
+
+ @override
+ Directory get parent {
+ try {
+ return wrapDirectory(delegate.parent);
+ } on _ChrootJailException {
+ return this;
+ }
+ }
+
+ @override
+ Future<Directory> create({bool recursive = false}) async {
+ if (_isLink) {
+ switch (await fileSystem.type(path)) {
+ case FileSystemEntityType.notFound:
+ throw common.noSuchFileOrDirectory(path);
+ case FileSystemEntityType.file:
+ throw common.fileExists(path);
+ case FileSystemEntityType.directory:
+ // Nothing to do.
+ return this;
+ default:
+ throw AssertionError();
+ }
+ } else {
+ return wrap(await delegate.create(recursive: recursive));
+ }
+ }
+
+ @override
+ void createSync({bool recursive = false}) {
+ if (_isLink) {
+ switch (fileSystem.typeSync(path)) {
+ case FileSystemEntityType.notFound:
+ throw common.noSuchFileOrDirectory(path);
+ case FileSystemEntityType.file:
+ throw common.fileExists(path);
+ case FileSystemEntityType.directory:
+ // Nothing to do.
+ return;
+ default:
+ throw AssertionError();
+ }
+ } else {
+ delegate.createSync(recursive: recursive);
+ }
+ }
+
+ @override
+ Stream<FileSystemEntity> list({
+ bool recursive = false,
+ bool followLinks = true,
+ }) {
+ Directory delegate = this.delegate as Directory;
+ String dirname = delegate.path;
+ return delegate
+ .list(recursive: recursive, followLinks: followLinks)
+ .map((io.FileSystemEntity entity) => _denormalize(entity, dirname));
+ }
+
+ @override
+ List<FileSystemEntity> listSync({
+ bool recursive = false,
+ bool followLinks = true,
+ }) {
+ Directory delegate = this.delegate as Directory;
+ String dirname = delegate.path;
+ return delegate
+ .listSync(recursive: recursive, followLinks: followLinks)
+ .map((io.FileSystemEntity entity) => _denormalize(entity, dirname))
+ .toList();
+ }
+
+ FileSystemEntity _denormalize(io.FileSystemEntity entity, String dirname) {
+ p.Context ctx = fileSystem.path;
+ String relativePart = ctx.relative(entity.path, from: dirname);
+ String entityPath = ctx.join(path, relativePart);
+ if (entity is io.File) {
+ return _ChrootFile(fileSystem, entityPath);
+ } else if (entity is io.Directory) {
+ return _ChrootDirectory(fileSystem, entityPath);
+ } else if (entity is io.Link) {
+ return _ChrootLink(fileSystem, entityPath);
+ }
+ throw FileSystemException('Unsupported type: $entity', entity.path);
+ }
+
+ @override
+ String toString() => "ChrootDirectory: '$path'";
+}
diff --git a/pkgs/file/lib/src/backends/chroot/chroot_file.dart b/pkgs/file/lib/src/backends/chroot/chroot_file.dart
new file mode 100644
index 0000000..4b67bc1
--- /dev/null
+++ b/pkgs/file/lib/src/backends/chroot/chroot_file.dart
@@ -0,0 +1,339 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of file.src.backends.chroot;
+
+typedef _SetupCallback = dynamic Function();
+
+class _ChrootFile extends _ChrootFileSystemEntity<File, io.File>
+ with ForwardingFile {
+ _ChrootFile(ChrootFileSystem fs, String path) : super(fs, path);
+
+ factory _ChrootFile.wrapped(
+ ChrootFileSystem fs,
+ io.File delegate, {
+ bool relative = false,
+ }) {
+ String localPath = fs._local(delegate.path, relative: relative);
+ return _ChrootFile(fs, localPath);
+ }
+
+ @override
+ FileSystemEntityType get expectedType => FileSystemEntityType.file;
+
+ @override
+ io.File _rawDelegate(String path) => fileSystem.delegate.file(path);
+
+ @override
+ Future<File> rename(String newPath) async {
+ _SetupCallback setUp = () async {};
+
+ if (await fileSystem.type(newPath, followLinks: false) ==
+ FileSystemEntityType.link) {
+ // The delegate file system will ensure that the link target references
+ // an actual file before allowing the rename, but we want the link target
+ // to be resolved with respect to this file system. Thus, we perform that
+ // validation here instead.
+ switch (await fileSystem.type(newPath)) {
+ case FileSystemEntityType.file:
+ case FileSystemEntityType.notFound:
+ // Validation passed; delete the link to keep the delegate file
+ // system's validation from getting in the way.
+ setUp = () async {
+ await fileSystem.link(newPath).delete();
+ };
+ break;
+ case FileSystemEntityType.directory:
+ throw common.isADirectory(newPath);
+ default:
+ // Should never happen.
+ throw AssertionError();
+ }
+ }
+
+ if (_isLink) {
+ switch (await fileSystem.type(path)) {
+ case FileSystemEntityType.notFound:
+ throw common.noSuchFileOrDirectory(path);
+ case FileSystemEntityType.directory:
+ throw common.isADirectory(path);
+ case FileSystemEntityType.file:
+ await setUp();
+ await fileSystem.delegate
+ .link(fileSystem._real(path))
+ .rename(fileSystem._real(newPath));
+ return _ChrootFile(fileSystem, newPath);
+ default:
+ throw AssertionError();
+ }
+ } else {
+ await setUp();
+ return wrap(await delegate.rename(fileSystem._real(newPath)));
+ }
+ }
+
+ @override
+ File renameSync(String newPath) {
+ _SetupCallback setUp = () {};
+
+ if (fileSystem.typeSync(newPath, followLinks: false) ==
+ FileSystemEntityType.link) {
+ // The delegate file system will ensure that the link target references
+ // an actual file before allowing the rename, but we want the link target
+ // to be resolved with respect to this file system. Thus, we perform that
+ // validation here instead.
+ switch (fileSystem.typeSync(newPath)) {
+ case FileSystemEntityType.file:
+ case FileSystemEntityType.notFound:
+ // Validation passed; delete the link to keep the delegate file
+ // system's validation from getting in the way.
+ setUp = () {
+ fileSystem.link(newPath).deleteSync();
+ };
+ break;
+ case FileSystemEntityType.directory:
+ throw common.isADirectory(newPath);
+ default:
+ // Should never happen.
+ throw AssertionError();
+ }
+ }
+
+ if (_isLink) {
+ switch (fileSystem.typeSync(path)) {
+ case FileSystemEntityType.notFound:
+ throw common.noSuchFileOrDirectory(path);
+ case FileSystemEntityType.directory:
+ throw common.isADirectory(path);
+ case FileSystemEntityType.file:
+ setUp();
+ fileSystem.delegate
+ .link(fileSystem._real(path))
+ .renameSync(fileSystem._real(newPath));
+ return _ChrootFile(fileSystem, newPath);
+ default:
+ throw AssertionError();
+ }
+ } else {
+ setUp();
+ return wrap(delegate.renameSync(fileSystem._real(newPath)));
+ }
+ }
+
+ @override
+ File get absolute => _ChrootFile(fileSystem, _absolutePath);
+
+ @override
+ Future<File> create({bool recursive = false, bool exclusive = false}) async {
+ String path = fileSystem._resolve(
+ this.path,
+ followLinks: false,
+ notFound: recursive ? _NotFoundBehavior.mkdir : _NotFoundBehavior.allow,
+ );
+
+ String real() => fileSystem._real(path, resolve: false);
+ Future<FileSystemEntityType> type() =>
+ fileSystem.delegate.type(real(), followLinks: false);
+
+ if (await type() == FileSystemEntityType.link) {
+ path = fileSystem._resolve(p.basename(path),
+ from: p.dirname(path), notFound: _NotFoundBehavior.allowAtTail);
+ switch (await type()) {
+ case FileSystemEntityType.notFound:
+ await _rawDelegate(real()).create();
+ return this;
+ case FileSystemEntityType.file:
+ // Nothing to do.
+ return this;
+ case FileSystemEntityType.directory:
+ throw common.isADirectory(path);
+ default:
+ throw AssertionError();
+ }
+ } else {
+ return wrap(await _rawDelegate(real()).create());
+ }
+ }
+
+ @override
+ void createSync({bool recursive = false, bool exclusive = false}) {
+ String path = fileSystem._resolve(
+ this.path,
+ followLinks: false,
+ notFound: recursive ? _NotFoundBehavior.mkdir : _NotFoundBehavior.allow,
+ );
+
+ String real() => fileSystem._real(path, resolve: false);
+ FileSystemEntityType type() =>
+ fileSystem.delegate.typeSync(real(), followLinks: false);
+
+ if (type() == FileSystemEntityType.link) {
+ path = fileSystem._resolve(p.basename(path),
+ from: p.dirname(path), notFound: _NotFoundBehavior.allowAtTail);
+ switch (type()) {
+ case FileSystemEntityType.notFound:
+ _rawDelegate(real()).createSync();
+ return;
+ case FileSystemEntityType.file:
+ // Nothing to do.
+ return;
+ case FileSystemEntityType.directory:
+ throw common.isADirectory(path);
+ default:
+ throw AssertionError();
+ }
+ } else {
+ _rawDelegate(real()).createSync();
+ }
+ }
+
+ @override
+ Future<File> copy(String newPath) async {
+ return wrap(await getDelegate(followLinks: true)
+ .copy(fileSystem._real(newPath, followLinks: true)));
+ }
+
+ @override
+ File copySync(String newPath) {
+ return wrap(getDelegate(followLinks: true)
+ .copySync(fileSystem._real(newPath, followLinks: true)));
+ }
+
+ @override
+ Future<int> length() => getDelegate(followLinks: true).length();
+
+ @override
+ int lengthSync() => getDelegate(followLinks: true).lengthSync();
+
+ @override
+ Future<DateTime> lastAccessed() =>
+ getDelegate(followLinks: true).lastAccessed();
+
+ @override
+ DateTime lastAccessedSync() =>
+ getDelegate(followLinks: true).lastAccessedSync();
+
+ @override
+ Future<dynamic> setLastAccessed(DateTime time) =>
+ getDelegate(followLinks: true).setLastAccessed(time);
+
+ @override
+ void setLastAccessedSync(DateTime time) =>
+ getDelegate(followLinks: true).setLastAccessedSync(time);
+
+ @override
+ Future<DateTime> lastModified() =>
+ getDelegate(followLinks: true).lastModified();
+
+ @override
+ DateTime lastModifiedSync() =>
+ getDelegate(followLinks: true).lastModifiedSync();
+
+ @override
+ Future<dynamic> setLastModified(DateTime time) =>
+ getDelegate(followLinks: true).setLastModified(time);
+
+ @override
+ void setLastModifiedSync(DateTime time) =>
+ getDelegate(followLinks: true).setLastModifiedSync(time);
+
+ @override
+ Future<RandomAccessFile> open({
+ FileMode mode = FileMode.read,
+ }) async =>
+ _ChrootRandomAccessFile(
+ path, await getDelegate(followLinks: true).open(mode: mode));
+
+ @override
+ RandomAccessFile openSync({FileMode mode = FileMode.read}) =>
+ _ChrootRandomAccessFile(
+ path, getDelegate(followLinks: true).openSync(mode: mode));
+
+ @override
+ Stream<List<int>> openRead([int? start, int? end]) =>
+ getDelegate(followLinks: true).openRead(start, end);
+
+ @override
+ IOSink openWrite({
+ FileMode mode = FileMode.write,
+ Encoding encoding = utf8,
+ }) =>
+ getDelegate(followLinks: true).openWrite(mode: mode, encoding: encoding);
+
+ @override
+ Future<Uint8List> readAsBytes() =>
+ getDelegate(followLinks: true).readAsBytes();
+
+ @override
+ Uint8List readAsBytesSync() =>
+ getDelegate(followLinks: true).readAsBytesSync();
+
+ @override
+ Future<String> readAsString({Encoding encoding = utf8}) =>
+ getDelegate(followLinks: true).readAsString(encoding: encoding);
+
+ @override
+ String readAsStringSync({Encoding encoding = utf8}) =>
+ getDelegate(followLinks: true).readAsStringSync(encoding: encoding);
+
+ @override
+ Future<List<String>> readAsLines({Encoding encoding = utf8}) =>
+ getDelegate(followLinks: true).readAsLines(encoding: encoding);
+
+ @override
+ List<String> readAsLinesSync({Encoding encoding = utf8}) =>
+ getDelegate(followLinks: true).readAsLinesSync(encoding: encoding);
+
+ @override
+ Future<File> writeAsBytes(
+ List<int> bytes, {
+ FileMode mode = FileMode.write,
+ bool flush = false,
+ }) async =>
+ wrap(await getDelegate(followLinks: true).writeAsBytes(
+ bytes,
+ mode: mode,
+ flush: flush,
+ ));
+
+ @override
+ void writeAsBytesSync(
+ List<int> bytes, {
+ FileMode mode = FileMode.write,
+ bool flush = false,
+ }) =>
+ getDelegate(followLinks: true)
+ .writeAsBytesSync(bytes, mode: mode, flush: flush);
+
+ @override
+ Future<File> writeAsString(
+ String contents, {
+ FileMode mode = FileMode.write,
+ Encoding encoding = utf8,
+ bool flush = false,
+ }) async =>
+ wrap(await getDelegate(followLinks: true).writeAsString(
+ contents,
+ mode: mode,
+ encoding: encoding,
+ flush: flush,
+ ));
+
+ @override
+ void writeAsStringSync(
+ String contents, {
+ FileMode mode = FileMode.write,
+ Encoding encoding = utf8,
+ bool flush = false,
+ }) =>
+ getDelegate(followLinks: true).writeAsStringSync(
+ contents,
+ mode: mode,
+ encoding: encoding,
+ flush: flush,
+ );
+
+ @override
+ String toString() => "ChrootFile: '$path'";
+}
diff --git a/pkgs/file/lib/src/backends/chroot/chroot_file_system.dart b/pkgs/file/lib/src/backends/chroot/chroot_file_system.dart
new file mode 100644
index 0000000..6889c98
--- /dev/null
+++ b/pkgs/file/lib/src/backends/chroot/chroot_file_system.dart
@@ -0,0 +1,391 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of file.src.backends.chroot;
+
+const String _thisDir = '.';
+const String _parentDir = '..';
+
+/// File system that provides a view into _another_ [FileSystem] via a path.
+///
+/// This is similar in concept to the `chroot` operation in Linux operating
+/// systems. Such a modified file system cannot name or access files outside of
+/// the designated directory tree.
+///
+/// ## Example use:
+/// ```dart
+/// // Create a "file system" where the root directory is /tmp/some-dir.
+/// var fs = ChrootFileSystem(existingFileSystem, '/tmp/some-dir');
+/// ```
+///
+/// **Notes on usage**:
+///
+/// * This file system maintains its _own_ [currentDirectory], distinct from
+/// that of the underlying file system, and new instances automatically start
+/// at the root (i.e. `/`).
+///
+/// * This file system does _not_ leverage any underlying OS system calls (such
+/// as `chroot` itself), so the developer needs to take care to not assume any
+/// more of a secure environment than is actually provided. For instance, the
+/// underlying system is available via the [delegate] - which underscores this
+/// file system is intended to be a convenient abstraction, not a security
+/// measure.
+///
+/// * This file system _necessarily_ carries certain performance overhead due
+/// to the fact that symbolic links are resolved manually (not delegated).
+class ChrootFileSystem extends FileSystem {
+ /// Creates a new file system backed by [root] path in [delegate] file system.
+ ///
+ /// **NOTE**: [root] must be a _canonicalized_ path; see [p.canonicalize].
+ ChrootFileSystem(this.delegate, this.root) {
+ if (root != delegate.path.canonicalize(root)) {
+ throw ArgumentError.value(root, 'root', 'Must be canonical path');
+ }
+ _cwd = _localRoot;
+ }
+
+ /// Underlying file system.
+ final FileSystem delegate;
+
+ /// Directory in [delegate] file system that is treated as the root here.
+ final String root;
+
+ String? _systemTemp;
+
+ /// Path to the synthetic current working directory in this file system.
+ late String _cwd;
+
+ /// Gets the root path, as seen by entities in this file system.
+ String get _localRoot => delegate.path.rootPrefix(root);
+
+ @override
+ Directory directory(dynamic path) => _ChrootDirectory(this, getPath(path));
+
+ @override
+ File file(dynamic path) => _ChrootFile(this, getPath(path));
+
+ @override
+ Link link(dynamic path) => _ChrootLink(this, getPath(path));
+
+ @override
+ p.Context get path => p.Context(style: delegate.path.style, current: _cwd);
+
+ /// Gets the system temp directory. This directory will be created on-demand
+ /// in the local root of the file system. Once created, its location is fixed
+ /// for the life of the process.
+ @override
+ Directory get systemTempDirectory {
+ _systemTemp ??= directory(_localRoot).createTempSync('.tmp_').path;
+ return directory(_systemTemp)..createSync();
+ }
+
+ /// Creates a directory object pointing to the current working directory.
+ ///
+ /// **NOTE** This does _not_ proxy to the underlying file system's current
+ /// directory in any way; the state of this file system's current directory
+ /// is local to this file system.
+ @override
+ Directory get currentDirectory => directory(_cwd);
+
+ /// Sets the current working directory to the specified [path].
+ ///
+ /// **NOTE** This does _not_ proxy to the underlying file system's current
+ /// directory in any way; the state of this file system's current directory
+ /// is local to this file system.
+ /// Gets the path context for this file system given the current working dir.
+
+ @override
+ set currentDirectory(dynamic path) {
+ String value;
+ if (path is io.Directory) {
+ value = path.path;
+ } else if (path is String) {
+ value = path;
+ } else {
+ throw ArgumentError('Invalid type for "path": ${path?.runtimeType}');
+ }
+
+ value = _resolve(value, notFound: _NotFoundBehavior.throwError);
+ String realPath = _real(value, resolve: false);
+ switch (delegate.typeSync(realPath, followLinks: false)) {
+ case FileSystemEntityType.directory:
+ break;
+ case FileSystemEntityType.notFound:
+ throw common.noSuchFileOrDirectory(path as String);
+ default:
+ throw common.notADirectory(path as String);
+ }
+ assert(() {
+ p.Context ctx = delegate.path;
+ return ctx.isAbsolute(value) && value == ctx.canonicalize(value);
+ }());
+ _cwd = value;
+ }
+
+ @override
+ Future<FileStat> stat(String path) {
+ try {
+ path = _resolve(path);
+ } on FileSystemException {
+ return Future<FileStat>.value(const _NotFoundFileStat());
+ }
+ return delegate.stat(_real(path, resolve: false));
+ }
+
+ @override
+ FileStat statSync(String path) {
+ try {
+ path = _resolve(path);
+ } on FileSystemException {
+ return const _NotFoundFileStat();
+ }
+ return delegate.statSync(_real(path, resolve: false));
+ }
+
+ @override
+ Future<bool> identical(String path1, String path2) => delegate.identical(
+ _real(_resolve(path1, followLinks: false)),
+ _real(_resolve(path2, followLinks: false)),
+ );
+
+ @override
+ bool identicalSync(String path1, String path2) => delegate.identicalSync(
+ _real(_resolve(path1, followLinks: false)),
+ _real(_resolve(path2, followLinks: false)),
+ );
+
+ @override
+ bool get isWatchSupported => false;
+
+ @override
+ Future<FileSystemEntityType> type(String path, {bool followLinks = true}) {
+ String realPath;
+ try {
+ realPath = _real(path, followLinks: followLinks);
+ } on FileSystemException {
+ return Future<FileSystemEntityType>.value(FileSystemEntityType.notFound);
+ }
+ return delegate.type(realPath, followLinks: false);
+ }
+
+ @override
+ FileSystemEntityType typeSync(String path, {bool followLinks = true}) {
+ String realPath;
+ try {
+ realPath = _real(path, followLinks: followLinks);
+ } on FileSystemException {
+ return FileSystemEntityType.notFound;
+ }
+ return delegate.typeSync(realPath, followLinks: false);
+ }
+
+ /// Converts a [realPath] in the underlying file system to a local path here.
+ ///
+ /// If [relative] is set to `true`, then the resulting path will be relative
+ /// to [currentDirectory], otherwise the resulting path will be absolute.
+ ///
+ /// An exception is thrown if the path is outside of this file system's root
+ /// directory unless [keepInJail] is true, in which case this will instead
+ /// return the path of the root of this file system.
+ String _local(
+ String realPath, {
+ bool relative = false,
+ bool keepInJail = false,
+ }) {
+ assert(path.isAbsolute(realPath));
+ if (!realPath.startsWith(root)) {
+ if (keepInJail) {
+ return _localRoot;
+ }
+ throw _ChrootJailException();
+ }
+ // TODO(tvolkert): See if _context.relative() works here
+ String result = realPath.substring(root.length);
+ if (result.isEmpty) {
+ result = _localRoot;
+ }
+ if (relative) {
+ assert(result.startsWith(_cwd));
+ result = path.relative(result, from: _cwd);
+ }
+ return result;
+ }
+
+ /// Converts [localPath] in this file system to the real path in the delegate.
+ ///
+ /// The returned path will always be absolute.
+ ///
+ /// If [resolve] is true, symbolic links will be resolved in the local file
+ /// system _before_ converting the path to the delegate file system's
+ /// namespace, and if the tail element of the path is a symbolic link, it will
+ /// only be resolved if [followLinks] is true (where-as symbolic links found
+ /// in the middle of the path will always be resolved).
+ String _real(
+ String localPath, {
+ bool resolve = true,
+ bool followLinks = false,
+ }) {
+ if (resolve) {
+ localPath = _resolve(localPath, followLinks: followLinks);
+ } else {
+ assert(path.isAbsolute(localPath));
+ }
+ return '$root$localPath';
+ }
+
+ /// Resolves symbolic links on [path] and returns the resulting resolved path.
+ ///
+ /// The return value will always be an absolute path; if [path] is relative
+ /// it will be interpreted relative to [from] (or [currentDirectory] if
+ /// `null`).
+ ///
+ /// If the tail element is a symbolic link, then the link will be resolved
+ /// only if [followLinks] is `true`. Symbolic links found in the middle of
+ /// the path will always be resolved.
+ ///
+ /// If the path cannot be resolved, and [notFound] is:
+ /// - [_NotFoundBehavior.throwError]: a [FileSystemException] is thrown.
+ /// - [_NotFoundBehavior.mkdir]: the path will be created as needed.
+ /// - [_NotFoundBehavior.allowAtTail]: a [FileSystemException] is thrown,
+ /// unless only the *tail* path element cannot be resolved, in which case
+ /// the resolution will halt at the tail element, and the partially
+ /// resolved path will be returned.
+ /// - [_NotFoundBehavior.allow] (the default), the resolution will halt and
+ /// the partially resolved path will be returned.
+ String _resolve(
+ String path, {
+ String? from,
+ bool followLinks = true,
+ _NotFoundBehavior notFound = _NotFoundBehavior.allow,
+ }) {
+ if (path.isEmpty) {
+ throw common.noSuchFileOrDirectory(path);
+ }
+
+ p.Context ctx = this.path;
+ String root = _localRoot;
+ List<String> parts, ledger;
+ if (ctx.isAbsolute(path)) {
+ parts = ctx.split(path).sublist(1);
+ ledger = <String>[];
+ } else {
+ from ??= _cwd;
+ assert(ctx.isAbsolute(from));
+ parts = ctx.split(path);
+ ledger = ctx.split(from).sublist(1);
+ }
+
+ String getCurrentPath() => root + ctx.joinAll(ledger);
+ Set<String> breadcrumbs = <String>{};
+ while (parts.isNotEmpty) {
+ String segment = parts.removeAt(0);
+ if (segment == _thisDir) {
+ continue;
+ } else if (segment == _parentDir) {
+ if (ledger.isNotEmpty) {
+ ledger.removeLast();
+ }
+ continue;
+ }
+
+ ledger.add(segment);
+ String currentPath = getCurrentPath();
+ String realPath = _real(currentPath, resolve: false);
+
+ switch (delegate.typeSync(realPath, followLinks: false)) {
+ case FileSystemEntityType.directory:
+ breadcrumbs.clear();
+ break;
+ case FileSystemEntityType.file:
+ breadcrumbs.clear();
+ if (parts.isNotEmpty) {
+ throw common.notADirectory(currentPath);
+ }
+ break;
+ case FileSystemEntityType.notFound:
+ String returnEarly() {
+ ledger.addAll(parts);
+ return getCurrentPath();
+ }
+
+ switch (notFound) {
+ case _NotFoundBehavior.mkdir:
+ if (parts.isNotEmpty) {
+ delegate.directory(realPath).createSync();
+ }
+ break;
+ case _NotFoundBehavior.allow:
+ return returnEarly();
+ case _NotFoundBehavior.allowAtTail:
+ if (parts.isEmpty) {
+ return returnEarly();
+ }
+ throw common.noSuchFileOrDirectory(path);
+ case _NotFoundBehavior.throwError:
+ throw common.noSuchFileOrDirectory(path);
+ }
+ break;
+ case FileSystemEntityType.link:
+ if (parts.isEmpty && !followLinks) {
+ break;
+ }
+ if (!breadcrumbs.add(currentPath)) {
+ throw common.tooManyLevelsOfSymbolicLinks(path);
+ }
+ String target = delegate.link(realPath).targetSync();
+ if (ctx.isAbsolute(target)) {
+ ledger.clear();
+ parts.insertAll(0, ctx.split(target).sublist(1));
+ } else {
+ ledger.removeLast();
+ parts.insertAll(0, ctx.split(target));
+ }
+ break;
+ default:
+ throw AssertionError();
+ }
+ }
+
+ return getCurrentPath();
+ }
+}
+
+/// Thrown when a path is encountered that exists outside of the root path.
+class _ChrootJailException implements IOException {}
+
+/// What to do when `NOT_FOUND` paths are encountered while resolving.
+enum _NotFoundBehavior {
+ allow,
+ allowAtTail,
+ throwError,
+ mkdir,
+}
+
+/// A [FileStat] representing a `NOT_FOUND` entity.
+class _NotFoundFileStat implements FileStat {
+ const _NotFoundFileStat();
+
+ static final DateTime _empty = DateTime(0);
+
+ @override
+ DateTime get changed => _empty;
+
+ @override
+ DateTime get modified => _empty;
+
+ @override
+ DateTime get accessed => _empty;
+
+ @override
+ FileSystemEntityType get type => FileSystemEntityType.notFound;
+
+ @override
+ int get mode => 0;
+
+ @override
+ int get size => -1;
+
+ @override
+ String modeString() => '---------';
+}
diff --git a/pkgs/file/lib/src/backends/chroot/chroot_file_system_entity.dart b/pkgs/file/lib/src/backends/chroot/chroot_file_system_entity.dart
new file mode 100644
index 0000000..8e859ac
--- /dev/null
+++ b/pkgs/file/lib/src/backends/chroot/chroot_file_system_entity.dart
@@ -0,0 +1,169 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of file.src.backends.chroot;
+
+abstract class _ChrootFileSystemEntity<T extends FileSystemEntity,
+ D extends io.FileSystemEntity> extends ForwardingFileSystemEntity<T, D> {
+ _ChrootFileSystemEntity(this.fileSystem, this.path);
+
+ @override
+ final ChrootFileSystem fileSystem;
+
+ @override
+ final String path;
+
+ @override
+ String get dirname => fileSystem.path.dirname(path);
+
+ @override
+ String get basename => fileSystem.path.basename(path);
+
+ @override
+ D get delegate => getDelegate();
+
+ /// Gets the delegate file system entity in the underlying file system that
+ /// corresponds to this entity's local file system path.
+ ///
+ /// If [followLinks] is true and this entity's path references a symbolic
+ /// link, then the path of the delegate entity will reference the ultimate
+ /// target of that symbolic link. Symbolic links in the middle of the path
+ /// will always be resolved in the delegate entity's path.
+ D getDelegate({bool followLinks = false}) =>
+ _rawDelegate(fileSystem._real(path, followLinks: followLinks));
+
+ /// Returns the expected type of this entity, which may differ from the type
+ /// of the entity that's found at the path specified by this entity.
+ FileSystemEntityType get expectedType;
+
+ /// Returns a delegate entity at the specified [realPath] (the path in the
+ /// underlying file system).
+ D _rawDelegate(String realPath);
+
+ /// Gets the path of this entity as an absolute path (unchanged if the
+ /// entity already specifies an absolute path).
+ String get _absolutePath => fileSystem.path.absolute(path);
+
+ /// Tells whether this entity's path references a symbolic link.
+ bool get _isLink =>
+ fileSystem.typeSync(path, followLinks: false) ==
+ FileSystemEntityType.link;
+
+ @override
+ Directory wrapDirectory(io.Directory delegate) =>
+ _ChrootDirectory.wrapped(fileSystem, delegate as Directory,
+ relative: !isAbsolute);
+
+ @override
+ File wrapFile(io.File delegate) =>
+ _ChrootFile.wrapped(fileSystem, delegate, relative: !isAbsolute);
+
+ @override
+ Link wrapLink(io.Link delegate) =>
+ _ChrootLink.wrapped(fileSystem, delegate, relative: !isAbsolute);
+
+ @override
+ Uri get uri => Uri.file(path);
+
+ @override
+ Future<bool> exists() => getDelegate(followLinks: true).exists();
+
+ @override
+ bool existsSync() => getDelegate(followLinks: true).existsSync();
+
+ @override
+ Future<String> resolveSymbolicLinks() async => resolveSymbolicLinksSync();
+
+ @override
+ String resolveSymbolicLinksSync() =>
+ fileSystem._resolve(path, notFound: _NotFoundBehavior.throwError);
+
+ @override
+ Future<FileStat> stat() {
+ D delegate;
+ try {
+ delegate = getDelegate(followLinks: true);
+ } on FileSystemException {
+ return Future<FileStat>.value(const _NotFoundFileStat());
+ }
+ return delegate.stat();
+ }
+
+ @override
+ FileStat statSync() {
+ D delegate;
+ try {
+ delegate = getDelegate(followLinks: true);
+ } on FileSystemException {
+ return const _NotFoundFileStat();
+ }
+ return delegate.statSync();
+ }
+
+ @override
+ Future<T> delete({bool recursive = false}) async {
+ String path = fileSystem._resolve(this.path,
+ followLinks: false, notFound: _NotFoundBehavior.throwError);
+
+ String real(String path) => fileSystem._real(path, resolve: false);
+ Future<FileSystemEntityType> type(String path) =>
+ fileSystem.delegate.type(real(path), followLinks: false);
+
+ if (await type(path) == FileSystemEntityType.link) {
+ if (expectedType == FileSystemEntityType.link) {
+ await fileSystem.delegate.link(real(path)).delete();
+ } else {
+ String resolvedPath = fileSystem._resolve(p.basename(path),
+ from: p.dirname(path), notFound: _NotFoundBehavior.allowAtTail);
+ if (!recursive && await type(resolvedPath) != expectedType) {
+ throw expectedType == FileSystemEntityType.file
+ ? common.isADirectory(path)
+ : common.notADirectory(path);
+ }
+ await fileSystem.delegate.link(real(path)).delete();
+ }
+ return this as T;
+ } else {
+ return wrap(
+ await _rawDelegate(real(path)).delete(recursive: recursive) as D);
+ }
+ }
+
+ @override
+ void deleteSync({bool recursive = false}) {
+ String path = fileSystem._resolve(this.path,
+ followLinks: false, notFound: _NotFoundBehavior.throwError);
+
+ String real(String path) => fileSystem._real(path, resolve: false);
+ FileSystemEntityType type(String path) =>
+ fileSystem.delegate.typeSync(real(path), followLinks: false);
+
+ if (type(path) == FileSystemEntityType.link) {
+ if (expectedType == FileSystemEntityType.link) {
+ fileSystem.delegate.link(real(path)).deleteSync();
+ } else {
+ String resolvedPath = fileSystem._resolve(p.basename(path),
+ from: p.dirname(path), notFound: _NotFoundBehavior.allowAtTail);
+ if (!recursive && type(resolvedPath) != expectedType) {
+ throw expectedType == FileSystemEntityType.file
+ ? common.isADirectory(path)
+ : common.notADirectory(path);
+ }
+ fileSystem.delegate.link(real(path)).deleteSync();
+ }
+ } else {
+ _rawDelegate(real(path)).deleteSync(recursive: recursive);
+ }
+ }
+
+ @override
+ Stream<FileSystemEvent> watch({
+ int events = FileSystemEvent.all,
+ bool recursive = false,
+ }) =>
+ throw UnsupportedError('watch is not supported on ChrootFileSystem');
+
+ @override
+ bool get isAbsolute => fileSystem.path.isAbsolute(path);
+}
diff --git a/pkgs/file/lib/src/backends/chroot/chroot_link.dart b/pkgs/file/lib/src/backends/chroot/chroot_link.dart
new file mode 100644
index 0000000..acbeda6
--- /dev/null
+++ b/pkgs/file/lib/src/backends/chroot/chroot_link.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of file.src.backends.chroot;
+
+class _ChrootLink extends _ChrootFileSystemEntity<Link, io.Link>
+ with ForwardingLink {
+ _ChrootLink(ChrootFileSystem fs, String path) : super(fs, path);
+
+ factory _ChrootLink.wrapped(
+ ChrootFileSystem fs,
+ io.Link delegate, {
+ bool relative = false,
+ }) {
+ String localPath = fs._local(delegate.path, relative: relative);
+ return _ChrootLink(fs, localPath);
+ }
+
+ @override
+ Future<bool> exists() => delegate.exists();
+
+ @override
+ bool existsSync() => delegate.existsSync();
+
+ @override
+ Future<Link> rename(String newPath) async {
+ return wrap(await delegate.rename(fileSystem._real(newPath)));
+ }
+
+ @override
+ Link renameSync(String newPath) {
+ return wrap(delegate.renameSync(fileSystem._real(newPath)));
+ }
+
+ @override
+ FileSystemEntityType get expectedType => FileSystemEntityType.link;
+
+ @override
+ io.Link _rawDelegate(String path) => fileSystem.delegate.link(path);
+
+ @override
+ Link get absolute => _ChrootLink(fileSystem, _absolutePath);
+
+ @override
+ String toString() => "ChrootLink: '$path'";
+}
diff --git a/pkgs/file/lib/src/backends/chroot/chroot_random_access_file.dart b/pkgs/file/lib/src/backends/chroot/chroot_random_access_file.dart
new file mode 100644
index 0000000..4105ac8
--- /dev/null
+++ b/pkgs/file/lib/src/backends/chroot/chroot_random_access_file.dart
@@ -0,0 +1,15 @@
+// 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.
+
+part of file.src.backends.chroot;
+
+class _ChrootRandomAccessFile with ForwardingRandomAccessFile {
+ _ChrootRandomAccessFile(this.path, this.delegate);
+
+ @override
+ final io.RandomAccessFile delegate;
+
+ @override
+ final String path;
+}
diff --git a/pkgs/file/lib/src/backends/local.dart b/pkgs/file/lib/src/backends/local.dart
new file mode 100644
index 0000000..1e92241
--- /dev/null
+++ b/pkgs/file/lib/src/backends/local.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+export 'local/local_file_system.dart' show LocalFileSystem;
diff --git a/pkgs/file/lib/src/backends/local/local_directory.dart b/pkgs/file/lib/src/backends/local/local_directory.dart
new file mode 100644
index 0000000..e23e68f
--- /dev/null
+++ b/pkgs/file/lib/src/backends/local/local_directory.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:file/file.dart';
+import 'package:file/src/common.dart' as common;
+import 'package:file/src/io.dart' as io;
+
+import 'local_file_system_entity.dart';
+
+/// [Directory] implementation that forwards all calls to `dart:io`.
+class LocalDirectory extends LocalFileSystemEntity<LocalDirectory, io.Directory>
+ with ForwardingDirectory<LocalDirectory>, common.DirectoryAddOnsMixin {
+ /// Instantiates a new [LocalDirectory] tied to the specified file system
+ /// and delegating to the specified [delegate].
+ LocalDirectory(FileSystem fs, io.Directory delegate) : super(fs, delegate);
+
+ @override
+ String toString() => "LocalDirectory: '$path'";
+}
diff --git a/pkgs/file/lib/src/backends/local/local_file.dart b/pkgs/file/lib/src/backends/local/local_file.dart
new file mode 100644
index 0000000..36293ba
--- /dev/null
+++ b/pkgs/file/lib/src/backends/local/local_file.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:file/file.dart';
+import 'package:file/src/io.dart' as io;
+
+import 'local_file_system_entity.dart';
+
+/// [File] implementation that forwards all calls to `dart:io`.
+class LocalFile extends LocalFileSystemEntity<File, io.File>
+ with ForwardingFile {
+ /// Instantiates a new [LocalFile] tied to the specified file system
+ /// and delegating to the specified [delegate].
+ LocalFile(FileSystem fs, io.File delegate) : super(fs, delegate);
+
+ @override
+ String toString() => "LocalFile: '$path'";
+}
diff --git a/pkgs/file/lib/src/backends/local/local_file_system.dart b/pkgs/file/lib/src/backends/local/local_file_system.dart
new file mode 100644
index 0000000..635998e
--- /dev/null
+++ b/pkgs/file/lib/src/backends/local/local_file_system.dart
@@ -0,0 +1,72 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:file/src/io.dart' as io;
+import 'package:file/file.dart';
+import 'package:path/path.dart' as p;
+
+import 'local_directory.dart';
+import 'local_file.dart';
+import 'local_link.dart';
+
+/// A wrapper implementation around `dart:io`'s implementation.
+///
+/// Since this implementation of the [FileSystem] interface delegates to
+/// `dart:io`, is is not suitable for use in the browser.
+class LocalFileSystem extends FileSystem {
+ /// Creates a new `LocalFileSystem`.
+ const LocalFileSystem();
+
+ @override
+ Directory directory(dynamic path) =>
+ LocalDirectory(this, io.Directory(getPath(path)));
+
+ @override
+ File file(dynamic path) => LocalFile(this, io.File(getPath(path)));
+
+ @override
+ Link link(dynamic path) => LocalLink(this, io.Link(getPath(path)));
+
+ @override
+ p.Context get path => p.Context();
+
+ /// Gets the directory provided by the operating system for creating temporary
+ /// files and directories in. The location of the system temp directory is
+ /// platform-dependent, and may be set by an environment variable.
+ @override
+ Directory get systemTempDirectory =>
+ LocalDirectory(this, io.Directory.systemTemp);
+
+ @override
+ Directory get currentDirectory => directory(io.Directory.current.path);
+
+ @override
+ set currentDirectory(dynamic path) => io.Directory.current = path;
+
+ @override
+ Future<io.FileStat> stat(String path) => io.FileStat.stat(path);
+
+ @override
+ io.FileStat statSync(String path) => io.FileStat.statSync(path);
+
+ @override
+ Future<bool> identical(String path1, String path2) =>
+ io.FileSystemEntity.identical(path1, path2);
+
+ @override
+ bool identicalSync(String path1, String path2) =>
+ io.FileSystemEntity.identicalSync(path1, path2);
+
+ @override
+ bool get isWatchSupported => io.FileSystemEntity.isWatchSupported;
+
+ @override
+ Future<io.FileSystemEntityType> type(String path,
+ {bool followLinks = true}) =>
+ io.FileSystemEntity.type(path, followLinks: followLinks);
+
+ @override
+ io.FileSystemEntityType typeSync(String path, {bool followLinks = true}) =>
+ io.FileSystemEntity.typeSync(path, followLinks: followLinks);
+}
diff --git a/pkgs/file/lib/src/backends/local/local_file_system_entity.dart b/pkgs/file/lib/src/backends/local/local_file_system_entity.dart
new file mode 100644
index 0000000..ca4617b
--- /dev/null
+++ b/pkgs/file/lib/src/backends/local/local_file_system_entity.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:file/file.dart';
+import 'package:file/src/io.dart' as io;
+
+import 'local_directory.dart';
+import 'local_file.dart';
+import 'local_link.dart';
+
+/// [FileSystemEntity] implementation that forwards all calls to `dart:io`.
+abstract class LocalFileSystemEntity<T extends FileSystemEntity,
+ D extends io.FileSystemEntity> extends ForwardingFileSystemEntity<T, D> {
+ /// Instantiates a new [LocalFileSystemEntity] tied to the specified file
+ /// system and delegating to the specified [delegate].
+ LocalFileSystemEntity(this.fileSystem, this.delegate);
+
+ @override
+ final FileSystem fileSystem;
+
+ @override
+ final D delegate;
+
+ @override
+ String get dirname => fileSystem.path.dirname(path);
+
+ @override
+ String get basename => fileSystem.path.basename(path);
+
+ @override
+ Directory wrapDirectory(io.Directory delegate) =>
+ LocalDirectory(fileSystem, delegate);
+
+ @override
+ File wrapFile(io.File delegate) => LocalFile(fileSystem, delegate);
+
+ @override
+ Link wrapLink(io.Link delegate) => LocalLink(fileSystem, delegate);
+}
diff --git a/pkgs/file/lib/src/backends/local/local_link.dart b/pkgs/file/lib/src/backends/local/local_link.dart
new file mode 100644
index 0000000..fc67d5e
--- /dev/null
+++ b/pkgs/file/lib/src/backends/local/local_link.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:file/file.dart';
+import 'package:file/src/io.dart' as io;
+
+import 'local_file_system_entity.dart';
+
+/// [Link] implementation that forwards all calls to `dart:io`.
+class LocalLink extends LocalFileSystemEntity<Link, io.Link>
+ with ForwardingLink {
+ /// Instantiates a new [LocalLink] tied to the specified file system
+ /// and delegating to the specified [delegate].
+ LocalLink(FileSystem fs, io.Link delegate) : super(fs, delegate);
+
+ @override
+ String toString() => "LocalLink: '$path'";
+}
diff --git a/pkgs/file/lib/src/backends/memory.dart b/pkgs/file/lib/src/backends/memory.dart
new file mode 100644
index 0000000..428bc54
--- /dev/null
+++ b/pkgs/file/lib/src/backends/memory.dart
@@ -0,0 +1,6 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+export 'memory/memory_file_system.dart' show MemoryFileSystem;
+export 'memory/style.dart' show FileSystemStyle, StyleableFileSystem;
diff --git a/pkgs/file/lib/src/backends/memory/clock.dart b/pkgs/file/lib/src/backends/memory/clock.dart
new file mode 100644
index 0000000..98d5434
--- /dev/null
+++ b/pkgs/file/lib/src/backends/memory/clock.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Interface describing clocks used by the [MemoryFileSystem].
+///
+/// The [MemoryFileSystem] uses a clock to determine the modification times of
+/// files that are created in that file system.
+abstract class Clock {
+ /// Abstract const constructor. This constructor enables subclasses to provide
+ /// const constructors so that they can be used in const expressions.
+ const Clock();
+
+ /// A real-time clock.
+ ///
+ /// Uses [DateTime.now] to reflect the actual time reported by the operating
+ /// system.
+ const factory Clock.realTime() = _RealtimeClock;
+
+ /// A monotonically-increasing test clock.
+ ///
+ /// Each time [now] is called, the time increases by one minute.
+ ///
+ /// The `start` argument can be used to set the seed time for the clock.
+ /// The first value will be that time plus one minute.
+ /// By default, `start` is midnight on the first of January, 2000.
+ factory Clock.monotonicTest() = _MonotonicTestClock;
+
+ /// Returns the value of the clock.
+ DateTime get now;
+}
+
+class _RealtimeClock extends Clock {
+ const _RealtimeClock();
+
+ @override
+ DateTime get now => DateTime.now();
+}
+
+class _MonotonicTestClock extends Clock {
+ _MonotonicTestClock({
+ DateTime? start,
+ }) : _current = start ?? DateTime(2000);
+
+ DateTime _current;
+
+ @override
+ DateTime get now {
+ _current = _current.add(const Duration(minutes: 1));
+ return _current;
+ }
+}
diff --git a/pkgs/file/lib/src/backends/memory/common.dart b/pkgs/file/lib/src/backends/memory/common.dart
new file mode 100644
index 0000000..80e3c38
--- /dev/null
+++ b/pkgs/file/lib/src/backends/memory/common.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:file/src/common.dart' as common;
+
+/// Generates a path to use in error messages.
+typedef PathGenerator = dynamic Function();
+
+/// Throws a `FileSystemException` if [object] is null.
+void checkExists(Object? object, PathGenerator path) {
+ if (object == null) {
+ throw common.noSuchFileOrDirectory(path() as String);
+ }
+}
diff --git a/pkgs/file/lib/src/backends/memory/memory_directory.dart b/pkgs/file/lib/src/backends/memory/memory_directory.dart
new file mode 100644
index 0000000..95fe542
--- /dev/null
+++ b/pkgs/file/lib/src/backends/memory/memory_directory.dart
@@ -0,0 +1,184 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:file/file.dart';
+import 'package:file/src/common.dart' as common;
+import 'package:file/src/io.dart' as io;
+import 'package:meta/meta.dart';
+
+import 'common.dart';
+import 'memory_file.dart';
+import 'memory_file_system_entity.dart';
+import 'memory_link.dart';
+import 'node.dart';
+import 'operations.dart';
+import 'style.dart';
+import 'utils.dart' as utils;
+
+// Tracks a unique name for system temp directories, per filesystem
+// instance.
+final Expando<int> _systemTempCounter = Expando<int>();
+
+/// Internal implementation of [Directory].
+class MemoryDirectory extends MemoryFileSystemEntity
+ with common.DirectoryAddOnsMixin
+ implements Directory {
+ /// Instantiates a new [MemoryDirectory].
+ MemoryDirectory(NodeBasedFileSystem fileSystem, String path)
+ : super(fileSystem, path);
+
+ @override
+ io.FileSystemEntityType get expectedType => io.FileSystemEntityType.directory;
+
+ @override
+ Uri get uri {
+ return Uri.directory(path,
+ windows: fileSystem.style == FileSystemStyle.windows);
+ }
+
+ @override
+ bool existsSync() {
+ fileSystem.opHandle.call(path, FileSystemOp.exists);
+ return backingOrNull?.stat.type == expectedType;
+ }
+
+ @override
+ Future<Directory> create({bool recursive = false}) async {
+ createSync(recursive: recursive);
+ return this;
+ }
+
+ @override
+ void createSync({bool recursive = false}) {
+ fileSystem.opHandle(path, FileSystemOp.create);
+ Node? node = internalCreateSync(
+ followTailLink: true,
+ visitLinks: true,
+ createChild: (DirectoryNode parent, bool isFinalSegment) {
+ if (recursive || isFinalSegment) {
+ return DirectoryNode(parent);
+ }
+ return null;
+ },
+ );
+ if (node?.type != expectedType) {
+ // There was an existing non-directory node at this object's path
+ throw common.notADirectory(path);
+ }
+ }
+
+ @override
+ Future<Directory> createTemp([String? prefix]) async =>
+ createTempSync(prefix);
+
+ @override
+ Directory createTempSync([String? prefix]) {
+ prefix = '${prefix ?? ''}rand';
+ String fullPath = fileSystem.path.join(path, prefix);
+ String dirname = fileSystem.path.dirname(fullPath);
+ String basename = fileSystem.path.basename(fullPath);
+ DirectoryNode? node = fileSystem.findNode(dirname) as DirectoryNode?;
+ checkExists(node, () => dirname);
+ utils.checkIsDir(node!, () => dirname);
+ int tempCounter = _systemTempCounter[fileSystem] ?? 0;
+ String name() => '$basename$tempCounter';
+ while (node.children.containsKey(name())) {
+ tempCounter++;
+ }
+ _systemTempCounter[fileSystem] = tempCounter;
+ DirectoryNode tempDir = DirectoryNode(node);
+ node.children[name()] = tempDir;
+ return MemoryDirectory(fileSystem, fileSystem.path.join(dirname, name()))
+ ..createSync();
+ }
+
+ @override
+ Future<Directory> rename(String newPath) async => renameSync(newPath);
+
+ @override
+ Directory renameSync(String newPath) => internalRenameSync<DirectoryNode>(
+ newPath,
+ validateOverwriteExistingEntity: (DirectoryNode existingNode) {
+ if (existingNode.children.isNotEmpty) {
+ throw common.directoryNotEmpty(newPath);
+ }
+ },
+ ) as Directory;
+
+ @override
+ Directory get parent =>
+ (backingOrNull?.isRoot ?? false) ? this : super.parent;
+
+ @override
+ Directory get absolute => super.absolute as Directory;
+
+ @override
+ Stream<FileSystemEntity> list({
+ bool recursive = false,
+ bool followLinks = true,
+ }) =>
+ Stream<FileSystemEntity>.fromIterable(listSync(
+ recursive: recursive,
+ followLinks: followLinks,
+ ));
+
+ @override
+ List<FileSystemEntity> listSync({
+ bool recursive = false,
+ bool followLinks = true,
+ }) {
+ DirectoryNode node = backing as DirectoryNode;
+ List<FileSystemEntity> listing = <FileSystemEntity>[];
+ List<_PendingListTask> tasks = <_PendingListTask>[
+ _PendingListTask(
+ node,
+ path.endsWith(fileSystem.path.separator)
+ ? path.substring(0, path.length - 1)
+ : path,
+ <LinkNode>{},
+ ),
+ ];
+ while (tasks.isNotEmpty) {
+ _PendingListTask task = tasks.removeLast();
+ task.dir.children.forEach((String name, Node child) {
+ Set<LinkNode> breadcrumbs = Set<LinkNode>.from(task.breadcrumbs);
+ String childPath = fileSystem.path.join(task.path, name);
+ while (followLinks &&
+ utils.isLink(child) &&
+ breadcrumbs.add(child as LinkNode)) {
+ Node? referent = child.referentOrNull;
+ if (referent != null) {
+ child = referent;
+ }
+ }
+ if (utils.isDirectory(child)) {
+ listing.add(MemoryDirectory(fileSystem, childPath));
+ if (recursive) {
+ tasks.add(_PendingListTask(
+ child as DirectoryNode, childPath, breadcrumbs));
+ }
+ } else if (utils.isLink(child)) {
+ listing.add(MemoryLink(fileSystem, childPath));
+ } else if (utils.isFile(child)) {
+ listing.add(MemoryFile(fileSystem, childPath));
+ }
+ });
+ }
+ return listing;
+ }
+
+ @override
+ @protected
+ Directory clone(String path) => MemoryDirectory(fileSystem, path);
+
+ @override
+ String toString() => "MemoryDirectory: '$path'";
+}
+
+class _PendingListTask {
+ _PendingListTask(this.dir, this.path, this.breadcrumbs);
+ final DirectoryNode dir;
+ final String path;
+ final Set<LinkNode> breadcrumbs;
+}
diff --git a/pkgs/file/lib/src/backends/memory/memory_file.dart b/pkgs/file/lib/src/backends/memory/memory_file.dart
new file mode 100644
index 0000000..ba4faab
--- /dev/null
+++ b/pkgs/file/lib/src/backends/memory/memory_file.dart
@@ -0,0 +1,470 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:math' as math show min;
+import 'dart:typed_data';
+
+import 'package:file/file.dart';
+import 'package:file/src/backends/memory/operations.dart';
+import 'package:file/src/common.dart' as common;
+import 'package:file/src/io.dart' as io;
+import 'package:meta/meta.dart';
+
+import 'common.dart';
+import 'memory_file_system_entity.dart';
+import 'memory_random_access_file.dart';
+import 'node.dart';
+import 'utils.dart' as utils;
+
+/// Internal implementation of [File].
+class MemoryFile extends MemoryFileSystemEntity implements File {
+ /// Instantiates a new [MemoryFile].
+ const MemoryFile(NodeBasedFileSystem fileSystem, String path)
+ : super(fileSystem, path);
+
+ FileNode get _resolvedBackingOrCreate {
+ Node? node = backingOrNull;
+ if (node == null) {
+ node = _doCreate();
+ } else {
+ node = utils.isLink(node)
+ ? utils.resolveLinks(node as LinkNode, () => path)
+ : node;
+ utils.checkType(expectedType, node.type, () => path);
+ }
+ return node as FileNode;
+ }
+
+ @override
+ io.FileSystemEntityType get expectedType => io.FileSystemEntityType.file;
+
+ @override
+ bool existsSync() {
+ fileSystem.opHandle.call(path, FileSystemOp.exists);
+ return backingOrNull?.stat.type == expectedType;
+ }
+
+ @override
+ Future<File> create({bool recursive = false, bool exclusive = false}) async {
+ createSync(recursive: recursive, exclusive: exclusive);
+ return this;
+ }
+
+ // TODO(dartbug.com/49647): Pass `exclusive` through after it lands.
+ @override
+ void createSync({bool recursive = false, bool exclusive = false}) {
+ fileSystem.opHandle(path, FileSystemOp.create);
+ _doCreate(recursive: recursive /*, exclusive: exclusive*/);
+ }
+
+ Node? _doCreate({bool recursive = false}) {
+ Node? node = internalCreateSync(
+ followTailLink: true,
+ createChild: (DirectoryNode parent, bool isFinalSegment) {
+ if (isFinalSegment) {
+ return FileNode(parent);
+ } else if (recursive) {
+ return DirectoryNode(parent);
+ }
+ return null;
+ },
+ );
+ if (node?.type != expectedType) {
+ // There was an existing non-file entity at this object's path
+ assert(node?.type == FileSystemEntityType.directory);
+ throw common.isADirectory(path);
+ }
+ return node;
+ }
+
+ @override
+ Future<File> rename(String newPath) async => renameSync(newPath);
+
+ @override
+ File renameSync(String newPath) => internalRenameSync(
+ newPath,
+ followTailLink: true,
+ checkType: (Node node) {
+ FileSystemEntityType actualType = node.stat.type;
+ if (actualType != expectedType) {
+ throw actualType == FileSystemEntityType.notFound
+ ? common.noSuchFileOrDirectory(path)
+ : common.isADirectory(path);
+ }
+ },
+ ) as File;
+
+ @override
+ Future<File> copy(String newPath) async => copySync(newPath);
+
+ @override
+ File copySync(String newPath) {
+ fileSystem.opHandle(path, FileSystemOp.copy);
+ FileNode sourceNode = resolvedBacking as FileNode;
+ fileSystem.findNode(
+ newPath,
+ segmentVisitor: (
+ DirectoryNode parent,
+ String childName,
+ Node? child,
+ int currentSegment,
+ int finalSegment,
+ ) {
+ if (currentSegment == finalSegment) {
+ if (child != null) {
+ if (utils.isLink(child)) {
+ List<String> ledger = <String>[];
+ child = utils.resolveLinks(child as LinkNode, () => newPath,
+ ledger: ledger);
+ checkExists(child, () => newPath);
+ parent = child.parent;
+ childName = ledger.last;
+ assert(parent.children.containsKey(childName));
+ }
+ utils.checkType(expectedType, child.type, () => newPath);
+ parent.children.remove(childName);
+ }
+ FileNode newNode = FileNode(parent);
+ newNode.copyFrom(sourceNode);
+ parent.children[childName] = newNode;
+ }
+ return child;
+ },
+ );
+ return clone(newPath);
+ }
+
+ @override
+ Future<int> length() async => lengthSync();
+
+ @override
+ int lengthSync() => (resolvedBacking as FileNode).size;
+
+ @override
+ File get absolute => super.absolute as File;
+
+ @override
+ Future<DateTime> lastAccessed() async => lastAccessedSync();
+
+ @override
+ DateTime lastAccessedSync() => (resolvedBacking as FileNode).stat.accessed;
+
+ @override
+ Future<dynamic> setLastAccessed(DateTime time) async =>
+ setLastAccessedSync(time);
+
+ @override
+ void setLastAccessedSync(DateTime time) {
+ FileNode node = resolvedBacking as FileNode;
+ node.accessed = time.millisecondsSinceEpoch;
+ }
+
+ @override
+ Future<DateTime> lastModified() async => lastModifiedSync();
+
+ @override
+ DateTime lastModifiedSync() => (resolvedBacking as FileNode).stat.modified;
+
+ @override
+ Future<dynamic> setLastModified(DateTime time) async =>
+ setLastModifiedSync(time);
+
+ @override
+ void setLastModifiedSync(DateTime time) {
+ FileNode node = resolvedBacking as FileNode;
+ node.modified = time.millisecondsSinceEpoch;
+ }
+
+ @override
+ Future<io.RandomAccessFile> open(
+ {io.FileMode mode = io.FileMode.read}) async =>
+ openSync(mode: mode);
+
+ @override
+ io.RandomAccessFile openSync({io.FileMode mode = io.FileMode.read}) {
+ fileSystem.opHandle(path, FileSystemOp.open);
+ if (utils.isWriteMode(mode) && !existsSync()) {
+ // [resolvedBacking] requires that the file already exists, so we must
+ // create it here first.
+ createSync();
+ }
+
+ return MemoryRandomAccessFile(path, resolvedBacking as FileNode, mode);
+ }
+
+ @override
+ Stream<List<int>> openRead([int? start, int? end]) {
+ fileSystem.opHandle(path, FileSystemOp.open);
+ try {
+ FileNode node = resolvedBacking as FileNode;
+ Uint8List content = node.content;
+ if (start != null) {
+ content = end == null
+ ? content.sublist(start)
+ : content.sublist(start, math.min(end, content.length));
+ }
+ return Stream.value(content);
+ } catch (e) {
+ return Stream.error(e);
+ }
+ }
+
+ @override
+ io.IOSink openWrite({
+ io.FileMode mode = io.FileMode.write,
+ Encoding encoding = utf8,
+ }) {
+ fileSystem.opHandle(path, FileSystemOp.open);
+ if (!utils.isWriteMode(mode)) {
+ throw ArgumentError.value(mode, 'mode',
+ 'Must be either WRITE, APPEND, WRITE_ONLY, or WRITE_ONLY_APPEND');
+ }
+ return _FileSink.fromFile(this, mode, encoding);
+ }
+
+ @override
+ Future<Uint8List> readAsBytes() async => readAsBytesSync();
+
+ @override
+ Uint8List readAsBytesSync() {
+ fileSystem.opHandle(path, FileSystemOp.read);
+ return Uint8List.fromList((resolvedBacking as FileNode).content);
+ }
+
+ @override
+ Future<String> readAsString({Encoding encoding = utf8}) async =>
+ readAsStringSync(encoding: encoding);
+
+ @override
+ String readAsStringSync({Encoding encoding = utf8}) {
+ try {
+ return encoding.decode(readAsBytesSync());
+ } on FormatException catch (err) {
+ throw FileSystemException(err.message, path);
+ }
+ }
+
+ @override
+ Future<List<String>> readAsLines({Encoding encoding = utf8}) async =>
+ readAsLinesSync(encoding: encoding);
+
+ @override
+ List<String> readAsLinesSync({Encoding encoding = utf8}) {
+ String str = readAsStringSync(encoding: encoding);
+
+ if (str.isEmpty) {
+ return <String>[];
+ }
+
+ final List<String> lines = str.split('\n');
+ if (str.endsWith('\n')) {
+ // A final newline should not create an additional line.
+ lines.removeLast();
+ }
+
+ return lines;
+ }
+
+ @override
+ Future<File> writeAsBytes(
+ List<int> bytes, {
+ io.FileMode mode = io.FileMode.write,
+ bool flush = false,
+ }) async {
+ writeAsBytesSync(bytes, mode: mode, flush: flush);
+ return this;
+ }
+
+ @override
+ void writeAsBytesSync(
+ List<int> bytes, {
+ io.FileMode mode = io.FileMode.write,
+ bool flush = false,
+ }) {
+ if (!utils.isWriteMode(mode)) {
+ throw common.badFileDescriptor(path);
+ }
+ FileNode node = _resolvedBackingOrCreate;
+ _truncateIfNecessary(node, mode);
+ fileSystem.opHandle(path, FileSystemOp.write);
+ node.write(bytes);
+ node.touch();
+ }
+
+ @override
+ Future<File> writeAsString(
+ String contents, {
+ io.FileMode mode = io.FileMode.write,
+ Encoding encoding = utf8,
+ bool flush = false,
+ }) async {
+ writeAsStringSync(contents, mode: mode, encoding: encoding, flush: flush);
+ return this;
+ }
+
+ @override
+ void writeAsStringSync(
+ String contents, {
+ io.FileMode mode = io.FileMode.write,
+ Encoding encoding = utf8,
+ bool flush = false,
+ }) =>
+ writeAsBytesSync(encoding.encode(contents), mode: mode, flush: flush);
+
+ @override
+ @protected
+ File clone(String path) => MemoryFile(fileSystem, path);
+
+ void _truncateIfNecessary(FileNode node, io.FileMode mode) {
+ if (mode == io.FileMode.write || mode == io.FileMode.writeOnly) {
+ node.clear();
+ }
+ }
+
+ @override
+ String toString() => "MemoryFile: '$path'";
+}
+
+/// Implementation of an [io.IOSink] that's backed by a [FileNode].
+class _FileSink implements io.IOSink {
+ factory _FileSink.fromFile(
+ MemoryFile file,
+ io.FileMode mode,
+ Encoding encoding,
+ ) {
+ late FileNode node;
+ Exception? deferredException;
+
+ // Resolve the backing immediately to ensure that the [FileNode] we write
+ // to is the same as when [openWrite] was called. This can matter if the
+ // file is moved or removed while open.
+ try {
+ node = file._resolvedBackingOrCreate;
+ } on Exception catch (e) {
+ // For behavioral consistency with [LocalFile], do not report failures
+ // immediately.
+ deferredException = e;
+ }
+
+ Future<FileNode> future = Future<FileNode>.microtask(() {
+ if (deferredException != null) {
+ throw deferredException;
+ }
+ file._truncateIfNecessary(node, mode);
+ return node;
+ });
+ return _FileSink._(future, encoding);
+ }
+
+ _FileSink._(Future<FileNode> node, this.encoding) : _pendingWrites = node;
+
+ final Completer<void> _completer = Completer<void>();
+
+ Future<FileNode> _pendingWrites;
+ Completer<void>? _streamCompleter;
+ bool _isClosed = false;
+
+ @override
+ Encoding encoding;
+
+ bool get isStreaming => !(_streamCompleter?.isCompleted ?? true);
+
+ @override
+ void add(List<int> data) {
+ _checkNotStreaming();
+ if (_isClosed) {
+ throw StateError('StreamSink is closed');
+ }
+
+ _addData(data);
+ }
+
+ @override
+ void write(Object? obj) => add(encoding.encode(obj?.toString() ?? 'null'));
+
+ @override
+ void writeAll(Iterable<dynamic> objects, [String separator = '']) {
+ bool firstIter = true;
+ for (dynamic obj in objects) {
+ if (!firstIter) {
+ write(separator);
+ }
+ firstIter = false;
+ write(obj);
+ }
+ }
+
+ @override
+ void writeln([Object? obj = '']) {
+ write(obj);
+ write('\n');
+ }
+
+ @override
+ void writeCharCode(int charCode) => write(String.fromCharCode(charCode));
+
+ @override
+ void addError(Object error, [StackTrace? stackTrace]) {
+ _checkNotStreaming();
+ _completer.completeError(error, stackTrace);
+ }
+
+ @override
+ Future<void> addStream(Stream<List<int>> stream) {
+ _checkNotStreaming();
+ _streamCompleter = Completer<void>();
+
+ stream.listen(
+ (List<int> data) => _addData(data),
+ cancelOnError: true,
+ onError: (Object error, StackTrace stackTrace) {
+ _streamCompleter!.completeError(error, stackTrace);
+ _streamCompleter = null;
+ },
+ onDone: () {
+ _streamCompleter!.complete();
+ _streamCompleter = null;
+ },
+ );
+ return _streamCompleter!.future;
+ }
+
+ @override
+ Future<void> flush() {
+ _checkNotStreaming();
+ return _pendingWrites;
+ }
+
+ @override
+ Future<void> close() {
+ _checkNotStreaming();
+ if (!_isClosed) {
+ _isClosed = true;
+ _pendingWrites.then(
+ (_) => _completer.complete(),
+ onError: (Object error, StackTrace stackTrace) =>
+ _completer.completeError(error, stackTrace),
+ );
+ }
+ return _completer.future;
+ }
+
+ @override
+ Future<void> get done => _completer.future;
+
+ void _addData(List<int> data) {
+ _pendingWrites = _pendingWrites.then((FileNode node) {
+ node.write(data);
+ return node;
+ });
+ }
+
+ void _checkNotStreaming() {
+ if (isStreaming) {
+ throw StateError('StreamSink is bound to a stream');
+ }
+ }
+}
diff --git a/pkgs/file/lib/src/backends/memory/memory_file_stat.dart b/pkgs/file/lib/src/backends/memory/memory_file_stat.dart
new file mode 100644
index 0000000..94f86d1
--- /dev/null
+++ b/pkgs/file/lib/src/backends/memory/memory_file_stat.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:file/src/io.dart' as io;
+
+/// Internal implementation of [io.FileStat].
+class MemoryFileStat implements io.FileStat {
+ /// Creates a new [MemoryFileStat] with the specified properties.
+ const MemoryFileStat(
+ this.changed,
+ this.modified,
+ this.accessed,
+ this.type,
+ this.mode,
+ this.size,
+ );
+
+ MemoryFileStat._internalNotFound()
+ : changed = DateTime(0),
+ modified = DateTime(0),
+ accessed = DateTime(0),
+ type = io.FileSystemEntityType.notFound,
+ mode = 0,
+ size = -1;
+
+ /// Shared instance representing a non-existent entity.
+ static final MemoryFileStat notFound = MemoryFileStat._internalNotFound();
+
+ @override
+ final DateTime changed;
+
+ @override
+ final DateTime modified;
+
+ @override
+ final DateTime accessed;
+
+ @override
+ final io.FileSystemEntityType type;
+
+ @override
+ final int mode;
+
+ @override
+ final int size;
+
+ @override
+ String modeString() {
+ int permissions = mode & 0xFFF;
+ List<String> codes = const <String>[
+ '---',
+ '--x',
+ '-w-',
+ '-wx',
+ 'r--',
+ 'r-x',
+ 'rw-',
+ 'rwx',
+ ];
+ List<String> result = <String>[];
+ result
+ ..add(codes[(permissions >> 6) & 0x7])
+ ..add(codes[(permissions >> 3) & 0x7])
+ ..add(codes[permissions & 0x7]);
+ return result.join();
+ }
+}
diff --git a/pkgs/file/lib/src/backends/memory/memory_file_system.dart b/pkgs/file/lib/src/backends/memory/memory_file_system.dart
new file mode 100644
index 0000000..f3cdaee
--- /dev/null
+++ b/pkgs/file/lib/src/backends/memory/memory_file_system.dart
@@ -0,0 +1,282 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:file/file.dart';
+import 'package:file/src/backends/memory/operations.dart';
+import 'package:file/src/io.dart' as io;
+import 'package:path/path.dart' as p;
+
+import 'clock.dart';
+import 'common.dart';
+import 'memory_directory.dart';
+import 'memory_file.dart';
+import 'memory_file_stat.dart';
+import 'memory_link.dart';
+import 'node.dart';
+import 'style.dart';
+import 'utils.dart' as utils;
+
+const String _thisDir = '.';
+const String _parentDir = '..';
+
+void _defaultOpHandle(String context, FileSystemOp operation) {}
+
+/// An implementation of [FileSystem] that exists entirely in memory with an
+/// internal representation loosely based on the Filesystem Hierarchy Standard.
+///
+/// [MemoryFileSystem] is suitable for mocking and tests, as well as for
+/// caching or staging before writing or reading to a live system.
+///
+/// This implementation of the [FileSystem] interface does not directly use
+/// any `dart:io` APIs; it merely uses the library's enum values and interfaces.
+/// As such, it is suitable for use in the browser.
+abstract class MemoryFileSystem implements StyleableFileSystem {
+ /// Creates a new `MemoryFileSystem`.
+ ///
+ /// The file system will be empty, and the current directory will be the
+ /// root directory.
+ ///
+ /// The clock will be a real-time clock; file modification times will
+ /// reflect the real time as reported by the operating system.
+ ///
+ /// If [style] is specified, the file system will use the specified path
+ /// style. The default is [FileSystemStyle.posix].
+ factory MemoryFileSystem({
+ FileSystemStyle style = FileSystemStyle.posix,
+ void Function(String context, FileSystemOp operation) opHandle =
+ _defaultOpHandle,
+ }) =>
+ _MemoryFileSystem(
+ style: style,
+ clock: const Clock.realTime(),
+ opHandle: opHandle,
+ );
+
+ /// Creates a new `MemoryFileSystem` that has a fake clock.
+ ///
+ /// The file system will be empty, and the current directory will be the
+ /// root directory.
+ ///
+ /// The clock will increase monotonically each time it is used, disconnected
+ /// from any real-world clock.
+ ///
+ /// If [style] is specified, the file system will use the specified path
+ /// style. The default is [FileSystemStyle.posix].
+ factory MemoryFileSystem.test({
+ FileSystemStyle style = FileSystemStyle.posix,
+ void Function(String context, FileSystemOp operation) opHandle =
+ _defaultOpHandle,
+ }) =>
+ _MemoryFileSystem(
+ style: style,
+ clock: Clock.monotonicTest(),
+ opHandle: opHandle,
+ );
+}
+
+/// Internal implementation of [MemoryFileSystem].
+class _MemoryFileSystem extends FileSystem
+ implements MemoryFileSystem, NodeBasedFileSystem {
+ _MemoryFileSystem({
+ this.style = FileSystemStyle.posix,
+ required this.clock,
+ this.opHandle = _defaultOpHandle,
+ }) : _context = style.contextFor(style.root) {
+ _root = RootNode(this);
+ }
+
+ RootNode? _root;
+ String? _systemTemp;
+ p.Context _context;
+
+ @override
+ final Function(String context, FileSystemOp operation) opHandle;
+
+ @override
+ final Clock clock;
+
+ @override
+ final FileSystemStyle style;
+
+ @override
+ RootNode? get root => _root;
+
+ @override
+ String get cwd => _context.current;
+
+ @override
+ Directory directory(dynamic path) => MemoryDirectory(this, getPath(path));
+
+ @override
+ File file(dynamic path) => MemoryFile(this, getPath(path));
+
+ @override
+ Link link(dynamic path) => MemoryLink(this, getPath(path));
+
+ @override
+ p.Context get path => _context;
+
+ /// Gets the system temp directory. This directory will be created on-demand
+ /// in the root of the file system. Once created, its location is fixed for
+ /// the life of the process.
+ @override
+ Directory get systemTempDirectory {
+ _systemTemp ??= directory(style.root).createTempSync('.tmp_').path;
+ return directory(_systemTemp)..createSync();
+ }
+
+ @override
+ Directory get currentDirectory => directory(cwd);
+
+ @override
+ set currentDirectory(dynamic path) {
+ String value;
+ if (path is io.Directory) {
+ value = path.path;
+ } else if (path is String) {
+ value = path;
+ } else {
+ throw ArgumentError('Invalid type for "path": ${path?.runtimeType}');
+ }
+
+ value = directory(value).resolveSymbolicLinksSync();
+ Node? node = findNode(value);
+ checkExists(node, () => value);
+ utils.checkIsDir(node!, () => value);
+ assert(_context.isAbsolute(value));
+ _context = style.contextFor(value);
+ }
+
+ @override
+ Future<io.FileStat> stat(String path) async => statSync(path);
+
+ @override
+ io.FileStat statSync(String path) {
+ try {
+ return findNode(path)?.stat ?? MemoryFileStat.notFound;
+ } on io.FileSystemException {
+ return MemoryFileStat.notFound;
+ }
+ }
+
+ @override
+ Future<bool> identical(String path1, String path2) async =>
+ identicalSync(path1, path2);
+
+ @override
+ bool identicalSync(String path1, String path2) {
+ Node? node1 = findNode(path1);
+ checkExists(node1, () => path1);
+ Node? node2 = findNode(path2);
+ checkExists(node2, () => path2);
+ return node1 != null && node1 == node2;
+ }
+
+ @override
+ bool get isWatchSupported => false;
+
+ @override
+ Future<io.FileSystemEntityType> type(
+ String path, {
+ bool followLinks = true,
+ }) async =>
+ typeSync(path, followLinks: followLinks);
+
+ @override
+ io.FileSystemEntityType typeSync(String path, {bool followLinks = true}) {
+ Node? node;
+ try {
+ node = findNode(path, followTailLink: followLinks);
+ } on io.FileSystemException {
+ node = null;
+ }
+ if (node == null) {
+ return io.FileSystemEntityType.notFound;
+ }
+ return node.type;
+ }
+
+ /// Gets the node backing for the current working directory. Note that this
+ /// can return null if the directory has been deleted or moved from under our
+ /// feet.
+ DirectoryNode? get _current => findNode(cwd) as DirectoryNode?;
+
+ @override
+ Node? findNode(
+ String path, {
+ Node? reference,
+ SegmentVisitor? segmentVisitor,
+ bool visitLinks = false,
+ List<String>? pathWithSymlinks,
+ bool followTailLink = false,
+ }) {
+ if (path.isEmpty) {
+ return null;
+ } else if (_context.isAbsolute(path)) {
+ reference = _root;
+ path = path.substring(style.drive.length);
+ } else {
+ reference ??= _current;
+ }
+
+ List<String> parts = path.split(style.separator)
+ ..removeWhere(utils.isEmpty);
+ DirectoryNode? directory = reference?.directory;
+ Node? child = directory;
+
+ int finalSegment = parts.length - 1;
+ for (int i = 0; i <= finalSegment; i++) {
+ String basename = parts[i];
+ assert(basename.isNotEmpty);
+
+ switch (basename) {
+ case _thisDir:
+ child = directory;
+ break;
+ case _parentDir:
+ child = directory?.parent;
+ directory = directory?.parent;
+ break;
+ default:
+ child = directory?.children[basename];
+ }
+
+ if (pathWithSymlinks != null) {
+ pathWithSymlinks.add(basename);
+ }
+
+ // Generates a subpath for the current segment.
+ String subpath() => parts.sublist(0, i + 1).join(_context.separator);
+
+ if (utils.isLink(child) && (i < finalSegment || followTailLink)) {
+ if (visitLinks || segmentVisitor == null) {
+ if (segmentVisitor != null) {
+ child =
+ segmentVisitor(directory!, basename, child, i, finalSegment);
+ }
+ child = utils.resolveLinks(child as LinkNode, subpath,
+ ledger: pathWithSymlinks);
+ } else {
+ child = utils.resolveLinks(
+ child as LinkNode,
+ subpath,
+ ledger: pathWithSymlinks,
+ tailVisitor: (DirectoryNode parent, String childName, Node? child) {
+ return segmentVisitor(parent, childName, child, i, finalSegment);
+ },
+ );
+ }
+ } else if (segmentVisitor != null) {
+ child = segmentVisitor(directory!, basename, child, i, finalSegment);
+ }
+
+ if (i < finalSegment) {
+ checkExists(child, subpath);
+ utils.checkIsDir(child!, subpath);
+ directory = child as DirectoryNode;
+ }
+ }
+ return child;
+ }
+}
diff --git a/pkgs/file/lib/src/backends/memory/memory_file_system_entity.dart b/pkgs/file/lib/src/backends/memory/memory_file_system_entity.dart
new file mode 100644
index 0000000..ad987d7
--- /dev/null
+++ b/pkgs/file/lib/src/backends/memory/memory_file_system_entity.dart
@@ -0,0 +1,309 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:file/file.dart';
+import 'package:file/src/common.dart' as common;
+import 'package:file/src/io.dart' as io;
+import 'package:meta/meta.dart';
+
+import 'common.dart';
+import 'memory_directory.dart';
+import 'node.dart';
+import 'operations.dart';
+import 'style.dart';
+import 'utils.dart' as utils;
+
+/// Validator function for use with `_renameSync`. This will be invoked if the
+/// rename would overwrite an existing entity at the new path. If this operation
+/// should not be allowed, this function is expected to throw a
+/// [io.FileSystemException]. The lack of such an exception will be interpreted
+/// as the overwrite being permissible.
+typedef RenameOverwriteValidator<T extends Node> = void Function(
+ T existingNode);
+
+/// Base class for all in-memory file system entity types.
+abstract class MemoryFileSystemEntity implements FileSystemEntity {
+ /// Constructor for subclasses.
+ const MemoryFileSystemEntity(this.fileSystem, this.path);
+
+ @override
+ final NodeBasedFileSystem fileSystem;
+
+ @override
+ final String path;
+
+ @override
+ String get dirname => fileSystem.path.dirname(path);
+
+ @override
+ String get basename => fileSystem.path.basename(path);
+
+ /// Returns the expected type of this entity, which may differ from the type
+ /// of the node that's found at the path specified by this entity.
+ io.FileSystemEntityType get expectedType;
+
+ /// Gets the node that backs this file system entity, or null if this
+ /// entity does not exist.
+ @protected
+ Node? get backingOrNull {
+ try {
+ return fileSystem.findNode(path);
+ } on io.FileSystemException {
+ return null;
+ }
+ }
+
+ /// Gets the node that backs this file system entity. Throws a
+ /// [io.FileSystemException] if this entity doesn't exist.
+ ///
+ /// The type of the node is not guaranteed to match [expectedType].
+ @protected
+ Node get backing {
+ Node? node = fileSystem.findNode(path);
+ checkExists(node, () => path);
+ return node!;
+ }
+
+ /// Gets the node that backs this file system entity, or if that node is
+ /// a symbolic link, the target node. This also will check that the type of
+ /// the node (after symlink resolution) matches [expectedType]. If the type
+ /// doesn't match, this will throw a [io.FileSystemException].
+ @protected
+ Node get resolvedBacking {
+ Node node = backing;
+ node = utils.isLink(node)
+ ? utils.resolveLinks(node as LinkNode, () => path)
+ : node;
+ utils.checkType(expectedType, node.type, () => path);
+ return node;
+ }
+
+ /// Checks the expected type of this file system entity against the specified
+ /// node's `stat` type, throwing a [FileSystemException] if the types don't
+ /// match. Note that since this checks the node's `stat` type, symbolic links
+ /// will be resolved to their target type for the purpose of this validation.
+ ///
+ /// Protected methods that accept a `checkType` argument will default to this
+ /// method if the `checkType` argument is unspecified.
+ @protected
+ void defaultCheckType(Node node) {
+ utils.checkType(expectedType, node.stat.type, () => path);
+ }
+
+ @override
+ Uri get uri {
+ return Uri.file(path, windows: fileSystem.style == FileSystemStyle.windows);
+ }
+
+ @override
+ Future<bool> exists() async => existsSync();
+
+ @override
+ Future<String> resolveSymbolicLinks() async => resolveSymbolicLinksSync();
+
+ @override
+ String resolveSymbolicLinksSync() {
+ if (path.isEmpty) {
+ throw common.noSuchFileOrDirectory(path);
+ }
+ List<String> ledger = <String>[];
+ if (isAbsolute) {
+ ledger.add(fileSystem.style.drive);
+ }
+ Node? node = fileSystem.findNode(path,
+ pathWithSymlinks: ledger, followTailLink: true);
+ checkExists(node, () => path);
+ String resolved = ledger.join(fileSystem.path.separator);
+ if (resolved == fileSystem.style.drive) {
+ resolved = fileSystem.style.root;
+ } else if (!fileSystem.path.isAbsolute(resolved)) {
+ resolved = fileSystem.cwd + fileSystem.path.separator + resolved;
+ }
+ return fileSystem.path.normalize(resolved);
+ }
+
+ @override
+ Future<io.FileStat> stat() => fileSystem.stat(path);
+
+ @override
+ io.FileStat statSync() => fileSystem.statSync(path);
+
+ @override
+ Future<FileSystemEntity> delete({bool recursive = false}) async {
+ deleteSync(recursive: recursive);
+ return this;
+ }
+
+ @override
+ void deleteSync({bool recursive = false}) =>
+ internalDeleteSync(recursive: recursive);
+
+ @override
+ Stream<io.FileSystemEvent> watch({
+ int events = io.FileSystemEvent.all,
+ bool recursive = false,
+ }) =>
+ throw UnsupportedError('Watching not supported in MemoryFileSystem');
+
+ @override
+ bool get isAbsolute => fileSystem.path.isAbsolute(path);
+
+ @override
+ FileSystemEntity get absolute {
+ String absolutePath = path;
+ if (!fileSystem.path.isAbsolute(absolutePath)) {
+ absolutePath = fileSystem.path.join(fileSystem.cwd, absolutePath);
+ }
+ return clone(absolutePath);
+ }
+
+ @override
+ Directory get parent => MemoryDirectory(fileSystem, dirname);
+
+ /// Helper method for subclasses wishing to synchronously create this entity.
+ /// This method will traverse the path to this entity one segment at a time,
+ /// calling [createChild] for each segment whose child does not already exist.
+ ///
+ /// When [createChild] is invoked:
+ /// - `parent` will be the parent node for the current segment and is
+ /// guaranteed to be non-null.
+ /// - `isFinalSegment` will indicate whether the current segment is the tail
+ /// segment, which in turn indicates that this is the segment into which to
+ /// create the node for this entity.
+ ///
+ /// This method returns with the backing node for the entity at this [path].
+ /// If an entity already existed at this path, [createChild] will not be
+ /// invoked at all, and this method will return with the backing node for the
+ /// existing entity (whose type may differ from this entity's type).
+ ///
+ /// If [followTailLink] is true and the result node is a link, this will
+ /// resolve it to its target prior to returning it.
+ @protected
+ Node? internalCreateSync({
+ required Node? Function(DirectoryNode parent, bool isFinalSegment)
+ createChild,
+ bool followTailLink = false,
+ bool visitLinks = false,
+ }) {
+ return fileSystem.findNode(
+ path,
+ followTailLink: followTailLink,
+ visitLinks: visitLinks,
+ segmentVisitor: (
+ DirectoryNode parent,
+ String childName,
+ Node? child,
+ int currentSegment,
+ int finalSegment,
+ ) {
+ if (child == null) {
+ assert(!parent.children.containsKey(childName));
+ child = createChild(parent, currentSegment == finalSegment);
+ if (child != null) {
+ parent.children[childName] = child;
+ }
+ }
+ return child;
+ },
+ );
+ }
+
+ /// Helper method for subclasses wishing to synchronously rename this entity.
+ /// This method will look for an existing file system entity at the location
+ /// identified by [newPath], and if it finds an existing entity, it will check
+ /// the following:
+ ///
+ /// - If the entity is of a different type than this entity, the operation
+ /// will fail, and a [io.FileSystemException] will be thrown.
+ /// - If the caller has specified [validateOverwriteExistingEntity], then that
+ /// method will be invoked and passed the node backing of the existing
+ /// entity that would overwritten by the rename action. That callback is
+ /// expected to throw a [io.FileSystemException] if overwriting the existing
+ /// entity is not allowed.
+ ///
+ /// If the previous two checks pass, or if there was no existing entity at
+ /// the specified location, this will perform the rename.
+ ///
+ /// If [newPath] cannot be traversed to because its directory does not exist,
+ /// a [io.FileSystemException] will be thrown.
+ ///
+ /// If [followTailLink] is true and there is an existing link at the location
+ /// identified by [newPath], this will resolve the link to its target prior
+ /// to running the validation checks above.
+ ///
+ /// If [checkType] is specified, it will be used to validate that the file
+ /// system entity that exists at [path] is of the expected type. By default,
+ /// [defaultCheckType] is used to perform this validation.
+ @protected
+ FileSystemEntity internalRenameSync<T extends Node>(
+ String newPath, {
+ RenameOverwriteValidator<T>? validateOverwriteExistingEntity,
+ bool followTailLink = false,
+ utils.TypeChecker? checkType,
+ }) {
+ Node node = backing;
+ (checkType ?? defaultCheckType)(node);
+ fileSystem.findNode(
+ newPath,
+ segmentVisitor: (
+ DirectoryNode parent,
+ String childName,
+ Node? child,
+ int currentSegment,
+ int finalSegment,
+ ) {
+ if (currentSegment == finalSegment) {
+ if (child != null) {
+ if (followTailLink) {
+ FileSystemEntityType childType = child.stat.type;
+ if (childType != FileSystemEntityType.notFound) {
+ utils.checkType(expectedType, child.stat.type, () => newPath);
+ }
+ } else {
+ utils.checkType(expectedType, child.type, () => newPath);
+ }
+ if (validateOverwriteExistingEntity != null) {
+ validateOverwriteExistingEntity(child as T);
+ }
+ parent.children.remove(childName);
+ }
+ node.parent.children.remove(basename);
+ parent.children[childName] = node;
+ node.parent = parent;
+ }
+ return child;
+ },
+ );
+ return clone(newPath);
+ }
+
+ /// Deletes this entity from the node tree.
+ ///
+ /// If [checkType] is specified, it will be used to validate that the file
+ /// system entity that exists at [path] is of the expected type. By default,
+ /// [defaultCheckType] is used to perform this validation.
+ @protected
+ void internalDeleteSync({
+ bool recursive = false,
+ utils.TypeChecker? checkType,
+ }) {
+ fileSystem.opHandle(path, FileSystemOp.delete);
+ Node node = backing;
+ if (!recursive) {
+ if (node is DirectoryNode && node.children.isNotEmpty) {
+ throw common.directoryNotEmpty(path);
+ }
+ (checkType ?? defaultCheckType)(node);
+ }
+ // Once we remove this reference, the node and all its children will be
+ // garbage collected; we don't need to explicitly delete all children in
+ // the recursive:true case.
+ node.parent.children.remove(basename);
+ }
+
+ /// Creates a new entity with the same type as this entity but with the
+ /// specified path.
+ @protected
+ FileSystemEntity clone(String path);
+}
diff --git a/pkgs/file/lib/src/backends/memory/memory_link.dart b/pkgs/file/lib/src/backends/memory/memory_link.dart
new file mode 100644
index 0000000..7d5afb4
--- /dev/null
+++ b/pkgs/file/lib/src/backends/memory/memory_link.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:file/file.dart';
+import 'package:file/src/common.dart' as common;
+import 'package:file/src/io.dart' as io;
+import 'package:meta/meta.dart';
+
+import 'memory_file_system_entity.dart';
+import 'node.dart';
+import 'operations.dart';
+import 'utils.dart' as utils;
+
+/// Internal implementation of [Link].
+class MemoryLink extends MemoryFileSystemEntity implements Link {
+ /// Instantiates a new [MemoryLink].
+ const MemoryLink(NodeBasedFileSystem fileSystem, String path)
+ : super(fileSystem, path);
+
+ @override
+ io.FileSystemEntityType get expectedType => io.FileSystemEntityType.link;
+
+ @override
+ bool existsSync() {
+ fileSystem.opHandle.call(path, FileSystemOp.exists);
+ return backingOrNull?.type == expectedType;
+ }
+
+ @override
+ Future<Link> rename(String newPath) async => renameSync(newPath);
+
+ @override
+ Link renameSync(String newPath) => internalRenameSync(
+ newPath,
+ checkType: (Node node) {
+ if (node.type != expectedType) {
+ throw node.type == FileSystemEntityType.directory
+ ? common.isADirectory(newPath)
+ : common.invalidArgument(newPath);
+ }
+ },
+ ) as Link;
+
+ @override
+ Future<Link> create(String target, {bool recursive = false}) async {
+ createSync(target, recursive: recursive);
+ return this;
+ }
+
+ @override
+ void createSync(String target, {bool recursive = false}) {
+ bool preexisting = true;
+ fileSystem.opHandle(path, FileSystemOp.create);
+ internalCreateSync(
+ createChild: (DirectoryNode parent, bool isFinalSegment) {
+ if (isFinalSegment) {
+ preexisting = false;
+ return LinkNode(parent, target);
+ } else if (recursive) {
+ return DirectoryNode(parent);
+ }
+ return null;
+ });
+ if (preexisting) {
+ // Per the spec, this is an error.
+ throw common.fileExists(path);
+ }
+ }
+
+ @override
+ Future<Link> update(String target) async {
+ updateSync(target);
+ return this;
+ }
+
+ @override
+ void updateSync(String target) {
+ Node node = backing;
+ utils.checkType(expectedType, node.type, () => path);
+ (node as LinkNode).target = target;
+ }
+
+ @override
+ void deleteSync({bool recursive = false}) => internalDeleteSync(
+ recursive: recursive,
+ checkType: (Node node) =>
+ utils.checkType(expectedType, node.type, () => path),
+ );
+
+ @override
+ Future<String> target() async => targetSync();
+
+ @override
+ String targetSync() {
+ Node node = backing;
+ if (node.type != expectedType) {
+ // Note: this may change; https://github.com/dart-lang/sdk/issues/28204
+ throw common.noSuchFileOrDirectory(path);
+ }
+ return (node as LinkNode).target;
+ }
+
+ @override
+ Link get absolute => super.absolute as Link;
+
+ @override
+ @protected
+ Link clone(String path) => MemoryLink(fileSystem, path);
+
+ @override
+ String toString() => "MemoryLink: '$path'";
+}
diff --git a/pkgs/file/lib/src/backends/memory/memory_random_access_file.dart b/pkgs/file/lib/src/backends/memory/memory_random_access_file.dart
new file mode 100644
index 0000000..d4fe73d
--- /dev/null
+++ b/pkgs/file/lib/src/backends/memory/memory_random_access_file.dart
@@ -0,0 +1,390 @@
+// 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:math' as math show min;
+import 'dart:typed_data';
+
+import 'package:file/src/common.dart' as common;
+import 'package:file/src/io.dart' as io;
+
+import 'memory_file.dart';
+import 'node.dart';
+import 'utils.dart' as utils;
+
+/// A [MemoryFileSystem]-backed implementation of [io.RandomAccessFile].
+class MemoryRandomAccessFile implements io.RandomAccessFile {
+ /// Constructs a [MemoryRandomAccessFile].
+ ///
+ /// This should be used only by [MemoryFile.open] or [MemoryFile.openSync].
+ MemoryRandomAccessFile(this.path, this._node, this._mode) {
+ switch (_mode) {
+ case io.FileMode.read:
+ break;
+ case io.FileMode.write:
+ case io.FileMode.writeOnly:
+ truncateSync(0);
+ break;
+ case io.FileMode.append:
+ case io.FileMode.writeOnlyAppend:
+ _position = lengthSync();
+ break;
+ default:
+ // [FileMode] provides no way of retrieving its value or name.
+ throw UnimplementedError('Unsupported FileMode');
+ }
+ }
+
+ @override
+ final String path;
+
+ final FileNode _node;
+ final io.FileMode _mode;
+
+ bool _isOpen = true;
+ int _position = 0;
+
+ /// Whether an asynchronous operation is pending.
+ ///
+ /// See [_asyncWrapper] for details.
+ bool get _asyncOperationPending => __asyncOperationPending;
+
+ set _asyncOperationPending(bool value) {
+ assert(__asyncOperationPending != value);
+ __asyncOperationPending = value;
+ }
+
+ bool __asyncOperationPending = false;
+
+ /// Throws a [io.FileSystemException] if an operation is attempted on a file
+ /// that is not open.
+ void _checkOpen() {
+ if (!_isOpen) {
+ throw io.FileSystemException('File closed', path);
+ }
+ }
+
+ /// Throws a [io.FileSystemException] if attempting to read from a file that
+ /// has not been opened for reading.
+ void _checkReadable(String operation) {
+ switch (_mode) {
+ case io.FileMode.read:
+ case io.FileMode.write:
+ case io.FileMode.append:
+ return;
+ case io.FileMode.writeOnly:
+ case io.FileMode.writeOnlyAppend:
+ default:
+ throw io.FileSystemException(
+ '$operation failed', path, common.badFileDescriptor(path).osError);
+ }
+ }
+
+ /// Throws a [io.FileSystemException] if attempting to read from a file that
+ /// has not been opened for writing.
+ void _checkWritable(String operation) {
+ if (utils.isWriteMode(_mode)) {
+ return;
+ }
+
+ throw io.FileSystemException(
+ '$operation failed', path, common.badFileDescriptor(path).osError);
+ }
+
+ /// Throws a [io.FileSystemException] if attempting to perform an operation
+ /// while an asynchronous operation is already in progress.
+ ///
+ /// See [_asyncWrapper] for details.
+ void _checkAsync() {
+ if (_asyncOperationPending) {
+ throw io.FileSystemException(
+ 'An async operation is currently pending', path);
+ }
+ }
+
+ /// Wraps a synchronous function to make it appear asynchronous.
+ ///
+ /// [_asyncOperationPending], [_checkAsync], and [_asyncWrapper] are used to
+ /// mimic [RandomAccessFile]'s enforcement that only one asynchronous
+ /// operation is pending for a [RandomAccessFile] instance. Since
+ /// [MemoryFileSystem]-based classes are likely to be used in tests, fidelity
+ /// is important to catch errors that might occur in production.
+ ///
+ /// [_asyncWrapper] does not call [f] directly since setting and unsetting
+ /// [_asyncOperationPending] synchronously would not be meaningful. We
+ /// instead execute [f] through a [Future.delayed] callback to better simulate
+ /// asynchrony.
+ Future<R> _asyncWrapper<R>(R Function() f) async {
+ _checkAsync();
+
+ _asyncOperationPending = true;
+ try {
+ return await Future<R>.delayed(
+ Duration.zero,
+ () {
+ // Temporarily reset [_asyncOpPending] in case [f]'s has its own
+ // checks for pending asynchronous operations.
+ _asyncOperationPending = false;
+ try {
+ return f();
+ } finally {
+ _asyncOperationPending = true;
+ }
+ },
+ );
+ } finally {
+ _asyncOperationPending = false;
+ }
+ }
+
+ @override
+ Future<void> close() async => _asyncWrapper(closeSync);
+
+ @override
+ void closeSync() {
+ _checkOpen();
+ _isOpen = false;
+ }
+
+ @override
+ Future<io.RandomAccessFile> flush() async {
+ await _asyncWrapper(flushSync);
+ return this;
+ }
+
+ @override
+ void flushSync() {
+ _checkOpen();
+ _checkAsync();
+ }
+
+ @override
+ Future<int> length() => _asyncWrapper(lengthSync);
+
+ @override
+ int lengthSync() {
+ _checkOpen();
+ _checkAsync();
+ return _node.size;
+ }
+
+ @override
+ Future<io.RandomAccessFile> lock([
+ io.FileLock mode = io.FileLock.exclusive,
+ int start = 0,
+ int end = -1,
+ ]) async {
+ await _asyncWrapper(() => lockSync(mode, start, end));
+ return this;
+ }
+
+ @override
+ void lockSync([
+ io.FileLock mode = io.FileLock.exclusive,
+ int start = 0,
+ int end = -1,
+ ]) {
+ _checkOpen();
+ _checkAsync();
+ // TODO(jamesderlin): Implement, https://github.com/google/file.dart/issues/140
+ throw UnimplementedError('TODO');
+ }
+
+ @override
+ Future<int> position() => _asyncWrapper(positionSync);
+
+ @override
+ int positionSync() {
+ _checkOpen();
+ _checkAsync();
+ return _position;
+ }
+
+ @override
+ Future<Uint8List> read(int bytes) => _asyncWrapper(() => readSync(bytes));
+
+ @override
+ Uint8List readSync(int bytes) {
+ _checkOpen();
+ _checkAsync();
+ _checkReadable('read');
+ // TODO(jamesderlin): Check for integer overflow.
+ final int end = math.min(_position + bytes, lengthSync());
+ final Uint8List copy = _node.content.sublist(_position, end);
+ _position = end;
+ return copy;
+ }
+
+ @override
+ Future<int> readByte() => _asyncWrapper(readByteSync);
+
+ @override
+ int readByteSync() {
+ _checkOpen();
+ _checkAsync();
+ _checkReadable('readByte');
+
+ if (_position >= lengthSync()) {
+ return -1;
+ }
+ return _node.content[_position++];
+ }
+
+ @override
+ Future<int> readInto(List<int> buffer, [int start = 0, int? end]) =>
+ _asyncWrapper(() => readIntoSync(buffer, start, end));
+
+ @override
+ int readIntoSync(List<int> buffer, [int start = 0, int? end]) {
+ _checkOpen();
+ _checkAsync();
+ _checkReadable('readInto');
+
+ end = RangeError.checkValidRange(start, end, buffer.length);
+
+ final int length = lengthSync();
+ int i;
+ for (i = start; i < end && _position < length; i += 1, _position += 1) {
+ buffer[i] = _node.content[_position];
+ }
+ return i - start;
+ }
+
+ @override
+ Future<io.RandomAccessFile> setPosition(int position) async {
+ await _asyncWrapper(() => setPositionSync(position));
+ return this;
+ }
+
+ @override
+ void setPositionSync(int position) {
+ _checkOpen();
+ _checkAsync();
+
+ if (position < 0) {
+ throw io.FileSystemException(
+ 'setPosition failed', path, common.invalidArgument(path).osError);
+ }
+
+ // Empirical testing indicates that setting the position to be beyond the
+ // end of the file is legal and will zero-fill upon the next write.
+ _position = position;
+ }
+
+ @override
+ Future<io.RandomAccessFile> truncate(int length) async {
+ await _asyncWrapper(() => truncateSync(length));
+ return this;
+ }
+
+ @override
+ void truncateSync(int length) {
+ _checkOpen();
+ _checkAsync();
+
+ if (length < 0 || !utils.isWriteMode(_mode)) {
+ throw io.FileSystemException(
+ 'truncate failed', path, common.invalidArgument(path).osError);
+ }
+
+ final int oldLength = lengthSync();
+ if (length < oldLength) {
+ _node.truncate(length);
+
+ // [_position] is intentionally left untouched to match the observed
+ // behavior of [RandomAccessFile].
+ } else if (length > oldLength) {
+ _node.write(Uint8List(length - oldLength));
+ }
+ assert(lengthSync() == length);
+ }
+
+ @override
+ Future<io.RandomAccessFile> unlock([int start = 0, int end = -1]) async {
+ await _asyncWrapper(() => unlockSync(start, end));
+ return this;
+ }
+
+ @override
+ void unlockSync([int start = 0, int end = -1]) {
+ _checkOpen();
+ _checkAsync();
+ // TODO(jamesderlin): Implement, https://github.com/google/file.dart/issues/140
+ throw UnimplementedError('TODO');
+ }
+
+ @override
+ Future<io.RandomAccessFile> writeByte(int value) async {
+ await _asyncWrapper(() => writeByteSync(value));
+ return this;
+ }
+
+ @override
+ int writeByteSync(int value) {
+ _checkOpen();
+ _checkAsync();
+ _checkWritable('writeByte');
+
+ // [Uint8List] will truncate values to 8-bits automatically, so we don't
+ // need to check [value].
+
+ int length = lengthSync();
+ if (_position >= length) {
+ // If [_position] is out of bounds, [RandomAccessFile] zero-fills the
+ // file.
+ truncateSync(_position + 1);
+ length = lengthSync();
+ }
+ assert(_position < length);
+ _node.content[_position++] = value;
+
+ // Despite what the documentation states, [RandomAccessFile.writeByteSync]
+ // always seems to return 1, even if we had to extend the file for an out of
+ // bounds write. See https://github.com/dart-lang/sdk/issues/42298.
+ return 1;
+ }
+
+ @override
+ Future<io.RandomAccessFile> writeFrom(
+ List<int> buffer, [
+ int start = 0,
+ int? end,
+ ]) async {
+ await _asyncWrapper(() => writeFromSync(buffer, start, end));
+ return this;
+ }
+
+ @override
+ void writeFromSync(List<int> buffer, [int start = 0, int? end]) {
+ _checkOpen();
+ _checkAsync();
+ _checkWritable('writeFrom');
+
+ end = RangeError.checkValidRange(start, end, buffer.length);
+
+ final int writeByteCount = end - start;
+ final int endPosition = _position + writeByteCount;
+
+ if (endPosition > lengthSync()) {
+ truncateSync(endPosition);
+ }
+
+ _node.content.setRange(_position, endPosition, buffer, start);
+ _position = endPosition;
+ }
+
+ @override
+ Future<io.RandomAccessFile> writeString(
+ String string, {
+ Encoding encoding = utf8,
+ }) async {
+ await _asyncWrapper(() => writeStringSync(string, encoding: encoding));
+ return this;
+ }
+
+ @override
+ void writeStringSync(String string, {Encoding encoding = utf8}) {
+ writeFromSync(encoding.encode(string));
+ }
+}
diff --git a/pkgs/file/lib/src/backends/memory/node.dart b/pkgs/file/lib/src/backends/memory/node.dart
new file mode 100644
index 0000000..ae4d3f7
--- /dev/null
+++ b/pkgs/file/lib/src/backends/memory/node.dart
@@ -0,0 +1,358 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:typed_data';
+
+import 'package:file/file.dart';
+import 'package:file/src/backends/memory/operations.dart';
+import 'package:file/src/io.dart' as io;
+
+import 'clock.dart';
+import 'common.dart';
+import 'memory_file_stat.dart';
+import 'style.dart';
+
+/// Visitor callback for use with [NodeBasedFileSystem.findNode].
+///
+/// [parent] is the parent node of the current path segment and is guaranteed
+/// to be non-null.
+///
+/// [childName] is the basename of the entity at the current path segment. It
+/// is guaranteed to be non-null.
+///
+/// [childNode] is the node at the current path segment. It will be
+/// non-null only if such an entity exists. The return value of this callback
+/// will be used as the value of this node, which allows this callback to
+/// do things like recursively create or delete folders.
+///
+/// [currentSegment] is the index of the current segment within the overall
+/// path that's being walked by [NodeBasedFileSystem.findNode].
+///
+/// [finalSegment] is the index of the final segment that will be walked by
+/// [NodeBasedFileSystem.findNode].
+typedef SegmentVisitor = Node? Function(
+ DirectoryNode parent,
+ String childName,
+ Node? childNode,
+ int currentSegment,
+ int finalSegment,
+);
+
+/// A [FileSystem] whose internal structure is made up of a tree of [Node]
+/// instances, rooted at a single node.
+abstract class NodeBasedFileSystem implements StyleableFileSystem {
+ /// An optional handle to hook into common file system operations.
+ void Function(String context, FileSystemOp operation) get opHandle;
+
+ /// The root node.
+ RootNode? get root;
+
+ /// The path of the current working directory.
+ String get cwd;
+
+ /// The clock to use when finding the current time (e.g. to set the creation
+ /// time of a new node).
+ Clock get clock;
+
+ /// Gets the backing node of the entity at the specified path. If the tail
+ /// element of the path does not exist, this will return null. If the tail
+ /// element cannot be reached because its directory does not exist, a
+ /// [io.FileSystemException] will be thrown.
+ ///
+ /// If [path] is a relative path, it will be resolved relative to
+ /// [reference], or the current working directory ([cwd]) if [reference] is
+ /// null. If [path] is an absolute path, [reference] will be ignored.
+ ///
+ /// If the last element in [path] represents a symbolic link, this will
+ /// return the [LinkNode] node for the link (it will not return the
+ /// node to which the link points), unless [followTailLink] is true.
+ /// Directory links in the _middle_ of the path will be followed in order to
+ /// find the node regardless of the value of [followTailLink].
+ ///
+ /// If [segmentVisitor] is specified, it will be invoked for every path
+ /// segment visited along the way starting where the reference (root folder
+ /// if the path is absolute) is the parent. For each segment, the return value
+ /// of [segmentVisitor] will be used as the backing node of that path
+ /// segment, thus allowing callers to create nodes on demand in the
+ /// specified path. Note that `..` and `.` segments may cause the visitor to
+ /// get invoked with the same node multiple times. When [segmentVisitor] is
+ /// invoked, for each path segment that resolves to a link node, the visitor
+ /// will visit the actual link node if [visitLinks] is true; otherwise it
+ /// will visit the target of the link node.
+ ///
+ /// If [pathWithSymlinks] is specified, the path to the node with symbolic
+ /// links explicitly broken out will be appended to the buffer. `..` and `.`
+ /// path segments will *not* be resolved and are left to the caller.
+ Node? findNode(
+ String path, {
+ Node reference,
+ SegmentVisitor segmentVisitor,
+ bool visitLinks = false,
+ List<String> pathWithSymlinks,
+ bool followTailLink = false,
+ });
+}
+
+/// A class that represents the actual storage of an existent file system
+/// entity (whereas classes [File], [Directory], and [Link] represent less
+/// concrete entities that may or may not yet exist).
+///
+/// This data structure is loosely based on a Unix-style file system inode
+/// (hence the name).
+abstract class Node {
+ /// Constructs a new [Node] as a child of the specified parent.
+ Node(this._parent) {
+ if (_parent == null && !isRoot) {
+ throw const io.FileSystemException('All nodes must have a parent.');
+ }
+ }
+
+ DirectoryNode? _parent;
+
+ /// Gets the directory that holds this node.
+ DirectoryNode get parent => _parent!;
+
+ /// Reparents this node to live in the specified directory.
+ set parent(DirectoryNode parent) {
+ DirectoryNode ancestor = parent;
+ while (!ancestor.isRoot) {
+ if (ancestor == this) {
+ throw const io.FileSystemException(
+ 'A directory cannot be its own ancestor.');
+ }
+ ancestor = ancestor.parent;
+ }
+ _parent = parent;
+ }
+
+ /// Returns the type of the file system entity that this node represents.
+ io.FileSystemEntityType get type;
+
+ /// Returns the POSIX stat information for this file system object.
+ io.FileStat get stat;
+
+ /// Returns the closest directory in the ancestry hierarchy starting with
+ /// this node. For directory nodes, it returns the node itself; for other
+ /// nodes, it returns the parent node.
+ DirectoryNode get directory => _parent!;
+
+ /// Tells if this node is a root node.
+ bool get isRoot => false;
+
+ /// Returns the file system responsible for this node.
+ NodeBasedFileSystem get fs => _parent!.fs;
+}
+
+/// Base class that represents the backing for those nodes that have
+/// substance (namely, node types that will not redirect to other types when
+/// you call [stat] on them).
+abstract class RealNode extends Node {
+ /// Constructs a new [RealNode] as a child of the specified [parent].
+ RealNode(DirectoryNode? parent) : super(parent) {
+ int now = clock.now.millisecondsSinceEpoch;
+ changed = now;
+ modified = now;
+ accessed = now;
+ }
+
+ /// See [NodeBasedFileSystem.clock].
+ Clock get clock => parent.clock;
+
+ /// Last changed time in milliseconds since the Epoch.
+ late int changed;
+
+ /// Last modified time in milliseconds since the Epoch.
+ late int modified;
+
+ /// Last accessed time in milliseconds since the Epoch.
+ late int accessed;
+
+ /// Bitmask representing the file read/write/execute mode.
+ int mode = 0x777;
+
+ @override
+ io.FileStat get stat {
+ return MemoryFileStat(
+ DateTime.fromMillisecondsSinceEpoch(changed),
+ DateTime.fromMillisecondsSinceEpoch(modified),
+ DateTime.fromMillisecondsSinceEpoch(accessed),
+ type,
+ mode,
+ size,
+ );
+ }
+
+ /// The size of the file system entity in bytes.
+ int get size;
+
+ /// Updates the last modified time of the node.
+ void touch() {
+ modified = clock.now.millisecondsSinceEpoch;
+ }
+}
+
+/// Class that represents the backing for an in-memory directory.
+class DirectoryNode extends RealNode {
+ /// Constructs a new [DirectoryNode] as a child of the specified [parent].
+ DirectoryNode(DirectoryNode? parent) : super(parent);
+
+ /// Child nodes, indexed by their basename.
+ final Map<String, Node> children = <String, Node>{};
+
+ @override
+ io.FileSystemEntityType get type => io.FileSystemEntityType.directory;
+
+ @override
+ DirectoryNode get directory => this;
+
+ @override
+ int get size => 0;
+}
+
+/// Class that represents the backing for the root of the in-memory file system.
+class RootNode extends DirectoryNode {
+ /// Constructs a new [RootNode] tied to the specified file system.
+ RootNode(this.fs)
+ : assert(fs.root == null),
+ super(null);
+
+ @override
+ final NodeBasedFileSystem fs;
+
+ @override
+ Clock get clock => fs.clock;
+
+ @override
+ DirectoryNode get parent => this;
+
+ @override
+ bool get isRoot => true;
+
+ @override
+ set parent(DirectoryNode parent) =>
+ throw UnsupportedError('Cannot set the parent of the root directory.');
+}
+
+/// Class that represents the backing for an in-memory regular file.
+class FileNode extends RealNode {
+ /// Constructs a new [FileNode] as a child of the specified [parent].
+ FileNode(DirectoryNode parent) : super(parent);
+
+ /// File contents in bytes.
+ Uint8List get content => _content;
+ Uint8List _content = Uint8List(0);
+
+ @override
+ io.FileSystemEntityType get type => io.FileSystemEntityType.file;
+
+ @override
+ int get size => _content.length;
+
+ /// Appends the specified bytes to the end of this node's [content].
+ void write(List<int> bytes) {
+ Uint8List existing = _content;
+ _content = Uint8List(existing.length + bytes.length);
+ _content.setRange(0, existing.length, existing);
+ _content.setRange(existing.length, _content.length, bytes);
+ }
+
+ /// Truncates this node's [content] to the specified length.
+ ///
+ /// [length] must be in the range \[0, [size]\].
+ void truncate(int length) {
+ assert(length >= 0);
+ assert(length <= _content.length);
+ _content = _content.sublist(0, length);
+ }
+
+ /// Clears the [content] of the node.
+ void clear() {
+ _content = Uint8List(0);
+ }
+
+ /// Copies data from [source] into this node. The [modified] and [changed]
+ /// fields will be reset as opposed to copied to indicate that this file
+ /// has been modified and changed.
+ void copyFrom(FileNode source) {
+ modified = changed = clock.now.millisecondsSinceEpoch;
+ accessed = source.accessed;
+ mode = source.mode;
+ _content = Uint8List.fromList(source.content);
+ }
+}
+
+/// Class that represents the backing for an in-memory symbolic link.
+class LinkNode extends Node {
+ /// Constructs a new [LinkNode] as a child of the specified [parent] and
+ /// linking to the specified [target] path.
+ LinkNode(DirectoryNode parent, this.target)
+ : assert(target.isNotEmpty),
+ super(parent);
+
+ /// The path to which this link points.
+ String target;
+
+ /// A marker used to detect circular link references.
+ bool _reentrant = false;
+
+ /// Gets the node backing for this link's target. Throws a
+ /// [FileSystemException] if this link references a non-existent file
+ /// system entity.
+ ///
+ /// If [tailVisitor] is specified, it will be invoked for the tail path
+ /// segment of this link's target, and its return value will be used as the
+ /// return value of this method. If the tail path segment of this link's
+ /// target cannot be traversed into, a [FileSystemException] will be thrown,
+ /// and [tailVisitor] will not be invoked.
+ Node getReferent({
+ Node? Function(DirectoryNode parent, String childName, Node? child)?
+ tailVisitor,
+ }) {
+ Node? referent = fs.findNode(
+ target,
+ reference: this,
+ segmentVisitor: (
+ DirectoryNode parent,
+ String childName,
+ Node? child,
+ int currentSegment,
+ int finalSegment,
+ ) {
+ if (tailVisitor != null && currentSegment == finalSegment) {
+ child = tailVisitor(parent, childName, child);
+ }
+ return child;
+ },
+ );
+ checkExists(referent, () => target);
+ return referent!;
+ }
+
+ /// Gets the node backing for this link's target, or null if this link
+ /// references a non-existent file system entity.
+ Node? get referentOrNull {
+ try {
+ return getReferent();
+ } on io.FileSystemException {
+ return null;
+ }
+ }
+
+ @override
+ io.FileSystemEntityType get type => io.FileSystemEntityType.link;
+
+ @override
+ io.FileStat get stat {
+ if (_reentrant) {
+ return MemoryFileStat.notFound;
+ }
+ _reentrant = true;
+ try {
+ Node? node = referentOrNull;
+ return node == null ? MemoryFileStat.notFound : node.stat;
+ } finally {
+ _reentrant = false;
+ }
+ }
+}
diff --git a/pkgs/file/lib/src/backends/memory/operations.dart b/pkgs/file/lib/src/backends/memory/operations.dart
new file mode 100644
index 0000000..9fc7462
--- /dev/null
+++ b/pkgs/file/lib/src/backends/memory/operations.dart
@@ -0,0 +1,86 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// A file system operation used by the [MemoryFileSytem] to allow
+/// tests to insert errors for certain operations.
+///
+/// This is not implemented as an enum to allow new values to be added in a
+/// backwards compatible manner.
+class FileSystemOp {
+ const FileSystemOp._(this._value);
+
+ // This field added to ensure const values can be different.
+ // ignore: unused_field
+ final int _value;
+
+ /// A file system operation used for all read methods.
+ ///
+ /// * [FileSystemEntity.readAsString]
+ /// * [FileSystemEntity.readAsStringSync]
+ /// * [FileSystemEntity.readAsBytes]
+ /// * [FileSystemEntity.readAsBytesSync]
+ static const FileSystemOp read = FileSystemOp._(0);
+
+ /// A file system operation used for all write methods.
+ ///
+ /// * [FileSystemEntity.writeAsString]
+ /// * [FileSystemEntity.writeAsStringSync]
+ /// * [FileSystemEntity.writeAsBytes]
+ /// * [FileSystemEntity.writeAsBytesSync]
+ static const FileSystemOp write = FileSystemOp._(1);
+
+ /// A file system operation used for all delete methods.
+ ///
+ /// * [FileSystemEntity.delete]
+ /// * [FileSystemEntity.deleteSync]
+ static const FileSystemOp delete = FileSystemOp._(2);
+
+ /// A file system operation used for all create methods.
+ ///
+ /// * [FileSystemEntity.create]
+ /// * [FileSystemEntity.createSync]
+ static const FileSystemOp create = FileSystemOp._(3);
+
+ /// A file operation used for all open methods.
+ ///
+ /// * [File.open]
+ /// * [File.openSync]
+ /// * [File.openRead]
+ /// * [File.openWrite]
+ static const FileSystemOp open = FileSystemOp._(4);
+
+ /// A file operation used for all copy methods.
+ ///
+ /// * [File.copy]
+ /// * [File.copySync]
+ static const FileSystemOp copy = FileSystemOp._(5);
+
+ /// A file system operation used for all exists methods.
+ ///
+ /// * [FileSystemEntity.exists]
+ /// * [FileSystemEntity.existsSync]
+ static const FileSystemOp exists = FileSystemOp._(6);
+
+ @override
+ String toString() {
+ switch (_value) {
+ case 0:
+ return 'FileSystemOp.read';
+ case 1:
+ return 'FileSystemOp.write';
+ case 2:
+ return 'FileSystemOp.delete';
+ case 3:
+ return 'FileSystemOp.create';
+ case 4:
+ return 'FileSystemOp.open';
+ case 5:
+ return 'FileSystemOp.copy';
+ case 6:
+ return 'FileSystemOp.exists';
+ default:
+ throw StateError('Invalid FileSytemOp type: $this');
+ }
+ }
+}
diff --git a/pkgs/file/lib/src/backends/memory/style.dart b/pkgs/file/lib/src/backends/memory/style.dart
new file mode 100644
index 0000000..701c9d0
--- /dev/null
+++ b/pkgs/file/lib/src/backends/memory/style.dart
@@ -0,0 +1,98 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:file/file.dart';
+import 'package:path/path.dart' as p;
+
+/// Class that represents the path style that a memory file system should
+/// adopt.
+///
+/// This is primarily useful if you want to test how your code will behave
+/// when faced with particular paths or particular path separator characters.
+/// For instance, you may want to test that your code will work on Windows,
+/// while still using a memory file system in order to gain hermeticity in your
+/// tests.
+abstract class FileSystemStyle {
+ const FileSystemStyle._();
+
+ /// Mimics the Unix file system style.
+ ///
+ /// * This style does not have the notion of drives
+ /// * All file system paths are rooted at `/`
+ /// * The path separator is `/`
+ ///
+ /// An example path in this style is `/path/to/file`.
+ static const FileSystemStyle posix = _Posix();
+
+ /// Mimics the Windows file system style.
+ ///
+ /// * This style mounts its root folder on a single root drive (`C:`)
+ /// * All file system paths are rooted at `C:\`
+ /// * The path separator is `\`
+ ///
+ /// An example path in this style is `C:\path\to\file`.
+ static const FileSystemStyle windows = _Windows();
+
+ /// The drive upon which the root directory is mounted.
+ ///
+ /// While real-world file systems that have the notion of drives will support
+ /// multiple drives per system, memory file system will only support one
+ /// root drive.
+ ///
+ /// This will be the empty string for styles that don't have the notion of
+ /// drives (e.g. [posix]).
+ String get drive;
+
+ /// The String that represents the delineation between a directory and its
+ /// children.
+ String get separator;
+
+ /// The string that represents the root of the file system.
+ ///
+ /// Memory file system is always single-rooted.
+ String get root => '$drive$separator';
+
+ /// Gets an object useful for manipulating paths in this style.
+ ///
+ /// Relative path manipulations will be relative to the specified [path].
+ p.Context contextFor(String path);
+}
+
+class _Posix extends FileSystemStyle {
+ const _Posix() : super._();
+
+ @override
+ String get drive => '';
+
+ @override
+ String get separator {
+ return p.Style.posix.separator; // ignore: deprecated_member_use
+ }
+
+ @override
+ p.Context contextFor(String path) =>
+ p.Context(style: p.Style.posix, current: path);
+}
+
+class _Windows extends FileSystemStyle {
+ const _Windows() : super._();
+
+ @override
+ String get drive => 'C:';
+
+ @override
+ String get separator {
+ return p.Style.windows.separator; // ignore: deprecated_member_use
+ }
+
+ @override
+ p.Context contextFor(String path) =>
+ p.Context(style: p.Style.windows, current: path);
+}
+
+/// A file system that supports different styles.
+abstract class StyleableFileSystem implements FileSystem {
+ /// The style used by this file system.
+ FileSystemStyle get style;
+}
diff --git a/pkgs/file/lib/src/backends/memory/utils.dart b/pkgs/file/lib/src/backends/memory/utils.dart
new file mode 100644
index 0000000..eec9980
--- /dev/null
+++ b/pkgs/file/lib/src/backends/memory/utils.dart
@@ -0,0 +1,117 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:file/file.dart';
+import 'package:file/src/common.dart' as common;
+import 'package:file/src/io.dart' as io;
+
+import 'common.dart';
+import 'node.dart';
+
+/// Checks if `node.type` returns [io.FileSystemEntityType.FILE].
+bool isFile(Node? node) => node?.type == io.FileSystemEntityType.file;
+
+/// Checks if `node.type` returns [io.FileSystemEntityType.DIRECTORY].
+bool isDirectory(Node? node) => node?.type == io.FileSystemEntityType.directory;
+
+/// Checks if `node.type` returns [io.FileSystemEntityType.LINK].
+bool isLink(Node? node) => node?.type == io.FileSystemEntityType.link;
+
+/// Validator function that is expected to throw a [FileSystemException] if
+/// the node does not represent the type that is expected in any given context.
+typedef TypeChecker = void Function(Node node);
+
+/// Throws a [io.FileSystemException] if [node] is not a directory.
+void checkIsDir(Node node, PathGenerator path) {
+ if (!isDirectory(node)) {
+ throw common.notADirectory(path() as String);
+ }
+}
+
+/// Throws a [io.FileSystemException] if [expectedType] doesn't match
+/// [actualType].
+void checkType(
+ FileSystemEntityType expectedType,
+ FileSystemEntityType actualType,
+ PathGenerator path,
+) {
+ if (expectedType != actualType) {
+ switch (expectedType) {
+ case FileSystemEntityType.directory:
+ throw common.notADirectory(path() as String);
+ case FileSystemEntityType.file:
+ assert(actualType == FileSystemEntityType.directory);
+ throw common.isADirectory(path() as String);
+ case FileSystemEntityType.link:
+ throw common.invalidArgument(path() as String);
+ default:
+ // Should not happen
+ throw AssertionError();
+ }
+ }
+}
+
+/// Tells if the specified file mode represents a write mode.
+bool isWriteMode(io.FileMode mode) =>
+ mode == io.FileMode.write ||
+ mode == io.FileMode.append ||
+ mode == io.FileMode.writeOnly ||
+ mode == io.FileMode.writeOnlyAppend;
+
+/// Tells whether the given string is empty.
+bool isEmpty(String str) => str.isEmpty;
+
+/// Returns the node ultimately referred to by [link]. This will resolve
+/// the link references (following chains of links as necessary) and return
+/// the node at the end of the link chain.
+///
+/// If a loop in the link chain is found, this will throw a
+/// [FileSystemException], calling [path] to generate the path.
+///
+/// If [ledger] is specified, the resolved path to the terminal node will be
+/// appended to the ledger (or overwritten in the ledger if a link target
+/// specified an absolute path). The path will not be normalized, meaning
+/// `..` and `.` path segments may be present.
+///
+/// If [tailVisitor] is specified, it will be invoked for the tail element of
+/// the last link in the symbolic link chain, and its return value will be the
+/// return value of this method (thus allowing callers to create the entity
+/// at the end of the chain on demand).
+Node resolveLinks(
+ LinkNode link,
+ PathGenerator path, {
+ List<String>? ledger,
+ Node? Function(DirectoryNode parent, String childName, Node? child)?
+ tailVisitor,
+}) {
+ // Record a breadcrumb trail to guard against symlink loops.
+ Set<LinkNode> breadcrumbs = <LinkNode>{};
+
+ Node node = link;
+ while (isLink(node)) {
+ link = node as LinkNode;
+ if (!breadcrumbs.add(link)) {
+ throw common.tooManyLevelsOfSymbolicLinks(path() as String);
+ }
+ if (ledger != null) {
+ if (link.fs.path.isAbsolute(link.target)) {
+ ledger.clear();
+ } else if (ledger.isNotEmpty) {
+ ledger.removeLast();
+ }
+ ledger.addAll(link.target.split(link.fs.path.separator));
+ }
+ node = link.getReferent(
+ tailVisitor: (DirectoryNode parent, String childName, Node? child) {
+ if (tailVisitor != null && !isLink(child)) {
+ // Only invoke [tailListener] on the final resolution pass.
+ child = tailVisitor(parent, childName, child);
+ }
+ return child;
+ },
+ );
+ }
+
+ return node;
+}
diff --git a/pkgs/file/lib/src/common.dart b/pkgs/file/lib/src/common.dart
new file mode 100644
index 0000000..6706ec9
--- /dev/null
+++ b/pkgs/file/lib/src/common.dart
@@ -0,0 +1,70 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'interface.dart';
+
+/// Returns a 'No such file or directory' [FileSystemException].
+FileSystemException noSuchFileOrDirectory(String path) {
+ return _fsException(path, 'No such file or directory', ErrorCodes.ENOENT);
+}
+
+/// Returns a 'Not a directory' [FileSystemException].
+FileSystemException notADirectory(String path) {
+ return _fsException(path, 'Not a directory', ErrorCodes.ENOTDIR);
+}
+
+/// Returns a 'Is a directory' [FileSystemException].
+FileSystemException isADirectory(String path) {
+ return _fsException(path, 'Is a directory', ErrorCodes.EISDIR);
+}
+
+/// Returns a 'Directory not empty' [FileSystemException].
+FileSystemException directoryNotEmpty(String path) {
+ return _fsException(path, 'Directory not empty', ErrorCodes.ENOTEMPTY);
+}
+
+/// Returns a 'File exists' [FileSystemException].
+FileSystemException fileExists(String path) {
+ return _fsException(path, 'File exists', ErrorCodes.EEXIST);
+}
+
+/// Returns a 'Invalid argument' [FileSystemException].
+FileSystemException invalidArgument(String path) {
+ return _fsException(path, 'Invalid argument', ErrorCodes.EINVAL);
+}
+
+/// Returns a 'Too many levels of symbolic links' [FileSystemException].
+FileSystemException tooManyLevelsOfSymbolicLinks(String path) {
+ // TODO(tvolkert): Switch to ErrorCodes.EMLINK
+ return _fsException(
+ path, 'Too many levels of symbolic links', ErrorCodes.ELOOP);
+}
+
+/// Returns a 'Bad file descriptor' [FileSystemException].
+FileSystemException badFileDescriptor(String path) {
+ return _fsException(path, 'Bad file descriptor', ErrorCodes.EBADF);
+}
+
+FileSystemException _fsException(String path, String msg, int errorCode) {
+ return FileSystemException(msg, path, OSError(msg, errorCode));
+}
+
+/// Mixin containing implementations of [Directory] methods that are common
+/// to all implementations.
+mixin DirectoryAddOnsMixin implements Directory {
+ @override
+ Directory childDirectory(String basename) {
+ return fileSystem.directory(fileSystem.path.join(path, basename));
+ }
+
+ @override
+ File childFile(String basename) {
+ return fileSystem.file(fileSystem.path.join(path, basename));
+ }
+
+ @override
+ Link childLink(String basename) {
+ return fileSystem.link(fileSystem.path.join(path, basename));
+ }
+}
diff --git a/pkgs/file/lib/src/forwarding.dart b/pkgs/file/lib/src/forwarding.dart
new file mode 100644
index 0000000..9566a30
--- /dev/null
+++ b/pkgs/file/lib/src/forwarding.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+export 'forwarding/forwarding_directory.dart';
+export 'forwarding/forwarding_file.dart';
+export 'forwarding/forwarding_file_system.dart';
+export 'forwarding/forwarding_file_system_entity.dart';
+export 'forwarding/forwarding_link.dart';
+export 'forwarding/forwarding_random_access_file.dart';
diff --git a/pkgs/file/lib/src/forwarding/forwarding_directory.dart b/pkgs/file/lib/src/forwarding/forwarding_directory.dart
new file mode 100644
index 0000000..dba0c8e
--- /dev/null
+++ b/pkgs/file/lib/src/forwarding/forwarding_directory.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:file/src/io.dart' as io;
+import 'package:file/file.dart';
+
+/// A directory that forwards all methods and properties to a delegate.
+mixin ForwardingDirectory<T extends Directory>
+ implements ForwardingFileSystemEntity<T, io.Directory>, Directory {
+ @override
+ T wrap(io.Directory delegate) => wrapDirectory(delegate) as T;
+
+ @override
+ Future<Directory> create({bool recursive = false}) async =>
+ wrap(await delegate.create(recursive: recursive));
+
+ @override
+ void createSync({bool recursive = false}) =>
+ delegate.createSync(recursive: recursive);
+
+ @override
+ Future<Directory> createTemp([String? prefix]) async =>
+ wrap(await delegate.createTemp(prefix));
+
+ @override
+ Directory createTempSync([String? prefix]) =>
+ wrap(delegate.createTempSync(prefix));
+
+ @override
+ Stream<FileSystemEntity> list({
+ bool recursive = false,
+ bool followLinks = true,
+ }) =>
+ delegate.list(recursive: recursive, followLinks: followLinks).map(_wrap);
+
+ @override
+ List<FileSystemEntity> listSync({
+ bool recursive = false,
+ bool followLinks = true,
+ }) =>
+ delegate
+ .listSync(recursive: recursive, followLinks: followLinks)
+ .map(_wrap)
+ .toList();
+
+ FileSystemEntity _wrap(io.FileSystemEntity entity) {
+ if (entity is io.File) {
+ return wrapFile(entity);
+ } else if (entity is io.Directory) {
+ return wrapDirectory(entity);
+ } else if (entity is io.Link) {
+ return wrapLink(entity);
+ }
+ throw FileSystemException('Unsupported type: $entity', entity.path);
+ }
+}
diff --git a/pkgs/file/lib/src/forwarding/forwarding_file.dart b/pkgs/file/lib/src/forwarding/forwarding_file.dart
new file mode 100644
index 0000000..49c211d
--- /dev/null
+++ b/pkgs/file/lib/src/forwarding/forwarding_file.dart
@@ -0,0 +1,156 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+import 'dart:typed_data';
+
+import 'package:file/src/io.dart' as io;
+import 'package:file/file.dart';
+
+/// A file that forwards all methods and properties to a delegate.
+mixin ForwardingFile
+ implements ForwardingFileSystemEntity<File, io.File>, File {
+ @override
+ ForwardingFile wrap(io.File delegate) => wrapFile(delegate) as ForwardingFile;
+
+ // TODO(dartbug.com/49647): Pass `exclusive` through after it lands.
+ @override
+ Future<File> create({bool recursive = false, bool exclusive = false}) async =>
+ wrap(await delegate.create(
+ recursive: recursive /*, exclusive: exclusive*/));
+
+ // TODO(dartbug.com/49647): Pass `exclusive` through after it lands.
+ @override
+ void createSync({bool recursive = false, bool exclusive = false}) =>
+ delegate.createSync(recursive: recursive /*, exclusive: exclusive*/);
+
+ @override
+ Future<File> copy(String newPath) async => wrap(await delegate.copy(newPath));
+
+ @override
+ File copySync(String newPath) => wrap(delegate.copySync(newPath));
+
+ @override
+ Future<int> length() => delegate.length();
+
+ @override
+ int lengthSync() => delegate.lengthSync();
+
+ @override
+ Future<DateTime> lastAccessed() => delegate.lastAccessed();
+
+ @override
+ DateTime lastAccessedSync() => delegate.lastAccessedSync();
+
+ @override
+ Future<dynamic> setLastAccessed(DateTime time) =>
+ delegate.setLastAccessed(time);
+
+ @override
+ void setLastAccessedSync(DateTime time) => delegate.setLastAccessedSync(time);
+
+ @override
+ Future<DateTime> lastModified() => delegate.lastModified();
+
+ @override
+ DateTime lastModifiedSync() => delegate.lastModifiedSync();
+
+ @override
+ Future<dynamic> setLastModified(DateTime time) =>
+ delegate.setLastModified(time);
+
+ @override
+ void setLastModifiedSync(DateTime time) => delegate.setLastModifiedSync(time);
+
+ @override
+ Future<RandomAccessFile> open({
+ FileMode mode = FileMode.read,
+ }) =>
+ delegate.open(mode: mode);
+
+ @override
+ RandomAccessFile openSync({FileMode mode = FileMode.read}) =>
+ delegate.openSync(mode: mode);
+
+ @override
+ Stream<List<int>> openRead([int? start, int? end]) =>
+ delegate.openRead(start, end);
+
+ @override
+ IOSink openWrite({
+ FileMode mode = FileMode.write,
+ Encoding encoding = utf8,
+ }) =>
+ delegate.openWrite(mode: mode, encoding: encoding);
+
+ @override
+ Future<Uint8List> readAsBytes() => delegate.readAsBytes();
+
+ @override
+ Uint8List readAsBytesSync() => delegate.readAsBytesSync();
+
+ @override
+ Future<String> readAsString({Encoding encoding = utf8}) =>
+ delegate.readAsString(encoding: encoding);
+
+ @override
+ String readAsStringSync({Encoding encoding = utf8}) =>
+ delegate.readAsStringSync(encoding: encoding);
+
+ @override
+ Future<List<String>> readAsLines({Encoding encoding = utf8}) =>
+ delegate.readAsLines(encoding: encoding);
+
+ @override
+ List<String> readAsLinesSync({Encoding encoding = utf8}) =>
+ delegate.readAsLinesSync(encoding: encoding);
+
+ @override
+ Future<File> writeAsBytes(
+ List<int> bytes, {
+ FileMode mode = FileMode.write,
+ bool flush = false,
+ }) async =>
+ wrap(await delegate.writeAsBytes(
+ bytes,
+ mode: mode,
+ flush: flush,
+ ));
+
+ @override
+ void writeAsBytesSync(
+ List<int> bytes, {
+ FileMode mode = FileMode.write,
+ bool flush = false,
+ }) =>
+ delegate.writeAsBytesSync(bytes, mode: mode, flush: flush);
+
+ @override
+ Future<File> writeAsString(
+ String contents, {
+ FileMode mode = FileMode.write,
+ Encoding encoding = utf8,
+ bool flush = false,
+ }) async =>
+ wrap(await delegate.writeAsString(
+ contents,
+ mode: mode,
+ encoding: encoding,
+ flush: flush,
+ ));
+
+ @override
+ void writeAsStringSync(
+ String contents, {
+ FileMode mode = FileMode.write,
+ Encoding encoding = utf8,
+ bool flush = false,
+ }) =>
+ delegate.writeAsStringSync(
+ contents,
+ mode: mode,
+ encoding: encoding,
+ flush: flush,
+ );
+}
diff --git a/pkgs/file/lib/src/forwarding/forwarding_file_system.dart b/pkgs/file/lib/src/forwarding/forwarding_file_system.dart
new file mode 100644
index 0000000..d864db9
--- /dev/null
+++ b/pkgs/file/lib/src/forwarding/forwarding_file_system.dart
@@ -0,0 +1,66 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:file/src/io.dart' as io;
+import 'package:file/file.dart';
+import 'package:meta/meta.dart';
+import 'package:path/path.dart' as p;
+
+/// A file system that forwards all methods and properties to a delegate.
+abstract class ForwardingFileSystem extends FileSystem {
+ /// Creates a new [ForwardingFileSystem] that forwards all methods and
+ /// properties to the specified [delegate].
+ ForwardingFileSystem(this.delegate);
+
+ /// The file system to which this file system will forward all activity.
+ @protected
+ final FileSystem delegate;
+
+ @override
+ Directory directory(dynamic path) => delegate.directory(path);
+
+ @override
+ File file(dynamic path) => delegate.file(path);
+
+ @override
+ Link link(dynamic path) => delegate.link(path);
+
+ @override
+ p.Context get path => delegate.path;
+
+ @override
+ Directory get systemTempDirectory => delegate.systemTempDirectory;
+
+ @override
+ Directory get currentDirectory => delegate.currentDirectory;
+
+ @override
+ set currentDirectory(dynamic path) => delegate.currentDirectory = path;
+
+ @override
+ Future<io.FileStat> stat(String path) => delegate.stat(path);
+
+ @override
+ io.FileStat statSync(String path) => delegate.statSync(path);
+
+ @override
+ Future<bool> identical(String path1, String path2) =>
+ delegate.identical(path1, path2);
+
+ @override
+ bool identicalSync(String path1, String path2) =>
+ delegate.identicalSync(path1, path2);
+
+ @override
+ bool get isWatchSupported => delegate.isWatchSupported;
+
+ @override
+ Future<io.FileSystemEntityType> type(String path,
+ {bool followLinks = true}) =>
+ delegate.type(path, followLinks: followLinks);
+
+ @override
+ io.FileSystemEntityType typeSync(String path, {bool followLinks = true}) =>
+ delegate.typeSync(path, followLinks: followLinks);
+}
diff --git a/pkgs/file/lib/src/forwarding/forwarding_file_system_entity.dart b/pkgs/file/lib/src/forwarding/forwarding_file_system_entity.dart
new file mode 100644
index 0000000..3c41b39
--- /dev/null
+++ b/pkgs/file/lib/src/forwarding/forwarding_file_system_entity.dart
@@ -0,0 +1,96 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:file/src/io.dart' as io;
+import 'package:file/file.dart';
+import 'package:meta/meta.dart';
+
+/// A file system entity that forwards all methods and properties to a delegate.
+abstract class ForwardingFileSystemEntity<T extends FileSystemEntity,
+ D extends io.FileSystemEntity> implements FileSystemEntity {
+ /// The entity to which this entity will forward all methods and properties.
+ @protected
+ D get delegate;
+
+ /// Creates a new entity with the same file system and same type as this
+ /// entity but backed by the specified delegate.
+ @protected
+ T wrap(D delegate);
+
+ /// Creates a new directory with the same file system as this entity and
+ /// backed by the specified delegate.
+ @protected
+ Directory wrapDirectory(io.Directory delegate);
+
+ /// Creates a new file with the same file system as this entity and
+ /// backed by the specified delegate.
+ @protected
+ File wrapFile(io.File delegate);
+
+ /// Creates a new link with the same file system as this entity and
+ /// backed by the specified delegate.
+ @protected
+ Link wrapLink(io.Link delegate);
+
+ @override
+ Uri get uri => delegate.uri;
+
+ @override
+ Future<bool> exists() => delegate.exists();
+
+ @override
+ bool existsSync() => delegate.existsSync();
+
+ @override
+ Future<T> rename(String newPath) async =>
+ wrap(await delegate.rename(newPath) as D);
+
+ @override
+ T renameSync(String newPath) => wrap(delegate.renameSync(newPath) as D);
+
+ @override
+ Future<String> resolveSymbolicLinks() => delegate.resolveSymbolicLinks();
+
+ @override
+ String resolveSymbolicLinksSync() => delegate.resolveSymbolicLinksSync();
+
+ @override
+ Future<io.FileStat> stat() => delegate.stat();
+
+ @override
+ io.FileStat statSync() => delegate.statSync();
+
+ @override
+ Future<T> delete({bool recursive = false}) async =>
+ wrap(await delegate.delete(recursive: recursive) as D);
+
+ @override
+ void deleteSync({bool recursive = false}) =>
+ delegate.deleteSync(recursive: recursive);
+
+ @override
+ Stream<FileSystemEvent> watch({
+ int events = FileSystemEvent.all,
+ bool recursive = false,
+ }) =>
+ delegate.watch(events: events, recursive: recursive);
+
+ @override
+ bool get isAbsolute => delegate.isAbsolute;
+
+ @override
+ T get absolute => wrap(delegate.absolute as D);
+
+ @override
+ Directory get parent => wrapDirectory(delegate.parent);
+
+ @override
+ String get path => delegate.path;
+
+ @override
+ String get basename => fileSystem.path.basename(path);
+
+ @override
+ String get dirname => fileSystem.path.dirname(path);
+}
diff --git a/pkgs/file/lib/src/forwarding/forwarding_link.dart b/pkgs/file/lib/src/forwarding/forwarding_link.dart
new file mode 100644
index 0000000..7a60ecb
--- /dev/null
+++ b/pkgs/file/lib/src/forwarding/forwarding_link.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:file/src/io.dart' as io;
+import 'package:file/file.dart';
+
+/// A link that forwards all methods and properties to a delegate.
+mixin ForwardingLink
+ implements ForwardingFileSystemEntity<Link, io.Link>, Link {
+ @override
+ ForwardingLink wrap(io.Link delegate) => wrapLink(delegate) as ForwardingLink;
+
+ @override
+ Future<Link> create(String target, {bool recursive = false}) async =>
+ wrap(await delegate.create(target, recursive: recursive));
+
+ @override
+ void createSync(String target, {bool recursive = false}) =>
+ delegate.createSync(target, recursive: recursive);
+
+ @override
+ Future<Link> update(String target) async =>
+ wrap(await delegate.update(target));
+
+ @override
+ void updateSync(String target) => delegate.updateSync(target);
+
+ @override
+ Future<String> target() => delegate.target();
+
+ @override
+ String targetSync() => delegate.targetSync();
+}
diff --git a/pkgs/file/lib/src/forwarding/forwarding_random_access_file.dart b/pkgs/file/lib/src/forwarding/forwarding_random_access_file.dart
new file mode 100644
index 0000000..9dd4079
--- /dev/null
+++ b/pkgs/file/lib/src/forwarding/forwarding_random_access_file.dart
@@ -0,0 +1,149 @@
+// 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:file/src/io.dart' as io;
+import 'package:meta/meta.dart';
+
+/// A [RandomAccessFile] implementation that forwards all methods and properties
+/// to a delegate.
+mixin ForwardingRandomAccessFile implements io.RandomAccessFile {
+ /// The entity to which this entity will forward all methods and properties.
+ @protected
+ io.RandomAccessFile get delegate;
+
+ @override
+ String get path => delegate.path;
+
+ @override
+ Future<void> close() => delegate.close();
+
+ @override
+ void closeSync() => delegate.closeSync();
+
+ @override
+ Future<io.RandomAccessFile> flush() async {
+ await delegate.flush();
+ return this;
+ }
+
+ @override
+ void flushSync() => delegate.flushSync();
+
+ @override
+ Future<int> length() => delegate.length();
+
+ @override
+ int lengthSync() => delegate.lengthSync();
+
+ @override
+ Future<io.RandomAccessFile> lock([
+ io.FileLock mode = io.FileLock.exclusive,
+ int start = 0,
+ int end = -1,
+ ]) async {
+ await delegate.lock(mode, start, end);
+ return this;
+ }
+
+ @override
+ void lockSync([
+ io.FileLock mode = io.FileLock.exclusive,
+ int start = 0,
+ int end = -1,
+ ]) =>
+ delegate.lockSync(mode, start, end);
+
+ @override
+ Future<int> position() => delegate.position();
+
+ @override
+ int positionSync() => delegate.positionSync();
+
+ @override
+ Future<Uint8List> read(int bytes) => delegate.read(bytes);
+
+ @override
+ Uint8List readSync(int bytes) => delegate.readSync(bytes);
+
+ @override
+ Future<int> readByte() => delegate.readByte();
+
+ @override
+ int readByteSync() => delegate.readByteSync();
+
+ @override
+ Future<int> readInto(List<int> buffer, [int start = 0, int? end]) =>
+ delegate.readInto(buffer, start, end);
+
+ @override
+ int readIntoSync(List<int> buffer, [int start = 0, int? end]) =>
+ delegate.readIntoSync(buffer, start, end);
+
+ @override
+ Future<io.RandomAccessFile> setPosition(int position) async {
+ await delegate.setPosition(position);
+ return this;
+ }
+
+ @override
+ void setPositionSync(int position) => delegate.setPositionSync(position);
+
+ @override
+ Future<io.RandomAccessFile> truncate(int length) async {
+ await delegate.truncate(length);
+ return this;
+ }
+
+ @override
+ void truncateSync(int length) => delegate.truncateSync(length);
+
+ @override
+ Future<io.RandomAccessFile> unlock([int start = 0, int end = -1]) async {
+ await delegate.unlock(start, end);
+ return this;
+ }
+
+ @override
+ void unlockSync([int start = 0, int end = -1]) =>
+ delegate.unlockSync(start, end);
+
+ @override
+ Future<io.RandomAccessFile> writeByte(int value) async {
+ await delegate.writeByte(value);
+ return this;
+ }
+
+ @override
+ int writeByteSync(int value) => delegate.writeByteSync(value);
+
+ @override
+ Future<io.RandomAccessFile> writeFrom(
+ List<int> buffer, [
+ int start = 0,
+ int? end,
+ ]) async {
+ await delegate.writeFrom(buffer, start, end);
+ return this;
+ }
+
+ @override
+ void writeFromSync(List<int> buffer, [int start = 0, int? end]) =>
+ delegate.writeFromSync(buffer, start, end);
+
+ @override
+ Future<io.RandomAccessFile> writeString(
+ String string, {
+ Encoding encoding = utf8,
+ }) async {
+ await delegate.writeString(string, encoding: encoding);
+ return this;
+ }
+
+ @override
+ void writeStringSync(String string, {Encoding encoding = utf8}) =>
+ delegate.writeStringSync(string, encoding: encoding);
+}
diff --git a/pkgs/file/lib/src/interface.dart b/pkgs/file/lib/src/interface.dart
new file mode 100644
index 0000000..4662e35
--- /dev/null
+++ b/pkgs/file/lib/src/interface.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library file.src.interface;
+
+export 'interface/directory.dart';
+export 'interface/error_codes.dart';
+export 'interface/file.dart';
+export 'interface/file_system.dart';
+export 'interface/file_system_entity.dart';
+export 'interface/link.dart';
+export 'io.dart' hide Directory, File, FileSystemEntity, Link;
diff --git a/pkgs/file/lib/src/interface/directory.dart b/pkgs/file/lib/src/interface/directory.dart
new file mode 100644
index 0000000..e62ad8c
--- /dev/null
+++ b/pkgs/file/lib/src/interface/directory.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import '../io.dart' as io;
+
+import 'file.dart';
+import 'file_system_entity.dart';
+import 'link.dart';
+
+/// A reference to a directory on the file system.
+abstract class Directory implements FileSystemEntity, io.Directory {
+ // Override method definitions to codify the return type covariance.
+ @override
+ Future<Directory> create({bool recursive = false});
+
+ @override
+ Future<Directory> createTemp([String? prefix]);
+
+ @override
+ Directory createTempSync([String? prefix]);
+
+ @override
+ Future<Directory> rename(String newPath);
+
+ @override
+ Directory renameSync(String newPath);
+
+ @override
+ Directory get absolute;
+
+ @override
+ Stream<FileSystemEntity> list(
+ {bool recursive = false, bool followLinks = true});
+
+ @override
+ List<FileSystemEntity> listSync(
+ {bool recursive = false, bool followLinks = true});
+
+ /// Returns a reference to a [Directory] that exists as a child of this
+ /// directory and has the specified [basename].
+ Directory childDirectory(String basename);
+
+ /// Returns a reference to a [File] that exists as a child of this directory
+ /// and has the specified [basename].
+ File childFile(String basename);
+
+ /// Returns a reference to a [Link] that exists as a child of this directory
+ /// and has the specified [basename].
+ Link childLink(String basename);
+}
diff --git a/pkgs/file/lib/src/interface/error_codes.dart b/pkgs/file/lib/src/interface/error_codes.dart
new file mode 100644
index 0000000..8943538
--- /dev/null
+++ b/pkgs/file/lib/src/interface/error_codes.dart
@@ -0,0 +1,585 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'error_codes_internal.dart'
+ if (dart.library.io) 'error_codes_dart_io.dart';
+
+/// Operating system error codes.
+// TODO(tvolkert): Remove (https://github.com/dart-lang/sdk/issues/28860)
+class ErrorCodes {
+ ErrorCodes._();
+
+ /// Argument list too long
+ // ignore: non_constant_identifier_names
+ static int get E2BIG => _platform((_Codes codes) => codes.e2big);
+
+ /// Permission denied
+ // ignore: non_constant_identifier_names
+ static int get EACCES => _platform((_Codes codes) => codes.eacces);
+
+ /// Try again
+ // ignore: non_constant_identifier_names
+ static int get EAGAIN => _platform((_Codes codes) => codes.eagain);
+
+ /// Bad file number
+ // ignore: non_constant_identifier_names
+ static int get EBADF => _platform((_Codes codes) => codes.ebadf);
+
+ /// Device or resource busy
+ // ignore: non_constant_identifier_names
+ static int get EBUSY => _platform((_Codes codes) => codes.ebusy);
+
+ /// No child processes
+ // ignore: non_constant_identifier_names
+ static int get ECHILD => _platform((_Codes codes) => codes.echild);
+
+ /// Resource deadlock would occur
+ // ignore: non_constant_identifier_names
+ static int get EDEADLK => _platform((_Codes codes) => codes.edeadlk);
+
+ /// Math argument out of domain of func
+ // ignore: non_constant_identifier_names
+ static int get EDOM => _platform((_Codes codes) => codes.edom);
+
+ /// File exists
+ // ignore: non_constant_identifier_names
+ static int get EEXIST => _platform((_Codes codes) => codes.eexist);
+
+ /// Bad address
+ // ignore: non_constant_identifier_names
+ static int get EFAULT => _platform((_Codes codes) => codes.efault);
+
+ /// File too large
+ // ignore: non_constant_identifier_names
+ static int get EFBIG => _platform((_Codes codes) => codes.efbig);
+
+ /// Illegal byte sequence
+ // ignore: non_constant_identifier_names
+ static int get EILSEQ => _platform((_Codes codes) => codes.eilseq);
+
+ /// Interrupted system call
+ // ignore: non_constant_identifier_names
+ static int get EINTR => _platform((_Codes codes) => codes.eintr);
+
+ /// Invalid argument
+ // ignore: non_constant_identifier_names
+ static int get EINVAL => _platform((_Codes codes) => codes.einval);
+
+ /// I/O error
+ // ignore: non_constant_identifier_names
+ static int get EIO => _platform((_Codes codes) => codes.eio);
+
+ /// Is a directory
+ // ignore: non_constant_identifier_names
+ static int get EISDIR => _platform((_Codes codes) => codes.eisdir);
+
+ /// Too many levels of symbolic links
+ // ignore: non_constant_identifier_names
+ static int get ELOOP => _platform((_Codes codes) => codes.eloop);
+
+ /// Too many open files
+ // ignore: non_constant_identifier_names
+ static int get EMFILE => _platform((_Codes codes) => codes.emfile);
+
+ /// Too many links
+ // ignore: non_constant_identifier_names
+ static int get EMLINK => _platform((_Codes codes) => codes.emlink);
+
+ /// File name too long
+ // ignore: non_constant_identifier_names
+ static int get ENAMETOOLONG =>
+ _platform((_Codes codes) => codes.enametoolong);
+
+ /// File table overflow
+ // ignore: non_constant_identifier_names
+ static int get ENFILE => _platform((_Codes codes) => codes.enfile);
+
+ /// No such device
+ // ignore: non_constant_identifier_names
+ static int get ENODEV => _platform((_Codes codes) => codes.enodev);
+
+ /// No such file or directory
+ // ignore: non_constant_identifier_names
+ static int get ENOENT => _platform((_Codes codes) => codes.enoent);
+
+ /// Exec format error
+ // ignore: non_constant_identifier_names
+ static int get ENOEXEC => _platform((_Codes codes) => codes.enoexec);
+
+ /// No record locks available
+ // ignore: non_constant_identifier_names
+ static int get ENOLCK => _platform((_Codes codes) => codes.enolck);
+
+ /// Out of memory
+ // ignore: non_constant_identifier_names
+ static int get ENOMEM => _platform((_Codes codes) => codes.enomem);
+
+ /// No space left on device
+ // ignore: non_constant_identifier_names
+ static int get ENOSPC => _platform((_Codes codes) => codes.enospc);
+
+ /// Function not implemented
+ // ignore: non_constant_identifier_names
+ static int get ENOSYS => _platform((_Codes codes) => codes.enosys);
+
+ /// Not a directory
+ // ignore: non_constant_identifier_names
+ static int get ENOTDIR => _platform((_Codes codes) => codes.enotdir);
+
+ /// Directory not empty
+ // ignore: non_constant_identifier_names
+ static int get ENOTEMPTY => _platform((_Codes codes) => codes.enotempty);
+
+ /// Not a typewriter
+ // ignore: non_constant_identifier_names
+ static int get ENOTTY => _platform((_Codes codes) => codes.enotty);
+
+ /// No such device or address
+ // ignore: non_constant_identifier_names
+ static int get ENXIO => _platform((_Codes codes) => codes.enxio);
+
+ /// Operation not permitted
+ // ignore: non_constant_identifier_names
+ static int get EPERM => _platform((_Codes codes) => codes.eperm);
+
+ /// Broken pipe
+ // ignore: non_constant_identifier_names
+ static int get EPIPE => _platform((_Codes codes) => codes.epipe);
+
+ /// Math result not representable
+ // ignore: non_constant_identifier_names
+ static int get ERANGE => _platform((_Codes codes) => codes.erange);
+
+ /// Read-only file system
+ // ignore: non_constant_identifier_names
+ static int get EROFS => _platform((_Codes codes) => codes.erofs);
+
+ /// Illegal seek
+ // ignore: non_constant_identifier_names
+ static int get ESPIPE => _platform((_Codes codes) => codes.espipe);
+
+ /// No such process
+ // ignore: non_constant_identifier_names
+ static int get ESRCH => _platform((_Codes codes) => codes.esrch);
+
+ /// Cross-device link
+ // ignore: non_constant_identifier_names
+ static int get EXDEV => _platform((_Codes codes) => codes.exdev);
+
+ static int _platform(int Function(_Codes codes) getCode) {
+ _Codes codes = (_platforms[operatingSystem] ?? _platforms['linux'])!;
+ return getCode(codes);
+ }
+}
+
+const Map<String, _Codes> _platforms = <String, _Codes>{
+ 'linux': _LinuxCodes(),
+ 'macos': _MacOSCodes(),
+ 'windows': _WindowsCodes(),
+};
+
+abstract class _Codes {
+ int get e2big;
+ int get eacces;
+ int get eagain;
+ int get ebadf;
+ int get ebusy;
+ int get echild;
+ int get edeadlk;
+ int get edom;
+ int get eexist;
+ int get efault;
+ int get efbig;
+ int get eilseq;
+ int get eintr;
+ int get einval;
+ int get eio;
+ int get eisdir;
+ int get eloop;
+ int get emfile;
+ int get emlink;
+ int get enametoolong;
+ int get enfile;
+ int get enodev;
+ int get enoent;
+ int get enoexec;
+ int get enolck;
+ int get enomem;
+ int get enospc;
+ int get enosys;
+ int get enotdir;
+ int get enotempty;
+ int get enotty;
+ int get enxio;
+ int get eperm;
+ int get epipe;
+ int get erange;
+ int get erofs;
+ int get espipe;
+ int get esrch;
+ int get exdev;
+}
+
+class _LinuxCodes implements _Codes {
+ const _LinuxCodes();
+
+ @override
+ int get e2big => 7;
+
+ @override
+ int get eacces => 13;
+
+ @override
+ int get eagain => 11;
+
+ @override
+ int get ebadf => 9;
+
+ @override
+ int get ebusy => 16;
+
+ @override
+ int get echild => 10;
+
+ @override
+ int get edeadlk => 35;
+
+ @override
+ int get edom => 33;
+
+ @override
+ int get eexist => 17;
+
+ @override
+ int get efault => 14;
+
+ @override
+ int get efbig => 27;
+
+ @override
+ int get eilseq => 84;
+
+ @override
+ int get eintr => 4;
+
+ @override
+ int get einval => 22;
+
+ @override
+ int get eio => 5;
+
+ @override
+ int get eisdir => 21;
+
+ @override
+ int get eloop => 40;
+
+ @override
+ int get emfile => 24;
+
+ @override
+ int get emlink => 31;
+
+ @override
+ int get enametoolong => 36;
+
+ @override
+ int get enfile => 23;
+
+ @override
+ int get enodev => 19;
+
+ @override
+ int get enoent => 2;
+
+ @override
+ int get enoexec => 8;
+
+ @override
+ int get enolck => 37;
+
+ @override
+ int get enomem => 12;
+
+ @override
+ int get enospc => 28;
+
+ @override
+ int get enosys => 38;
+
+ @override
+ int get enotdir => 20;
+
+ @override
+ int get enotempty => 39;
+
+ @override
+ int get enotty => 25;
+
+ @override
+ int get enxio => 6;
+
+ @override
+ int get eperm => 1;
+
+ @override
+ int get epipe => 32;
+
+ @override
+ int get erange => 34;
+
+ @override
+ int get erofs => 30;
+
+ @override
+ int get espipe => 29;
+
+ @override
+ int get esrch => 3;
+
+ @override
+ int get exdev => 18;
+}
+
+class _MacOSCodes implements _Codes {
+ const _MacOSCodes();
+
+ @override
+ int get e2big => 7;
+
+ @override
+ int get eacces => 13;
+
+ @override
+ int get eagain => 35;
+
+ @override
+ int get ebadf => 9;
+
+ @override
+ int get ebusy => 16;
+
+ @override
+ int get echild => 10;
+
+ @override
+ int get edeadlk => 11;
+
+ @override
+ int get edom => 33;
+
+ @override
+ int get eexist => 17;
+
+ @override
+ int get efault => 14;
+
+ @override
+ int get efbig => 27;
+
+ @override
+ int get eilseq => 92;
+
+ @override
+ int get eintr => 4;
+
+ @override
+ int get einval => 22;
+
+ @override
+ int get eio => 5;
+
+ @override
+ int get eisdir => 21;
+
+ @override
+ int get eloop => 62;
+
+ @override
+ int get emfile => 24;
+
+ @override
+ int get emlink => 31;
+
+ @override
+ int get enametoolong => 63;
+
+ @override
+ int get enfile => 23;
+
+ @override
+ int get enodev => 19;
+
+ @override
+ int get enoent => 2;
+
+ @override
+ int get enoexec => 8;
+
+ @override
+ int get enolck => 77;
+
+ @override
+ int get enomem => 12;
+
+ @override
+ int get enospc => 28;
+
+ @override
+ int get enosys => 78;
+
+ @override
+ int get enotdir => 20;
+
+ @override
+ int get enotempty => 66;
+
+ @override
+ int get enotty => 25;
+
+ @override
+ int get enxio => 6;
+
+ @override
+ int get eperm => 1;
+
+ @override
+ int get epipe => 32;
+
+ @override
+ int get erange => 34;
+
+ @override
+ int get erofs => 30;
+
+ @override
+ int get espipe => 29;
+
+ @override
+ int get esrch => 3;
+
+ @override
+ int get exdev => 18;
+}
+
+class _WindowsCodes implements _Codes {
+ const _WindowsCodes();
+
+ @override
+ int get e2big => 7;
+
+ @override
+ int get eacces => 13;
+
+ @override
+ int get eagain => 11;
+
+ @override
+ int get ebadf => 9;
+
+ @override
+ int get ebusy => 16;
+
+ @override
+ int get echild => 10;
+
+ @override
+ int get edeadlk => 36;
+
+ @override
+ int get edom => 33;
+
+ @override
+ int get eexist => 17;
+
+ @override
+ int get efault => 14;
+
+ @override
+ int get efbig => 27;
+
+ @override
+ int get eilseq => 42;
+
+ @override
+ int get eintr => 4;
+
+ @override
+ int get einval => 22;
+
+ @override
+ int get eio => 5;
+
+ @override
+ int get eisdir => 21;
+
+ @override
+ int get eloop => -1;
+
+ @override
+ int get emfile => 24;
+
+ @override
+ int get emlink => 31;
+
+ @override
+ int get enametoolong => 38;
+
+ @override
+ int get enfile => 23;
+
+ @override
+ int get enodev => 19;
+
+ @override
+ int get enoent => 2;
+
+ @override
+ int get enoexec => 8;
+
+ @override
+ int get enolck => 39;
+
+ @override
+ int get enomem => 12;
+
+ @override
+ int get enospc => 28;
+
+ @override
+ int get enosys => 40;
+
+ @override
+ int get enotdir => 20;
+
+ @override
+ int get enotempty => 41;
+
+ @override
+ int get enotty => 25;
+
+ @override
+ int get enxio => 6;
+
+ @override
+ int get eperm => 1;
+
+ @override
+ int get epipe => 32;
+
+ @override
+ int get erange => 34;
+
+ @override
+ int get erofs => 30;
+
+ @override
+ int get espipe => 29;
+
+ @override
+ int get esrch => 3;
+
+ @override
+ int get exdev => 18;
+}
diff --git a/pkgs/file/lib/src/interface/error_codes_dart_io.dart b/pkgs/file/lib/src/interface/error_codes_dart_io.dart
new file mode 100644
index 0000000..3f0a97f
--- /dev/null
+++ b/pkgs/file/lib/src/interface/error_codes_dart_io.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io' show Platform;
+
+/// If we have `dart:io` available, we pull the current operating system from
+/// the [Platform] class, so we'll get errno values that match our current
+/// operating system.
+final String operatingSystem = Platform.operatingSystem;
diff --git a/pkgs/file/lib/src/interface/error_codes_internal.dart b/pkgs/file/lib/src/interface/error_codes_internal.dart
new file mode 100644
index 0000000..0a9d7dc
--- /dev/null
+++ b/pkgs/file/lib/src/interface/error_codes_internal.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// In environments that don't have `dart:io`, we can't access the Platform
+/// class to determine what platform we're on, so we just pretend we're on
+/// Linux, meaning we'll get errno values that match Linux's errno.h.
+const String operatingSystem = 'linux';
diff --git a/pkgs/file/lib/src/interface/file.dart b/pkgs/file/lib/src/interface/file.dart
new file mode 100644
index 0000000..87417c6
--- /dev/null
+++ b/pkgs/file/lib/src/interface/file.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+
+import '../io.dart' as io;
+
+import 'file_system_entity.dart';
+
+/// A reference to a file on the file system.
+abstract class File implements FileSystemEntity, io.File {
+ // Override method definitions to codify the return type covariance.
+ @override
+ Future<File> create({bool recursive = false, bool exclusive = false});
+
+ @override
+ Future<File> rename(String newPath);
+
+ @override
+ File renameSync(String newPath);
+
+ @override
+ Future<File> copy(String newPath);
+
+ @override
+ File copySync(String newPath);
+
+ @override
+ File get absolute;
+
+ @override
+ Future<File> writeAsBytes(List<int> bytes,
+ {io.FileMode mode = io.FileMode.write, bool flush = false});
+
+ @override
+ Future<File> writeAsString(String contents,
+ {io.FileMode mode = io.FileMode.write,
+ Encoding encoding = utf8,
+ bool flush = false});
+}
diff --git a/pkgs/file/lib/src/interface/file_system.dart b/pkgs/file/lib/src/interface/file_system.dart
new file mode 100644
index 0000000..4fd528d
--- /dev/null
+++ b/pkgs/file/lib/src/interface/file_system.dart
@@ -0,0 +1,163 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:meta/meta.dart';
+import 'package:path/path.dart' as p;
+
+import '../io.dart' as io;
+
+import 'directory.dart';
+import 'file.dart';
+import 'file_system_entity.dart';
+import 'link.dart';
+
+/// A generic representation of a file system.
+///
+/// Note that this class uses `dart:io` only inasmuch as it deals in the types
+/// exposed by the `dart:io` library. Subclasses should document their level of
+/// dependence on the library (and the associated implications of using that
+/// implementation in the browser).
+abstract class FileSystem {
+ /// Creates a new `FileSystem`.
+ const FileSystem();
+
+ /// Returns a reference to a [Directory] at [path].
+ ///
+ /// [path] can be either a [`String`], a [`Uri`], or a [`FileSystemEntity`].
+ Directory directory(dynamic path);
+
+ /// Returns a reference to a [File] at [path].
+ ///
+ /// [path] can be either a [`String`], a [`Uri`], or a [`FileSystemEntity`].
+ File file(dynamic path);
+
+ /// Returns a reference to a [Link] at [path].
+ ///
+ /// [path] can be either a [`String`], a [`Uri`], or a [`FileSystemEntity`].
+ Link link(dynamic path);
+
+ /// An object for manipulating paths in this file system.
+ p.Context get path;
+
+ /// Gets the system temp directory.
+ ///
+ /// It is left to file system implementations to decide how to define the
+ /// "system temp directory".
+ Directory get systemTempDirectory;
+
+ /// Creates a directory object pointing to the current working directory.
+ Directory get currentDirectory;
+
+ /// Sets the current working directory to the specified [path].
+ ///
+ /// The new value set can be either a [Directory] or a [String].
+ ///
+ /// Relative paths will be resolved by the underlying file system
+ /// implementation (meaning it is up to the underlying implementation to
+ /// decide whether to support relative paths).
+ set currentDirectory(dynamic path);
+
+ /// Asynchronously calls the operating system's stat() function on [path].
+ /// Returns a Future which completes with a [io.FileStat] object containing
+ /// the data returned by stat().
+ /// If the call fails, completes the future with a [io.FileStat] object with
+ /// .type set to FileSystemEntityType.NOT_FOUND and the other fields invalid.
+ Future<io.FileStat> stat(String path);
+
+ /// Calls the operating system's stat() function on [path].
+ /// Returns a [io.FileStat] object containing the data returned by stat().
+ /// If the call fails, returns a [io.FileStat] object with .type set to
+ /// FileSystemEntityType.NOT_FOUND and the other fields invalid.
+ io.FileStat statSync(String path);
+
+ /// Checks whether two paths refer to the same object in the
+ /// file system. Returns a [Future<bool>] that completes with the result.
+ ///
+ /// Comparing a link to its target returns false, as does comparing two links
+ /// that point to the same target. To check the target of a link, use
+ /// Link.target explicitly to fetch it. Directory links appearing
+ /// inside a path are followed, though, to find the file system object.
+ ///
+ /// Completes the returned Future with an error if one of the paths points
+ /// to an object that does not exist.
+ Future<bool> identical(String path1, String path2);
+
+ /// Synchronously checks whether two paths refer to the same object in the
+ /// file system.
+ ///
+ /// Comparing a link to its target returns false, as does comparing two links
+ /// that point to the same target. To check the target of a link, use
+ /// Link.target explicitly to fetch it. Directory links appearing
+ /// inside a path are followed, though, to find the file system object.
+ ///
+ /// Throws an error if one of the paths points to an object that does not
+ /// exist.
+ bool identicalSync(String path1, String path2);
+
+ /// Tests if [FileSystemEntity.watch] is supported on the current system.
+ bool get isWatchSupported;
+
+ /// Finds the type of file system object that a [path] points to. Returns
+ /// a Future<FileSystemEntityType> that completes with the result.
+ ///
+ /// [io.FileSystemEntityType.LINK] will only be returned if [followLinks] is
+ /// `false`, and [path] points to a link
+ ///
+ /// If the [path] does not point to a file system object or an error occurs
+ /// then [io.FileSystemEntityType.notFound] is returned.
+ Future<io.FileSystemEntityType> type(String path, {bool followLinks = true});
+
+ /// Syncronously finds the type of file system object that a [path] points
+ /// to. Returns a [io.FileSystemEntityType].
+ ///
+ /// [io.FileSystemEntityType.LINK] will only be returned if [followLinks] is
+ /// `false`, and [path] points to a link
+ ///
+ /// If the [path] does not point to a file system object or an error occurs
+ /// then [io.FileSystemEntityType.notFound] is returned.
+ io.FileSystemEntityType typeSync(String path, {bool followLinks = true});
+
+ /// Checks if [`type(path)`](type) returns [io.FileSystemEntityType.FILE].
+ Future<bool> isFile(String path) async =>
+ await type(path) == io.FileSystemEntityType.file;
+
+ /// Synchronously checks if [`type(path)`](type) returns
+ /// [io.FileSystemEntityType.FILE].
+ bool isFileSync(String path) =>
+ typeSync(path) == io.FileSystemEntityType.file;
+
+ /// Checks if [`type(path)`](type) returns [io.FileSystemEntityType.DIRECTORY].
+ Future<bool> isDirectory(String path) async =>
+ await type(path) == io.FileSystemEntityType.directory;
+
+ /// Synchronously checks if [`type(path)`](type) returns
+ /// [io.FileSystemEntityType.DIRECTORY].
+ bool isDirectorySync(String path) =>
+ typeSync(path) == io.FileSystemEntityType.directory;
+
+ /// Checks if [`type(path)`](type) returns [io.FileSystemEntityType.LINK].
+ Future<bool> isLink(String path) async =>
+ await type(path, followLinks: false) == io.FileSystemEntityType.link;
+
+ /// Synchronously checks if [`type(path)`](type) returns
+ /// [io.FileSystemEntityType.LINK].
+ bool isLinkSync(String path) =>
+ typeSync(path, followLinks: false) == io.FileSystemEntityType.link;
+
+ /// Gets the string path represented by the specified generic [path].
+ ///
+ /// [path] may be a [io.FileSystemEntity], a [String], or a [Uri].
+ @protected
+ String getPath(dynamic path) {
+ if (path is io.FileSystemEntity) {
+ return path.path;
+ } else if (path is String) {
+ return path;
+ } else if (path is Uri) {
+ return this.path.fromUri(path);
+ } else {
+ throw ArgumentError('Invalid type for "path": ${path?.runtimeType}');
+ }
+ }
+}
diff --git a/pkgs/file/lib/src/interface/file_system_entity.dart b/pkgs/file/lib/src/interface/file_system_entity.dart
new file mode 100644
index 0000000..a377397
--- /dev/null
+++ b/pkgs/file/lib/src/interface/file_system_entity.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import '../io.dart' as io;
+
+import 'directory.dart';
+import 'file_system.dart';
+
+/// The common super class for [io.File], [io.Directory], and [io.Link] objects.
+abstract class FileSystemEntity implements io.FileSystemEntity {
+ /// Returns the file system responsible for this entity.
+ FileSystem get fileSystem;
+
+ /// Gets the part of this entity's path after the last separator.
+ ///
+ /// context.basename('path/to/foo.dart'); // -> 'foo.dart'
+ /// context.basename('path/to'); // -> 'to'
+ ///
+ /// Trailing separators are ignored.
+ ///
+ /// context.basename('path/to/'); // -> 'to'
+ String get basename;
+
+ /// Gets the part of this entity's path before the last separator.
+ ///
+ /// context.dirname('path/to/foo.dart'); // -> 'path/to'
+ /// context.dirname('path/to'); // -> 'path'
+ /// context.dirname('foo.dart'); // -> '.'
+ ///
+ /// Trailing separators are ignored.
+ ///
+ /// context.dirname('path/to/'); // -> 'path'
+ String get dirname;
+
+ // Override method definitions to codify the return type covariance.
+ @override
+ Future<FileSystemEntity> delete({bool recursive = false});
+
+ @override
+ Directory get parent;
+}
diff --git a/pkgs/file/lib/src/interface/link.dart b/pkgs/file/lib/src/interface/link.dart
new file mode 100644
index 0000000..27874b3
--- /dev/null
+++ b/pkgs/file/lib/src/interface/link.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import '../io.dart' as io;
+
+import 'file_system_entity.dart';
+
+/// A reference to a symbolic link on the file system.
+abstract class Link implements FileSystemEntity, io.Link {
+ // Override method definitions to codify the return type covariance.
+ @override
+ Future<Link> create(String target, {bool recursive = false});
+
+ @override
+ Future<Link> update(String target);
+
+ @override
+ Future<Link> rename(String newPath);
+
+ @override
+ Link renameSync(String newPath);
+
+ @override
+ Link get absolute;
+}
diff --git a/pkgs/file/lib/src/io.dart b/pkgs/file/lib/src/io.dart
new file mode 100644
index 0000000..9d57e78
--- /dev/null
+++ b/pkgs/file/lib/src/io.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// For internal use only!
+///
+/// This exposes the subset of the `dart:io` interfaces that are required by
+/// the `file` package. The `file` package re-exports these interfaces (or in
+/// some cases, implementations of these interfaces by the same name), so this
+/// file need not be exposes publicly and exists for internal use only.
+export 'dart:io'
+ show
+ Directory,
+ File,
+ FileLock,
+ FileMode,
+ FileStat,
+ FileSystemEntity,
+ FileSystemEntityType,
+ FileSystemEvent,
+ FileSystemException,
+ IOException,
+ IOSink,
+ Link,
+ OSError,
+ RandomAccessFile;
diff --git a/pkgs/file/pubspec.yaml b/pkgs/file/pubspec.yaml
new file mode 100644
index 0000000..b4195f7
--- /dev/null
+++ b/pkgs/file/pubspec.yaml
@@ -0,0 +1,19 @@
+name: file
+version: 7.0.1
+description:
+ A pluggable, mockable file system abstraction for Dart. Supports local file
+ system access, as well as in-memory file systems, record-replay file systems,
+ and chroot file systems.
+repository: https://github.com/dart-lang/tools/tree/main/pkgs/file
+
+environment:
+ sdk: ^3.0.0
+
+dependencies:
+ meta: ^1.9.1
+ path: ^1.8.3
+
+dev_dependencies:
+ file_testing: ^3.0.0
+ lints: ^2.0.1
+ test: ^1.23.1
diff --git a/pkgs/file/test/chroot_test.dart b/pkgs/file/test/chroot_test.dart
new file mode 100644
index 0000000..6c34ff2
--- /dev/null
+++ b/pkgs/file/test/chroot_test.dart
@@ -0,0 +1,177 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@TestOn('vm')
+import 'dart:io' as io;
+
+import 'package:file/chroot.dart';
+import 'package:file/file.dart';
+import 'package:file/local.dart';
+import 'package:file/memory.dart';
+import 'package:file_testing/file_testing.dart';
+import 'package:test/test.dart';
+
+import 'common_tests.dart';
+
+void main() {
+ group('ChrootFileSystem', () {
+ ChrootFileSystem createMemoryBackedChrootFileSystem() {
+ MemoryFileSystem fs = MemoryFileSystem();
+ fs.directory('/tmp').createSync();
+ return ChrootFileSystem(fs, '/tmp');
+ }
+
+ // TODO(jamesderlin): Make ChrootFile.openSync return a delegating
+ // RandomAccessFile that uses the chroot'd path.
+ List<String> skipCommon = <String>[
+ 'File > open > .* > RandomAccessFile > read > openReadHandleDoesNotChange',
+ 'File > open > .* > RandomAccessFile > openWriteHandleDoesNotChange',
+ ];
+
+ group('memoryBacked', () {
+ runCommonTests(createMemoryBackedChrootFileSystem, skip: skipCommon);
+ });
+
+ group('localBacked', () {
+ late ChrootFileSystem fs;
+ late io.Directory tmp;
+
+ setUp(() {
+ tmp = io.Directory.systemTemp.createTempSync('file_test_');
+ tmp = io.Directory(tmp.resolveSymbolicLinksSync());
+ fs = ChrootFileSystem(const LocalFileSystem(), tmp.path);
+ });
+
+ tearDown(() {
+ tmp.deleteSync(recursive: true);
+ });
+
+ runCommonTests(
+ () => fs,
+ skip: <String>[
+ // https://github.com/dart-lang/sdk/issues/28275
+ 'Link > rename > throwsIfDestinationExistsAsDirectory',
+
+ // https://github.com/dart-lang/sdk/issues/28277
+ 'Link > rename > throwsIfDestinationExistsAsFile',
+
+ ...skipCommon,
+ ],
+ );
+ }, skip: io.Platform.isWindows);
+
+ group('chrootSpecific', () {
+ late ChrootFileSystem fs;
+ late MemoryFileSystem mem;
+
+ setUp(() {
+ fs = createMemoryBackedChrootFileSystem();
+ mem = fs.delegate as MemoryFileSystem;
+ });
+
+ group('FileSystem', () {
+ group('currentDirectory', () {
+ test('staysInJailIfSetToParentOfRoot', () {
+ fs.currentDirectory = '../../../..';
+ fs.file('foo').createSync();
+ expect(mem.file('/tmp/foo'), exists);
+ });
+
+ test('throwsIfSetToSymlinkToDirectoryOutsideJail', () {
+ mem.directory('/bar').createSync();
+ mem.link('/tmp/foo').createSync('/bar');
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.currentDirectory = '/foo';
+ });
+ });
+ });
+
+ group('stat', () {
+ test('isNotFoundForJailbreakPath', () {
+ mem.file('/foo').createSync();
+ expect(fs.statSync('../foo').type, FileSystemEntityType.notFound);
+ });
+
+ test('isNotFoundForSymlinkWithJailbreakTarget', () {
+ mem.file('/foo').createSync();
+ mem.link('/tmp/bar').createSync('/foo');
+ expect(mem.statSync('/tmp/bar').type, FileSystemEntityType.file);
+ expect(fs.statSync('/bar').type, FileSystemEntityType.notFound);
+ });
+
+ test('isNotFoundForSymlinkToOutsideAndBackInsideJail', () {
+ mem.file('/tmp/bar').createSync();
+ mem.link('/foo').createSync('/tmp/bar');
+ mem.link('/tmp/baz').createSync('/foo');
+ expect(mem.statSync('/tmp/baz').type, FileSystemEntityType.file);
+ expect(fs.statSync('/baz').type, FileSystemEntityType.notFound);
+ });
+ });
+
+ group('type', () {
+ test('isNotFoundForJailbreakPath', () {
+ mem.file('/foo').createSync();
+ expect(fs.typeSync('../foo'), FileSystemEntityType.notFound);
+ });
+
+ test('isNotFoundForSymlinkWithJailbreakTarget', () {
+ mem.file('/foo').createSync();
+ mem.link('/tmp/bar').createSync('/foo');
+ expect(mem.typeSync('/tmp/bar'), FileSystemEntityType.file);
+ expect(fs.typeSync('/bar'), FileSystemEntityType.notFound);
+ });
+
+ test('isNotFoundForSymlinkToOutsideAndBackInsideJail', () {
+ mem.file('/tmp/bar').createSync();
+ mem.link('/foo').createSync('/tmp/bar');
+ mem.link('/tmp/baz').createSync('/foo');
+ expect(mem.typeSync('/tmp/baz'), FileSystemEntityType.file);
+ expect(fs.typeSync('/baz'), FileSystemEntityType.notFound);
+ });
+ });
+ });
+
+ group('File', () {
+ group('delegate', () {
+ test('referencesRootEntityForJailbreakPath', () {
+ mem.file('/foo').createSync();
+ dynamic f = fs.file('../foo');
+ expect(f.delegate.path, '/tmp/foo');
+ });
+ });
+
+ group('create', () {
+ test('createsAtRootIfPathReferencesJailbreakFile', () {
+ fs.file('../foo').createSync();
+ expect(mem.file('/foo'), isNot(exists));
+ expect(mem.file('/tmp/foo'), exists);
+ });
+ });
+
+ group('copy', () {
+ test('copiesToRootDirectoryIfDestinationIsJailbreakPath', () {
+ File f = fs.file('/foo')..createSync();
+ f.copySync('../bar');
+ expect(mem.file('/bar'), isNot(exists));
+ expect(mem.file('/tmp/bar'), exists);
+ });
+ });
+ });
+
+ group('Link', () {
+ group('target', () {
+ test('chrootAndDelegateFileSystemsReturnSameValue', () {
+ mem.file('/foo').createSync();
+ mem.link('/tmp/bar').createSync('/foo');
+ mem.link('/tmp/baz').createSync('../foo');
+ expect(mem.link('/tmp/bar').targetSync(), '/foo');
+ expect(fs.link('/bar').targetSync(), '/foo');
+ expect(mem.link('/tmp/baz').targetSync(), '../foo');
+ expect(fs.link('/baz').targetSync(), '../foo');
+ });
+ });
+ });
+ });
+ });
+}
diff --git a/pkgs/file/test/common_tests.dart b/pkgs/file/test/common_tests.dart
new file mode 100644
index 0000000..6028c77
--- /dev/null
+++ b/pkgs/file/test/common_tests.dart
@@ -0,0 +1,3517 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@TestOn('vm')
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io' as io;
+
+import 'package:file/file.dart';
+import 'package:file_testing/file_testing.dart';
+import 'package:path/path.dart' as p;
+import 'package:test/test.dart';
+import 'package:test/test.dart' as testpkg show group, setUp, tearDown, test;
+
+import 'utils.dart';
+
+/// Callback used in [runCommonTests] to produce the root folder in which all
+/// file system entities will be created.
+typedef RootPathGenerator = String Function();
+
+/// Callback used in [runCommonTests] to create the file system under test.
+/// It must return either a [FileSystem] or a [Future] that completes with a
+/// [FileSystem].
+typedef FileSystemGenerator = dynamic Function();
+
+/// A function to run before tests (passed to [setUp]) or after tests
+/// (passed to [tearDown]).
+typedef SetUpTearDown = dynamic Function();
+
+/// Runs a suite of tests common to all file system implementations. All file
+/// system implementations should run *at least* these tests to ensure
+/// compliance with file system API.
+///
+/// If [root] is specified, its return value will be used as the root folder
+/// in which all file system entities will be created. If not specified, the
+/// tests will attempt to create entities in the file system root.
+///
+/// [skip] may be used to skip certain tests (or entire groups of tests) in
+/// this suite (to be used, for instance, if a file system implementation is
+/// not yet fully complete). The format of each entry in the list is:
+/// `$group1Description > $group2Description > ... > $testDescription`.
+/// Entries may use regular expression syntax.
+///
+/// If [replay] is specified, each test (and its setup callbacks) will run
+/// twice - once as a "setup" pass with the file system returned by
+/// [createFileSystem], and again as the "test" pass with the file system
+/// returned by [replay]. This is intended for use with `ReplayFileSystem`,
+/// where in order for the file system to behave as expected, a recording of
+/// the invocation(s) must first be made.
+void runCommonTests(
+ FileSystemGenerator createFileSystem, {
+ RootPathGenerator? root,
+ List<String> skip = const <String>[],
+ FileSystemGenerator? replay,
+}) {
+ RootPathGenerator? rootfn = root;
+
+ group('common', () {
+ late FileSystemGenerator createFs;
+ late List<SetUpTearDown> setUps;
+ late List<SetUpTearDown> tearDowns;
+ late FileSystem fs;
+ late String root;
+ List<String> stack = <String>[];
+
+ void skipIfNecessary(String description, void Function() callback) {
+ stack.add(description);
+ bool matchesCurrentFrame(String input) =>
+ RegExp('^$input\$').hasMatch(stack.join(' > '));
+ if (skip.where(matchesCurrentFrame).isEmpty) {
+ callback();
+ }
+ stack.removeLast();
+ }
+
+ testpkg.setUp(() async {
+ createFs = createFileSystem;
+ setUps = <SetUpTearDown>[];
+ tearDowns = <SetUpTearDown>[];
+ });
+
+ void setUp(FutureOr<void> Function() callback) {
+ testpkg.setUp(replay == null ? callback : () => setUps.add(callback));
+ }
+
+ void tearDown(FutureOr<void> Function() callback) {
+ if (replay == null) {
+ testpkg.tearDown(callback);
+ } else {
+ testpkg.setUp(() => tearDowns.insert(0, callback));
+ }
+ }
+
+ void group(String description, void Function() body) =>
+ skipIfNecessary(description, () => testpkg.group(description, body));
+
+ void test(String description, FutureOr<void> Function() body,
+ {dynamic skip}) =>
+ skipIfNecessary(description, () {
+ if (replay == null) {
+ testpkg.test(description, body, skip: skip);
+ } else {
+ group('rerun', () {
+ testpkg.setUp(() async {
+ await Future.forEach(setUps, (SetUpTearDown setUp) => setUp());
+ await body();
+ for (SetUpTearDown tearDown in tearDowns) {
+ await tearDown();
+ }
+ createFs = replay;
+ await Future.forEach(setUps, (SetUpTearDown setUp) => setUp());
+ });
+
+ testpkg.test(description, body, skip: skip);
+
+ testpkg.tearDown(() async {
+ for (SetUpTearDown tearDown in tearDowns) {
+ await tearDown();
+ }
+ });
+ });
+ }
+ });
+
+ /// Returns [path] prefixed by the [root] namespace.
+ /// This is only intended for absolute paths.
+ String ns(String path) {
+ p.Context posix = p.Context(style: p.Style.posix);
+ List<String> parts = posix.split(path);
+ parts[0] = root;
+ path = fs.path.joinAll(parts);
+ String rootPrefix = fs.path.rootPrefix(path);
+ assert(rootPrefix.isNotEmpty);
+ String result = root == rootPrefix
+ ? path
+ : (path == rootPrefix
+ ? root
+ : fs.path.join(root, fs.path.joinAll(parts.sublist(1))));
+ return result;
+ }
+
+ setUp(() async {
+ root = rootfn != null ? rootfn() : '/';
+ fs = await createFs() as FileSystem;
+ assert(fs.path.isAbsolute(root));
+ assert(!root.endsWith(fs.path.separator) ||
+ fs.path.rootPrefix(root) == root);
+ });
+
+ group('FileSystem', () {
+ group('directory', () {
+ test('allowsStringArgument', () {
+ expect(fs.directory(ns('/foo')), isDirectory);
+ });
+
+ test('allowsUriArgument', () {
+ expect(fs.directory(Uri.parse('file:///')), isDirectory);
+ });
+
+ test('succeedsWithUriArgument', () {
+ fs.directory(ns('/foo')).createSync();
+ Uri uri = fs.path.toUri(ns('/foo'));
+ expect(fs.directory(uri), exists);
+ });
+
+ test('allowsDirectoryArgument', () {
+ expect(fs.directory(io.Directory(ns('/foo'))), isDirectory);
+ });
+
+ test('disallowsOtherArgumentType', () {
+ expect(() => fs.directory(123), throwsArgumentError);
+ });
+
+ // Fails due to
+ // https://github.com/google/file.dart/issues/112
+ test('considersBothSlashesEquivalent', () {
+ fs.directory(r'foo\bar_dir').createSync(recursive: true);
+ expect(fs.directory(r'foo/bar_dir'), exists);
+ }, skip: 'Fails due to https://github.com/google/file.dart/issues/112');
+ });
+
+ group('file', () {
+ test('allowsStringArgument', () {
+ expect(fs.file(ns('/foo')), isFile);
+ });
+
+ test('allowsUriArgument', () {
+ expect(fs.file(Uri.parse('file:///')), isFile);
+ });
+
+ test('succeedsWithUriArgument', () {
+ fs.file(ns('/foo')).createSync();
+ Uri uri = fs.path.toUri(ns('/foo'));
+ expect(fs.file(uri), exists);
+ });
+
+ test('allowsDirectoryArgument', () {
+ expect(fs.file(io.File(ns('/foo'))), isFile);
+ });
+
+ test('disallowsOtherArgumentType', () {
+ expect(() => fs.file(123), throwsArgumentError);
+ });
+
+ // Fails due to
+ // https://github.com/google/file.dart/issues/112
+ test('considersBothSlashesEquivalent', () {
+ fs.file(r'foo\bar_file').createSync(recursive: true);
+ expect(fs.file(r'foo/bar_file'), exists);
+ }, skip: 'Fails due to https://github.com/google/file.dart/issues/112');
+ });
+
+ group('link', () {
+ test('allowsStringArgument', () {
+ expect(fs.link(ns('/foo')), isLink);
+ });
+
+ test('allowsUriArgument', () {
+ expect(fs.link(Uri.parse('file:///')), isLink);
+ });
+
+ test('succeedsWithUriArgument', () {
+ fs.file(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ Uri uri = fs.path.toUri(ns('/bar'));
+ expect(fs.link(uri), exists);
+ });
+
+ test('allowsDirectoryArgument', () {
+ expect(fs.link(io.File(ns('/foo'))), isLink);
+ });
+
+ test('disallowsOtherArgumentType', () {
+ expect(() => fs.link(123), throwsArgumentError);
+ });
+ });
+
+ group('path', () {
+ test('hasCorrectCurrentWorkingDirectory', () {
+ expect(fs.path.current, fs.currentDirectory.path);
+ });
+
+ test('separatorIsAmongExpectedValues', () {
+ expect(fs.path.separator, anyOf('/', r'\'));
+ });
+ });
+
+ group('systemTempDirectory', () {
+ test('existsAsDirectory', () {
+ Directory tmp = fs.systemTempDirectory;
+ expect(tmp, isDirectory);
+ expect(tmp, exists);
+ });
+ });
+
+ group('currentDirectory', () {
+ test('defaultsToRoot', () {
+ expect(fs.currentDirectory.path, root);
+ });
+
+ test('throwsIfSetToNonExistentPath', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.currentDirectory = ns('/foo');
+ });
+ });
+
+ test('throwsIfHasNonExistentPathInComplexChain', () {
+ fs.directory(ns('/foo')).createSync();
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.currentDirectory = ns('/bar/../foo');
+ });
+ });
+
+ test('succeedsIfSetToValidStringPath', () {
+ fs.directory(ns('/foo')).createSync();
+ fs.currentDirectory = ns('/foo');
+ expect(fs.currentDirectory.path, ns('/foo'));
+ });
+
+ test('succeedsIfSetToValidDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ fs.currentDirectory = io.Directory(ns('/foo'));
+ expect(fs.currentDirectory.path, ns('/foo'));
+ });
+
+ test('throwsIfArgumentIsNotStringOrDirectory', () {
+ expect(() {
+ fs.currentDirectory = 123;
+ }, throwsArgumentError);
+ });
+
+ test('succeedsIfSetToRelativePath', () {
+ fs.directory(ns('/foo/bar')).createSync(recursive: true);
+ fs.currentDirectory = 'foo';
+ expect(fs.currentDirectory.path, ns('/foo'));
+ fs.currentDirectory = 'bar';
+ expect(fs.currentDirectory.path, ns('/foo/bar'));
+ });
+
+ test('succeedsIfSetToAbsolutePathWhenCwdIsNotRoot', () {
+ fs.directory(ns('/foo/bar')).createSync(recursive: true);
+ fs.directory(ns('/baz/qux')).createSync(recursive: true);
+ fs.currentDirectory = ns('/foo/bar');
+ expect(fs.currentDirectory.path, ns('/foo/bar'));
+ fs.currentDirectory = fs.directory(ns('/baz/qux'));
+ expect(fs.currentDirectory.path, ns('/baz/qux'));
+ });
+
+ test('succeedsIfSetToParentDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ fs.currentDirectory = 'foo';
+ expect(fs.currentDirectory.path, ns('/foo'));
+ fs.currentDirectory = '..';
+ expect(fs.currentDirectory.path, ns('/'));
+ });
+
+ test('staysAtRootIfSetToParentOfRoot', () {
+ fs.currentDirectory =
+ List<String>.filled(20, '..').join(fs.path.separator);
+ String cwd = fs.currentDirectory.path;
+ expect(cwd, fs.path.rootPrefix(cwd));
+ });
+
+ test('removesTrailingSlashIfSet', () {
+ fs.directory(ns('/foo')).createSync();
+ fs.currentDirectory = ns('/foo/');
+ expect(fs.currentDirectory.path, ns('/foo'));
+ });
+
+ test('throwsIfSetToFilePathSegmentAtTail', () {
+ fs.file(ns('/foo')).createSync();
+ expectFileSystemException(ErrorCodes.ENOTDIR, () {
+ fs.currentDirectory = ns('/foo');
+ });
+ });
+
+ test('throwsIfSetToFilePathSegmentViaTraversal', () {
+ fs.file(ns('/foo')).createSync();
+ expectFileSystemException(ErrorCodes.ENOTDIR, () {
+ fs.currentDirectory = ns('/foo/bar/baz');
+ });
+ });
+
+ test('resolvesLinksIfEncountered', () {
+ fs.link(ns('/foo/bar/baz')).createSync(ns('/qux'), recursive: true);
+ fs.directory(ns('/qux')).createSync();
+ fs.directory(ns('/quux')).createSync();
+ fs.currentDirectory = ns('/foo/bar/baz/../quux/');
+ expect(fs.currentDirectory.path, ns('/quux'));
+ });
+
+ test('succeedsIfSetToDirectoryLinkAtTail', () {
+ fs.directory(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ fs.currentDirectory = ns('/bar');
+ expect(fs.currentDirectory.path, ns('/foo'));
+ });
+
+ test('throwsIfSetToLinkLoop', () {
+ fs.link(ns('/foo')).createSync(ns('/bar'));
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ expectFileSystemException(
+ anyOf(ErrorCodes.EMLINK, ErrorCodes.ELOOP),
+ () {
+ fs.currentDirectory = ns('/foo');
+ },
+ );
+ });
+ });
+
+ group('stat', () {
+ test('isNotFoundForEmptyPath', () {
+ FileStat stat = fs.statSync('');
+ expect(stat.type, FileSystemEntityType.notFound);
+ });
+
+ test('isNotFoundForPathToNonExistentEntityAtTail', () {
+ FileStat stat = fs.statSync(ns('/foo'));
+ expect(stat.type, FileSystemEntityType.notFound);
+ });
+
+ test('isNotFoundForPathToNonExistentEntityInTraversal', () {
+ FileStat stat = fs.statSync(ns('/foo/bar'));
+ expect(stat.type, FileSystemEntityType.notFound);
+ });
+
+ test('isDirectoryForDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ FileStat stat = fs.statSync(ns('/foo'));
+ expect(stat.type, FileSystemEntityType.directory);
+ });
+
+ test('isFileForFile', () {
+ fs.file(ns('/foo')).createSync();
+ FileStat stat = fs.statSync(ns('/foo'));
+ expect(stat.type, FileSystemEntityType.file);
+ });
+
+ test('isFileForLinkToFile', () {
+ fs.file(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ FileStat stat = fs.statSync(ns('/bar'));
+ expect(stat.type, FileSystemEntityType.file);
+ });
+
+ test('isNotFoundForLinkWithCircularReference', () {
+ fs.link(ns('/foo')).createSync(ns('/bar'));
+ fs.link(ns('/bar')).createSync(ns('/baz'));
+ fs.link(ns('/baz')).createSync(ns('/foo'));
+ FileStat stat = fs.statSync(ns('/foo'));
+ expect(stat.type, FileSystemEntityType.notFound);
+ });
+ });
+
+ group('identical', () {
+ test('isTrueForIdenticalPathsToExistentFile', () {
+ fs.file(ns('/foo')).createSync();
+ expect(fs.identicalSync(ns('/foo'), ns('/foo')), true);
+ });
+
+ test('isFalseForDifferentPathsToDifferentFiles', () {
+ fs.file(ns('/foo')).createSync();
+ fs.file(ns('/bar')).createSync();
+ expect(fs.identicalSync(ns('/foo'), ns('/bar')), false);
+ });
+
+ test('isTrueForDifferentPathsToSameFileViaLinkInTraversal', () {
+ fs.file(ns('/foo/file')).createSync(recursive: true);
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ expect(fs.identicalSync(ns('/foo/file'), ns('/bar/file')), true);
+ });
+
+ test('isFalseForDifferentPathsToSameFileViaLinkAtTail', () {
+ fs.file(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ expect(fs.identicalSync(ns('/foo'), ns('/bar')), false);
+ });
+
+ test('throwsForDifferentPathsToNonExistentEntities', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.identicalSync(ns('/foo'), ns('/bar'));
+ });
+ });
+
+ test('throwsForDifferentPathsToOneFileOneNonExistentEntity', () {
+ fs.file(ns('/foo')).createSync();
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.identicalSync(ns('/foo'), ns('/bar'));
+ });
+ });
+ });
+
+ group('type', () {
+ test('isFileForFile', () {
+ fs.file(ns('/foo')).createSync();
+ FileSystemEntityType type = fs.typeSync(ns('/foo'));
+ expect(type, FileSystemEntityType.file);
+ });
+
+ test('isDirectoryForDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ FileSystemEntityType type = fs.typeSync(ns('/foo'));
+ expect(type, FileSystemEntityType.directory);
+ });
+
+ test('isDirectoryForAncestorOfRoot', () {
+ FileSystemEntityType type = fs
+ .typeSync(List<String>.filled(20, '..').join(fs.path.separator));
+ expect(type, FileSystemEntityType.directory);
+ });
+
+ test('isFileForLinkToFileAndFollowLinksTrue', () {
+ fs.file(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ FileSystemEntityType type = fs.typeSync(ns('/bar'));
+ expect(type, FileSystemEntityType.file);
+ });
+
+ test('isLinkForLinkToFileAndFollowLinksFalse', () {
+ fs.file(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ FileSystemEntityType type =
+ fs.typeSync(ns('/bar'), followLinks: false);
+ expect(type, FileSystemEntityType.link);
+ });
+
+ test('isNotFoundForLinkWithCircularReferenceAndFollowLinksTrue', () {
+ fs.link(ns('/foo')).createSync(ns('/bar'));
+ fs.link(ns('/bar')).createSync(ns('/baz'));
+ fs.link(ns('/baz')).createSync(ns('/foo'));
+ FileSystemEntityType type = fs.typeSync(ns('/foo'));
+ expect(type, FileSystemEntityType.notFound);
+ });
+
+ test('isNotFoundForNoEntityAtTail', () {
+ FileSystemEntityType type = fs.typeSync(ns('/foo'));
+ expect(type, FileSystemEntityType.notFound);
+ });
+
+ test('isNotFoundForNoDirectoryInTraversal', () {
+ FileSystemEntityType type = fs.typeSync(ns('/foo/bar/baz'));
+ expect(type, FileSystemEntityType.notFound);
+ });
+ });
+
+ group('isFile/isDirectory/isLink', () {
+ late String filePath;
+ late String directoryPath;
+ late String fileLinkPath;
+ late String directoryLinkPath;
+
+ setUp(() {
+ filePath = ns('/file');
+ directoryPath = ns('/directory');
+ fileLinkPath = ns('/file-link');
+ directoryLinkPath = ns('/directory-link');
+
+ fs.file(filePath).createSync();
+ fs.directory(directoryPath).createSync();
+ fs.link(fileLinkPath).createSync(filePath);
+ fs.link(directoryLinkPath).createSync(directoryPath);
+ });
+
+ test('isFile', () {
+ expect(fs.isFileSync(filePath), true);
+ expect(fs.isFileSync(directoryPath), false);
+ expect(fs.isFileSync(fileLinkPath), true);
+ expect(fs.isFileSync(directoryLinkPath), false);
+ });
+
+ test('isDirectory', () {
+ expect(fs.isDirectorySync(filePath), false);
+ expect(fs.isDirectorySync(directoryPath), true);
+ expect(fs.isDirectorySync(fileLinkPath), false);
+ expect(fs.isDirectorySync(directoryLinkPath), true);
+ });
+
+ test('isLink', () {
+ expect(fs.isLinkSync(filePath), false);
+ expect(fs.isLinkSync(directoryPath), false);
+ expect(fs.isLinkSync(fileLinkPath), true);
+ expect(fs.isLinkSync(directoryLinkPath), true);
+ });
+ });
+ });
+
+ group('Directory', () {
+ test('uri', () {
+ expect(fs.directory(ns('/foo')).uri, fs.path.toUri('${ns('/foo')}/'));
+ expect(fs.directory('foo').uri.toString(), 'foo/');
+ });
+
+ group('exists', () {
+ test('falseIfNotExists', () {
+ expect(fs.directory(ns('/foo')), isNot(exists));
+ expect(fs.directory('foo'), isNot(exists));
+ expect(fs.directory(ns('/foo/bar')), isNot(exists));
+ });
+
+ test('trueIfExistsAsDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ expect(fs.directory(ns('/foo')), exists);
+ expect(fs.directory('foo'), exists);
+ });
+
+ test('falseIfExistsAsFile', () {
+ fs.file(ns('/foo')).createSync();
+ expect(fs.directory(ns('/foo')), isNot(exists));
+ expect(fs.directory('foo'), isNot(exists));
+ });
+
+ test('trueIfExistsAsLinkToDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ expect(fs.directory(ns('/bar')), exists);
+ expect(fs.directory('bar'), exists);
+ });
+
+ test('falseIfExistsAsLinkToFile', () {
+ fs.file(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ expect(fs.directory(ns('/bar')), isNot(exists));
+ expect(fs.directory('bar'), isNot(exists));
+ });
+
+ test('falseIfNotFoundSegmentExistsThenIsBackedOut', () {
+ fs.directory(ns('/foo')).createSync();
+ expect(fs.directory(ns('/bar/../foo')), isNot(exists));
+ });
+ });
+
+ group('create', () {
+ test('returnsCovariantType', () async {
+ expect(await fs.directory(ns('/foo')).create(), isDirectory);
+ });
+
+ test('succeedsIfAlreadyExistsAsDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ fs.directory(ns('/foo')).createSync();
+ });
+
+ test('throwsIfAlreadyExistsAsFile', () {
+ fs.file(ns('/foo')).createSync();
+ expectFileSystemException(ErrorCodes.ENOTDIR, () {
+ fs.directory(ns('/foo')).createSync();
+ });
+ });
+
+ test('succeedsIfAlreadyExistsAsLinkToDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ fs.directory(ns('/bar')).createSync();
+ });
+
+ test('throwsIfAlreadyExistsAsLinkToFile', () {
+ fs.file(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ // TODO(tvolkert): Change this to just be 'Not a directory'
+ // once Dart 1.22 is stable.
+ expectFileSystemException(
+ anyOf(ErrorCodes.EEXIST, ErrorCodes.ENOTDIR),
+ () {
+ fs.directory(ns('/bar')).createSync();
+ },
+ );
+ });
+
+ test('throwsIfAlreadyExistsAsLinkToNotFoundAtTail', () {
+ fs.link(ns('/foo')).createSync(ns('/bar'));
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.directory(ns('/foo')).createSync();
+ });
+ });
+
+ test('throwsIfAlreadyExistsAsLinkToNotFoundViaTraversal', () {
+ fs.link(ns('/foo')).createSync(ns('/bar/baz'));
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.directory(ns('/foo')).createSync();
+ });
+ });
+
+ test('throwsIfAlreadyExistsAsLinkToNotFoundInDifferentDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ fs.directory(ns('/bar')).createSync();
+ fs.link(ns('/bar/baz')).createSync(ns('/foo/qux'));
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.directory(ns('/bar/baz')).createSync();
+ });
+ });
+
+ test('succeedsIfTailDoesntExist', () {
+ expect(fs.directory(ns('/')), exists);
+ fs.directory(ns('/foo')).createSync();
+ expect(fs.directory(ns('/foo')), exists);
+ });
+
+ test('throwsIfAncestorDoesntExistRecursiveFalse', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.directory(ns('/foo/bar')).createSync();
+ });
+ });
+
+ test('succeedsIfAncestorDoesntExistRecursiveTrue', () {
+ fs.directory(ns('/foo/bar')).createSync(recursive: true);
+ expect(fs.directory(ns('/foo')), exists);
+ expect(fs.directory(ns('/foo/bar')), exists);
+ });
+ });
+
+ group('rename', () {
+ test('returnsCovariantType', () async {
+ Directory src() => fs.directory(ns('/foo'))..createSync();
+ expect(src().renameSync(ns('/bar')), isDirectory);
+ expect(await src().rename(ns('/baz')), isDirectory);
+ });
+
+ test('succeedsIfDestinationDoesntExist', () {
+ Directory src = fs.directory(ns('/foo'))..createSync();
+ Directory dest = src.renameSync(ns('/bar'));
+ expect(dest.path, ns('/bar'));
+ expect(dest, exists);
+ });
+
+ test(
+ 'succeedsIfDestinationIsEmptyDirectory',
+ () {
+ fs.directory(ns('/bar')).createSync();
+ Directory src = fs.directory(ns('/foo'))..createSync();
+ Directory dest = src.renameSync(ns('/bar'));
+ expect(src, isNot(exists));
+ expect(dest, exists);
+ },
+ // See https://github.com/google/file.dart/issues/197.
+ skip: io.Platform.isWindows,
+ );
+
+ test('throwsIfDestinationIsFile', () {
+ fs.file(ns('/bar')).createSync();
+ Directory src = fs.directory(ns('/foo'))..createSync();
+ expectFileSystemException(ErrorCodes.ENOTDIR, () {
+ src.renameSync(ns('/bar'));
+ });
+ });
+
+ test('throwsIfDestinationParentFolderDoesntExist', () {
+ Directory src = fs.directory(ns('/foo'))..createSync();
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ src.renameSync(ns('/bar/baz'));
+ });
+ });
+
+ test('throwsIfDestinationIsNonEmptyDirectory', () {
+ fs.file(ns('/bar/baz')).createSync(recursive: true);
+ Directory src = fs.directory(ns('/foo'))..createSync();
+ // The error will be 'Directory not empty' on OS X, but it will be
+ // 'File exists' on Linux.
+ expectFileSystemException(
+ anyOf(ErrorCodes.ENOTEMPTY, ErrorCodes.EEXIST),
+ () {
+ src.renameSync(ns('/bar'));
+ },
+ );
+ });
+
+ test('throwsIfSourceDoesntExist', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.directory(ns('/foo')).renameSync(ns('/bar'));
+ });
+ });
+
+ test('throwsIfSourceIsFile', () {
+ fs.file(ns('/foo')).createSync();
+ expectFileSystemException(ErrorCodes.ENOTDIR, () {
+ fs.directory(ns('/foo')).renameSync(ns('/bar'));
+ });
+ });
+
+ test('succeedsIfSourceIsLinkToDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ fs.directory(ns('/bar')).renameSync(ns('/baz'));
+ expect(fs.typeSync(ns('/foo'), followLinks: false),
+ FileSystemEntityType.directory);
+ expect(fs.typeSync(ns('/bar')), FileSystemEntityType.notFound);
+ expect(fs.typeSync(ns('/baz'), followLinks: false),
+ FileSystemEntityType.link);
+ expect(fs.link(ns('/baz')).targetSync(), ns('/foo'));
+ });
+
+ test('throwsIfDestinationIsLinkToNotFound', () {
+ Directory src = fs.directory(ns('/foo'))..createSync();
+ fs.link(ns('/bar')).createSync(ns('/baz'));
+ expectFileSystemException(ErrorCodes.ENOTDIR, () {
+ src.renameSync(ns('/bar'));
+ });
+ });
+
+ test('throwsIfDestinationIsLinkToEmptyDirectory', () {
+ Directory src = fs.directory(ns('/foo'))..createSync();
+ fs.directory(ns('/bar')).createSync();
+ fs.link(ns('/baz')).createSync(ns('/bar'));
+ expectFileSystemException(ErrorCodes.ENOTDIR, () {
+ src.renameSync(ns('/baz'));
+ });
+ });
+
+ test('succeedsIfDestinationIsInDifferentDirectory', () {
+ Directory src = fs.directory(ns('/foo'))..createSync();
+ fs.directory(ns('/bar')).createSync();
+ src.renameSync(ns('/bar/baz'));
+ expect(fs.typeSync(ns('/foo')), FileSystemEntityType.notFound);
+ expect(fs.typeSync(ns('/bar/baz')), FileSystemEntityType.directory);
+ });
+
+ test('succeedsIfSourceIsLinkToDifferentDirectory', () {
+ fs.directory(ns('/foo/subfoo')).createSync(recursive: true);
+ fs.directory(ns('/bar/subbar')).createSync(recursive: true);
+ fs.directory(ns('/baz/subbaz')).createSync(recursive: true);
+ fs.link(ns('/foo/subfoo/lnk')).createSync(ns('/bar/subbar'));
+ fs.directory(ns('/foo/subfoo/lnk')).renameSync(ns('/baz/subbaz/dst'));
+ expect(fs.typeSync(ns('/foo/subfoo/lnk')),
+ FileSystemEntityType.notFound);
+ expect(fs.typeSync(ns('/baz/subbaz/dst'), followLinks: false),
+ FileSystemEntityType.link);
+ expect(fs.typeSync(ns('/baz/subbaz/dst'), followLinks: true),
+ FileSystemEntityType.directory);
+ });
+ });
+
+ group('delete', () {
+ test('returnsCovariantType', () async {
+ Directory dir = fs.directory(ns('/foo'))..createSync();
+ expect(await dir.delete(), isDirectory);
+ });
+
+ test('succeedsIfEmptyDirectoryExistsAndRecursiveFalse', () {
+ Directory dir = fs.directory(ns('/foo'))..createSync();
+ dir.deleteSync();
+ expect(dir, isNot(exists));
+ });
+
+ test('succeedsIfEmptyDirectoryExistsAndRecursiveTrue', () {
+ Directory dir = fs.directory(ns('/foo'))..createSync();
+ dir.deleteSync(recursive: true);
+ expect(dir, isNot(exists));
+ });
+
+ test('throwsIfNonEmptyDirectoryExistsAndRecursiveFalse', () {
+ Directory dir = fs.directory(ns('/foo'))..createSync();
+ fs.file(ns('/foo/bar')).createSync();
+ expectFileSystemException(ErrorCodes.ENOTEMPTY, () {
+ dir.deleteSync();
+ });
+ });
+
+ test('succeedsIfNonEmptyDirectoryExistsAndRecursiveTrue', () {
+ Directory dir = fs.directory(ns('/foo'))..createSync();
+ fs.file(ns('/foo/bar')).createSync();
+ dir.deleteSync(recursive: true);
+ expect(fs.directory(ns('/foo')), isNot(exists));
+ expect(fs.file(ns('/foo/bar')), isNot(exists));
+ });
+
+ test('throwsIfDirectoryDoesntExistAndRecursiveFalse', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.directory(ns('/foo')).deleteSync();
+ });
+ });
+
+ test('throwsIfDirectoryDoesntExistAndRecursiveTrue', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.directory(ns('/foo')).deleteSync(recursive: true);
+ });
+ });
+
+ test('succeedsIfPathReferencesFileAndRecursiveTrue', () {
+ fs.file(ns('/foo')).createSync();
+ fs.directory(ns('/foo')).deleteSync(recursive: true);
+ expect(fs.typeSync(ns('/foo')), FileSystemEntityType.notFound);
+ });
+
+ test('throwsIfPathReferencesFileAndRecursiveFalse', () {
+ fs.file(ns('/foo')).createSync();
+ expectFileSystemException(ErrorCodes.ENOTDIR, () {
+ fs.directory(ns('/foo')).deleteSync();
+ });
+ });
+
+ test('succeedsIfPathReferencesLinkToDirectoryAndRecursiveTrue', () {
+ fs.directory(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ fs.directory(ns('/bar')).deleteSync(recursive: true);
+ expect(fs.typeSync(ns('/foo'), followLinks: false),
+ FileSystemEntityType.directory);
+ expect(fs.typeSync(ns('/bar'), followLinks: false),
+ FileSystemEntityType.notFound);
+ });
+
+ test('succeedsIfPathReferencesLinkToDirectoryAndRecursiveFalse', () {
+ fs.directory(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ fs.directory(ns('/bar')).deleteSync();
+ expect(fs.typeSync(ns('/foo'), followLinks: false),
+ FileSystemEntityType.directory);
+ expect(fs.typeSync(ns('/bar'), followLinks: false),
+ FileSystemEntityType.notFound);
+ });
+
+ test('succeedsIfExistsAsLinkToDirectoryInDifferentDirectory', () {
+ fs.directory(ns('/foo/bar')).createSync(recursive: true);
+ fs.link(ns('/baz/qux')).createSync(ns('/foo/bar'), recursive: true);
+ fs.directory(ns('/baz/qux')).deleteSync();
+ expect(fs.typeSync(ns('/foo/bar'), followLinks: false),
+ FileSystemEntityType.directory);
+ expect(fs.typeSync(ns('/baz/qux'), followLinks: false),
+ FileSystemEntityType.notFound);
+ });
+
+ test('succeedsIfPathReferencesLinkToFileAndRecursiveTrue', () {
+ fs.file(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ fs.directory(ns('/bar')).deleteSync(recursive: true);
+ expect(fs.typeSync(ns('/foo'), followLinks: false),
+ FileSystemEntityType.file);
+ expect(fs.typeSync(ns('/bar'), followLinks: false),
+ FileSystemEntityType.notFound);
+ });
+
+ test('throwsIfPathReferencesLinkToFileAndRecursiveFalse', () {
+ fs.file(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ expectFileSystemException(ErrorCodes.ENOTDIR, () {
+ fs.directory(ns('/bar')).deleteSync();
+ });
+ });
+
+ test('throwsIfPathReferencesLinkToNotFoundAndRecursiveFalse', () {
+ fs.link(ns('/foo')).createSync(ns('/bar'));
+ expectFileSystemException(ErrorCodes.ENOTDIR, () {
+ fs.directory(ns('/foo')).deleteSync();
+ });
+ });
+ });
+
+ group('resolveSymbolicLinks', () {
+ test('succeedsForRootDirectory', () {
+ expect(fs.directory(ns('/')).resolveSymbolicLinksSync(), ns('/'));
+ });
+
+ test('throwsIfPathIsEmpty', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.directory('').resolveSymbolicLinksSync();
+ });
+ });
+
+ test('throwsIfLoopInLinkChain', () {
+ fs.link(ns('/foo')).createSync(ns('/bar'));
+ fs.link(ns('/bar')).createSync(ns('/baz'));
+ fs.link(ns('/baz')).createSync(ns('/foo'));
+ expectFileSystemException(
+ anyOf(ErrorCodes.EMLINK, ErrorCodes.ELOOP),
+ () {
+ fs.directory(ns('/foo')).resolveSymbolicLinksSync();
+ },
+ );
+ });
+
+ test('throwsIfPathNotFoundInTraversal', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.directory(ns('/foo/bar')).resolveSymbolicLinksSync();
+ });
+ });
+
+ test('throwsIfPathNotFoundAtTail', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.directory(ns('/foo')).resolveSymbolicLinksSync();
+ });
+ });
+
+ test('throwsIfPathNotFoundInMiddleThenBackedOut', () {
+ fs.directory(ns('/foo/bar')).createSync(recursive: true);
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.directory(ns('/foo/baz/../bar')).resolveSymbolicLinksSync();
+ });
+ });
+
+ test('resolvesRelativePathToCurrentDirectory', () {
+ fs.directory(ns('/foo/bar')).createSync(recursive: true);
+ fs.link(ns('/foo/baz')).createSync(ns('/foo/bar'));
+ fs.currentDirectory = ns('/foo');
+ expect(
+ fs.directory('baz').resolveSymbolicLinksSync(), ns('/foo/bar'));
+ });
+
+ test('resolvesAbsolutePathsAbsolutely', () {
+ fs.directory(ns('/foo/bar')).createSync(recursive: true);
+ fs.currentDirectory = ns('/foo');
+ expect(fs.directory(ns('/foo/bar')).resolveSymbolicLinksSync(),
+ ns('/foo/bar'));
+ });
+
+ test('handlesRelativeLinks', () {
+ fs.directory(ns('/foo/bar/baz')).createSync(recursive: true);
+ fs.link(ns('/foo/qux')).createSync(fs.path.join('bar', 'baz'));
+ expect(
+ fs.directory(ns('/foo/qux')).resolveSymbolicLinksSync(),
+ ns('/foo/bar/baz'),
+ );
+ expect(
+ fs.directory(fs.path.join('foo', 'qux')).resolveSymbolicLinksSync(),
+ ns('/foo/bar/baz'),
+ );
+ });
+
+ test('handlesAbsoluteLinks', () {
+ fs.directory(ns('/foo')).createSync();
+ fs.directory(ns('/bar/baz/qux')).createSync(recursive: true);
+ fs.link(ns('/foo/quux')).createSync(ns('/bar/baz/qux'));
+ expect(fs.directory(ns('/foo/quux')).resolveSymbolicLinksSync(),
+ ns('/bar/baz/qux'));
+ });
+
+ test('handlesLinksWhoseTargetsHaveNestedLinks', () {
+ fs.directory(ns('/foo')).createSync();
+ fs.link(ns('/foo/quuz')).createSync(ns('/bar'));
+ fs.link(ns('/foo/grault')).createSync(ns('/baz/quux'));
+ fs.directory(ns('/bar')).createSync();
+ fs.link(ns('/bar/qux')).createSync(ns('/baz'));
+ fs.link(ns('/bar/garply')).createSync(ns('/foo'));
+ fs.directory(ns('/baz')).createSync();
+ fs.link(ns('/baz/quux')).createSync(ns('/bar/garply/quuz'));
+ expect(fs.directory(ns('/foo/grault/qux')).resolveSymbolicLinksSync(),
+ ns('/baz'));
+ });
+
+ test('handlesParentAndThisFolderReferences', () {
+ fs.directory(ns('/foo/bar/baz')).createSync(recursive: true);
+ fs.link(ns('/foo/bar/baz/qux')).createSync(fs.path.join('..', '..'));
+ String resolved = fs
+ .directory(ns('/foo/./bar/baz/../baz/qux/bar'))
+ .resolveSymbolicLinksSync();
+ expect(resolved, ns('/foo/bar'));
+ });
+
+ test('handlesBackToBackSlashesInPath', () {
+ fs.directory(ns('/foo/bar/baz')).createSync(recursive: true);
+ expect(fs.directory(ns('//foo/bar///baz')).resolveSymbolicLinksSync(),
+ ns('/foo/bar/baz'));
+ });
+
+ test('handlesComplexPathWithMultipleLinks', () {
+ fs
+ .link(ns('/foo/bar/baz'))
+ .createSync(fs.path.join('..', '..', 'qux'), recursive: true);
+ fs.link(ns('/qux')).createSync('quux');
+ fs.link(ns('/quux/quuz')).createSync(ns('/foo'), recursive: true);
+ String resolved = fs
+ .directory(ns('/foo//bar/./baz/quuz/bar/..///bar/baz/'))
+ .resolveSymbolicLinksSync();
+ expect(resolved, ns('/quux'));
+ });
+ });
+
+ group('absolute', () {
+ test('returnsCovariantType', () {
+ expect(fs.directory('foo').absolute, isDirectory);
+ });
+
+ test('returnsSamePathIfAlreadyAbsolute', () {
+ expect(fs.directory(ns('/foo')).absolute.path, ns('/foo'));
+ });
+
+ test('succeedsForRelativePaths', () {
+ expect(fs.directory('foo').absolute.path, ns('/foo'));
+ });
+ });
+
+ group('parent', () {
+ late String root;
+
+ setUp(() {
+ root = fs.path.style.name == 'windows' ? r'C:\' : '/';
+ });
+
+ test('returnsCovariantType', () {
+ expect(fs.directory(root).parent, isDirectory);
+ });
+
+ test('returnsRootForRoot', () {
+ expect(fs.directory(root).parent.path, root);
+ });
+
+ test('succeedsForNonRoot', () {
+ expect(fs.directory(ns('/foo/bar')).parent.path, ns('/foo'));
+ });
+ });
+
+ group('createTemp', () {
+ test('returnsCovariantType', () {
+ expect(fs.directory(ns('/')).createTempSync(), isDirectory);
+ });
+
+ test('throwsIfDirectoryDoesntExist', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.directory(ns('/foo')).createTempSync();
+ });
+ });
+
+ test('resolvesNameCollisions', () {
+ fs.directory(ns('/foo/bar')).createSync(recursive: true);
+ Directory tmp = fs.directory(ns('/foo')).createTempSync('bar');
+ expect(tmp.path,
+ allOf(isNot(ns('/foo/bar')), startsWith(ns('/foo/bar'))));
+ });
+
+ test('succeedsWithoutPrefix', () {
+ Directory dir = fs.directory(ns('/foo'))..createSync();
+ expect(dir.createTempSync().path, startsWith(ns('/foo/')));
+ });
+
+ test('succeedsWithPrefix', () {
+ Directory dir = fs.directory(ns('/foo'))..createSync();
+ expect(dir.createTempSync('bar').path, startsWith(ns('/foo/bar')));
+ });
+
+ test('succeedsWithNestedPathPrefixThatExists', () {
+ fs.directory(ns('/foo/bar')).createSync(recursive: true);
+ Directory tmp = fs.directory(ns('/foo')).createTempSync('bar/baz');
+ expect(tmp.path, startsWith(ns('/foo/bar/baz')));
+ });
+
+ test('throwsWithNestedPathPrefixThatDoesntExist', () {
+ Directory dir = fs.directory(ns('/foo'))..createSync();
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ dir.createTempSync('bar/baz');
+ });
+ });
+ });
+
+ group('list', () {
+ late Directory dir;
+
+ setUp(() {
+ dir = fs.currentDirectory = fs.directory(ns('/foo'))..createSync();
+ fs.file('bar').createSync();
+ fs.file(fs.path.join('baz', 'qux')).createSync(recursive: true);
+ fs.link('quux').createSync(fs.path.join('baz', 'qux'));
+ fs
+ .link(fs.path.join('baz', 'quuz'))
+ .createSync(fs.path.join('..', 'quux'));
+ fs.link(fs.path.join('baz', 'grault')).createSync('.');
+ fs.currentDirectory = ns('/');
+ });
+
+ test('returnsCovariantType', () async {
+ void expectIsFileSystemEntity(dynamic entity) {
+ expect(entity, isFileSystemEntity);
+ }
+
+ dir.listSync().forEach(expectIsFileSystemEntity);
+ (await dir.list().toList()).forEach(expectIsFileSystemEntity);
+ });
+
+ test('returnsEmptyListForEmptyDirectory', () {
+ Directory empty = fs.directory(ns('/bar'))..createSync();
+ expect(empty.listSync(), isEmpty);
+ });
+
+ test('throwsIfDirectoryDoesntExist', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.directory(ns('/bar')).listSync();
+ });
+ });
+
+ test('returnsLinkObjectsIfFollowLinksFalse', () {
+ List<FileSystemEntity> list = dir.listSync(followLinks: false);
+ expect(list, hasLength(3));
+ expect(list, contains(allOf(isFile, hasPath(ns('/foo/bar')))));
+ expect(list, contains(allOf(isDirectory, hasPath(ns('/foo/baz')))));
+ expect(list, contains(allOf(isLink, hasPath(ns('/foo/quux')))));
+ });
+
+ test('followsLinksIfFollowLinksTrue', () {
+ List<FileSystemEntity> list = dir.listSync();
+ expect(list, hasLength(3));
+ expect(list, contains(allOf(isFile, hasPath(ns('/foo/bar')))));
+ expect(list, contains(allOf(isDirectory, hasPath(ns('/foo/baz')))));
+ expect(list, contains(allOf(isFile, hasPath(ns('/foo/quux')))));
+ });
+
+ test('returnsLinkObjectsForRecursiveLinkIfFollowLinksTrue', () {
+ expect(
+ dir.listSync(recursive: true),
+ allOf(
+ hasLength(9),
+ allOf(
+ contains(allOf(isFile, hasPath(ns('/foo/bar')))),
+ contains(allOf(isFile, hasPath(ns('/foo/quux')))),
+ contains(allOf(isFile, hasPath(ns('/foo/baz/qux')))),
+ contains(allOf(isFile, hasPath(ns('/foo/baz/quuz')))),
+ contains(allOf(isFile, hasPath(ns('/foo/baz/grault/qux')))),
+ contains(allOf(isFile, hasPath(ns('/foo/baz/grault/quuz')))),
+ ),
+ allOf(
+ contains(allOf(isDirectory, hasPath(ns('/foo/baz')))),
+ contains(allOf(isDirectory, hasPath(ns('/foo/baz/grault')))),
+ ),
+ contains(allOf(isLink, hasPath(ns('/foo/baz/grault/grault')))),
+ ),
+ );
+ });
+
+ test('recurseIntoDirectoriesIfRecursiveTrueFollowLinksFalse', () {
+ expect(
+ dir.listSync(recursive: true, followLinks: false),
+ allOf(
+ hasLength(6),
+ contains(allOf(isFile, hasPath(ns('/foo/bar')))),
+ contains(allOf(isFile, hasPath(ns('/foo/baz/qux')))),
+ contains(allOf(isLink, hasPath(ns('/foo/quux')))),
+ contains(allOf(isLink, hasPath(ns('/foo/baz/quuz')))),
+ contains(allOf(isLink, hasPath(ns('/foo/baz/grault')))),
+ contains(allOf(isDirectory, hasPath(ns('/foo/baz')))),
+ ),
+ );
+ });
+
+ test('childEntriesNotNormalized', () {
+ dir = fs.directory(ns('/bar/baz'))..createSync(recursive: true);
+ fs.file(ns('/bar/baz/qux')).createSync();
+ List<FileSystemEntity> list =
+ fs.directory(ns('/bar//../bar/./baz')).listSync();
+ expect(list, hasLength(1));
+ expect(list[0], allOf(isFile, hasPath(ns('/bar//../bar/./baz/qux'))));
+ });
+
+ test('symlinksToNotFoundAlwaysReturnedAsLinks', () {
+ dir = fs.directory(ns('/bar'))..createSync();
+ fs.link(ns('/bar/baz')).createSync('qux');
+ for (bool followLinks in const <bool>[true, false]) {
+ List<FileSystemEntity> list =
+ dir.listSync(followLinks: followLinks);
+ expect(list, hasLength(1));
+ expect(list[0], allOf(isLink, hasPath(ns('/bar/baz'))));
+ }
+ });
+ });
+
+ test('childEntities', () {
+ Directory dir = fs.directory(ns('/foo'))..createSync();
+ dir.childDirectory('bar').createSync();
+ dir.childFile('baz').createSync();
+ dir.childLink('qux').createSync('bar');
+ expect(fs.directory(ns('/foo/bar')), exists);
+ expect(fs.file(ns('/foo/baz')), exists);
+ expect(fs.link(ns('/foo/qux')), exists);
+ });
+ });
+
+ group('File', () {
+ test('uri', () {
+ expect(fs.file(ns('/foo')).uri, fs.path.toUri(ns('/foo')));
+ expect(fs.file('foo').uri.toString(), 'foo');
+ });
+
+ group('create', () {
+ test('returnsCovariantType', () async {
+ expect(await fs.file(ns('/foo')).create(), isFile);
+ });
+
+ test('succeedsIfTailDoesntAlreadyExist', () {
+ fs.file(ns('/foo')).createSync();
+ expect(fs.file(ns('/foo')), exists);
+ });
+
+ test('succeedsIfAlreadyExistsAsFile', () {
+ fs.file(ns('/foo')).createSync();
+ fs.file(ns('/foo')).createSync();
+ expect(fs.file(ns('/foo')), exists);
+ });
+
+ test('throwsIfAncestorDoesntExistRecursiveFalse', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.file(ns('/foo/bar')).createSync();
+ });
+ });
+
+ test('succeedsIfAncestorDoesntExistRecursiveTrue', () {
+ fs.file(ns('/foo/bar')).createSync(recursive: true);
+ expect(fs.file(ns('/foo/bar')), exists);
+ });
+
+ test('throwsIfAlreadyExistsAsDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ expectFileSystemException(ErrorCodes.EISDIR, () {
+ fs.file(ns('/foo')).createSync();
+ });
+ });
+
+ test('throwsIfAlreadyExistsAsLinkToDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ expectFileSystemException(ErrorCodes.EISDIR, () {
+ fs.file(ns('/bar')).createSync();
+ });
+ });
+
+ test('succeedsIfAlreadyExistsAsLinkToFile', () {
+ fs.file(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ fs.file(ns('/bar')).createSync();
+ expect(fs.file(ns('/bar')), exists);
+ });
+
+ test('succeedsIfAlreadyExistsAsLinkToNotFoundAtTail', () {
+ fs.link(ns('/foo')).createSync(ns('/bar'));
+ fs.file(ns('/foo')).createSync();
+ expect(fs.typeSync(ns('/foo'), followLinks: false),
+ FileSystemEntityType.link);
+ expect(fs.typeSync(ns('/bar'), followLinks: false),
+ FileSystemEntityType.file);
+ });
+
+ test('throwsIfAlreadyExistsAsLinkToNotFoundViaTraversal', () {
+ fs.link(ns('/foo')).createSync(ns('/bar/baz'));
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.file(ns('/foo')).createSync();
+ });
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.file(ns('/foo')).createSync(recursive: true);
+ });
+ });
+
+ /*
+ test('throwsIfPathSegmentIsLinkToNotFoundAndRecursiveTrue', () {
+ fs.link(ns('/foo')).createSync(ns('/bar'));
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.file(ns('/foo/baz')).createSync(recursive: true);
+ });
+ });
+ */
+
+ test('succeedsIfAlreadyExistsAsLinkToNotFoundInDifferentDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ fs.directory(ns('/bar')).createSync();
+ fs.link(ns('/bar/baz')).createSync(ns('/foo/qux'));
+ fs.file(ns('/bar/baz')).createSync();
+ expect(fs.typeSync(ns('/bar/baz'), followLinks: false),
+ FileSystemEntityType.link);
+ expect(fs.typeSync(ns('/foo/qux'), followLinks: false),
+ FileSystemEntityType.file);
+ });
+ });
+
+ group('rename', () {
+ test('returnsCovariantType', () async {
+ File f() => fs.file(ns('/foo'))..createSync();
+ expect(await f().rename(ns('/bar')), isFile);
+ expect(f().renameSync(ns('/baz')), isFile);
+ });
+
+ test('succeedsIfDestinationDoesntExistAtTail', () {
+ File src = fs.file(ns('/foo'))..createSync();
+ File dest = src.renameSync(ns('/bar'));
+ expect(fs.file(ns('/foo')), isNot(exists));
+ expect(fs.file(ns('/bar')), exists);
+ expect(dest.path, ns('/bar'));
+ });
+
+ test('throwsIfDestinationDoesntExistViaTraversal', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ f.renameSync(ns('/bar/baz'));
+ });
+ });
+
+ test('succeedsIfDestinationExistsAsFile', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ fs.file(ns('/bar')).createSync();
+ f.renameSync(ns('/bar'));
+ expect(fs.file(ns('/foo')), isNot(exists));
+ expect(fs.file(ns('/bar')), exists);
+ });
+
+ test('throwsIfDestinationExistsAsDirectory', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ fs.directory(ns('/bar')).createSync();
+ expectFileSystemException(ErrorCodes.EISDIR, () {
+ f.renameSync(ns('/bar'));
+ });
+ });
+
+ test('succeedsIfDestinationExistsAsLinkToFile', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ fs.file(ns('/bar')).createSync();
+ fs.link(ns('/baz')).createSync(ns('/bar'));
+ f.renameSync(ns('/baz'));
+ expect(fs.typeSync(ns('/foo')), FileSystemEntityType.notFound);
+ expect(fs.typeSync(ns('/bar'), followLinks: false),
+ FileSystemEntityType.file);
+ expect(fs.typeSync(ns('/baz'), followLinks: false),
+ FileSystemEntityType.file);
+ });
+
+ test('throwsIfDestinationExistsAsLinkToDirectory', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ fs.directory(ns('/bar')).createSync();
+ fs.link(ns('/baz')).createSync(ns('/bar'));
+ expectFileSystemException(ErrorCodes.EISDIR, () {
+ f.renameSync(ns('/baz'));
+ });
+ });
+
+ test('succeedsIfDestinationExistsAsLinkToNotFound', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ fs.link(ns('/bar')).createSync(ns('/baz'));
+ f.renameSync(ns('/bar'));
+ expect(fs.typeSync(ns('/foo')), FileSystemEntityType.notFound);
+ expect(fs.typeSync(ns('/bar'), followLinks: false),
+ FileSystemEntityType.file);
+ });
+
+ test('throwsIfSourceDoesntExist', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.file(ns('/foo')).renameSync(ns('/bar'));
+ });
+ });
+
+ test('throwsIfSourceExistsAsDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ expectFileSystemException(ErrorCodes.EISDIR, () {
+ fs.file(ns('/foo')).renameSync(ns('/bar'));
+ });
+ });
+
+ test('succeedsIfSourceExistsAsLinkToFile', () {
+ fs.file(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ fs.file(ns('/bar')).renameSync(ns('/baz'));
+ expect(fs.typeSync(ns('/bar')), FileSystemEntityType.notFound);
+ expect(fs.typeSync(ns('/baz'), followLinks: false),
+ FileSystemEntityType.link);
+ expect(fs.typeSync(ns('/baz'), followLinks: true),
+ FileSystemEntityType.file);
+ });
+
+ test('throwsIfSourceExistsAsLinkToDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ expectFileSystemException(ErrorCodes.EISDIR, () {
+ fs.file(ns('/bar')).renameSync(ns('/baz'));
+ });
+ });
+
+ test('throwsIfSourceExistsAsLinkToNotFound', () {
+ fs.link(ns('/foo')).createSync(ns('/bar'));
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.file(ns('/foo')).renameSync(ns('/baz'));
+ });
+ });
+ });
+
+ group('copy', () {
+ test('returnsCovariantType', () async {
+ File f() => fs.file(ns('/foo'))..createSync();
+ expect(await f().copy(ns('/bar')), isFile);
+ expect(f().copySync(ns('/baz')), isFile);
+ });
+
+ test('succeedsIfDestinationDoesntExistAtTail', () {
+ File f = fs.file(ns('/foo'))
+ ..createSync()
+ ..writeAsStringSync('foo');
+ f.copySync(ns('/bar'));
+ expect(fs.file(ns('/foo')), exists);
+ expect(fs.file(ns('/bar')), exists);
+ expect(fs.file(ns('/foo')).readAsStringSync(), 'foo');
+ });
+
+ test('throwsIfDestinationDoesntExistViaTraversal', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ f.copySync(ns('/bar/baz'));
+ });
+ });
+
+ test('succeedsIfDestinationExistsAsFile', () {
+ File f = fs.file(ns('/foo'))
+ ..createSync()
+ ..writeAsStringSync('foo');
+ fs.file(ns('/bar'))
+ ..createSync()
+ ..writeAsStringSync('bar');
+ f.copySync(ns('/bar'));
+ expect(fs.file(ns('/foo')), exists);
+ expect(fs.file(ns('/bar')), exists);
+ expect(fs.file(ns('/foo')).readAsStringSync(), 'foo');
+ expect(fs.file(ns('/bar')).readAsStringSync(), 'foo');
+ });
+
+ test('throwsIfDestinationExistsAsDirectory', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ fs.directory(ns('/bar')).createSync();
+ expectFileSystemException(ErrorCodes.EISDIR, () {
+ f.copySync(ns('/bar'));
+ });
+ });
+
+ test('succeedsIfDestinationExistsAsLinkToFile', () {
+ File f = fs.file(ns('/foo'))
+ ..createSync()
+ ..writeAsStringSync('foo');
+ fs.file(ns('/bar'))
+ ..createSync()
+ ..writeAsStringSync('bar');
+ fs.link(ns('/baz')).createSync(ns('/bar'));
+ f.copySync(ns('/baz'));
+ expect(fs.typeSync(ns('/foo'), followLinks: false),
+ FileSystemEntityType.file);
+ expect(fs.typeSync(ns('/bar'), followLinks: false),
+ FileSystemEntityType.file);
+ expect(fs.typeSync(ns('/baz'), followLinks: false),
+ FileSystemEntityType.link);
+ expect(fs.file(ns('/foo')).readAsStringSync(), 'foo');
+ expect(fs.file(ns('/bar')).readAsStringSync(), 'foo');
+ }, skip: io.Platform.isWindows /* No links on Windows */);
+
+ test('throwsIfDestinationExistsAsLinkToDirectory', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ fs.directory(ns('/bar')).createSync();
+ fs.link(ns('/baz')).createSync(ns('/bar'));
+ expectFileSystemException(ErrorCodes.EISDIR, () {
+ f.copySync(ns('/baz'));
+ });
+ });
+
+ test('throwsIfSourceDoesntExist', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.file(ns('/foo')).copySync(ns('/bar'));
+ });
+ });
+
+ test('throwsIfSourceExistsAsDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ expectFileSystemException(ErrorCodes.EISDIR, () {
+ fs.file(ns('/foo')).copySync(ns('/bar'));
+ });
+ });
+
+ test('succeedsIfSourceExistsAsLinkToFile', () {
+ fs.file(ns('/foo'))
+ ..createSync()
+ ..writeAsStringSync('foo');
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ fs.file(ns('/bar')).copySync(ns('/baz'));
+ expect(fs.typeSync(ns('/foo'), followLinks: false),
+ FileSystemEntityType.file);
+ expect(fs.typeSync(ns('/bar'), followLinks: false),
+ FileSystemEntityType.link);
+ expect(fs.typeSync(ns('/baz'), followLinks: false),
+ FileSystemEntityType.file);
+ expect(fs.file(ns('/foo')).readAsStringSync(), 'foo');
+ expect(fs.file(ns('/baz')).readAsStringSync(), 'foo');
+ });
+
+ test('succeedsIfDestinationIsInDifferentDirectoryThanSource', () {
+ File f = fs.file(ns('/foo/bar'))
+ ..createSync(recursive: true)
+ ..writeAsStringSync('foo');
+ fs.directory(ns('/baz')).createSync();
+ f.copySync(ns('/baz/qux'));
+ expect(fs.file(ns('/foo/bar')), exists);
+ expect(fs.file(ns('/baz/qux')), exists);
+ expect(fs.file(ns('/foo/bar')).readAsStringSync(), 'foo');
+ expect(fs.file(ns('/baz/qux')).readAsStringSync(), 'foo');
+ });
+
+ test('succeedsIfSourceIsLinkToFileInDifferentDirectory', () {
+ fs.file(ns('/foo/bar'))
+ ..createSync(recursive: true)
+ ..writeAsStringSync('foo');
+ fs.link(ns('/baz/qux')).createSync(ns('/foo/bar'), recursive: true);
+ fs.file(ns('/baz/qux')).copySync(ns('/baz/quux'));
+ expect(fs.typeSync(ns('/foo/bar'), followLinks: false),
+ FileSystemEntityType.file);
+ expect(fs.typeSync(ns('/baz/qux'), followLinks: false),
+ FileSystemEntityType.link);
+ expect(fs.typeSync(ns('/baz/quux'), followLinks: false),
+ FileSystemEntityType.file);
+ expect(fs.file(ns('/foo/bar')).readAsStringSync(), 'foo');
+ expect(fs.file(ns('/baz/quux')).readAsStringSync(), 'foo');
+ });
+
+ test('succeedsIfDestinationIsLinkToFileInDifferentDirectory', () {
+ fs.file(ns('/foo/bar'))
+ ..createSync(recursive: true)
+ ..writeAsStringSync('bar');
+ fs.file(ns('/baz/qux'))
+ ..createSync(recursive: true)
+ ..writeAsStringSync('qux');
+ fs.link(ns('/baz/quux')).createSync(ns('/foo/bar'));
+ fs.file(ns('/baz/qux')).copySync(ns('/baz/quux'));
+ expect(fs.typeSync(ns('/foo/bar'), followLinks: false),
+ FileSystemEntityType.file);
+ expect(fs.typeSync(ns('/baz/qux'), followLinks: false),
+ FileSystemEntityType.file);
+ expect(fs.typeSync(ns('/baz/quux'), followLinks: false),
+ FileSystemEntityType.link);
+ expect(fs.file(ns('/foo/bar')).readAsStringSync(), 'qux');
+ expect(fs.file(ns('/baz/qux')).readAsStringSync(), 'qux');
+ }, skip: io.Platform.isWindows /* No links on Windows */);
+ });
+
+ group('length', () {
+ test('throwsIfDoesntExist', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.file(ns('/foo')).lengthSync();
+ });
+ });
+
+ test('throwsIfExistsAsDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ expectFileSystemException(ErrorCodes.EISDIR, () {
+ fs.file(ns('/foo')).lengthSync();
+ });
+ });
+
+ test('returnsZeroForNewlyCreatedFile', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ expect(f.lengthSync(), 0);
+ });
+
+ test('writeNBytesReturnsLengthN', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ f.writeAsBytesSync(<int>[1, 2, 3, 4], flush: true);
+ expect(f.lengthSync(), 4);
+ });
+
+ test('succeedsIfExistsAsLinkToFile', () {
+ fs.file(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ expect(fs.file(ns('/bar')).lengthSync(), 0);
+ });
+ });
+
+ group('absolute', () {
+ test('returnsSamePathIfAlreadyAbsolute', () {
+ expect(fs.file(ns('/foo')).absolute.path, ns('/foo'));
+ });
+
+ test('succeedsForRelativePaths', () {
+ expect(fs.file('foo').absolute.path, ns('/foo'));
+ });
+ });
+
+ group('lastAccessed', () {
+ test('isNowForNewlyCreatedFile', () {
+ DateTime before = downstairs();
+ File f = fs.file(ns('/foo'))..createSync();
+ DateTime after = ceil();
+ DateTime accessed = f.lastAccessedSync();
+ expect(accessed, isSameOrAfter(before));
+ expect(accessed, isSameOrBefore(after));
+ });
+
+ test('throwsIfDoesntExist', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.file(ns('/foo')).lastAccessedSync();
+ });
+ });
+
+ test('throwsIfExistsAsDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ expectFileSystemException(ErrorCodes.EISDIR, () {
+ fs.file(ns('/foo')).lastAccessedSync();
+ });
+ });
+
+ test('succeedsIfExistsAsLinkToFile', () {
+ DateTime before = downstairs();
+ fs.file(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ DateTime after = ceil();
+ DateTime accessed = fs.file(ns('/bar')).lastAccessedSync();
+ expect(accessed, isSameOrAfter(before));
+ expect(accessed, isSameOrBefore(after));
+ });
+ });
+
+ group('setLastAccessed', () {
+ final DateTime time = DateTime(1999);
+
+ test('throwsIfDoesntExist', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.file(ns('/foo')).setLastAccessedSync(time);
+ });
+ });
+
+ test('throwsIfExistsAsDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ expectFileSystemException(ErrorCodes.EISDIR, () {
+ fs.file(ns('/foo')).setLastAccessedSync(time);
+ });
+ });
+
+ test('succeedsIfExistsAsFile', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ f.setLastAccessedSync(time);
+ expect(fs.file(ns('/foo')).lastAccessedSync(), time);
+ });
+
+ test('succeedsIfExistsAsLinkToFile', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ f.setLastAccessedSync(time);
+ expect(fs.file(ns('/bar')).lastAccessedSync(), time);
+ });
+ });
+
+ group('lastModified', () {
+ test('isNowForNewlyCreatedFile', () {
+ DateTime before = downstairs();
+ File f = fs.file(ns('/foo'))..createSync();
+ DateTime after = ceil();
+ DateTime modified = f.lastModifiedSync();
+ expect(modified, isSameOrAfter(before));
+ expect(modified, isSameOrBefore(after));
+ });
+
+ test('throwsIfDoesntExist', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.file(ns('/foo')).lastModifiedSync();
+ });
+ });
+
+ test('throwsIfExistsAsDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ expectFileSystemException(ErrorCodes.EISDIR, () {
+ fs.file(ns('/foo')).lastModifiedSync();
+ });
+ });
+
+ test('succeedsIfExistsAsLinkToFile', () {
+ DateTime before = downstairs();
+ fs.file(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ DateTime after = ceil();
+ DateTime modified = fs.file(ns('/bar')).lastModifiedSync();
+ expect(modified, isSameOrAfter(before));
+ expect(modified, isSameOrBefore(after));
+ });
+ });
+
+ group('setLastModified', () {
+ final DateTime time = DateTime(1999);
+
+ test('throwsIfDoesntExist', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.file(ns('/foo')).setLastModifiedSync(time);
+ });
+ });
+
+ test('throwsIfExistsAsDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ expectFileSystemException(ErrorCodes.EISDIR, () {
+ fs.file(ns('/foo')).setLastModifiedSync(time);
+ });
+ });
+
+ test('succeedsIfExistsAsFile', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ f.setLastModifiedSync(time);
+ expect(fs.file(ns('/foo')).lastModifiedSync(), time);
+ });
+
+ test('succeedsIfExistsAsLinkToFile', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ f.setLastModifiedSync(time);
+ expect(fs.file(ns('/bar')).lastModifiedSync(), time);
+ });
+ });
+
+ group('open', () {
+ void testIfDoesntExistAtTail(FileMode mode) {
+ if (mode == FileMode.read) {
+ test('throwsIfDoesntExistAtTail', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.file(ns('/bar')).openSync(mode: mode);
+ });
+ });
+ } else {
+ test('createsFileIfDoesntExistAtTail', () {
+ RandomAccessFile raf = fs.file(ns('/bar')).openSync(mode: mode);
+ raf.closeSync();
+ expect(fs.file(ns('/bar')), exists);
+ });
+ }
+ }
+
+ void testThrowsIfDoesntExistViaTraversal(FileMode mode) {
+ test('throwsIfDoesntExistViaTraversal', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.file(ns('/bar/baz')).openSync(mode: mode);
+ });
+ });
+ }
+
+ void testRandomAccessFileOperations(FileMode mode) {
+ group('RandomAccessFile', () {
+ late File f;
+ late RandomAccessFile raf;
+
+ setUp(() {
+ f = fs.file(ns('/foo'))..createSync();
+ f.writeAsStringSync('pre-existing content\n', flush: true);
+ raf = f.openSync(mode: mode);
+ });
+
+ tearDown(() {
+ try {
+ raf.closeSync();
+ } on FileSystemException {
+ // Ignore; a test may have already closed it.
+ }
+ });
+
+ test('succeedsIfClosedAfterClosed', () {
+ raf.closeSync();
+ expectFileSystemException(null, () {
+ raf.closeSync();
+ });
+ });
+
+ test('throwsIfReadAfterClose', () {
+ raf.closeSync();
+ expectFileSystemException(null, () {
+ raf.readByteSync();
+ });
+ });
+
+ test('throwsIfWriteAfterClose', () {
+ raf.closeSync();
+ expectFileSystemException(null, () {
+ raf.writeByteSync(0xBAD);
+ });
+ });
+
+ test('throwsIfTruncateAfterClose', () {
+ raf.closeSync();
+ expectFileSystemException(null, () {
+ raf.truncateSync(0);
+ });
+ });
+
+ if (mode == FileMode.write || mode == FileMode.writeOnly) {
+ test('lengthIsResetToZeroIfOpened', () {
+ expect(raf.lengthSync(), equals(0));
+ });
+
+ test('throwsIfAsyncUnawaited', () async {
+ try {
+ final Future<void> future = raf.flush();
+ expectFileSystemException(null, () => raf.flush());
+ expectFileSystemException(null, () => raf.flushSync());
+ await expectLater(future, completes);
+ raf.flushSync();
+ } finally {
+ raf.closeSync();
+ }
+ });
+ } else {
+ test('lengthIsNotModifiedIfOpened', () {
+ expect(raf.lengthSync(), isNot(equals(0)));
+ });
+ }
+
+ if (mode == FileMode.writeOnly ||
+ mode == FileMode.writeOnlyAppend) {
+ test('throwsIfReadByte', () {
+ expectFileSystemException(ErrorCodes.EBADF, () {
+ raf.readByteSync();
+ });
+ });
+
+ test('throwsIfRead', () {
+ expectFileSystemException(ErrorCodes.EBADF, () {
+ raf.readSync(2);
+ });
+ });
+
+ test('throwsIfReadInto', () {
+ expectFileSystemException(ErrorCodes.EBADF, () {
+ raf.readIntoSync(List<int>.filled(5, 0));
+ });
+ });
+ } else {
+ group('read', () {
+ setUp(() {
+ if (mode == FileMode.write) {
+ // Write data back that we truncated when opening the file.
+ raf.writeStringSync('pre-existing content\n');
+ }
+ // Reset the position to zero so we can read the content.
+ raf.setPositionSync(0);
+ });
+
+ test('readByte', () {
+ expect(utf8.decode(<int>[raf.readByteSync()]), 'p');
+ });
+
+ test('read', () {
+ List<int> bytes = raf.readSync(1024);
+ expect(bytes.length, 21);
+ expect(utf8.decode(bytes), 'pre-existing content\n');
+ });
+
+ test('readIntoWithBufferLargerThanContent', () {
+ List<int> buffer = List<int>.filled(1024, 0);
+ int numRead = raf.readIntoSync(buffer);
+ expect(numRead, 21);
+ expect(utf8.decode(buffer.sublist(0, 21)),
+ 'pre-existing content\n');
+ });
+
+ test('readIntoWithBufferSmallerThanContent', () {
+ List<int> buffer = List<int>.filled(10, 0);
+ int numRead = raf.readIntoSync(buffer);
+ expect(numRead, 10);
+ expect(utf8.decode(buffer), 'pre-existi');
+ });
+
+ test('readIntoWithStart', () {
+ List<int> buffer = List<int>.filled(10, 0);
+ int numRead = raf.readIntoSync(buffer, 2);
+ expect(numRead, 8);
+ expect(utf8.decode(buffer.sublist(2)), 'pre-exis');
+ });
+
+ test('readIntoWithStartAndEnd', () {
+ List<int> buffer = List<int>.filled(10, 0);
+ int numRead = raf.readIntoSync(buffer, 2, 5);
+ expect(numRead, 3);
+ expect(utf8.decode(buffer.sublist(2, 5)), 'pre');
+ });
+
+ test('openReadHandleDoesNotChange', () {
+ final String initial = utf8.decode(raf.readSync(4));
+ expect(initial, 'pre-');
+ final File newFile = f.renameSync(ns('/bar'));
+ String rest = utf8.decode(raf.readSync(1024));
+ expect(rest, 'existing content\n');
+
+ assert(newFile.path != f.path);
+ expect(f, isNot(exists));
+ expect(newFile, exists);
+
+ // [RandomAccessFile.path] always returns the original path.
+ expect(raf.path, f.path);
+ });
+ });
+ }
+
+ if (mode == FileMode.read) {
+ test('throwsIfWriteByte', () {
+ expectFileSystemException(ErrorCodes.EBADF, () {
+ raf.writeByteSync(0xBAD);
+ });
+ });
+
+ test('throwsIfWriteFrom', () {
+ expectFileSystemException(ErrorCodes.EBADF, () {
+ raf.writeFromSync(<int>[1, 2, 3, 4]);
+ });
+ });
+
+ test('throwsIfWriteString', () {
+ expectFileSystemException(ErrorCodes.EBADF, () {
+ raf.writeStringSync('This should throw.');
+ });
+ });
+ } else {
+ test('lengthGrowsAsDataIsWritten', () {
+ int lengthBefore = f.lengthSync();
+ raf.writeByteSync(0xFACE);
+ expect(raf.lengthSync(), lengthBefore + 1);
+ });
+
+ test('flush', () {
+ int lengthBefore = f.lengthSync();
+ raf.writeByteSync(0xFACE);
+ raf.flushSync();
+ expect(f.lengthSync(), lengthBefore + 1);
+ });
+
+ test('writeByte', () {
+ raf.writeByteSync(utf8.encode('A').first);
+ raf.flushSync();
+ if (mode == FileMode.write || mode == FileMode.writeOnly) {
+ expect(f.readAsStringSync(), 'A');
+ } else {
+ expect(f.readAsStringSync(), 'pre-existing content\nA');
+ }
+ });
+
+ test('writeFrom', () {
+ raf.writeFromSync(utf8.encode('Hello world'));
+ raf.flushSync();
+ if (mode == FileMode.write || mode == FileMode.writeOnly) {
+ expect(f.readAsStringSync(), 'Hello world');
+ } else {
+ expect(f.readAsStringSync(),
+ 'pre-existing content\nHello world');
+ }
+ });
+
+ test('writeFromWithStart', () {
+ raf.writeFromSync(utf8.encode('Hello world'), 2);
+ raf.flushSync();
+ if (mode == FileMode.write || mode == FileMode.writeOnly) {
+ expect(f.readAsStringSync(), 'llo world');
+ } else {
+ expect(
+ f.readAsStringSync(), 'pre-existing content\nllo world');
+ }
+ });
+
+ test('writeFromWithStartAndEnd', () {
+ raf.writeFromSync(utf8.encode('Hello world'), 2, 5);
+ raf.flushSync();
+ if (mode == FileMode.write || mode == FileMode.writeOnly) {
+ expect(f.readAsStringSync(), 'llo');
+ } else {
+ expect(f.readAsStringSync(), 'pre-existing content\nllo');
+ }
+ });
+
+ test('writeString', () {
+ raf.writeStringSync('Hello world');
+ raf.flushSync();
+ if (mode == FileMode.write || mode == FileMode.writeOnly) {
+ expect(f.readAsStringSync(), 'Hello world');
+ } else {
+ expect(f.readAsStringSync(),
+ 'pre-existing content\nHello world');
+ }
+ });
+
+ test('openWriteHandleDoesNotChange', () {
+ raf.writeStringSync('Hello ');
+ final File newFile = f.renameSync(ns('/bar'));
+ raf.writeStringSync('world');
+
+ final String contents = newFile.readAsStringSync();
+ if (mode == FileMode.write || mode == FileMode.writeOnly) {
+ expect(contents, 'Hello world');
+ } else {
+ expect(contents, 'pre-existing content\nHello world');
+ }
+
+ assert(newFile.path != f.path);
+ expect(f, isNot(exists));
+ expect(newFile, exists);
+
+ // [RandomAccessFile.path] always returns the original path.
+ expect(raf.path, f.path);
+ });
+ }
+
+ if (mode == FileMode.append || mode == FileMode.writeOnlyAppend) {
+ test('positionInitializedToEndOfFile', () {
+ expect(raf.positionSync(), 21);
+ });
+ } else {
+ test('positionInitializedToZero', () {
+ expect(raf.positionSync(), 0);
+ });
+ }
+
+ group('position', () {
+ setUp(() {
+ if (mode == FileMode.write || mode == FileMode.writeOnly) {
+ // Write data back that we truncated when opening the file.
+ raf.writeStringSync('pre-existing content\n');
+ }
+ });
+
+ if (mode != FileMode.writeOnly &&
+ mode != FileMode.writeOnlyAppend) {
+ test('growsAfterRead', () {
+ raf.setPositionSync(0);
+ raf.readSync(10);
+ expect(raf.positionSync(), 10);
+ });
+
+ test('affectsRead', () {
+ raf.setPositionSync(5);
+ expect(utf8.decode(raf.readSync(5)), 'xisti');
+ });
+ }
+
+ if (mode == FileMode.read) {
+ test('succeedsIfSetPastEndOfFile', () {
+ raf.setPositionSync(32);
+ expect(raf.positionSync(), 32);
+ });
+ } else {
+ test('growsAfterWrite', () {
+ int positionBefore = raf.positionSync();
+ raf.writeStringSync('Hello world');
+ expect(raf.positionSync(), positionBefore + 11);
+ });
+
+ test('affectsWrite', () {
+ raf.setPositionSync(5);
+ raf.writeStringSync('-yo-');
+ raf.flushSync();
+ expect(f.readAsStringSync(), 'pre-e-yo-ing content\n');
+ });
+
+ test('succeedsIfSetAndWrittenPastEndOfFile', () {
+ raf.setPositionSync(32);
+ expect(raf.positionSync(), 32);
+ raf.writeStringSync('here');
+ raf.flushSync();
+ List<int> bytes = f.readAsBytesSync();
+ expect(bytes.length, 36);
+ expect(utf8.decode(bytes.sublist(0, 21)),
+ 'pre-existing content\n');
+ expect(utf8.decode(bytes.sublist(32, 36)), 'here');
+ expect(bytes.sublist(21, 32), everyElement(0));
+ });
+ }
+
+ test('throwsIfSetToNegativeNumber', () {
+ expectFileSystemException(ErrorCodes.EINVAL, () {
+ raf.setPositionSync(-12);
+ });
+ });
+ });
+
+ if (mode == FileMode.read) {
+ test('throwsIfTruncate', () {
+ expectFileSystemException(ErrorCodes.EINVAL, () {
+ raf.truncateSync(5);
+ });
+ });
+ } else {
+ group('truncate', () {
+ setUp(() {
+ if (mode == FileMode.write || mode == FileMode.writeOnly) {
+ // Write data back that we truncated when opening the file.
+ raf.writeStringSync('pre-existing content\n');
+ }
+ });
+
+ test('succeedsIfSetWithinRangeOfContent', () {
+ raf.truncateSync(5);
+ raf.flushSync();
+ expect(f.lengthSync(), 5);
+ expect(f.readAsStringSync(), 'pre-e');
+ });
+
+ test('succeedsIfSetToZero', () {
+ raf.truncateSync(0);
+ raf.flushSync();
+ expect(f.lengthSync(), 0);
+ expect(f.readAsStringSync(), isEmpty);
+ });
+
+ test('throwsIfSetToNegativeNumber', () {
+ expectFileSystemException(ErrorCodes.EINVAL, () {
+ raf.truncateSync(-2);
+ });
+ });
+
+ test('extendsFileIfSetPastEndOfFile', () {
+ raf.truncateSync(32);
+ raf.flushSync();
+ List<int> bytes = f.readAsBytesSync();
+ expect(bytes.length, 32);
+ expect(utf8.decode(bytes.sublist(0, 21)),
+ 'pre-existing content\n');
+ expect(bytes.sublist(21, 32), everyElement(0));
+ });
+ });
+ }
+ });
+ }
+
+ void testOpenWithMode(FileMode mode) {
+ testIfDoesntExistAtTail(mode);
+ testThrowsIfDoesntExistViaTraversal(mode);
+ testRandomAccessFileOperations(mode);
+ }
+
+ group('READ', () => testOpenWithMode(FileMode.read));
+ group('WRITE', () => testOpenWithMode(FileMode.write));
+ group('APPEND', () => testOpenWithMode(FileMode.append));
+ group('WRITE_ONLY', () => testOpenWithMode(FileMode.writeOnly));
+ group('WRITE_ONLY_APPEND',
+ () => testOpenWithMode(FileMode.writeOnlyAppend));
+ });
+
+ group('openRead', () {
+ test('throwsIfDoesntExist', () {
+ Stream<List<int>> stream = fs.file(ns('/foo')).openRead();
+ expect(stream.drain<void>(),
+ throwsFileSystemException(ErrorCodes.ENOENT));
+ });
+
+ test('succeedsIfExistsAsFile', () async {
+ File f = fs.file(ns('/foo'))..createSync();
+ f.writeAsStringSync('Hello world', flush: true);
+ Stream<List<int>> stream = f.openRead();
+ List<List<int>> data = await stream.toList();
+ expect(data, hasLength(1));
+ expect(utf8.decode(data[0]), 'Hello world');
+ });
+
+ test('throwsIfExistsAsDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ Stream<List<int>> stream = fs.file(ns('/foo')).openRead();
+ expect(stream.drain<void>(),
+ throwsFileSystemException(ErrorCodes.EISDIR));
+ });
+
+ test('succeedsIfExistsAsLinkToFile', () async {
+ File f = fs.file(ns('/foo'))..createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ f.writeAsStringSync('Hello world', flush: true);
+ Stream<List<int>> stream = fs.file(ns('/bar')).openRead();
+ List<List<int>> data = await stream.toList();
+ expect(data, hasLength(1));
+ expect(utf8.decode(data[0]), 'Hello world');
+ });
+
+ test('respectsStartAndEndParameters', () async {
+ File f = fs.file(ns('/foo'))..createSync();
+ f.writeAsStringSync('Hello world', flush: true);
+ Stream<List<int>> stream = f.openRead(2);
+ List<List<int>> data = await stream.toList();
+ expect(data, hasLength(1));
+ expect(utf8.decode(data[0]), 'llo world');
+ stream = f.openRead(2, 5);
+ data = await stream.toList();
+ expect(data, hasLength(1));
+ expect(utf8.decode(data[0]), 'llo');
+ });
+
+ test('throwsIfStartParameterIsNegative', () async {
+ File f = fs.file(ns('/foo'))..createSync();
+ Stream<List<int>> stream = f.openRead(-2);
+ expect(stream.drain<void>(), throwsRangeError);
+ });
+
+ test('stopsAtEndOfFileIfEndParameterIsPastEndOfFile', () async {
+ File f = fs.file(ns('/foo'))..createSync();
+ f.writeAsStringSync('Hello world', flush: true);
+ Stream<List<int>> stream = f.openRead(2, 1024);
+ List<List<int>> data = await stream.toList();
+ expect(data, hasLength(1));
+ expect(utf8.decode(data[0]), 'llo world');
+ });
+
+ test('providesSingleSubscriptionStream', () async {
+ File f = fs.file(ns('/foo'))..createSync();
+ f.writeAsStringSync('Hello world', flush: true);
+ Stream<List<int>> stream = f.openRead();
+ expect(stream.isBroadcast, isFalse);
+ await stream.drain<void>();
+ });
+
+ test('openReadHandleDoesNotChange', () async {
+ // Ideally, `data` should be large enough so that its contents are
+ // split across multiple chunks in the [Stream]. However, there
+ // doesn't seem to be a good way to determine the chunk size used by
+ // [io.File].
+ final List<int> data = List<int>.generate(
+ 1024 * 256,
+ (int index) => index & 0xFF,
+ growable: false,
+ );
+
+ final File f = fs.file(ns('/foo'))..createSync();
+
+ f.writeAsBytesSync(data, flush: true);
+ final Stream<List<int>> stream = f.openRead();
+
+ File? newFile;
+ List<int>? initialChunk;
+ final List<int> remainingChunks = <int>[];
+
+ await for (List<int> chunk in stream) {
+ if (initialChunk == null) {
+ initialChunk = chunk;
+ assert(initialChunk.isNotEmpty);
+ expect(initialChunk, data.getRange(0, initialChunk.length));
+
+ newFile = f.renameSync(ns('/bar'));
+ } else {
+ remainingChunks.addAll(chunk);
+ }
+ }
+
+ expect(
+ remainingChunks,
+ data.getRange(initialChunk!.length, data.length),
+ );
+
+ assert(newFile?.path != f.path);
+ expect(f, isNot(exists));
+ expect(newFile, exists);
+ });
+
+ test('openReadCompatibleWithUtf8Decoder', () async {
+ const content = 'Hello world!';
+ File file = fs.file(ns('/foo'))
+ ..createSync()
+ ..writeAsStringSync(content);
+ expect(
+ await file
+ .openRead()
+ .transform(utf8.decoder)
+ .transform(const LineSplitter())
+ .first,
+ content,
+ );
+ });
+ });
+
+ group('openWrite', () {
+ test('createsFileIfDoesntExist', () async {
+ await fs.file(ns('/foo')).openWrite().close();
+ expect(fs.file(ns('/foo')), exists);
+ });
+
+ test('throwsIfExistsAsDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ expect(fs.file(ns('/foo')).openWrite().close(),
+ throwsFileSystemException(ErrorCodes.EISDIR));
+ });
+
+ test('throwsIfExistsAsLinkToDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ expect(fs.file(ns('/bar')).openWrite().close(),
+ throwsFileSystemException(ErrorCodes.EISDIR));
+ });
+
+ test('throwsIfModeIsRead', () {
+ expect(() => fs.file(ns('/foo')).openWrite(mode: FileMode.read),
+ throwsArgumentError);
+ });
+
+ test('succeedsIfExistsAsEmptyFile', () async {
+ File f = fs.file(ns('/foo'))..createSync();
+ IOSink sink = f.openWrite();
+ sink.write('Hello world');
+ await sink.flush();
+ await sink.close();
+ expect(f.readAsStringSync(), 'Hello world');
+ });
+
+ test('succeedsIfExistsAsLinkToFile', () async {
+ fs.file(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ IOSink sink = fs.file(ns('/bar')).openWrite();
+ sink.write('Hello world');
+ await sink.flush();
+ await sink.close();
+ expect(fs.file(ns('/foo')).readAsStringSync(), 'Hello world');
+ });
+
+ test('overwritesContentInWriteMode', () async {
+ File f = fs.file(ns('/foo'))..createSync();
+ f.writeAsStringSync('Hello');
+ IOSink sink = f.openWrite();
+ sink.write('Goodbye');
+ await sink.flush();
+ await sink.close();
+ expect(fs.file(ns('/foo')).readAsStringSync(), 'Goodbye');
+ });
+
+ test('appendsContentInAppendMode', () async {
+ File f = fs.file(ns('/foo'))..createSync();
+ f.writeAsStringSync('Hello');
+ IOSink sink = f.openWrite(mode: FileMode.append);
+ sink.write('Goodbye');
+ await sink.flush();
+ await sink.close();
+ expect(fs.file(ns('/foo')).readAsStringSync(), 'HelloGoodbye');
+ });
+
+ test('openWriteHandleDoesNotChange', () async {
+ File f = fs.file(ns('/foo'))..createSync();
+ IOSink sink = f.openWrite();
+ sink.write('Hello');
+ await sink.flush();
+
+ final File newFile = f.renameSync(ns('/bar'));
+ sink.write('Goodbye');
+ await sink.flush();
+ await sink.close();
+
+ expect(newFile.readAsStringSync(), 'HelloGoodbye');
+
+ assert(newFile.path != f.path);
+ expect(f, isNot(exists));
+ expect(newFile, exists);
+ });
+
+ group('ioSink', () {
+ late File f;
+ late IOSink sink;
+ late bool isSinkClosed;
+
+ Future<dynamic> closeSink() {
+ Future<dynamic> future = sink.close();
+ isSinkClosed = true;
+ return future;
+ }
+
+ setUp(() {
+ f = fs.file(ns('/foo'));
+ sink = f.openWrite();
+ isSinkClosed = false;
+ });
+
+ tearDown(() async {
+ if (!isSinkClosed) {
+ await closeSink();
+ }
+ });
+
+ test('throwsIfAddError', () async {
+ sink.addError(ArgumentError());
+ expect(sink.done, throwsArgumentError);
+ isSinkClosed = true;
+ });
+
+ test('allowsChangingEncoding', () async {
+ sink.encoding = latin1;
+ sink.write('ÿ');
+ sink.encoding = utf8;
+ sink.write('ÿ');
+ await sink.flush();
+ expect(await f.readAsBytes(), <int>[255, 195, 191]);
+ });
+
+ test('succeedsIfAddRawData', () async {
+ sink.add(<int>[1, 2, 3, 4]);
+ await sink.flush();
+ expect(await f.readAsBytes(), <int>[1, 2, 3, 4]);
+ });
+
+ test('succeedsIfWrite', () async {
+ sink.write('Hello world');
+ await sink.flush();
+ expect(await f.readAsString(), 'Hello world');
+ });
+
+ test('succeedsIfWriteAll', () async {
+ sink.writeAll(<String>['foo', 'bar', 'baz'], ' ');
+ await sink.flush();
+ expect(await f.readAsString(), 'foo bar baz');
+ });
+
+ test('succeedsIfWriteCharCode', () async {
+ sink.writeCharCode(35);
+ await sink.flush();
+ expect(await f.readAsString(), '#');
+ });
+
+ test('succeedsIfWriteln', () async {
+ sink.writeln('Hello world');
+ await sink.flush();
+ expect(await f.readAsString(), 'Hello world\n');
+ });
+
+ test('ignoresDataWrittenAfterClose', () async {
+ sink.write('Before close');
+ await closeSink();
+ expect(() => sink.write('After close'), throwsStateError);
+ expect(await f.readAsString(), 'Before close');
+ });
+
+ test('ignoresCloseAfterAlreadyClosed', () async {
+ sink.write('Hello world');
+ Future<dynamic> f1 = closeSink();
+ Future<dynamic> f2 = closeSink();
+ await Future.wait<dynamic>(<Future<dynamic>>[f1, f2]);
+ });
+
+ test('returnsAccurateDoneFuture', () async {
+ bool done = false;
+ // ignore: unawaited_futures
+ sink.done.then((dynamic _) => done = true);
+ expect(done, isFalse);
+ sink.write('foo');
+ expect(done, isFalse);
+ await sink.close();
+ expect(done, isTrue);
+ });
+
+ group('addStream', () {
+ late StreamController<List<int>> controller;
+ late bool isControllerClosed;
+
+ Future<dynamic> closeController() {
+ Future<dynamic> future = controller.close();
+ isControllerClosed = true;
+ return future;
+ }
+
+ setUp(() {
+ controller = StreamController<List<int>>();
+ isControllerClosed = false;
+ sink.addStream(controller.stream);
+ });
+
+ tearDown(() async {
+ if (!isControllerClosed) {
+ await closeController();
+ }
+ });
+
+ test('succeedsIfStreamProducesData', () async {
+ controller.add(<int>[1, 2, 3, 4, 5]);
+ await closeController();
+ await sink.flush();
+ expect(await f.readAsBytes(), <int>[1, 2, 3, 4, 5]);
+ });
+
+ test('blocksCallToAddWhileStreamIsActive', () {
+ expect(() => sink.add(<int>[1, 2, 3]), throwsStateError);
+ });
+
+ test('blocksCallToWriteWhileStreamIsActive', () {
+ expect(() => sink.write('foo'), throwsStateError);
+ });
+
+ test('blocksCallToWriteAllWhileStreamIsActive', () {
+ expect(() => sink.writeAll(<String>['a', 'b']), throwsStateError);
+ });
+
+ test('blocksCallToWriteCharCodeWhileStreamIsActive', () {
+ expect(() => sink.writeCharCode(35), throwsStateError);
+ });
+
+ test('blocksCallToWritelnWhileStreamIsActive', () {
+ expect(() => sink.writeln('foo'), throwsStateError);
+ });
+
+ test('blocksCallToFlushWhileStreamIsActive', () {
+ expect(() => sink.flush(), throwsStateError);
+ });
+ });
+ });
+ });
+
+ group('readAsBytes', () {
+ test('throwsIfDoesntExist', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.file(ns('/foo')).readAsBytesSync();
+ });
+ });
+
+ test('throwsIfExistsAsDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ expectFileSystemException(ErrorCodes.EISDIR, () {
+ fs.file(ns('/foo')).readAsBytesSync();
+ });
+ });
+
+ test('throwsIfExistsAsLinkToDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ expectFileSystemException(ErrorCodes.EISDIR, () {
+ fs.file(ns('/bar')).readAsBytesSync();
+ });
+ });
+
+ test('succeedsIfExistsAsFile', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ f.writeAsBytesSync(<int>[1, 2, 3, 4]);
+ expect(f.readAsBytesSync(), <int>[1, 2, 3, 4]);
+ });
+
+ test('succeedsIfExistsAsLinkToFile', () {
+ fs.file(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ fs.file(ns('/foo')).writeAsBytesSync(<int>[1, 2, 3, 4]);
+ expect(fs.file(ns('/bar')).readAsBytesSync(), <int>[1, 2, 3, 4]);
+ });
+
+ test('returnsEmptyListForZeroByteFile', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ expect(f.readAsBytesSync(), isEmpty);
+ });
+
+ test('returns a copy, not a view, of the file content', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ f.writeAsBytesSync(<int>[1, 2, 3, 4]);
+ List<int> result = f.readAsBytesSync();
+ expect(result, <int>[1, 2, 3, 4]);
+ result[0] = 10;
+ expect(f.readAsBytesSync(), <int>[1, 2, 3, 4]);
+ });
+ });
+
+ group('readAsString', () {
+ test('throwsIfDoesntExist', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.file(ns('/foo')).readAsStringSync();
+ });
+ });
+
+ test('throwsIfExistsAsDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ expectFileSystemException(ErrorCodes.EISDIR, () {
+ fs.file(ns('/foo')).readAsStringSync();
+ });
+ });
+
+ test('throwsIfExistsAsLinkToDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ expectFileSystemException(ErrorCodes.EISDIR, () {
+ fs.file(ns('/bar')).readAsStringSync();
+ });
+ });
+
+ test('succeedsIfExistsAsFile', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ f.writeAsStringSync('Hello world');
+ expect(f.readAsStringSync(), 'Hello world');
+ });
+
+ test('succeedsIfExistsAsLinkToFile', () {
+ fs.file(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ fs.file(ns('/foo')).writeAsStringSync('Hello world');
+ expect(fs.file(ns('/bar')).readAsStringSync(), 'Hello world');
+ });
+
+ test('returnsEmptyStringForZeroByteFile', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ expect(f.readAsStringSync(), isEmpty);
+ });
+ });
+
+ group('readAsLines', () {
+ const String testString = 'Hello world\nHow are you?\nI am fine';
+ final List<String> expectedLines = <String>[
+ 'Hello world',
+ 'How are you?',
+ 'I am fine',
+ ];
+
+ test('throwsIfDoesntExist', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.file(ns('/foo')).readAsLinesSync();
+ });
+ });
+
+ test('throwsIfExistsAsDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ expectFileSystemException(ErrorCodes.EISDIR, () {
+ fs.file(ns('/foo')).readAsLinesSync();
+ });
+ });
+
+ test('throwsIfExistsAsLinkToDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ expectFileSystemException(ErrorCodes.EISDIR, () {
+ fs.file(ns('/bar')).readAsLinesSync();
+ });
+ });
+
+ test('succeedsIfExistsAsFile', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ f.writeAsStringSync(testString);
+ expect(f.readAsLinesSync(), expectedLines);
+ });
+
+ test('succeedsIfExistsAsLinkToFile', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ f.writeAsStringSync(testString);
+ expect(f.readAsLinesSync(), expectedLines);
+ });
+
+ test('returnsEmptyListForZeroByteFile', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ expect(f.readAsLinesSync(), isEmpty);
+ });
+
+ test('isTrailingNewlineAgnostic', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ f.writeAsStringSync('$testString\n');
+ expect(f.readAsLinesSync(), expectedLines);
+
+ f.writeAsStringSync('\n');
+ expect(f.readAsLinesSync(), <String>['']);
+
+ f.writeAsStringSync('\n\n');
+ expect(f.readAsLinesSync(), <String>['', '']);
+ });
+ });
+
+ group('writeAsBytes', () {
+ test('returnsCovariantType', () async {
+ expect(await fs.file(ns('/foo')).writeAsBytes(<int>[]), isFile);
+ });
+
+ test('createsFileIfDoesntExist', () {
+ File f = fs.file(ns('/foo'));
+ expect(f, isNot(exists));
+ f.writeAsBytesSync(<int>[1, 2, 3, 4]);
+ expect(f, exists);
+ });
+
+ test('throwsIfExistsAsDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ expectFileSystemException(ErrorCodes.EISDIR, () {
+ fs.file(ns('/foo')).writeAsBytesSync(<int>[1, 2, 3, 4]);
+ });
+ });
+
+ test('throwsIfExistsAsLinkToDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ expectFileSystemException(ErrorCodes.EISDIR, () {
+ fs.file(ns('/foo')).writeAsBytesSync(<int>[1, 2, 3, 4]);
+ });
+ });
+
+ test('succeedsIfExistsAsLinkToFile', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ fs.file(ns('/bar')).writeAsBytesSync(<int>[1, 2, 3, 4]);
+ expect(f.readAsBytesSync(), <int>[1, 2, 3, 4]);
+ });
+
+ test('throwsIfFileModeRead', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ expectFileSystemException(ErrorCodes.EBADF, () {
+ f.writeAsBytesSync(<int>[1], mode: FileMode.read);
+ });
+ });
+
+ test('overwritesContentIfFileModeWrite', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ f.writeAsBytesSync(<int>[1, 2]);
+ expect(f.readAsBytesSync(), <int>[1, 2]);
+ f.writeAsBytesSync(<int>[3, 4]);
+ expect(f.readAsBytesSync(), <int>[3, 4]);
+ });
+
+ test('appendsContentIfFileModeAppend', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ f.writeAsBytesSync(<int>[1, 2], mode: FileMode.append);
+ expect(f.readAsBytesSync(), <int>[1, 2]);
+ f.writeAsBytesSync(<int>[3, 4], mode: FileMode.append);
+ expect(f.readAsBytesSync(), <int>[1, 2, 3, 4]);
+ });
+
+ test('acceptsEmptyBytesList', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ f.writeAsBytesSync(<int>[]);
+ expect(f.readAsBytesSync(), <int>[]);
+ });
+
+ test('updatesLastModifiedTime', () async {
+ File f = fs.file(ns('/foo'))..createSync();
+ DateTime before = f.statSync().modified;
+ await Future<void>.delayed(const Duration(seconds: 2));
+ f.writeAsBytesSync(<int>[1, 2, 3]);
+ DateTime after = f.statSync().modified;
+ expect(after, isAfter(before));
+ });
+ });
+
+ group('writeAsString', () {
+ test('returnsCovariantType', () async {
+ expect(await fs.file(ns('/foo')).writeAsString('foo'), isFile);
+ });
+
+ test('createsFileIfDoesntExist', () {
+ File f = fs.file(ns('/foo'));
+ expect(f, isNot(exists));
+ f.writeAsStringSync('Hello world');
+ expect(f, exists);
+ });
+
+ test('throwsIfExistsAsDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ expectFileSystemException(ErrorCodes.EISDIR, () {
+ fs.file(ns('/foo')).writeAsStringSync('Hello world');
+ });
+ });
+
+ test('throwsIfExistsAsLinkToDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ expectFileSystemException(ErrorCodes.EISDIR, () {
+ fs.file(ns('/foo')).writeAsStringSync('Hello world');
+ });
+ });
+
+ test('succeedsIfExistsAsLinkToFile', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ fs.file(ns('/bar')).writeAsStringSync('Hello world');
+ expect(f.readAsStringSync(), 'Hello world');
+ });
+
+ test('throwsIfFileModeRead', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ expectFileSystemException(ErrorCodes.EBADF, () {
+ f.writeAsStringSync('Hello world', mode: FileMode.read);
+ });
+ });
+
+ test('overwritesContentIfFileModeWrite', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ f.writeAsStringSync('Hello world');
+ expect(f.readAsStringSync(), 'Hello world');
+ f.writeAsStringSync('Goodbye cruel world');
+ expect(f.readAsStringSync(), 'Goodbye cruel world');
+ });
+
+ test('appendsContentIfFileModeAppend', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ f.writeAsStringSync('Hello', mode: FileMode.append);
+ expect(f.readAsStringSync(), 'Hello');
+ f.writeAsStringSync('Goodbye', mode: FileMode.append);
+ expect(f.readAsStringSync(), 'HelloGoodbye');
+ });
+
+ test('acceptsEmptyString', () {
+ File f = fs.file(ns('/foo'))..createSync();
+ f.writeAsStringSync('');
+ expect(f.readAsStringSync(), isEmpty);
+ });
+ });
+
+ group('exists', () {
+ test('trueIfExists', () {
+ fs.file(ns('/foo')).createSync();
+ expect(fs.file(ns('/foo')), exists);
+ });
+
+ test('falseIfDoesntExistAtTail', () {
+ expect(fs.file(ns('/foo')), isNot(exists));
+ });
+
+ test('falseIfDoesntExistViaTraversal', () {
+ expect(fs.file(ns('/foo/bar')), isNot(exists));
+ });
+
+ test('falseIfExistsAsDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ expect(fs.file(ns('/foo')), isNot(exists));
+ });
+
+ test('falseIfExistsAsLinkToDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ expect(fs.file(ns('/bar')), isNot(exists));
+ });
+
+ test('trueIfExistsAsLinkToFile', () {
+ fs.file(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ expect(fs.file(ns('/bar')), exists);
+ });
+
+ test('falseIfNotFoundSegmentExistsThenIsBackedOut', () {
+ fs.file(ns('/foo/bar')).createSync(recursive: true);
+ expect(fs.directory(ns('/baz/../foo/bar')), isNot(exists));
+ });
+ });
+
+ group('stat', () {
+ test('isNotFoundIfDoesntExistAtTail', () {
+ FileStat stat = fs.file(ns('/foo')).statSync();
+ expect(stat.type, FileSystemEntityType.notFound);
+ });
+
+ test('isNotFoundIfDoesntExistViaTraversal', () {
+ FileStat stat = fs.file(ns('/foo/bar')).statSync();
+ expect(stat.type, FileSystemEntityType.notFound);
+ });
+
+ test('isDirectoryIfExistsAsDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ FileStat stat = fs.file(ns('/foo')).statSync();
+ expect(stat.type, FileSystemEntityType.directory);
+ });
+
+ test('isFileIfExistsAsFile', () {
+ fs.file(ns('/foo')).createSync();
+ FileStat stat = fs.file(ns('/foo')).statSync();
+ expect(stat.type, FileSystemEntityType.file);
+ });
+
+ test('isFileIfExistsAsLinkToFile', () {
+ fs.file(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ FileStat stat = fs.file(ns('/bar')).statSync();
+ expect(stat.type, FileSystemEntityType.file);
+ });
+ });
+
+ group('delete', () {
+ test('returnsCovariantType', () async {
+ File f = fs.file(ns('/foo'))..createSync();
+ expect(await f.delete(), isFile);
+ });
+
+ test('succeedsIfExistsAsFile', () {
+ fs.file(ns('/foo')).createSync();
+ expect(fs.file(ns('/foo')), exists);
+ fs.file(ns('/foo')).deleteSync();
+ expect(fs.file(ns('/foo')), isNot(exists));
+ });
+
+ test('throwsIfDoesntExistAndRecursiveFalse', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.file(ns('/foo')).deleteSync();
+ });
+ });
+
+ test('throwsIfDoesntExistAndRecursiveTrue', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.file(ns('/foo')).deleteSync(recursive: true);
+ });
+ });
+
+ test('succeedsIfExistsAsDirectoryAndRecursiveTrue', () {
+ fs.directory(ns('/foo')).createSync();
+ fs.file(ns('/foo')).deleteSync(recursive: true);
+ expect(fs.typeSync(ns('/foo')), FileSystemEntityType.notFound);
+ });
+
+ test('throwsIfExistsAsDirectoryAndRecursiveFalse', () {
+ fs.directory(ns('/foo')).createSync();
+ expectFileSystemException(ErrorCodes.EISDIR, () {
+ fs.file(ns('/foo')).deleteSync();
+ });
+ });
+
+ test('succeedsIfExistsAsLinkToFileAndRecursiveTrue', () {
+ fs.file(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ expect(fs.file(ns('/bar')), exists);
+ fs.file(ns('/bar')).deleteSync(recursive: true);
+ expect(fs.file(ns('/bar')), isNot(exists));
+ });
+
+ test('succeedsIfExistsAsLinkToFileAndRecursiveFalse', () {
+ fs.file(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ expect(fs.file(ns('/bar')), exists);
+ fs.file(ns('/bar')).deleteSync();
+ expect(fs.file(ns('/bar')), isNot(exists));
+ });
+
+ test('succeedsIfExistsAsLinkToDirectoryAndRecursiveTrue', () {
+ fs.directory(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ expect(fs.typeSync(ns('/bar')), FileSystemEntityType.directory);
+ fs.file(ns('/bar')).deleteSync(recursive: true);
+ expect(fs.typeSync(ns('/foo')), FileSystemEntityType.directory);
+ expect(fs.typeSync(ns('/bar')), FileSystemEntityType.notFound);
+ });
+
+ test('throwsIfExistsAsLinkToDirectoryAndRecursiveFalse', () {
+ fs.directory(ns('/foo')).createSync();
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ expectFileSystemException(ErrorCodes.EISDIR, () {
+ fs.file(ns('/bar')).deleteSync();
+ });
+ });
+ });
+ });
+
+ group('Link', () {
+ group('uri', () {
+ test('whenTargetIsDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ Link l = fs.link(ns('/bar'))..createSync(ns('/foo'));
+ expect(l.uri, fs.path.toUri(ns('/bar')));
+ expect(fs.link('bar').uri.toString(), 'bar');
+ });
+
+ test('whenTargetIsFile', () {
+ fs.file(ns('/foo')).createSync();
+ Link l = fs.link(ns('/bar'))..createSync(ns('/foo'));
+ expect(l.uri, fs.path.toUri(ns('/bar')));
+ expect(fs.link('bar').uri.toString(), 'bar');
+ });
+
+ test('whenLinkDoesntExist', () {
+ expect(fs.link(ns('/foo')).uri, fs.path.toUri(ns('/foo')));
+ expect(fs.link('foo').uri.toString(), 'foo');
+ });
+ });
+
+ group('exists', () {
+ test('isFalseIfLinkDoesntExistAtTail', () {
+ expect(fs.link(ns('/foo')), isNot(exists));
+ });
+
+ test('isFalseIfLinkDoesntExistViaTraversal', () {
+ expect(fs.link(ns('/foo/bar')), isNot(exists));
+ });
+
+ test('isFalseIfPathReferencesFile', () {
+ fs.file(ns('/foo')).createSync();
+ expect(fs.link(ns('/foo')), isNot(exists));
+ });
+
+ test('isFalseIfPathReferencesDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ expect(fs.link(ns('/foo')), isNot(exists));
+ });
+
+ test('isTrueIfTargetIsNotFound', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ expect(l, exists);
+ });
+
+ test('isTrueIfTargetIsFile', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ fs.file(ns('/bar')).createSync();
+ expect(l, exists);
+ });
+
+ test('isTrueIfTargetIsDirectory', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ fs.directory(ns('/bar')).createSync();
+ expect(l, exists);
+ });
+
+ test('isTrueIfTargetIsLinkLoop', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ expect(l, exists);
+ });
+ });
+
+ group('stat', () {
+ test('isNotFoundIfLinkDoesntExistAtTail', () {
+ expect(fs.link(ns('/foo')).statSync().type,
+ FileSystemEntityType.notFound);
+ });
+
+ test('isNotFoundIfLinkDoesntExistViaTraversal', () {
+ expect(fs.link(ns('/foo/bar')).statSync().type,
+ FileSystemEntityType.notFound);
+ });
+
+ test('isFileIfPathReferencesFile', () {
+ fs.file(ns('/foo')).createSync();
+ expect(
+ fs.link(ns('/foo')).statSync().type, FileSystemEntityType.file);
+ });
+
+ test('isDirectoryIfPathReferencesDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ expect(fs.link(ns('/foo')).statSync().type,
+ FileSystemEntityType.directory);
+ });
+
+ test('isNotFoundIfTargetNotFoundAtTail', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ expect(l.statSync().type, FileSystemEntityType.notFound);
+ });
+
+ test('isNotFoundIfTargetNotFoundViaTraversal', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar/baz'));
+ expect(l.statSync().type, FileSystemEntityType.notFound);
+ });
+
+ test('isNotFoundIfTargetIsLinkLoop', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ expect(l.statSync().type, FileSystemEntityType.notFound);
+ });
+
+ test('isFileIfTargetIsFile', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ fs.file(ns('/bar')).createSync();
+ expect(l.statSync().type, FileSystemEntityType.file);
+ });
+
+ test('isDirectoryIfTargetIsDirectory', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ fs.directory(ns('/bar')).createSync();
+ expect(l.statSync().type, FileSystemEntityType.directory);
+ });
+ });
+
+ group('delete', () {
+ test('returnsCovariantType', () async {
+ Link link = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ expect(await link.delete(), isLink);
+ });
+
+ test('throwsIfLinkDoesntExistAtTail', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.link(ns('/foo')).deleteSync();
+ });
+ });
+
+ test('throwsIfLinkDoesntExistViaTraversal', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.link(ns('/foo/bar')).deleteSync();
+ });
+ });
+
+ test('throwsIfPathReferencesFileAndRecursiveFalse', () {
+ fs.file(ns('/foo')).createSync();
+ expectFileSystemException(ErrorCodes.EINVAL, () {
+ fs.link(ns('/foo')).deleteSync();
+ });
+ });
+
+ test('succeedsIfPathReferencesFileAndRecursiveTrue', () {
+ fs.file(ns('/foo')).createSync();
+ fs.link(ns('/foo')).deleteSync(recursive: true);
+ expect(fs.typeSync(ns('/foo'), followLinks: false),
+ FileSystemEntityType.notFound);
+ });
+
+ test('throwsIfPathReferencesDirectoryAndRecursiveFalse', () {
+ fs.directory(ns('/foo')).createSync();
+ // TODO(tvolkert): Change this to just be 'Is a directory'
+ // once Dart 1.22 is stable.
+ expectFileSystemException(
+ anyOf(ErrorCodes.EINVAL, ErrorCodes.EISDIR),
+ () {
+ fs.link(ns('/foo')).deleteSync();
+ },
+ );
+ });
+
+ test('succeedsIfPathReferencesDirectoryAndRecursiveTrue', () {
+ fs.directory(ns('/foo')).createSync();
+ fs.link(ns('/foo')).deleteSync(recursive: true);
+ expect(fs.typeSync(ns('/foo'), followLinks: false),
+ FileSystemEntityType.notFound);
+ });
+
+ test('unlinksIfTargetIsFileAndRecursiveFalse', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ fs.file(ns('/bar')).createSync();
+ l.deleteSync();
+ expect(fs.typeSync(ns('/foo'), followLinks: false),
+ FileSystemEntityType.notFound);
+ expect(fs.typeSync(ns('/bar'), followLinks: false),
+ FileSystemEntityType.file);
+ });
+
+ test('unlinksIfTargetIsFileAndRecursiveTrue', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ fs.file(ns('/bar')).createSync();
+ l.deleteSync(recursive: true);
+ expect(fs.typeSync(ns('/foo'), followLinks: false),
+ FileSystemEntityType.notFound);
+ expect(fs.typeSync(ns('/bar'), followLinks: false),
+ FileSystemEntityType.file);
+ });
+
+ test('unlinksIfTargetIsDirectoryAndRecursiveFalse', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ fs.directory(ns('/bar')).createSync();
+ l.deleteSync();
+ expect(fs.typeSync(ns('/foo'), followLinks: false),
+ FileSystemEntityType.notFound);
+ expect(fs.typeSync(ns('/bar'), followLinks: false),
+ FileSystemEntityType.directory);
+ });
+
+ test('unlinksIfTargetIsDirectoryAndRecursiveTrue', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ fs.directory(ns('/bar')).createSync();
+ l.deleteSync(recursive: true);
+ expect(fs.typeSync(ns('/foo'), followLinks: false),
+ FileSystemEntityType.notFound);
+ expect(fs.typeSync(ns('/bar'), followLinks: false),
+ FileSystemEntityType.directory);
+ });
+
+ test('unlinksIfTargetIsLinkLoop', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ l.deleteSync();
+ expect(fs.typeSync(ns('/foo'), followLinks: false),
+ FileSystemEntityType.notFound);
+ expect(fs.typeSync(ns('/bar'), followLinks: false),
+ FileSystemEntityType.link);
+ });
+ });
+
+ group('parent', () {
+ test('returnsCovariantType', () {
+ expect(fs.link(ns('/foo')).parent, isDirectory);
+ });
+
+ test('succeedsIfLinkDoesntExist', () {
+ expect(fs.link(ns('/foo')).parent.path, ns('/'));
+ });
+
+ test('ignoresLinkTarget', () {
+ Link l = fs.link(ns('/foo/bar'))
+ ..createSync(ns('/baz/qux'), recursive: true);
+ expect(l.parent.path, ns('/foo'));
+ });
+ });
+
+ group('create', () {
+ test('returnsCovariantType', () async {
+ expect(await fs.link(ns('/foo')).create(ns('/bar')), isLink);
+ });
+
+ test('succeedsIfLinkDoesntExistAtTail', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ expect(fs.typeSync(ns('/foo'), followLinks: false),
+ FileSystemEntityType.link);
+ expect(l.targetSync(), ns('/bar'));
+ });
+
+ test('throwsIfLinkDoesntExistViaTraversalAndRecursiveFalse', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.link(ns('/foo/bar')).createSync('baz');
+ });
+ });
+
+ test('succeedsIfLinkDoesntExistViaTraversalAndRecursiveTrue', () {
+ Link l = fs.link(ns('/foo/bar'))..createSync('baz', recursive: true);
+ expect(fs.typeSync(ns('/foo'), followLinks: false),
+ FileSystemEntityType.directory);
+ expect(fs.typeSync(ns('/foo/bar'), followLinks: false),
+ FileSystemEntityType.link);
+ expect(l.targetSync(), 'baz');
+ });
+
+ test('throwsIfAlreadyExistsAsFile', () {
+ fs.file(ns('/foo')).createSync();
+ expectFileSystemException(ErrorCodes.EEXIST, () {
+ fs.link(ns('/foo')).createSync(ns('/bar'));
+ });
+ });
+
+ test('throwsIfAlreadyExistsAsDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ expectFileSystemException(ErrorCodes.EEXIST, () {
+ fs.link(ns('/foo')).createSync(ns('/bar'));
+ });
+ });
+
+ test('throwsIfAlreadyExistsWithSameTarget', () {
+ fs.link(ns('/foo')).createSync(ns('/bar'));
+ expectFileSystemException(ErrorCodes.EEXIST, () {
+ fs.link(ns('/foo')).createSync(ns('/bar'));
+ });
+ });
+
+ test('throwsIfAlreadyExistsWithDifferentTarget', () {
+ fs.link(ns('/foo')).createSync(ns('/bar'));
+ expectFileSystemException(ErrorCodes.EEXIST, () {
+ fs.link(ns('/foo')).createSync(ns('/baz'));
+ });
+ });
+ });
+
+ group('update', () {
+ test('returnsCovariantType', () async {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ expect(await l.update(ns('/baz')), isLink);
+ });
+
+ test('throwsIfLinkDoesntExistAtTail', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.link(ns('/foo')).updateSync(ns('/bar'));
+ });
+ });
+
+ test('throwsIfLinkDoesntExistViaTraversal', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.link(ns('/foo/bar')).updateSync(ns('/baz'));
+ });
+ });
+
+ test('throwsIfPathReferencesFile', () {
+ fs.file(ns('/foo')).createSync();
+ expectFileSystemException(ErrorCodes.EINVAL, () {
+ fs.link(ns('/foo')).updateSync(ns('/bar'));
+ });
+ });
+
+ test('throwsIfPathReferencesDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ // TODO(tvolkert): Change this to just be 'Is a directory'
+ // once Dart 1.22 is stable.
+ expectFileSystemException(
+ anyOf(ErrorCodes.EINVAL, ErrorCodes.EISDIR),
+ () {
+ fs.link(ns('/foo')).updateSync(ns('/bar'));
+ },
+ );
+ });
+
+ test('succeedsIfNewTargetSameAsOldTarget', () {
+ fs.link(ns('/foo')).createSync(ns('/bar'));
+ fs.link(ns('/foo')).updateSync(ns('/bar'));
+ expect(fs.typeSync(ns('/foo'), followLinks: false),
+ FileSystemEntityType.link);
+ expect(fs.link(ns('/foo')).targetSync(), ns('/bar'));
+ });
+
+ test('succeedsIfNewTargetDifferentFromOldTarget', () {
+ fs.link(ns('/foo')).createSync(ns('/bar'));
+ fs.link(ns('/foo')).updateSync(ns('/baz'));
+ expect(fs.typeSync(ns('/foo'), followLinks: false),
+ FileSystemEntityType.link);
+ expect(fs.link(ns('/foo')).targetSync(), ns('/baz'));
+ });
+ });
+
+ group('absolute', () {
+ test('returnsCovariantType', () {
+ expect(fs.link('foo').absolute, isLink);
+ });
+
+ test('returnsSamePathIfAlreadyAbsolute', () {
+ expect(fs.link(ns('/foo')).absolute.path, ns('/foo'));
+ });
+
+ test('succeedsForRelativePaths', () {
+ expect(fs.link('foo').absolute.path, ns('/foo'));
+ });
+ });
+
+ group('target', () {
+ test('throwsIfLinkDoesntExistAtTail', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.link(ns('/foo')).targetSync();
+ });
+ });
+
+ test('throwsIfLinkDoesntExistViaTraversal', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.link(ns('/foo/bar')).targetSync();
+ });
+ });
+
+ test('throwsIfPathReferencesFile', () {
+ fs.file(ns('/foo')).createSync();
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.link(ns('/foo')).targetSync();
+ });
+ });
+
+ test('throwsIfPathReferencesDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.link(ns('/foo')).targetSync();
+ });
+ });
+
+ test('succeedsIfTargetIsNotFound', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ expect(l.targetSync(), ns('/bar'));
+ });
+
+ test('succeedsIfTargetIsFile', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ fs.file(ns('/bar')).createSync();
+ expect(l.targetSync(), ns('/bar'));
+ });
+
+ test('succeedsIfTargetIsDirectory', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ fs.directory(ns('/bar')).createSync();
+ expect(l.targetSync(), ns('/bar'));
+ });
+
+ test('succeedsIfTargetIsLinkLoop', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ expect(l.targetSync(), ns('/bar'));
+ });
+ });
+
+ group('rename', () {
+ test('returnsCovariantType', () async {
+ Link l() => fs.link(ns('/foo'))..createSync(ns('/bar'));
+ expect(l().renameSync(ns('/bar')), isLink);
+ expect(await l().rename(ns('/bar')), isLink);
+ });
+
+ test('throwsIfSourceDoesntExistAtTail', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.link(ns('/foo')).renameSync(ns('/bar'));
+ });
+ });
+
+ test('throwsIfSourceDoesntExistViaTraversal', () {
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ fs.link(ns('/foo/bar')).renameSync(ns('/bar'));
+ });
+ });
+
+ test('throwsIfSourceIsFile', () {
+ fs.file(ns('/foo')).createSync();
+ expectFileSystemException(ErrorCodes.EINVAL, () {
+ fs.link(ns('/foo')).renameSync(ns('/bar'));
+ });
+ });
+
+ test('throwsIfSourceIsDirectory', () {
+ fs.directory(ns('/foo')).createSync();
+ expectFileSystemException(ErrorCodes.EISDIR, () {
+ fs.link(ns('/foo')).renameSync(ns('/bar'));
+ });
+ });
+
+ test('succeedsIfSourceIsLinkToFile', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ fs.file(ns('/bar')).createSync();
+ Link renamed = l.renameSync(ns('/baz'));
+ expect(renamed.path, ns('/baz'));
+ expect(fs.typeSync(ns('/foo'), followLinks: false),
+ FileSystemEntityType.notFound);
+ expect(fs.typeSync(ns('/bar'), followLinks: false),
+ FileSystemEntityType.file);
+ expect(fs.typeSync(ns('/baz'), followLinks: false),
+ FileSystemEntityType.link);
+ expect(fs.link(ns('/baz')).targetSync(), ns('/bar'));
+ });
+
+ test('succeedsIfSourceIsLinkToNotFound', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ Link renamed = l.renameSync(ns('/baz'));
+ expect(renamed.path, ns('/baz'));
+ expect(fs.typeSync(ns('/foo'), followLinks: false),
+ FileSystemEntityType.notFound);
+ expect(fs.typeSync(ns('/baz'), followLinks: false),
+ FileSystemEntityType.link);
+ expect(fs.link(ns('/baz')).targetSync(), ns('/bar'));
+ });
+
+ test('succeedsIfSourceIsLinkToDirectory', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ fs.directory(ns('/bar')).createSync();
+ Link renamed = l.renameSync(ns('/baz'));
+ expect(renamed.path, ns('/baz'));
+ expect(fs.typeSync(ns('/foo'), followLinks: false),
+ FileSystemEntityType.notFound);
+ expect(fs.typeSync(ns('/bar'), followLinks: false),
+ FileSystemEntityType.directory);
+ expect(fs.typeSync(ns('/baz'), followLinks: false),
+ FileSystemEntityType.link);
+ expect(fs.link(ns('/baz')).targetSync(), ns('/bar'));
+ });
+
+ test('succeedsIfSourceIsLinkLoop', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ fs.link(ns('/bar')).createSync(ns('/foo'));
+ Link renamed = l.renameSync(ns('/baz'));
+ expect(renamed.path, ns('/baz'));
+ expect(fs.typeSync(ns('/foo'), followLinks: false),
+ FileSystemEntityType.notFound);
+ expect(fs.typeSync(ns('/bar'), followLinks: false),
+ FileSystemEntityType.link);
+ expect(fs.typeSync(ns('/baz'), followLinks: false),
+ FileSystemEntityType.link);
+ expect(fs.link(ns('/baz')).targetSync(), ns('/bar'));
+ });
+
+ test('succeedsIfDestinationDoesntExistAtTail', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ Link renamed = l.renameSync(ns('/baz'));
+ expect(renamed.path, ns('/baz'));
+ expect(fs.link(ns('/foo')), isNot(exists));
+ expect(fs.link(ns('/baz')), exists);
+ });
+
+ test('throwsIfDestinationDoesntExistViaTraversal', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ expectFileSystemException(ErrorCodes.ENOENT, () {
+ l.renameSync(ns('/baz/qux'));
+ });
+ });
+
+ test('throwsIfDestinationExistsAsFile', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ fs.file(ns('/baz')).createSync();
+ expectFileSystemException(ErrorCodes.EINVAL, () {
+ l.renameSync(ns('/baz'));
+ });
+ });
+
+ test('throwsIfDestinationExistsAsDirectory', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ fs.directory(ns('/baz')).createSync();
+ expectFileSystemException(ErrorCodes.EINVAL, () {
+ l.renameSync(ns('/baz'));
+ });
+ });
+
+ test('succeedsIfDestinationExistsAsLinkToFile', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ fs.file(ns('/baz')).createSync();
+ fs.link(ns('/qux')).createSync(ns('/baz'));
+ l.renameSync(ns('/qux'));
+ expect(fs.typeSync(ns('/foo')), FileSystemEntityType.notFound);
+ expect(fs.typeSync(ns('/baz'), followLinks: false),
+ FileSystemEntityType.file);
+ expect(fs.typeSync(ns('/qux'), followLinks: false),
+ FileSystemEntityType.link);
+ expect(fs.link(ns('/qux')).targetSync(), ns('/bar'));
+ });
+
+ test('throwsIfDestinationExistsAsLinkToDirectory', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ fs.directory(ns('/baz')).createSync();
+ fs.link(ns('/qux')).createSync(ns('/baz'));
+ l.renameSync(ns('/qux'));
+ expect(fs.typeSync(ns('/foo')), FileSystemEntityType.notFound);
+ expect(fs.typeSync(ns('/baz'), followLinks: false),
+ FileSystemEntityType.directory);
+ expect(fs.typeSync(ns('/qux'), followLinks: false),
+ FileSystemEntityType.link);
+ expect(fs.link(ns('/qux')).targetSync(), ns('/bar'));
+ });
+
+ test('succeedsIfDestinationExistsAsLinkToNotFound', () {
+ Link l = fs.link(ns('/foo'))..createSync(ns('/bar'));
+ fs.link(ns('/baz')).createSync(ns('/qux'));
+ l.renameSync(ns('/baz'));
+ expect(fs.typeSync(ns('/foo')), FileSystemEntityType.notFound);
+ expect(fs.typeSync(ns('/baz'), followLinks: false),
+ FileSystemEntityType.link);
+ expect(fs.link(ns('/baz')).targetSync(), ns('/bar'));
+ });
+ });
+ });
+ });
+}
diff --git a/pkgs/file/test/local_test.dart b/pkgs/file/test/local_test.dart
new file mode 100644
index 0000000..e1618d2
--- /dev/null
+++ b/pkgs/file/test/local_test.dart
@@ -0,0 +1,132 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@TestOn('vm')
+import 'dart:io' as io;
+
+import 'package:file/local.dart';
+import 'package:file_testing/src/testing/internal.dart';
+import 'package:test/test.dart';
+
+import 'common_tests.dart';
+
+void main() {
+ group('LocalFileSystem', () {
+ late LocalFileSystem fs;
+ late io.Directory tmp;
+ late String cwd;
+
+ setUp(() {
+ fs = const LocalFileSystem();
+ tmp = io.Directory.systemTemp.createTempSync('file_test_');
+ tmp = io.Directory(tmp.resolveSymbolicLinksSync());
+ cwd = io.Directory.current.path;
+ io.Directory.current = tmp;
+ });
+
+ tearDown(() {
+ io.Directory.current = cwd;
+ tmp.deleteSync(recursive: true);
+ });
+
+ setUpAll(() {
+ if (io.Platform.isWindows) {
+ // TODO(tvolkert): Remove once all more serious test failures are fixed
+ // https://github.com/google/file.dart/issues/56
+ ignoreOsErrorCodes = true;
+ }
+ });
+
+ tearDownAll(() {
+ ignoreOsErrorCodes = false;
+ });
+
+ Map<String, List<String>> skipOnPlatform = <String, List<String>>{
+ 'windows': <String>[
+ 'FileSystem > currentDirectory > throwsIfHasNonExistentPathInComplexChain',
+ 'FileSystem > currentDirectory > resolvesLinksIfEncountered',
+ 'FileSystem > currentDirectory > succeedsIfSetToDirectoryLinkAtTail',
+ 'FileSystem > stat > isFileForLinkToFile',
+ 'FileSystem > type > isFileForLinkToFileAndFollowLinksTrue',
+ 'FileSystem > type > isNotFoundForLinkWithCircularReferenceAndFollowLinksTrue',
+ 'Directory > exists > falseIfNotFoundSegmentExistsThenIsBackedOut',
+ 'Directory > rename > throwsIfDestinationIsNonEmptyDirectory',
+ 'Directory > rename > throwsIfDestinationIsLinkToEmptyDirectory',
+ 'Directory > resolveSymbolicLinks > throwsIfPathNotFoundInMiddleThenBackedOut',
+ 'Directory > resolveSymbolicLinks > handlesRelativeLinks',
+ 'Directory > resolveSymbolicLinks > handlesLinksWhoseTargetsHaveNestedLinks',
+ 'Directory > resolveSymbolicLinks > handlesComplexPathWithMultipleLinks',
+ 'Directory > createTemp > succeedsWithNestedPathPrefixThatExists',
+ 'Directory > list > followsLinksIfFollowLinksTrue',
+ 'Directory > list > returnsCovariantType',
+ 'Directory > list > returnsLinkObjectsForRecursiveLinkIfFollowLinksTrue',
+ 'Directory > delete > succeedsIfPathReferencesLinkToFileAndRecursiveTrue',
+ 'File > rename > succeedsIfSourceExistsAsLinkToFile',
+ 'File > copy > succeedsIfSourceExistsAsLinkToFile',
+ 'File > copy > succeedsIfSourceIsLinkToFileInDifferentDirectory',
+ 'File > delete > succeedsIfExistsAsLinkToFileAndRecursiveTrue',
+ 'File > openWrite > ioSink > throwsIfEncodingIsNullAndWriteObject',
+ 'File > openWrite > ioSink > allowsChangingEncoding',
+ 'File > openWrite > ioSink > succeedsIfAddRawData',
+ 'File > openWrite > ioSink > succeedsIfWrite',
+ 'File > openWrite > ioSink > succeedsIfWriteAll',
+ 'File > openWrite > ioSink > succeedsIfWriteCharCode',
+ 'File > openWrite > ioSink > succeedsIfWriteln',
+ 'File > openWrite > ioSink > addStream > succeedsIfStreamProducesData',
+ 'File > openWrite > ioSink > addStream > blocksCallToAddWhileStreamIsActive',
+ 'File > openWrite > ioSink > addStream > blocksCallToWriteWhileStreamIsActive',
+ 'File > openWrite > ioSink > addStream > blocksCallToWriteAllWhileStreamIsActive',
+ 'File > openWrite > ioSink > addStream > blocksCallToWriteCharCodeWhileStreamIsActive',
+ 'File > openWrite > ioSink > addStream > blocksCallToWritelnWhileStreamIsActive',
+ 'File > openWrite > ioSink > addStream > blocksCallToFlushWhileStreamIsActive',
+ 'File > stat > isFileIfExistsAsLinkToFile',
+ 'Link > stat > isFileIfTargetIsFile',
+ 'Link > stat > isDirectoryIfTargetIsDirectory',
+ 'Link > delete > unlinksIfTargetIsDirectoryAndRecursiveTrue',
+ 'Link > delete > unlinksIfTargetIsFileAndRecursiveTrue',
+
+ // Fixed in SDK 1.23 (https://github.com/dart-lang/sdk/issues/28852)
+ 'File > open > WRITE > RandomAccessFile > truncate > throwsIfSetToNegativeNumber',
+ 'File > open > APPEND > RandomAccessFile > truncate > throwsIfSetToNegativeNumber',
+ 'File > open > WRITE_ONLY > RandomAccessFile > truncate > throwsIfSetToNegativeNumber',
+ 'File > open > WRITE_ONLY_APPEND > RandomAccessFile > truncate > throwsIfSetToNegativeNumber',
+
+ // Windows does not allow removing or renaming open files.
+ '.* > openReadHandleDoesNotChange',
+ '.* > openWriteHandleDoesNotChange',
+ ],
+ };
+
+ runCommonTests(
+ () => fs,
+ root: () => tmp.path,
+ skip: <String>[
+ // https://github.com/dart-lang/sdk/issues/28171
+ 'File > rename > throwsIfDestinationExistsAsLinkToDirectory',
+
+ // https://github.com/dart-lang/sdk/issues/28275
+ 'Link > rename > throwsIfDestinationExistsAsDirectory',
+
+ // https://github.com/dart-lang/sdk/issues/28277
+ 'Link > rename > throwsIfDestinationExistsAsFile',
+
+ ...skipOnPlatform[io.Platform.operatingSystem] ?? <String>[],
+ ],
+ );
+
+ group('toString', () {
+ test('File', () {
+ expect(fs.file('/foo').toString(), "LocalFile: '/foo'");
+ });
+
+ test('Directory', () {
+ expect(fs.directory('/foo').toString(), "LocalDirectory: '/foo'");
+ });
+
+ test('Link', () {
+ expect(fs.link('/foo').toString(), "LocalLink: '/foo'");
+ });
+ });
+ });
+}
diff --git a/pkgs/file/test/memory_operations_test.dart b/pkgs/file/test/memory_operations_test.dart
new file mode 100644
index 0000000..5e27843
--- /dev/null
+++ b/pkgs/file/test/memory_operations_test.dart
@@ -0,0 +1,231 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:file/file.dart';
+import 'package:file/memory.dart';
+import 'package:test/test.dart';
+
+void main() {
+ test('Read operations invoke opHandle', () async {
+ List<String> contexts = <String>[];
+ List<FileSystemOp> operations = <FileSystemOp>[];
+ MemoryFileSystem fs = MemoryFileSystem.test(
+ opHandle: (String context, FileSystemOp operation) {
+ if (operation == FileSystemOp.read) {
+ contexts.add(context);
+ operations.add(operation);
+ }
+ });
+ final File file = fs.file('test')..createSync();
+
+ await file.readAsBytes();
+ file.readAsBytesSync();
+ await file.readAsString();
+ file.readAsStringSync();
+
+ expect(contexts, <String>['test', 'test', 'test', 'test']);
+ expect(operations, <FileSystemOp>[
+ FileSystemOp.read,
+ FileSystemOp.read,
+ FileSystemOp.read,
+ FileSystemOp.read
+ ]);
+ });
+
+ test('Write operations invoke opHandle', () async {
+ List<String> contexts = <String>[];
+ List<FileSystemOp> operations = <FileSystemOp>[];
+ MemoryFileSystem fs = MemoryFileSystem.test(
+ opHandle: (String context, FileSystemOp operation) {
+ if (operation == FileSystemOp.write) {
+ contexts.add(context);
+ operations.add(operation);
+ }
+ });
+ final File file = fs.file('test')..createSync();
+
+ await file.writeAsBytes(<int>[]);
+ file.writeAsBytesSync(<int>[]);
+ await file.writeAsString('');
+ file.writeAsStringSync('');
+
+ expect(contexts, <String>['test', 'test', 'test', 'test']);
+ expect(operations, <FileSystemOp>[
+ FileSystemOp.write,
+ FileSystemOp.write,
+ FileSystemOp.write,
+ FileSystemOp.write
+ ]);
+ });
+
+ test('Delete operations invoke opHandle', () async {
+ List<String> contexts = <String>[];
+ List<FileSystemOp> operations = <FileSystemOp>[];
+ MemoryFileSystem fs = MemoryFileSystem.test(
+ opHandle: (String context, FileSystemOp operation) {
+ if (operation == FileSystemOp.delete) {
+ contexts.add(context);
+ operations.add(operation);
+ }
+ });
+ final File file = fs.file('test')..createSync();
+ final Directory directory = fs.directory('testDir')..createSync();
+ final Link link = fs.link('testLink')..createSync('foo');
+
+ await file.delete();
+ file.createSync();
+ file.deleteSync();
+
+ await directory.delete();
+ directory.createSync();
+ directory.deleteSync();
+
+ await link.delete();
+ link.createSync('foo');
+ link.deleteSync();
+
+ expect(contexts,
+ <String>['test', 'test', 'testDir', 'testDir', 'testLink', 'testLink']);
+ expect(operations, <FileSystemOp>[
+ FileSystemOp.delete,
+ FileSystemOp.delete,
+ FileSystemOp.delete,
+ FileSystemOp.delete,
+ FileSystemOp.delete,
+ FileSystemOp.delete,
+ ]);
+ });
+
+ test('Create operations invoke opHandle', () async {
+ List<String> contexts = <String>[];
+ List<FileSystemOp> operations = <FileSystemOp>[];
+ MemoryFileSystem fs = MemoryFileSystem.test(
+ opHandle: (String context, FileSystemOp operation) {
+ if (operation == FileSystemOp.create) {
+ contexts.add(context);
+ operations.add(operation);
+ }
+ });
+ fs.file('testA').createSync();
+ await fs.file('testB').create();
+ fs.directory('testDirA').createSync();
+ await fs.directory('testDirB').create();
+ fs.link('testLinkA').createSync('foo');
+ await fs.link('testLinkB').create('foo');
+ fs.currentDirectory.createTempSync('tmp.bar');
+ await fs.currentDirectory.createTemp('tmp.bar');
+
+ expect(contexts, <dynamic>[
+ 'testA',
+ 'testB',
+ 'testDirA',
+ 'testDirB',
+ 'testLinkA',
+ 'testLinkB',
+ startsWith('/tmp.bar'),
+ startsWith('/tmp.bar'),
+ ]);
+ expect(operations, <FileSystemOp>[
+ FileSystemOp.create,
+ FileSystemOp.create,
+ FileSystemOp.create,
+ FileSystemOp.create,
+ FileSystemOp.create,
+ FileSystemOp.create,
+ FileSystemOp.create,
+ FileSystemOp.create,
+ ]);
+ });
+
+ test('Open operations invoke opHandle', () async {
+ List<String> contexts = <String>[];
+ List<FileSystemOp> operations = <FileSystemOp>[];
+ MemoryFileSystem fs = MemoryFileSystem.test(
+ opHandle: (String context, FileSystemOp operation) {
+ if (operation == FileSystemOp.open) {
+ contexts.add(context);
+ operations.add(operation);
+ }
+ });
+ final File file = fs.file('test')..createSync();
+
+ await file.open();
+ file.openSync();
+ file.openRead();
+ file.openWrite();
+
+ expect(contexts, <String>['test', 'test', 'test', 'test']);
+ expect(operations, <FileSystemOp>[
+ FileSystemOp.open,
+ FileSystemOp.open,
+ FileSystemOp.open,
+ FileSystemOp.open,
+ ]);
+ });
+
+ test('Copy operations invoke opHandle', () async {
+ List<String> contexts = <String>[];
+ List<FileSystemOp> operations = <FileSystemOp>[];
+ MemoryFileSystem fs = MemoryFileSystem.test(
+ opHandle: (String context, FileSystemOp operation) {
+ if (operation == FileSystemOp.copy) {
+ contexts.add(context);
+ operations.add(operation);
+ }
+ });
+ final File file = fs.file('test')..createSync();
+
+ await file.copy('A');
+ file.copySync('B');
+
+ expect(contexts, <String>['test', 'test']);
+ expect(operations, <FileSystemOp>[
+ FileSystemOp.copy,
+ FileSystemOp.copy,
+ ]);
+ });
+
+ test('Exists operations invoke opHandle', () async {
+ List<String> contexts = <String>[];
+ List<FileSystemOp> operations = <FileSystemOp>[];
+ MemoryFileSystem fs = MemoryFileSystem.test(
+ opHandle: (String context, FileSystemOp operation) {
+ if (operation == FileSystemOp.exists) {
+ contexts.add(context);
+ operations.add(operation);
+ }
+ });
+ fs.file('testA').existsSync();
+ await fs.file('testB').exists();
+ fs.directory('testDirA').existsSync();
+ await fs.directory('testDirB').exists();
+ fs.link('testLinkA').existsSync();
+ await fs.link('testLinkB').exists();
+
+ expect(contexts, <dynamic>[
+ 'testA',
+ 'testB',
+ 'testDirA',
+ 'testDirB',
+ 'testLinkA',
+ 'testLinkB',
+ ]);
+ expect(operations, <FileSystemOp>[
+ FileSystemOp.exists,
+ FileSystemOp.exists,
+ FileSystemOp.exists,
+ FileSystemOp.exists,
+ FileSystemOp.exists,
+ FileSystemOp.exists,
+ ]);
+ });
+
+ test('FileSystemOp toString', () {
+ expect(FileSystemOp.create.toString(), 'FileSystemOp.create');
+ expect(FileSystemOp.delete.toString(), 'FileSystemOp.delete');
+ expect(FileSystemOp.read.toString(), 'FileSystemOp.read');
+ expect(FileSystemOp.write.toString(), 'FileSystemOp.write');
+ expect(FileSystemOp.exists.toString(), 'FileSystemOp.exists');
+ });
+}
diff --git a/pkgs/file/test/memory_test.dart b/pkgs/file/test/memory_test.dart
new file mode 100644
index 0000000..f3b324e
--- /dev/null
+++ b/pkgs/file/test/memory_test.dart
@@ -0,0 +1,173 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io' as io;
+
+import 'package:file/file.dart';
+import 'package:file/memory.dart';
+import 'package:file/src/backends/memory/memory_random_access_file.dart';
+import 'package:test/test.dart';
+
+import 'common_tests.dart';
+
+void main() {
+ group('MemoryFileSystem unix style', () {
+ late MemoryFileSystem fs;
+
+ setUp(() {
+ fs = MemoryFileSystem();
+ });
+
+ runCommonTests(() => fs);
+
+ group('toString', () {
+ test('File', () {
+ expect(fs.file('/foo').toString(), "MemoryFile: '/foo'");
+ });
+
+ test('Directory', () {
+ expect(fs.directory('/foo').toString(), "MemoryDirectory: '/foo'");
+ });
+
+ test('Link', () {
+ expect(fs.link('/foo').toString(), "MemoryLink: '/foo'");
+ });
+ });
+ });
+
+ group('MemoryFileSystem windows style', () {
+ late MemoryFileSystem fs;
+
+ setUp(() {
+ fs = MemoryFileSystem(style: FileSystemStyle.windows);
+ });
+
+ runCommonTests(
+ () => fs,
+ root: () => fs.style.root,
+ );
+
+ group('toString', () {
+ test('File', () {
+ expect(fs.file('C:\\foo').toString(), "MemoryFile: 'C:\\foo'");
+ });
+
+ test('Directory', () {
+ expect(
+ fs.directory('C:\\foo').toString(), "MemoryDirectory: 'C:\\foo'");
+ });
+
+ test('Link', () {
+ expect(fs.link('C:\\foo').toString(), "MemoryLink: 'C:\\foo'");
+ });
+ });
+ });
+
+ test('MemoryFileSystem.test', () {
+ final MemoryFileSystem fs =
+ MemoryFileSystem.test(); // creates root directory
+ fs.file('/test1.txt').createSync(); // creates file
+ fs.file('/test2.txt').createSync(); // creates file
+ expect(fs.directory('/').statSync().modified, DateTime(2000, 1, 1, 0, 1));
+ expect(
+ fs.file('/test1.txt').statSync().modified, DateTime(2000, 1, 1, 0, 2));
+ expect(
+ fs.file('/test2.txt').statSync().modified, DateTime(2000, 1, 1, 0, 3));
+ fs.file('/test1.txt').createSync();
+ fs.file('/test2.txt').createSync();
+ expect(fs.file('/test1.txt').statSync().modified,
+ DateTime(2000, 1, 1, 0, 2)); // file already existed
+ expect(fs.file('/test2.txt').statSync().modified,
+ DateTime(2000, 1, 1, 0, 3)); // file already existed
+ fs.file('/test1.txt').writeAsStringSync('test'); // touches file
+ expect(
+ fs.file('/test1.txt').statSync().modified, DateTime(2000, 1, 1, 0, 4));
+ expect(fs.file('/test2.txt').statSync().modified,
+ DateTime(2000, 1, 1, 0, 3)); // didn't touch it
+ fs.file('/test1.txt').copySync(
+ '/test2.txt'); // creates file, then mutates file (so time changes twice)
+ expect(fs.file('/test1.txt').statSync().modified,
+ DateTime(2000, 1, 1, 0, 4)); // didn't touch it
+ expect(
+ fs.file('/test2.txt').statSync().modified, DateTime(2000, 1, 1, 0, 6));
+ });
+
+ test('MemoryFile.openSync returns a MemoryRandomAccessFile', () async {
+ final MemoryFileSystem fs = MemoryFileSystem.test();
+ final io.File file = fs.file('/test1')..createSync();
+
+ io.RandomAccessFile raf = file.openSync();
+ try {
+ expect(raf, isA<MemoryRandomAccessFile>());
+ } finally {
+ raf.closeSync();
+ }
+
+ raf = await file.open();
+ try {
+ expect(raf, isA<MemoryRandomAccessFile>());
+ } finally {
+ raf.closeSync();
+ }
+ });
+
+ test('MemoryFileSystem.systemTempDirectory test', () {
+ final MemoryFileSystem fs = MemoryFileSystem.test();
+
+ final io.Directory fooA = fs.systemTempDirectory.createTempSync('foo');
+ final io.Directory fooB = fs.systemTempDirectory.createTempSync('foo');
+
+ expect(fooA.path, '/.tmp_rand0/foorand0');
+ expect(fooB.path, '/.tmp_rand0/foorand1');
+
+ final MemoryFileSystem secondFs = MemoryFileSystem.test();
+
+ final io.Directory fooAA =
+ secondFs.systemTempDirectory.createTempSync('foo');
+ final io.Directory fooBB =
+ secondFs.systemTempDirectory.createTempSync('foo');
+
+ // Names are recycled with a new instance
+ expect(fooAA.path, '/.tmp_rand0/foorand0');
+ expect(fooBB.path, '/.tmp_rand0/foorand1');
+ });
+
+ test('Failed UTF8 decoding in MemoryFileSystem throws a FileSystemException',
+ () {
+ final MemoryFileSystem fileSystem = MemoryFileSystem.test();
+ final File file = fileSystem.file('foo')
+ ..writeAsBytesSync(<int>[0xFFFE]); // Invalid UTF8
+
+ expect(file.readAsStringSync, throwsA(isA<FileSystemException>()));
+ });
+
+ test('Creating a temporary directory actually creates the directory', () {
+ final MemoryFileSystem fileSystem = MemoryFileSystem.test();
+ final Directory tempDir = fileSystem.currentDirectory.createTempSync('foo');
+
+ expect(tempDir.existsSync(), true);
+ });
+
+ test(
+ 'addStream forwards error to returned future and file can still be '
+ 'closed', () async {
+ final file = MemoryFileSystem.test().file('foo').openWrite();
+ await expectLater(file.addStream(Stream.error('bar')), throwsA('bar'));
+ await file.close();
+ });
+
+ test(
+ 'addStream cancels on error and does not misbehave if the stream '
+ 'produces multiple errors and then closes', () async {
+ final file = MemoryFileSystem.test().file('foo').openWrite();
+ final controller = StreamController<List<int>>()
+ ..addError('bar')
+ ..addError('baz');
+ final close = controller.close();
+ await expectLater(file.addStream(controller.stream), throwsA('bar'));
+ await file.close();
+ await close;
+ });
+}
diff --git a/pkgs/file/test/utils.dart b/pkgs/file/test/utils.dart
new file mode 100644
index 0000000..231312f
--- /dev/null
+++ b/pkgs/file/test/utils.dart
@@ -0,0 +1,117 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:meta/meta.dart';
+import 'package:test/test.dart';
+
+const Duration _oneSecond = Duration(seconds: 1);
+
+/// Returns a [DateTime] with an exact second-precision by removing the
+/// milliseconds and microseconds from the specified [time].
+///
+/// If [time] is not specified, it will default to the current time.
+DateTime floor([DateTime? time]) {
+ time ??= DateTime.now();
+ return time.subtract(Duration(
+ milliseconds: time.millisecond,
+ microseconds: time.microsecond,
+ ));
+}
+
+/// Returns a [DateTime] with an exact second precision, rounding up to the
+/// nearest second if necessary.
+///
+/// If [time] is not specified, it will default to the current time.
+DateTime ceil([DateTime? time]) {
+ time ??= DateTime.now();
+ int microseconds = (1000 * time.millisecond) + time.microsecond;
+ return (microseconds == 0)
+ ? time
+ // Add just enough milliseconds and microseconds to reach the next second.
+ : time.add(Duration(microseconds: 1000000 - microseconds));
+}
+
+/// Returns 1 second before the [floor] of the specified [DateTime].
+// TODO(jamesderlin): Remove this and use [floor], https://github.com/dart-lang/sdk/issues/42444
+DateTime downstairs([DateTime? time]) => floor(time).subtract(_oneSecond);
+
+/// Successfully matches against a [DateTime] that is the same moment or before
+/// the specified [time].
+Matcher isSameOrBefore(DateTime time) => _IsSameOrBefore(time);
+
+/// Successfully matches against a [DateTime] that is the same moment or after
+/// the specified [time].
+Matcher isSameOrAfter(DateTime time) => _IsSameOrAfter(time);
+
+/// Successfully matches against a [DateTime] that is after the specified
+/// [time].
+Matcher isAfter(DateTime time) => _IsAfter(time);
+
+abstract class _CompareDateTime extends Matcher {
+ const _CompareDateTime(this._time, this._matcher);
+
+ final DateTime _time;
+ final Matcher _matcher;
+
+ @override
+ bool matches(dynamic item, Map<dynamic, dynamic> matchState) {
+ return item is DateTime &&
+ _matcher.matches(item.compareTo(_time), <dynamic, dynamic>{});
+ }
+
+ @protected
+ String get descriptionOperator;
+
+ @override
+ Description describe(Description description) =>
+ description.add('a DateTime $descriptionOperator $_time');
+
+ @protected
+ String get mismatchAdjective;
+
+ @override
+ Description describeMismatch(
+ dynamic item,
+ Description description,
+ Map<dynamic, dynamic> matchState,
+ bool verbose,
+ ) {
+ if (item is DateTime) {
+ Duration diff = item.difference(_time).abs();
+ return description.add('is $mismatchAdjective $_time by $diff');
+ } else {
+ return description.add('is not a DateTime');
+ }
+ }
+}
+
+class _IsSameOrBefore extends _CompareDateTime {
+ const _IsSameOrBefore(DateTime time) : super(time, isNonPositive);
+
+ @override
+ String get descriptionOperator => '<=';
+
+ @override
+ String get mismatchAdjective => 'after';
+}
+
+class _IsSameOrAfter extends _CompareDateTime {
+ const _IsSameOrAfter(DateTime time) : super(time, isNonNegative);
+
+ @override
+ String get descriptionOperator => '>=';
+
+ @override
+ String get mismatchAdjective => 'before';
+}
+
+class _IsAfter extends _CompareDateTime {
+ const _IsAfter(DateTime time) : super(time, isPositive);
+
+ @override
+ String get descriptionOperator => '>';
+
+ @override
+ String get mismatchAdjective => 'before';
+}
diff --git a/pkgs/file/test/utils_test.dart b/pkgs/file/test/utils_test.dart
new file mode 100644
index 0000000..75293bf
--- /dev/null
+++ b/pkgs/file/test/utils_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test/test.dart';
+
+import 'utils.dart';
+
+void main() {
+ test('floorAndCeilProduceExactSecondDateTime', () {
+ DateTime time = DateTime.fromMicrosecondsSinceEpoch(1001);
+ DateTime lower = floor(time);
+ DateTime upper = ceil(time);
+ expect(lower.millisecond, 0);
+ expect(upper.millisecond, 0);
+ expect(lower.microsecond, 0);
+ expect(upper.microsecond, 0);
+ });
+
+ test('floorAndCeilWorkWithNow', () {
+ DateTime time = DateTime.now();
+ int lower = time.difference(floor(time)).inMicroseconds;
+ int upper = ceil(time).difference(time).inMicroseconds;
+ expect(lower, lessThan(1000000));
+ expect(upper, lessThanOrEqualTo(1000000));
+ });
+
+ test('floorAndCeilWorkWithExactSecondDateTime', () {
+ DateTime time = DateTime.parse('1999-12-31 23:59:59');
+ DateTime lower = floor(time);
+ DateTime upper = ceil(time);
+ expect(lower, time);
+ expect(upper, time);
+ });
+
+ test('floorAndCeilWorkWithInexactSecondDateTime', () {
+ DateTime time = DateTime.parse('1999-12-31 23:59:59.500');
+ DateTime lower = floor(time);
+ DateTime upper = ceil(time);
+ Duration difference = upper.difference(lower);
+ expect(difference.inMicroseconds, 1000000);
+ });
+}
diff --git a/pkgs/file_testing/.gitignore b/pkgs/file_testing/.gitignore
new file mode 100644
index 0000000..ddfdca1
--- /dev/null
+++ b/pkgs/file_testing/.gitignore
@@ -0,0 +1,5 @@
+.dart_tool/
+.packages
+.pub/
+build/
+pubspec.lock
diff --git a/pkgs/file_testing/CHANGELOG.md b/pkgs/file_testing/CHANGELOG.md
new file mode 100644
index 0000000..0af779d
--- /dev/null
+++ b/pkgs/file_testing/CHANGELOG.md
@@ -0,0 +1,44 @@
+## 3.0.2
+
+* Require Dart 3.1.
+
+## 3.0.1
+
+* Update the pubspec repository field to reflect the new package repository.
+* Require Dart 3.0.
+
+## 3.0.0
+
+* Migrate to null safety.
+
+## 2.2.0
+
+* Change dependency on `package:test_api` back to `package:test`.
+
+## 2.1.0
+
+* Changed dependency on `package:test` to `package:test_api`
+* Bumped Dart SDK constraint to match `package:test_api`'s requirements
+* Updated style to match latest lint rules from Flutter repo.
+
+## 2.0.3
+
+* Relaxed constraints on `package:test`
+
+## 2.0.2
+
+* Bumped dependency on `package:test` to version 1.0
+
+## 2.0.1
+
+* Bumped Dart SDK constraint to allow for Dart 2 stable
+
+## 2.0.0
+
+* Removed `record_replay_matchers.dart` from API
+
+## 1.0.0
+
+* Moved `package:file/testing.dart` library into a dedicated package so that
+ libraries don't need to take on a transitive dependency on `package:test`
+ in order to use `package:file`.
diff --git a/pkgs/file_testing/LICENSE b/pkgs/file_testing/LICENSE
new file mode 100644
index 0000000..076334f
--- /dev/null
+++ b/pkgs/file_testing/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2017, the Dart project authors. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of Google Inc. nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/pkgs/file_testing/README.md b/pkgs/file_testing/README.md
new file mode 100644
index 0000000..7dda57e
--- /dev/null
+++ b/pkgs/file_testing/README.md
@@ -0,0 +1,39 @@
+[](https://pub.dev/packages/file_testing)
+[](https://pub.dev/packages/file_testing/publisher)
+
+Testing utilities intended to work with `package:file`.
+
+## Features
+
+This package provides a series of matchers to be used in tests that work with file
+system types.
+
+## Usage
+
+```dart
+import 'package:file/file.dart';
+import 'package:file/memory.dart';
+import 'package:file_testing/file_testing.dart';
+import 'package:test/test.dart';
+
+void main() {
+ MemoryFileSystem fs;
+
+ setUp(() {
+ fs = MemoryFileSystem();
+ fs.file('/foo').createSync();
+ });
+
+ test('some test', () {
+ expectFileSystemException(
+ ErrorCodes.ENOENT,
+ () {
+ fs.directory('').resolveSymbolicLinksSync();
+ },
+ );
+ expect(fs.file('/path/to/file'), isFile);
+ expect(fs.file('/path/to/directory'), isDirectory);
+ expect(fs.file('/foo'), exists);
+ });
+}
+```
diff --git a/pkgs/file_testing/analysis_options.yaml b/pkgs/file_testing/analysis_options.yaml
new file mode 100644
index 0000000..8fbd2e4
--- /dev/null
+++ b/pkgs/file_testing/analysis_options.yaml
@@ -0,0 +1,6 @@
+include: package:lints/recommended.yaml
+
+analyzer:
+ errors:
+ # Allow having TODOs in the code
+ todo: ignore
diff --git a/pkgs/file_testing/lib/file_testing.dart b/pkgs/file_testing/lib/file_testing.dart
new file mode 100644
index 0000000..2ac2d0a
--- /dev/null
+++ b/pkgs/file_testing/lib/file_testing.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Matchers (from `package:test`) for use in tests that deal with file systems.
+library;
+
+export 'src/testing/core_matchers.dart';
diff --git a/pkgs/file_testing/lib/src/testing/core_matchers.dart b/pkgs/file_testing/lib/src/testing/core_matchers.dart
new file mode 100644
index 0000000..f58539f
--- /dev/null
+++ b/pkgs/file_testing/lib/src/testing/core_matchers.dart
@@ -0,0 +1,155 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:test/test.dart';
+
+import 'internal.dart';
+
+/// Matcher that successfully matches against any instance of [Directory].
+const Matcher isDirectory = TypeMatcher<Directory>();
+
+/// Matcher that successfully matches against any instance of [File].
+const Matcher isFile = TypeMatcher<File>();
+
+/// Matcher that successfully matches against any instance of [Link].
+const Matcher isLink = TypeMatcher<Link>();
+
+/// Matcher that successfully matches against any instance of
+/// [FileSystemEntity].
+const Matcher isFileSystemEntity = TypeMatcher<FileSystemEntity>();
+
+/// Matcher that successfully matches against any instance of [FileStat].
+const Matcher isFileStat = TypeMatcher<FileStat>();
+
+/// Returns a [Matcher] that matches [path] against an entity's path.
+///
+/// [path] may be a String, a predicate function, or a [Matcher]. If it is
+/// a String, it will be wrapped in an equality matcher.
+Matcher hasPath(dynamic path) => _HasPath(path);
+
+/// Returns a [Matcher] that successfully matches against an instance of
+/// [FileSystemException].
+///
+/// If [osErrorCode] is specified, matches will be limited to exceptions whose
+/// `osError.errorCode` also match the specified matcher.
+///
+/// [osErrorCode] may be an `int`, a predicate function, or a [Matcher]. If it
+/// is an `int`, it will be wrapped in an equality matcher.
+Matcher isFileSystemException([dynamic osErrorCode]) =>
+ _FileSystemException(osErrorCode);
+
+/// Returns a matcher that successfully matches against a future or function
+/// that throws a [FileSystemException].
+///
+/// If [osErrorCode] is specified, matches will be limited to exceptions whose
+/// `osError.errorCode` also match the specified matcher.
+///
+/// [osErrorCode] may be an `int`, a predicate function, or a [Matcher]. If it
+/// is an `int`, it will be wrapped in an equality matcher.
+Matcher throwsFileSystemException([dynamic osErrorCode]) =>
+ throwsA(isFileSystemException(osErrorCode));
+
+/// Expects the specified [callback] to throw a [FileSystemException] with the
+/// specified [osErrorCode] (matched against the exception's
+/// `osError.errorCode`).
+///
+/// [osErrorCode] may be an `int`, a predicate function, or a [Matcher]. If it
+/// is an `int`, it will be wrapped in an equality matcher.
+///
+/// See also:
+/// - [ErrorCodes]
+void expectFileSystemException(dynamic osErrorCode, void Function() callback) {
+ expect(callback, throwsFileSystemException(osErrorCode));
+}
+
+/// Matcher that successfully matches against a [FileSystemEntity] that
+/// exists ([FileSystemEntity.existsSync] returns true).
+const Matcher exists = _Exists();
+
+class _FileSystemException extends Matcher {
+ _FileSystemException(dynamic osErrorCode)
+ : _matcher = _wrapMatcher(osErrorCode);
+
+ final Matcher? _matcher;
+
+ static Matcher? _wrapMatcher(dynamic osErrorCode) {
+ if (osErrorCode == null) {
+ return null;
+ }
+ return ignoreOsErrorCodes ? anything : wrapMatcher(osErrorCode);
+ }
+
+ @override
+ bool matches(dynamic item, Map<dynamic, dynamic> matchState) {
+ if (item is FileSystemException) {
+ return _matcher == null ||
+ _matcher!.matches(item.osError?.errorCode, matchState);
+ }
+ return false;
+ }
+
+ @override
+ Description describe(Description desc) {
+ if (_matcher == null) {
+ return desc.add('FileSystemException');
+ } else {
+ desc.add('FileSystemException with osError.errorCode: ');
+ return _matcher!.describe(desc);
+ }
+ }
+}
+
+class _HasPath extends Matcher {
+ _HasPath(dynamic path) : _matcher = wrapMatcher(path);
+
+ final Matcher _matcher;
+
+ @override
+ bool matches(dynamic item, Map<dynamic, dynamic> matchState) =>
+ _matcher.matches(item.path, matchState);
+
+ @override
+ Description describe(Description desc) {
+ desc.add('has path: ');
+ return _matcher.describe(desc);
+ }
+
+ @override
+ Description describeMismatch(
+ dynamic item,
+ Description desc,
+ Map<dynamic, dynamic> matchState,
+ bool verbose,
+ ) {
+ desc.add('has path: \'${item.path}\'').add('\n Which: ');
+ final Description pathDesc = StringDescription();
+ _matcher.describeMismatch(item.path, pathDesc, matchState, verbose);
+ desc.add(pathDesc.toString());
+ return desc;
+ }
+}
+
+class _Exists extends Matcher {
+ const _Exists();
+
+ @override
+ bool matches(dynamic item, Map<dynamic, dynamic> matchState) =>
+ item is FileSystemEntity && item.existsSync();
+
+ @override
+ Description describe(Description description) =>
+ description.add('a file system entity that exists');
+
+ @override
+ Description describeMismatch(
+ dynamic item,
+ Description description,
+ Map<dynamic, dynamic> matchState,
+ bool verbose,
+ ) {
+ return description.add('does not exist');
+ }
+}
diff --git a/pkgs/file_testing/lib/src/testing/internal.dart b/pkgs/file_testing/lib/src/testing/internal.dart
new file mode 100644
index 0000000..8f53a65
--- /dev/null
+++ b/pkgs/file_testing/lib/src/testing/internal.dart
@@ -0,0 +1,6 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// True if we should ignore OS error codes in our matchers.
+bool ignoreOsErrorCodes = false;
diff --git a/pkgs/file_testing/pubspec.yaml b/pkgs/file_testing/pubspec.yaml
new file mode 100644
index 0000000..1dd0396
--- /dev/null
+++ b/pkgs/file_testing/pubspec.yaml
@@ -0,0 +1,13 @@
+name: file_testing
+version: 3.0.2
+description: Testing utilities for package:file.
+repository: https://github.com/dart-lang/tools/tree/main/pkgs/file_testing
+
+environment:
+ sdk: ^3.1.0
+
+dependencies:
+ test: ^1.23.1
+
+dev_dependencies:
+ lints: ^5.0.0
diff --git a/pkgs/graphs/.gitignore b/pkgs/graphs/.gitignore
new file mode 100644
index 0000000..ddfdca1
--- /dev/null
+++ b/pkgs/graphs/.gitignore
@@ -0,0 +1,5 @@
+.dart_tool/
+.packages
+.pub/
+build/
+pubspec.lock
diff --git a/pkgs/graphs/CHANGELOG.md b/pkgs/graphs/CHANGELOG.md
new file mode 100644
index 0000000..7213b5a
--- /dev/null
+++ b/pkgs/graphs/CHANGELOG.md
@@ -0,0 +1,77 @@
+## 2.3.3-wip
+
+- Add an example usage to the README.
+
+## 2.3.2
+
+- Require Dart 3.4
+- Update to the latest version of `package:dart_flutter_team_lints`.
+
+## 2.3.1
+
+- Update package repository after move.
+
+## 2.3.0
+
+- Add a `transitiveClosure` function.
+- Make `stronglyConnectedComponents` and `topologicalSort` iterative rather than
+ recursive to avoid stack overflows on very large graphs.
+- Require Dart 2.18
+
+## 2.2.0
+
+- Add a `secondarySort` parameter to the `topologicalSort()` function which
+ applies an additional lexical sort where that doesn't break the topological
+ sort.
+
+## 2.1.0
+
+- Add a `topologicalSort()` function.
+
+## 2.0.0
+
+- **Breaking**: `crawlAsync` will no longer ignore a node from the graph if the
+ `readNode` callback returns null.
+
+## 1.0.0
+
+- Migrate to null safety.
+- **Breaking**: Paths from `shortestPath[s]` are now returned as iterables to
+ reduce memory consumption of the algorithm to O(n).
+
+## 0.2.0
+
+- **BREAKING** `shortestPath`, `shortestPaths` and `stronglyConnectedComponents`
+ now have one generic parameter and have replaced the `key` parameter with
+ optional params: `{bool equals(T key1, T key2), int hashCode(T key)}`.
+ This follows the pattern used in `dart:collection` classes `HashMap` and
+ `LinkedHashMap`. It improves the usability and performance of the case where
+ the source values are directly usable in a hash data structure.
+
+## 0.1.3+1
+
+- Fixed a bug with non-identity `key` in `shortestPath` and `shortestPaths`.
+
+## 0.1.3
+
+- Added `shortestPath` and `shortestPaths` functions.
+- Use `HashMap` and `HashSet` from `dart:collection` for
+ `stronglyConnectedComponents`. Improves runtime performance.
+
+## 0.1.2+1
+
+- Allow using non-dev Dart 2 SDK.
+
+## 0.1.2
+
+- `crawlAsync` surfaces exceptions while crawling through the result stream
+ rather than as uncaught asynchronous errors.
+
+## 0.1.1
+
+- `crawlAsync` will now ignore nodes that are resolved to `null`.
+
+## 0.1.0
+
+- Initial release with an implementation of `stronglyConnectedComponents` and
+ `crawlAsync`.
diff --git a/pkgs/graphs/LICENSE b/pkgs/graphs/LICENSE
new file mode 100644
index 0000000..03af64a
--- /dev/null
+++ b/pkgs/graphs/LICENSE
@@ -0,0 +1,27 @@
+Copyright 2017, the Dart project authors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of Google LLC nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/pkgs/graphs/README.md b/pkgs/graphs/README.md
new file mode 100644
index 0000000..09512b8
--- /dev/null
+++ b/pkgs/graphs/README.md
@@ -0,0 +1,57 @@
+[](https://github.com/dart-lang/tools/actions/workflows/graphs.yml)
+[](https://pub.dev/packages/graphs)
+[](https://pub.dev/packages/graphs/publisher)
+
+Graph algorithms that do not specify a particular approach for representing a
+Graph.
+
+Each algorithm is a top level function which takes callback arguments that
+provide the mechanism for traversing the graph. For example, two common
+approaches for representing a graph:
+
+```dart
+class AdjacencyListGraph<T> {
+ Map<T, List<T>> nodes;
+ // ...
+}
+```
+
+```dart
+class TreeGraph<T> {
+ Node<T> root;
+ // ...
+}
+class Node<T> {
+ List<Node<T>> edges;
+ T value;
+}
+```
+
+Any representation can be adapted to the callback arguments.
+
+- Algorithms which need to traverse the graph take an `edges` callback which
+ provides the immediate neighbors of a given node.
+- Algorithms which need to associate unique data with each node in the graph
+ allow passing `equals` and/or `hashCode` callbacks if the unique data type
+ does not correctly or efficiently implement `operator==` or `get hashCode`.
+
+
+Algorithms that support graphs which are resolved asynchronously will have
+similar callbacks which return `FutureOr`.
+
+```dart
+import 'package:graphs/graphs.dart';
+
+void sendMessage() {
+ final network = AdjacencyListGraph();
+ // ...
+ final route = shortestPath(
+ sender, receiver, (node) => network.nodes[node] ?? const []);
+}
+
+void resolveBuildOrder() {
+ final dependencies = TreeGraph();
+ // ...
+ final buildOrder = topologicalSort([dependencies.root], (node) => node.edges);
+}
+```
diff --git a/pkgs/graphs/analysis_options.yaml b/pkgs/graphs/analysis_options.yaml
new file mode 100644
index 0000000..19437b4
--- /dev/null
+++ b/pkgs/graphs/analysis_options.yaml
@@ -0,0 +1,36 @@
+# https://dart.dev/guides/language/analysis-options
+include: package:dart_flutter_team_lints/analysis_options.yaml
+
+analyzer:
+ language:
+ strict-raw-types: true
+ errors:
+ sort_pub_dependencies: ignore
+ # https://github.com/dart-lang/sdk/issues/56465
+ unintended_html_in_doc_comment: ignore
+
+linter:
+ rules:
+ - avoid_bool_literals_in_conditional_expressions
+ - avoid_classes_with_only_static_members
+ - avoid_private_typedef_functions
+ - avoid_redundant_argument_values
+ - avoid_returning_this
+ - avoid_unused_constructor_parameters
+ - avoid_void_async
+ - cancel_subscriptions
+ - join_return_with_assignment
+ - literal_only_boolean_expressions
+ - missing_whitespace_between_adjacent_strings
+ - no_adjacent_strings_in_list
+ - no_runtimeType_toString
+ - package_api_docs
+ - prefer_const_declarations
+ - prefer_expression_function_bodies
+ - prefer_final_locals
+ - require_trailing_commas
+ - unnecessary_await_in_return
+ - unnecessary_raw_strings
+ - use_if_null_to_convert_nulls_to_bools
+ - use_raw_strings
+ - use_string_buffers
diff --git a/pkgs/graphs/benchmark/connected_components_benchmark.dart b/pkgs/graphs/benchmark/connected_components_benchmark.dart
new file mode 100644
index 0000000..1f71879
--- /dev/null
+++ b/pkgs/graphs/benchmark/connected_components_benchmark.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:collection';
+import 'dart:math' show Random;
+
+import 'package:graphs/graphs.dart';
+
+void main() {
+ final rnd = Random(0);
+ const size = 2000;
+ final graph = HashMap<int, List<int>>();
+
+ for (var i = 0; i < size * 3; i++) {
+ final toList = graph.putIfAbsent(rnd.nextInt(size), () => <int>[]);
+
+ final toValue = rnd.nextInt(size);
+ if (!toList.contains(toValue)) {
+ toList.add(toValue);
+ }
+ }
+
+ var maxCount = 0;
+ var maxIteration = 0;
+
+ const duration = Duration(milliseconds: 100);
+
+ for (var i = 1;; i++) {
+ var count = 0;
+ final watch = Stopwatch()..start();
+ while (watch.elapsed < duration) {
+ count++;
+ final length =
+ stronglyConnectedComponents(graph.keys, (e) => graph[e] ?? <Never>[])
+ .length;
+ assert(length == 244, '$length');
+ }
+
+ if (count > maxCount) {
+ maxCount = count;
+ maxIteration = i;
+ }
+
+ if (maxIteration == i || (i - maxIteration) % 20 == 0) {
+ print('max iterations in ${duration.inMilliseconds}ms: $maxCount\t'
+ 'after $maxIteration of $i iterations');
+ }
+ }
+}
diff --git a/pkgs/graphs/benchmark/shortest_path_benchmark.dart b/pkgs/graphs/benchmark/shortest_path_benchmark.dart
new file mode 100644
index 0000000..67e7367
--- /dev/null
+++ b/pkgs/graphs/benchmark/shortest_path_benchmark.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:collection';
+import 'dart:math' show Random;
+
+import 'package:graphs/graphs.dart';
+
+void main() {
+ final rnd = Random(1);
+ const size = 1000;
+ final graph = HashMap<int, List<int>>();
+
+ for (var i = 0; i < size * 5; i++) {
+ final toList = graph.putIfAbsent(rnd.nextInt(size), () => <int>[]);
+
+ final toValue = rnd.nextInt(size);
+ if (!toList.contains(toValue)) {
+ toList.add(toValue);
+ }
+ }
+
+ int? minTicks;
+ var maxIteration = 0;
+
+ final testOutput =
+ shortestPath(0, size - 1, (e) => graph[e] ?? <Never>[]).toString();
+ print(testOutput);
+ assert(testOutput == '(258, 252, 819, 999)', testOutput);
+
+ final watch = Stopwatch();
+ for (var i = 1;; i++) {
+ watch
+ ..reset()
+ ..start();
+ final result = shortestPath(0, size - 1, (e) => graph[e] ?? <Never>[])!;
+ final length = result.length;
+ final first = result.first;
+ watch.stop();
+ assert(length == 4, '$length');
+ assert(first == 258, '$first');
+
+ if (minTicks == null || watch.elapsedTicks < minTicks) {
+ minTicks = watch.elapsedTicks;
+ maxIteration = i;
+ }
+
+ if (maxIteration == i || (i - maxIteration) % 100000 == 0) {
+ print('min ticks for one run: $minTicks\t'
+ 'after $maxIteration of $i iterations');
+ }
+ }
+}
diff --git a/pkgs/graphs/benchmark/shortest_path_worst_case_benchmark.dart b/pkgs/graphs/benchmark/shortest_path_worst_case_benchmark.dart
new file mode 100644
index 0000000..d3117ac
--- /dev/null
+++ b/pkgs/graphs/benchmark/shortest_path_worst_case_benchmark.dart
@@ -0,0 +1,58 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:collection';
+
+import 'package:graphs/graphs.dart';
+
+void main() {
+ const size = 1000;
+ final graph = HashMap<int, List<int>>();
+
+ // We create a graph where every subsequent node has an edge to every other
+ // node before it as well as the next node. This triggers worst case behavior
+ // in many algorithms as it requires visiting all nodes and edges before
+ // finding a solution, and there are a maximum number of edges.
+ for (var i = 0; i < size; i++) {
+ final toList = graph.putIfAbsent(i, () => <int>[]);
+ for (var t = 0; t < i + 2 && i < size; t++) {
+ if (i == t) continue;
+ toList.add(t);
+ }
+ }
+
+ int? minTicks;
+ var maxIteration = 0;
+
+ final testOutput =
+ shortestPath(0, size - 1, (e) => graph[e] ?? <Never>[]).toString();
+ print(testOutput);
+ assert(
+ testOutput == Iterable.generate(size - 1, (i) => i + 1).toString(),
+ testOutput,
+ );
+
+ final watch = Stopwatch();
+ for (var i = 1;; i++) {
+ watch
+ ..reset()
+ ..start();
+ final result = shortestPath(0, size - 1, (e) => graph[e] ?? <Never>[])!;
+ final length = result.length;
+ final first = result.first;
+ watch.stop();
+ assert(length == 999, '$length');
+ assert(first == 1, '$first');
+
+ if (minTicks == null || watch.elapsedTicks < minTicks) {
+ minTicks = watch.elapsedTicks;
+ maxIteration = i;
+ }
+
+ if (maxIteration == i || (i - maxIteration) % 100000 == 0) {
+ print('min ticks for one run: $minTicks\t'
+ 'after $maxIteration of $i iterations');
+ }
+ }
+}
diff --git a/pkgs/graphs/example/crawl_async_example.dart b/pkgs/graphs/example/crawl_async_example.dart
new file mode 100644
index 0000000..bd305c9
--- /dev/null
+++ b/pkgs/graphs/example/crawl_async_example.dart
@@ -0,0 +1,84 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:isolate';
+
+import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:graphs/graphs.dart';
+import 'package:path/path.dart' as p;
+import 'package:pool/pool.dart';
+
+/// Print a transitive set of imported URIs where libraries are read
+/// asynchronously.
+Future<void> main() async {
+ // Limits calls to [findImports].
+ final pool = Pool(10);
+ final allImports = await crawlAsync<Uri, Source>(
+ [Uri.parse('package:graphs/graphs.dart')],
+ read,
+ (from, source) => pool.withResource(() => findImports(from, source)),
+ ).toList();
+ print(allImports.map((s) => s.uri).toList());
+}
+
+AnalysisContextCollection? _analysisContextCollection;
+
+Future<AnalysisContextCollection> get analysisContextCollection async {
+ var collection = _analysisContextCollection;
+ if (collection == null) {
+ final libUri = Uri.parse('package:graphs/');
+ final libPath = await pathForUri(libUri);
+ final packagePath = p.dirname(libPath);
+
+ collection = _analysisContextCollection = AnalysisContextCollection(
+ includedPaths: [packagePath],
+ );
+ }
+
+ return collection;
+}
+
+Future<Iterable<Uri>> findImports(Uri from, Source source) async =>
+ source.unit.directives
+ .whereType<UriBasedDirective>()
+ .map((d) => d.uri.stringValue!)
+ .where((uri) => !uri.startsWith('dart:'))
+ .map((import) => resolveImport(import, from));
+
+Future<CompilationUnit> parseUri(Uri uri) async {
+ final path = await pathForUri(uri);
+ final analysisContext = (await analysisContextCollection).contexts.single;
+ final analysisSession = analysisContext.currentSession;
+ final parseResult = analysisSession.getParsedUnit(path);
+ return (parseResult as ParsedUnitResult).unit;
+}
+
+Future<String> pathForUri(Uri uri) async {
+ final fileUri = await Isolate.resolvePackageUri(uri);
+ if (fileUri == null || !fileUri.isScheme('file')) {
+ throw StateError('Expected to resolve $uri to a file URI, got $fileUri');
+ }
+ return p.fromUri(fileUri);
+}
+
+Future<Source> read(Uri uri) async => Source(uri, await parseUri(uri));
+
+Uri resolveImport(String import, Uri from) {
+ if (import.startsWith('package:')) return Uri.parse(import);
+ assert(from.scheme == 'package');
+ final package = from.pathSegments.first;
+ final fromPath = p.joinAll(from.pathSegments.skip(1));
+ final path = p.normalize(p.join(p.dirname(fromPath), import));
+ return Uri.parse('package:${p.join(package, path)}');
+}
+
+class Source {
+ final Uri uri;
+ final CompilationUnit unit;
+
+ Source(this.uri, this.unit);
+}
diff --git a/pkgs/graphs/example/example.dart b/pkgs/graphs/example/example.dart
new file mode 100644
index 0000000..c9cf6dd
--- /dev/null
+++ b/pkgs/graphs/example/example.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:graphs/graphs.dart';
+
+/// A representation of a directed graph.
+///
+/// Data is stored on the [Node] class.
+class Graph {
+ final Map<Node, List<Node>> nodes;
+
+ Graph(this.nodes);
+}
+
+class Node {
+ final String id;
+ final int data;
+
+ Node(this.id, this.data);
+
+ @override
+ bool operator ==(Object other) => other is Node && other.id == id;
+
+ @override
+ int get hashCode => id.hashCode;
+
+ @override
+ String toString() => '<$id -> $data>';
+}
+
+void main() {
+ final nodeA = Node('A', 1);
+ final nodeB = Node('B', 2);
+ final nodeC = Node('C', 3);
+ final nodeD = Node('D', 4);
+ final graph = Graph({
+ nodeA: [nodeB, nodeC],
+ nodeB: [nodeC, nodeD],
+ nodeC: [nodeB, nodeD],
+ });
+
+ final components = stronglyConnectedComponents<Node>(
+ graph.nodes.keys,
+ (node) => graph.nodes[node] ?? [],
+ );
+
+ print(components);
+}
diff --git a/pkgs/graphs/lib/graphs.dart b/pkgs/graphs/lib/graphs.dart
new file mode 100644
index 0000000..f10b2e4
--- /dev/null
+++ b/pkgs/graphs/lib/graphs.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+export 'src/crawl_async.dart' show crawlAsync;
+export 'src/cycle_exception.dart' show CycleException;
+export 'src/shortest_path.dart' show shortestPath, shortestPaths;
+export 'src/strongly_connected_components.dart'
+ show stronglyConnectedComponents;
+export 'src/topological_sort.dart' show topologicalSort;
+export 'src/transitive_closure.dart' show transitiveClosure;
diff --git a/pkgs/graphs/lib/src/crawl_async.dart b/pkgs/graphs/lib/src/crawl_async.dart
new file mode 100644
index 0000000..68c0a5b
--- /dev/null
+++ b/pkgs/graphs/lib/src/crawl_async.dart
@@ -0,0 +1,85 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:collection';
+
+final _empty = Future<void>.value();
+
+/// Finds and returns every node in a graph who's nodes and edges are
+/// asynchronously resolved.
+///
+/// Cycles are allowed. If this is an undirected graph the [edges] function
+/// may be symmetric. In this case the [roots] may be any node in each connected
+/// graph.
+///
+/// [V] is the type of values in the graph nodes. [K] must be a type suitable
+/// for using as a Map or Set key. [edges] should return the next reachable
+/// nodes.
+///
+/// There are no ordering guarantees. This is useful for ensuring some work is
+/// performed at every node in an asynchronous graph, but does not give
+/// guarantees that the work is done in topological order.
+///
+/// If either [readNode] or [edges] throws the error will be forwarded
+/// through the result stream and no further nodes will be crawled, though some
+/// work may have already been started.
+///
+/// Crawling is eager, so calls to [edges] may overlap with other calls that
+/// have not completed. If the [edges] callback needs to be limited or throttled
+/// that must be done by wrapping it before calling [crawlAsync].
+Stream<V> crawlAsync<K extends Object, V>(
+ Iterable<K> roots,
+ FutureOr<V> Function(K) readNode,
+ FutureOr<Iterable<K>> Function(K, V) edges,
+) {
+ final crawl = _CrawlAsync(roots, readNode, edges)..run();
+ return crawl.result.stream;
+}
+
+class _CrawlAsync<K, V> {
+ final result = StreamController<V>();
+
+ final FutureOr<V> Function(K) readNode;
+ final FutureOr<Iterable<K>> Function(K, V) edges;
+ final Iterable<K> roots;
+
+ final _seen = HashSet<K>();
+
+ _CrawlAsync(this.roots, this.readNode, this.edges);
+
+ /// Add all nodes in the graph to [result] and return a Future which fires
+ /// after all nodes have been seen.
+ Future<void> run() async {
+ try {
+ await Future.wait(roots.map(_visit), eagerError: true);
+ await result.close();
+ } catch (e, st) {
+ result.addError(e, st);
+ await result.close();
+ }
+ }
+
+ /// Resolve the node at [key] and output it, then start crawling all of it's
+ /// edges.
+ Future<void> _crawlFrom(K key) async {
+ final value = await readNode(key);
+ if (result.isClosed) return;
+ result.add(value);
+ final next = await edges(key, value);
+ await Future.wait(next.map(_visit), eagerError: true);
+ }
+
+ /// Synchronously record that [key] is being handled then start work on the
+ /// node for [key].
+ ///
+ /// The returned Future will complete only after the work for [key] and all
+ /// transitively reachable nodes has either been finished, or will be finished
+ /// by some other Future in [_seen].
+ Future<void> _visit(K key) {
+ if (_seen.contains(key)) return _empty;
+ _seen.add(key);
+ return _crawlFrom(key);
+ }
+}
diff --git a/pkgs/graphs/lib/src/cycle_exception.dart b/pkgs/graphs/lib/src/cycle_exception.dart
new file mode 100644
index 0000000..eb9b433
--- /dev/null
+++ b/pkgs/graphs/lib/src/cycle_exception.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2021, 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.
+
+/// An exception indicating that a cycle was detected in a graph that was
+/// expected to be acyclic.
+class CycleException<T> implements Exception {
+ /// The list of nodes comprising the cycle.
+ ///
+ /// Each node in this list has an edge to the next node. The final node has an
+ /// edge to the first node.
+ final List<T> cycle;
+
+ CycleException(Iterable<T> cycle) : cycle = List.unmodifiable(cycle);
+
+ @override
+ String toString() => 'A cycle was detected in a graph that must be acyclic:\n'
+ '${cycle.map((node) => '* $node').join('\n')}';
+}
diff --git a/pkgs/graphs/lib/src/shortest_path.dart b/pkgs/graphs/lib/src/shortest_path.dart
new file mode 100644
index 0000000..28f7e51
--- /dev/null
+++ b/pkgs/graphs/lib/src/shortest_path.dart
@@ -0,0 +1,144 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:collection';
+
+/// Returns the shortest path from [start] to [target] given the directed
+/// edges of a graph provided by [edges].
+///
+/// If [start] `==` [target], an empty [List] is returned and [edges] is never
+/// called.
+///
+/// If [equals] is provided, it is used to compare nodes in the graph. If
+/// [equals] is omitted, the node's own [Object.==] is used instead.
+///
+/// Similarly, if [hashCode] is provided, it is used to produce a hash value
+/// for nodes to efficiently calculate the return value. If it is omitted, the
+/// key's own [Object.hashCode] is used.
+///
+/// If you supply one of [equals] or [hashCode], you should generally also to
+/// supply the other.
+Iterable<T>? shortestPath<T extends Object>(
+ T start,
+ T target,
+ Iterable<T> Function(T) edges, {
+ bool Function(T, T)? equals,
+ int Function(T)? hashCode,
+}) =>
+ _shortestPaths<T>(
+ start,
+ edges,
+ target: target,
+ equals: equals,
+ hashCode: hashCode,
+ )[target];
+
+/// Returns a [Map] of the shortest paths from [start] to all of the nodes in
+/// the directed graph defined by [edges].
+///
+/// All return values will contain the key [start] with an empty [List] value.
+///
+/// [start] and all values returned by [edges] must not be `null`.
+/// If asserts are enabled, an [AssertionError] is raised if these conditions
+/// are not met. If asserts are not enabled, violations result in undefined
+/// behavior.
+///
+/// If [equals] is provided, it is used to compare nodes in the graph. If
+/// [equals] is omitted, the node's own [Object.==] is used instead.
+///
+/// Similarly, if [hashCode] is provided, it is used to produce a hash value
+/// for nodes to efficiently calculate the return value. If it is omitted, the
+/// key's own [Object.hashCode] is used.
+///
+/// If you supply one of [equals] or [hashCode], you should generally also to
+/// supply the other.
+Map<T, Iterable<T>> shortestPaths<T extends Object>(
+ T start,
+ Iterable<T> Function(T) edges, {
+ bool Function(T, T)? equals,
+ int Function(T)? hashCode,
+}) =>
+ _shortestPaths<T>(
+ start,
+ edges,
+ equals: equals,
+ hashCode: hashCode,
+ );
+
+Map<T, Iterable<T>> _shortestPaths<T extends Object>(
+ T start,
+ Iterable<T> Function(T) edges, {
+ T? target,
+ bool Function(T, T)? equals,
+ int Function(T)? hashCode,
+}) {
+ final distances = HashMap<T, _Tail<T>>(equals: equals, hashCode: hashCode);
+ distances[start] = _Tail<T>();
+
+ final nonNullEquals = equals ??= _defaultEquals;
+ final isTarget =
+ target == null ? _neverTarget : (T node) => nonNullEquals(node, target);
+ if (isTarget(start)) {
+ return distances;
+ }
+
+ final toVisit = ListQueue<T>()..add(start);
+
+ while (toVisit.isNotEmpty) {
+ final current = toVisit.removeFirst();
+ final currentPath = distances[current]!;
+
+ for (var edge in edges(current)) {
+ final existingPath = distances[edge];
+
+ if (existingPath == null) {
+ distances[edge] = currentPath.append(edge);
+ if (isTarget(edge)) {
+ return distances;
+ }
+ toVisit.add(edge);
+ }
+ }
+ }
+
+ return distances;
+}
+
+bool _defaultEquals(Object a, Object b) => a == b;
+bool _neverTarget(Object _) => false;
+
+/// An immutable iterable that can efficiently return a copy with a value
+/// appended.
+///
+/// This implementation has an efficient [length] property.
+///
+/// Note that grabbing an [iterator] for the first time is O(n) in time and
+/// space because it copies all the values to a new list and uses that
+/// iterator in order to avoid stack overflows for large paths. This copy is
+/// cached for subsequent calls.
+class _Tail<T extends Object> extends Iterable<T> {
+ final T? tail;
+ final _Tail<T>? head;
+ @override
+ final int length;
+ _Tail()
+ : tail = null,
+ head = null,
+ length = 0;
+ _Tail._(this.tail, this.head, this.length);
+ _Tail<T> append(T value) => _Tail._(value, this, length + 1);
+
+ @override
+ Iterator<T> get iterator => _asIterable.iterator;
+
+ late final _asIterable = () {
+ _Tail<T>? next = this;
+ final reversed = List.generate(length, (_) {
+ final val = next!.tail;
+ next = next!.head;
+ return val as T;
+ });
+ return reversed.reversed;
+ }();
+}
diff --git a/pkgs/graphs/lib/src/strongly_connected_components.dart b/pkgs/graphs/lib/src/strongly_connected_components.dart
new file mode 100644
index 0000000..e8a775c
--- /dev/null
+++ b/pkgs/graphs/lib/src/strongly_connected_components.dart
@@ -0,0 +1,117 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:collection';
+import 'dart:math' show min;
+
+/// Finds the strongly connected components of a directed graph using Tarjan's
+/// algorithm.
+///
+/// The result will be a valid reverse topological order ordering of the
+/// strongly connected components. Components further from a root will appear in
+/// the result before the components which they are connected to.
+///
+/// Nodes within a strongly connected component have no ordering guarantees,
+/// except that if the first value in [nodes] is a valid root, and is contained
+/// in a cycle, it will be the last element of that cycle.
+///
+/// [nodes] must contain at least a root of every tree in the graph if there are
+/// disjoint subgraphs but it may contain all nodes in the graph if the roots
+/// are not known.
+///
+/// If [equals] is provided, it is used to compare nodes in the graph. If
+/// [equals] is omitted, the node's own [Object.==] is used instead.
+///
+/// Similarly, if [hashCode] is provided, it is used to produce a hash value
+/// for nodes to efficiently calculate the return value. If it is omitted, the
+/// key's own [Object.hashCode] is used.
+///
+/// If you supply one of [equals] or [hashCode], you should generally also to
+/// supply the other.
+List<List<T>> stronglyConnectedComponents<T extends Object>(
+ Iterable<T> nodes,
+ Iterable<T> Function(T) edges, {
+ bool Function(T, T)? equals,
+ int Function(T)? hashCode,
+}) {
+ final result = <List<T>>[];
+ final lowLinks = HashMap<T, int>(equals: equals, hashCode: hashCode);
+ final indexes = HashMap<T, int>(equals: equals, hashCode: hashCode);
+ final onStack = HashSet<T>(equals: equals, hashCode: hashCode);
+
+ final nonNullEquals = equals ?? _defaultEquals;
+
+ var index = 0;
+ final lastVisited = Queue<T>();
+
+ final stack = [for (final node in nodes) _StackState(node)];
+ outer:
+ while (stack.isNotEmpty) {
+ final state = stack.removeLast();
+ final node = state.node;
+ var iterator = state.iterator;
+
+ int lowLink;
+ if (iterator == null) {
+ if (indexes.containsKey(node)) continue;
+ indexes[node] = index;
+ lowLink = lowLinks[node] = index;
+ index++;
+ iterator = edges(node).iterator;
+
+ // Nodes with no edges are always in their own component.
+ if (!iterator.moveNext()) {
+ result.add([node]);
+ continue;
+ }
+
+ lastVisited.addLast(node);
+ onStack.add(node);
+ } else {
+ lowLink = min(lowLinks[node]!, lowLinks[iterator.current]!);
+ }
+
+ do {
+ final next = iterator.current;
+ if (!indexes.containsKey(next)) {
+ stack.add(_StackState(node, iterator));
+ stack.add(_StackState(next));
+ continue outer;
+ } else if (onStack.contains(next)) {
+ lowLink = lowLinks[node] = min(lowLink, indexes[next]!);
+ }
+ } while (iterator.moveNext());
+
+ if (lowLink == indexes[node]) {
+ final component = <T>[];
+ T next;
+ do {
+ next = lastVisited.removeLast();
+ onStack.remove(next);
+ component.add(next);
+ } while (!nonNullEquals(next, node));
+ result.add(component);
+ }
+ }
+
+ return result;
+}
+
+/// The state of a pass on a single node in Tarjan's Algorithm.
+///
+/// This is used to perform the algorithm with an explicit stack rather than
+/// recursively, to avoid stack overflow errors for very large graphs.
+class _StackState<T> {
+ /// The node being inspected.
+ final T node;
+
+ /// The iterator traversing [node]'s edges.
+ ///
+ /// This is null if the node hasn't yet begun being traversed.
+ final Iterator<T>? iterator;
+
+ _StackState(this.node, [this.iterator]);
+}
+
+bool _defaultEquals(Object a, Object b) => a == b;
diff --git a/pkgs/graphs/lib/src/topological_sort.dart b/pkgs/graphs/lib/src/topological_sort.dart
new file mode 100644
index 0000000..948e696
--- /dev/null
+++ b/pkgs/graphs/lib/src/topological_sort.dart
@@ -0,0 +1,146 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:collection';
+
+import 'package:collection/collection.dart' hide stronglyConnectedComponents;
+
+import 'cycle_exception.dart';
+
+/// Returns a topological sort of the nodes of the directed edges of a graph
+/// provided by [nodes] and [edges].
+///
+/// Each element of the returned iterable is guaranteed to appear after all
+/// nodes that have edges leading to that node. The result is not guaranteed to
+/// be unique, nor is it guaranteed to be stable across releases of this
+/// package; however, it will be stable for a given input within a given package
+/// version.
+///
+/// If [equals] is provided, it is used to compare nodes in the graph. If
+/// [equals] is omitted, the node's own [Object.==] is used instead.
+///
+/// Similarly, if [hashCode] is provided, it is used to produce a hash value
+/// for nodes to efficiently calculate the return value. If it is omitted, the
+/// key's own [Object.hashCode] is used.
+///
+/// If you supply one of [equals] or [hashCode], you should generally also to
+/// supply the other.
+///
+/// If you supply [secondarySort], the resulting list will be sorted by that
+/// comparison function as much as possible without violating the topological
+/// ordering. Note that even with a secondary sort, the result is _still_ not
+/// guaranteed to be unique or stable across releases of this package.
+///
+/// Note: this requires that [nodes] and each iterable returned by [edges]
+/// contain no duplicate entries.
+///
+/// Throws a [CycleException<T>] if the graph is cyclical.
+List<T> topologicalSort<T>(
+ Iterable<T> nodes,
+ Iterable<T> Function(T) edges, {
+ bool Function(T, T)? equals,
+ int Function(T)? hashCode,
+ Comparator<T>? secondarySort,
+}) {
+ if (secondarySort != null) {
+ return _topologicalSortWithSecondary(
+ [...nodes],
+ edges,
+ secondarySort,
+ equals,
+ hashCode,
+ );
+ }
+
+ // https://en.wikipedia.org/wiki/Topological_sorting#Depth-first_search
+ final result = QueueList<T>();
+ final permanentMark = HashSet<T>(equals: equals, hashCode: hashCode);
+ final temporaryMark = LinkedHashSet<T>(equals: equals, hashCode: hashCode);
+ final stack = [...nodes];
+ while (stack.isNotEmpty) {
+ final node = stack.removeLast();
+ if (permanentMark.contains(node)) continue;
+
+ // If we're visiting this node while it's already marked and not through a
+ // dependency, that must mean we've traversed all its dependencies and it's
+ // safe to add it to the result.
+ if (temporaryMark.contains(node)) {
+ temporaryMark.remove(node);
+ permanentMark.add(node);
+ result.addFirst(node);
+ } else {
+ temporaryMark.add(node);
+
+ // Revisit this node once we've visited all its children.
+ stack.add(node);
+ for (var child in edges(node)) {
+ if (temporaryMark.contains(child)) throw CycleException(temporaryMark);
+ stack.add(child);
+ }
+ }
+ }
+
+ return result;
+}
+
+/// An implementation of [topologicalSort] with a secondary comparison function.
+List<T> _topologicalSortWithSecondary<T>(
+ List<T> nodes,
+ Iterable<T> Function(T) edges,
+ Comparator<T> comparator,
+ bool Function(T, T)? equals,
+ int Function(T)? hashCode,
+) {
+ // https://en.wikipedia.org/wiki/Topological_sorting#Kahn's_algorithm,
+ // modified to sort the nodes to traverse. Also documented in
+ // https://www.algotree.org/algorithms/tree_graph_traversal/lexical_topological_sort_c++/
+
+ // For each node, the number of incoming edges it has that we haven't yet
+ // traversed.
+ final incomingEdges = HashMap<T, int>(equals: equals, hashCode: hashCode);
+ for (var node in nodes) {
+ for (var child in edges(node)) {
+ incomingEdges[child] = (incomingEdges[child] ?? 0) + 1;
+ }
+ }
+
+ // A priority queue of nodes that have no remaining incoming edges.
+ final nodesToTraverse = PriorityQueue<T>(comparator);
+ for (var node in nodes) {
+ if (!incomingEdges.containsKey(node)) nodesToTraverse.add(node);
+ }
+
+ final result = <T>[];
+ while (nodesToTraverse.isNotEmpty) {
+ final node = nodesToTraverse.removeFirst();
+ result.add(node);
+ for (var child in edges(node)) {
+ var remainingEdges = incomingEdges[child]!;
+ remainingEdges--;
+ incomingEdges[child] = remainingEdges;
+ if (remainingEdges == 0) nodesToTraverse.add(child);
+ }
+ }
+
+ if (result.length < nodes.length) {
+ // This algorithm doesn't automatically produce a cycle list as a side
+ // effect of sorting, so to throw the appropriate [CycleException] we just
+ // call the normal [topologicalSort] with a view of this graph that only
+ // includes nodes that still have edges.
+ bool nodeIsInCycle(T node) {
+ final edges = incomingEdges[node];
+ return edges != null && edges > 0;
+ }
+
+ topologicalSort<T>(
+ nodes.where(nodeIsInCycle),
+ edges,
+ equals: equals,
+ hashCode: hashCode,
+ );
+ assert(false, 'topologicalSort() should throw if the graph has a cycle');
+ }
+
+ return result;
+}
diff --git a/pkgs/graphs/lib/src/transitive_closure.dart b/pkgs/graphs/lib/src/transitive_closure.dart
new file mode 100644
index 0000000..24791d6
--- /dev/null
+++ b/pkgs/graphs/lib/src/transitive_closure.dart
@@ -0,0 +1,143 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:collection';
+
+import 'cycle_exception.dart';
+import 'strongly_connected_components.dart';
+import 'topological_sort.dart';
+
+/// Returns a transitive closure of a directed graph provided by [nodes] and
+/// [edges].
+///
+/// The result is a map from [nodes] to the sets of nodes that are transitively
+/// reachable through [edges]. No particular ordering is guaranteed.
+///
+/// If [equals] is provided, it is used to compare nodes in the graph. If
+/// [equals] is omitted, the node's own [Object.==] is used instead.
+///
+/// Similarly, if [hashCode] is provided, it is used to produce a hash value
+/// for nodes to efficiently calculate the return value. If it is omitted, the
+/// key's own [Object.hashCode] is used.
+///
+/// If you supply one of [equals] or [hashCode], you should generally also to
+/// supply the other.
+///
+/// Note: this requires that [nodes] and each iterable returned by [edges]
+/// contain no duplicate entries.
+///
+/// By default, this can handle either cyclic or acyclic graphs. If [acyclic] is
+/// true, this will run more efficiently but throw a [CycleException] if the
+/// graph is cyclical.
+Map<T, Set<T>> transitiveClosure<T extends Object>(
+ Iterable<T> nodes,
+ Iterable<T> Function(T) edges, {
+ bool Function(T, T)? equals,
+ int Function(T)? hashCode,
+ bool acyclic = false,
+}) {
+ if (!acyclic) {
+ return _cyclicTransitiveClosure(
+ nodes,
+ edges,
+ equals: equals,
+ hashCode: hashCode,
+ );
+ }
+
+ final topologicalOrder =
+ topologicalSort(nodes, edges, equals: equals, hashCode: hashCode);
+ final result = LinkedHashMap<T, Set<T>>(equals: equals, hashCode: hashCode);
+ for (final node in topologicalOrder.reversed) {
+ final closure = LinkedHashSet<T>(equals: equals, hashCode: hashCode);
+ for (var child in edges(node)) {
+ closure.add(child);
+ closure.addAll(result[child]!);
+ }
+
+ result[node] = closure;
+ }
+
+ return result;
+}
+
+/// Returns the transitive closure of a cyclic graph using [Purdom's algorithm].
+///
+/// [Purdom's algorithm]: https://algowiki-project.org/en/Purdom%27s_algorithm
+///
+/// This first computes the strongly connected components of the graph and finds
+/// the transitive closure of those before flattening it out into the transitive
+/// closure of the entire graph.
+Map<T, Set<T>> _cyclicTransitiveClosure<T extends Object>(
+ Iterable<T> nodes,
+ Iterable<T> Function(T) edges, {
+ bool Function(T, T)? equals,
+ int Function(T)? hashCode,
+}) {
+ final components = stronglyConnectedComponents<T>(
+ nodes,
+ edges,
+ equals: equals,
+ hashCode: hashCode,
+ );
+ final nodesToComponents =
+ HashMap<T, List<T>>(equals: equals, hashCode: hashCode);
+ for (final component in components) {
+ for (final node in component) {
+ nodesToComponents[node] = component;
+ }
+ }
+
+ // Because [stronglyConnectedComponents] returns the components in reverse
+ // topological order, we can avoid an additional topological sort here.
+ // Instead, we directly traverse the component list with the knowledge that
+ // once we reach a component, everything reachable from it has already been
+ // registered in [result].
+ final result = LinkedHashMap<T, Set<T>>(equals: equals, hashCode: hashCode);
+ for (final component in components) {
+ final closure = LinkedHashSet<T>(equals: equals, hashCode: hashCode);
+ if (_componentIncludesCycle(component, edges, equals)) {
+ closure.addAll(component);
+ }
+
+ // De-duplicate downstream components to avoid adding the same transitive
+ // children over and over.
+ final downstreamComponents = {
+ for (final node in component)
+ for (final child in edges(node)) nodesToComponents[child]!,
+ };
+ for (final childComponent in downstreamComponents) {
+ if (childComponent == component) continue;
+
+ // This if check is just for efficiency. If [childComponent] has multiple
+ // nodes, `result[childComponent.first]` will contain all the nodes in
+ // `childComponent` anyway since it's cyclical.
+ if (childComponent.length == 1) closure.addAll(childComponent);
+ closure.addAll(result[childComponent.first]!);
+ }
+
+ for (final node in component) {
+ result[node] = closure;
+ }
+ }
+ return result;
+}
+
+/// Returns whether the strongly-connected component [component] of a graph
+/// defined by [edges] includes a cycle.
+bool _componentIncludesCycle<T>(
+ List<T> component,
+ Iterable<T> Function(T) edges,
+ bool Function(T, T)? equals,
+) {
+ // A strongly-connected component with more than one node always contains a
+ // cycle, by definition.
+ if (component.length > 1) return true;
+
+ // A component with only a single node only contains a cycle if that node has
+ // an edge to itself.
+ final node = component.single;
+ return edges(node)
+ .any((edge) => equals == null ? edge == node : equals(edge, node));
+}
diff --git a/pkgs/graphs/pubspec.yaml b/pkgs/graphs/pubspec.yaml
new file mode 100644
index 0000000..5b5457a
--- /dev/null
+++ b/pkgs/graphs/pubspec.yaml
@@ -0,0 +1,19 @@
+name: graphs
+version: 2.3.3-wip
+description: Graph algorithms that operate on graphs in any representation.
+repository: https://github.com/dart-lang/tools/tree/main/pkgs/graphs
+
+environment:
+ sdk: ^3.4.0
+
+dependencies:
+ collection: ^1.15.0
+
+dev_dependencies:
+ dart_flutter_team_lints: ^3.0.0
+ test: ^1.21.6
+
+ # For examples
+ analyzer: '>=5.2.0 <7.0.0'
+ path: ^1.8.0
+ pool: ^1.5.0
diff --git a/pkgs/graphs/test/crawl_async_test.dart b/pkgs/graphs/test/crawl_async_test.dart
new file mode 100644
index 0000000..9e168e6
--- /dev/null
+++ b/pkgs/graphs/test/crawl_async_test.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:graphs/graphs.dart';
+import 'package:test/test.dart';
+
+import 'utils/graph.dart';
+
+void main() {
+ group('asyncCrawl', () {
+ Future<List<String?>> crawl(
+ Map<String, List<String>?> g,
+ Iterable<String> roots,
+ ) {
+ final graph = AsyncGraph(g);
+ return crawlAsync(roots, graph.readNode, graph.edges).toList();
+ }
+
+ test('empty result for empty graph', () async {
+ final result = await crawl({}, []);
+ expect(result, isEmpty);
+ });
+
+ test('single item for a single node', () async {
+ final result = await crawl({'a': []}, ['a']);
+ expect(result, ['a']);
+ });
+
+ test('hits every node in a graph', () async {
+ final result = await crawl({
+ 'a': ['b', 'c'],
+ 'b': ['c'],
+ 'c': ['d'],
+ 'd': [],
+ }, [
+ 'a',
+ ]);
+ expect(result, hasLength(4));
+ expect(
+ result,
+ allOf(contains('a'), contains('b'), contains('c'), contains('d')),
+ );
+ });
+
+ test('handles cycles', () async {
+ final result = await crawl({
+ 'a': ['b'],
+ 'b': ['c'],
+ 'c': ['b'],
+ }, [
+ 'a',
+ ]);
+ expect(result, hasLength(3));
+ expect(result, allOf(contains('a'), contains('b'), contains('c')));
+ });
+
+ test('handles self cycles', () async {
+ final result = await crawl({
+ 'a': ['b'],
+ 'b': ['b'],
+ }, [
+ 'a',
+ ]);
+ expect(result, hasLength(2));
+ expect(result, allOf(contains('a'), contains('b')));
+ });
+
+ test('allows null edges', () async {
+ final result = await crawl({
+ 'a': ['b'],
+ 'b': null,
+ }, [
+ 'a',
+ ]);
+ expect(result, hasLength(2));
+ expect(result, allOf(contains('a'), contains('b')));
+ });
+
+ test('allows null nodes', () async {
+ final result = await crawl({
+ 'a': ['b'],
+ }, [
+ 'a',
+ ]);
+ expect(result, ['a', null]);
+ });
+
+ test('surfaces exceptions for crawling edges', () {
+ final graph = {
+ 'a': ['b'],
+ };
+ final nodes = crawlAsync(
+ ['a'],
+ (n) => n,
+ (k, n) => k == 'b' ? throw ArgumentError() : graph[k] ?? <String>[],
+ );
+ expect(nodes, emitsThrough(emitsError(isArgumentError)));
+ });
+
+ test('surfaces exceptions for resolving keys', () {
+ final graph = {
+ 'a': ['b'],
+ };
+ final nodes = crawlAsync(
+ ['a'],
+ (n) => n == 'b' ? throw ArgumentError() : n,
+ (k, n) => graph[k] ?? <Never>[],
+ );
+ expect(nodes, emitsThrough(emitsError(isArgumentError)));
+ });
+ });
+}
diff --git a/pkgs/graphs/test/shortest_path_test.dart b/pkgs/graphs/test/shortest_path_test.dart
new file mode 100644
index 0000000..88281d4
--- /dev/null
+++ b/pkgs/graphs/test/shortest_path_test.dart
@@ -0,0 +1,161 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:collection';
+import 'dart:math' show Random;
+
+import 'package:graphs/graphs.dart';
+import 'package:test/test.dart';
+
+import 'utils/utils.dart';
+
+void main() {
+ const graph = <String, List<String>>{
+ '1': ['2', '5'],
+ '2': ['3'],
+ '3': ['4', '5'],
+ '4': ['1'],
+ '5': ['8'],
+ '6': ['7'],
+ };
+
+ List<String> readEdges(String key) => graph[key] ?? [];
+
+ List<X> getXValues(X key) => graph[key.value]?.map(X.new).toList() ?? [];
+
+ void singlePathTest(String from, String to, List<String>? expected) {
+ test('$from -> $to should be $expected (mapped)', () {
+ expect(
+ shortestPath<X>(
+ X(from),
+ X(to),
+ getXValues,
+ equals: xEquals,
+ hashCode: xHashCode,
+ )?.map((x) => x.value),
+ expected,
+ );
+ });
+
+ test('$from -> $to should be $expected', () {
+ expect(shortestPath(from, to, readEdges), expected);
+ });
+ }
+
+ void pathsTest(
+ String from,
+ Map<String, List<String>> expected,
+ List<String> nullPaths,
+ ) {
+ test('paths from $from (mapped)', () {
+ final result = shortestPaths<X>(
+ X(from),
+ getXValues,
+ equals: xEquals,
+ hashCode: xHashCode,
+ ).map((k, v) => MapEntry(k.value, v.map((x) => x.value).toList()));
+ expect(result, expected);
+ });
+
+ test('paths from $from', () {
+ final result = shortestPaths(from, readEdges);
+ expect(result, expected);
+ });
+
+ for (var entry in expected.entries) {
+ singlePathTest(from, entry.key, entry.value);
+ }
+
+ for (var entry in nullPaths) {
+ singlePathTest(from, entry, null);
+ }
+ }
+
+ pathsTest('1', {
+ '5': ['5'],
+ '3': ['2', '3'],
+ '8': ['5', '8'],
+ '1': [],
+ '2': ['2'],
+ '4': ['2', '3', '4'],
+ }, [
+ '6',
+ '7',
+ ]);
+
+ pathsTest('6', {
+ '7': ['7'],
+ '6': [],
+ }, [
+ '1',
+ ]);
+ pathsTest('7', {'7': []}, ['1', '6']);
+
+ pathsTest('42', {'42': []}, ['1', '6']);
+
+ test('integration test', () {
+ // Be deterministic in the generated graph. This test may have to be updated
+ // if the behavior of `Random` changes for the provided seed.
+ final rnd = Random(1);
+ const size = 1000;
+ final graph = HashMap<int, List<int>>();
+
+ Iterable<int>? resultForGraph() =>
+ shortestPath(0, size - 1, (e) => graph[e] ?? const []);
+
+ void addRandomEdge() {
+ final toList = graph.putIfAbsent(rnd.nextInt(size), () => <int>[]);
+
+ final toValue = rnd.nextInt(size);
+ if (!toList.contains(toValue)) {
+ toList.add(toValue);
+ }
+ }
+
+ Iterable<int>? result;
+
+ // Add edges until there is a shortest path between `0` and `size - 1`
+ do {
+ addRandomEdge();
+ result = resultForGraph();
+ } while (result == null);
+
+ expect(result, [313, 547, 91, 481, 74, 64, 439, 388, 660, 275, 999]);
+
+ var count = 0;
+ // Add edges until the shortest path between `0` and `size - 1` is 2 items
+ // Adding edges should never increase the length of the shortest path.
+ // Adding enough edges should reduce the length of the shortest path.
+ do {
+ expect(++count, lessThan(size * 5), reason: 'This loop should finish.');
+ addRandomEdge();
+ final previousResultLength = result!.length;
+ result = resultForGraph();
+ expect(result, hasLength(lessThanOrEqualTo(previousResultLength)));
+ } while (result!.length > 2);
+
+ expect(result, [275, 999]);
+
+ count = 0;
+ // Remove edges until there is no shortest path.
+ // Removing edges should never reduce the length of the shortest path.
+ // Removing enough edges should increase the length of the shortest path and
+ // eventually eliminate any path.
+ do {
+ expect(++count, lessThan(size * 5), reason: 'This loop should finish.');
+ final randomKey = graph.keys.elementAt(rnd.nextInt(graph.length));
+ final list = graph[randomKey]!;
+ expect(list, isNotEmpty);
+ list.removeAt(rnd.nextInt(list.length));
+ if (list.isEmpty) {
+ graph.remove(randomKey);
+ }
+ final previousResultLength = result!.length;
+ result = resultForGraph();
+ if (result != null) {
+ expect(result, hasLength(greaterThanOrEqualTo(previousResultLength)));
+ }
+ } while (result != null);
+ });
+}
diff --git a/pkgs/graphs/test/strongly_connected_components_test.dart b/pkgs/graphs/test/strongly_connected_components_test.dart
new file mode 100644
index 0000000..2fa4d88
--- /dev/null
+++ b/pkgs/graphs/test/strongly_connected_components_test.dart
@@ -0,0 +1,304 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:graphs/graphs.dart';
+import 'package:test/test.dart';
+
+import 'utils/graph.dart';
+import 'utils/utils.dart';
+
+void main() {
+ group('strongly connected components', () {
+ /// Run [stronglyConnectedComponents] on [g].
+ List<List<String>> components(
+ Map<String, List<String>?> g, {
+ Iterable<String>? startNodes,
+ }) {
+ final graph = Graph(g);
+ return stronglyConnectedComponents(
+ startNodes ?? graph.allNodes,
+ graph.edges,
+ );
+ }
+
+ test('empty result for empty graph', () {
+ final result = components({});
+ expect(result, isEmpty);
+ });
+
+ test('single item for single node', () {
+ final result = components({'a': []});
+ expect(result, [
+ ['a'],
+ ]);
+ });
+
+ test('handles non-cycles', () {
+ final result = components({
+ 'a': ['b'],
+ 'b': ['c'],
+ 'c': [],
+ });
+ expect(result, [
+ ['c'],
+ ['b'],
+ ['a'],
+ ]);
+ });
+
+ test('handles entire graph as cycle', () {
+ final result = components({
+ 'a': ['b'],
+ 'b': ['c'],
+ 'c': ['d'],
+ 'd': ['a'],
+ });
+ expect(
+ result,
+ [allOf(contains('a'), contains('b'), contains('c'), contains('d'))],
+ );
+ });
+
+ test('includes the first passed root last in a cycle', () {
+ // In cases where this is used to find a topological ordering the first
+ // value in nodes should always come last.
+ final graph = {
+ 'a': ['b'],
+ 'b': ['a'],
+ };
+ final resultFromA = components(graph, startNodes: ['a']);
+ final resultFromB = components(graph, startNodes: ['b']);
+ expect(resultFromA.single.last, 'a');
+ expect(resultFromB.single.last, 'b');
+ });
+
+ test('handles cycles in the middle', () {
+ final result = components({
+ 'a': ['b', 'c'],
+ 'b': ['c', 'd'],
+ 'c': ['b', 'd'],
+ 'd': [],
+ });
+ expect(result, [
+ ['d'],
+ allOf(contains('b'), contains('c')),
+ ['a'],
+ ]);
+ });
+
+ test('handles self cycles', () {
+ final result = components({
+ 'a': ['b'],
+ 'b': ['b'],
+ });
+ expect(result, [
+ ['b'],
+ ['a'],
+ ]);
+ });
+
+ test('valid topological ordering for disjoint subgraphs', () {
+ final result = components({
+ 'a': ['b', 'c'],
+ 'b': ['b1', 'b2'],
+ 'c': ['c1', 'c2'],
+ 'b1': [],
+ 'b2': [],
+ 'c1': [],
+ 'c2': [],
+ });
+
+ expect(
+ result,
+ containsAllInOrder([
+ ['c1'],
+ ['c'],
+ ['a'],
+ ]),
+ );
+ expect(
+ result,
+ containsAllInOrder([
+ ['c2'],
+ ['c'],
+ ['a'],
+ ]),
+ );
+ expect(
+ result,
+ containsAllInOrder([
+ ['b1'],
+ ['b'],
+ ['a'],
+ ]),
+ );
+ expect(
+ result,
+ containsAllInOrder([
+ ['b2'],
+ ['b'],
+ ['a'],
+ ]),
+ );
+ });
+
+ test('handles getting null for edges', () {
+ final result = components({
+ 'a': ['b'],
+ 'b': null,
+ });
+ expect(result, [
+ ['b'],
+ ['a'],
+ ]);
+ });
+ });
+
+ group('custom hashCode and equals', () {
+ /// Run [stronglyConnectedComponents] on [g].
+ List<List<String>> components(
+ Map<String, List<String>?> g, {
+ Iterable<String>? startNodes,
+ }) {
+ final graph = BadGraph(g);
+
+ startNodes ??= graph.allNodes.map((n) => n.value);
+
+ return stronglyConnectedComponents<X>(
+ startNodes.map(X.new),
+ graph.edges,
+ equals: xEquals,
+ hashCode: xHashCode,
+ ).map((list) => list.map((x) => x.value).toList()).toList();
+ }
+
+ test('empty result for empty graph', () {
+ final result = components({});
+ expect(result, isEmpty);
+ });
+
+ test('single item for single node', () {
+ final result = components({'a': []});
+ expect(result, [
+ ['a'],
+ ]);
+ });
+
+ test('handles non-cycles', () {
+ final result = components({
+ 'a': ['b'],
+ 'b': ['c'],
+ 'c': [],
+ });
+ expect(result, [
+ ['c'],
+ ['b'],
+ ['a'],
+ ]);
+ });
+
+ test('handles entire graph as cycle', () {
+ final result = components({
+ 'a': ['b'],
+ 'b': ['c'],
+ 'c': ['a'],
+ });
+ expect(result, [allOf(contains('a'), contains('b'), contains('c'))]);
+ });
+
+ test('includes the first passed root last in a cycle', () {
+ // In cases where this is used to find a topological ordering the first
+ // value in nodes should always come last.
+ final graph = {
+ 'a': ['b'],
+ 'b': ['a'],
+ };
+ final resultFromA = components(graph, startNodes: ['a']);
+ final resultFromB = components(graph, startNodes: ['b']);
+ expect(resultFromA.single.last, 'a');
+ expect(resultFromB.single.last, 'b');
+ });
+
+ test('handles cycles in the middle', () {
+ final result = components({
+ 'a': ['b', 'c'],
+ 'b': ['c', 'd'],
+ 'c': ['b', 'd'],
+ 'd': [],
+ });
+ expect(result, [
+ ['d'],
+ allOf(contains('b'), contains('c')),
+ ['a'],
+ ]);
+ });
+
+ test('handles self cycles', () {
+ final result = components({
+ 'a': ['b'],
+ 'b': ['b'],
+ });
+ expect(result, [
+ ['b'],
+ ['a'],
+ ]);
+ });
+
+ test('valid topological ordering for disjoint subgraphs', () {
+ final result = components({
+ 'a': ['b', 'c'],
+ 'b': ['b1', 'b2'],
+ 'c': ['c1', 'c2'],
+ 'b1': [],
+ 'b2': [],
+ 'c1': [],
+ 'c2': [],
+ });
+
+ expect(
+ result,
+ containsAllInOrder([
+ ['c1'],
+ ['c'],
+ ['a'],
+ ]),
+ );
+ expect(
+ result,
+ containsAllInOrder([
+ ['c2'],
+ ['c'],
+ ['a'],
+ ]),
+ );
+ expect(
+ result,
+ containsAllInOrder([
+ ['b1'],
+ ['b'],
+ ['a'],
+ ]),
+ );
+ expect(
+ result,
+ containsAllInOrder([
+ ['b2'],
+ ['b'],
+ ['a'],
+ ]),
+ );
+ });
+
+ test('handles getting null for edges', () {
+ final result = components({
+ 'a': ['b'],
+ 'b': null,
+ });
+ expect(result, [
+ ['b'],
+ ['a'],
+ ]);
+ });
+ });
+}
diff --git a/pkgs/graphs/test/topological_sort_test.dart b/pkgs/graphs/test/topological_sort_test.dart
new file mode 100644
index 0000000..831946b
--- /dev/null
+++ b/pkgs/graphs/test/topological_sort_test.dart
@@ -0,0 +1,362 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:collection';
+
+import 'package:graphs/graphs.dart';
+import 'package:test/test.dart';
+
+import 'utils/utils.dart';
+
+void main() {
+ group('without secondarySort', () {
+ group('topologically sorts a graph', () {
+ test('with no nodes', () {
+ expect(_topologicalSort({}), isEmpty);
+ });
+
+ test('with only one node', () {
+ expect(_topologicalSort({1: []}), equals([1]));
+ });
+
+ test('with no edges', () {
+ expect(
+ _topologicalSort({1: [], 2: [], 3: [], 4: []}),
+ unorderedEquals([1, 2, 3, 4]),
+ );
+ });
+
+ test('with single edges', () {
+ expect(
+ _topologicalSort({
+ 1: [2],
+ 2: [3],
+ 3: [4],
+ 4: [],
+ }),
+ equals([1, 2, 3, 4]),
+ );
+ });
+
+ test('with many edges from one node', () {
+ final result = _topologicalSort({
+ 1: [2, 3, 4],
+ 2: [],
+ 3: [],
+ 4: [],
+ });
+ expect(result.indexOf(1), lessThan(result.indexOf(2)));
+ expect(result.indexOf(1), lessThan(result.indexOf(3)));
+ expect(result.indexOf(1), lessThan(result.indexOf(4)));
+ });
+
+ test('with transitive edges', () {
+ final result = _topologicalSort({
+ 1: [2, 4],
+ 2: [],
+ 3: [],
+ 4: [3],
+ });
+ expect(result.indexOf(1), lessThan(result.indexOf(2)));
+ expect(result.indexOf(1), lessThan(result.indexOf(3)));
+ expect(result.indexOf(1), lessThan(result.indexOf(4)));
+ expect(result.indexOf(4), lessThan(result.indexOf(3)));
+ });
+
+ test('with diamond edges', () {
+ final result = _topologicalSort({
+ 1: [2, 3],
+ 2: [4],
+ 3: [4],
+ 4: [],
+ });
+ expect(result.indexOf(1), lessThan(result.indexOf(2)));
+ expect(result.indexOf(1), lessThan(result.indexOf(3)));
+ expect(result.indexOf(1), lessThan(result.indexOf(4)));
+ expect(result.indexOf(2), lessThan(result.indexOf(4)));
+ expect(result.indexOf(3), lessThan(result.indexOf(4)));
+ });
+ });
+
+ test('respects custom equality and hash functions', () {
+ expect(
+ _topologicalSort<int>(
+ {
+ 0: [2],
+ 3: [4],
+ 5: [6],
+ 7: [],
+ },
+ equals: (i, j) => (i ~/ 2) == (j ~/ 2),
+ hashCode: (i) => (i ~/ 2).hashCode,
+ ),
+ equals([
+ 0,
+ anyOf([2, 3]),
+ anyOf([4, 5]),
+ anyOf([6, 7]),
+ ]),
+ );
+ });
+
+ group('throws a CycleException for a graph with', () {
+ test('a one-node cycle', () {
+ expect(
+ () => _topologicalSort({
+ 1: [1],
+ }),
+ throwsCycleException([1]),
+ );
+ });
+
+ test('a multi-node cycle', () {
+ expect(
+ () => _topologicalSort({
+ 1: [2],
+ 2: [3],
+ 3: [4],
+ 4: [1],
+ }),
+ throwsCycleException([4, 1, 2, 3]),
+ );
+ });
+ });
+ });
+
+ group('with secondarySort', () {
+ group('topologically sorts a graph', () {
+ test('with no nodes', () {
+ expect(_topologicalSort({}, secondarySort: true), isEmpty);
+ });
+
+ test('with only one node', () {
+ expect(_topologicalSort({1: []}, secondarySort: true), equals([1]));
+ });
+
+ test('with no edges', () {
+ expect(
+ _topologicalSort({1: [], 2: [], 3: [], 4: []}, secondarySort: true),
+ unorderedEquals([1, 2, 3, 4]),
+ );
+ });
+
+ test('with single edges', () {
+ expect(
+ _topologicalSort(
+ {
+ 1: [2],
+ 2: [3],
+ 3: [4],
+ 4: [],
+ },
+ secondarySort: true,
+ ),
+ equals([1, 2, 3, 4]),
+ );
+ });
+
+ test('with many edges from one node', () {
+ final result = _topologicalSort(
+ {
+ 1: [2, 3, 4],
+ 2: [],
+ 3: [],
+ 4: [],
+ },
+ secondarySort: true,
+ );
+ expect(result.indexOf(1), lessThan(result.indexOf(2)));
+ expect(result.indexOf(1), lessThan(result.indexOf(3)));
+ expect(result.indexOf(1), lessThan(result.indexOf(4)));
+ });
+
+ test('with transitive edges', () {
+ final result = _topologicalSort(
+ {
+ 1: [2, 4],
+ 2: [],
+ 3: [],
+ 4: [3],
+ },
+ secondarySort: true,
+ );
+ expect(result.indexOf(1), lessThan(result.indexOf(2)));
+ expect(result.indexOf(1), lessThan(result.indexOf(3)));
+ expect(result.indexOf(1), lessThan(result.indexOf(4)));
+ expect(result.indexOf(4), lessThan(result.indexOf(3)));
+ });
+
+ test('with diamond edges', () {
+ final result = _topologicalSort(
+ {
+ 1: [2, 3],
+ 2: [4],
+ 3: [4],
+ 4: [],
+ },
+ secondarySort: true,
+ );
+ expect(result.indexOf(1), lessThan(result.indexOf(2)));
+ expect(result.indexOf(1), lessThan(result.indexOf(3)));
+ expect(result.indexOf(1), lessThan(result.indexOf(4)));
+ expect(result.indexOf(2), lessThan(result.indexOf(4)));
+ expect(result.indexOf(3), lessThan(result.indexOf(4)));
+ });
+ });
+
+ group('lexically sorts a graph where possible', () {
+ test('with no edges', () {
+ final result =
+ _topologicalSort({4: [], 3: [], 1: [], 2: []}, secondarySort: true);
+ expect(result, equals([1, 2, 3, 4]));
+ });
+
+ test('with one non-lexical edge', () {
+ final result = _topologicalSort(
+ {
+ 4: [],
+ 3: [1],
+ 1: [],
+ 2: [],
+ },
+ secondarySort: true,
+ );
+ expect(
+ result,
+ equals(
+ anyOf([
+ [2, 3, 1, 4],
+ [3, 1, 2, 4],
+ ]),
+ ),
+ );
+ });
+
+ test('with a non-lexical topolgical order', () {
+ final result = _topologicalSort(
+ {
+ 4: [3],
+ 3: [2],
+ 2: [1],
+ 1: [],
+ },
+ secondarySort: true,
+ );
+ expect(result, equals([4, 3, 2, 1]));
+ });
+
+ group('with multiple layers', () {
+ test('in lexical order', () {
+ final result = _topologicalSort(
+ {
+ 1: [2],
+ 2: [3],
+ 3: [],
+ 4: [5],
+ 5: [6],
+ 6: [],
+ },
+ secondarySort: true,
+ );
+ expect(result, equals([1, 2, 3, 4, 5, 6]));
+ });
+
+ test('in non-lexical order', () {
+ final result = _topologicalSort(
+ {
+ 1: [3],
+ 3: [5],
+ 4: [2],
+ 2: [6],
+ 5: [],
+ 6: [],
+ },
+ secondarySort: true,
+ );
+ expect(
+ result,
+ anyOf([
+ equals([1, 3, 4, 2, 5, 6]),
+ equals([1, 4, 2, 3, 5, 6]),
+ ]),
+ );
+ });
+ });
+ });
+
+ test('respects custom equality and hash functions', () {
+ expect(
+ _topologicalSort<int>(
+ {
+ 0: [2],
+ 3: [4],
+ 5: [6],
+ 7: [],
+ },
+ equals: (i, j) => (i ~/ 2) == (j ~/ 2),
+ hashCode: (i) => (i ~/ 2).hashCode,
+ secondarySort: true,
+ ),
+ equals([
+ 0,
+ anyOf([2, 3]),
+ anyOf([4, 5]),
+ anyOf([6, 7]),
+ ]),
+ );
+ });
+
+ group('throws a CycleException for a graph with', () {
+ test('a one-node cycle', () {
+ expect(
+ () => _topologicalSort(
+ {
+ 1: [1],
+ },
+ secondarySort: true,
+ ),
+ throwsCycleException([1]),
+ );
+ });
+
+ test('a multi-node cycle', () {
+ expect(
+ () => _topologicalSort(
+ {
+ 1: [2],
+ 2: [3],
+ 3: [4],
+ 4: [1],
+ },
+ secondarySort: true,
+ ),
+ throwsCycleException([4, 1, 2, 3]),
+ );
+ });
+ });
+ });
+}
+
+/// Runs a topological sort on a graph represented a map from keys to edges.
+List<T> _topologicalSort<T>(
+ Map<T, List<T>> graph, {
+ bool Function(T, T)? equals,
+ int Function(T)? hashCode,
+ bool secondarySort = false,
+}) {
+ if (equals != null) {
+ graph = LinkedHashMap(equals: equals, hashCode: hashCode)..addAll(graph);
+ }
+ return topologicalSort(
+ graph.keys,
+ (node) {
+ expect(graph, contains(node));
+ return graph[node]!;
+ },
+ equals: equals,
+ hashCode: hashCode,
+ secondarySort:
+ secondarySort ? (a, b) => (a as Comparable<T>).compareTo(b) : null,
+ );
+}
diff --git a/pkgs/graphs/test/transitive_closure_test.dart b/pkgs/graphs/test/transitive_closure_test.dart
new file mode 100644
index 0000000..f732573
--- /dev/null
+++ b/pkgs/graphs/test/transitive_closure_test.dart
@@ -0,0 +1,350 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:collection';
+
+import 'package:graphs/graphs.dart';
+import 'package:test/test.dart';
+
+import 'utils/utils.dart';
+
+void main() {
+ group('for an acyclic graph', () {
+ for (final acyclic in [true, false]) {
+ group('with acyclic: $acyclic', () {
+ group('returns the transitive closure for a graph', () {
+ test('with no nodes', () {
+ expect(_transitiveClosure<int>({}, acyclic: acyclic), isEmpty);
+ });
+
+ test('with only one node', () {
+ expect(
+ _transitiveClosure<int>({1: []}, acyclic: acyclic),
+ equals({1: <int>{}}),
+ );
+ });
+
+ test('with no edges', () {
+ expect(
+ _transitiveClosure<int>(
+ {1: [], 2: [], 3: [], 4: []},
+ acyclic: acyclic,
+ ),
+ equals(<int, Set<int>>{1: {}, 2: {}, 3: {}, 4: {}}),
+ );
+ });
+
+ test('with single edges', () {
+ expect(
+ _transitiveClosure<int>(
+ {
+ 1: [2],
+ 2: [3],
+ 3: [4],
+ 4: [],
+ },
+ acyclic: acyclic,
+ ),
+ equals({
+ 1: {2, 3, 4},
+ 2: {3, 4},
+ 3: {4},
+ 4: <int>{},
+ }),
+ );
+ });
+
+ test('with many edges from one node', () {
+ expect(
+ _transitiveClosure<int>(
+ {
+ 1: [2, 3, 4],
+ 2: [],
+ 3: [],
+ 4: [],
+ },
+ acyclic: acyclic,
+ ),
+ equals(<int, Set<int>>{
+ 1: {2, 3, 4},
+ 2: {},
+ 3: {},
+ 4: {},
+ }),
+ );
+ });
+
+ test('with transitive edges', () {
+ expect(
+ _transitiveClosure<int>(
+ {
+ 1: [2, 4],
+ 2: [],
+ 3: [],
+ 4: [3],
+ },
+ acyclic: acyclic,
+ ),
+ equals(<int, Set<int>>{
+ 1: {2, 3, 4},
+ 2: {},
+ 3: {},
+ 4: {3},
+ }),
+ );
+ });
+
+ test('with diamond edges', () {
+ expect(
+ _transitiveClosure<int>(
+ {
+ 1: [2, 3],
+ 2: [4],
+ 3: [4],
+ 4: [],
+ },
+ acyclic: acyclic,
+ ),
+ equals(<int, Set<int>>{
+ 1: {2, 3, 4},
+ 2: {4},
+ 3: {4},
+ 4: {},
+ }),
+ );
+ });
+
+ test('with disjoint subgraphs', () {
+ expect(
+ _transitiveClosure<int>(
+ {
+ 1: [2],
+ 2: [3],
+ 3: [],
+ 4: [5],
+ 5: [6],
+ 6: [],
+ },
+ acyclic: acyclic,
+ ),
+ equals(<int, Set<int>>{
+ 1: {2, 3},
+ 2: {3},
+ 3: {},
+ 4: {5, 6},
+ 5: {6},
+ 6: {},
+ }),
+ );
+ });
+ });
+
+ test('respects custom equality and hash functions', () {
+ final result = _transitiveClosure<int>(
+ {
+ 0: [2],
+ 3: [4],
+ 5: [6],
+ 7: [],
+ },
+ equals: (i, j) => (i ~/ 2) == (j ~/ 2),
+ hashCode: (i) => (i ~/ 2).hashCode,
+ );
+
+ expect(
+ result.keys,
+ unorderedMatches([
+ 0,
+ anyOf([2, 3]),
+ anyOf([4, 5]),
+ anyOf([6, 7]),
+ ]),
+ );
+ expect(
+ result[0],
+ equals({
+ anyOf([2, 3]),
+ anyOf([4, 5]),
+ anyOf([6, 7]),
+ }),
+ );
+ expect(
+ result[2],
+ equals({
+ anyOf([4, 5]),
+ anyOf([6, 7]),
+ }),
+ );
+ expect(
+ result[4],
+ equals({
+ anyOf([6, 7]),
+ }),
+ );
+ expect(result[6], isEmpty);
+ });
+ });
+ }
+ });
+
+ group('for a cyclic graph', () {
+ group('with acyclic: true throws a CycleException for a graph with', () {
+ test('a one-node cycle', () {
+ expect(
+ () => _transitiveClosure<int>(
+ {
+ 1: [1],
+ },
+ acyclic: true,
+ ),
+ throwsCycleException([1]),
+ );
+ });
+
+ test('a multi-node cycle', () {
+ expect(
+ () => _transitiveClosure<int>(
+ {
+ 1: [2],
+ 2: [3],
+ 3: [4],
+ 4: [1],
+ },
+ acyclic: true,
+ ),
+ throwsCycleException([4, 1, 2, 3]),
+ );
+ });
+ });
+
+ group('returns the transitive closure for a graph', () {
+ test('with a single one-node component', () {
+ expect(
+ _transitiveClosure<int>({
+ 1: [1],
+ }),
+ equals({
+ 1: {1},
+ }),
+ );
+ });
+
+ test('with a single multi-node component', () {
+ expect(
+ _transitiveClosure<int>({
+ 1: [2],
+ 2: [3],
+ 3: [4],
+ 4: [1],
+ }),
+ equals({
+ 1: {1, 2, 3, 4},
+ 2: {1, 2, 3, 4},
+ 3: {1, 2, 3, 4},
+ 4: {1, 2, 3, 4},
+ }),
+ );
+ });
+
+ test('with a series of multi-node components', () {
+ expect(
+ _transitiveClosure<int>({
+ 1: [2],
+ 2: [1, 3],
+ 3: [4],
+ 4: [3, 5],
+ 5: [6],
+ 6: [5, 7],
+ 7: [8],
+ 8: [7],
+ }),
+ equals({
+ 1: {1, 2, 3, 4, 5, 6, 7, 8},
+ 2: {1, 2, 3, 4, 5, 6, 7, 8},
+ 3: {3, 4, 5, 6, 7, 8},
+ 4: {3, 4, 5, 6, 7, 8},
+ 5: {5, 6, 7, 8},
+ 6: {5, 6, 7, 8},
+ 7: {7, 8},
+ 8: {7, 8},
+ }),
+ );
+ });
+
+ test('with a diamond of multi-node components', () {
+ expect(
+ _transitiveClosure<int>({
+ 1: [2],
+ 2: [1, 3, 5],
+ 3: [4],
+ 4: [3, 7],
+ 5: [6],
+ 6: [5, 7],
+ 7: [8],
+ 8: [7],
+ }),
+ equals({
+ 1: {1, 2, 3, 4, 5, 6, 7, 8},
+ 2: {1, 2, 3, 4, 5, 6, 7, 8},
+ 3: {3, 4, 7, 8},
+ 4: {3, 4, 7, 8},
+ 5: {5, 6, 7, 8},
+ 6: {5, 6, 7, 8},
+ 7: {7, 8},
+ 8: {7, 8},
+ }),
+ );
+ });
+
+ test('mixed single- and multi-node components', () {
+ expect(
+ _transitiveClosure<int>({
+ 1: [2],
+ 2: [1, 3],
+ 3: [4],
+ 4: [5],
+ 5: [4, 6],
+ 6: [7],
+ 7: [8],
+ 8: [7],
+ }),
+ equals({
+ 1: {1, 2, 3, 4, 5, 6, 7, 8},
+ 2: {1, 2, 3, 4, 5, 6, 7, 8},
+ 3: {4, 5, 6, 7, 8},
+ 4: {4, 5, 6, 7, 8},
+ 5: {4, 5, 6, 7, 8},
+ 6: {7, 8},
+ 7: {7, 8},
+ 8: {7, 8},
+ }),
+ );
+ });
+ });
+ });
+}
+
+/// Returns the transitive closure of a graph represented a map from keys to
+/// edges.
+Map<T, Set<T>> _transitiveClosure<T extends Object>(
+ Map<T, List<T>> graph, {
+ bool Function(T, T)? equals,
+ int Function(T)? hashCode,
+ bool acyclic = false,
+}) {
+ assert((equals == null) == (hashCode == null));
+ if (equals != null) {
+ graph = LinkedHashMap(equals: equals, hashCode: hashCode)..addAll(graph);
+ }
+ return transitiveClosure(
+ graph.keys,
+ (node) {
+ expect(graph, contains(node));
+ return graph[node]!;
+ },
+ equals: equals,
+ hashCode: hashCode,
+ acyclic: acyclic,
+ );
+}
diff --git a/pkgs/graphs/test/utils/graph.dart b/pkgs/graphs/test/utils/graph.dart
new file mode 100644
index 0000000..ffa24b5
--- /dev/null
+++ b/pkgs/graphs/test/utils/graph.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:collection';
+
+import 'utils.dart';
+
+/// A representation of a Graph since none is specified in `lib/`.
+class Graph {
+ final Map<String, List<String>?> _graph;
+
+ Graph(this._graph);
+
+ List<String> edges(String node) => _graph[node] ?? <Never>[];
+
+ Iterable<String> get allNodes => _graph.keys;
+}
+
+class BadGraph {
+ final Map<X, List<X>?> _graph;
+
+ BadGraph(Map<String, List<String>?> values)
+ : _graph = LinkedHashMap(equals: xEquals, hashCode: xHashCode)
+ ..addEntries(
+ values.entries
+ .map((e) => MapEntry(X(e.key), e.value?.map(X.new).toList())),
+ );
+
+ List<X> edges(X node) => _graph[node] ?? <Never>[];
+
+ Iterable<X> get allNodes => _graph.keys;
+}
+
+/// A representation of a Graph where keys can asynchronously be resolved to
+/// real values or to edges.
+class AsyncGraph {
+ final Map<String, List<String>?> graph;
+
+ AsyncGraph(this.graph);
+
+ Future<String?> readNode(String node) async =>
+ graph.containsKey(node) ? node : null;
+
+ Future<Iterable<String>> edges(String key, String? node) async =>
+ graph[key] ?? <Never>[];
+}
diff --git a/pkgs/graphs/test/utils/utils.dart b/pkgs/graphs/test/utils/utils.dart
new file mode 100644
index 0000000..45a42c6
--- /dev/null
+++ b/pkgs/graphs/test/utils/utils.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:graphs/graphs.dart';
+import 'package:test/test.dart';
+
+bool xEquals(X a, X b) => a.value == b.value;
+
+int xHashCode(X a) => a.value.hashCode;
+
+/// Returns a matcher that verifies that a function throws a [CycleException<T>]
+/// with the given [cycle].
+Matcher throwsCycleException<T>(List<T> cycle) => throwsA(
+ allOf([
+ isA<CycleException<T>>(),
+ predicate((exception) {
+ expect((exception as CycleException<T>).cycle, equals(cycle));
+ return true;
+ }),
+ ]),
+ );
+
+class X {
+ final String value;
+
+ X(this.value);
+
+ @override
+ bool operator ==(Object other) => throw UnimplementedError();
+
+ @override
+ int get hashCode => 42;
+
+ @override
+ String toString() => '($value)';
+}
diff --git a/pkgs/mime/.gitignore b/pkgs/mime/.gitignore
new file mode 100644
index 0000000..a433102
--- /dev/null
+++ b/pkgs/mime/.gitignore
@@ -0,0 +1,5 @@
+.packages
+.dart_tool/
+.pub/
+packages
+pubspec.lock
diff --git a/pkgs/mime/AUTHORS b/pkgs/mime/AUTHORS
new file mode 100644
index 0000000..e8063a8
--- /dev/null
+++ b/pkgs/mime/AUTHORS
@@ -0,0 +1,6 @@
+# Below is a list of people and organizations that have contributed
+# to the project. Names should be added to the list like so:
+#
+# Name/Organization <email address>
+
+Google Inc.
diff --git a/pkgs/mime/CHANGELOG.md b/pkgs/mime/CHANGELOG.md
new file mode 100644
index 0000000..fd5a249
--- /dev/null
+++ b/pkgs/mime/CHANGELOG.md
@@ -0,0 +1,110 @@
+## 2.0.0
+
+* **[Breaking]** `extensionFromMime(String mimeType)` returns `null` instead of `mimeType` for an unknown mime type.
+* Update `extensionFromMime` to return a default extension when a MIME type maps to multiple extensions.
+
+## 1.0.6
+
+* Add `topics` section to `pubspec.yaml`.
+* Move to `dart-lang/tools` monorepo.
+
+## 1.0.5
+
+* Update `video/mp4` mimeType lookup by header bytes.
+* Add `image/heic` mimeType lookup by header bytes.
+* Add `image/heif` mimeType lookup by header bytes.
+* Add m4b mimeType lookup by extension.
+* Add `text/markdown` mimeType lookup by extension.
+* Require Dart 3.2.0.
+
+## 1.0.4
+
+* Changed `.js` to `text/javascript` per
+ https://datatracker.ietf.org/doc/html/rfc9239.
+* Added `.mjs` as `text/javascript`.
+* Add `application/dicom` mimeType lookup by extension.
+* Require Dart 2.18.
+
+## 1.0.3
+
+* Add application/manifest+json lookup by extension.
+* Add application/toml mimeType lookup by extension.
+* Add audio/aac mimeType lookup by header bytes.
+* Add audio/mpeg mimeType lookup by header bytes.
+* Add audio/ogg mimeType lookup by header bytes.
+* Add audio/weba mimeType lookup by header bytes.
+* Add font/woff2 lookup by extension and header bytes.
+* Add image/avif mimeType lookup by extension.
+* Add image/heic mimeType lookup by extension.
+* Add image/heif mimeType lookup by extension.
+* Change audio/x-aac to audio/aac when detected by extension.
+
+## 1.0.2
+
+* Add audio/x-aiff mimeType lookup by header bytes.
+* Add audio/x-flac mimeType lookup by header bytes.
+* Add audio/x-wav mimeType lookup by header bytes.
+* Add audio/mp4 mimeType lookup by file path.
+
+## 1.0.1
+
+* Add image/webp mimeType lookup by header bytes.
+
+## 1.0.0
+
+* Stable null safety release.
+
+## 1.0.0-nullsafety.0
+
+* Update to null safety.
+
+## 0.9.7
+
+* Add `extensionFromMime` utility function.
+
+## 0.9.6+3
+
+* Change the mime type for Dart source from `application/dart` to `text/x-dart`.
+* Add example.
+* Fix links and code in README.
+
+## 0.9.6+2
+
+* Set max SDK version to `<3.0.0`, and adjust other dependencies.
+
+## 0.9.6+1
+
+* Stop using deprecated constants from the SDK.
+
+## 0.9.6
+
+* Updates to support Dart 2.0 core library changes (wave
+ 2.2). See [issue 31847][sdk#31847] for details.
+
+ [sdk#31847]: https://github.com/dart-lang/sdk/issues/31847
+
+## 0.9.5
+
+* Add support for the WebAssembly format.
+
+## 0.9.4
+
+* Updated Dart SDK requirement to `>= 1.8.3 <2.0.0`
+
+* Strong-mode clean.
+
+* Added support for glTF text and binary formats.
+
+## 0.9.3
+
+* Fixed erroneous behavior for listening and when pausing/resuming
+ stream of parts.
+
+## 0.9.2
+
+* Fixed erroneous behavior when pausing/canceling stream of parts but already
+ listened to one part.
+
+## 0.9.1
+
+* Handle parsing of MIME multipart content with no parts.
diff --git a/pkgs/mime/CONTRIBUTING.md b/pkgs/mime/CONTRIBUTING.md
new file mode 100644
index 0000000..463063a
--- /dev/null
+++ b/pkgs/mime/CONTRIBUTING.md
@@ -0,0 +1,37 @@
+Want to contribute? Great! First, read this page (including the small print at
+the end).
+
+### Before you contribute
+Before we can use your code, you must sign the
+[Google Individual Contributor License Agreement](https://cla.developers.google.com/about/google-individual)
+(CLA), which you can do online. The CLA is necessary mainly because you own the
+copyright to your changes, even after your contribution becomes part of our
+codebase, so we need your permission to use and distribute your code. We also
+need to be sure of various other things—for instance that you'll tell us if you
+know that your code infringes on other people's patents. You don't have to sign
+the CLA until after you've submitted your code for review and a member has
+approved it, but you must do it before we can put your code into our codebase.
+
+Before you start working on a larger contribution, you should get in touch with
+us first through the issue tracker with your idea so that we can help out and
+possibly guide you. Coordinating up front makes it much easier to avoid
+frustration later on.
+
+### Code reviews
+All submissions, including submissions by project members, require review.
+
+### File headers
+All files in the project must start with the following header.
+
+ // 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.
+
+### The small print
+Contributions made by corporations are covered by a different agreement than the
+one above, the
+[Software Grant and Corporate Contributor License Agreement](https://developers.google.com/open-source/cla/corporate).
+
+### Adding an extension / MIME type mapping
+If a MIME type ends up with multiple extensions, it is recommended to define a
+preferred extension in `_defaultMimeTypeMap` in [extension.dart](lib/src/extension.dart).
\ No newline at end of file
diff --git a/pkgs/mime/LICENSE b/pkgs/mime/LICENSE
new file mode 100644
index 0000000..dbd2843
--- /dev/null
+++ b/pkgs/mime/LICENSE
@@ -0,0 +1,27 @@
+Copyright 2015, the Dart project authors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of Google LLC nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/pkgs/mime/README.md b/pkgs/mime/README.md
new file mode 100644
index 0000000..da06de6
--- /dev/null
+++ b/pkgs/mime/README.md
@@ -0,0 +1,70 @@
+[](https://github.com/dart-lang/tools/actions/workflows/mime.yml)
+[](https://pub.dev/packages/mime)
+[](https://pub.dev/packages/mime/publisher)
+
+Package for working with MIME type definitions and for processing
+streams of MIME multipart media types.
+
+## Determining the MIME type for a file
+
+The `MimeTypeResolver` class can be used to determine the MIME type of
+a file. It supports both using the extension of the file name and
+looking at magic bytes from the beginning of the file.
+
+There is a builtin instance of `MimeTypeResolver` accessible through
+the top level function `lookupMimeType`. This builtin instance has
+the most common file name extensions and magic bytes registered.
+
+```dart
+import 'package:mime/mime.dart';
+
+void main() {
+ print(lookupMimeType('test.html'));
+ // text/html
+
+ print(lookupMimeType('test', headerBytes: [0xFF, 0xD8]));
+ // image/jpeg
+
+ print(lookupMimeType('test.html', headerBytes: [0xFF, 0xD8]));
+ // image/jpeg
+}
+```
+
+You can build you own resolver by creating an instance of
+`MimeTypeResolver` and adding file name extensions and magic bytes
+using `addExtension` and `addMagicNumber`.
+
+## Processing MIME multipart media types
+
+The class `MimeMultipartTransformer` is used to process a `Stream` of
+bytes encoded using a MIME multipart media types encoding. The
+transformer provides a new `Stream` of `MimeMultipart` objects each of
+which have the headers and the content of each part. The content of a
+part is provided as a stream of bytes.
+
+Below is an example showing how to process an HTTP request and print
+the length of the content of each part.
+
+```dart
+// HTTP request with content type multipart/form-data.
+HttpRequest request = ...;
+// Determine the boundary form the content type header
+String boundary = request.headers.contentType.parameters['boundary'];
+
+// Process the body just calculating the length of each part.
+request
+ .transform(new MimeMultipartTransformer(boundary))
+ .map((part) => part.fold(0, (p, d) => p + d))
+ .listen((length) => print('Part with length $length'));
+```
+
+## Determining file extension by MIME type
+
+The top level function `extensionFromMime` can be used to determine the
+file extension of a given MIME type.
+
+```dart
+print(extensionFromMime('text/html')); // Prints "html".
+print(extensionFromMime('image/jpeg')); // Prints "jpg".
+print(extensionFromMime('application/pdf')); // Prints "pdf".
+```
diff --git a/pkgs/mime/analysis_options.yaml b/pkgs/mime/analysis_options.yaml
new file mode 100644
index 0000000..44b61cf
--- /dev/null
+++ b/pkgs/mime/analysis_options.yaml
@@ -0,0 +1,34 @@
+# https://dart.dev/tools/analysis#the-analysis-options-file
+include: package:dart_flutter_team_lints/analysis_options.yaml
+
+analyzer:
+ language:
+ strict-casts: true
+ strict-inference: true
+ strict-raw-types: true
+
+linter:
+ rules:
+ - avoid_bool_literals_in_conditional_expressions
+ - avoid_classes_with_only_static_members
+ - avoid_private_typedef_functions
+ - avoid_redundant_argument_values
+ - avoid_returning_this
+ - avoid_unused_constructor_parameters
+ - avoid_void_async
+ - cancel_subscriptions
+ - join_return_with_assignment
+ - literal_only_boolean_expressions
+ - missing_whitespace_between_adjacent_strings
+ - no_adjacent_strings_in_list
+ - no_runtimeType_toString
+ - package_api_docs
+ - prefer_const_declarations
+ - prefer_expression_function_bodies
+ - prefer_final_locals
+ - unnecessary_await_in_return
+ - unnecessary_breaks
+ - unnecessary_raw_strings
+ - use_if_null_to_convert_nulls_to_bools
+ - use_raw_strings
+ - use_string_buffers
diff --git a/pkgs/mime/example/example.dart b/pkgs/mime/example/example.dart
new file mode 100644
index 0000000..b54f8e7
--- /dev/null
+++ b/pkgs/mime/example/example.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2024, 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:mime/mime.dart';
+
+void main() {
+ print(lookupMimeType('test.html'));
+ // text/html
+
+ print(lookupMimeType('test', headerBytes: [0xFF, 0xD8]));
+ // image/jpeg
+
+ print(lookupMimeType('test.html', headerBytes: [0xFF, 0xD8]));
+ // image/jpeg
+}
diff --git a/pkgs/mime/lib/mime.dart b/pkgs/mime/lib/mime.dart
new file mode 100644
index 0000000..cb45098
--- /dev/null
+++ b/pkgs/mime/lib/mime.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2013, 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.
+
+/// Help for working with file format identifiers
+/// such as `text/html` and `image/png`.
+///
+/// More details, including a list of types, are in the Wikipedia article
+/// [Internet media type](http://en.wikipedia.org/wiki/Internet_media_type).
+library;
+
+export 'src/extension.dart';
+export 'src/mime_multipart_transformer.dart';
+export 'src/mime_shared.dart';
+export 'src/mime_type.dart';
diff --git a/pkgs/mime/lib/src/bound_multipart_stream.dart b/pkgs/mime/lib/src/bound_multipart_stream.dart
new file mode 100644
index 0000000..03b213b
--- /dev/null
+++ b/pkgs/mime/lib/src/bound_multipart_stream.dart
@@ -0,0 +1,372 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:convert';
+
+import 'char_code.dart' as char_code;
+import 'mime_shared.dart';
+
+/// Bytes for `()<>@,;:\\"/[]?={} \t`.
+const _separators = {
+ 40, 41, 60, 62, 64, 44, 59, 58, 92, 34, 47, 91, 93, 63, 61, 123, 125, 32, 9 //
+};
+
+bool _isTokenChar(int byte) =>
+ byte > 31 && byte < 128 && !_separators.contains(byte);
+
+int _toLowerCase(int byte) {
+ const delta = char_code.lowerA - char_code.upperA;
+ return (char_code.upperA <= byte && byte <= char_code.upperZ)
+ ? byte + delta
+ : byte;
+}
+
+void _expectByteValue(int val1, int val2) {
+ if (val1 != val2) {
+ throw const MimeMultipartException('Failed to parse multipart mime 1');
+ }
+}
+
+void _expectWhitespace(int byte) {
+ if (byte != char_code.sp && byte != char_code.ht) {
+ throw const MimeMultipartException('Failed to parse multipart mime 2');
+ }
+}
+
+class _MimeMultipart extends MimeMultipart {
+ @override
+ final Map<String, String> headers;
+ final Stream<List<int>> _stream;
+
+ _MimeMultipart(this.headers, this._stream);
+
+ @override
+ StreamSubscription<List<int>> listen(
+ void Function(List<int> data)? onData, {
+ void Function()? onDone,
+ Function? onError,
+ bool? cancelOnError,
+ }) =>
+ _stream.listen(
+ onData,
+ onDone: onDone,
+ onError: onError,
+ cancelOnError: cancelOnError,
+ );
+}
+
+class BoundMultipartStream {
+ static const int _startCode = 0;
+ static const int _boundaryEndingCode = 1;
+ static const int _boundaryEndCode = 2;
+ static const int _headerStartCode = 3;
+ static const int _headerFieldCode = 4;
+ static const int _headerValueStartCode = 5;
+ static const int _headerValueCode = 6;
+ static const int _headerValueFoldingOrEndingCode = 7;
+ static const int _headerValueFoldOrEndCode = 8;
+ static const int _headerEndingCode = 9;
+ static const int _contentCode = 10;
+ static const int _lastBoundaryDash2Code = 11;
+ static const int _lastBoundaryEndingCode = 12;
+ static const int _lastBoundaryEndCode = 13;
+ static const int _doneCode = 14;
+ static const int _failCode = 15;
+
+ final List<int> _boundary;
+ final List<int> _headerField = [];
+ final List<int> _headerValue = [];
+
+ // The following states belong to `_controller`, state changes will not be
+ // immediately acted upon but rather only after the current
+ // `_multipartController` is done.
+ static const int _controllerStateIdle = 0;
+ static const int _controllerStateActive = 1;
+ static const int _controllerStatePaused = 2;
+ static const int _controllerStateCanceled = 3;
+
+ int _controllerState = _controllerStateIdle;
+
+ final _controller = StreamController<MimeMultipart>(sync: true);
+
+ Stream<MimeMultipart> get stream => _controller.stream;
+
+ late StreamSubscription<void> _subscription;
+
+ StreamController<List<int>>? _multipartController;
+ Map<String, String>? _headers;
+
+ int _state = _startCode;
+ int _boundaryIndex = 2;
+
+ /// Current index into [_buffer].
+ ///
+ /// If index is negative then it is the index into the artificial prefix of
+ /// the boundary string.
+ int _index = 0;
+ List<int> _buffer = _placeholderBuffer;
+
+ BoundMultipartStream(this._boundary, Stream<List<int>> stream) {
+ _controller
+ ..onPause = _pauseStream
+ ..onResume = _resumeStream
+ ..onCancel = () {
+ _controllerState = _controllerStateCanceled;
+ _tryPropagateControllerState();
+ }
+ ..onListen = () {
+ _controllerState = _controllerStateActive;
+ _subscription = stream.listen((data) {
+ assert(_buffer == _placeholderBuffer);
+ _subscription.pause();
+ _buffer = data;
+ _index = 0;
+ _parse();
+ }, onDone: () {
+ if (_state != _doneCode) {
+ _controller
+ .addError(const MimeMultipartException('Bad multipart ending'));
+ }
+ _controller.close();
+ }, onError: _controller.addError);
+ };
+ }
+
+ void _resumeStream() {
+ assert(_controllerState == _controllerStatePaused);
+ _controllerState = _controllerStateActive;
+ _tryPropagateControllerState();
+ }
+
+ void _pauseStream() {
+ _controllerState = _controllerStatePaused;
+ _tryPropagateControllerState();
+ }
+
+ void _tryPropagateControllerState() {
+ if (_multipartController == null) {
+ switch (_controllerState) {
+ case _controllerStateActive:
+ if (_subscription.isPaused) _subscription.resume();
+ case _controllerStatePaused:
+ if (!_subscription.isPaused) _subscription.pause();
+ case _controllerStateCanceled:
+ _subscription.cancel();
+ default:
+ throw StateError('This code should never be reached.');
+ }
+ }
+ }
+
+ void _parse() {
+ // Number of boundary bytes to artificially place before the supplied data.
+ // The data to parse might be 'artificially' prefixed with a
+ // partial match of the boundary.
+ final boundaryPrefix = _boundaryIndex;
+ // Position where content starts. Will be null if no known content
+ // start exists. Will be negative of the content starts in the
+ // boundary prefix. Will be zero or position if the content starts
+ // in the current buffer.
+ var contentStartIndex =
+ _state == _contentCode && _boundaryIndex == 0 ? 0 : null;
+
+ // Function to report content data for the current part. The data
+ // reported is from the current content start index up til the
+ // current index. As the data can be artificially prefixed with a
+ // prefix of the boundary both the content start index and index
+ // can be negative.
+ void reportData() {
+ if (contentStartIndex! < 0) {
+ final contentLength = boundaryPrefix + _index - _boundaryIndex;
+ if (contentLength <= boundaryPrefix) {
+ _multipartController!.add(_boundary.sublist(0, contentLength));
+ } else {
+ _multipartController!.add(_boundary.sublist(0, boundaryPrefix));
+ _multipartController!
+ .add(_buffer.sublist(0, contentLength - boundaryPrefix));
+ }
+ } else {
+ final contentEndIndex = _index - _boundaryIndex;
+ _multipartController!
+ .add(_buffer.sublist(contentStartIndex, contentEndIndex));
+ }
+ }
+
+ while (
+ _index < _buffer.length && _state != _failCode && _state != _doneCode) {
+ final byte =
+ _index < 0 ? _boundary[boundaryPrefix + _index] : _buffer[_index];
+ switch (_state) {
+ case _startCode:
+ if (byte == _boundary[_boundaryIndex]) {
+ _boundaryIndex++;
+ if (_boundaryIndex == _boundary.length) {
+ _state = _boundaryEndingCode;
+ _boundaryIndex = 0;
+ }
+ } else {
+ // Restart matching of the boundary.
+ _index = _index - _boundaryIndex;
+ _boundaryIndex = 0;
+ }
+
+ case _boundaryEndingCode:
+ if (byte == char_code.cr) {
+ _state = _boundaryEndCode;
+ } else if (byte == char_code.dash) {
+ _state = _lastBoundaryDash2Code;
+ } else {
+ _expectWhitespace(byte);
+ }
+
+ case _boundaryEndCode:
+ _expectByteValue(byte, char_code.lf);
+ _multipartController?.close();
+ if (_multipartController != null) {
+ _multipartController = null;
+ _tryPropagateControllerState();
+ }
+ _state = _headerStartCode;
+
+ case _headerStartCode:
+ _headers = <String, String>{};
+ if (byte == char_code.cr) {
+ _state = _headerEndingCode;
+ } else {
+ // Start of new header field.
+ _headerField.add(_toLowerCase(byte));
+ _state = _headerFieldCode;
+ }
+
+ case _headerFieldCode:
+ if (byte == char_code.colon) {
+ _state = _headerValueStartCode;
+ } else {
+ if (!_isTokenChar(byte)) {
+ throw const MimeMultipartException('Invalid header field name');
+ }
+ _headerField.add(_toLowerCase(byte));
+ }
+
+ case _headerValueStartCode:
+ if (byte == char_code.cr) {
+ _state = _headerValueFoldingOrEndingCode;
+ } else if (byte != char_code.sp && byte != char_code.ht) {
+ // Start of new header value.
+ _headerValue.add(byte);
+ _state = _headerValueCode;
+ }
+
+ case _headerValueCode:
+ if (byte == char_code.cr) {
+ _state = _headerValueFoldingOrEndingCode;
+ } else {
+ _headerValue.add(byte);
+ }
+
+ case _headerValueFoldingOrEndingCode:
+ _expectByteValue(byte, char_code.lf);
+ _state = _headerValueFoldOrEndCode;
+
+ case _headerValueFoldOrEndCode:
+ if (byte == char_code.sp || byte == char_code.ht) {
+ _state = _headerValueStartCode;
+ } else {
+ final headerField = utf8.decode(_headerField);
+ final headerValue = utf8.decode(_headerValue);
+ _headers![headerField.toLowerCase()] = headerValue;
+ _headerField.clear();
+ _headerValue.clear();
+ if (byte == char_code.cr) {
+ _state = _headerEndingCode;
+ } else {
+ // Start of new header field.
+ _headerField.add(_toLowerCase(byte));
+ _state = _headerFieldCode;
+ }
+ }
+
+ case _headerEndingCode:
+ _expectByteValue(byte, char_code.lf);
+ _multipartController = StreamController(
+ sync: true,
+ onListen: () {
+ if (_subscription.isPaused) _subscription.resume();
+ },
+ onPause: _subscription.pause,
+ onResume: _subscription.resume);
+ _controller
+ .add(_MimeMultipart(_headers!, _multipartController!.stream));
+ _headers = null;
+ _state = _contentCode;
+ contentStartIndex = _index + 1;
+
+ case _contentCode:
+ if (byte == _boundary[_boundaryIndex]) {
+ _boundaryIndex++;
+ if (_boundaryIndex == _boundary.length) {
+ if (contentStartIndex != null) {
+ _index++;
+ reportData();
+ _index--;
+ }
+ _multipartController!.close();
+ _multipartController = null;
+ _tryPropagateControllerState();
+ _boundaryIndex = 0;
+ _state = _boundaryEndingCode;
+ }
+ } else {
+ // Restart matching of the boundary.
+ _index = _index - _boundaryIndex;
+ contentStartIndex ??= _index;
+ _boundaryIndex = 0;
+ }
+
+ case _lastBoundaryDash2Code:
+ _expectByteValue(byte, char_code.dash);
+ _state = _lastBoundaryEndingCode;
+
+ case _lastBoundaryEndingCode:
+ if (byte == char_code.cr) {
+ _state = _lastBoundaryEndCode;
+ } else {
+ _expectWhitespace(byte);
+ }
+
+ case _lastBoundaryEndCode:
+ _expectByteValue(byte, char_code.lf);
+ _multipartController?.close();
+ if (_multipartController != null) {
+ _multipartController = null;
+ _tryPropagateControllerState();
+ }
+ _state = _doneCode;
+
+ default:
+ // Should be unreachable.
+ assert(false);
+ }
+
+ // Move to the next byte.
+ _index++;
+ }
+
+ // Report any known content.
+ if (_state == _contentCode && contentStartIndex != null) {
+ reportData();
+ }
+
+ // Resume if at end.
+ if (_index == _buffer.length) {
+ _buffer = _placeholderBuffer;
+ _index = 0;
+ _subscription.resume();
+ }
+ }
+}
+
+// Used as a placeholder instead of having a nullable buffer.
+const _placeholderBuffer = <int>[];
diff --git a/pkgs/mime/lib/src/char_code.dart b/pkgs/mime/lib/src/char_code.dart
new file mode 100644
index 0000000..4cca1b1
--- /dev/null
+++ b/pkgs/mime/lib/src/char_code.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+const int ht = 9;
+const int lf = 10;
+const int cr = 13;
+const int sp = 32;
+const int dash = 45;
+const int colon = 58;
+const int upperA = 65;
+const int upperZ = 90;
+const int lowerA = 97;
diff --git a/pkgs/mime/lib/src/default_extension_map.dart b/pkgs/mime/lib/src/default_extension_map.dart
new file mode 100644
index 0000000..287c957
--- /dev/null
+++ b/pkgs/mime/lib/src/default_extension_map.dart
@@ -0,0 +1,1012 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+const Map<String, String> defaultExtensionMap = <String, String>{
+ '123': 'application/vnd.lotus-1-2-3',
+ '3dml': 'text/vnd.in3d.3dml',
+ '3ds': 'image/x-3ds',
+ '3g2': 'video/3gpp2',
+ '3gp': 'video/3gpp',
+ '7z': 'application/x-7z-compressed',
+ 'aab': 'application/x-authorware-bin',
+ 'aac': 'audio/aac',
+ 'aam': 'application/x-authorware-map',
+ 'aas': 'application/x-authorware-seg',
+ 'abw': 'application/x-abiword',
+ 'ac': 'application/pkix-attr-cert',
+ 'acc': 'application/vnd.americandynamics.acc',
+ 'ace': 'application/x-ace-compressed',
+ 'acu': 'application/vnd.acucobol',
+ 'acutc': 'application/vnd.acucorp',
+ 'adp': 'audio/adpcm',
+ 'aep': 'application/vnd.audiograph',
+ 'afm': 'application/x-font-type1',
+ 'afp': 'application/vnd.ibm.modcap',
+ 'ahead': 'application/vnd.ahead.space',
+ 'ai': 'application/postscript',
+ 'aif': 'audio/x-aiff',
+ 'aifc': 'audio/x-aiff',
+ 'aiff': 'audio/x-aiff',
+ 'air': 'application/vnd.adobe.air-application-installer-package+zip',
+ 'ait': 'application/vnd.dvb.ait',
+ 'ami': 'application/vnd.amiga.ami',
+ 'apk': 'application/vnd.android.package-archive',
+ 'appcache': 'text/cache-manifest',
+ 'application': 'application/x-ms-application',
+ 'apr': 'application/vnd.lotus-approach',
+ 'arc': 'application/x-freearc',
+ 'asc': 'application/pgp-signature',
+ 'asf': 'video/x-ms-asf',
+ 'asm': 'text/x-asm',
+ 'aso': 'application/vnd.accpac.simply.aso',
+ 'asx': 'video/x-ms-asf',
+ 'atc': 'application/vnd.acucorp',
+ 'atom': 'application/atom+xml',
+ 'atomcat': 'application/atomcat+xml',
+ 'atomsvc': 'application/atomsvc+xml',
+ 'atx': 'application/vnd.antix.game-component',
+ 'au': 'audio/basic',
+ 'avi': 'video/x-msvideo',
+ 'avif': 'image/avif',
+ 'aw': 'application/applixware',
+ 'azf': 'application/vnd.airzip.filesecure.azf',
+ 'azs': 'application/vnd.airzip.filesecure.azs',
+ 'azw': 'application/vnd.amazon.ebook',
+ 'bat': 'application/x-msdownload',
+ 'bcpio': 'application/x-bcpio',
+ 'bdf': 'application/x-font-bdf',
+ 'bdm': 'application/vnd.syncml.dm+wbxml',
+ 'bed': 'application/vnd.realvnc.bed',
+ 'bh2': 'application/vnd.fujitsu.oasysprs',
+ 'bin': 'application/octet-stream',
+ 'blb': 'application/x-blorb',
+ 'blorb': 'application/x-blorb',
+ 'bmi': 'application/vnd.bmi',
+ 'bmp': 'image/bmp',
+ 'book': 'application/vnd.framemaker',
+ 'box': 'application/vnd.previewsystems.box',
+ 'boz': 'application/x-bzip2',
+ 'bpk': 'application/octet-stream',
+ 'btif': 'image/prs.btif',
+ 'bz': 'application/x-bzip',
+ 'bz2': 'application/x-bzip2',
+ 'c': 'text/x-c',
+ 'c11amc': 'application/vnd.cluetrust.cartomobile-config',
+ 'c11amz': 'application/vnd.cluetrust.cartomobile-config-pkg',
+ 'c4d': 'application/vnd.clonk.c4group',
+ 'c4f': 'application/vnd.clonk.c4group',
+ 'c4g': 'application/vnd.clonk.c4group',
+ 'c4p': 'application/vnd.clonk.c4group',
+ 'c4u': 'application/vnd.clonk.c4group',
+ 'cab': 'application/vnd.ms-cab-compressed',
+ 'caf': 'audio/x-caf',
+ 'cap': 'application/vnd.tcpdump.pcap',
+ 'car': 'application/vnd.curl.car',
+ 'cat': 'application/vnd.ms-pki.seccat',
+ 'cb7': 'application/x-cbr',
+ 'cba': 'application/x-cbr',
+ 'cbr': 'application/x-cbr',
+ 'cbt': 'application/x-cbr',
+ 'cbz': 'application/x-cbr',
+ 'cc': 'text/x-c',
+ 'cct': 'application/x-director',
+ 'ccxml': 'application/ccxml+xml',
+ 'cdbcmsg': 'application/vnd.contact.cmsg',
+ 'cdf': 'application/x-netcdf',
+ 'cdkey': 'application/vnd.mediastation.cdkey',
+ 'cdmia': 'application/cdmi-capability',
+ 'cdmic': 'application/cdmi-container',
+ 'cdmid': 'application/cdmi-domain',
+ 'cdmio': 'application/cdmi-object',
+ 'cdmiq': 'application/cdmi-queue',
+ 'cdx': 'chemical/x-cdx',
+ 'cdxml': 'application/vnd.chemdraw+xml',
+ 'cdy': 'application/vnd.cinderella',
+ 'cer': 'application/pkix-cert',
+ 'cfs': 'application/x-cfs-compressed',
+ 'cgm': 'image/cgm',
+ 'chat': 'application/x-chat',
+ 'chm': 'application/vnd.ms-htmlhelp',
+ 'chrt': 'application/vnd.kde.kchart',
+ 'cif': 'chemical/x-cif',
+ 'cii': 'application/vnd.anser-web-certificate-issue-initiation',
+ 'cil': 'application/vnd.ms-artgalry',
+ 'cla': 'application/vnd.claymore',
+ 'class': 'application/java-vm',
+ 'clkk': 'application/vnd.crick.clicker.keyboard',
+ 'clkp': 'application/vnd.crick.clicker.palette',
+ 'clkt': 'application/vnd.crick.clicker.template',
+ 'clkw': 'application/vnd.crick.clicker.wordbank',
+ 'clkx': 'application/vnd.crick.clicker',
+ 'clp': 'application/x-msclip',
+ 'cmc': 'application/vnd.cosmocaller',
+ 'cmdf': 'chemical/x-cmdf',
+ 'cml': 'chemical/x-cml',
+ 'cmp': 'application/vnd.yellowriver-custom-menu',
+ 'cmx': 'image/x-cmx',
+ 'cod': 'application/vnd.rim.cod',
+ 'com': 'application/x-msdownload',
+ 'conf': 'text/plain',
+ 'cpio': 'application/x-cpio',
+ 'cpp': 'text/x-c',
+ 'cpt': 'application/mac-compactpro',
+ 'crd': 'application/x-mscardfile',
+ 'crl': 'application/pkix-crl',
+ 'crt': 'application/x-x509-ca-cert',
+ 'cryptonote': 'application/vnd.rig.cryptonote',
+ 'csh': 'application/x-csh',
+ 'csml': 'chemical/x-csml',
+ 'csp': 'application/vnd.commonspace',
+ 'css': 'text/css',
+ 'cst': 'application/x-director',
+ 'csv': 'text/csv',
+ 'cu': 'application/cu-seeme',
+ 'curl': 'text/vnd.curl',
+ 'cww': 'application/prs.cww',
+ 'cxt': 'application/x-director',
+ 'cxx': 'text/x-c',
+ 'dae': 'model/vnd.collada+xml',
+ 'daf': 'application/vnd.mobius.daf',
+ 'dart': 'text/x-dart',
+ 'dataless': 'application/vnd.fdsn.seed',
+ 'davmount': 'application/davmount+xml',
+ 'dbk': 'application/docbook+xml',
+ 'dcm': 'application/dicom',
+ 'dcr': 'application/x-director',
+ 'dcurl': 'text/vnd.curl.dcurl',
+ 'dd2': 'application/vnd.oma.dd2+xml',
+ 'ddd': 'application/vnd.fujixerox.ddd',
+ 'deb': 'application/x-debian-package',
+ 'def': 'text/plain',
+ 'deploy': 'application/octet-stream',
+ 'der': 'application/x-x509-ca-cert',
+ 'dfac': 'application/vnd.dreamfactory',
+ 'dgc': 'application/x-dgc-compressed',
+ 'dic': 'text/x-c',
+ 'dir': 'application/x-director',
+ 'dis': 'application/vnd.mobius.dis',
+ 'dist': 'application/octet-stream',
+ 'distz': 'application/octet-stream',
+ 'djv': 'image/vnd.djvu',
+ 'djvu': 'image/vnd.djvu',
+ 'dll': 'application/x-msdownload',
+ 'dmg': 'application/x-apple-diskimage',
+ 'dmp': 'application/vnd.tcpdump.pcap',
+ 'dms': 'application/octet-stream',
+ 'dna': 'application/vnd.dna',
+ 'doc': 'application/msword',
+ 'docm': 'application/vnd.ms-word.document.macroenabled.12',
+ 'docx':
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+ 'dot': 'application/msword',
+ 'dotm': 'application/vnd.ms-word.template.macroenabled.12',
+ 'dotx':
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
+ 'dp': 'application/vnd.osgi.dp',
+ 'dpg': 'application/vnd.dpgraph',
+ 'dra': 'audio/vnd.dra',
+ 'dsc': 'text/prs.lines.tag',
+ 'dssc': 'application/dssc+der',
+ 'dtb': 'application/x-dtbook+xml',
+ 'dtd': 'application/xml-dtd',
+ 'dts': 'audio/vnd.dts',
+ 'dtshd': 'audio/vnd.dts.hd',
+ 'dump': 'application/octet-stream',
+ 'dvb': 'video/vnd.dvb.file',
+ 'dvi': 'application/x-dvi',
+ 'dwf': 'model/vnd.dwf',
+ 'dwg': 'image/vnd.dwg',
+ 'dxf': 'image/vnd.dxf',
+ 'dxp': 'application/vnd.spotfire.dxp',
+ 'dxr': 'application/x-director',
+ 'ecelp4800': 'audio/vnd.nuera.ecelp4800',
+ 'ecelp7470': 'audio/vnd.nuera.ecelp7470',
+ 'ecelp9600': 'audio/vnd.nuera.ecelp9600',
+ 'ecma': 'application/ecmascript',
+ 'edm': 'application/vnd.novadigm.edm',
+ 'edx': 'application/vnd.novadigm.edx',
+ 'efif': 'application/vnd.picsel',
+ 'ei6': 'application/vnd.pg.osasli',
+ 'elc': 'application/octet-stream',
+ 'emf': 'application/x-msmetafile',
+ 'eml': 'message/rfc822',
+ 'emma': 'application/emma+xml',
+ 'emz': 'application/x-msmetafile',
+ 'eol': 'audio/vnd.digital-winds',
+ 'eot': 'application/vnd.ms-fontobject',
+ 'eps': 'application/postscript',
+ 'epub': 'application/epub+zip',
+ 'es3': 'application/vnd.eszigno3+xml',
+ 'esa': 'application/vnd.osgi.subsystem',
+ 'esf': 'application/vnd.epson.esf',
+ 'et3': 'application/vnd.eszigno3+xml',
+ 'etx': 'text/x-setext',
+ 'eva': 'application/x-eva',
+ 'evy': 'application/x-envoy',
+ 'exe': 'application/x-msdownload',
+ 'exi': 'application/exi',
+ 'ext': 'application/vnd.novadigm.ext',
+ 'ez': 'application/andrew-inset',
+ 'ez2': 'application/vnd.ezpix-album',
+ 'ez3': 'application/vnd.ezpix-package',
+ 'f': 'text/x-fortran',
+ 'f4v': 'video/x-f4v',
+ 'f77': 'text/x-fortran',
+ 'f90': 'text/x-fortran',
+ 'fbs': 'image/vnd.fastbidsheet',
+ 'fcdt': 'application/vnd.adobe.formscentral.fcdt',
+ 'fcs': 'application/vnd.isac.fcs',
+ 'fdf': 'application/vnd.fdf',
+ 'fe_launch': 'application/vnd.denovo.fcselayout-link',
+ 'fg5': 'application/vnd.fujitsu.oasysgp',
+ 'fgd': 'application/x-director',
+ 'fh': 'image/x-freehand',
+ 'fh4': 'image/x-freehand',
+ 'fh5': 'image/x-freehand',
+ 'fh7': 'image/x-freehand',
+ 'fhc': 'image/x-freehand',
+ 'fig': 'application/x-xfig',
+ 'flac': 'audio/x-flac',
+ 'fli': 'video/x-fli',
+ 'flo': 'application/vnd.micrografx.flo',
+ 'flv': 'video/x-flv',
+ 'flw': 'application/vnd.kde.kivio',
+ 'flx': 'text/vnd.fmi.flexstor',
+ 'fly': 'text/vnd.fly',
+ 'fm': 'application/vnd.framemaker',
+ 'fnc': 'application/vnd.frogans.fnc',
+ 'for': 'text/x-fortran',
+ 'fpx': 'image/vnd.fpx',
+ 'frame': 'application/vnd.framemaker',
+ 'fsc': 'application/vnd.fsc.weblaunch',
+ 'fst': 'image/vnd.fst',
+ 'ftc': 'application/vnd.fluxtime.clip',
+ 'fti': 'application/vnd.anser-web-funds-transfer-initiation',
+ 'fvt': 'video/vnd.fvt',
+ 'fxp': 'application/vnd.adobe.fxp',
+ 'fxpl': 'application/vnd.adobe.fxp',
+ 'fzs': 'application/vnd.fuzzysheet',
+ 'g2w': 'application/vnd.geoplan',
+ 'g3': 'image/g3fax',
+ 'g3w': 'application/vnd.geospace',
+ 'gac': 'application/vnd.groove-account',
+ 'gam': 'application/x-tads',
+ 'gbr': 'application/rpki-ghostbusters',
+ 'gca': 'application/x-gca-compressed',
+ 'gdl': 'model/vnd.gdl',
+ 'geo': 'application/vnd.dynageo',
+ 'gex': 'application/vnd.geometry-explorer',
+ 'ggb': 'application/vnd.geogebra.file',
+ 'ggt': 'application/vnd.geogebra.tool',
+ 'ghf': 'application/vnd.groove-help',
+ 'gif': 'image/gif',
+ 'gim': 'application/vnd.groove-identity-message',
+ 'glb': 'model/gltf-binary',
+ 'gltf': 'model/gltf+json',
+ 'gml': 'application/gml+xml',
+ 'gmx': 'application/vnd.gmx',
+ 'gnumeric': 'application/x-gnumeric',
+ 'gph': 'application/vnd.flographit',
+ 'gpx': 'application/gpx+xml',
+ 'gqf': 'application/vnd.grafeq',
+ 'gqs': 'application/vnd.grafeq',
+ 'gram': 'application/srgs',
+ 'gramps': 'application/x-gramps-xml',
+ 'gre': 'application/vnd.geometry-explorer',
+ 'grv': 'application/vnd.groove-injector',
+ 'grxml': 'application/srgs+xml',
+ 'gsf': 'application/x-font-ghostscript',
+ 'gtar': 'application/x-gtar',
+ 'gtm': 'application/vnd.groove-tool-message',
+ 'gtw': 'model/vnd.gtw',
+ 'gv': 'text/vnd.graphviz',
+ 'gxf': 'application/gxf',
+ 'gxt': 'application/vnd.geonext',
+ 'h': 'text/x-c',
+ 'h261': 'video/h261',
+ 'h263': 'video/h263',
+ 'h264': 'video/h264',
+ 'hal': 'application/vnd.hal+xml',
+ 'hbci': 'application/vnd.hbci',
+ 'hdf': 'application/x-hdf',
+ 'heic': 'image/heic',
+ 'heif': 'image/heif',
+ 'hh': 'text/x-c',
+ 'hlp': 'application/winhlp',
+ 'hpgl': 'application/vnd.hp-hpgl',
+ 'hpid': 'application/vnd.hp-hpid',
+ 'hps': 'application/vnd.hp-hps',
+ 'hqx': 'application/mac-binhex40',
+ 'htke': 'application/vnd.kenameaapp',
+ 'htm': 'text/html',
+ 'html': 'text/html',
+ 'hvd': 'application/vnd.yamaha.hv-dic',
+ 'hvp': 'application/vnd.yamaha.hv-voice',
+ 'hvs': 'application/vnd.yamaha.hv-script',
+ 'i2g': 'application/vnd.intergeo',
+ 'icc': 'application/vnd.iccprofile',
+ 'ice': 'x-conference/x-cooltalk',
+ 'icm': 'application/vnd.iccprofile',
+ 'ico': 'image/x-icon',
+ 'ics': 'text/calendar',
+ 'ief': 'image/ief',
+ 'ifb': 'text/calendar',
+ 'ifm': 'application/vnd.shana.informed.formdata',
+ 'iges': 'model/iges',
+ 'igl': 'application/vnd.igloader',
+ 'igm': 'application/vnd.insors.igm',
+ 'igs': 'model/iges',
+ 'igx': 'application/vnd.micrografx.igx',
+ 'iif': 'application/vnd.shana.informed.interchange',
+ 'imp': 'application/vnd.accpac.simply.imp',
+ 'ims': 'application/vnd.ms-ims',
+ 'in': 'text/plain',
+ 'ink': 'application/inkml+xml',
+ 'inkml': 'application/inkml+xml',
+ 'install': 'application/x-install-instructions',
+ 'iota': 'application/vnd.astraea-software.iota',
+ 'ipfix': 'application/ipfix',
+ 'ipk': 'application/vnd.shana.informed.package',
+ 'irm': 'application/vnd.ibm.rights-management',
+ 'irp': 'application/vnd.irepository.package+xml',
+ 'iso': 'application/x-iso9660-image',
+ 'itp': 'application/vnd.shana.informed.formtemplate',
+ 'ivp': 'application/vnd.immervision-ivp',
+ 'ivu': 'application/vnd.immervision-ivu',
+ 'jad': 'text/vnd.sun.j2me.app-descriptor',
+ 'jam': 'application/vnd.jam',
+ 'jar': 'application/java-archive',
+ 'java': 'text/x-java-source',
+ 'jisp': 'application/vnd.jisp',
+ 'jlt': 'application/vnd.hp-jlyt',
+ 'jnlp': 'application/x-java-jnlp-file',
+ 'joda': 'application/vnd.joost.joda-archive',
+ 'jpe': 'image/jpeg',
+ 'jpeg': 'image/jpeg',
+ 'jpg': 'image/jpeg',
+ 'jpgm': 'video/jpm',
+ 'jpgv': 'video/jpeg',
+ 'jpm': 'video/jpm',
+ 'js': 'text/javascript',
+ 'json': 'application/json',
+ 'jsonml': 'application/jsonml+json',
+ 'kar': 'audio/midi',
+ 'karbon': 'application/vnd.kde.karbon',
+ 'kfo': 'application/vnd.kde.kformula',
+ 'kia': 'application/vnd.kidspiration',
+ 'kml': 'application/vnd.google-earth.kml+xml',
+ 'kmz': 'application/vnd.google-earth.kmz',
+ 'kne': 'application/vnd.kinar',
+ 'knp': 'application/vnd.kinar',
+ 'kon': 'application/vnd.kde.kontour',
+ 'kpr': 'application/vnd.kde.kpresenter',
+ 'kpt': 'application/vnd.kde.kpresenter',
+ 'kpxx': 'application/vnd.ds-keypoint',
+ 'ksp': 'application/vnd.kde.kspread',
+ 'ktr': 'application/vnd.kahootz',
+ 'ktx': 'image/ktx',
+ 'ktz': 'application/vnd.kahootz',
+ 'kwd': 'application/vnd.kde.kword',
+ 'kwt': 'application/vnd.kde.kword',
+ 'lasxml': 'application/vnd.las.las+xml',
+ 'latex': 'application/x-latex',
+ 'lbd': 'application/vnd.llamagraphics.life-balance.desktop',
+ 'lbe': 'application/vnd.llamagraphics.life-balance.exchange+xml',
+ 'les': 'application/vnd.hhe.lesson-player',
+ 'lha': 'application/x-lzh-compressed',
+ 'link66': 'application/vnd.route66.link66+xml',
+ 'list': 'text/plain',
+ 'list3820': 'application/vnd.ibm.modcap',
+ 'listafp': 'application/vnd.ibm.modcap',
+ 'lnk': 'application/x-ms-shortcut',
+ 'log': 'text/plain',
+ 'lostxml': 'application/lost+xml',
+ 'lrf': 'application/octet-stream',
+ 'lrm': 'application/vnd.ms-lrm',
+ 'ltf': 'application/vnd.frogans.ltf',
+ 'lvp': 'audio/vnd.lucent.voice',
+ 'lwp': 'application/vnd.lotus-wordpro',
+ 'lzh': 'application/x-lzh-compressed',
+ 'm13': 'application/x-msmediaview',
+ 'm14': 'application/x-msmediaview',
+ 'm1v': 'video/mpeg',
+ 'm21': 'application/mp21',
+ 'm2a': 'audio/mpeg',
+ 'm2v': 'video/mpeg',
+ 'm3a': 'audio/mpeg',
+ 'm3u': 'audio/x-mpegurl',
+ 'm3u8': 'application/vnd.apple.mpegurl',
+ // Source: https://datatracker.ietf.org/doc/html/rfc4337#section-2
+ 'm4a': 'audio/mp4',
+ 'm4b': 'audio/mp4',
+ 'm4u': 'video/vnd.mpegurl',
+ 'm4v': 'video/x-m4v',
+ 'ma': 'application/mathematica',
+ 'mads': 'application/mads+xml',
+ 'mag': 'application/vnd.ecowin.chart',
+ 'maker': 'application/vnd.framemaker',
+ 'man': 'text/troff',
+ 'mar': 'application/octet-stream',
+ 'mathml': 'application/mathml+xml',
+ 'mb': 'application/mathematica',
+ 'mbk': 'application/vnd.mobius.mbk',
+ 'mbox': 'application/mbox',
+ 'mc1': 'application/vnd.medcalcdata',
+ 'mcd': 'application/vnd.mcd',
+ 'mcurl': 'text/vnd.curl.mcurl',
+ // https://www.rfc-editor.org/rfc/rfc7763
+ 'md': 'text/markdown',
+ 'markdown': 'text/markdown',
+ 'mdb': 'application/x-msaccess',
+ 'mdi': 'image/vnd.ms-modi',
+ 'me': 'text/troff',
+ 'mesh': 'model/mesh',
+ 'meta4': 'application/metalink4+xml',
+ 'metalink': 'application/metalink+xml',
+ 'mets': 'application/mets+xml',
+ 'mfm': 'application/vnd.mfmp',
+ 'mft': 'application/rpki-manifest',
+ 'mgp': 'application/vnd.osgeo.mapguide.package',
+ 'mgz': 'application/vnd.proteus.magazine',
+ 'mid': 'audio/midi',
+ 'midi': 'audio/midi',
+ 'mie': 'application/x-mie',
+ 'mif': 'application/vnd.mif',
+ 'mime': 'message/rfc822',
+ 'mj2': 'video/mj2',
+ 'mjp2': 'video/mj2',
+ 'mjs': 'text/javascript',
+ 'mk3d': 'video/x-matroska',
+ 'mka': 'audio/x-matroska',
+ 'mks': 'video/x-matroska',
+ 'mkv': 'video/x-matroska',
+ 'mlp': 'application/vnd.dolby.mlp',
+ 'mmd': 'application/vnd.chipnuts.karaoke-mmd',
+ 'mmf': 'application/vnd.smaf',
+ 'mmr': 'image/vnd.fujixerox.edmics-mmr',
+ 'mng': 'video/x-mng',
+ 'mny': 'application/x-msmoney',
+ 'mobi': 'application/x-mobipocket-ebook',
+ 'mods': 'application/mods+xml',
+ 'mov': 'video/quicktime',
+ 'movie': 'video/x-sgi-movie',
+ 'mp2': 'audio/mpeg',
+ 'mp21': 'application/mp21',
+ 'mp2a': 'audio/mpeg',
+ 'mp3': 'audio/mpeg',
+ 'mp4': 'video/mp4',
+ 'mp4a': 'audio/mp4',
+ 'mp4s': 'application/mp4',
+ 'mp4v': 'video/mp4',
+ 'mpc': 'application/vnd.mophun.certificate',
+ 'mpe': 'video/mpeg',
+ 'mpeg': 'video/mpeg',
+ 'mpg': 'video/mpeg',
+ 'mpg4': 'video/mp4',
+ 'mpga': 'audio/mpeg',
+ 'mpkg': 'application/vnd.apple.installer+xml',
+ 'mpm': 'application/vnd.blueice.multipass',
+ 'mpn': 'application/vnd.mophun.application',
+ 'mpp': 'application/vnd.ms-project',
+ 'mpt': 'application/vnd.ms-project',
+ 'mpy': 'application/vnd.ibm.minipay',
+ 'mqy': 'application/vnd.mobius.mqy',
+ 'mrc': 'application/marc',
+ 'mrcx': 'application/marcxml+xml',
+ 'ms': 'text/troff',
+ 'mscml': 'application/mediaservercontrol+xml',
+ 'mseed': 'application/vnd.fdsn.mseed',
+ 'mseq': 'application/vnd.mseq',
+ 'msf': 'application/vnd.epson.msf',
+ 'msh': 'model/mesh',
+ 'msi': 'application/x-msdownload',
+ 'msl': 'application/vnd.mobius.msl',
+ 'msty': 'application/vnd.muvee.style',
+ 'mts': 'model/vnd.mts',
+ 'mus': 'application/vnd.musician',
+ 'musicxml': 'application/vnd.recordare.musicxml+xml',
+ 'mvb': 'application/x-msmediaview',
+ 'mwf': 'application/vnd.mfer',
+ 'mxf': 'application/mxf',
+ 'mxl': 'application/vnd.recordare.musicxml',
+ 'mxml': 'application/xv+xml',
+ 'mxs': 'application/vnd.triscape.mxs',
+ 'mxu': 'video/vnd.mpegurl',
+ 'n-gage': 'application/vnd.nokia.n-gage.symbian.install',
+ 'n3': 'text/n3',
+ 'nb': 'application/mathematica',
+ 'nbp': 'application/vnd.wolfram.player',
+ 'nc': 'application/x-netcdf',
+ 'ncx': 'application/x-dtbncx+xml',
+ 'nfo': 'text/x-nfo',
+ 'ngdat': 'application/vnd.nokia.n-gage.data',
+ 'nitf': 'application/vnd.nitf',
+ 'nlu': 'application/vnd.neurolanguage.nlu',
+ 'nml': 'application/vnd.enliven',
+ 'nnd': 'application/vnd.noblenet-directory',
+ 'nns': 'application/vnd.noblenet-sealer',
+ 'nnw': 'application/vnd.noblenet-web',
+ 'npx': 'image/vnd.net-fpx',
+ 'nsc': 'application/x-conference',
+ 'nsf': 'application/vnd.lotus-notes',
+ 'ntf': 'application/vnd.nitf',
+ 'nzb': 'application/x-nzb',
+ 'oa2': 'application/vnd.fujitsu.oasys2',
+ 'oa3': 'application/vnd.fujitsu.oasys3',
+ 'oas': 'application/vnd.fujitsu.oasys',
+ 'obd': 'application/x-msbinder',
+ 'obj': 'application/x-tgif',
+ 'oda': 'application/oda',
+ 'odb': 'application/vnd.oasis.opendocument.database',
+ 'odc': 'application/vnd.oasis.opendocument.chart',
+ 'odf': 'application/vnd.oasis.opendocument.formula',
+ 'odft': 'application/vnd.oasis.opendocument.formula-template',
+ 'odg': 'application/vnd.oasis.opendocument.graphics',
+ 'odi': 'application/vnd.oasis.opendocument.image',
+ 'odm': 'application/vnd.oasis.opendocument.text-master',
+ 'odp': 'application/vnd.oasis.opendocument.presentation',
+ 'ods': 'application/vnd.oasis.opendocument.spreadsheet',
+ 'odt': 'application/vnd.oasis.opendocument.text',
+ 'oga': 'audio/ogg',
+ 'ogg': 'audio/ogg',
+ 'ogv': 'video/ogg',
+ 'ogx': 'application/ogg',
+ 'omdoc': 'application/omdoc+xml',
+ 'onepkg': 'application/onenote',
+ 'onetmp': 'application/onenote',
+ 'onetoc': 'application/onenote',
+ 'onetoc2': 'application/onenote',
+ 'opf': 'application/oebps-package+xml',
+ 'opml': 'text/x-opml',
+ 'oprc': 'application/vnd.palm',
+ 'org': 'application/vnd.lotus-organizer',
+ 'osf': 'application/vnd.yamaha.openscoreformat',
+ 'osfpvg': 'application/vnd.yamaha.openscoreformat.osfpvg+xml',
+ 'otc': 'application/vnd.oasis.opendocument.chart-template',
+ 'otf': 'application/x-font-otf',
+ 'otg': 'application/vnd.oasis.opendocument.graphics-template',
+ 'oth': 'application/vnd.oasis.opendocument.text-web',
+ 'oti': 'application/vnd.oasis.opendocument.image-template',
+ 'otp': 'application/vnd.oasis.opendocument.presentation-template',
+ 'ots': 'application/vnd.oasis.opendocument.spreadsheet-template',
+ 'ott': 'application/vnd.oasis.opendocument.text-template',
+ 'oxps': 'application/oxps',
+ 'oxt': 'application/vnd.openofficeorg.extension',
+ 'p': 'text/x-pascal',
+ 'p10': 'application/pkcs10',
+ 'p12': 'application/x-pkcs12',
+ 'p7b': 'application/x-pkcs7-certificates',
+ 'p7c': 'application/pkcs7-mime',
+ 'p7m': 'application/pkcs7-mime',
+ 'p7r': 'application/x-pkcs7-certreqresp',
+ 'p7s': 'application/pkcs7-signature',
+ 'p8': 'application/pkcs8',
+ 'pas': 'text/x-pascal',
+ 'paw': 'application/vnd.pawaafile',
+ 'pbd': 'application/vnd.powerbuilder6',
+ 'pbm': 'image/x-portable-bitmap',
+ 'pcap': 'application/vnd.tcpdump.pcap',
+ 'pcf': 'application/x-font-pcf',
+ 'pcl': 'application/vnd.hp-pcl',
+ 'pclxl': 'application/vnd.hp-pclxl',
+ 'pct': 'image/x-pict',
+ 'pcurl': 'application/vnd.curl.pcurl',
+ 'pcx': 'image/x-pcx',
+ 'pdb': 'application/vnd.palm',
+ 'pdf': 'application/pdf',
+ 'pfa': 'application/x-font-type1',
+ 'pfb': 'application/x-font-type1',
+ 'pfm': 'application/x-font-type1',
+ 'pfr': 'application/font-tdpfr',
+ 'pfx': 'application/x-pkcs12',
+ 'pgm': 'image/x-portable-graymap',
+ 'pgn': 'application/x-chess-pgn',
+ 'pgp': 'application/pgp-encrypted',
+ 'pic': 'image/x-pict',
+ 'pkg': 'application/octet-stream',
+ 'pki': 'application/pkixcmp',
+ 'pkipath': 'application/pkix-pkipath',
+ 'plb': 'application/vnd.3gpp.pic-bw-large',
+ 'plc': 'application/vnd.mobius.plc',
+ 'plf': 'application/vnd.pocketlearn',
+ 'pls': 'application/pls+xml',
+ 'pml': 'application/vnd.ctc-posml',
+ 'png': 'image/png',
+ 'pnm': 'image/x-portable-anymap',
+ 'portpkg': 'application/vnd.macports.portpkg',
+ 'pot': 'application/vnd.ms-powerpoint',
+ 'potm': 'application/vnd.ms-powerpoint.template.macroenabled.12',
+ 'potx':
+ 'application/vnd.openxmlformats-officedocument.presentationml.template',
+ 'ppam': 'application/vnd.ms-powerpoint.addin.macroenabled.12',
+ 'ppd': 'application/vnd.cups-ppd',
+ 'ppm': 'image/x-portable-pixmap',
+ 'pps': 'application/vnd.ms-powerpoint',
+ 'ppsm': 'application/vnd.ms-powerpoint.slideshow.macroenabled.12',
+ 'ppsx':
+ 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
+ 'ppt': 'application/vnd.ms-powerpoint',
+ 'pptm': 'application/vnd.ms-powerpoint.presentation.macroenabled.12',
+ 'pptx':
+ 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
+ 'pqa': 'application/vnd.palm',
+ 'prc': 'application/x-mobipocket-ebook',
+ 'pre': 'application/vnd.lotus-freelance',
+ 'prf': 'application/pics-rules',
+ 'ps': 'application/postscript',
+ 'psb': 'application/vnd.3gpp.pic-bw-small',
+ 'psd': 'image/vnd.adobe.photoshop',
+ 'psf': 'application/x-font-linux-psf',
+ 'pskcxml': 'application/pskc+xml',
+ 'ptid': 'application/vnd.pvi.ptid1',
+ 'pub': 'application/x-mspublisher',
+ 'pvb': 'application/vnd.3gpp.pic-bw-var',
+ 'pwn': 'application/vnd.3m.post-it-notes',
+ 'pya': 'audio/vnd.ms-playready.media.pya',
+ 'pyv': 'video/vnd.ms-playready.media.pyv',
+ 'qam': 'application/vnd.epson.quickanime',
+ 'qbo': 'application/vnd.intu.qbo',
+ 'qfx': 'application/vnd.intu.qfx',
+ 'qps': 'application/vnd.publishare-delta-tree',
+ 'qt': 'video/quicktime',
+ 'qwd': 'application/vnd.quark.quarkxpress',
+ 'qwt': 'application/vnd.quark.quarkxpress',
+ 'qxb': 'application/vnd.quark.quarkxpress',
+ 'qxd': 'application/vnd.quark.quarkxpress',
+ 'qxl': 'application/vnd.quark.quarkxpress',
+ 'qxt': 'application/vnd.quark.quarkxpress',
+ 'ra': 'audio/x-pn-realaudio',
+ 'ram': 'audio/x-pn-realaudio',
+ 'rar': 'application/x-rar-compressed',
+ 'ras': 'image/x-cmu-raster',
+ 'rcprofile': 'application/vnd.ipunplugged.rcprofile',
+ 'rdf': 'application/rdf+xml',
+ 'rdz': 'application/vnd.data-vision.rdz',
+ 'rep': 'application/vnd.businessobjects',
+ 'res': 'application/x-dtbresource+xml',
+ 'rgb': 'image/x-rgb',
+ 'rif': 'application/reginfo+xml',
+ 'rip': 'audio/vnd.rip',
+ 'ris': 'application/x-research-info-systems',
+ 'rl': 'application/resource-lists+xml',
+ 'rlc': 'image/vnd.fujixerox.edmics-rlc',
+ 'rld': 'application/resource-lists-diff+xml',
+ 'rm': 'application/vnd.rn-realmedia',
+ 'rmi': 'audio/midi',
+ 'rmp': 'audio/x-pn-realaudio-plugin',
+ 'rms': 'application/vnd.jcp.javame.midlet-rms',
+ 'rmvb': 'application/vnd.rn-realmedia-vbr',
+ 'rnc': 'application/relax-ng-compact-syntax',
+ 'roa': 'application/rpki-roa',
+ 'roff': 'text/troff',
+ 'rp9': 'application/vnd.cloanto.rp9',
+ 'rpss': 'application/vnd.nokia.radio-presets',
+ 'rpst': 'application/vnd.nokia.radio-preset',
+ 'rq': 'application/sparql-query',
+ 'rs': 'application/rls-services+xml',
+ 'rsd': 'application/rsd+xml',
+ 'rss': 'application/rss+xml',
+ 'rtf': 'application/rtf',
+ 'rtx': 'text/richtext',
+ 's': 'text/x-asm',
+ 's3m': 'audio/s3m',
+ 'saf': 'application/vnd.yamaha.smaf-audio',
+ 'sbml': 'application/sbml+xml',
+ 'sc': 'application/vnd.ibm.secure-container',
+ 'scd': 'application/x-msschedule',
+ 'scm': 'application/vnd.lotus-screencam',
+ 'scq': 'application/scvp-cv-request',
+ 'scs': 'application/scvp-cv-response',
+ 'scurl': 'text/vnd.curl.scurl',
+ 'sda': 'application/vnd.stardivision.draw',
+ 'sdc': 'application/vnd.stardivision.calc',
+ 'sdd': 'application/vnd.stardivision.impress',
+ 'sdkd': 'application/vnd.solent.sdkm+xml',
+ 'sdkm': 'application/vnd.solent.sdkm+xml',
+ 'sdp': 'application/sdp',
+ 'sdw': 'application/vnd.stardivision.writer',
+ 'see': 'application/vnd.seemail',
+ 'seed': 'application/vnd.fdsn.seed',
+ 'sema': 'application/vnd.sema',
+ 'semd': 'application/vnd.semd',
+ 'semf': 'application/vnd.semf',
+ 'ser': 'application/java-serialized-object',
+ 'setpay': 'application/set-payment-initiation',
+ 'setreg': 'application/set-registration-initiation',
+ 'sfd-hdstx': 'application/vnd.hydrostatix.sof-data',
+ 'sfs': 'application/vnd.spotfire.sfs',
+ 'sfv': 'text/x-sfv',
+ 'sgi': 'image/sgi',
+ 'sgl': 'application/vnd.stardivision.writer-global',
+ 'sgm': 'text/sgml',
+ 'sgml': 'text/sgml',
+ 'sh': 'application/x-sh',
+ 'shar': 'application/x-shar',
+ 'shf': 'application/shf+xml',
+ 'sid': 'image/x-mrsid-image',
+ 'sig': 'application/pgp-signature',
+ 'sil': 'audio/silk',
+ 'silo': 'model/mesh',
+ 'sis': 'application/vnd.symbian.install',
+ 'sisx': 'application/vnd.symbian.install',
+ 'sit': 'application/x-stuffit',
+ 'sitx': 'application/x-stuffitx',
+ 'skd': 'application/vnd.koan',
+ 'skm': 'application/vnd.koan',
+ 'skp': 'application/vnd.koan',
+ 'skt': 'application/vnd.koan',
+ 'sldm': 'application/vnd.ms-powerpoint.slide.macroenabled.12',
+ 'sldx': 'application/vnd.openxmlformats-officedocument.presentationml.slide',
+ 'slt': 'application/vnd.epson.salt',
+ 'sm': 'application/vnd.stepmania.stepchart',
+ 'smf': 'application/vnd.stardivision.math',
+ 'smi': 'application/smil+xml',
+ 'smil': 'application/smil+xml',
+ 'smv': 'video/x-smv',
+ 'smzip': 'application/vnd.stepmania.package',
+ 'snd': 'audio/basic',
+ 'snf': 'application/x-font-snf',
+ 'so': 'application/octet-stream',
+ 'spc': 'application/x-pkcs7-certificates',
+ 'spf': 'application/vnd.yamaha.smaf-phrase',
+ 'spl': 'application/x-futuresplash',
+ 'spot': 'text/vnd.in3d.spot',
+ 'spp': 'application/scvp-vp-response',
+ 'spq': 'application/scvp-vp-request',
+ 'spx': 'audio/ogg',
+ 'sql': 'application/x-sql',
+ 'src': 'application/x-wais-source',
+ 'srt': 'application/x-subrip',
+ 'sru': 'application/sru+xml',
+ 'srx': 'application/sparql-results+xml',
+ 'ssdl': 'application/ssdl+xml',
+ 'sse': 'application/vnd.kodak-descriptor',
+ 'ssf': 'application/vnd.epson.ssf',
+ 'ssml': 'application/ssml+xml',
+ 'st': 'application/vnd.sailingtracker.track',
+ 'stc': 'application/vnd.sun.xml.calc.template',
+ 'std': 'application/vnd.sun.xml.draw.template',
+ 'stf': 'application/vnd.wt.stf',
+ 'sti': 'application/vnd.sun.xml.impress.template',
+ 'stk': 'application/hyperstudio',
+ 'stl': 'application/vnd.ms-pki.stl',
+ 'str': 'application/vnd.pg.format',
+ 'stw': 'application/vnd.sun.xml.writer.template',
+ 'sub': 'text/vnd.dvb.subtitle',
+ 'sus': 'application/vnd.sus-calendar',
+ 'susp': 'application/vnd.sus-calendar',
+ 'sv4cpio': 'application/x-sv4cpio',
+ 'sv4crc': 'application/x-sv4crc',
+ 'svc': 'application/vnd.dvb.service',
+ 'svd': 'application/vnd.svd',
+ 'svg': 'image/svg+xml',
+ 'svgz': 'image/svg+xml',
+ 'swa': 'application/x-director',
+ 'swf': 'application/x-shockwave-flash',
+ 'swi': 'application/vnd.aristanetworks.swi',
+ 'sxc': 'application/vnd.sun.xml.calc',
+ 'sxd': 'application/vnd.sun.xml.draw',
+ 'sxg': 'application/vnd.sun.xml.writer.global',
+ 'sxi': 'application/vnd.sun.xml.impress',
+ 'sxm': 'application/vnd.sun.xml.math',
+ 'sxw': 'application/vnd.sun.xml.writer',
+ 't': 'text/troff',
+ 't3': 'application/x-t3vm-image',
+ 'taglet': 'application/vnd.mynfc',
+ 'tao': 'application/vnd.tao.intent-module-archive',
+ 'tar': 'application/x-tar',
+ 'tcap': 'application/vnd.3gpp2.tcap',
+ 'tcl': 'application/x-tcl',
+ 'teacher': 'application/vnd.smart.teacher',
+ 'tei': 'application/tei+xml',
+ 'teicorpus': 'application/tei+xml',
+ 'tex': 'application/x-tex',
+ 'texi': 'application/x-texinfo',
+ 'texinfo': 'application/x-texinfo',
+ 'text': 'text/plain',
+ 'tfi': 'application/thraud+xml',
+ 'tfm': 'application/x-tex-tfm',
+ 'tga': 'image/x-tga',
+ 'thmx': 'application/vnd.ms-officetheme',
+ 'tif': 'image/tiff',
+ 'tiff': 'image/tiff',
+ 'tmo': 'application/vnd.tmobile-livetv',
+ // Source: https://toml.io/en/v1.0.0#mime-type
+ 'toml': 'application/toml',
+ 'torrent': 'application/x-bittorrent',
+ 'tpl': 'application/vnd.groove-tool-template',
+ 'tpt': 'application/vnd.trid.tpt',
+ 'tr': 'text/troff',
+ 'tra': 'application/vnd.trueapp',
+ 'trm': 'application/x-msterminal',
+ 'tsd': 'application/timestamped-data',
+ 'tsv': 'text/tab-separated-values',
+ 'ttc': 'application/x-font-ttf',
+ 'ttf': 'application/x-font-ttf',
+ 'ttl': 'text/turtle',
+ 'twd': 'application/vnd.simtech-mindmapper',
+ 'twds': 'application/vnd.simtech-mindmapper',
+ 'txd': 'application/vnd.genomatix.tuxedo',
+ 'txf': 'application/vnd.mobius.txf',
+ 'txt': 'text/plain',
+ 'u32': 'application/x-authorware-bin',
+ 'udeb': 'application/x-debian-package',
+ 'ufd': 'application/vnd.ufdl',
+ 'ufdl': 'application/vnd.ufdl',
+ 'ulx': 'application/x-glulx',
+ 'umj': 'application/vnd.umajin',
+ 'unityweb': 'application/vnd.unity',
+ 'uoml': 'application/vnd.uoml+xml',
+ 'uri': 'text/uri-list',
+ 'uris': 'text/uri-list',
+ 'urls': 'text/uri-list',
+ 'ustar': 'application/x-ustar',
+ 'utz': 'application/vnd.uiq.theme',
+ 'uu': 'text/x-uuencode',
+ 'uva': 'audio/vnd.dece.audio',
+ 'uvd': 'application/vnd.dece.data',
+ 'uvf': 'application/vnd.dece.data',
+ 'uvg': 'image/vnd.dece.graphic',
+ 'uvh': 'video/vnd.dece.hd',
+ 'uvi': 'image/vnd.dece.graphic',
+ 'uvm': 'video/vnd.dece.mobile',
+ 'uvp': 'video/vnd.dece.pd',
+ 'uvs': 'video/vnd.dece.sd',
+ 'uvt': 'application/vnd.dece.ttml+xml',
+ 'uvu': 'video/vnd.uvvu.mp4',
+ 'uvv': 'video/vnd.dece.video',
+ 'uvva': 'audio/vnd.dece.audio',
+ 'uvvd': 'application/vnd.dece.data',
+ 'uvvf': 'application/vnd.dece.data',
+ 'uvvg': 'image/vnd.dece.graphic',
+ 'uvvh': 'video/vnd.dece.hd',
+ 'uvvi': 'image/vnd.dece.graphic',
+ 'uvvm': 'video/vnd.dece.mobile',
+ 'uvvp': 'video/vnd.dece.pd',
+ 'uvvs': 'video/vnd.dece.sd',
+ 'uvvt': 'application/vnd.dece.ttml+xml',
+ 'uvvu': 'video/vnd.uvvu.mp4',
+ 'uvvv': 'video/vnd.dece.video',
+ 'uvvx': 'application/vnd.dece.unspecified',
+ 'uvvz': 'application/vnd.dece.zip',
+ 'uvx': 'application/vnd.dece.unspecified',
+ 'uvz': 'application/vnd.dece.zip',
+ 'vcard': 'text/vcard',
+ 'vcd': 'application/x-cdlink',
+ 'vcf': 'text/x-vcard',
+ 'vcg': 'application/vnd.groove-vcard',
+ 'vcs': 'text/x-vcalendar',
+ 'vcx': 'application/vnd.vcx',
+ 'vis': 'application/vnd.visionary',
+ 'viv': 'video/vnd.vivo',
+ 'vob': 'video/x-ms-vob',
+ 'vor': 'application/vnd.stardivision.writer',
+ 'vox': 'application/x-authorware-bin',
+ 'vrml': 'model/vrml',
+ 'vsd': 'application/vnd.visio',
+ 'vsf': 'application/vnd.vsf',
+ 'vss': 'application/vnd.visio',
+ 'vst': 'application/vnd.visio',
+ 'vsw': 'application/vnd.visio',
+ 'vtu': 'model/vnd.vtu',
+ 'vxml': 'application/voicexml+xml',
+ 'w3d': 'application/x-director',
+ 'wad': 'application/x-doom',
+ 'wasm': 'application/wasm',
+ 'wav': 'audio/x-wav',
+ 'wax': 'audio/x-ms-wax',
+ 'wbmp': 'image/vnd.wap.wbmp',
+ 'wbs': 'application/vnd.criticaltools.wbs+xml',
+ 'wbxml': 'application/vnd.wap.wbxml',
+ 'wcm': 'application/vnd.ms-works',
+ 'wdb': 'application/vnd.ms-works',
+ 'wdp': 'image/vnd.ms-photo',
+ 'weba': 'audio/webm',
+ 'webm': 'video/webm',
+ // Source: https://w3c.github.io/manifest/#media-type-registration
+ 'webmanifest': 'application/manifest+json',
+ 'webp': 'image/webp',
+ 'wg': 'application/vnd.pmi.widget',
+ 'wgt': 'application/widget',
+ 'wks': 'application/vnd.ms-works',
+ 'wm': 'video/x-ms-wm',
+ 'wma': 'audio/x-ms-wma',
+ 'wmd': 'application/x-ms-wmd',
+ 'wmf': 'application/x-msmetafile',
+ 'wml': 'text/vnd.wap.wml',
+ 'wmlc': 'application/vnd.wap.wmlc',
+ 'wmls': 'text/vnd.wap.wmlscript',
+ 'wmlsc': 'application/vnd.wap.wmlscriptc',
+ 'wmv': 'video/x-ms-wmv',
+ 'wmx': 'video/x-ms-wmx',
+ 'wmz': 'application/x-ms-wmz',
+ 'woff': 'application/x-font-woff',
+ 'woff2': 'font/woff2',
+ 'wpd': 'application/vnd.wordperfect',
+ 'wpl': 'application/vnd.ms-wpl',
+ 'wps': 'application/vnd.ms-works',
+ 'wqd': 'application/vnd.wqd',
+ 'wri': 'application/x-mswrite',
+ 'wrl': 'model/vrml',
+ 'wsdl': 'application/wsdl+xml',
+ 'wspolicy': 'application/wspolicy+xml',
+ 'wtb': 'application/vnd.webturbo',
+ 'wvx': 'video/x-ms-wvx',
+ 'x32': 'application/x-authorware-bin',
+ 'x3d': 'model/x3d+xml',
+ 'x3db': 'model/x3d+binary',
+ 'x3dbz': 'model/x3d+binary',
+ 'x3dv': 'model/x3d+vrml',
+ 'x3dvz': 'model/x3d+vrml',
+ 'x3dz': 'model/x3d+xml',
+ 'xaml': 'application/xaml+xml',
+ 'xap': 'application/x-silverlight-app',
+ 'xar': 'application/vnd.xara',
+ 'xbap': 'application/x-ms-xbap',
+ 'xbd': 'application/vnd.fujixerox.docuworks.binder',
+ 'xbm': 'image/x-xbitmap',
+ 'xdf': 'application/xcap-diff+xml',
+ 'xdm': 'application/vnd.syncml.dm+xml',
+ 'xdp': 'application/vnd.adobe.xdp+xml',
+ 'xdssc': 'application/dssc+xml',
+ 'xdw': 'application/vnd.fujixerox.docuworks',
+ 'xenc': 'application/xenc+xml',
+ 'xer': 'application/patch-ops-error+xml',
+ 'xfdf': 'application/vnd.adobe.xfdf',
+ 'xfdl': 'application/vnd.xfdl',
+ 'xht': 'application/xhtml+xml',
+ 'xhtml': 'application/xhtml+xml',
+ 'xhvml': 'application/xv+xml',
+ 'xif': 'image/vnd.xiff',
+ 'xla': 'application/vnd.ms-excel',
+ 'xlam': 'application/vnd.ms-excel.addin.macroenabled.12',
+ 'xlc': 'application/vnd.ms-excel',
+ 'xlf': 'application/x-xliff+xml',
+ 'xlm': 'application/vnd.ms-excel',
+ 'xls': 'application/vnd.ms-excel',
+ 'xlsb': 'application/vnd.ms-excel.sheet.binary.macroenabled.12',
+ 'xlsm': 'application/vnd.ms-excel.sheet.macroenabled.12',
+ 'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+ 'xlt': 'application/vnd.ms-excel',
+ 'xltm': 'application/vnd.ms-excel.template.macroenabled.12',
+ 'xltx':
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
+ 'xlw': 'application/vnd.ms-excel',
+ 'xm': 'audio/xm',
+ 'xml': 'application/xml',
+ 'xo': 'application/vnd.olpc-sugar',
+ 'xop': 'application/xop+xml',
+ 'xpi': 'application/x-xpinstall',
+ 'xpl': 'application/xproc+xml',
+ 'xpm': 'image/x-xpixmap',
+ 'xpr': 'application/vnd.is-xpr',
+ 'xps': 'application/vnd.ms-xpsdocument',
+ 'xpw': 'application/vnd.intercon.formnet',
+ 'xpx': 'application/vnd.intercon.formnet',
+ 'xsl': 'application/xml',
+ 'xslt': 'application/xslt+xml',
+ 'xsm': 'application/vnd.syncml+xml',
+ 'xspf': 'application/xspf+xml',
+ 'xul': 'application/vnd.mozilla.xul+xml',
+ 'xvm': 'application/xv+xml',
+ 'xvml': 'application/xv+xml',
+ 'xwd': 'image/x-xwindowdump',
+ 'xyz': 'chemical/x-xyz',
+ 'xz': 'application/x-xz',
+ 'yang': 'application/yang',
+ 'yin': 'application/yin+xml',
+ 'z1': 'application/x-zmachine',
+ 'z2': 'application/x-zmachine',
+ 'z3': 'application/x-zmachine',
+ 'z4': 'application/x-zmachine',
+ 'z5': 'application/x-zmachine',
+ 'z6': 'application/x-zmachine',
+ 'z7': 'application/x-zmachine',
+ 'z8': 'application/x-zmachine',
+ 'zaz': 'application/vnd.zzazz.deck+xml',
+ 'zip': 'application/zip',
+ 'zir': 'application/vnd.zul',
+ 'zirz': 'application/vnd.zul',
+ 'zmm': 'application/vnd.handheld-entertainment+xml',
+};
diff --git a/pkgs/mime/lib/src/extension.dart b/pkgs/mime/lib/src/extension.dart
new file mode 100644
index 0000000..293449a
--- /dev/null
+++ b/pkgs/mime/lib/src/extension.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2023, 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 'default_extension_map.dart';
+
+/// Default extension for recognized MIME types.
+///
+/// Is the inverse of [defaultExtensionMap], and where that
+/// map has multiple extensions which map to the same
+/// MIME type, this map maps that MIME type to a *default*
+/// extension.
+///
+/// Used by [extensionFromMime].
+final Map<String, String> _defaultMimeTypeMap = {
+ for (var entry in defaultExtensionMap.entries) entry.value: entry.key,
+ 'application/msword': 'doc',
+ 'application/vnd.ms-excel': 'xls',
+ 'application/vnd.ms-powerpoint': 'ppt',
+ 'application/x-debian-package': 'deb',
+ 'application/xhtml+xml': 'xhtml',
+ 'application/xml': 'xml',
+ 'audio/x-aiff': 'aif',
+ 'audio/midi': 'mid',
+ 'audio/mp4': 'm4a',
+ 'audio/ogg': 'ogg',
+ 'image/jpeg': 'jpg',
+ 'image/tiff': 'tif',
+ 'image/svg+xml': 'svg',
+ 'model/vrml': 'vrml',
+ 'text/calendar': 'ics',
+ 'text/html': 'html',
+ 'text/javascript': 'js',
+ 'text/markdown': 'md',
+ 'text/plain': 'txt',
+ 'text/sgml': 'sgml',
+ 'text/x-asm': 'asm',
+ 'text/x-c': 'c',
+ 'text/x-pascal': 'pas',
+ 'video/mp4': 'mp4',
+ 'video/mpeg': 'mpg',
+ 'video/quicktime': 'mov',
+ 'video/x-matroska': 'mkv',
+};
+
+/// The default file extension for a given MIME type.
+///
+/// If [mimeType] has multiple associated extensions,
+/// the returned string is one of those, chosen as the default
+/// extension for that MIME type.
+///
+/// Returns `null` if [mimeType] is not a recognized and
+/// supported MIME type.
+String? extensionFromMime(String mimeType) =>
+ _defaultMimeTypeMap[mimeType.toLowerCase()];
diff --git a/pkgs/mime/lib/src/magic_number.dart b/pkgs/mime/lib/src/magic_number.dart
new file mode 100644
index 0000000..c8b5c3b
--- /dev/null
+++ b/pkgs/mime/lib/src/magic_number.dart
@@ -0,0 +1,407 @@
+// Copyright (c) 2013, 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 MagicNumber {
+ final String mimeType;
+ final List<int> numbers;
+ final List<int>? mask;
+
+ const MagicNumber(this.mimeType, this.numbers, {this.mask});
+
+ bool matches(List<int> header) {
+ if (header.length < numbers.length) return false;
+
+ for (var i = 0; i < numbers.length; i++) {
+ if (mask != null) {
+ if ((mask![i] & numbers[i]) != (mask![i] & header[i])) return false;
+ } else {
+ if (numbers[i] != header[i]) return false;
+ }
+ }
+
+ return true;
+ }
+}
+
+const int initialMagicNumbersMaxLength = 12;
+
+const List<MagicNumber> initialMagicNumbers = [
+ MagicNumber('application/pdf', [0x25, 0x50, 0x44, 0x46]),
+ MagicNumber('application/postscript', [0x25, 0x51]),
+
+ /// AIFF is based on the EA IFF 85 Standard for Interchange Format Files.
+ /// -> 4 bytes have the ASCII characters 'F' 'O' 'R' 'M'.
+ /// -> 4 bytes indicating the size of the file
+ /// -> 4 bytes have the ASCII characters 'A' 'I' 'F' 'F'.
+ /// http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/AIFF/Docs/AIFF-1.3.pdf
+ MagicNumber('audio/x-aiff', [
+ 0x46,
+ 0x4F,
+ 0x52,
+ 0x4D,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x41,
+ 0x49,
+ 0x46,
+ 0x46
+ ], mask: [
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF
+ ]),
+
+ /// -> 4 bytes have the ASCII characters 'f' 'L' 'a' 'C'.
+ /// https://xiph.org/flac/format.html
+ MagicNumber('audio/x-flac', [0x66, 0x4C, 0x61, 0x43]),
+
+ /// The WAVE file format is based on the RIFF document format.
+ /// -> 4 bytes have the ASCII characters 'R' 'I' 'F' 'F'.
+ /// -> 4 bytes indicating the size of the file
+ /// -> 4 bytes have the ASCII characters 'W' 'A' 'V' 'E'.
+ /// http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Docs/riffmci.pdf
+ MagicNumber('audio/x-wav', [
+ 0x52,
+ 0x49,
+ 0x46,
+ 0x46,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x57,
+ 0x41,
+ 0x56,
+ 0x45
+ ], mask: [
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF
+ ]),
+ MagicNumber('image/gif', [0x47, 0x49, 0x46, 0x38, 0x37, 0x61]),
+ MagicNumber('image/gif', [0x47, 0x49, 0x46, 0x38, 0x39, 0x61]),
+ MagicNumber('image/jpeg', [0xFF, 0xD8]),
+ MagicNumber('image/png', [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]),
+ MagicNumber('image/tiff', [0x49, 0x49, 0x2A, 0x00]),
+ MagicNumber('image/tiff', [0x4D, 0x4D, 0x00, 0x2A]),
+ MagicNumber('audio/aac', [0xFF, 0xF1]),
+ MagicNumber('audio/aac', [0xFF, 0xF9]),
+ MagicNumber('audio/weba', [0x1A, 0x45, 0xDF, 0xA3]),
+ MagicNumber('audio/mpeg', [0x49, 0x44, 0x33]),
+ MagicNumber('audio/mpeg', [0xFF, 0xFB]),
+ MagicNumber('audio/ogg', [0x4F, 0x70, 0x75]),
+ MagicNumber('video/3gpp', [
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x66,
+ 0x74,
+ 0x79,
+ 0x70,
+ 0x33,
+ 0x67,
+ 0x70,
+ 0x35
+ ], mask: [
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0x00,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF
+ ]),
+ MagicNumber('video/mp4', [
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x66,
+ 0x74,
+ 0x79,
+ 0x70,
+ 0x61,
+ 0x76,
+ 0x63,
+ 0x31
+ ], mask: [
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF
+ ]),
+ MagicNumber('video/mp4', [
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x66,
+ 0x74,
+ 0x79,
+ 0x70,
+ 0x69,
+ 0x73,
+ 0x6F,
+ 0x32
+ ], mask: [
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF
+ ]),
+ MagicNumber('video/mp4', [
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x66,
+ 0x74,
+ 0x79,
+ 0x70,
+ 0x69,
+ 0x73,
+ 0x6F,
+ 0x6D
+ ], mask: [
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF
+ ]),
+ MagicNumber('video/mp4', [
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x66,
+ 0x74,
+ 0x79,
+ 0x70,
+ 0x6D,
+ 0x70,
+ 0x34,
+ 0x31
+ ], mask: [
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF
+ ]),
+ MagicNumber('video/mp4', [
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x66,
+ 0x74,
+ 0x79,
+ 0x70,
+ 0x6D,
+ 0x70,
+ 0x34,
+ 0x32
+ ], mask: [
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF
+ ]),
+ MagicNumber('model/gltf-binary', [0x46, 0x54, 0x6C, 0x67]),
+
+ /// The WebP file format is based on the RIFF document format.
+ /// -> 4 bytes have the ASCII characters 'R' 'I' 'F' 'F'.
+ /// -> 4 bytes indicating the size of the file
+ /// -> 4 bytes have the ASCII characters 'W' 'E' 'B' 'P'.
+ /// https://developers.google.com/speed/webp/docs/riff_container
+ MagicNumber('image/webp', [
+ 0x52,
+ 0x49,
+ 0x46,
+ 0x46,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x57,
+ 0x45,
+ 0x42,
+ 0x50
+ ], mask: [
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF
+ ]),
+
+ MagicNumber('font/woff2', [0x77, 0x4f, 0x46, 0x32]),
+
+ /// High Efficiency Image File Format (ISO/IEC 23008-12).
+ /// -> 4 bytes indicating the ftyp box length.
+ /// -> 4 bytes have the ASCII characters 'f' 't' 'y' 'p'.
+ /// -> 4 bytes have the ASCII characters 'h' 'e' 'i' 'c'.
+ /// https://www.iana.org/assignments/media-types/image/heic
+ MagicNumber('image/heic', [
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x66,
+ 0x74,
+ 0x79,
+ 0x70,
+ 0x68,
+ 0x65,
+ 0x69,
+ 0x63
+ ], mask: [
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF
+ ]),
+
+ /// -> 4 bytes indicating the ftyp box length.
+ /// -> 4 bytes have the ASCII characters 'f' 't' 'y' 'p'.
+ /// -> 4 bytes have the ASCII characters 'h' 'e' 'i' 'x'.
+ MagicNumber('image/heic', [
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x66,
+ 0x74,
+ 0x79,
+ 0x70,
+ 0x68,
+ 0x65,
+ 0x69,
+ 0x78
+ ], mask: [
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF
+ ]),
+
+ /// -> 4 bytes indicating the ftyp box length.
+ /// -> 4 bytes have the ASCII characters 'f' 't' 'y' 'p'.
+ /// -> 4 bytes have the ASCII characters 'm' 'i' 'f' '1'.
+ MagicNumber('image/heif', [
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x66,
+ 0x74,
+ 0x79,
+ 0x70,
+ 0x6D,
+ 0x69,
+ 0x66,
+ 0x31
+ ], mask: [
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF
+ ]),
+];
diff --git a/pkgs/mime/lib/src/mime_multipart_transformer.dart b/pkgs/mime/lib/src/mime_multipart_transformer.dart
new file mode 100644
index 0000000..2648d7d
--- /dev/null
+++ b/pkgs/mime/lib/src/mime_multipart_transformer.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:typed_data';
+
+import 'bound_multipart_stream.dart';
+import 'char_code.dart' as char_code;
+import 'mime_shared.dart';
+
+Uint8List _getBoundary(String boundary) {
+ final charCodes = boundary.codeUnits;
+
+ final boundaryList = Uint8List(4 + charCodes.length);
+ // Set-up the matching boundary preceding it with CRLF and two
+ // dashes.
+ boundaryList[0] = char_code.cr;
+ boundaryList[1] = char_code.lf;
+ boundaryList[2] = char_code.dash;
+ boundaryList[3] = char_code.dash;
+ boundaryList.setRange(4, 4 + charCodes.length, charCodes);
+ return boundaryList;
+}
+
+/// Parser for MIME multipart types of data as described in RFC 2046
+/// section 5.1.1. The data is transformed into [MimeMultipart] objects, each
+/// of them streaming the multipart data.
+class MimeMultipartTransformer
+ extends StreamTransformerBase<List<int>, MimeMultipart> {
+ final List<int> _boundary;
+
+ /// Construct a new MIME multipart parser with the boundary
+ /// [boundary]. The boundary should be as specified in the content
+ /// type parameter, that is without the -- prefix.
+ MimeMultipartTransformer(String boundary)
+ : _boundary = _getBoundary(boundary);
+
+ @override
+ Stream<MimeMultipart> bind(Stream<List<int>> stream) =>
+ BoundMultipartStream(_boundary, stream).stream;
+}
diff --git a/pkgs/mime/lib/src/mime_shared.dart b/pkgs/mime/lib/src/mime_shared.dart
new file mode 100644
index 0000000..1c98971
--- /dev/null
+++ b/pkgs/mime/lib/src/mime_shared.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'mime_multipart_transformer.dart';
+
+class MimeMultipartException implements Exception {
+ final String message;
+
+ const MimeMultipartException([this.message = '']);
+
+ @override
+ String toString() => 'MimeMultipartException: $message';
+}
+
+/// A Mime Multipart class representing each part parsed by
+/// [MimeMultipartTransformer]. The data is streamed in as it become available.
+abstract class MimeMultipart extends Stream<List<int>> {
+ Map<String, String> get headers;
+}
diff --git a/pkgs/mime/lib/src/mime_type.dart b/pkgs/mime/lib/src/mime_type.dart
new file mode 100644
index 0000000..9cf9194
--- /dev/null
+++ b/pkgs/mime/lib/src/mime_type.dart
@@ -0,0 +1,109 @@
+// Copyright (c) 2013, 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 'default_extension_map.dart';
+import 'magic_number.dart';
+
+final MimeTypeResolver _globalResolver = MimeTypeResolver();
+
+/// The maximum number of bytes needed, to match all default magic-numbers.
+int get defaultMagicNumbersMaxLength => _globalResolver.magicNumbersMaxLength;
+
+/// Extract the extension from [path] and use that for MIME-type lookup, using
+/// the default extension map.
+///
+/// If no matching MIME-type was found, `null` is returned.
+///
+/// If [headerBytes] is present, a match for known magic-numbers will be
+/// performed first. This allows the correct mime-type to be found, even though
+/// a file have been saved using the wrong file-name extension. If less than
+/// [defaultMagicNumbersMaxLength] bytes was provided, some magic-numbers won't
+/// be matched against.
+String? lookupMimeType(String path, {List<int>? headerBytes}) =>
+ _globalResolver.lookup(path, headerBytes: headerBytes);
+
+/// MIME-type resolver class, used to customize the lookup of mime-types.
+class MimeTypeResolver {
+ final Map<String, String> _extensionMap = {};
+ final List<MagicNumber> _magicNumbers = [];
+ final bool _useDefault;
+ int _magicNumbersMaxLength;
+
+ /// Create a new empty [MimeTypeResolver].
+ MimeTypeResolver.empty()
+ : _useDefault = false,
+ _magicNumbersMaxLength = 0;
+
+ /// Create a new [MimeTypeResolver] containing the default scope.
+ MimeTypeResolver()
+ : _useDefault = true,
+ _magicNumbersMaxLength = initialMagicNumbersMaxLength;
+
+ /// Get the maximum number of bytes required to match all magic numbers, when
+ /// performing [lookup] with headerBytes present.
+ int get magicNumbersMaxLength => _magicNumbersMaxLength;
+
+ /// Extract the extension from [path] and use that for MIME-type lookup.
+ ///
+ /// If no matching MIME-type was found, `null` is returned.
+ ///
+ /// If [headerBytes] is present, a match for known magic-numbers will be
+ /// performed first. This allows the correct mime-type to be found, even
+ /// though a file have been saved using the wrong file-name extension. If less
+ /// than [magicNumbersMaxLength] bytes was provided, some magic-numbers won't
+ /// be matched against.
+ String? lookup(String path, {List<int>? headerBytes}) {
+ String? result;
+ if (headerBytes != null) {
+ result = _matchMagic(headerBytes, _magicNumbers);
+ if (result != null) return result;
+ if (_useDefault) {
+ result = _matchMagic(headerBytes, initialMagicNumbers);
+ if (result != null) return result;
+ }
+ }
+ final ext = _ext(path);
+ result = _extensionMap[ext];
+ if (result != null) return result;
+ if (_useDefault) {
+ result = defaultExtensionMap[ext];
+ if (result != null) return result;
+ }
+ return null;
+ }
+
+ /// Add a new MIME-type mapping to the [MimeTypeResolver]. If the [extension]
+ /// is already present in the [MimeTypeResolver], it'll be overwritten.
+ void addExtension(String extension, String mimeType) {
+ _extensionMap[extension] = mimeType;
+ }
+
+ /// Add a new magic-number mapping to the [MimeTypeResolver].
+ ///
+ /// If [mask] is present,the [mask] is used to only perform matching on
+ /// selective bits. The [mask] must have the same length as [bytes].
+ void addMagicNumber(List<int> bytes, String mimeType, {List<int>? mask}) {
+ if (mask != null && bytes.length != mask.length) {
+ throw ArgumentError('Bytes and mask are of different lengths');
+ }
+ if (bytes.length > _magicNumbersMaxLength) {
+ _magicNumbersMaxLength = bytes.length;
+ }
+ _magicNumbers.add(MagicNumber(mimeType, bytes, mask: mask));
+ }
+
+ static String? _matchMagic(
+ List<int> headerBytes, List<MagicNumber> magicNumbers) {
+ for (var mn in magicNumbers) {
+ if (mn.matches(headerBytes)) return mn.mimeType;
+ }
+ return null;
+ }
+
+ static String _ext(String path) {
+ final index = path.lastIndexOf('.');
+ if (index < 0 || index + 1 >= path.length) return path;
+ return path.substring(index + 1).toLowerCase();
+ }
+}
diff --git a/pkgs/mime/pubspec.yaml b/pkgs/mime/pubspec.yaml
new file mode 100644
index 0000000..41b3842
--- /dev/null
+++ b/pkgs/mime/pubspec.yaml
@@ -0,0 +1,18 @@
+name: mime
+version: 2.0.0
+description: >-
+ Utilities for handling media (MIME) types, including determining a type from
+ a file extension and file contents.
+repository: https://github.com/dart-lang/tools/tree/main/pkgs/mime
+topics:
+ - magic-numbers
+ - mime
+ - mimetype
+ - multipart-form
+
+environment:
+ sdk: ^3.2.0
+
+dev_dependencies:
+ dart_flutter_team_lints: ^3.0.0
+ test: ^1.16.0
diff --git a/pkgs/mime/test/default_extension_map_test.dart b/pkgs/mime/test/default_extension_map_test.dart
new file mode 100644
index 0000000..b5539dd
--- /dev/null
+++ b/pkgs/mime/test/default_extension_map_test.dart
@@ -0,0 +1,16 @@
+// 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:mime/src/default_extension_map.dart';
+import 'package:test/test.dart';
+
+void main() {
+ group('defaultExtensionMap', () {
+ test('keys are lowercase', () {
+ for (final key in defaultExtensionMap.keys) {
+ expect(key, equals(key.toLowerCase()));
+ }
+ });
+ });
+}
diff --git a/pkgs/mime/test/extension_test.dart b/pkgs/mime/test/extension_test.dart
new file mode 100644
index 0000000..40dae6d
--- /dev/null
+++ b/pkgs/mime/test/extension_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2023, 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:mime/mime.dart';
+import 'package:test/test.dart';
+
+void main() {
+ test('valid-mime-type', () {
+ expect(extensionFromMime('text/x-dart'), equals('dart'));
+ expect(extensionFromMime('text/javascript'), equals('js'));
+ expect(extensionFromMime('application/java-archive'), equals('jar'));
+ expect(extensionFromMime('application/json'), equals('json'));
+ expect(extensionFromMime('application/pdf'), equals('pdf'));
+ expect(extensionFromMime('application/vnd.ms-excel'), equals('xls'));
+ expect(extensionFromMime('application/xhtml+xml'), equals('xhtml'));
+ expect(extensionFromMime('image/jpeg'), equals('jpg'));
+ expect(extensionFromMime('image/png'), equals('png'));
+ expect(extensionFromMime('text/css'), equals('css'));
+ expect(extensionFromMime('text/html'), equals('html'));
+ expect(extensionFromMime('text/plain'), equals('txt'));
+ expect(extensionFromMime('text/x-c'), equals('c'));
+ });
+
+ test('invalid-mime-type', () {
+ expect(extensionFromMime('invalid-mime-type'), isNull);
+ expect(extensionFromMime('invalid/mime/type'), isNull);
+ });
+
+ test('unknown-mime-type', () {
+ expect(extensionFromMime('application/to-be-invented'), isNull);
+ });
+}
diff --git a/pkgs/mime/test/mime_multipart_transformer_test.dart b/pkgs/mime/test/mime_multipart_transformer_test.dart
new file mode 100644
index 0000000..109a9bc
--- /dev/null
+++ b/pkgs/mime/test/mime_multipart_transformer_test.dart
@@ -0,0 +1,469 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:math';
+
+import 'package:mime/mime.dart';
+import 'package:test/test.dart';
+
+void _writeInChunks(
+ List<int> data, int chunkSize, StreamController<List<int>> controller) {
+ if (chunkSize == -1) chunkSize = data.length;
+
+ for (var pos = 0; pos < data.length; pos += chunkSize) {
+ final remaining = data.length - pos;
+ final writeLength = min(chunkSize, remaining);
+ controller.add(data.sublist(pos, pos + writeLength));
+ }
+ controller.close();
+}
+
+enum TestMode { immediateListen, delayListen, pauseResume }
+
+void _runParseTest(
+ String message,
+ String boundary,
+ TestMode mode, [
+ List<Map<String, String>>? expectedHeaders,
+ List<String?>? expectedParts,
+ bool expectError = false,
+]) {
+ Future<void> testWrite(List<int> data, [int chunkSize = -1]) {
+ final controller = StreamController<List<int>>(sync: true);
+
+ final stream =
+ controller.stream.transform(MimeMultipartTransformer(boundary));
+ var i = 0;
+ final completer = Completer<void>();
+ final futures = <Future<void>>[];
+ stream.listen((multipart) {
+ final part = i++;
+ if (expectedHeaders != null) {
+ expect(multipart.headers, equals(expectedHeaders[part]));
+ }
+ switch (mode) {
+ case TestMode.immediateListen:
+ futures.add(multipart.fold<List<int>>(
+ [], (buffer, data) => buffer..addAll(data)).then((data) {
+ if (expectedParts?[part] != null) {
+ expect(data, equals(expectedParts?[part]!.codeUnits));
+ }
+ }));
+
+ case TestMode.delayListen:
+ futures.add(
+ Future(
+ () => multipart.fold<List<int>>(
+ [],
+ (buffer, data) => buffer..addAll(data),
+ ).then(
+ (data) {
+ if (expectedParts?[part] != null) {
+ expect(data, equals(expectedParts?[part]!.codeUnits));
+ }
+ },
+ ),
+ ),
+ );
+
+ case TestMode.pauseResume:
+ final completer = Completer<void>();
+ futures.add(completer.future);
+ final buffer = <int>[];
+ late StreamSubscription<List<int>> subscription;
+ subscription = multipart.listen((data) {
+ buffer.addAll(data);
+ subscription.pause();
+ Future(() => subscription.resume());
+ }, onDone: () {
+ if (expectedParts?[part] != null) {
+ expect(buffer, equals(expectedParts?[part]!.codeUnits));
+ }
+ completer.complete();
+ });
+ addTearDown(subscription.cancel);
+ }
+ }, onError: (Object error) {
+ // ignore: only_throw_errors
+ if (!expectError) throw error;
+ }, onDone: () {
+ if (expectedParts != null) {
+ expect(i, equals(expectedParts.length));
+ }
+ Future.wait(futures).then(completer.complete);
+ });
+
+ _writeInChunks(data, chunkSize, controller);
+
+ return completer.future;
+ }
+
+ Future<void> testFirstPartOnly(List<int> data, [int chunkSize = -1]) {
+ final completer = Completer<void>();
+ final controller = StreamController<List<int>>(sync: true);
+
+ final stream =
+ controller.stream.transform(MimeMultipartTransformer(boundary));
+
+ stream.first.then((multipart) {
+ if (expectedHeaders != null) {
+ expect(multipart.headers, equals(expectedHeaders[0]));
+ }
+ return multipart.fold<List<int>>([], (b, d) => b..addAll(d)).then(
+ (data) {
+ if (expectedParts != null && expectedParts[0] != null) {
+ expect(data, equals(expectedParts[0]!.codeUnits));
+ }
+ },
+ );
+ }).then((_) {
+ completer.complete();
+ });
+
+ _writeInChunks(data, chunkSize, controller);
+
+ return completer.future;
+ }
+
+ Future<void> testCompletePartAfterCancel(List<int> data, int parts,
+ [int chunkSize = -1]) {
+ final completer = Completer<void>();
+ final controller = StreamController<List<int>>(sync: true);
+ final stream =
+ controller.stream.transform(MimeMultipartTransformer(boundary));
+ late StreamSubscription<void> subscription;
+ var i = 0;
+ final futures = <Future<void>>[];
+ subscription = stream.listen((multipart) {
+ final partIndex = i;
+
+ if (partIndex >= parts) {
+ throw StateError('Expected no more parts, but got one.');
+ }
+
+ if (expectedHeaders != null) {
+ expect(multipart.headers, equals(expectedHeaders[partIndex]));
+ }
+ futures.add(
+ multipart.fold<List<int>>([], (b, d) => b..addAll(d)).then((data) {
+ if (expectedParts != null && expectedParts[partIndex] != null) {
+ expect(data, equals(expectedParts[partIndex]!.codeUnits));
+ }
+ }));
+
+ if (partIndex == (parts - 1)) {
+ subscription.cancel();
+ Future.wait(futures).then(completer.complete);
+ }
+ i++;
+ });
+
+ _writeInChunks(data, chunkSize, controller);
+
+ return completer.future;
+ }
+
+ // Test parsing the data three times delivering the data in
+ // different chunks.
+ final data = message.codeUnits;
+ test('test', () {
+ expect(
+ Future.wait([
+ testWrite(data),
+ testWrite(data, 10),
+ testWrite(data, 2),
+ testWrite(data, 1),
+ ]),
+ completes);
+ });
+
+ if (expectedParts!.isNotEmpty) {
+ test('test-first-part-only', () {
+ expect(
+ Future.wait([
+ testFirstPartOnly(data),
+ testFirstPartOnly(data, 10),
+ testFirstPartOnly(data, 2),
+ testFirstPartOnly(data, 1),
+ ]),
+ completes);
+ });
+
+ test('test-n-parts-only', () {
+ var numPartsExpected = expectedParts.length - 1;
+ if (numPartsExpected == 0) numPartsExpected = 1;
+
+ expect(
+ Future.wait([
+ testCompletePartAfterCancel(data, numPartsExpected),
+ testCompletePartAfterCancel(data, numPartsExpected, 10),
+ testCompletePartAfterCancel(data, numPartsExpected, 2),
+ testCompletePartAfterCancel(data, numPartsExpected, 1),
+ ]),
+ completes);
+ });
+ }
+}
+
+void _testParse(String message, String boundary,
+ [List<Map<String, String>>? expectedHeaders,
+ List<String?>? expectedParts,
+ bool expectError = false]) {
+ _runParseTest(message, boundary, TestMode.immediateListen, expectedHeaders,
+ expectedParts, expectError);
+ _runParseTest(message, boundary, TestMode.delayListen, expectedHeaders,
+ expectedParts, expectError);
+ _runParseTest(message, boundary, TestMode.pauseResume, expectedHeaders,
+ expectedParts, expectError);
+}
+
+void _testParseValid() {
+ // Empty message from Chrome form post.
+ var message = '------WebKitFormBoundaryU3FBruSkJKG0Yor1--\r\n';
+ _testParse(message, '----WebKitFormBoundaryU3FBruSkJKG0Yor1', [], []);
+
+ // Sample from Wikipedia.
+ message = '''
+This is a message with multiple parts in MIME format.\r
+--frontier\r
+Content-Type: text/plain\r
+\r
+This is the body of the message.\r
+--frontier\r
+Content-Type: application/octet-stream\r
+Content-Transfer-Encoding: base64\r
+\r
+PGh0bWw+CiAgPGhlYWQ+CiAgPC9oZWFkPgogIDxib2R5PgogICAgPHA+VGhpcyBpcyB0aGUg
+Ym9keSBvZiB0aGUgbWVzc2FnZS48L3A+CiAgPC9ib2R5Pgo8L2h0bWw+Cg=\r
+--frontier--\r\n''';
+ var headers1 = <String, String>{'content-type': 'text/plain'};
+ var headers2 = <String, String>{
+ 'content-type': 'application/octet-stream',
+ 'content-transfer-encoding': 'base64'
+ };
+ var body1 = 'This is the body of the message.';
+ var body2 = '''
+PGh0bWw+CiAgPGhlYWQ+CiAgPC9oZWFkPgogIDxib2R5PgogICAgPHA+VGhpcyBpcyB0aGUg
+Ym9keSBvZiB0aGUgbWVzc2FnZS48L3A+CiAgPC9ib2R5Pgo8L2h0bWw+Cg=''';
+ _testParse(message, 'frontier', [headers1, headers2], [body1, body2]);
+
+ // Sample from HTML 4.01 Specification.
+ message = '''
+\r\n--AaB03x\r
+Content-Disposition: form-data; name="submit-name"\r
+\r
+Larry\r
+--AaB03x\r
+Content-Disposition: form-data; name="files"; filename="file1.txt"\r
+Content-Type: text/plain\r
+\r
+... contents of file1.txt ...\r
+--AaB03x--\r\n''';
+ headers1 = <String, String>{
+ 'content-disposition': 'form-data; name="submit-name"'
+ };
+ headers2 = <String, String>{
+ 'content-type': 'text/plain',
+ 'content-disposition': 'form-data; name="files"; filename="file1.txt"'
+ };
+ body1 = 'Larry';
+ body2 = '... contents of file1.txt ...';
+ _testParse(message, 'AaB03x', [headers1, headers2], [body1, body2]);
+
+ // Longer form from submitting the following from Chrome.
+ //
+ // <html>
+ // <body>
+ // <FORM action="http://127.0.0.1:1234/"
+ // enctype="multipart/form-data"
+ // method='post'>
+ // <P>
+ // Text: <INPUT type='text' name='text_input'>
+ // Password: <INPUT type='password' name='password_input'>
+ // Checkbox: <INPUT type='checkbox' name='checkbox_input'>
+ // Radio: <INPUT type='radio' name='radio_input'>
+ // Send <INPUT type='submit'>
+ // </P>
+ // </FORM>
+ // </body>
+ // </html>
+
+ message = '''
+\r\n------WebKitFormBoundaryQ3cgYAmGRF8yOeYB\r
+Content-Disposition: form-data; name="text_input"\r
+\r
+text\r
+------WebKitFormBoundaryQ3cgYAmGRF8yOeYB\r
+Content-Disposition: form-data; name="password_input"\r
+\r
+password\r
+------WebKitFormBoundaryQ3cgYAmGRF8yOeYB\r
+Content-Disposition: form-data; name="checkbox_input"\r
+\r
+on\r
+------WebKitFormBoundaryQ3cgYAmGRF8yOeYB\r
+Content-Disposition: form-data; name="radio_input"\r
+\r
+on\r
+------WebKitFormBoundaryQ3cgYAmGRF8yOeYB--\r\n''';
+ headers1 = <String, String>{
+ 'content-disposition': 'form-data; name="text_input"'
+ };
+ headers2 = <String, String>{
+ 'content-disposition': 'form-data; name="password_input"'
+ };
+ final headers3 = <String, String>{
+ 'content-disposition': 'form-data; name="checkbox_input"'
+ };
+ final headers4 = <String, String>{
+ 'content-disposition': 'form-data; name="radio_input"'
+ };
+ body1 = 'text';
+ body2 = 'password';
+ const body3 = 'on';
+ const body4 = 'on';
+ _testParse(message, '----WebKitFormBoundaryQ3cgYAmGRF8yOeYB',
+ [headers1, headers2, headers3, headers4], [body1, body2, body3, body4]);
+
+ // Same form from Firefox.
+ message = '''
+\r\n-----------------------------52284550912143824192005403738\r
+Content-Disposition: form-data; name="text_input"\r
+\r
+text\r
+-----------------------------52284550912143824192005403738\r
+Content-Disposition: form-data; name="password_input"\r
+\r
+password\r
+-----------------------------52284550912143824192005403738\r
+Content-Disposition: form-data; name="checkbox_input"\r
+\r
+on\r
+-----------------------------52284550912143824192005403738\r
+Content-Disposition: form-data; name="radio_input"\r
+\r
+on\r
+-----------------------------52284550912143824192005403738--\r\n''';
+ _testParse(
+ message,
+ '---------------------------52284550912143824192005403738',
+ [headers1, headers2, headers3, headers4],
+ [body1, body2, body3, body4]);
+
+ // And Internet Explorer
+ message = '''
+\r\n-----------------------------7dc8f38c60326\r
+Content-Disposition: form-data; name="text_input"\r
+\r
+text\r
+-----------------------------7dc8f38c60326\r
+Content-Disposition: form-data; name="password_input"\r
+\r
+password\r
+-----------------------------7dc8f38c60326\r
+Content-Disposition: form-data; name="checkbox_input"\r
+\r
+on\r
+-----------------------------7dc8f38c60326\r
+Content-Disposition: form-data; name="radio_input"\r
+\r
+on\r
+-----------------------------7dc8f38c60326--\r\n''';
+ _testParse(message, '---------------------------7dc8f38c60326',
+ [headers1, headers2, headers3, headers4], [body1, body2, body3, body4]);
+
+ // Test boundary prefix inside prefix and content.
+ message = '''
+-\r
+--\r
+--b\r
+--bo\r
+--bou\r
+--boun\r
+--bound\r
+--bounda\r
+--boundar\r
+--boundary\r
+Content-Type: text/plain\r
+\r
+-\r
+--\r
+--b\r
+--bo\r
+--bou\r
+--boun\r
+--bound\r\r
+--bounda\r\r\r
+--boundar\r\r\r\r
+--boundary\r
+Content-Type: text/plain\r
+\r
+--boundar\r
+--bounda\r
+--bound\r
+--boun\r
+--bou\r
+--bo\r
+--b\r\r\r\r
+--\r\r\r
+-\r\r
+--boundary--\r\n''';
+ final headers = <String, String>{'content-type': 'text/plain'};
+ body1 = '''
+-\r
+--\r
+--b\r
+--bo\r
+--bou\r
+--boun\r
+--bound\r\r
+--bounda\r\r\r
+--boundar\r\r\r''';
+ body2 = '''
+--boundar\r
+--bounda\r
+--bound\r
+--boun\r
+--bou\r
+--bo\r
+--b\r\r\r\r
+--\r\r\r
+-\r''';
+ _testParse(message, 'boundary', [headers, headers], [body1, body2]);
+
+ // Without initial CRLF.
+ message = '''
+--xxx\r
+\r
+\r
+Body 1\r
+--xxx\r
+\r
+\r
+Body2\r
+--xxx--\r\n''';
+ _testParse(message, 'xxx', null, ['\r\nBody 1', '\r\nBody2']);
+}
+
+void _testParseInvalid() {
+ // Missing end boundary.
+ const message = '''
+\r
+--xxx\r
+\r
+\r
+Body 1\r
+--xxx\r
+\r
+\r
+Body2\r
+--xxx\r\n''';
+ _testParse(message, 'xxx', null, [null, null], true);
+}
+
+void main() {
+ _testParseValid();
+ _testParseInvalid();
+}
diff --git a/pkgs/mime/test/mime_type_test.dart b/pkgs/mime/test/mime_type_test.dart
new file mode 100644
index 0000000..23cb34a
--- /dev/null
+++ b/pkgs/mime/test/mime_type_test.dart
@@ -0,0 +1,320 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:math' as math;
+
+import 'package:mime/mime.dart';
+import 'package:mime/src/magic_number.dart';
+import 'package:test/test.dart';
+
+void _expectMimeType(String path, String? expectedMimeType,
+ {List<int>? headerBytes, MimeTypeResolver? resolver}) {
+ String? mimeType;
+ if (resolver == null) {
+ mimeType = lookupMimeType(path, headerBytes: headerBytes);
+ } else {
+ mimeType = resolver.lookup(path, headerBytes: headerBytes);
+ }
+
+ expect(mimeType, expectedMimeType);
+}
+
+void main() {
+ group('global-lookup', () {
+ test('by-path', () {
+ _expectMimeType('file.dart', 'text/x-dart');
+ // Test mixed-case
+ _expectMimeType('file.DaRT', 'text/x-dart');
+ _expectMimeType('file.dcm', 'application/dicom');
+ _expectMimeType('file.html', 'text/html');
+ _expectMimeType('file.xhtml', 'application/xhtml+xml');
+ _expectMimeType('file.jpeg', 'image/jpeg');
+ _expectMimeType('file.jpg', 'image/jpeg');
+ _expectMimeType('file.png', 'image/png');
+ _expectMimeType('file.gif', 'image/gif');
+ _expectMimeType('file.cc', 'text/x-c');
+ _expectMimeType('file.c', 'text/x-c');
+ _expectMimeType('file.css', 'text/css');
+ _expectMimeType('file.js', 'text/javascript');
+ _expectMimeType('file.mjs', 'text/javascript');
+ _expectMimeType('file.ps', 'application/postscript');
+ _expectMimeType('file.pdf', 'application/pdf');
+ _expectMimeType('file.tiff', 'image/tiff');
+ _expectMimeType('file.tif', 'image/tiff');
+ _expectMimeType('file.webp', 'image/webp');
+ _expectMimeType('file.mp3', 'audio/mpeg');
+ _expectMimeType('file.aac', 'audio/aac');
+ _expectMimeType('file.ogg', 'audio/ogg');
+ _expectMimeType('file.aiff', 'audio/x-aiff');
+ _expectMimeType('file.m4a', 'audio/mp4');
+ _expectMimeType('file.m4b', 'audio/mp4');
+ _expectMimeType('file.toml', 'application/toml');
+ _expectMimeType('file.md', 'text/markdown');
+ _expectMimeType('file.markdown', 'text/markdown');
+ _expectMimeType('file.heif', 'image/heif');
+ _expectMimeType('file.heic', 'image/heic');
+ });
+
+ test('unknown-mime-type', () {
+ _expectMimeType('file.unsupported-extension', null);
+ });
+
+ test('by-header-bytes', () {
+ _expectMimeType('file.jpg', 'image/png',
+ headerBytes: [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]);
+ _expectMimeType('file.jpg', 'image/gif', headerBytes: [
+ 0x47,
+ 0x49,
+ 0x46,
+ 0x38,
+ 0x39,
+ 0x61,
+ 0x0D,
+ 0x0A,
+ 0x1A,
+ 0x0A
+ ]);
+ _expectMimeType('file.gif', 'image/jpeg', headerBytes: [
+ 0xFF,
+ 0xD8,
+ 0x46,
+ 0x38,
+ 0x39,
+ 0x61,
+ 0x0D,
+ 0x0A,
+ 0x1A,
+ 0x0A
+ ]);
+ _expectMimeType('file', 'video/3gpp', headerBytes: [
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x04,
+ 0x66,
+ 0x74,
+ 0x79,
+ 0x70,
+ 0x33,
+ 0x67,
+ 0x70,
+ 0x35
+ ]);
+ _expectMimeType('file.mp4', 'video/mp4', headerBytes: [
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x04,
+ 0x66,
+ 0x74,
+ 0x79,
+ 0x70,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF
+ ]);
+ _expectMimeType('file', 'video/mp4', headerBytes: [
+ 0x00,
+ 0xF0,
+ 0xF0,
+ 0xF0,
+ 0x66,
+ 0x74,
+ 0x79,
+ 0x70,
+ 0x61,
+ 0x76,
+ 0x63,
+ 0x31
+ ]);
+ _expectMimeType('file', 'video/mp4', headerBytes: [
+ 0x00,
+ 0xF0,
+ 0xF0,
+ 0xF0,
+ 0x66,
+ 0x74,
+ 0x79,
+ 0x70,
+ 0x69,
+ 0x73,
+ 0x6F,
+ 0x32
+ ]);
+ _expectMimeType('file', 'video/mp4', headerBytes: [
+ 0x00,
+ 0xF0,
+ 0xF0,
+ 0xF0,
+ 0x66,
+ 0x74,
+ 0x79,
+ 0x70,
+ 0x69,
+ 0x73,
+ 0x6F,
+ 0x6D
+ ]);
+ _expectMimeType('file', 'video/mp4', headerBytes: [
+ 0x00,
+ 0xF0,
+ 0xF0,
+ 0xF0,
+ 0x66,
+ 0x74,
+ 0x79,
+ 0x70,
+ 0x6D,
+ 0x70,
+ 0x34,
+ 0x31
+ ]);
+ _expectMimeType('file', 'video/mp4', headerBytes: [
+ 0x00,
+ 0xF0,
+ 0xF0,
+ 0xF0,
+ 0x66,
+ 0x74,
+ 0x79,
+ 0x70,
+ 0x6D,
+ 0x70,
+ 0x34,
+ 0x32
+ ]);
+ _expectMimeType('file', 'image/webp', headerBytes: [
+ 0x52,
+ 0x49,
+ 0x46,
+ 0x46,
+ 0xE2,
+ 0x4A,
+ 0x01,
+ 0x00,
+ 0x57,
+ 0x45,
+ 0x42,
+ 0x50
+ ]);
+ _expectMimeType('file', 'audio/mpeg',
+ headerBytes: [0x49, 0x44, 0x33, 0x0D, 0x0A, 0x1A, 0x0A]);
+ _expectMimeType('file', 'audio/aac',
+ headerBytes: [0xFF, 0xF1, 0x0D, 0x0A, 0x1A, 0x0A]);
+ _expectMimeType('file', 'audio/ogg',
+ headerBytes: [0x4F, 0x70, 0x75, 0x0D, 0x0A, 0x1A, 0x0A]);
+ _expectMimeType('file', 'audio/x-aiff', headerBytes: [
+ 0x46,
+ 0x4F,
+ 0x52,
+ 0x4D,
+ 0x04,
+ 0x0B,
+ 0xEF,
+ 0xF4,
+ 0x41,
+ 0x49,
+ 0x46,
+ 0x46
+ ]);
+ _expectMimeType('file', 'audio/x-flac',
+ headerBytes: [0x66, 0x4C, 0x61, 0x43]);
+ _expectMimeType('file', 'audio/x-wav', headerBytes: [
+ 0x52,
+ 0x49,
+ 0x46,
+ 0x46,
+ 0xA6,
+ 0x4E,
+ 0x70,
+ 0x03,
+ 0x57,
+ 0x41,
+ 0x56,
+ 0x45
+ ]);
+ _expectMimeType('file', 'image/heic', headerBytes: [
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x18,
+ 0x66,
+ 0x74,
+ 0x79,
+ 0x70,
+ 0x68,
+ 0x65,
+ 0x69,
+ 0x63,
+ 0x00
+ ]);
+ _expectMimeType('file', 'image/heic', headerBytes: [
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x18,
+ 0x66,
+ 0x74,
+ 0x79,
+ 0x70,
+ 0x68,
+ 0x65,
+ 0x69,
+ 0x78,
+ 0x00
+ ]);
+ _expectMimeType('file', 'image/heif', headerBytes: [
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x18,
+ 0x66,
+ 0x74,
+ 0x79,
+ 0x70,
+ 0x6D,
+ 0x69,
+ 0x66,
+ 0x31,
+ 0x00
+ ]);
+ });
+ });
+
+ group('custom-resolver', () {
+ test('override-extension', () {
+ final resolver = MimeTypeResolver();
+ resolver.addExtension('jpg', 'my-mime-type');
+ _expectMimeType('file.jpg', 'my-mime-type', resolver: resolver);
+ });
+
+ test('fallthrough-extension', () {
+ final resolver = MimeTypeResolver();
+ resolver.addExtension('jpg2', 'my-mime-type');
+ _expectMimeType('file.jpg', 'image/jpeg', resolver: resolver);
+ });
+
+ test('with-mask', () {
+ final resolver = MimeTypeResolver.empty();
+ resolver.addMagicNumber([0x01, 0x02, 0x03], 'my-mime-type',
+ mask: [0x01, 0xFF, 0xFE]);
+ _expectMimeType('file', 'my-mime-type',
+ headerBytes: [0x01, 0x02, 0x03], resolver: resolver);
+ _expectMimeType('file', null,
+ headerBytes: [0x01, 0x03, 0x03], resolver: resolver);
+ _expectMimeType('file', 'my-mime-type',
+ headerBytes: [0xFF, 0x02, 0x02], resolver: resolver);
+ });
+ });
+
+ test('default magic number', () {
+ final actualMaxBytes = initialMagicNumbers.fold<int>(
+ 0,
+ (previous, magic) => math.max(previous, magic.numbers.length),
+ );
+
+ expect(initialMagicNumbersMaxLength, actualMaxBytes);
+ });
+}
diff --git a/pkgs/oauth2/.gitignore b/pkgs/oauth2/.gitignore
new file mode 100644
index 0000000..bbe1007
--- /dev/null
+++ b/pkgs/oauth2/.gitignore
@@ -0,0 +1,16 @@
+# Don’t commit the following directories created by pub.
+.buildlog
+.pub/
+.dart_tool/
+build/
+packages
+.packages
+
+# Or the files created by dart2js.
+*.dart.js
+*.js_
+*.js.deps
+*.js.map
+
+# Include when developing application packages.
+pubspec.lock
\ No newline at end of file
diff --git a/pkgs/oauth2/CHANGELOG.md b/pkgs/oauth2/CHANGELOG.md
new file mode 100644
index 0000000..ff39de3
--- /dev/null
+++ b/pkgs/oauth2/CHANGELOG.md
@@ -0,0 +1,135 @@
+## 2.0.4-wip
+
+* Require Dart 3.4
+
+## 2.0.3
+
+* Require `package:http` v1.0.0
+* Move to `dart-lang/tools`.
+
+## 2.0.2
+
+* Require Dart 3.0.
+* Support `package:http` 1.0.0.
+
+## 2.0.1
+
+* Handle `expires_in` when encoded as string.
+* Populate the pubspec `repository` field.
+* Increase the minimum Dart SDK to `2.17.0`.
+
+## 2.0.0
+
+* Migrate to null safety.
+
+## 1.6.3
+
+* Added optional `codeVerifier` parameter to `AuthorizationCodeGrant` constructor.
+
+## 1.6.1
+
+* Added fix to make sure that credentials are only refreshed once when multiple calls are made.
+
+## 1.6.0
+
+* Added PKCE support to `AuthorizationCodeGrant`.
+
+## 1.5.0
+
+* Added support for `clientCredentialsGrant`.
+
+## 1.4.0
+
+* OpenID's id_token treated.
+
+## 1.3.0
+
+* Added `onCredentialsRefreshed` option when creating `Client` objects.
+
+## 1.2.3
+
+* Support the latest `package:http` release.
+
+## 1.2.2
+
+* Allow the stable 2.0 SDK.
+
+## 1.2.1
+
+* Updated SDK version to 2.0.0-dev.17.0
+
+## 1.2.0
+
+* Add a `getParameter()` parameter to `new AuthorizationCodeGrant()`, `new
+ Credentials()`, and `resourceOwnerPasswordGrant()`. This controls how the
+ authorization server's response is parsed for servers that don't provide the
+ standard JSON response.
+
+## 1.1.1
+
+* `resourceOwnerPasswordGrant()` now properly uses its HTTP client for requests
+ made by the OAuth2 client it returns.
+
+## 1.1.0
+
+* Add a `delimiter` parameter to `new AuthorizationCodeGrant()`, `new
+ Credentials()`, and `resourceOwnerPasswordGrant()`. This controls the
+ delimiter between scopes, which some authorization servers require to be
+ different values than the specified `' '`.
+
+## 1.0.2
+
+* Fix all strong-mode warnings.
+* Support `crypto` 1.0.0.
+* Support `http_parser` 3.0.0.
+
+## 1.0.1
+
+* Support `http_parser` 2.0.0.
+
+## 1.0.0
+
+### Breaking changes
+
+* Requests that use client authentication, such as the
+ `AuthorizationCodeGrant`'s access token request and `Credentials`' refresh
+ request, now use HTTP Basic authentication by default. This form of
+ authentication is strongly recommended by the OAuth 2.0 spec. The new
+ `basicAuth` parameter may be set to `false` to force form-based authentication
+ for servers that require it.
+
+* `new AuthorizationCodeGrant()` now takes `secret` as an optional named
+ argument rather than a required argument. This matches the OAuth 2.0 spec,
+ which says that a client secret is only required for confidential clients.
+
+* `new Client()` and `Credentials.refresh()` now take both `identifier` and
+ `secret` as optional named arguments rather than required arguments. This
+ matches the OAuth 2.0 spec, which says that the server may choose not to
+ require client authentication for some flows.
+
+* `new Credentials()` now takes named arguments rather than optional positional
+ arguments.
+
+### Non-breaking changes
+
+* Added a `resourceOwnerPasswordGrant` method.
+
+* The `scopes` argument to `AuthorizationCodeGrant.getAuthorizationUrl()` and
+ `new Credentials()` and the `newScopes` argument to `Credentials.refresh` now
+ take an `Iterable` rather than just a `List`.
+
+* The `scopes` argument to `AuthorizationCodeGrant.getAuthorizationUrl()` now
+ defaults to `null` rather than `const []`.
+
+# 0.9.3
+
+* Update the `http` dependency.
+
+* Since `http` 0.11.0 now works in non-`dart:io` contexts, `oauth2` does as
+ well.
+
+## 0.9.2
+
+* Expand the dependency on the HTTP package to include 0.10.x.
+
+* Add a README file.
diff --git a/pkgs/oauth2/LICENSE b/pkgs/oauth2/LICENSE
new file mode 100644
index 0000000..162572a
--- /dev/null
+++ b/pkgs/oauth2/LICENSE
@@ -0,0 +1,27 @@
+Copyright 2014, the Dart project authors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of Google LLC nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/pkgs/oauth2/README.md b/pkgs/oauth2/README.md
new file mode 100644
index 0000000..07a5976
--- /dev/null
+++ b/pkgs/oauth2/README.md
@@ -0,0 +1,260 @@
+[](https://github.com/dart-lang/tools/actions/workflows/oauth2.yml)
+[](https://pub.dev/packages/oauth2)
+[](https://pub.dev/packages/oauth2/publisher)
+
+A client library for authenticating with a remote service via OAuth2 on behalf
+of a user, and making authorized HTTP requests with the user's OAuth2
+credentials.
+
+## About OAuth2
+
+OAuth2 allows a client (the program using this library) to access and manipulate
+a resource that's owned by a resource owner (the end user) and lives on a remote
+server. The client directs the resource owner to an authorization server
+(usually but not always the same as the server that hosts the resource), where
+the resource owner tells the authorization server to give the client an access
+token. This token serves as proof that the client has permission to access
+resources on behalf of the resource owner.
+
+OAuth2 provides several different methods for the client to obtain
+authorization. At the time of writing, this library only supports the
+[Authorization Code Grant][authorizationCodeGrantSection],
+[Client Credentials Grant][clientCredentialsGrantSection] and
+[Resource Owner Password Grant][resourceOwnerPasswordGrantSection] flows, but
+more may be added in the future.
+
+## Authorization Code Grant
+
+**Resources:** [Class summary][authorizationCodeGrantMethod],
+[OAuth documentation][authorizationCodeGrantDocs]
+
+```dart
+import 'dart:io';
+
+import 'package:oauth2/oauth2.dart' as oauth2;
+
+// These URLs are endpoints that are provided by the authorization
+// server. They're usually included in the server's documentation of its
+// OAuth2 API.
+final authorizationEndpoint =
+ Uri.parse('http://example.com/oauth2/authorization');
+final tokenEndpoint = Uri.parse('http://example.com/oauth2/token');
+
+// The authorization server will issue each client a separate client
+// identifier and secret, which allows the server to tell which client
+// is accessing it. Some servers may also have an anonymous
+// identifier/secret pair that any client may use.
+//
+// Note that clients whose source code or binary executable is readily
+// available may not be able to make sure the client secret is kept a
+// secret. This is fine; OAuth2 servers generally won't rely on knowing
+// with certainty that a client is who it claims to be.
+final identifier = 'my client identifier';
+final secret = 'my client secret';
+
+// This is a URL on your application's server. The authorization server
+// will redirect the resource owner here once they've authorized the
+// client. The redirection will include the authorization code in the
+// query parameters.
+final redirectUrl = Uri.parse('http://my-site.com/oauth2-redirect');
+
+/// A file in which the users credentials are stored persistently. If the server
+/// issues a refresh token allowing the client to refresh outdated credentials,
+/// these may be valid indefinitely, meaning the user never has to
+/// re-authenticate.
+final credentialsFile = File('~/.myapp/credentials.json');
+
+/// Either load an OAuth2 client from saved credentials or authenticate a new
+/// one.
+Future<oauth2.Client> createClient() async {
+ var exists = await credentialsFile.exists();
+
+ // If the OAuth2 credentials have already been saved from a previous run, we
+ // just want to reload them.
+ if (exists) {
+ var credentials =
+ oauth2.Credentials.fromJson(await credentialsFile.readAsString());
+ return oauth2.Client(credentials, identifier: identifier, secret: secret);
+ }
+
+ // If we don't have OAuth2 credentials yet, we need to get the resource owner
+ // to authorize us. We're assuming here that we're a command-line application.
+ var grant = oauth2.AuthorizationCodeGrant(
+ identifier, authorizationEndpoint, tokenEndpoint,
+ secret: secret);
+
+ // A URL on the authorization server (authorizationEndpoint with some additional
+ // query parameters). Scopes and state can optionally be passed into this method.
+ var authorizationUrl = grant.getAuthorizationUrl(redirectUrl);
+
+ // Redirect the resource owner to the authorization URL. Once the resource
+ // owner has authorized, they'll be redirected to `redirectUrl` with an
+ // authorization code. The `redirect` should cause the browser to redirect to
+ // another URL which should also have a listener.
+ //
+ // `redirect` and `listen` are not shown implemented here. See below for the
+ // details.
+ await redirect(authorizationUrl);
+ var responseUrl = await listen(redirectUrl);
+
+ // Once the user is redirected to `redirectUrl`, pass the query parameters to
+ // the AuthorizationCodeGrant. It will validate them and extract the
+ // authorization code to create a new Client.
+ return await grant.handleAuthorizationResponse(responseUrl.queryParameters);
+}
+
+void main() async {
+ var client = await createClient();
+
+ // Once you have a Client, you can use it just like any other HTTP client.
+ print(await client.read('http://example.com/protected-resources.txt'));
+
+ // Once we're done with the client, save the credentials file. This ensures
+ // that if the credentials were automatically refreshed while using the
+ // client, the new credentials are available for the next run of the
+ // program.
+ await credentialsFile.writeAsString(client.credentials.toJson());
+}
+```
+
+<details>
+ <summary>Click here to learn how to implement `redirect` and `listen`.</summary>
+
+--------------------------------------------------------------------------------
+
+There is not a universal example for implementing `redirect` and `listen`,
+because different options exist for each platform.
+
+For Flutter apps, there's two popular approaches:
+
+1. Launch a browser using [url_launcher][] and listen for a redirect using
+ [uni_links][].
+
+ ```dart
+ if (await canLaunch(authorizationUrl.toString())) {
+ await launch(authorizationUrl.toString()); }
+
+ // ------- 8< -------
+
+ final linksStream = getLinksStream().listen((Uri uri) async {
+ if (uri.toString().startsWith(redirectUrl)) {
+ responseUrl = uri;
+ }
+ });
+ ```
+
+1. Launch a WebView inside the app and listen for a redirect using
+ [webview_flutter][].
+
+ ```dart
+ WebView(
+ javascriptMode: JavascriptMode.unrestricted,
+ initialUrl: authorizationUrl.toString(),
+ navigationDelegate: (navReq) {
+ if (navReq.url.startsWith(redirectUrl)) {
+ responseUrl = Uri.parse(navReq.url);
+ return NavigationDecision.prevent;
+ }
+ return NavigationDecision.navigate;
+ },
+ // ------- 8< -------
+ );
+ ```
+
+For Dart apps, the best approach depends on the available options for accessing
+a browser. In general, you'll need to launch the authorization URL through the
+client's browser and listen for the redirect URL.
+</details>
+
+## Client Credentials Grant
+
+**Resources:** [Method summary][clientCredentialsGrantMethod],
+[OAuth documentation][clientCredentialsGrantDocs]
+
+```dart
+// This URL is an endpoint that's provided by the authorization server. It's
+// usually included in the server's documentation of its OAuth2 API.
+final authorizationEndpoint =
+ Uri.parse('http://example.com/oauth2/authorization');
+
+// The OAuth2 specification expects a client's identifier and secret
+// to be sent when using the client credentials grant.
+//
+// Because the client credentials grant is not inherently associated with a user,
+// it is up to the server in question whether the returned token allows limited
+// API access.
+//
+// Either way, you must provide both a client identifier and a client secret:
+final identifier = 'my client identifier';
+final secret = 'my client secret';
+
+// Calling the top-level `clientCredentialsGrant` function will return a
+// [Client] instead.
+var client = await oauth2.clientCredentialsGrant(
+ authorizationEndpoint, identifier, secret);
+
+// With an authenticated client, you can make requests, and the `Bearer` token
+// returned by the server during the client credentials grant will be attached
+// to any request you make.
+var response =
+ await client.read('https://example.com/api/some_resource.json');
+
+// You can save the client's credentials, which consists of an access token, and
+// potentially a refresh token and expiry date, to a file. This way, subsequent runs
+// do not need to reauthenticate, and you can avoid saving the client identifier and
+// secret.
+await credentialsFile.writeAsString(client.credentials.toJson());
+```
+
+## Resource Owner Password Grant
+
+**Resources:** [Method summary][resourceOwnerPasswordGrantMethod],
+[OAuth documentation][resourceOwnerPasswordGrantDocs]
+
+```dart
+// This URL is an endpoint that's provided by the authorization server. It's
+// usually included in the server's documentation of its OAuth2 API.
+final authorizationEndpoint =
+ Uri.parse('http://example.com/oauth2/authorization');
+
+// The user should supply their own username and password.
+final username = 'example user';
+final password = 'example password';
+
+// The authorization server may issue each client a separate client
+// identifier and secret, which allows the server to tell which client
+// is accessing it. Some servers may also have an anonymous
+// identifier/secret pair that any client may use.
+//
+// Some servers don't require the client to authenticate itself, in which case
+// these should be omitted.
+final identifier = 'my client identifier';
+final secret = 'my client secret';
+
+// Make a request to the authorization endpoint that will produce the fully
+// authenticated Client.
+var client = await oauth2.resourceOwnerPasswordGrant(
+ authorizationEndpoint, username, password,
+ identifier: identifier, secret: secret);
+
+// Once you have the client, you can use it just like any other HTTP client.
+var result = await client.read('http://example.com/protected-resources.txt');
+
+// Once we're done with the client, save the credentials file. This will allow
+// us to re-use the credentials and avoid storing the username and password
+// directly.
+File('~/.myapp/credentials.json').writeAsString(client.credentials.toJson());
+```
+
+[authorizationCodeGrantDocs]: https://oauth.net/2/grant-types/authorization-code/
+[authorizationCodeGrantMethod]: https://pub.dev/documentation/oauth2/latest/oauth2/AuthorizationCodeGrant-class.html
+[authorizationCodeGrantSection]: #authorization-code-grant
+[clientCredentialsGrantDocs]: https://oauth.net/2/grant-types/client-credentials/
+[clientCredentialsGrantMethod]: https://pub.dev/documentation/oauth2/latest/oauth2/clientCredentialsGrant.html
+[clientCredentialsGrantSection]: #client-credentials-grant
+[resourceOwnerPasswordGrantDocs]: https://oauth.net/2/grant-types/password/
+[resourceOwnerPasswordGrantMethod]: https://pub.dev/documentation/oauth2/latest/oauth2/resourceOwnerPasswordGrant.html
+[resourceOwnerPasswordGrantSection]: #resource-owner-password-grant
+[uni_links]: https://pub.dev/packages/uni_links
+[url_launcher]: https://pub.dev/packages/url_launcher
+[webview_flutter]: https://pub.dev/packages/webview_flutter
diff --git a/pkgs/oauth2/analysis_options.yaml b/pkgs/oauth2/analysis_options.yaml
new file mode 100644
index 0000000..e21412c
--- /dev/null
+++ b/pkgs/oauth2/analysis_options.yaml
@@ -0,0 +1,23 @@
+include: package:dart_flutter_team_lints/analysis_options.yaml
+
+analyzer:
+ errors:
+ # Too many exceptions
+ comment_references: ignore
+ language:
+ strict-casts: true
+ strict-raw-types: true
+
+linter:
+ rules:
+ - avoid_private_typedef_functions
+ - avoid_unused_constructor_parameters
+ - avoid_void_async
+ - cancel_subscriptions
+ - literal_only_boolean_expressions
+ - no_adjacent_strings_in_list
+ - no_runtimeType_toString
+ - package_api_docs
+ - prefer_const_declarations
+ - unnecessary_await_in_return
+ - use_string_buffers
diff --git a/pkgs/oauth2/example/main.dart b/pkgs/oauth2/example/main.dart
new file mode 100644
index 0000000..68e5aa0
--- /dev/null
+++ b/pkgs/oauth2/example/main.dart
@@ -0,0 +1,100 @@
+// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:oauth2/oauth2.dart' as oauth2;
+
+// These URLs are endpoints that are provided by the authorization
+// server. They're usually included in the server's documentation of its
+// OAuth2 API.
+final authorizationEndpoint =
+ Uri.parse('http://example.com/oauth2/authorization');
+final tokenEndpoint = Uri.parse('http://example.com/oauth2/token');
+
+// The authorization server will issue each client a separate client
+// identifier and secret, which allows the server to tell which client
+// is accessing it. Some servers may also have an anonymous
+// identifier/secret pair that any client may use.
+//
+// Note that clients whose source code or binary executable is readily
+// available may not be able to make sure the client secret is kept a
+// secret. This is fine; OAuth2 servers generally won't rely on knowing
+// with certainty that a client is who it claims to be.
+const identifier = 'my client identifier';
+const secret = 'my client secret';
+
+// This is a URL on your application's server. The authorization server
+// will redirect the resource owner here once they've authorized the
+// client. The redirection will include the authorization code in the
+// query parameters.
+final redirectUrl = Uri.parse('http://my-site.com/oauth2-redirect');
+
+/// A file in which the users credentials are stored persistently. If the server
+/// issues a refresh token allowing the client to refresh outdated credentials,
+/// these may be valid indefinitely, meaning the user never has to
+/// re-authenticate.
+final credentialsFile = File('~/.myapp/credentials.json');
+
+/// Either load an OAuth2 client from saved credentials or authenticate a new
+/// one.
+Future<oauth2.Client> createClient() async {
+ var exists = await credentialsFile.exists();
+
+ // If the OAuth2 credentials have already been saved from a previous run, we
+ // just want to reload them.
+ if (exists) {
+ var credentials =
+ oauth2.Credentials.fromJson(await credentialsFile.readAsString());
+ return oauth2.Client(credentials, identifier: identifier, secret: secret);
+ }
+
+ // If we don't have OAuth2 credentials yet, we need to get the resource owner
+ // to authorize us. We're assuming here that we're a command-line application.
+ var grant = oauth2.AuthorizationCodeGrant(
+ identifier, authorizationEndpoint, tokenEndpoint,
+ secret: secret);
+
+ // A URL on the authorization server (authorizationEndpoint with some
+ // additional query parameters). Scopes and state can optionally be passed
+ // into this method.
+ var authorizationUrl = grant.getAuthorizationUrl(redirectUrl);
+
+ // Redirect the resource owner to the authorization URL. Once the resource
+ // owner has authorized, they'll be redirected to `redirectUrl` with an
+ // authorization code. The `redirect` should cause the browser to redirect to
+ // another URL which should also have a listener.
+ //
+ // `redirect` and `listen` are not shown implemented here.
+ await redirect(authorizationUrl);
+ var responseUrl = await listen(redirectUrl);
+
+ // Once the user is redirected to `redirectUrl`, pass the query parameters to
+ // the AuthorizationCodeGrant. It will validate them and extract the
+ // authorization code to create a new Client.
+ return grant.handleAuthorizationResponse(responseUrl.queryParameters);
+}
+
+void main() async {
+ var client = await createClient();
+
+ // Once you have a Client, you can use it just like any other HTTP client.
+ print(await client.read(Uri.http('example.com', 'protected-resources.txt')));
+
+ // Once we're done with the client, save the credentials file. This ensures
+ // that if the credentials were automatically refreshed while using the
+ // client, the new credentials are available for the next run of the
+ // program.
+ await credentialsFile.writeAsString(client.credentials.toJson());
+}
+
+Future<void> redirect(Uri url) async {
+ // Client implementation detail
+}
+
+Future<Uri> listen(Uri url) async {
+ // Client implementation detail
+ return Uri();
+}
diff --git a/pkgs/oauth2/lib/oauth2.dart b/pkgs/oauth2/lib/oauth2.dart
new file mode 100644
index 0000000..45efc5c
--- /dev/null
+++ b/pkgs/oauth2/lib/oauth2.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2012, 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.
+
+export 'src/authorization_code_grant.dart';
+export 'src/authorization_exception.dart';
+export 'src/client.dart';
+export 'src/client_credentials_grant.dart';
+export 'src/credentials.dart';
+export 'src/expiration_exception.dart';
+export 'src/resource_owner_password_grant.dart';
diff --git a/pkgs/oauth2/lib/src/authorization_code_grant.dart b/pkgs/oauth2/lib/src/authorization_code_grant.dart
new file mode 100644
index 0000000..fac56ba
--- /dev/null
+++ b/pkgs/oauth2/lib/src/authorization_code_grant.dart
@@ -0,0 +1,371 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:math';
+
+import 'package:crypto/crypto.dart';
+import 'package:http/http.dart' as http;
+import 'package:http_parser/http_parser.dart';
+
+import 'authorization_exception.dart';
+import 'client.dart';
+import 'credentials.dart';
+import 'handle_access_token_response.dart';
+import 'parameters.dart';
+import 'utils.dart';
+
+/// A class for obtaining credentials via an [authorization code grant][].
+///
+/// This method of authorization involves sending the resource owner to the
+/// authorization server where they will authorize the client. They're then
+/// redirected back to your server, along with an authorization code. This is
+/// used to obtain [Credentials] and create a fully-authorized [Client].
+///
+/// To use this class, you must first call [getAuthorizationUrl] to get the URL
+/// to which to redirect the resource owner. Then once they've been redirected
+/// back to your application, call [handleAuthorizationResponse] or
+/// [handleAuthorizationCode] to process the authorization server's response and
+/// construct a [Client].
+///
+/// [authorization code grant]: http://tools.ietf.org/html/draft-ietf-oauth-v2-31#section-4.1
+class AuthorizationCodeGrant {
+ /// The function used to parse parameters from a host's response.
+ final GetParameters _getParameters;
+
+ /// The client identifier for this client.
+ ///
+ /// The authorization server will issue each client a separate client
+ /// identifier and secret, which allows the server to tell which client is
+ /// accessing it. Some servers may also have an anonymous identifier/secret
+ /// pair that any client may use.
+ ///
+ /// This is usually global to the program using this library.
+ final String identifier;
+
+ /// The client secret for this client.
+ ///
+ /// The authorization server will issue each client a separate client
+ /// identifier and secret, which allows the server to tell which client is
+ /// accessing it. Some servers may also have an anonymous identifier/secret
+ /// pair that any client may use.
+ ///
+ /// This is usually global to the program using this library.
+ ///
+ /// Note that clients whose source code or binary executable is readily
+ /// available may not be able to make sure the client secret is kept a secret.
+ /// This is fine; OAuth2 servers generally won't rely on knowing with
+ /// certainty that a client is who it claims to be.
+ final String? secret;
+
+ /// A URL provided by the authorization server that serves as the base for the
+ /// URL that the resource owner will be redirected to to authorize this
+ /// client.
+ ///
+ /// This will usually be listed in the authorization server's OAuth2 API
+ /// documentation.
+ final Uri authorizationEndpoint;
+
+ /// A URL provided by the authorization server that this library uses to
+ /// obtain long-lasting credentials.
+ ///
+ /// This will usually be listed in the authorization server's OAuth2 API
+ /// documentation.
+ final Uri tokenEndpoint;
+
+ /// Callback to be invoked whenever the credentials are refreshed.
+ ///
+ /// This will be passed as-is to the constructed [Client].
+ final CredentialsRefreshedCallback? _onCredentialsRefreshed;
+
+ /// Whether to use HTTP Basic authentication for authorizing the client.
+ final bool _basicAuth;
+
+ /// A [String] used to separate scopes; defaults to `" "`.
+ final String _delimiter;
+
+ /// The HTTP client used to make HTTP requests.
+ http.Client? _httpClient;
+
+ /// The URL to which the resource owner will be redirected after they
+ /// authorize this client with the authorization server.
+ Uri? _redirectEndpoint;
+
+ /// The scopes that the client is requesting access to.
+ List<String>? _scopes;
+
+ /// An opaque string that users of this library may specify that will be
+ /// included in the response query parameters.
+ String? _stateString;
+
+ /// The current state of the grant object.
+ _State _state = _State.initial;
+
+ /// Allowed characters for generating the _codeVerifier
+ static const String _charset =
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~';
+
+ /// The PKCE code verifier. Will be generated if one is not provided in the
+ /// constructor.
+ final String _codeVerifier;
+
+ /// Creates a new grant.
+ ///
+ /// If [basicAuth] is `true` (the default), the client credentials are sent to
+ /// the server using using HTTP Basic authentication as defined in [RFC 2617].
+ /// Otherwise, they're included in the request body. Note that the latter form
+ /// is not recommended by the OAuth 2.0 spec, and should only be used if the
+ /// server doesn't support Basic authentication.
+ ///
+ /// [RFC 2617]: https://tools.ietf.org/html/rfc2617
+ ///
+ /// [httpClient] is used for all HTTP requests made by this grant, as well as
+ /// those of the [Client] is constructs.
+ ///
+ /// [onCredentialsRefreshed] will be called by the constructed [Client]
+ /// whenever the credentials are refreshed.
+ ///
+ /// [codeVerifier] String to be used as PKCE code verifier. If none is
+ /// provided a random codeVerifier will be generated.
+ /// The codeVerifier must meet requirements specified in [RFC 7636].
+ ///
+ /// [RFC 7636]: https://tools.ietf.org/html/rfc7636#section-4.1
+ ///
+ /// The scope strings will be separated by the provided [delimiter]. This
+ /// defaults to `" "`, the OAuth2 standard, but some APIs (such as Facebook's)
+ /// use non-standard delimiters.
+ ///
+ /// By default, this follows the OAuth2 spec and requires the server's
+ /// responses to be in JSON format. However, some servers return non-standard
+ /// response formats, which can be parsed using the [getParameters] function.
+ ///
+ /// This function is passed the `Content-Type` header of the response as well
+ /// as its body as a UTF-8-decoded string. It should return a map in the same
+ /// format as the [standard JSON response][].
+ ///
+ /// [standard JSON response]: https://tools.ietf.org/html/rfc6749#section-5.1
+ AuthorizationCodeGrant(
+ this.identifier, this.authorizationEndpoint, this.tokenEndpoint,
+ {this.secret,
+ String? delimiter,
+ bool basicAuth = true,
+ http.Client? httpClient,
+ CredentialsRefreshedCallback? onCredentialsRefreshed,
+ Map<String, dynamic> Function(MediaType? contentType, String body)?
+ getParameters,
+ String? codeVerifier})
+ : _basicAuth = basicAuth,
+ _httpClient = httpClient ?? http.Client(),
+ _delimiter = delimiter ?? ' ',
+ _getParameters = getParameters ?? parseJsonParameters,
+ _onCredentialsRefreshed = onCredentialsRefreshed,
+ _codeVerifier = codeVerifier ?? _createCodeVerifier();
+
+ /// Returns the URL to which the resource owner should be redirected to
+ /// authorize this client.
+ ///
+ /// The resource owner will then be redirected to [redirect], which should
+ /// point to a server controlled by the client. This redirect will have
+ /// additional query parameters that should be passed to
+ /// [handleAuthorizationResponse].
+ ///
+ /// The specific permissions being requested from the authorization server may
+ /// be specified via [scopes]. The scope strings are specific to the
+ /// authorization server and may be found in its documentation. Note that you
+ /// may not be granted access to every scope you request; you may check the
+ /// [Credentials.scopes] field of [Client.credentials] to see which scopes you
+ /// were granted.
+ ///
+ /// An opaque [state] string may also be passed that will be present in the
+ /// query parameters provided to the redirect URL.
+ ///
+ /// It is a [StateError] to call this more than once.
+ Uri getAuthorizationUrl(Uri redirect,
+ {Iterable<String>? scopes, String? state}) {
+ if (_state != _State.initial) {
+ throw StateError('The authorization URL has already been generated.');
+ }
+ _state = _State.awaitingResponse;
+
+ var scopeList = scopes?.toList() ?? <String>[];
+ var codeChallenge = base64Url
+ .encode(sha256.convert(ascii.encode(_codeVerifier)).bytes)
+ .replaceAll('=', '');
+
+ _redirectEndpoint = redirect;
+ _scopes = scopeList;
+ _stateString = state;
+ var parameters = {
+ 'response_type': 'code',
+ 'client_id': identifier,
+ 'redirect_uri': redirect.toString(),
+ 'code_challenge': codeChallenge,
+ 'code_challenge_method': 'S256'
+ };
+
+ if (state != null) parameters['state'] = state;
+ if (scopeList.isNotEmpty) parameters['scope'] = scopeList.join(_delimiter);
+
+ return addQueryParameters(authorizationEndpoint, parameters);
+ }
+
+ /// Processes the query parameters added to a redirect from the authorization
+ /// server.
+ ///
+ /// Note that this "response" is not an HTTP response, but rather the data
+ /// passed to a server controlled by the client as query parameters on the
+ /// redirect URL.
+ ///
+ /// It is a [StateError] to call this more than once, to call it before
+ /// [getAuthorizationUrl] is called, or to call it after
+ /// [handleAuthorizationCode] is called.
+ ///
+ /// Throws [FormatException] if [parameters] is invalid according to the
+ /// OAuth2 spec or if the authorization server otherwise provides invalid
+ /// responses. If `state` was passed to [getAuthorizationUrl], this will throw
+ /// a [FormatException] if the `state` parameter doesn't match the original
+ /// value.
+ ///
+ /// Throws [AuthorizationException] if the authorization fails.
+ Future<Client> handleAuthorizationResponse(
+ Map<String, String> parameters) async {
+ if (_state == _State.initial) {
+ throw StateError('The authorization URL has not yet been generated.');
+ } else if (_state == _State.finished) {
+ throw StateError('The authorization code has already been received.');
+ }
+ _state = _State.finished;
+
+ if (_stateString != null) {
+ if (!parameters.containsKey('state')) {
+ throw FormatException('Invalid OAuth response for '
+ '"$authorizationEndpoint": parameter "state" expected to be '
+ '"$_stateString", was missing.');
+ } else if (parameters['state'] != _stateString) {
+ throw FormatException('Invalid OAuth response for '
+ '"$authorizationEndpoint": parameter "state" expected to be '
+ '"$_stateString", was "${parameters['state']}".');
+ }
+ }
+
+ if (parameters.containsKey('error')) {
+ var description = parameters['error_description'];
+ var uriString = parameters['error_uri'];
+ var uri = uriString == null ? null : Uri.parse(uriString);
+ throw AuthorizationException(parameters['error']!, description, uri);
+ } else if (!parameters.containsKey('code')) {
+ throw FormatException('Invalid OAuth response for '
+ '"$authorizationEndpoint": did not contain required parameter '
+ '"code".');
+ }
+
+ return _handleAuthorizationCode(parameters['code']);
+ }
+
+ /// Processes an authorization code directly.
+ ///
+ /// Usually [handleAuthorizationResponse] is preferable to this method, since
+ /// it validates all of the query parameters. However, some authorization
+ /// servers allow the user to copy and paste an authorization code into a
+ /// command-line application, in which case this method must be used.
+ ///
+ /// It is a [StateError] to call this more than once, to call it before
+ /// [getAuthorizationUrl] is called, or to call it after
+ /// [handleAuthorizationCode] is called.
+ ///
+ /// Throws [FormatException] if the authorization server provides invalid
+ /// responses while retrieving credentials.
+ ///
+ /// Throws [AuthorizationException] if the authorization fails.
+ Future<Client> handleAuthorizationCode(String authorizationCode) async {
+ if (_state == _State.initial) {
+ throw StateError('The authorization URL has not yet been generated.');
+ } else if (_state == _State.finished) {
+ throw StateError('The authorization code has already been received.');
+ }
+ _state = _State.finished;
+
+ return _handleAuthorizationCode(authorizationCode);
+ }
+
+ /// This works just like [handleAuthorizationCode], except it doesn't validate
+ /// the state beforehand.
+ Future<Client> _handleAuthorizationCode(String? authorizationCode) async {
+ var startTime = DateTime.now();
+
+ var headers = <String, String>{};
+
+ var body = {
+ 'grant_type': 'authorization_code',
+ 'code': authorizationCode,
+ 'redirect_uri': _redirectEndpoint.toString(),
+ 'code_verifier': _codeVerifier
+ };
+
+ var secret = this.secret;
+ if (_basicAuth && secret != null) {
+ headers['Authorization'] = basicAuthHeader(identifier, secret);
+ } else {
+ // The ID is required for this request any time basic auth isn't being
+ // used, even if there's no actual client authentication to be done.
+ body['client_id'] = identifier;
+ if (secret != null) body['client_secret'] = secret;
+ }
+
+ var response =
+ await _httpClient!.post(tokenEndpoint, headers: headers, body: body);
+
+ var credentials = handleAccessTokenResponse(
+ response, tokenEndpoint, startTime, _scopes, _delimiter,
+ getParameters: _getParameters);
+ return Client(credentials,
+ identifier: identifier,
+ secret: secret,
+ basicAuth: _basicAuth,
+ httpClient: _httpClient,
+ onCredentialsRefreshed: _onCredentialsRefreshed);
+ }
+
+ // Randomly generate a 128 character string to be used as the PKCE code
+ // verifier.
+ static String _createCodeVerifier() => List.generate(
+ 128,
+ (i) => _charset[Random.secure().nextInt(_charset.length)],
+ ).join();
+
+ /// Closes the grant and frees its resources.
+ ///
+ /// This will close the underlying HTTP client, which is shared by the
+ /// [Client] created by this grant, so it's not safe to close the grant and
+ /// continue using the client.
+ void close() {
+ _httpClient?.close();
+ _httpClient = null;
+ }
+}
+
+/// States that [AuthorizationCodeGrant] can be in.
+class _State {
+ /// [AuthorizationCodeGrant.getAuthorizationUrl] has not yet been called for
+ /// this grant.
+ static const initial = _State('initial');
+
+ // [AuthorizationCodeGrant.getAuthorizationUrl] has been called but neither
+ // [AuthorizationCodeGrant.handleAuthorizationResponse] nor
+ // [AuthorizationCodeGrant.handleAuthorizationCode] has been called.
+ static const awaitingResponse = _State('awaiting response');
+
+ // [AuthorizationCodeGrant.getAuthorizationUrl] and either
+ // [AuthorizationCodeGrant.handleAuthorizationResponse] or
+ // [AuthorizationCodeGrant.handleAuthorizationCode] have been called.
+ static const finished = _State('finished');
+
+ final String _name;
+
+ const _State(this._name);
+
+ @override
+ String toString() => _name;
+}
diff --git a/pkgs/oauth2/lib/src/authorization_exception.dart b/pkgs/oauth2/lib/src/authorization_exception.dart
new file mode 100644
index 0000000..14a5a3c
--- /dev/null
+++ b/pkgs/oauth2/lib/src/authorization_exception.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2012, 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.
+
+/// An exception raised when OAuth2 authorization fails.
+class AuthorizationException implements Exception {
+ /// The name of the error.
+ ///
+ /// Possible names are enumerated in [the spec][].
+ ///
+ /// [the spec]: http://tools.ietf.org/html/draft-ietf-oauth-v2-31#section-5.2
+ final String error;
+
+ /// The description of the error, provided by the server.
+ ///
+ /// May be `null` if the server provided no description.
+ final String? description;
+
+ /// A URL for a page that describes the error in more detail, provided by the
+ /// server.
+ ///
+ /// May be `null` if the server provided no URL.
+ final Uri? uri;
+
+ /// Creates an AuthorizationException.
+ AuthorizationException(this.error, this.description, this.uri);
+
+ /// Provides a string description of the AuthorizationException.
+ @override
+ String toString() {
+ var header = 'OAuth authorization error ($error)';
+ if (description != null) {
+ header = '$header: $description';
+ } else if (uri != null) {
+ header = '$header: $uri';
+ }
+ return '$header.';
+ }
+}
diff --git a/pkgs/oauth2/lib/src/client.dart b/pkgs/oauth2/lib/src/client.dart
new file mode 100644
index 0000000..1dd2282
--- /dev/null
+++ b/pkgs/oauth2/lib/src/client.dart
@@ -0,0 +1,187 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:collection/collection.dart';
+import 'package:http/http.dart' as http;
+import 'package:http_parser/http_parser.dart';
+
+import 'authorization_exception.dart';
+import 'credentials.dart';
+import 'expiration_exception.dart';
+
+/// An OAuth2 client.
+///
+/// This acts as a drop-in replacement for an [http.Client], while sending
+/// OAuth2 authorization credentials along with each request.
+///
+/// The client also automatically refreshes its credentials if possible. When it
+/// makes a request, if its credentials are expired, it will first refresh them.
+/// This means that any request may throw an [AuthorizationException] if the
+/// refresh is not authorized for some reason, a [FormatException] if the
+/// authorization server provides ill-formatted responses, or an
+/// [ExpirationException] if the credentials are expired and can't be refreshed.
+///
+/// The client will also throw an [AuthorizationException] if the resource
+/// server returns a 401 response with a WWW-Authenticate header indicating that
+/// the current credentials are invalid.
+///
+/// If you already have a set of [Credentials], you can construct a [Client]
+/// directly. However, in order to first obtain the credentials, you must
+/// authorize. At the time of writing, the only authorization method this
+/// library supports is [AuthorizationCodeGrant].
+class Client extends http.BaseClient {
+ /// The client identifier for this client.
+ ///
+ /// The authorization server will issue each client a separate client
+ /// identifier and secret, which allows the server to tell which client is
+ /// accessing it. Some servers may also have an anonymous identifier/secret
+ /// pair that any client may use.
+ ///
+ /// This is usually global to the program using this library.
+ final String? identifier;
+
+ /// The client secret for this client.
+ ///
+ /// The authorization server will issue each client a separate client
+ /// identifier and secret, which allows the server to tell which client is
+ /// accessing it. Some servers may also have an anonymous identifier/secret
+ /// pair that any client may use.
+ ///
+ /// This is usually global to the program using this library.
+ ///
+ /// Note that clients whose source code or binary executable is readily
+ /// available may not be able to make sure the client secret is kept a secret.
+ /// This is fine; OAuth2 servers generally won't rely on knowing with
+ /// certainty that a client is who it claims to be.
+ final String? secret;
+
+ /// The credentials this client uses to prove to the resource server that it's
+ /// authorized.
+ ///
+ /// This may change from request to request as the credentials expire and the
+ /// client refreshes them automatically.
+ Credentials get credentials => _credentials;
+ Credentials _credentials;
+
+ /// Callback to be invoked whenever the credentials refreshed.
+ final CredentialsRefreshedCallback? _onCredentialsRefreshed;
+
+ /// Whether to use HTTP Basic authentication for authorizing the client.
+ final bool _basicAuth;
+
+ /// The underlying HTTP client.
+ http.Client? _httpClient;
+
+ /// Creates a new client from a pre-existing set of credentials.
+ ///
+ /// When authorizing a client for the first time, you should use
+ /// [AuthorizationCodeGrant] or [resourceOwnerPasswordGrant] instead of
+ /// constructing a [Client] directly.
+ ///
+ /// [httpClient] is the underlying client that this forwards requests to after
+ /// adding authorization credentials to them.
+ ///
+ /// Throws an [ArgumentError] if [secret] is passed without [identifier].
+ Client(this._credentials,
+ {this.identifier,
+ this.secret,
+ CredentialsRefreshedCallback? onCredentialsRefreshed,
+ bool basicAuth = true,
+ http.Client? httpClient})
+ : _basicAuth = basicAuth,
+ _onCredentialsRefreshed = onCredentialsRefreshed,
+ _httpClient = httpClient ?? http.Client() {
+ if (identifier == null && secret != null) {
+ throw ArgumentError('secret may not be passed without identifier.');
+ }
+ }
+
+ /// Sends an HTTP request with OAuth2 authorization credentials attached.
+ ///
+ /// This will also automatically refresh this client's [Credentials] before
+ /// sending the request if necessary.
+ @override
+ Future<http.StreamedResponse> send(http.BaseRequest request) async {
+ if (credentials.isExpired) {
+ if (!credentials.canRefresh) throw ExpirationException(credentials);
+ await refreshCredentials();
+ }
+
+ request.headers['authorization'] = 'Bearer ${credentials.accessToken}';
+ var response = await _httpClient!.send(request);
+
+ if (response.statusCode != 401) return response;
+ if (!response.headers.containsKey('www-authenticate')) return response;
+
+ List<AuthenticationChallenge> challenges;
+ try {
+ challenges = AuthenticationChallenge.parseHeader(
+ response.headers['www-authenticate']!);
+ } on FormatException {
+ return response;
+ }
+
+ var challenge = challenges
+ .firstWhereOrNull((challenge) => challenge.scheme == 'bearer');
+ if (challenge == null) return response;
+
+ var params = challenge.parameters;
+ if (!params.containsKey('error')) return response;
+
+ throw AuthorizationException(params['error']!, params['error_description'],
+ params['error_uri'] == null ? null : Uri.parse(params['error_uri']!));
+ }
+
+ /// A [Future] used to track whether [refreshCredentials] is running.
+ Future<Credentials>? _refreshingFuture;
+
+ /// Explicitly refreshes this client's credentials. Returns this client.
+ ///
+ /// This will throw a [StateError] if the [Credentials] can't be refreshed, an
+ /// [AuthorizationException] if refreshing the credentials fails, or a
+ /// [FormatException] if the authorization server returns invalid responses.
+ ///
+ /// You may request different scopes than the default by passing in
+ /// [newScopes]. These must be a subset of the scopes in the
+ /// [Credentials.scopes] field of [Client.credentials].
+ Future<Client> refreshCredentials([List<String>? newScopes]) async {
+ if (!credentials.canRefresh) {
+ var prefix = 'OAuth credentials';
+ if (credentials.isExpired) prefix = '$prefix have expired and';
+ throw StateError("$prefix can't be refreshed.");
+ }
+
+ // To make sure that only one refresh happens when credentials are expired
+ // we track it using the [_refreshingFuture]. And also make sure that the
+ // _onCredentialsRefreshed callback is only called once.
+ if (_refreshingFuture == null) {
+ try {
+ _refreshingFuture = credentials.refresh(
+ identifier: identifier,
+ secret: secret,
+ newScopes: newScopes,
+ basicAuth: _basicAuth,
+ httpClient: _httpClient,
+ );
+ _credentials = await _refreshingFuture!;
+ _onCredentialsRefreshed?.call(_credentials);
+ } finally {
+ _refreshingFuture = null;
+ }
+ } else {
+ await _refreshingFuture;
+ }
+
+ return this;
+ }
+
+ /// Closes this client and its underlying HTTP client.
+ @override
+ void close() {
+ _httpClient?.close();
+ _httpClient = null;
+ }
+}
diff --git a/pkgs/oauth2/lib/src/client_credentials_grant.dart b/pkgs/oauth2/lib/src/client_credentials_grant.dart
new file mode 100644
index 0000000..045d1a0
--- /dev/null
+++ b/pkgs/oauth2/lib/src/client_credentials_grant.dart
@@ -0,0 +1,79 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:http/http.dart' as http;
+import 'package:http_parser/http_parser.dart';
+
+import 'client.dart';
+import 'handle_access_token_response.dart';
+import 'utils.dart';
+
+/// Obtains credentials using a [client credentials grant](https://tools.ietf.org/html/rfc6749#section-1.3.4).
+///
+/// This mode of authorization uses the client's [identifier] and [secret]
+/// to obtain an authorization token from the authorization server, instead
+/// of sending a user through a dedicated flow.
+///
+/// The client [identifier] and [secret] are required, and are
+/// used to identify and authenticate your specific OAuth2 client. These are
+/// usually global to the program using this library.
+///
+/// The specific permissions being requested from the authorization server may
+/// be specified via [scopes]. The scope strings are specific to the
+/// authorization server and may be found in its documentation. Note that you
+/// may not be granted access to every scope you request; you may check the
+/// [Credentials.scopes] field of [Client.credentials] to see which scopes you
+/// were granted.
+///
+/// The scope strings will be separated by the provided [delimiter]. This
+/// defaults to `" "`, the OAuth2 standard, but some APIs (such as Facebook's)
+/// use non-standard delimiters.
+///
+/// By default, this follows the OAuth2 spec and requires the server's responses
+/// to be in JSON format. However, some servers return non-standard response
+/// formats, which can be parsed using the [getParameters] function.
+///
+/// This function is passed the `Content-Type` header of the response as well as
+/// its body as a UTF-8-decoded string. It should return a map in the same
+/// format as the [standard JSON response](https://tools.ietf.org/html/rfc6749#section-5.1)
+Future<Client> clientCredentialsGrant(
+ Uri authorizationEndpoint, String? identifier, String? secret,
+ {Iterable<String>? scopes,
+ bool basicAuth = true,
+ http.Client? httpClient,
+ String? delimiter,
+ Map<String, dynamic> Function(MediaType? contentType, String body)?
+ getParameters}) async {
+ delimiter ??= ' ';
+ var startTime = DateTime.now();
+
+ var body = {'grant_type': 'client_credentials'};
+
+ var headers = <String, String>{};
+
+ if (identifier != null) {
+ if (basicAuth) {
+ headers['Authorization'] = basicAuthHeader(identifier, secret!);
+ } else {
+ body['client_id'] = identifier;
+ if (secret != null) body['client_secret'] = secret;
+ }
+ }
+
+ if (scopes != null && scopes.isNotEmpty) {
+ body['scope'] = scopes.join(delimiter);
+ }
+
+ httpClient ??= http.Client();
+ var response = await httpClient.post(authorizationEndpoint,
+ headers: headers, body: body);
+
+ var credentials = handleAccessTokenResponse(response, authorizationEndpoint,
+ startTime, scopes?.toList() ?? [], delimiter,
+ getParameters: getParameters);
+ return Client(credentials,
+ identifier: identifier, secret: secret, httpClient: httpClient);
+}
diff --git a/pkgs/oauth2/lib/src/credentials.dart b/pkgs/oauth2/lib/src/credentials.dart
new file mode 100644
index 0000000..088b482
--- /dev/null
+++ b/pkgs/oauth2/lib/src/credentials.dart
@@ -0,0 +1,267 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:collection';
+import 'dart:convert';
+
+import 'package:http/http.dart' as http;
+import 'package:http_parser/http_parser.dart';
+
+import 'handle_access_token_response.dart';
+import 'parameters.dart';
+import 'utils.dart';
+
+/// Type of the callback when credentials are refreshed.
+typedef CredentialsRefreshedCallback = void Function(Credentials);
+
+/// Credentials that prove that a client is allowed to access a resource on the
+/// resource owner's behalf.
+///
+/// These credentials are long-lasting and can be safely persisted across
+/// multiple runs of the program.
+///
+/// Many authorization servers will attach an expiration date to a set of
+/// credentials, along with a token that can be used to refresh the credentials
+/// once they've expired. The [http.Client] will automatically refresh its
+/// credentials when necessary. It's also possible to explicitly refresh them
+/// via [http.Client.refreshCredentials] or [Credentials.refresh].
+///
+/// Note that a given set of credentials can only be refreshed once, so be sure
+/// to save the refreshed credentials for future use.
+class Credentials {
+ /// A [String] used to separate scopes; defaults to `" "`.
+ String _delimiter;
+
+ /// The token that is sent to the resource server to prove the authorization
+ /// of a client.
+ final String accessToken;
+
+ /// The token that is sent to the authorization server to refresh the
+ /// credentials.
+ ///
+ /// This may be `null`, indicating that the credentials can't be refreshed.
+ final String? refreshToken;
+
+ /// The token that is received from the authorization server to enable
+ /// End-Users to be Authenticated, contains Claims, represented as a
+ /// JSON Web Token (JWT).
+ ///
+ /// This may be `null`, indicating that the 'openid' scope was not
+ /// requested (or not supported).
+ ///
+ /// [spec]: https://openid.net/specs/openid-connect-core-1_0.html#IDToken
+ final String? idToken;
+
+ /// The URL of the authorization server endpoint that's used to refresh the
+ /// credentials.
+ ///
+ /// This may be `null`, indicating that the credentials can't be refreshed.
+ final Uri? tokenEndpoint;
+
+ /// The specific permissions being requested from the authorization server.
+ ///
+ /// The scope strings are specific to the authorization server and may be
+ /// found in its documentation.
+ final List<String>? scopes;
+
+ /// The date at which these credentials will expire.
+ ///
+ /// This is likely to be a few seconds earlier than the server's idea of the
+ /// expiration date.
+ final DateTime? expiration;
+
+ /// The function used to parse parameters from a host's response.
+ final GetParameters _getParameters;
+
+ /// Whether or not these credentials have expired.
+ ///
+ /// Note that it's possible the credentials will expire shortly after this is
+ /// called. However, since the client's expiration date is kept a few seconds
+ /// earlier than the server's, there should be enough leeway to rely on this.
+ bool get isExpired {
+ var expiration = this.expiration;
+ return expiration != null && DateTime.now().isAfter(expiration);
+ }
+
+ /// Whether it's possible to refresh these credentials.
+ bool get canRefresh => refreshToken != null && tokenEndpoint != null;
+
+ /// Creates a new set of credentials.
+ ///
+ /// This class is usually not constructed directly; rather, it's accessed via
+ /// [Client.credentials] after a [Client] is created by
+ /// [AuthorizationCodeGrant]. Alternately, it may be loaded from a serialized
+ /// form via [Credentials.fromJson].
+ ///
+ /// The scope strings will be separated by the provided [delimiter]. This
+ /// defaults to `" "`, the OAuth2 standard, but some APIs (such as Facebook's)
+ /// use non-standard delimiters.
+ ///
+ /// By default, this follows the OAuth2 spec and requires the server's
+ /// responses to be in JSON format. However, some servers return non-standard
+ /// response formats, which can be parsed using the [getParameters] function.
+ ///
+ /// This function is passed the `Content-Type` header of the response as well
+ /// as its body as a UTF-8-decoded string. It should return a map in the same
+ /// format as the [standard JSON response][].
+ ///
+ /// [standard JSON response]: https://tools.ietf.org/html/rfc6749#section-5.1
+ Credentials(this.accessToken,
+ {this.refreshToken,
+ this.idToken,
+ this.tokenEndpoint,
+ Iterable<String>? scopes,
+ this.expiration,
+ String? delimiter,
+ Map<String, dynamic> Function(MediaType? mediaType, String body)?
+ getParameters})
+ : scopes = UnmodifiableListView(
+ // Explicitly type-annotate the list literal to work around
+ // sdk#24202.
+ scopes == null ? <String>[] : scopes.toList()),
+ _delimiter = delimiter ?? ' ',
+ _getParameters = getParameters ?? parseJsonParameters;
+
+ /// Loads a set of credentials from a JSON-serialized form.
+ ///
+ /// Throws a [FormatException] if the JSON is incorrectly formatted.
+ factory Credentials.fromJson(String json) {
+ void validate(bool condition, String message) {
+ if (condition) return;
+ throw FormatException('Failed to load credentials: $message.\n\n$json');
+ }
+
+ dynamic parsed;
+ try {
+ parsed = jsonDecode(json);
+ } on FormatException {
+ validate(false, 'invalid JSON');
+ }
+
+ validate(parsed is Map, 'was not a JSON map');
+
+ parsed = parsed as Map;
+ validate(parsed.containsKey('accessToken'),
+ 'did not contain required field "accessToken"');
+ validate(
+ parsed['accessToken'] is String,
+ 'required field "accessToken" was not a string, was '
+ '${parsed["accessToken"]}',
+ );
+
+ for (var stringField in ['refreshToken', 'idToken', 'tokenEndpoint']) {
+ var value = parsed[stringField];
+ validate(value == null || value is String,
+ 'field "$stringField" was not a string, was "$value"');
+ }
+
+ var scopes = parsed['scopes'];
+ validate(scopes == null || scopes is List,
+ 'field "scopes" was not a list, was "$scopes"');
+
+ var tokenEndpoint = parsed['tokenEndpoint'];
+ Uri? tokenEndpointUri;
+ if (tokenEndpoint != null) {
+ tokenEndpointUri = Uri.parse(tokenEndpoint as String);
+ }
+
+ var expiration = parsed['expiration'];
+ DateTime? expirationDateTime;
+ if (expiration != null) {
+ validate(expiration is int,
+ 'field "expiration" was not an int, was "$expiration"');
+ expiration = expiration as int;
+ expirationDateTime = DateTime.fromMillisecondsSinceEpoch(expiration);
+ }
+
+ return Credentials(
+ parsed['accessToken'] as String,
+ refreshToken: parsed['refreshToken'] as String?,
+ idToken: parsed['idToken'] as String?,
+ tokenEndpoint: tokenEndpointUri,
+ scopes: (scopes as List).map((scope) => scope as String),
+ expiration: expirationDateTime,
+ );
+ }
+
+ /// Serializes a set of credentials to JSON.
+ ///
+ /// Nothing is guaranteed about the output except that it's valid JSON and
+ /// compatible with [Credentials.toJson].
+ String toJson() => jsonEncode({
+ 'accessToken': accessToken,
+ 'refreshToken': refreshToken,
+ 'idToken': idToken,
+ 'tokenEndpoint': tokenEndpoint?.toString(),
+ 'scopes': scopes,
+ 'expiration': expiration?.millisecondsSinceEpoch
+ });
+
+ /// Returns a new set of refreshed credentials.
+ ///
+ /// See [Client.identifier] and [Client.secret] for explanations of those
+ /// parameters.
+ ///
+ /// You may request different scopes than the default by passing in
+ /// [newScopes]. These must be a subset of [scopes].
+ ///
+ /// This throws an [ArgumentError] if [secret] is passed without [identifier],
+ /// a [StateError] if these credentials can't be refreshed, an
+ /// [AuthorizationException] if refreshing the credentials fails, or a
+ /// [FormatException] if the authorization server returns invalid responses.
+ Future<Credentials> refresh(
+ {String? identifier,
+ String? secret,
+ Iterable<String>? newScopes,
+ bool basicAuth = true,
+ http.Client? httpClient}) async {
+ var scopes = this.scopes;
+ if (newScopes != null) scopes = newScopes.toList();
+ scopes ??= [];
+ httpClient ??= http.Client();
+
+ if (identifier == null && secret != null) {
+ throw ArgumentError('secret may not be passed without identifier.');
+ }
+
+ var startTime = DateTime.now();
+ var tokenEndpoint = this.tokenEndpoint;
+ if (refreshToken == null) {
+ throw StateError("Can't refresh credentials without a refresh "
+ 'token.');
+ } else if (tokenEndpoint == null) {
+ throw StateError("Can't refresh credentials without a token "
+ 'endpoint.');
+ }
+
+ var headers = <String, String>{};
+
+ var body = {'grant_type': 'refresh_token', 'refresh_token': refreshToken};
+ if (scopes.isNotEmpty) body['scope'] = scopes.join(_delimiter);
+
+ if (basicAuth && secret != null) {
+ headers['Authorization'] = basicAuthHeader(identifier!, secret);
+ } else {
+ if (identifier != null) body['client_id'] = identifier;
+ if (secret != null) body['client_secret'] = secret;
+ }
+
+ var response =
+ await httpClient.post(tokenEndpoint, headers: headers, body: body);
+ var credentials = handleAccessTokenResponse(
+ response, tokenEndpoint, startTime, scopes, _delimiter,
+ getParameters: _getParameters);
+
+ // The authorization server may issue a new refresh token. If it doesn't,
+ // we should re-use the one we already have.
+ if (credentials.refreshToken != null) return credentials;
+ return Credentials(credentials.accessToken,
+ refreshToken: refreshToken,
+ idToken: credentials.idToken,
+ tokenEndpoint: credentials.tokenEndpoint,
+ scopes: credentials.scopes,
+ expiration: credentials.expiration);
+ }
+}
diff --git a/pkgs/oauth2/lib/src/expiration_exception.dart b/pkgs/oauth2/lib/src/expiration_exception.dart
new file mode 100644
index 0000000..d72fcf6
--- /dev/null
+++ b/pkgs/oauth2/lib/src/expiration_exception.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2012, 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 'credentials.dart';
+
+/// An exception raised when attempting to use expired OAuth2 credentials.
+class ExpirationException implements Exception {
+ /// The expired credentials.
+ final Credentials credentials;
+
+ /// Creates an ExpirationException.
+ ExpirationException(this.credentials);
+
+ /// Provides a string description of the ExpirationException.
+ @override
+ String toString() =>
+ "OAuth2 credentials have expired and can't be refreshed.";
+}
diff --git a/pkgs/oauth2/lib/src/handle_access_token_response.dart b/pkgs/oauth2/lib/src/handle_access_token_response.dart
new file mode 100644
index 0000000..f318e3b
--- /dev/null
+++ b/pkgs/oauth2/lib/src/handle_access_token_response.dart
@@ -0,0 +1,158 @@
+// Copyright (c) 2012, 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:http/http.dart' as http;
+import 'package:http_parser/http_parser.dart';
+
+import 'authorization_exception.dart';
+import 'credentials.dart';
+import 'parameters.dart';
+
+/// The amount of time to add as a "grace period" for credential expiration.
+///
+/// This allows credential expiration checks to remain valid for a reasonable
+/// amount of time.
+const _expirationGrace = Duration(seconds: 10);
+
+/// Handles a response from the authorization server that contains an access
+/// token.
+///
+/// This response format is common across several different components of the
+/// OAuth2 flow.
+///
+/// By default, this follows the OAuth2 spec and requires the server's responses
+/// to be in JSON format. However, some servers return non-standard response
+/// formats, which can be parsed using the [getParameters] function.
+///
+/// This function is passed the `Content-Type` header of the response as well as
+/// its body as a UTF-8-decoded string. It should return a map in the same
+/// format as the [standard JSON response][].
+///
+/// [standard JSON response]: https://tools.ietf.org/html/rfc6749#section-5.1
+Credentials handleAccessTokenResponse(http.Response response, Uri tokenEndpoint,
+ DateTime startTime, List<String>? scopes, String delimiter,
+ {Map<String, dynamic> Function(MediaType? contentType, String body)?
+ getParameters}) {
+ getParameters ??= parseJsonParameters;
+
+ try {
+ if (response.statusCode != 200) {
+ _handleErrorResponse(response, tokenEndpoint, getParameters);
+ }
+
+ var contentTypeString = response.headers['content-type'];
+ if (contentTypeString == null) {
+ throw const FormatException('Missing Content-Type string.');
+ }
+
+ var parameters =
+ getParameters(MediaType.parse(contentTypeString), response.body);
+
+ for (var requiredParameter in ['access_token', 'token_type']) {
+ if (!parameters.containsKey(requiredParameter)) {
+ throw FormatException(
+ 'did not contain required parameter "$requiredParameter"');
+ } else if (parameters[requiredParameter] is! String) {
+ throw FormatException(
+ 'required parameter "$requiredParameter" was not a string, was '
+ '"${parameters[requiredParameter]}"');
+ }
+ }
+
+ // TODO(nweiz): support the "mac" token type
+ // (http://tools.ietf.org/html/draft-ietf-oauth-v2-http-mac-01)
+ if ((parameters['token_type'] as String).toLowerCase() != 'bearer') {
+ throw FormatException(
+ '"$tokenEndpoint": unknown token type "${parameters['token_type']}"');
+ }
+
+ var expiresIn = parameters['expires_in'];
+ if (expiresIn != null) {
+ if (expiresIn is String) {
+ try {
+ expiresIn = double.parse(expiresIn).toInt();
+ } on FormatException {
+ throw FormatException(
+ 'parameter "expires_in" could not be parsed as in, was: '
+ '"$expiresIn"',
+ );
+ }
+ } else if (expiresIn is! int) {
+ throw FormatException(
+ 'parameter "expires_in" was not an int, was: "$expiresIn"');
+ }
+ }
+
+ for (var name in ['refresh_token', 'id_token', 'scope']) {
+ var value = parameters[name];
+ if (value != null && value is! String) {
+ throw FormatException(
+ 'parameter "$name" was not a string, was "$value"');
+ }
+ }
+
+ var scope = parameters['scope'] as String?;
+ if (scope != null) scopes = scope.split(delimiter);
+
+ var expiration = expiresIn == null
+ ? null
+ : startTime.add(Duration(seconds: expiresIn as int) - _expirationGrace);
+
+ return Credentials(
+ parameters['access_token'] as String,
+ refreshToken: parameters['refresh_token'] as String?,
+ idToken: parameters['id_token'] as String?,
+ tokenEndpoint: tokenEndpoint,
+ scopes: scopes,
+ expiration: expiration,
+ );
+ } on FormatException catch (e) {
+ throw FormatException('Invalid OAuth response for "$tokenEndpoint": '
+ '${e.message}.\n\n${response.body}');
+ }
+}
+
+/// Throws the appropriate exception for an error response from the
+/// authorization server.
+void _handleErrorResponse(
+ http.Response response, Uri tokenEndpoint, GetParameters getParameters) {
+ // OAuth2 mandates a 400 or 401 response code for access token error
+ // responses. If it's not a 400 reponse, the server is either broken or
+ // off-spec.
+ if (response.statusCode != 400 && response.statusCode != 401) {
+ var reason = '';
+ var reasonPhrase = response.reasonPhrase;
+ if (reasonPhrase != null && reasonPhrase.isNotEmpty) {
+ reason = ' $reasonPhrase';
+ }
+ throw FormatException('OAuth request for "$tokenEndpoint" failed '
+ 'with status ${response.statusCode}$reason.\n\n${response.body}');
+ }
+
+ var contentTypeString = response.headers['content-type'];
+ var contentType =
+ contentTypeString == null ? null : MediaType.parse(contentTypeString);
+
+ var parameters = getParameters(contentType, response.body);
+
+ if (!parameters.containsKey('error')) {
+ throw const FormatException('did not contain required parameter "error"');
+ } else if (parameters['error'] is! String) {
+ throw FormatException('required parameter "error" was not a string, was '
+ '"${parameters["error"]}"');
+ }
+
+ for (var name in ['error_description', 'error_uri']) {
+ var value = parameters[name];
+
+ if (value != null && value is! String) {
+ throw FormatException('parameter "$name" was not a string, was "$value"');
+ }
+ }
+
+ var uriString = parameters['error_uri'] as String?;
+ var uri = uriString == null ? null : Uri.parse(uriString);
+ var description = parameters['error_description'] as String?;
+ throw AuthorizationException(parameters['error'] as String, description, uri);
+}
diff --git a/pkgs/oauth2/lib/src/parameters.dart b/pkgs/oauth2/lib/src/parameters.dart
new file mode 100644
index 0000000..ecc6559
--- /dev/null
+++ b/pkgs/oauth2/lib/src/parameters.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+
+import 'package:http_parser/http_parser.dart';
+
+/// The type of a callback that parses parameters from an HTTP response.
+typedef GetParameters = Map<String, dynamic> Function(
+ MediaType? contentType, String body);
+
+/// Parses parameters from a response with a JSON body, as per the
+/// [OAuth2 spec][].
+///
+/// [OAuth2 spec]: https://tools.ietf.org/html/rfc6749#section-5.1
+Map<String, dynamic> parseJsonParameters(MediaType? contentType, String body) {
+ // The spec requires a content-type of application/json, but some endpoints
+ // (e.g. Dropbox) serve it as text/javascript instead.
+ if (contentType == null ||
+ (contentType.mimeType != 'application/json' &&
+ contentType.mimeType != 'text/javascript')) {
+ throw FormatException(
+ 'Content-Type was "$contentType", expected "application/json"');
+ }
+
+ var untypedParameters = jsonDecode(body);
+ if (untypedParameters is Map<String, dynamic>) {
+ return untypedParameters;
+ }
+
+ throw FormatException('Parameters must be a map, was "$untypedParameters"');
+}
diff --git a/pkgs/oauth2/lib/src/resource_owner_password_grant.dart b/pkgs/oauth2/lib/src/resource_owner_password_grant.dart
new file mode 100644
index 0000000..96fb503
--- /dev/null
+++ b/pkgs/oauth2/lib/src/resource_owner_password_grant.dart
@@ -0,0 +1,94 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:http/http.dart' as http;
+import 'package:http_parser/http_parser.dart';
+
+import 'client.dart';
+import 'credentials.dart';
+import 'handle_access_token_response.dart';
+import 'utils.dart';
+
+/// Obtains credentials using a [resource owner password grant](https://tools.ietf.org/html/rfc6749#section-1.3.3).
+///
+/// This mode of authorization uses the user's username and password to obtain
+/// an authentication token, which can then be stored. This is safer than
+/// storing the username and password directly, but it should be avoided if any
+/// other authorization method is available, since it requires the user to
+/// provide their username and password to a third party (you).
+///
+/// The client [identifier] and [secret] may be issued by the server, and are
+/// used to identify and authenticate your specific OAuth2 client. These are
+/// usually global to the program using this library.
+///
+/// The specific permissions being requested from the authorization server may
+/// be specified via [scopes]. The scope strings are specific to the
+/// authorization server and may be found in its documentation. Note that you
+/// may not be granted access to every scope you request; you may check the
+/// [Credentials.scopes] field of [Client.credentials] to see which scopes you
+/// were granted.
+///
+/// The scope strings will be separated by the provided [delimiter]. This
+/// defaults to `" "`, the OAuth2 standard, but some APIs (such as Facebook's)
+/// use non-standard delimiters.
+///
+/// By default, this follows the OAuth2 spec and requires the server's responses
+/// to be in JSON format. However, some servers return non-standard response
+/// formats, which can be parsed using the [getParameters] function.
+///
+/// This function is passed the `Content-Type` header of the response as well as
+/// its body as a UTF-8-decoded string. It should return a map in the same
+/// format as the [standard JSON response][].
+///
+/// [standard JSON response]: https://tools.ietf.org/html/rfc6749#section-5.1
+Future<Client> resourceOwnerPasswordGrant(
+ Uri authorizationEndpoint, String username, String password,
+ {String? identifier,
+ String? secret,
+ Iterable<String>? scopes,
+ bool basicAuth = true,
+ CredentialsRefreshedCallback? onCredentialsRefreshed,
+ http.Client? httpClient,
+ String? delimiter,
+ Map<String, dynamic> Function(MediaType? contentType, String body)?
+ getParameters}) async {
+ delimiter ??= ' ';
+ var startTime = DateTime.now();
+
+ var body = {
+ 'grant_type': 'password',
+ 'username': username,
+ 'password': password
+ };
+
+ var headers = <String, String>{};
+
+ if (identifier != null) {
+ if (basicAuth) {
+ headers['Authorization'] = basicAuthHeader(identifier, secret!);
+ } else {
+ body['client_id'] = identifier;
+ if (secret != null) body['client_secret'] = secret;
+ }
+ }
+
+ if (scopes != null && scopes.isNotEmpty) {
+ body['scope'] = scopes.join(delimiter);
+ }
+
+ httpClient ??= http.Client();
+ var response = await httpClient.post(authorizationEndpoint,
+ headers: headers, body: body);
+
+ var credentials = handleAccessTokenResponse(
+ response, authorizationEndpoint, startTime, scopes?.toList(), delimiter,
+ getParameters: getParameters);
+ return Client(credentials,
+ identifier: identifier,
+ secret: secret,
+ httpClient: httpClient,
+ onCredentialsRefreshed: onCredentialsRefreshed);
+}
diff --git a/pkgs/oauth2/lib/src/utils.dart b/pkgs/oauth2/lib/src/utils.dart
new file mode 100644
index 0000000..2a22b9f
--- /dev/null
+++ b/pkgs/oauth2/lib/src/utils.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2012, 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';
+
+/// Adds additional query parameters to [url], overwriting the original
+/// parameters if a name conflict occurs.
+Uri addQueryParameters(Uri url, Map<String, String> parameters) => url.replace(
+ queryParameters: Map.from(url.queryParameters)..addAll(parameters));
+
+String basicAuthHeader(String identifier, String secret) {
+ var userPass = '${Uri.encodeFull(identifier)}:${Uri.encodeFull(secret)}';
+ return 'Basic ${base64Encode(ascii.encode(userPass))}';
+}
diff --git a/pkgs/oauth2/pubspec.yaml b/pkgs/oauth2/pubspec.yaml
new file mode 100644
index 0000000..75ded18
--- /dev/null
+++ b/pkgs/oauth2/pubspec.yaml
@@ -0,0 +1,20 @@
+name: oauth2
+version: 2.0.4-wip
+description: >-
+ A client library for authenticating with a remote service via OAuth2 on
+ behalf of a user, and making authorized HTTP requests with the user's
+ OAuth2 credentials.
+repository: https://github.com/dart-lang/tools/tree/main/pkgs/oauth2
+
+environment:
+ sdk: ^3.4.0
+
+dependencies:
+ collection: ^1.15.0
+ crypto: ^3.0.0
+ http: ^1.0.0
+ http_parser: ^4.0.0
+
+dev_dependencies:
+ dart_flutter_team_lints: ^3.0.0
+ test: ^1.16.0
diff --git a/pkgs/oauth2/test/authorization_code_grant_test.dart b/pkgs/oauth2/test/authorization_code_grant_test.dart
new file mode 100644
index 0000000..06e88af
--- /dev/null
+++ b/pkgs/oauth2/test/authorization_code_grant_test.dart
@@ -0,0 +1,391 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:convert';
+
+import 'package:http/http.dart' as http;
+import 'package:oauth2/oauth2.dart' as oauth2;
+import 'package:test/test.dart';
+
+import 'utils.dart';
+
+final redirectUrl = Uri.parse('http://example.com/redirect');
+
+void main() {
+ late ExpectClient client;
+ late oauth2.AuthorizationCodeGrant grant;
+ setUp(() {
+ client = ExpectClient();
+ grant = oauth2.AuthorizationCodeGrant(
+ 'identifier',
+ Uri.parse('https://example.com/authorization'),
+ Uri.parse('https://example.com/token'),
+ secret: 'secret',
+ httpClient: client);
+ });
+
+ group('.getAuthorizationUrl', () {
+ test('builds the correct URL', () {
+ expect(
+ grant.getAuthorizationUrl(redirectUrl).toString(),
+ allOf([
+ startsWith('https://example.com/authorization?response_type=code'),
+ contains('&client_id=identifier'),
+ contains('&redirect_uri=http%3A%2F%2Fexample.com%2Fredirect'),
+ matches(r'&code_challenge=[A-Za-z0-9\+\/\-\_]{43}'),
+ contains('&code_challenge_method=S256')
+ ]));
+ });
+
+ test('builds the correct URL with scopes', () {
+ var authorizationUrl = grant
+ .getAuthorizationUrl(redirectUrl, scopes: ['scope', 'other/scope']);
+ expect(
+ authorizationUrl.toString(),
+ allOf([
+ startsWith('https://example.com/authorization?response_type=code'),
+ contains('&client_id=identifier'),
+ contains('&redirect_uri=http%3A%2F%2Fexample.com%2Fredirect'),
+ matches(r'&code_challenge=[A-Za-z0-9\+\/\-\_]{43}'),
+ contains('&code_challenge_method=S256'),
+ contains('&scope=scope+other%2Fscope')
+ ]));
+ });
+
+ test('builds the correct URL with passed in code verifier', () {
+ const codeVerifier =
+ 'it1shei7LooGoh3looxaa4sieveijeib2zecauz2oo8aebae5aehee0ahPirewoh'
+ '5Bo6Maexooqui3uL2si6ahweiv7shauc1shahxooveoB3aeyahsaiye0Egh3raix';
+ const expectedCodeChallenge =
+ 'EjfFMv8TFPd3GuNxAn5COhlWBGpfZLimHett7ypJfJ0';
+ var grant = oauth2.AuthorizationCodeGrant(
+ 'identifier',
+ Uri.parse('https://example.com/authorization'),
+ Uri.parse('https://example.com/token'),
+ secret: 'secret',
+ httpClient: client,
+ codeVerifier: codeVerifier);
+ expect(
+ grant.getAuthorizationUrl(redirectUrl).toString(),
+ allOf([
+ startsWith('https://example.com/authorization?response_type=code'),
+ contains('&client_id=identifier'),
+ contains('&redirect_uri=http%3A%2F%2Fexample.com%2Fredirect'),
+ contains('&code_challenge=$expectedCodeChallenge'),
+ contains('&code_challenge_method=S256')
+ ]));
+ });
+
+ test('separates scopes with the correct delimiter', () {
+ var grant = oauth2.AuthorizationCodeGrant(
+ 'identifier',
+ Uri.parse('https://example.com/authorization'),
+ Uri.parse('https://example.com/token'),
+ secret: 'secret',
+ httpClient: client,
+ delimiter: '_');
+ var authorizationUrl = grant
+ .getAuthorizationUrl(redirectUrl, scopes: ['scope', 'other/scope']);
+ expect(
+ authorizationUrl.toString(),
+ allOf([
+ startsWith('https://example.com/authorization?response_type=code'),
+ contains('&client_id=identifier'),
+ contains('&redirect_uri=http%3A%2F%2Fexample.com%2Fredirect'),
+ matches(r'&code_challenge=[A-Za-z0-9\+\/\-\_]{43}'),
+ contains('&code_challenge_method=S256'),
+ contains('&scope=scope_other%2Fscope')
+ ]));
+ });
+
+ test('builds the correct URL with state', () {
+ var authorizationUrl =
+ grant.getAuthorizationUrl(redirectUrl, state: 'state');
+ expect(
+ authorizationUrl.toString(),
+ allOf([
+ startsWith('https://example.com/authorization?response_type=code'),
+ contains('&client_id=identifier'),
+ contains('&redirect_uri=http%3A%2F%2Fexample.com%2Fredirect'),
+ matches(r'&code_challenge=[A-Za-z0-9\+\/\-\_]{43}'),
+ contains('&code_challenge_method=S256'),
+ contains('&state=state')
+ ]));
+ });
+
+ test('merges with existing query parameters', () {
+ grant = oauth2.AuthorizationCodeGrant(
+ 'identifier',
+ Uri.parse('https://example.com/authorization?query=value'),
+ Uri.parse('https://example.com/token'),
+ secret: 'secret',
+ httpClient: client);
+
+ var authorizationUrl = grant.getAuthorizationUrl(redirectUrl);
+ expect(
+ authorizationUrl.toString(),
+ allOf([
+ startsWith('https://example.com/authorization?query=value'),
+ contains('&response_type=code'),
+ contains('&client_id=identifier'),
+ contains('&redirect_uri=http%3A%2F%2Fexample.com%2Fredirect'),
+ matches(r'&code_challenge=[A-Za-z0-9\+\/\-\_]{43}'),
+ contains('&code_challenge_method=S256'),
+ ]));
+ });
+
+ test("can't be called twice", () {
+ grant.getAuthorizationUrl(redirectUrl);
+ expect(() => grant.getAuthorizationUrl(redirectUrl), throwsStateError);
+ });
+ });
+
+ group('.handleAuthorizationResponse', () {
+ test("can't be called before .getAuthorizationUrl", () {
+ expect(grant.handleAuthorizationResponse({}), throwsStateError);
+ });
+
+ test("can't be called twice", () {
+ grant.getAuthorizationUrl(redirectUrl);
+ expect(grant.handleAuthorizationResponse({'code': 'auth code'}),
+ throwsFormatException);
+ expect(grant.handleAuthorizationResponse({'code': 'auth code'}),
+ throwsStateError);
+ });
+
+ test('must have a state parameter if the authorization URL did', () {
+ grant.getAuthorizationUrl(redirectUrl, state: 'state');
+ expect(grant.handleAuthorizationResponse({'code': 'auth code'}),
+ throwsFormatException);
+ });
+
+ test('must have the same state parameter the authorization URL did', () {
+ grant.getAuthorizationUrl(redirectUrl, state: 'state');
+ expect(
+ grant.handleAuthorizationResponse(
+ {'code': 'auth code', 'state': 'other state'}),
+ throwsFormatException);
+ });
+
+ test('must have a code parameter', () {
+ grant.getAuthorizationUrl(redirectUrl);
+ expect(grant.handleAuthorizationResponse({}), throwsFormatException);
+ });
+
+ test('with an error parameter throws an AuthorizationException', () {
+ grant.getAuthorizationUrl(redirectUrl);
+ expect(grant.handleAuthorizationResponse({'error': 'invalid_request'}),
+ throwsA(isA<oauth2.AuthorizationException>()));
+ });
+
+ test('sends an authorization code request', () {
+ grant.getAuthorizationUrl(redirectUrl);
+ client.expectRequest((request) {
+ expect(request.method, equals('POST'));
+ expect(request.url.toString(), equals(grant.tokenEndpoint.toString()));
+ expect(
+ request.bodyFields,
+ allOf([
+ containsPair('grant_type', 'authorization_code'),
+ containsPair('code', 'auth code'),
+ containsPair('redirect_uri', redirectUrl.toString()),
+ containsPair(
+ 'code_verifier', matches(r'[A-Za-z0-9\-\.\_\~]{128}'))
+ ]));
+ expect(request.headers,
+ containsPair('Authorization', 'Basic aWRlbnRpZmllcjpzZWNyZXQ='));
+
+ return Future.value(http.Response(
+ jsonEncode({
+ 'access_token': 'access token',
+ 'token_type': 'bearer',
+ }),
+ 200,
+ headers: {'content-type': 'application/json'}));
+ });
+
+ expect(
+ grant.handleAuthorizationResponse({'code': 'auth code'}).then(
+ (client) => client.credentials.accessToken),
+ completion(equals('access token')));
+ });
+ });
+
+ group('.handleAuthorizationCode', () {
+ test("can't be called before .getAuthorizationUrl", () {
+ expect(grant.handleAuthorizationCode('auth code'), throwsStateError);
+ });
+
+ test("can't be called twice", () {
+ grant.getAuthorizationUrl(redirectUrl);
+ expect(grant.handleAuthorizationCode('auth code'), throwsFormatException);
+ expect(grant.handleAuthorizationCode('auth code'), throwsStateError);
+ });
+
+ test('sends an authorization code request', () async {
+ grant.getAuthorizationUrl(redirectUrl);
+ client.expectRequest((request) {
+ expect(request.method, equals('POST'));
+ expect(request.url.toString(), equals(grant.tokenEndpoint.toString()));
+ expect(
+ request.bodyFields,
+ allOf([
+ containsPair('grant_type', 'authorization_code'),
+ containsPair('code', 'auth code'),
+ containsPair('redirect_uri', redirectUrl.toString()),
+ containsPair(
+ 'code_verifier', matches(r'[A-Za-z0-9\-\.\_\~]{128}'))
+ ]));
+ expect(request.headers,
+ containsPair('Authorization', 'Basic aWRlbnRpZmllcjpzZWNyZXQ='));
+
+ return Future.value(http.Response(
+ jsonEncode({
+ 'access_token': 'access token',
+ 'token_type': 'bearer',
+ }),
+ 200,
+ headers: {'content-type': 'application/json'}));
+ });
+
+ expect(
+ await grant.handleAuthorizationCode('auth code'),
+ isA<oauth2.Client>().having((c) => c.credentials.accessToken,
+ 'credentials.accessToken', 'access token'));
+ });
+ });
+
+ group('with basicAuth: false', () {
+ setUp(() {
+ client = ExpectClient();
+ grant = oauth2.AuthorizationCodeGrant(
+ 'identifier',
+ Uri.parse('https://example.com/authorization'),
+ Uri.parse('https://example.com/token'),
+ secret: 'secret',
+ basicAuth: false,
+ httpClient: client);
+ });
+
+ test('.handleAuthorizationResponse sends an authorization code request',
+ () {
+ grant.getAuthorizationUrl(redirectUrl);
+ client.expectRequest((request) {
+ expect(request.method, equals('POST'));
+ expect(request.url.toString(), equals(grant.tokenEndpoint.toString()));
+ expect(
+ request.bodyFields,
+ allOf([
+ containsPair('grant_type', 'authorization_code'),
+ containsPair('code', 'auth code'),
+ containsPair('redirect_uri', redirectUrl.toString()),
+ containsPair(
+ 'code_verifier', matches(r'[A-Za-z0-9\-\.\_\~]{128}')),
+ containsPair('client_id', 'identifier'),
+ containsPair('client_secret', 'secret')
+ ]));
+
+ return Future.value(http.Response(
+ jsonEncode({
+ 'access_token': 'access token',
+ 'token_type': 'bearer',
+ }),
+ 200,
+ headers: {'content-type': 'application/json'}));
+ });
+
+ expect(
+ grant.handleAuthorizationResponse({'code': 'auth code'}).then(
+ (client) => client.credentials.accessToken),
+ completion(equals('access token')));
+ });
+
+ test('.handleAuthorizationCode sends an authorization code request',
+ () async {
+ grant.getAuthorizationUrl(redirectUrl);
+ client.expectRequest((request) {
+ expect(request.method, equals('POST'));
+ expect(request.url.toString(), equals(grant.tokenEndpoint.toString()));
+ expect(
+ request.bodyFields,
+ allOf([
+ containsPair('grant_type', 'authorization_code'),
+ containsPair('code', 'auth code'),
+ containsPair('redirect_uri', redirectUrl.toString()),
+ containsPair(
+ 'code_verifier', matches(r'[A-Za-z0-9\-\.\_\~]{128}')),
+ containsPair('client_id', 'identifier'),
+ containsPair('client_secret', 'secret')
+ ]));
+
+ return Future.value(http.Response(
+ jsonEncode({
+ 'access_token': 'access token',
+ 'token_type': 'bearer',
+ }),
+ 200,
+ headers: {'content-type': 'application/json'}));
+ });
+
+ expect(
+ await grant.handleAuthorizationCode('auth code'),
+ isA<oauth2.Client>().having((c) => c.credentials.accessToken,
+ 'credentials.accessToken', 'access token'));
+ });
+ });
+
+ group('onCredentialsRefreshed', () {
+ test('is correctly propagated', () async {
+ var isCallbackInvoked = false;
+ var grant = oauth2.AuthorizationCodeGrant(
+ 'identifier',
+ Uri.parse('https://example.com/authorization'),
+ Uri.parse('https://example.com/token'),
+ secret: 'secret',
+ basicAuth: false,
+ httpClient: client, onCredentialsRefreshed: (credentials) {
+ isCallbackInvoked = true;
+ });
+
+ grant.getAuthorizationUrl(redirectUrl);
+ client.expectRequest(
+ (request) => Future.value(
+ http.Response(
+ jsonEncode({
+ 'access_token': 'access token',
+ 'token_type': 'bearer',
+ 'expires_in': -3600,
+ 'refresh_token': 'refresh token',
+ }),
+ 200,
+ headers: {'content-type': 'application/json'},
+ ),
+ ),
+ );
+
+ var oauth2Client = await grant.handleAuthorizationCode('auth code');
+
+ client.expectRequest(
+ (request) => Future.value(
+ http.Response(
+ jsonEncode({
+ 'access_token': 'new access token',
+ 'token_type': 'bearer',
+ }),
+ 200,
+ headers: {'content-type': 'application/json'},
+ ),
+ ),
+ );
+
+ client.expectRequest(
+ (request) => Future.value(http.Response('good job', 200)));
+
+ await oauth2Client.read(Uri.parse('http://example.com/resource'));
+
+ expect(isCallbackInvoked, equals(true));
+ });
+ });
+}
diff --git a/pkgs/oauth2/test/client_credentials_grant_test.dart b/pkgs/oauth2/test/client_credentials_grant_test.dart
new file mode 100644
index 0000000..28de425
--- /dev/null
+++ b/pkgs/oauth2/test/client_credentials_grant_test.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2012, 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.
+
+@TestOn('vm')
+library;
+
+import 'dart:convert';
+
+import 'package:http/http.dart' as http;
+import 'package:oauth2/oauth2.dart' as oauth2;
+import 'package:test/test.dart';
+
+import 'utils.dart';
+
+final success = jsonEncode({
+ 'access_token': '2YotnFZFEjr1zCsicMWpAA',
+ 'token_type': 'bearer',
+ 'expires_in': 3600,
+ 'refresh_token': 'tGzv3JOkF0XG5Qx2TlKWIA',
+});
+
+String auth = 'Basic Y2xpZW50OnNlY3JldA==';
+Uri authEndpoint = Uri.parse('https://example.com');
+
+void main() {
+ late ExpectClient expectClient;
+
+ setUp(() => expectClient = ExpectClient());
+
+ group('basic', () {
+ test('builds correct request with client when using basic auth for client',
+ () async {
+ expectClient.expectRequest((request) async {
+ expect(auth, equals(request.headers['authorization']));
+ expect(request.bodyFields['grant_type'], equals('client_credentials'));
+ return http.Response(success, 200,
+ headers: {'content-type': 'application/json'});
+ });
+
+ var client = await oauth2.clientCredentialsGrant(
+ authEndpoint, 'client', 'secret',
+ httpClient: expectClient);
+
+ expect(client.credentials, isNotNull);
+ expect(client.credentials.accessToken, equals('2YotnFZFEjr1zCsicMWpAA'));
+ });
+
+ test('builds correct request when using query parameters for client',
+ () async {
+ expectClient.expectRequest((request) async {
+ expect(request.bodyFields['grant_type'], equals('client_credentials'));
+ expect(request.bodyFields['client_id'], equals('client'));
+ expect(request.bodyFields['client_secret'], equals('secret'));
+ return http.Response(success, 200,
+ headers: {'content-type': 'application/json'});
+ });
+
+ var client = await oauth2.clientCredentialsGrant(
+ authEndpoint, 'client', 'secret',
+ basicAuth: false, httpClient: expectClient);
+ expect(client.credentials, isNotNull);
+ expect(client.credentials.accessToken, equals('2YotnFZFEjr1zCsicMWpAA'));
+ });
+
+ test('builds correct request using scope', () async {
+ expectClient.expectRequest((request) async {
+ expect(auth, equals(request.headers['authorization']));
+ expect(request.bodyFields['grant_type'], equals('client_credentials'));
+ expect(request.bodyFields['scope'], equals('one two'));
+ return http.Response(success, 200,
+ headers: {'content-type': 'application/json'});
+ });
+
+ var client = await oauth2.clientCredentialsGrant(
+ authEndpoint, 'client', 'secret',
+ scopes: ['one', 'two'], httpClient: expectClient);
+ expect(client.credentials, isNotNull);
+ expect(client.credentials.accessToken, equals('2YotnFZFEjr1zCsicMWpAA'));
+ });
+
+ test('builds correct request using scope with custom delimiter', () async {
+ expectClient.expectRequest((request) async {
+ expect(request.bodyFields['grant_type'], equals('client_credentials'));
+ expect(request.bodyFields['scope'], equals('one,two'));
+ return http.Response(success, 200,
+ headers: {'content-type': 'application/json'});
+ });
+
+ await oauth2.clientCredentialsGrant(authEndpoint, 'client', 'secret',
+ scopes: ['one', 'two'], httpClient: expectClient, delimiter: ',');
+ });
+
+ test('merges with existing query parameters', () async {
+ var authEndpoint = Uri.parse('https://example.com?query=value');
+
+ expectClient.expectRequest((request) async {
+ expect(request.bodyFields['grant_type'], equals('client_credentials'));
+ expect(request.bodyFields['client_id'], equals('client'));
+ expect(request.bodyFields['client_secret'], equals('secret'));
+ expect(request.url.queryParameters['query'], equals('value'));
+ return http.Response(success, 200,
+ headers: {'content-type': 'application/json'});
+ });
+
+ var client = await oauth2.clientCredentialsGrant(
+ authEndpoint, 'client', 'secret',
+ basicAuth: false, httpClient: expectClient);
+ expect(client.credentials, isNotNull);
+ expect(client.credentials.accessToken, equals('2YotnFZFEjr1zCsicMWpAA'));
+ });
+ });
+}
diff --git a/pkgs/oauth2/test/client_test.dart b/pkgs/oauth2/test/client_test.dart
new file mode 100644
index 0000000..3c30d36
--- /dev/null
+++ b/pkgs/oauth2/test/client_test.dart
@@ -0,0 +1,287 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:convert';
+
+import 'package:http/http.dart' as http;
+import 'package:oauth2/oauth2.dart' as oauth2;
+import 'package:test/test.dart';
+
+import 'utils.dart';
+
+final Uri requestUri = Uri.parse('http://example.com/resource');
+
+final Uri tokenEndpoint = Uri.parse('http://example.com/token');
+
+void main() {
+ late ExpectClient httpClient;
+
+ setUp(() => httpClient = ExpectClient());
+
+ group('with expired credentials', () {
+ test("that can't be refreshed throws an ExpirationException on send", () {
+ var expiration = DateTime.now().subtract(const Duration(hours: 1));
+ var credentials =
+ oauth2.Credentials('access token', expiration: expiration);
+ var client = oauth2.Client(credentials,
+ identifier: 'identifier', secret: 'secret', httpClient: httpClient);
+
+ expect(client.get(requestUri),
+ throwsA(const TypeMatcher<oauth2.ExpirationException>()));
+ });
+
+ test(
+ 'that can be refreshed refreshes the credentials and sends the '
+ 'request', () async {
+ var expiration = DateTime.now().subtract(const Duration(hours: 1));
+ var credentials = oauth2.Credentials('access token',
+ refreshToken: 'refresh token',
+ tokenEndpoint: tokenEndpoint,
+ expiration: expiration);
+ var client = oauth2.Client(credentials,
+ identifier: 'identifier', secret: 'secret', httpClient: httpClient);
+
+ httpClient.expectRequest((request) {
+ expect(request.method, equals('POST'));
+ expect(request.url.toString(), equals(tokenEndpoint.toString()));
+ return Future.value(http.Response(
+ jsonEncode(
+ {'access_token': 'new access token', 'token_type': 'bearer'}),
+ 200,
+ headers: {'content-type': 'application/json'}));
+ });
+
+ httpClient.expectRequest((request) {
+ expect(request.method, equals('GET'));
+ expect(request.url.toString(), equals(requestUri.toString()));
+ expect(request.headers['authorization'],
+ equals('Bearer new access token'));
+
+ return Future.value(http.Response('good job', 200));
+ });
+
+ await client.read(requestUri);
+ expect(client.credentials.accessToken, equals('new access token'));
+ });
+
+ test(
+ 'that can be refreshed refreshes only once if multiple requests are made',
+ () async {
+ var expiration = DateTime.now().subtract(const Duration(hours: 1));
+ var credentials = oauth2.Credentials('access token',
+ refreshToken: 'refresh token',
+ tokenEndpoint: tokenEndpoint,
+ expiration: expiration);
+ var client = oauth2.Client(credentials,
+ identifier: 'identifier', secret: 'secret', httpClient: httpClient);
+
+ httpClient.expectRequest((request) {
+ expect(request.method, equals('POST'));
+ expect(request.url.toString(), equals(tokenEndpoint.toString()));
+ return Future.value(http.Response(
+ jsonEncode(
+ {'access_token': 'new access token', 'token_type': 'bearer'}),
+ 200,
+ headers: {'content-type': 'application/json'}));
+ });
+
+ const numCalls = 2;
+
+ for (var i = 0; i < numCalls; i++) {
+ httpClient.expectRequest((request) {
+ expect(request.method, equals('GET'));
+ expect(request.url.toString(), equals(requestUri.toString()));
+ expect(request.headers['authorization'],
+ equals('Bearer new access token'));
+
+ return Future.value(http.Response('good job', 200));
+ });
+ }
+
+ await Future.wait(
+ List<Future<String>>.generate(
+ numCalls, (_) => client.read(requestUri)),
+ );
+
+ expect(client.credentials.accessToken, equals('new access token'));
+ },
+ );
+
+ test('that onCredentialsRefreshed is called', () async {
+ var callbackCalled = false;
+
+ var expiration = DateTime.now().subtract(const Duration(hours: 1));
+ var credentials = oauth2.Credentials('access token',
+ refreshToken: 'refresh token',
+ tokenEndpoint: tokenEndpoint,
+ expiration: expiration);
+ var client = oauth2.Client(credentials,
+ identifier: 'identifier',
+ secret: 'secret',
+ httpClient: httpClient, onCredentialsRefreshed: (credentials) {
+ callbackCalled = true;
+ expect(credentials.accessToken, equals('new access token'));
+ });
+
+ httpClient.expectRequest(
+ (request) => Future.value(
+ http.Response(
+ jsonEncode(
+ {'access_token': 'new access token', 'token_type': 'bearer'},
+ ),
+ 200,
+ headers: {'content-type': 'application/json'},
+ ),
+ ),
+ );
+
+ httpClient.expectRequest(
+ (request) => Future.value(http.Response('good job', 200)));
+
+ await client.read(requestUri);
+ expect(callbackCalled, equals(true));
+ });
+ });
+
+ group('with valid credentials', () {
+ test('sends a request with bearer authorization', () {
+ var credentials = oauth2.Credentials('access token');
+ var client = oauth2.Client(credentials,
+ identifier: 'identifier', secret: 'secret', httpClient: httpClient);
+
+ httpClient.expectRequest((request) {
+ expect(request.method, equals('GET'));
+ expect(request.url.toString(), equals(requestUri.toString()));
+ expect(request.headers['authorization'], equals('Bearer access token'));
+
+ return Future.value(http.Response('good job', 200));
+ });
+
+ expect(client.read(requestUri), completion(equals('good job')));
+ });
+
+ test('can manually refresh the credentials', () async {
+ var credentials = oauth2.Credentials('access token',
+ refreshToken: 'refresh token', tokenEndpoint: tokenEndpoint);
+ var client = oauth2.Client(credentials,
+ identifier: 'identifier', secret: 'secret', httpClient: httpClient);
+
+ httpClient.expectRequest((request) {
+ expect(request.method, equals('POST'));
+ expect(request.url.toString(), equals(tokenEndpoint.toString()));
+ return Future.value(http.Response(
+ jsonEncode(
+ {'access_token': 'new access token', 'token_type': 'bearer'}),
+ 200,
+ headers: {'content-type': 'application/json'}));
+ });
+
+ await client.refreshCredentials();
+ expect(client.credentials.accessToken, equals('new access token'));
+ });
+
+ test("without a refresh token can't manually refresh the credentials", () {
+ var credentials = oauth2.Credentials('access token');
+ var client = oauth2.Client(credentials,
+ identifier: 'identifier', secret: 'secret', httpClient: httpClient);
+
+ expect(client.refreshCredentials(), throwsA(isStateError));
+ });
+ });
+
+ group('with invalid credentials', () {
+ test('throws an AuthorizationException for a 401 response', () {
+ var credentials = oauth2.Credentials('access token');
+ var client = oauth2.Client(credentials,
+ identifier: 'identifier', secret: 'secret', httpClient: httpClient);
+
+ httpClient.expectRequest((request) {
+ expect(request.method, equals('GET'));
+ expect(request.url.toString(), equals(requestUri.toString()));
+ expect(request.headers['authorization'], equals('Bearer access token'));
+
+ var authenticate = 'Bearer error="invalid_token", error_description='
+ '"Something is terribly wrong."';
+ return Future.value(http.Response('bad job', 401,
+ headers: {'www-authenticate': authenticate}));
+ });
+
+ expect(client.read(requestUri),
+ throwsA(const TypeMatcher<oauth2.AuthorizationException>()));
+ });
+
+ test('passes through a 401 response without www-authenticate', () async {
+ var credentials = oauth2.Credentials('access token');
+ var client = oauth2.Client(credentials,
+ identifier: 'identifier', secret: 'secret', httpClient: httpClient);
+
+ httpClient.expectRequest((request) {
+ expect(request.method, equals('GET'));
+ expect(request.url.toString(), equals(requestUri.toString()));
+ expect(request.headers['authorization'], equals('Bearer access token'));
+
+ return Future.value(http.Response('bad job', 401));
+ });
+
+ expect((await client.get(requestUri)).statusCode, equals(401));
+ });
+
+ test('passes through a 401 response with invalid www-authenticate',
+ () async {
+ var credentials = oauth2.Credentials('access token');
+ var client = oauth2.Client(credentials,
+ identifier: 'identifier', secret: 'secret', httpClient: httpClient);
+
+ httpClient.expectRequest((request) {
+ expect(request.method, equals('GET'));
+ expect(request.url.toString(), equals(requestUri.toString()));
+ expect(request.headers['authorization'], equals('Bearer access token'));
+
+ var authenticate = 'Bearer error="invalid_token" error_description='
+ '"Something is terribly wrong."';
+ return Future.value(http.Response('bad job', 401,
+ headers: {'www-authenticate': authenticate}));
+ });
+
+ expect((await client.get(requestUri)).statusCode, equals(401));
+ });
+
+ test('passes through a 401 response with non-bearer www-authenticate',
+ () async {
+ var credentials = oauth2.Credentials('access token');
+ var client = oauth2.Client(credentials,
+ identifier: 'identifier', secret: 'secret', httpClient: httpClient);
+
+ httpClient.expectRequest((request) {
+ expect(request.method, equals('GET'));
+ expect(request.url.toString(), equals(requestUri.toString()));
+ expect(request.headers['authorization'], equals('Bearer access token'));
+
+ return Future.value(http.Response('bad job', 401,
+ headers: {'www-authenticate': 'Digest'}));
+ });
+
+ expect((await client.get(requestUri)).statusCode, equals(401));
+ });
+
+ test('passes through a 401 response with non-OAuth2 www-authenticate',
+ () async {
+ var credentials = oauth2.Credentials('access token');
+ var client = oauth2.Client(credentials,
+ identifier: 'identifier', secret: 'secret', httpClient: httpClient);
+
+ httpClient.expectRequest((request) {
+ expect(request.method, equals('GET'));
+ expect(request.url.toString(), equals(requestUri.toString()));
+ expect(request.headers['authorization'], equals('Bearer access token'));
+
+ return Future.value(http.Response('bad job', 401,
+ headers: {'www-authenticate': 'Bearer'}));
+ });
+
+ expect((await client.get(requestUri)).statusCode, equals(401));
+ });
+ });
+}
diff --git a/pkgs/oauth2/test/credentials_test.dart b/pkgs/oauth2/test/credentials_test.dart
new file mode 100644
index 0000000..d83bc7e
--- /dev/null
+++ b/pkgs/oauth2/test/credentials_test.dart
@@ -0,0 +1,331 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:convert';
+
+import 'package:http/http.dart' as http;
+import 'package:oauth2/oauth2.dart' as oauth2;
+import 'package:test/test.dart';
+
+import 'utils.dart';
+
+final Uri tokenEndpoint = Uri.parse('http://example.com/token');
+
+void main() {
+ late ExpectClient httpClient;
+
+ setUp(() => httpClient = ExpectClient());
+
+ test('is not expired if no expiration exists', () {
+ var credentials = oauth2.Credentials('access token');
+ expect(credentials.isExpired, isFalse);
+ });
+
+ test('is not expired if the expiration is in the future', () {
+ var expiration = DateTime.now().add(const Duration(hours: 1));
+ var credentials =
+ oauth2.Credentials('access token', expiration: expiration);
+ expect(credentials.isExpired, isFalse);
+ });
+
+ test('is expired if the expiration is in the past', () {
+ var expiration = DateTime.now().subtract(const Duration(hours: 1));
+ var credentials =
+ oauth2.Credentials('access token', expiration: expiration);
+ expect(credentials.isExpired, isTrue);
+ });
+
+ test("can't refresh without a refresh token", () {
+ var credentials =
+ oauth2.Credentials('access token', tokenEndpoint: tokenEndpoint);
+ expect(credentials.canRefresh, false);
+
+ expect(
+ credentials.refresh(
+ identifier: 'identifier', secret: 'secret', httpClient: httpClient),
+ throwsStateError);
+ });
+
+ test("can't refresh without a token endpoint", () {
+ var credentials =
+ oauth2.Credentials('access token', refreshToken: 'refresh token');
+ expect(credentials.canRefresh, false);
+
+ expect(
+ credentials.refresh(
+ identifier: 'identifier', secret: 'secret', httpClient: httpClient),
+ throwsStateError);
+ });
+
+ test('can refresh with a refresh token and a token endpoint', () async {
+ var credentials = oauth2.Credentials('access token',
+ refreshToken: 'refresh token',
+ tokenEndpoint: tokenEndpoint,
+ scopes: ['scope1', 'scope2']);
+ expect(credentials.canRefresh, true);
+
+ httpClient.expectRequest((request) {
+ expect(request.method, equals('POST'));
+ expect(request.url.toString(), equals(tokenEndpoint.toString()));
+ expect(
+ request.bodyFields,
+ equals({
+ 'grant_type': 'refresh_token',
+ 'refresh_token': 'refresh token',
+ 'scope': 'scope1 scope2'
+ }));
+ expect(
+ request.headers,
+ containsPair('Authorization',
+ 'Basic aWQlQzMlQUJudCVDNCVBQmZpZXI6cyVDMyVBQmNyZXQ='));
+
+ return Future.value(http.Response(
+ jsonEncode({
+ 'access_token': 'new access token',
+ 'token_type': 'bearer',
+ 'refresh_token': 'new refresh token'
+ }),
+ 200,
+ headers: {'content-type': 'application/json'}));
+ });
+
+ credentials = await credentials.refresh(
+ identifier: 'idëntÄ«fier', secret: 'sëcret', httpClient: httpClient);
+ expect(credentials.accessToken, equals('new access token'));
+ expect(credentials.refreshToken, equals('new refresh token'));
+ });
+
+ test('sets proper scope string when using custom delimiter', () async {
+ var credentials = oauth2.Credentials('access token',
+ refreshToken: 'refresh token',
+ tokenEndpoint: tokenEndpoint,
+ scopes: ['scope1', 'scope2'],
+ delimiter: ',');
+ httpClient.expectRequest((http.Request request) {
+ expect(request.bodyFields['scope'], equals('scope1,scope2'));
+ return Future.value(http.Response(
+ jsonEncode({
+ 'access_token': 'new access token',
+ 'token_type': 'bearer',
+ 'refresh_token': 'new refresh token'
+ }),
+ 200,
+ headers: {'content-type': 'application/json'}));
+ });
+ await credentials.refresh(
+ identifier: 'idëntÄ«fier', secret: 'sëcret', httpClient: httpClient);
+ });
+
+ test('can refresh without a client secret', () async {
+ var credentials = oauth2.Credentials('access token',
+ refreshToken: 'refresh token',
+ tokenEndpoint: tokenEndpoint,
+ scopes: ['scope1', 'scope2']);
+ expect(credentials.canRefresh, true);
+
+ httpClient.expectRequest((request) {
+ expect(request.method, equals('POST'));
+ expect(request.url.toString(), equals(tokenEndpoint.toString()));
+ expect(
+ request.bodyFields,
+ equals({
+ 'grant_type': 'refresh_token',
+ 'refresh_token': 'refresh token',
+ 'scope': 'scope1 scope2',
+ 'client_id': 'identifier'
+ }));
+
+ return Future.value(http.Response(
+ jsonEncode({
+ 'access_token': 'new access token',
+ 'token_type': 'bearer',
+ 'refresh_token': 'new refresh token'
+ }),
+ 200,
+ headers: {'content-type': 'application/json'}));
+ });
+
+ credentials = await credentials.refresh(
+ identifier: 'identifier', httpClient: httpClient);
+ expect(credentials.accessToken, equals('new access token'));
+ expect(credentials.refreshToken, equals('new refresh token'));
+ });
+
+ test('can refresh without client authentication', () async {
+ var credentials = oauth2.Credentials('access token',
+ refreshToken: 'refresh token',
+ tokenEndpoint: tokenEndpoint,
+ scopes: ['scope1', 'scope2']);
+ expect(credentials.canRefresh, true);
+
+ httpClient.expectRequest((request) {
+ expect(request.method, equals('POST'));
+ expect(request.url.toString(), equals(tokenEndpoint.toString()));
+ expect(
+ request.bodyFields,
+ equals({
+ 'grant_type': 'refresh_token',
+ 'refresh_token': 'refresh token',
+ 'scope': 'scope1 scope2'
+ }));
+
+ return Future.value(http.Response(
+ jsonEncode({
+ 'access_token': 'new access token',
+ 'token_type': 'bearer',
+ 'refresh_token': 'new refresh token'
+ }),
+ 200,
+ headers: {'content-type': 'application/json'}));
+ });
+
+ credentials = await credentials.refresh(httpClient: httpClient);
+ expect(credentials.accessToken, equals('new access token'));
+ expect(credentials.refreshToken, equals('new refresh token'));
+ });
+
+ test("uses the old refresh token if a new one isn't provided", () async {
+ var credentials = oauth2.Credentials('access token',
+ refreshToken: 'refresh token', tokenEndpoint: tokenEndpoint);
+ expect(credentials.canRefresh, true);
+
+ httpClient.expectRequest((request) {
+ expect(request.method, equals('POST'));
+ expect(request.url.toString(), equals(tokenEndpoint.toString()));
+ expect(
+ request.bodyFields,
+ equals({
+ 'grant_type': 'refresh_token',
+ 'refresh_token': 'refresh token'
+ }));
+ expect(
+ request.headers,
+ containsPair('Authorization',
+ 'Basic aWQlQzMlQUJudCVDNCVBQmZpZXI6cyVDMyVBQmNyZXQ='));
+
+ return Future.value(http.Response(
+ jsonEncode(
+ {'access_token': 'new access token', 'token_type': 'bearer'}),
+ 200,
+ headers: {'content-type': 'application/json'}));
+ });
+
+ credentials = await credentials.refresh(
+ identifier: 'idëntÄ«fier', secret: 'sëcret', httpClient: httpClient);
+ expect(credentials.accessToken, equals('new access token'));
+ expect(credentials.refreshToken, equals('refresh token'));
+ });
+
+ test('uses form-field authentication if basicAuth is false', () async {
+ var credentials = oauth2.Credentials('access token',
+ refreshToken: 'refresh token',
+ tokenEndpoint: tokenEndpoint,
+ scopes: ['scope1', 'scope2']);
+ expect(credentials.canRefresh, true);
+
+ httpClient.expectRequest((request) {
+ expect(request.method, equals('POST'));
+ expect(request.url.toString(), equals(tokenEndpoint.toString()));
+ expect(
+ request.bodyFields,
+ equals({
+ 'grant_type': 'refresh_token',
+ 'refresh_token': 'refresh token',
+ 'scope': 'scope1 scope2',
+ 'client_id': 'idëntÄ«fier',
+ 'client_secret': 'sëcret'
+ }));
+
+ return Future.value(http.Response(
+ jsonEncode({
+ 'access_token': 'new access token',
+ 'token_type': 'bearer',
+ 'refresh_token': 'new refresh token'
+ }),
+ 200,
+ headers: {'content-type': 'application/json'}));
+ });
+
+ credentials = await credentials.refresh(
+ identifier: 'idëntÄ«fier',
+ secret: 'sëcret',
+ basicAuth: false,
+ httpClient: httpClient);
+ expect(credentials.accessToken, equals('new access token'));
+ expect(credentials.refreshToken, equals('new refresh token'));
+ });
+
+ group('fromJson', () {
+ oauth2.Credentials fromMap(Map<String, dynamic> map) =>
+ oauth2.Credentials.fromJson(jsonEncode(map));
+
+ test('should load the same credentials from toJson', () {
+ // Round the expiration down to milliseconds since epoch, since that's
+ // what the credentials file stores. Otherwise sub-millisecond time gets
+ // in the way.
+ var expiration = DateTime.now().subtract(const Duration(hours: 1));
+ expiration = DateTime.fromMillisecondsSinceEpoch(
+ expiration.millisecondsSinceEpoch);
+
+ var credentials = oauth2.Credentials('access token',
+ refreshToken: 'refresh token',
+ idToken: 'id token',
+ tokenEndpoint: tokenEndpoint,
+ scopes: ['scope1', 'scope2'],
+ expiration: expiration);
+ var reloaded = oauth2.Credentials.fromJson(credentials.toJson());
+
+ expect(reloaded.accessToken, equals(credentials.accessToken));
+ expect(reloaded.refreshToken, equals(credentials.refreshToken));
+ expect(reloaded.idToken, equals(credentials.idToken));
+ expect(reloaded.tokenEndpoint.toString(),
+ equals(credentials.tokenEndpoint.toString()));
+ expect(reloaded.scopes, equals(credentials.scopes));
+ expect(reloaded.expiration, equals(credentials.expiration));
+ });
+
+ test('should throw a FormatException for invalid JSON', () {
+ expect(
+ () => oauth2.Credentials.fromJson('foo bar'), throwsFormatException);
+ });
+
+ test("should throw a FormatException for JSON that's not a map", () {
+ expect(() => oauth2.Credentials.fromJson('null'), throwsFormatException);
+ });
+
+ test('should throw a FormatException if there is no accessToken', () {
+ expect(() => fromMap({}), throwsFormatException);
+ });
+
+ test('should throw a FormatException if accessToken is not a string', () {
+ expect(() => fromMap({'accessToken': 12}), throwsFormatException);
+ });
+
+ test('should throw a FormatException if refreshToken is not a string', () {
+ expect(() => fromMap({'accessToken': 'foo', 'refreshToken': 12}),
+ throwsFormatException);
+ });
+
+ test('should throw a FormatException if idToken is not a string', () {
+ expect(() => fromMap({'accessToken': 'foo', 'idToken': 12}),
+ throwsFormatException);
+ });
+
+ test('should throw a FormatException if tokenEndpoint is not a string', () {
+ expect(() => fromMap({'accessToken': 'foo', 'tokenEndpoint': 12}),
+ throwsFormatException);
+ });
+
+ test('should throw a FormatException if scopes is not a list', () {
+ expect(() => fromMap({'accessToken': 'foo', 'scopes': 12}),
+ throwsFormatException);
+ });
+
+ test('should throw a FormatException if expiration is not an int', () {
+ expect(() => fromMap({'accessToken': 'foo', 'expiration': '12'}),
+ throwsFormatException);
+ });
+ });
+}
diff --git a/pkgs/oauth2/test/handle_access_token_response_test.dart b/pkgs/oauth2/test/handle_access_token_response_test.dart
new file mode 100644
index 0000000..4d7b519
--- /dev/null
+++ b/pkgs/oauth2/test/handle_access_token_response_test.dart
@@ -0,0 +1,301 @@
+// Copyright (c) 2012, 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 'package:http/http.dart' as http;
+import 'package:oauth2/oauth2.dart' as oauth2;
+import 'package:oauth2/src/handle_access_token_response.dart';
+import 'package:oauth2/src/parameters.dart';
+import 'package:test/test.dart';
+
+import 'utils.dart';
+
+final Uri tokenEndpoint = Uri.parse('https://example.com/token');
+
+final DateTime startTime = DateTime.now();
+
+oauth2.Credentials handle(http.Response response,
+ {GetParameters? getParameters}) =>
+ handleAccessTokenResponse(
+ response, tokenEndpoint, startTime, ['scope'], ' ',
+ getParameters: getParameters);
+
+void main() {
+ group('an error response', () {
+ oauth2.Credentials handleError(
+ {String body = '{"error": "invalid_request"}',
+ int statusCode = 400,
+ Map<String, String> headers = const {
+ 'content-type': 'application/json'
+ }}) =>
+ handle(http.Response(body, statusCode, headers: headers));
+
+ test('causes an AuthorizationException', () {
+ expect(handleError, throwsAuthorizationException);
+ });
+
+ test('with a 401 code causes an AuthorizationException', () {
+ expect(() => handleError(statusCode: 401), throwsAuthorizationException);
+ });
+
+ test('with an unexpected code causes a FormatException', () {
+ expect(() => handleError(statusCode: 500), throwsFormatException);
+ });
+
+ test('with no content-type causes a FormatException', () {
+ expect(() => handleError(headers: {}), throwsFormatException);
+ });
+
+ test('with a non-JSON content-type causes a FormatException', () {
+ expect(() => handleError(headers: {'content-type': 'text/plain'}),
+ throwsFormatException);
+ });
+
+ test('with a non-JSON, non-plain content-type causes a FormatException',
+ () {
+ expect(() => handleError(headers: {'content-type': 'image/png'}),
+ throwsFormatException);
+ });
+
+ test(
+ 'with a JSON content-type and charset causes an '
+ 'AuthorizationException', () {
+ expect(
+ () => handleError(
+ headers: {'content-type': 'application/json; charset=UTF-8'}),
+ throwsAuthorizationException);
+ });
+
+ test('with invalid JSON causes a FormatException', () {
+ expect(() => handleError(body: 'not json'), throwsFormatException);
+ });
+
+ test('with a non-string error causes a FormatException', () {
+ expect(() => handleError(body: '{"error": 12}'), throwsFormatException);
+ });
+
+ test('with a non-string error_description causes a FormatException', () {
+ expect(
+ () => handleError(
+ body: jsonEncode(
+ {'error': 'invalid_request', 'error_description': 12})),
+ throwsFormatException);
+ });
+
+ test('with a non-string error_uri causes a FormatException', () {
+ expect(
+ () => handleError(
+ body: jsonEncode({'error': 'invalid_request', 'error_uri': 12})),
+ throwsFormatException);
+ });
+
+ test('with a string error_description causes a AuthorizationException', () {
+ expect(
+ () => handleError(
+ body: jsonEncode({
+ 'error': 'invalid_request',
+ 'error_description': 'description'
+ })),
+ throwsAuthorizationException);
+ });
+
+ test('with a string error_uri causes a AuthorizationException', () {
+ expect(
+ () => handleError(
+ body: jsonEncode({
+ 'error': 'invalid_request',
+ 'error_uri': 'http://example.com/error'
+ })),
+ throwsAuthorizationException);
+ });
+ });
+
+ group('a success response', () {
+ oauth2.Credentials handleSuccess(
+ {String contentType = 'application/json',
+ Object? accessToken = 'access token',
+ Object? tokenType = 'bearer',
+ Object? expiresIn,
+ Object? refreshToken,
+ Object? scope}) {
+ return handle(http.Response(
+ jsonEncode({
+ 'access_token': accessToken,
+ 'token_type': tokenType,
+ 'expires_in': expiresIn,
+ 'refresh_token': refreshToken,
+ 'scope': scope
+ }),
+ 200,
+ headers: {'content-type': contentType}));
+ }
+
+ test('returns the correct credentials', () {
+ var credentials = handleSuccess();
+ expect(credentials.accessToken, equals('access token'));
+ expect(credentials.tokenEndpoint.toString(),
+ equals(tokenEndpoint.toString()));
+ });
+
+ test('with no content-type causes a FormatException', () {
+ expect(() => handleSuccess(contentType: ''), throwsFormatException);
+ });
+
+ test('with a non-JSON content-type causes a FormatException', () {
+ expect(() => handleSuccess(contentType: 'text/plain'),
+ throwsFormatException);
+ });
+
+ test(
+ 'with a JSON content-type and charset returns the correct '
+ 'credentials', () {
+ var credentials =
+ handleSuccess(contentType: 'application/json; charset=UTF-8');
+ expect(credentials.accessToken, equals('access token'));
+ });
+
+ test('with a JavScript content-type returns the correct credentials', () {
+ var credentials = handleSuccess(contentType: 'text/javascript');
+ expect(credentials.accessToken, equals('access token'));
+ });
+
+ test('with custom getParameters() returns the correct credentials', () {
+ var body = '_${jsonEncode({
+ 'token_type': 'bearer',
+ 'access_token': 'access token'
+ })}';
+ var credentials = handle(
+ http.Response(body, 200, headers: {'content-type': 'text/plain'}),
+ getParameters: (contentType, body) =>
+ jsonDecode(body.substring(1)) as Map<String, dynamic>,
+ );
+ expect(credentials.accessToken, equals('access token'));
+ expect(credentials.tokenEndpoint.toString(),
+ equals(tokenEndpoint.toString()));
+ });
+
+ test('throws a FormatException if custom getParameters rejects response',
+ () {
+ var response = http.Response(
+ jsonEncode({
+ 'access_token': 'access token',
+ 'token_type': 'bearer',
+ 'expires_in': 24,
+ 'refresh_token': 'refresh token',
+ 'scope': 'scope',
+ }),
+ 200,
+ headers: {'content-type': 'foo/bar'});
+
+ expect(
+ () => handle(response,
+ getParameters: (contentType, body) => throw FormatException(
+ 'unsupported content-type: $contentType')),
+ throwsFormatException);
+ });
+
+ test('with a null access token throws a FormatException', () {
+ expect(() => handleSuccess(accessToken: null), throwsFormatException);
+ });
+
+ test('with a non-string access token throws a FormatException', () {
+ expect(() => handleSuccess(accessToken: 12), throwsFormatException);
+ });
+
+ test('with a null token type throws a FormatException', () {
+ expect(() => handleSuccess(tokenType: null), throwsFormatException);
+ });
+
+ test('with a non-string token type throws a FormatException', () {
+ expect(() => handleSuccess(tokenType: 12), throwsFormatException);
+ });
+
+ test('with a non-"bearer" token type throws a FormatException', () {
+ expect(() => handleSuccess(tokenType: 'mac'), throwsFormatException);
+ });
+
+ test('with a non-int expires-in throws a FormatException', () {
+ expect(() => handleSuccess(expiresIn: 'whenever'), throwsFormatException);
+ });
+
+ test(
+ 'with expires-in sets the expiration to ten seconds earlier than the '
+ 'server says', () {
+ var credentials = handleSuccess(expiresIn: 100);
+ expect(credentials.expiration?.millisecondsSinceEpoch,
+ startTime.millisecondsSinceEpoch + 90 * 1000);
+ });
+
+ test('with expires-in encoded as string', () {
+ var credentials = handleSuccess(expiresIn: '110');
+ expect(credentials.expiration?.millisecondsSinceEpoch,
+ startTime.millisecondsSinceEpoch + 100 * 1000);
+ });
+
+ test('with a non-string refresh token throws a FormatException', () {
+ expect(() => handleSuccess(refreshToken: 12), throwsFormatException);
+ });
+
+ test('with a refresh token sets the refresh token', () {
+ var credentials = handleSuccess(refreshToken: 'refresh me');
+ expect(credentials.refreshToken, equals('refresh me'));
+ });
+
+ test('with a non-string scope throws a FormatException', () {
+ expect(() => handleSuccess(scope: 12), throwsFormatException);
+ });
+
+ test('with a scope sets the scopes', () {
+ var credentials = handleSuccess(scope: 'scope1 scope2');
+ expect(credentials.scopes, equals(['scope1', 'scope2']));
+ });
+
+ test('with a custom scope delimiter sets the scopes', () {
+ var response = http.Response(
+ jsonEncode({
+ 'access_token': 'access token',
+ 'token_type': 'bearer',
+ 'expires_in': null,
+ 'refresh_token': null,
+ 'scope': 'scope1,scope2'
+ }),
+ 200,
+ headers: {'content-type': 'application/json'});
+ var credentials = handleAccessTokenResponse(
+ response, tokenEndpoint, startTime, ['scope'], ',');
+ expect(credentials.scopes, equals(['scope1', 'scope2']));
+ });
+ });
+
+ group('a success response with a id_token', () {
+ oauth2.Credentials handleSuccess(
+ {String contentType = 'application/json',
+ Object? accessToken = 'access token',
+ Object? tokenType = 'bearer',
+ Object? expiresIn,
+ Object? idToken = 'decode me',
+ Object? scope}) {
+ return handle(http.Response(
+ jsonEncode({
+ 'access_token': accessToken,
+ 'token_type': tokenType,
+ 'expires_in': expiresIn,
+ 'id_token': idToken,
+ 'scope': scope
+ }),
+ 200,
+ headers: {'content-type': contentType}));
+ }
+
+ test('with a non-string id token throws a FormatException', () {
+ expect(() => handleSuccess(idToken: 12), throwsFormatException);
+ });
+
+ test('with a id token sets the id token', () {
+ var credentials = handleSuccess(idToken: 'decode me');
+ expect(credentials.idToken, equals('decode me'));
+ });
+ });
+}
diff --git a/pkgs/oauth2/test/resource_owner_password_grant_test.dart b/pkgs/oauth2/test/resource_owner_password_grant_test.dart
new file mode 100644
index 0000000..7a5d9b5
--- /dev/null
+++ b/pkgs/oauth2/test/resource_owner_password_grant_test.dart
@@ -0,0 +1,168 @@
+// Copyright (c) 2012, 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.
+
+@TestOn('vm')
+library;
+
+import 'dart:async';
+import 'dart:convert';
+
+import 'package:http/http.dart' as http;
+import 'package:oauth2/oauth2.dart' as oauth2;
+import 'package:test/test.dart';
+
+import 'utils.dart';
+
+final success = jsonEncode({
+ 'access_token': '2YotnFZFEjr1zCsicMWpAA',
+ 'token_type': 'bearer',
+ 'expires_in': 3600,
+ 'refresh_token': 'tGzv3JOkF0XG5Qx2TlKWIA',
+});
+
+String auth = 'Basic Y2xpZW50OnNlY3JldA==';
+Uri authEndpoint = Uri.parse('https://example.com');
+
+void main() {
+ late ExpectClient expectClient;
+
+ setUp(() => expectClient = ExpectClient());
+
+ group('basic', () {
+ test('builds correct request with client when using basic auth for client',
+ () async {
+ expectClient.expectRequest((request) async {
+ expect(auth, equals(request.headers['authorization']));
+ expect(request.bodyFields['grant_type'], equals('password'));
+ expect(request.bodyFields['username'], equals('username'));
+ expect(request.bodyFields['password'], equals('userpass'));
+ return http.Response(success, 200,
+ headers: {'content-type': 'application/json'});
+ });
+
+ var client = await oauth2.resourceOwnerPasswordGrant(
+ authEndpoint, 'username', 'userpass',
+ identifier: 'client', secret: 'secret', httpClient: expectClient);
+
+ expect(client.credentials, isNotNull);
+ expect(client.credentials.accessToken, equals('2YotnFZFEjr1zCsicMWpAA'));
+ });
+
+ test('passes the onCredentialsRefreshed callback to the client', () async {
+ expectClient.expectRequest((request) async {
+ return http.Response(
+ jsonEncode({
+ 'access_token': '2YotnFZFEjr1zCsicMWpAA',
+ 'token_type': 'bearer',
+ 'expires_in': -3600,
+ 'refresh_token': 'tGzv3JOkF0XG5Qx2TlKWIA',
+ }),
+ 200,
+ headers: {'content-type': 'application/json'});
+ });
+
+ var isCallbackInvoked = false;
+
+ var client = await oauth2.resourceOwnerPasswordGrant(
+ authEndpoint, 'username', 'userpass',
+ identifier: 'client', secret: 'secret', httpClient: expectClient,
+ onCredentialsRefreshed: (oauth2.Credentials credentials) {
+ isCallbackInvoked = true;
+ });
+
+ expectClient.expectRequest((request) {
+ return Future.value(http.Response(
+ jsonEncode(
+ {'access_token': 'new access token', 'token_type': 'bearer'}),
+ 200,
+ headers: {'content-type': 'application/json'}));
+ });
+
+ expectClient.expectRequest((request) {
+ return Future.value(http.Response('good job', 200));
+ });
+
+ await client.read(Uri.parse('http://example.com/resource'));
+ expect(isCallbackInvoked, equals(true));
+ });
+
+ test('builds correct request when using query parameters for client',
+ () async {
+ expectClient.expectRequest((request) async {
+ expect(request.bodyFields['grant_type'], equals('password'));
+ expect(request.bodyFields['client_id'], equals('client'));
+ expect(request.bodyFields['client_secret'], equals('secret'));
+ expect(request.bodyFields['username'], equals('username'));
+ expect(request.bodyFields['password'], equals('userpass'));
+ return http.Response(success, 200,
+ headers: {'content-type': 'application/json'});
+ });
+
+ var client = await oauth2.resourceOwnerPasswordGrant(
+ authEndpoint, 'username', 'userpass',
+ identifier: 'client',
+ secret: 'secret',
+ basicAuth: false,
+ httpClient: expectClient);
+ expect(client.credentials, isNotNull);
+ expect(client.credentials.accessToken, equals('2YotnFZFEjr1zCsicMWpAA'));
+ });
+
+ test('builds correct request using scope', () async {
+ expectClient.expectRequest((request) async {
+ expect(request.bodyFields['grant_type'], equals('password'));
+ expect(request.bodyFields['username'], equals('username'));
+ expect(request.bodyFields['password'], equals('userpass'));
+ expect(request.bodyFields['scope'], equals('one two'));
+ return http.Response(success, 200,
+ headers: {'content-type': 'application/json'});
+ });
+
+ var client = await oauth2.resourceOwnerPasswordGrant(
+ authEndpoint, 'username', 'userpass',
+ scopes: ['one', 'two'], httpClient: expectClient);
+ expect(client.credentials, isNotNull);
+ expect(client.credentials.accessToken, equals('2YotnFZFEjr1zCsicMWpAA'));
+ });
+
+ test('builds correct request using scope with custom delimiter', () async {
+ expectClient.expectRequest((request) async {
+ expect(request.bodyFields['grant_type'], equals('password'));
+ expect(request.bodyFields['username'], equals('username'));
+ expect(request.bodyFields['password'], equals('userpass'));
+ expect(request.bodyFields['scope'], equals('one,two'));
+ return http.Response(success, 200,
+ headers: {'content-type': 'application/json'});
+ });
+
+ await oauth2.resourceOwnerPasswordGrant(
+ authEndpoint, 'username', 'userpass',
+ scopes: ['one', 'two'], httpClient: expectClient, delimiter: ',');
+ });
+
+ test('merges with existing query parameters', () async {
+ var authEndpoint = Uri.parse('https://example.com?query=value');
+
+ expectClient.expectRequest((request) async {
+ expect(request.bodyFields['grant_type'], equals('password'));
+ expect(request.bodyFields['client_id'], equals('client'));
+ expect(request.bodyFields['client_secret'], equals('secret'));
+ expect(request.bodyFields['username'], equals('username'));
+ expect(request.bodyFields['password'], equals('userpass'));
+ expect(request.url.queryParameters['query'], equals('value'));
+ return http.Response(success, 200,
+ headers: {'content-type': 'application/json'});
+ });
+
+ var client = await oauth2.resourceOwnerPasswordGrant(
+ authEndpoint, 'username', 'userpass',
+ identifier: 'client',
+ secret: 'secret',
+ basicAuth: false,
+ httpClient: expectClient);
+ expect(client.credentials, isNotNull);
+ expect(client.credentials.accessToken, equals('2YotnFZFEjr1zCsicMWpAA'));
+ });
+ });
+}
diff --git a/pkgs/oauth2/test/utils.dart b/pkgs/oauth2/test/utils.dart
new file mode 100644
index 0000000..4f3b747
--- /dev/null
+++ b/pkgs/oauth2/test/utils.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:collection' show Queue;
+
+import 'package:http/http.dart' as http;
+import 'package:http/testing.dart';
+import 'package:oauth2/oauth2.dart' as oauth2;
+import 'package:test/test.dart';
+
+class ExpectClient extends MockClient {
+ final Queue<MockClientHandler> _handlers;
+
+ ExpectClient._(super.fn) : _handlers = Queue<MockClientHandler>();
+
+ factory ExpectClient() {
+ late ExpectClient client;
+ client = ExpectClient._((request) => client._handleRequest(request));
+ return client;
+ }
+
+ void expectRequest(MockClientHandler fn) {
+ var completer = Completer<void>();
+ expect(completer.future, completes);
+
+ _handlers.add((request) {
+ completer.complete(null);
+ return fn(request);
+ });
+ }
+
+ Future<http.Response> _handleRequest(http.Request request) {
+ if (_handlers.isEmpty) {
+ return Future.value(http.Response('not found', 404));
+ } else {
+ return _handlers.removeFirst()(request);
+ }
+ }
+}
+
+/// A matcher for functions that throw AuthorizationException.
+final Matcher throwsAuthorizationException =
+ throwsA(const TypeMatcher<oauth2.AuthorizationException>());
+
+/// A matcher for functions that throw ExpirationException.
+final Matcher throwsExpirationException =
+ throwsA(const TypeMatcher<oauth2.ExpirationException>());
diff --git a/pkgs/source_map_stack_trace/.gitignore b/pkgs/source_map_stack_trace/.gitignore
new file mode 100644
index 0000000..f73b2f9
--- /dev/null
+++ b/pkgs/source_map_stack_trace/.gitignore
@@ -0,0 +1,4 @@
+.dart_tool/
+.packages
+.pub/
+pubspec.lock
diff --git a/pkgs/source_map_stack_trace/.test_config b/pkgs/source_map_stack_trace/.test_config
new file mode 100644
index 0000000..531426a
--- /dev/null
+++ b/pkgs/source_map_stack_trace/.test_config
@@ -0,0 +1,5 @@
+{
+ "test_package": {
+ "platforms": ["vm"]
+ }
+}
\ No newline at end of file
diff --git a/pkgs/source_map_stack_trace/AUTHORS b/pkgs/source_map_stack_trace/AUTHORS
new file mode 100644
index 0000000..e8063a8
--- /dev/null
+++ b/pkgs/source_map_stack_trace/AUTHORS
@@ -0,0 +1,6 @@
+# Below is a list of people and organizations that have contributed
+# to the project. Names should be added to the list like so:
+#
+# Name/Organization <email address>
+
+Google Inc.
diff --git a/pkgs/source_map_stack_trace/CHANGELOG.md b/pkgs/source_map_stack_trace/CHANGELOG.md
new file mode 100644
index 0000000..00c66d9
--- /dev/null
+++ b/pkgs/source_map_stack_trace/CHANGELOG.md
@@ -0,0 +1,82 @@
+## 2.1.3-wip
+
+## 2.1.2
+
+* Require Dart 3.3.0
+* Move to `dart-lang/tools` monorepo.
+
+## 2.1.1
+
+* Populate the pubspec `repository` field.
+
+## 2.1.0
+
+* Stable release for null safety.
+* Require Dart 2.12
+
+## 2.0.0
+
+### Breaking Changes
+
+* Removed dependency on `package_resolver` and changed the apis to accept a
+ `Map<String, Uri>` which maps package names to the base uri to resolve the
+ `package:` uris for those packages.
+* The `sdkRoot` argument must be an `Uri`. Use `Uri.parse` for use
+ cases previously passing a `String`.
+* The deprecated `packageRoot` argument has been removed.
+
+## 1.1.5
+
+* Set max SDK version to `<3.0.0`.
+
+## 1.1.4
+
+* Support source maps that depend on the uri of the location to resolve spans
+ correctly.
+
+## 1.1.3
+
+* Add a missing dependency on `path`.
+
+## 1.1.2
+
+* Fix a typo in the previous fix.
+
+## 1.1.1
+
+* Don't crash if the `SyncPackageResolver` has no package information at all.
+
+## 1.1.0
+
+* `mapStackTrace()` now uses a `SyncPackageResolver` object from the
+ [`package_resolver` package][package_resolver] to recreate `package:` URIs.
+
+* **Deprecation**: the `packageRoot` parameter to `mapStackTrace` is deprecated
+ in favor of the `packageInfo` parameter described above. It will be removed in
+ a future release.
+
+[package_resolver]: https://pub.dartlang.org/packages/package_resolver
+
+## 1.0.5
+
+* Add compatibility for member names that include named arguments.
+
+## 1.0.4
+
+* Add compatibility for Dart 1.10-style name munging.
+
+## 1.0.3
+
+* Prefer "dart:" URLs to "package:" URLs.
+
+## 1.0.2
+
+* Fix an off-by-one bug that was causing line numbers to be slightly off.
+
+## 1.0.1
+
+* Don't crash when mapping stack chains.
+
+## 1.0.0
+
+* Initial release.
diff --git a/pkgs/source_map_stack_trace/LICENSE b/pkgs/source_map_stack_trace/LICENSE
new file mode 100644
index 0000000..633672a
--- /dev/null
+++ b/pkgs/source_map_stack_trace/LICENSE
@@ -0,0 +1,27 @@
+Copyright 2015, the Dart project authors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of Google LLC nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/pkgs/source_map_stack_trace/README.md b/pkgs/source_map_stack_trace/README.md
new file mode 100644
index 0000000..9b11612
--- /dev/null
+++ b/pkgs/source_map_stack_trace/README.md
@@ -0,0 +1,50 @@
+[](https://github.com/dart-lang/tools/actions/workflows/source_map_stack_trace.yml)
+[](https://pub.dev/packages/source_map_stack_trace)
+[](https://pub.dev/packages/source_map_stack_trace/publisher)
+
+`source_map_stack_trace` is a package for converting stack traces generated by
+dart2js-compiled JavaScript code into readable native Dart stack traces using
+source maps. For example:
+
+```dart
+import 'package:source_map_stack_trace/source_map_stack_trace.dart';
+
+void main() {
+ var jsTrace = // Get a StackTrace generated by dart2js.
+ var mapping = // Get a source map mapping the JS to the Dart source.
+
+ // Convert jsTrace to refer to the Dart source instead.
+ var dartTrace = mapStackTrace(jsTrace, sourceMap);
+ print(dartTrace);
+}
+```
+
+This can convert the following JavaScript trace:
+
+```
+expect_async_test.dart.browser_test.dart.js 2636:15 dart.wrapException
+expect_async_test.dart.browser_test.dart.js 14661:15 main__closure16.call$0
+expect_async_test.dart.browser_test.dart.js 18237:26 Declarer_test__closure.call$1
+expect_async_test.dart.browser_test.dart.js 17905:23 StackZoneSpecification_registerUnaryCallback__closure.call$0
+expect_async_test.dart.browser_test.dart.js 17876:16 StackZoneSpecification._stack_zone_specification$_run$2
+expect_async_test.dart.browser_test.dart.js 17899:26 StackZoneSpecification_registerUnaryCallback_closure.call$1
+expect_async_test.dart.browser_test.dart.js 6115:16 _rootRunUnary
+expect_async_test.dart.browser_test.dart.js 8576:39 _CustomZone.runUnary$2
+expect_async_test.dart.browser_test.dart.js 7135:57 _Future__propagateToListeners_handleValueCallback.call$0
+expect_async_test.dart.browser_test.dart.js 7031:147 dart._Future.static._Future__propagateToListeners
+```
+
+to:
+
+```
+dart:_internal/compiler/js_lib/js_helper.dart 1210:1 wrapException
+test/frontend/expect_async_test.dart 24:5 main.<fn>.<fn>
+package:test/src/backend/declarer.dart 45:48 Declarer.test.<fn>.<fn>
+package:stack_trace/src/stack_zone_specification.dart 134:30 StackZoneSpecification.registerUnaryCallback.<fn>.<fn>
+package:stack_trace/src/stack_zone_specification.dart 210:7 StackZoneSpecification._run
+package:stack_trace/src/stack_zone_specification.dart 135:5 StackZoneSpecification.registerUnaryCallback.<fn>
+dart:async/zone.dart 904:14 _rootRunUnary
+dart:async/zone.dart 806:3 _CustomZone.runUnary
+dart:async/future_impl.dart 486:13 _Future._propagateToListeners.handleValueCallback
+dart:async/future_impl.dart 567:32 _Future._propagateToListeners
+```
diff --git a/pkgs/source_map_stack_trace/analysis_options.yaml b/pkgs/source_map_stack_trace/analysis_options.yaml
new file mode 100644
index 0000000..5ee158a
--- /dev/null
+++ b/pkgs/source_map_stack_trace/analysis_options.yaml
@@ -0,0 +1,7 @@
+# https://dart.dev/tools/analysis#the-analysis-options-file
+include: package:dart_flutter_team_lints/analysis_options.yaml
+
+analyzer:
+ language:
+ strict-casts: true
+ strict-raw-types: true
diff --git a/pkgs/source_map_stack_trace/lib/source_map_stack_trace.dart b/pkgs/source_map_stack_trace/lib/source_map_stack_trace.dart
new file mode 100644
index 0000000..a3925cd
--- /dev/null
+++ b/pkgs/source_map_stack_trace/lib/source_map_stack_trace.dart
@@ -0,0 +1,104 @@
+// 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:path/path.dart' as p;
+import 'package:source_maps/source_maps.dart';
+import 'package:stack_trace/stack_trace.dart';
+
+/// Convert [stackTrace], a stack trace generated by dart2js-compiled
+/// JavaScript, to a native-looking stack trace using [sourceMap].
+///
+/// [minified] indicates whether or not the dart2js code was minified. If it
+/// hasn't, this tries to clean up the stack frame member names.
+///
+/// The [packageMap] maps package names to the base uri used to resolve the
+/// `package:` uris for those packages. It is used to it's used to reconstruct
+/// `package:` URIs for stack frames that come from packages.
+///
+/// [sdkRoot] is the URI surfaced in the stack traces for SDK libraries.
+/// If it's passed, stack frames from the SDK will have `dart:` URLs.
+StackTrace mapStackTrace(Mapping sourceMap, StackTrace stackTrace,
+ {bool minified = false, Map<String, Uri>? packageMap, Uri? sdkRoot}) {
+ if (stackTrace is Chain) {
+ return Chain(stackTrace.traces.map((trace) {
+ return Trace.from(mapStackTrace(sourceMap, trace,
+ minified: minified, packageMap: packageMap, sdkRoot: sdkRoot));
+ }));
+ }
+
+ var sdkLib = sdkRoot == null ? null : '$sdkRoot/lib';
+
+ var trace = Trace.from(stackTrace);
+ return Trace(trace.frames.map((frame) {
+ var line = frame.line;
+ // If there's no line information, there's no way to translate this frame.
+ // We could return it as-is, but these lines are usually not useful anyways.
+ if (line == null) return null;
+
+ // If there's no column, try using the first column of the line.
+ var column = frame.column ?? 0;
+
+ // Subtract 1 because stack traces use 1-indexed lines and columns and
+ // source maps uses 0-indexed.
+ var span =
+ sourceMap.spanFor(line - 1, column - 1, uri: frame.uri.toString());
+
+ // If we can't find a source span, ignore the frame. It's probably something
+ // internal that the user doesn't care about.
+ if (span == null) return null;
+
+ var sourceUrl = span.sourceUrl.toString();
+ if (sdkLib != null && p.url.isWithin(sdkLib, sourceUrl)) {
+ sourceUrl = 'dart:${p.url.relative(sourceUrl, from: sdkLib)}';
+ } else if (packageMap != null) {
+ for (var package in packageMap.keys) {
+ var packageUrl = packageMap[package].toString();
+ if (!p.url.isWithin(packageUrl, sourceUrl)) continue;
+
+ sourceUrl =
+ 'package:$package/${p.url.relative(sourceUrl, from: packageUrl)}';
+ break;
+ }
+ }
+
+ return Frame(
+ Uri.parse(sourceUrl),
+ span.start.line + 1,
+ span.start.column + 1,
+ // If the dart2js output is minified, there's no use trying to prettify
+ // its member names. Use the span's identifier if available, otherwise
+ // use the minified member name.
+ minified
+ ? (span.isIdentifier ? span.text : frame.member)
+ : _prettifyMember(frame.member!));
+ }).whereType<Frame>());
+}
+
+/// Reformats a JS member name to make it look more Dart-like.
+String _prettifyMember(String member) {
+ return member
+ // Get rid of the noise that Firefox sometimes adds.
+ .replaceAll(RegExp(r'/?<$'), '')
+ // Get rid of arity indicators and named arguments.
+ .replaceAll(RegExp(r'\$\d+(\$[a-zA-Z_0-9]+)*$'), '')
+ // Convert closures to <fn>.
+ .replaceAllMapped(
+ RegExp(r'(_+)closure\d*\.call$'),
+ // The number of underscores before "closure" indicates how nested it
+ // is.
+ (match) => '.<fn>' * match[1]!.length)
+ // Get rid of explicitly-generated calls.
+ .replaceAll(RegExp(r'\.call$'), '')
+ // Get rid of the top-level method prefix.
+ .replaceAll(RegExp(r'^dart\.'), '')
+ // Get rid of library namespaces.
+ .replaceAll(RegExp(r'[a-zA-Z_0-9]+\$'), '')
+ // Get rid of the static method prefix. The class name also exists in the
+ // invocation, so we're not getting rid of any information.
+ .replaceAll(RegExp(r'^[a-zA-Z_0-9]+.(static|dart).'), '')
+ // Convert underscores after identifiers to dots. This runs the risk of
+ // incorrectly converting members that contain underscores, but those are
+ // contrary to the style guide anyway.
+ .replaceAllMapped(RegExp(r'([a-zA-Z0-9]+)_'), (match) => '${match[1]!}.');
+}
diff --git a/pkgs/source_map_stack_trace/pubspec.yaml b/pkgs/source_map_stack_trace/pubspec.yaml
new file mode 100644
index 0000000..d4b8c3a
--- /dev/null
+++ b/pkgs/source_map_stack_trace/pubspec.yaml
@@ -0,0 +1,17 @@
+name: source_map_stack_trace
+version: 2.1.3-wip
+description: A package for applying source maps to stack traces.
+repository: https://github.com/dart-lang/tools/tree/main/pkgs/source_map_stack_trace
+
+environment:
+ sdk: ^3.3.0
+
+dependencies:
+ path: ^1.8.0
+ source_maps: ^0.10.10
+ stack_trace: ^1.10.0
+
+dev_dependencies:
+ dart_flutter_team_lints: ^3.0.0
+ source_span: ^1.8.0
+ test: ^1.16.0
diff --git a/pkgs/source_map_stack_trace/test/source_map_stack_trace_test.dart b/pkgs/source_map_stack_trace/test/source_map_stack_trace_test.dart
new file mode 100644
index 0000000..dd4d710
--- /dev/null
+++ b/pkgs/source_map_stack_trace/test/source_map_stack_trace_test.dart
@@ -0,0 +1,264 @@
+// 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:path/path.dart' as p;
+import 'package:source_map_stack_trace/source_map_stack_trace.dart';
+import 'package:source_maps/source_maps.dart';
+import 'package:source_span/source_span.dart';
+import 'package:stack_trace/stack_trace.dart';
+import 'package:test/test.dart';
+
+/// A simple [Mapping] for tests that don't need anything special.
+final _simpleMapping = parseJson((SourceMapBuilder()
+ ..addSpan(
+ SourceMapSpan.identifier(
+ SourceLocation(1, line: 1, column: 3, sourceUrl: 'foo.dart'),
+ 'qux'),
+ SourceSpan(SourceLocation(8, line: 5, column: 0),
+ SourceLocation(18, line: 15, column: 0), '\n' * 10)))
+ .build('foo.dart.js.map'));
+
+final _packageMap = {
+ 'bar': Uri.parse('packages/bar'),
+ 'foo': Uri.parse('packages/foo'),
+};
+
+void main() {
+ test('maps a JS line and column to a Dart line and span', () {
+ var trace = Trace.parse('foo.dart.js 10:11 foo');
+ var frame = _mapTrace(_simpleMapping, trace).frames.first;
+ expect(frame.uri, equals(Uri.parse('foo.dart')));
+
+ // These are +1 because stack_trace is 1-based whereas source_span is
+ // 0-basd.
+ expect(frame.line, equals(2));
+ expect(frame.column, equals(4));
+ });
+
+ test('ignores JS frames without line info', () {
+ var trace = Trace.parse('''
+foo.dart.js 10:11 foo
+foo.dart.js bar
+foo.dart.js 10:11 baz
+''');
+ var frames = _mapTrace(_simpleMapping, trace).frames;
+
+ expect(frames.length, equals(2));
+ expect(frames.first.member, equals('foo'));
+ expect(frames.last.member, equals('baz'));
+ });
+
+ test('ignores JS frames without corresponding spans', () {
+ var trace = Trace.parse('''
+foo.dart.js 10:11 foo
+foo.dart.js 1:1 bar
+foo.dart.js 10:11 baz
+''');
+
+ var frames = _mapTrace(_simpleMapping, trace).frames;
+
+ expect(frames.length, equals(2));
+ expect(frames.first.member, equals('foo'));
+ expect(frames.last.member, equals('baz'));
+ });
+
+ test('include frames from JS files not covered by the source map bundle', () {
+ var trace = Trace.parse('''
+foo.dart.js 10:11 foo
+jquery.js 10:1 foo
+bar.dart.js 10:11 foo
+''');
+ var builder = SourceMapBuilder()
+ ..addSpan(
+ SourceMapSpan.identifier(
+ SourceLocation(1,
+ line: 1, column: 3, sourceUrl: 'packages/foo/foo.dart'),
+ 'qux'),
+ SourceSpan(SourceLocation(8, line: 5, column: 0),
+ SourceLocation(12, line: 9, column: 1), '\n' * 4));
+ var sourceMapJson1 = builder.build('foo.dart.js.map');
+ sourceMapJson1['file'] = 'foo.dart.js';
+
+ builder = SourceMapBuilder()
+ ..addSpan(
+ SourceMapSpan.identifier(
+ SourceLocation(1,
+ line: 1, column: 3, sourceUrl: 'packages/bar/bar.dart'),
+ 'qux'),
+ SourceSpan(SourceLocation(8, line: 5, column: 0),
+ SourceLocation(12, line: 9, column: 1), '\n' * 4));
+ var sourceMapJson2 = builder.build('bar.dart.js.map');
+ sourceMapJson2['file'] = 'bar.dart.js';
+
+ var bundle = [sourceMapJson1, sourceMapJson2];
+ var mapping = parseJsonExtended(bundle);
+ var frames = _mapTrace(mapping, trace, packageMap: _packageMap).frames;
+
+ expect(frames.length, equals(3));
+
+ var frame = frames[0];
+ expect(frame.uri, equals(Uri.parse('package:foo/foo.dart')));
+ expect(frame.line, equals(2));
+ expect(frame.column, equals(4));
+
+ frame = frames[1];
+ expect(p.basename(frame.uri.toString()), equals('jquery.js'));
+ expect(frame.line, equals(10));
+
+ frame = frames[2];
+ expect(frame.uri, equals(Uri.parse('package:bar/bar.dart')));
+ expect(frame.line, equals(2));
+ expect(frame.column, equals(4));
+ });
+
+ test('falls back to column 0 for unlisted column', () {
+ var trace = Trace.parse('foo.dart.js 10 foo');
+ var builder = SourceMapBuilder()
+ ..addSpan(
+ SourceMapSpan.identifier(
+ SourceLocation(1, line: 1, column: 3, sourceUrl: 'foo.dart'),
+ 'qux'),
+ SourceSpan(SourceLocation(8, line: 5, column: 0),
+ SourceLocation(12, line: 9, column: 1), '\n' * 4));
+
+ var mapping = parseJson(builder.build('foo.dart.js.map'));
+ var frame = _mapTrace(mapping, trace).frames.first;
+ expect(frame.uri, equals(Uri.parse('foo.dart')));
+ expect(frame.line, equals(2));
+ expect(frame.column, equals(4));
+ });
+
+ test('uses package: URIs for frames within a packageResolver.packageMap URL',
+ () {
+ var trace = Trace.parse('foo.dart.js 10 foo');
+ var builder = SourceMapBuilder()
+ ..addSpan(
+ SourceMapSpan.identifier(
+ SourceLocation(1,
+ line: 1, column: 3, sourceUrl: 'packages/foo/foo.dart'),
+ 'qux'),
+ SourceSpan(SourceLocation(8, line: 5, column: 0),
+ SourceLocation(12, line: 9, column: 1), '\n' * 4));
+
+ var mapping = parseJson(builder.build('foo.dart.js.map'));
+ var mappedTrace = _mapTrace(mapping, trace, packageMap: _packageMap);
+ var frame = mappedTrace.frames.first;
+ expect(frame.uri, equals(Uri.parse('package:foo/foo.dart')));
+ expect(frame.line, equals(2));
+ expect(frame.column, equals(4));
+ });
+
+ test('uses dart: URIs for frames within sdkRoot', () {
+ var trace = Trace.parse('foo.dart.js 10 foo');
+ var builder = SourceMapBuilder()
+ ..addSpan(
+ SourceMapSpan.identifier(
+ SourceLocation(1,
+ line: 1, column: 3, sourceUrl: 'sdk/lib/async/foo.dart'),
+ 'qux'),
+ SourceSpan(SourceLocation(8, line: 5, column: 0),
+ SourceLocation(12, line: 9, column: 1), '\n' * 4));
+
+ var mapping = parseJson(builder.build('foo.dart.js.map'));
+ var frame =
+ _mapTrace(mapping, trace, sdkRoot: Uri.parse('sdk/')).frames.first;
+ expect(frame.uri, equals(Uri.parse('dart:async/foo.dart')));
+ expect(frame.line, equals(2));
+ expect(frame.column, equals(4));
+ });
+
+ test('converts a stack chain', () {
+ var trace = Chain([
+ Trace.parse('foo.dart.js 10:11 foo'),
+ Trace.parse('foo.dart.js 10:11 bar')
+ ]);
+ var traces = _mapChain(_simpleMapping, trace).traces;
+
+ var frame = traces.first.frames.single;
+ expect(frame.uri, equals(Uri.parse('foo.dart')));
+ expect(frame.member, equals('foo'));
+ expect(frame.line, equals(2));
+ expect(frame.column, equals(4));
+
+ frame = traces.last.frames.single;
+ expect(frame.uri, equals(Uri.parse('foo.dart')));
+ expect(frame.member, equals('bar'));
+ expect(frame.line, equals(2));
+ expect(frame.column, equals(4));
+ });
+
+ group('cleans up', () {
+ test('Firefox junk', () {
+ expect(_prettify('foo/<'), equals('foo'));
+ expect(_prettify('foo<'), equals('foo'));
+ });
+
+ test('arity indicators', () {
+ expect(_prettify(r'foo$1'), equals('foo'));
+ expect(_prettify(r'foo$1234'), equals('foo'));
+ });
+
+ test('named arguments', () {
+ expect(_prettify(r'foo$1$bar'), equals('foo'));
+ expect(_prettify(r'foo$123$bar$bang$qux'), equals('foo'));
+ });
+
+ test('closures', () {
+ expect(_prettify('foo_closure.call'), equals('foo.<fn>'));
+ });
+
+ test('nested closures', () {
+ expect(_prettify('foo__closure.call'), equals('foo.<fn>.<fn>'));
+ expect(
+ _prettify('foo____closure.call'), equals('foo.<fn>.<fn>.<fn>.<fn>'));
+ });
+
+ test('.call', () {
+ expect(_prettify('foo.call'), equals('foo'));
+ });
+
+ test('top-level functions', () {
+ expect(_prettify('dart.foo'), equals('foo'));
+ });
+
+ test('library namespaces', () {
+ expect(_prettify(r'my_library$foo'), equals('foo'));
+ });
+
+ test('static methods', () {
+ expect(_prettify(r'Foo.static.foo'), equals('foo'));
+ });
+
+ test('instance methods', () {
+ expect(_prettify(r'Foo_bar__baz'), equals('Foo.bar._baz'));
+ });
+
+ test('lots of stuff', () {
+ expect(_prettify(r'lib$Foo.static.lib$Foo_closure.call$0/<'),
+ equals('Foo.<fn>'));
+ });
+ });
+}
+
+/// Like [mapStackTrace], but is guaranteed to return a [Trace] so it can be
+/// inspected.
+Trace _mapTrace(Mapping sourceMap, StackTrace stackTrace,
+ {bool minified = false, Map<String, Uri>? packageMap, Uri? sdkRoot}) {
+ return Trace.from(mapStackTrace(sourceMap, stackTrace,
+ minified: minified, packageMap: packageMap, sdkRoot: sdkRoot));
+}
+
+/// Like [mapStackTrace], but is guaranteed to return a [Chain] so it can be
+/// inspected.
+Chain _mapChain(Mapping sourceMap, StackTrace stackTrace,
+ {bool minified = false, Map<String, Uri>? packageMap, Uri? sdkRoot}) {
+ return Chain.forTrace(mapStackTrace(sourceMap, stackTrace,
+ minified: minified, packageMap: packageMap, sdkRoot: sdkRoot));
+}
+
+/// Runs the mapper's prettification logic on [member] and returns the result.
+String? _prettify(String member) {
+ var trace = Trace([Frame(Uri.parse('foo.dart.js'), 10, 11, member)]);
+ return _mapTrace(_simpleMapping, trace).frames.first.member;
+}
diff --git a/pkgs/unified_analytics/.gitignore b/pkgs/unified_analytics/.gitignore
new file mode 100644
index 0000000..9377e38
--- /dev/null
+++ b/pkgs/unified_analytics/.gitignore
@@ -0,0 +1,14 @@
+# Files and directories created by pub.
+.dart_tool/
+.packages
+
+# Conventional directory for build outputs.
+build/
+
+# Omit committing pubspec.lock for library packages; see
+# https://dart.dev/guides/libraries/private-files#pubspeclock.
+pubspec.lock
+
+.vscode/
+coverage/
+*.DS_Store
diff --git a/pkgs/unified_analytics/CHANGELOG.md b/pkgs/unified_analytics/CHANGELOG.md
new file mode 100644
index 0000000..86d0110
--- /dev/null
+++ b/pkgs/unified_analytics/CHANGELOG.md
@@ -0,0 +1,173 @@
+## 6.1.4
+
+- Fix formatting and remove dependency on `package:intl`.
+- Remove direct usage of `package:path` in favor of `package:file`.
+- Added `androidAppId` and `iosBundleId` to the `Event.devtoolsEvent` constructor.
+
+## 6.1.3
+
+- Require Dart 3.4.
+- Added `isWasm` parameter to the `Event.devtoolsEvent` constructor.
+- Added an optional parameter `data` to the `Event.exception` constructor.
+
+## 6.1.2
+
+- Avoid opening large telemetry log files to prevent out of memory errors.
+
+## 6.1.1
+
+- Fixed bug where calling `Analytics.send` could result in a `FileSystemException` when unable to write to a log file.
+
+## 6.1.0
+
+- Added new event constructor `Event.devtoolsEvent` for the single devtools event with a new enum value `DashEvent.devtoolsEvent`
+
+## 6.0.0
+
+- Consolidate `Session` functionality into `UserProperty` to prevent race condition crash where session logic crashed before initializing `UserProperty`
+- Get rid of `late` variables throughout implementation class, `AnalyticsImpl`
+- Any error events (`Event.analyticsException`) encountered within package will be sent when invoking `Analytics.close`; replacing `ErrorHandler` functionality
+- Exposing new method for `FakeAnalytics.sendPendingErrorEvents` to send error events on command
+- Added `Event.fromJson` static method to generate instance of `Event` from JSON
+- Remove unused parameters `measurementId` and `apiSecret` from the `Analytics.test` constructor
+- Remove `Analytics.test` factory constructor in favor of `Analytics.fake` static method to return a `FakeAnalytics` instance
+- Remove `FakeAnalytics` default constructor in favor of `Analytics.fake`
+
+## 5.8.8
+
+- [Bug fix](https://github.com/dart-lang/tools/issues/252) rewrite the other call site for the session file
+
+## 5.8.7
+
+- [Bug fix](https://github.com/dart-lang/tools/issues/252) to rewrite the `last_ping` key into the session json file
+
+## 5.8.6
+
+- Refactored session handler class to use the last modified timestamp as the last ping value to prevent writing to file with each send
+- Bumping intl package to 0.19.0 to fix version solving issue with flutter_tools
+
+## 5.8.5
+
+- Fix late initialization error for `Analytics.userProperty` [bug](https://github.com/dart-lang/tools/issues/238)
+
+## 5.8.4
+
+- Exporting all enums from [`enums.dart`](https://github.com/dart-lang/tools/blob/main/pkgs/unified_analytics/lib/src/enums.dart) through `lib/testing.dart`
+
+## 5.8.3
+
+- [Fix bug](https://github.com/flutter/flutter/issues/143792) when parsing session json file
+
+## 5.8.2
+
+- Added new event `Event.analyticsException` to track internal errors for this package
+- Redirecting the `Analytics.test` factory to return an instance of `FakeAnalytics`
+- Exposing new helper function that can be used to parse the Dart SDK version
+
+## 5.8.1
+
+- Refactor logic for `okToSend` and `shouldShowMessage`
+- Check devtools config file for legacy opt out status
+
+## 5.8.0
+
+- Fix template string for consent message
+- Add `enabledFeatures` to constructor to collect features enabled for each dash tool
+
+## 5.7.0
+
+- Added the `Event.commandUsageValues` constructor
+
+## 5.6.0
+
+- Added the `Event.timing` constructor
+
+## 5.5.0
+
+- Edit to the `Event.flutterCommandResult` constructor to add `commandHasTerminal`
+- Added timeout for `Analytics.setTelemetry` to prevent the clients from hanging
+- Added the `Event.appleUsageEvent` constructor
+- Added the `Event.exception` constructor
+
+## 5.4.0
+
+- Added the `Event.codeSizeAnalysis` constructor
+
+## 5.3.0
+
+- User property "host_os_version" added to provide detail version information about the host
+- User property "locale" added to provide language related information
+- User property "client_ide" (optional) added to provide the IDE used by the Dash tool using this package, if applicable
+- Added the `Event.flutterCommandResult` constructor
+
+## 5.2.0
+
+- Added the `Event.hotRunnerInfo` constructor
+
+## 5.1.0
+
+- Added the `Event.flutterBuildInfo` constructor
+
+## 5.0.0
+
+- Update to the latest version of `package:dart_flutter_team_lints`
+- Using internal futures list to store send events
+- Added the `Event.doctorValidatorResult` constructor
+
+## 4.0.1
+
+- Adding constant for the NoOpAnalytics instance client ID to enable clients to reference it in tests
+
+## 4.0.0
+
+- Enhanced `LogFileStats` data to include information about flutter channel counts and tool counts
+- Added new method to suppress telemetry collection temporarily for current invocation via `analytics.suppressTelemetry()`
+- Added `SurveyHandler` feature to `Analytics` instance to fetch available surveys from remote endpoint to display to users along with functionality to dismiss them
+- Surveys will be disabled for any users that have been opted out
+- Shipping `FakeAnalytics` for clients of this tool that need to ensure workflows are sending events in tests
+- Adding getter to `Analytics` instance to fetch the client ID being sent to GA4
+
+## 3.0.0
+
+- Allow latest package versions for `file` and `http`
+- Introducing new `Event` class that will standardize what event data can be sent with each event
+- Deprecating the `sendEvent` method in favor of the `send` method
+
+## 2.0.0
+
+- Refactoring `dateStamp` utility function to be defined in `utils.dart` instead of having static methods in `Initializer` and `ConfigHandler`
+- Remove the `pddFlag` now that the revisions to the PDD have been finalized to persist data in the log file and session json file
+- Opting out will now delete the contents of the CLIENT ID, session json, and log files; opting back in will regenerate them as events send
+- `enableAsserts` parameter added to constructors for `Analytics` to check body of POST request for Google Analytics 4 limitations
+- Now checking if write permissions are enabled for user's home directory, if not allowed, `NoOpAnalytics` returned by `Analytics` factory constructor
+
+## 1.1.0
+
+- Added a `okToSend` getter so that clients can easily and accurately check the state of the consent mechanism.
+- Initialize the config file with user opted out if user was opted out in legacy Flutter and Dart analytics
+
+## 1.0.1
+
+- Error handling on the `analytics.sendEvent(...)` method to silently error out and return a `500` http status code to let tools using this package know Google Analytics did not receive the event (all successful requests will have a status code of `2xx` provided by Google Analytics)
+
+## 1.0.0
+
+- Error handling functionality added to prevent malformed session json data from causing a crash
+- Creating a new analytics constructor to point to a test instance of Google Analytics for developers
+- Align supported tool list with PDD
+- Exposing a new instance method that will need to be invoked when a client has successfully shown the consent message to the user `clientShowedMessage()`
+- Adding and incrementing a tool's version will automatically use the current consent message version instead of incrementing by 1
+- Default constructor has disabled the usage of local log file and session json file until revisions have landed to the privacy document
+
+## 0.1.2
+
+- Implemented fake Google Analytics Client for `Analytics.test(...)` constructor; marked with visible for testing annotation
+
+## 0.1.1
+
+- Bumping intl package to 0.18.0 to fix version solving issue with flutter_tools
+- LogFileStats includes more information about how many events are persisted and total count of how many times each event was sent
+
+## 0.1.0
+
+- Initial version
diff --git a/pkgs/unified_analytics/LICENSE b/pkgs/unified_analytics/LICENSE
new file mode 100644
index 0000000..ac90031
--- /dev/null
+++ b/pkgs/unified_analytics/LICENSE
@@ -0,0 +1,27 @@
+Copyright 2023, the Dart project authors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of Google LLC nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/pkgs/unified_analytics/README.md b/pkgs/unified_analytics/README.md
new file mode 100644
index 0000000..4263cfb
--- /dev/null
+++ b/pkgs/unified_analytics/README.md
@@ -0,0 +1,17 @@
+[](https://github.com/dart-lang/tools/actions/workflows/unified_analytics.yml)
+[](https://pub.dev/packages/unified_analytics)
+[](https://pub.dev/packages/unified_analytics/publisher)
+
+## What's this?
+
+This package is intended to be used on Dart and Flutter related
+tooling only. It provides APIs to send events to Google Analytics using the
+Measurement Protocol.
+
+This is not intended to be general purpose or consumed by the community. It is
+responsible for toggling analytics collection for related tooling on each
+developer's machine.
+
+## Using this package
+
+Refer to the [usage guide](USAGE_GUIDE.md).
diff --git a/pkgs/unified_analytics/USAGE_GUIDE.md b/pkgs/unified_analytics/USAGE_GUIDE.md
new file mode 100644
index 0000000..ef5bbea
--- /dev/null
+++ b/pkgs/unified_analytics/USAGE_GUIDE.md
@@ -0,0 +1,202 @@
+This package is intended to be used on Dart and Flutter related tooling only.
+It provides APIs to send events to Google Analytics using the Measurement Protocol.
+
+## Usage
+
+To get started using this package, import at the entrypoint dart file and
+initialize with the required parameters.
+
+The example file shows an end-to-end usage guide for using this package and
+can be referred to here [unified_analytics_example.dart](example/unified_analytics_example.dart).
+
+**IMPORTANT**: It is best practice to close the http client connection when finished
+sending events, otherwise, you may notice that the dart process hangs on exit. The example below
+shows how to handle closing the connection via `analytics.close()` method.
+
+[Link to documentation for http client's close method](https://pub.dev/documentation/http/latest/http/Client-class.html)
+
+
+## Opting In and Out of Analytics Collection
+
+It will be important for each tool to expose a trivial method to
+disabling or enabling analytics collection. Based on how the user interacts
+with the tool, this can be done through the CLI, IDE, etc. The tool will
+then pass a boolean to an API exposed by the package as shown below.
+
+```dart
+// Begin by initializing the class
+final Analytics analytics = Analytics(...);
+
+// The boolean below simulates the user deciding to opt-out
+// of Analytics collection
+final bool status = false;
+
+// Call the method to pass the boolean
+analytics.setTelemetry(status);
+```
+
+## Displaying Consent Message to Users
+
+When a user first uses any tool with this package enabled, the tool using
+this package will need to ensure that the user has seen the consent message.
+The tool using this package should check with the `Analytics` instance
+by invoking the `shouldShowMessage` getter. When this getter returns
+`true`, this means that the user has not been enrolled into analytics
+collection yet. It is at this point that the tool using this package will
+invoke the `getConsentMessage` getter to return a string to share with the
+user (each tool will have their own method of displaying the message
+through cli stdout, popup modal, etc.). Once the message has been shown,
+the tool using this package will need to confirm to the `Analytics` instance
+that it has shown the message; it is at this point that the user has
+officially been onboarded to analytics collection.
+
+
+
+```dart
+// Begin by initializing the class near the entrypoint
+final Analytics analytics = Analytics(...);
+
+// This conditional should always run; the first time it is run, this
+// will return true since the consent message has never been shown
+if (analytics.shouldShowMessage) {
+
+ // Simulates displaying the message, this will vary from
+ // client to client; ie. stdout, popup in IDE, etc.
+ print(analytics.getConsentMessage);
+
+ // After receiving confirmation that the message has been
+ // displayed, invoking the below method will successfully
+ // onboard the tool into the config file and allow for
+ // events to be sent on the next creation of the analytics
+ // instance
+ analytics.clientShowedMessage();
+}
+```
+
+## Checking User Opt-In Status
+
+Some tools may need to know if the user has opted in for Analytics
+collection in order to enable additional functionality. The example below
+shows how to check the status.
+
+```dart
+// Begin by initializing the class
+final Analytics analytics = Analytics(...);
+
+// This getter will return a boolean showing the status;
+// print statement used for trivial usage example
+print('This user's status: ${analytics.telemetryEnabled}'); // true if opted-in
+```
+
+## Checking for New Versions of Consent Message
+
+In the event that the package consent messaging needs has been updated, an
+API has been exposed on an instance of `Analytics` that will notify the tool
+using this package whether to display the message again.
+
+```dart
+// Begin by initializing the class
+//
+// This is assuming that the tool has already been onboarded
+// and that the user has already seen the previous version of
+// the consent message
+final Analytics analytics = Analytics(...);
+
+
+// Much like the first example, if there is a new version of
+// the tools message that needs to be shown, use the same work
+// workflow
+if (analytics.shouldShowMessage) {
+
+ // Simulates displaying the message, this will vary from
+ // client to client; ie. stdout, popup in IDE, etc.
+ print(analytics.getConsentMessage);
+
+ // After receiving confirmation that the message has been
+ // displayed, invoking the below method will successfully
+ // onboard the tool into the config file and allow for
+ // events to be sent on the next creation of the analytics
+ // instance
+ analytics.clientShowedMessage();
+}
+```
+
+It is important to note events will not be sent if there is a new version of
+the consent message.
+
+## Developing Within `package:unified_analytics`
+
+### Adding new data classes
+
+#### User properties
+In Google Analytics, new data fields can be collected as user properties
+or events.
+
+User properties are key-value pairs that can be used to segment users. For example,
+the Flutter channel used. To request that a new user property
+be added, file an issue [using this template](https://github.com/dart-lang/tools/issues/new?template=unified_analytics_user_property.yml).
+
+To add a new user property, add a new property to the `UserProperty` class
+in the [`user_property.dart` file](./lib/src/user_property.dart).
+
+#### Events
+Events are actions that the user, or tool, performs. In Google Analytics,
+events can have associated data. This event data is stored
+in key-value pairs.
+
+To request new events, or event data, file an issue
+[using this template](https://github.com/dart-lang/tools/issues/new?template=unified_analytics_event.yml).
+
+To add a new event, create a new field in the `DashEvent` enum (if necessary) in
+the [`enums.dart` file](./lib/src/enums.dart).
+
+Then, add event data, create a new constructor for the `Event` class
+in the [`event.dart` file](./lib/src/event.dart).
+
+
+### Testing event collection
+
+When contributing to this package, if the developer needs to verify that
+events have been sent, the developer should the use development constructor
+so that the events being sent are not going into the production instance.
+
+```dart
+final Analytics analytics = Analytics.development(...);
+```
+
+Reach out to maintainers to get access to the test Google Analytics endpoint.
+
+## Advanced Usage: Querying Locally Persisted Logs
+
+This package enables tools to persist the events that have been sent
+to Google Analytics for logging by default. This can be very helpful if
+tools would like to understand the user's activity level across all
+related tooling. For example, if querying the locally persisted logs
+shows that the user has not been active for N number of days, a tool that
+works within an IDE can prompt the user with a survey to understand why their
+level of activity has dropped.
+
+The snippet below shows how to invoke the query and a sample response.
+
+```dart
+// Begin by initializing the class
+final Analytics analytics = Analytics(...);
+
+// Printing the query results returns json formatted
+// string to view; data can also be accessed through
+// [LogFileStats] getters
+print(analytics.logFileStats());
+```
+Refer to the `LogFileStats` instance [variables](lib/src/log_handler.dart) for details on the result.
+
+Explanation of the each key above
+
+- startDateTime: the earliest event that was sent
+- minsFromStartDateTime: the number of minutes elapsed since the earliest message
+- endDateTime: the latest, most recent event that was sent
+- minsFromEndDateTime: the number of minutes elapsed since the latest message
+- sessionCount: count of sessions; sessions have a minimum time of 30 minutes
+- flutterChannelCount: count of flutter channels (can be 0 if developer is a Dart dev only)
+- toolCount: count of the Dart and Flutter tools sending analytics
+- recordCount: count of the total number of events in the log file
+- eventCount: counts each unique event and how many times they occurred in the log file
\ No newline at end of file
diff --git a/pkgs/unified_analytics/analysis_options.yaml b/pkgs/unified_analytics/analysis_options.yaml
new file mode 100644
index 0000000..746ad64
--- /dev/null
+++ b/pkgs/unified_analytics/analysis_options.yaml
@@ -0,0 +1,10 @@
+# This file configures the static analysis results for your project (errors,
+# warnings, and lints).
+
+include: package:dart_flutter_team_lints/analysis_options.yaml
+
+linter:
+ rules:
+ - avoid_catches_without_on_clauses
+ - prefer_final_in_for_each
+ - prefer_final_locals
diff --git a/pkgs/unified_analytics/coverage_runner.sh b/pkgs/unified_analytics/coverage_runner.sh
new file mode 100755
index 0000000..4043614
--- /dev/null
+++ b/pkgs/unified_analytics/coverage_runner.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+# Generate `coverage/lcov.info` file
+flutter test --coverage
+
+# Generate HTML report
+# Note: on macOS you need to have lcov installed on your system (`brew install lcov`) to use this:
+genhtml coverage/lcov.info -o coverage/html
+
+# Open the report
+open coverage/html/index.html
diff --git a/pkgs/unified_analytics/example/sample_rate.dart b/pkgs/unified_analytics/example/sample_rate.dart
new file mode 100644
index 0000000..51b0cdb
--- /dev/null
+++ b/pkgs/unified_analytics/example/sample_rate.dart
@@ -0,0 +1,90 @@
+// Copyright (c) 2023, 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:unified_analytics/src/utils.dart';
+
+/// The purpose of this example file is to demonstrate the sampling
+/// rate functionality from the survey handler.
+///
+/// It defines a `remoteUniqueId` that subs in for a real survey's unique
+/// ID that is hosted in the remote json file.
+///
+/// Begin the simulation by setting the `testSampleRate` and `iterations`
+/// variables, where `iterations` simulates real users and `testSampleRate`
+/// represents a fraction of how many people should be sampled.
+///
+/// In this example, we have set the `testSampleRate` to `0.3`, meaning we want
+/// sample 30% of users, and `iterations` to `10,000`, which simulates `10,000`
+/// users.
+///
+/// Running the script with predefined seed of `123` will
+/// generate the below `stdout`
+/// ```
+/// Test sample rate = 0.3
+/// Number of iterations = 10000
+/// ---
+///
+/// Count of iterations sampled (successes) = 3046
+/// Actual sample rate = 0.3046
+/// ---
+///
+/// Runtime = 8ms
+/// ```
+///
+/// The actual results yielded 3,046 people selected for a rate
+/// of `30.46%` which is about the `30%` defined in `testSampleRate`.
+void main() {
+ // Seed has been set to replicate results
+ //
+ // Test with your own seed and alter other parameters
+ // as needed
+ final uuidGenerator = Uuid(123);
+
+ // Randomly generate an ID that will simulate being used for
+ // a given survey
+ final remoteUniqueId = uuidGenerator.generateV4();
+
+ // Define a sampling rate that we would like to test
+ //
+ // Setting 0.3 means any generated doubles less than or
+ // equal to 0.3 results in a survey getting delievered
+ const testSampleRate = 0.3;
+
+ // Define how many iterations to run, each iteration can
+ // be thought of as a developer using a dash tool
+ const iterations = 10000;
+
+ // Initializing a counter that will count the number of
+ // iterations that were below the sampling rate
+ var count = 0;
+
+ final start = DateTime.now();
+ for (var i = 0; i < iterations; i++) {
+ // Each newly generated ID is simulating a unique
+ // developer's CLIENT ID that is persisted on their disk
+ final clientId = uuidGenerator.generateV4();
+
+ // Generate a double that will be compared against the sampleRate
+ final generatedDouble = sampleRate(remoteUniqueId, clientId);
+
+ // Count successes if the generated double is less than our
+ // testing sample rate
+ if (generatedDouble <= testSampleRate) {
+ count++;
+ }
+ }
+ final end = DateTime.now();
+
+ print('''
+Test sample rate = $testSampleRate
+Number of iterations = $iterations
+---
+
+Count of iterations sampled (successes) = $count
+Actual sample rate = ${(count / iterations).toStringAsFixed(4)}
+---
+
+Runtime = ${end.difference(start).inMilliseconds}ms
+''');
+}
diff --git a/pkgs/unified_analytics/example/serving_surveys.dart b/pkgs/unified_analytics/example/serving_surveys.dart
new file mode 100644
index 0000000..d56339e
--- /dev/null
+++ b/pkgs/unified_analytics/example/serving_surveys.dart
@@ -0,0 +1,165 @@
+// Copyright (c) 2023, 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:clock/clock.dart';
+import 'package:file/file.dart';
+import 'package:file/memory.dart';
+
+import 'package:unified_analytics/src/constants.dart';
+import 'package:unified_analytics/src/enums.dart';
+import 'package:unified_analytics/src/survey_handler.dart';
+import 'package:unified_analytics/unified_analytics.dart';
+
+/// This example code is intended to only be used as guidance for
+/// clients using this package. Clients using this package should avoid
+/// the use of the [Analytics.fake] static method.
+///
+/// It was used in this example file so that the real [FileSystem] was swapped
+/// out for a [MemoryFileSystem] so that repeated runs of this script yield
+/// the same results.
+void main() async {
+ late final MemoryFileSystem fs;
+ late final Analytics analytics;
+ late final Directory home;
+ // We need to initialize with a fake clock since the surveys have
+ // a period of time they are valid for
+ await withClock(Clock.fixed(DateTime(2023, 3, 3, 12, 0)), () async {
+ // Use a memory file system to repeatedly run this example
+ // file with the test instance
+ fs = MemoryFileSystem(style: FileSystemStyle.posix);
+ home = fs.directory('home');
+ home.createSync();
+
+ // The purpose of `initialAnalytics` is so that the tool is able to
+ // send events after its first run; this instance won't be used below
+ //
+ // ignore: invalid_use_of_visible_for_testing_member
+ final initialAnalytics = Analytics.fake(
+ tool: DashTool.flutterTool,
+ homeDirectory: home,
+ dartVersion: 'dartVersion',
+ fs: fs,
+ platform: DevicePlatform.macos,
+ );
+ // The below command allows `DashTool.flutterTool` to send telemetry
+ initialAnalytics.clientShowedMessage();
+
+ // ignore: invalid_use_of_visible_for_testing_member
+ analytics = Analytics.fake(
+ tool: DashTool.flutterTool,
+ homeDirectory: home,
+ dartVersion: 'dartVersion',
+ fs: fs,
+ platform: DevicePlatform.macos,
+ surveyHandler: FakeSurveyHandler.fromList(
+ dismissedSurveyFile: home
+ .childDirectory(kDartToolDirectoryName)
+ .childFile(kDismissedSurveyFileName),
+ initializedSurveys: [
+ Survey(
+ uniqueId: 'uniqueId',
+ startDate: DateTime(2023, 1, 1),
+ endDate: DateTime(2023, 5, 31),
+ description: 'description',
+ snoozeForMinutes: 10,
+ samplingRate: 1.0,
+ excludeDashToolList: [],
+ conditionList: [],
+ buttonList: [
+ SurveyButton(
+ buttonText: 'View Survey',
+ action: 'accept',
+ promptRemainsVisible: false,
+ url: 'http://example.com',
+ ),
+ SurveyButton(
+ buttonText: 'More Info',
+ action: 'snooze',
+ promptRemainsVisible: true,
+ url: 'http://example2.com',
+ ),
+ SurveyButton(
+ buttonText: 'Dismiss Survey',
+ action: 'dismiss',
+ promptRemainsVisible: false,
+ )
+ ],
+ ),
+ ],
+ ));
+ });
+
+ // Each client of this package will be able to fetch all of
+ // the available surveys with the below method
+ //
+ // Sample rate will be applied automatically; it also won't
+ // fetch any surveys in the snooze period or if they have
+ // been dismissed
+ final surveyList = await analytics.fetchAvailableSurveys();
+ assert(surveyList.length == 1);
+
+ // Grab the first and only survey to simulate displaying it to a user
+ final survey = surveyList.first;
+ print('Simulating displaying the survey with a print below:');
+ print('Survey id: ${survey.uniqueId}\n');
+
+ // Immediately after displaying the survey, the method below
+ // should be run so that no other clients using this tool will show
+ // it at the same time
+ //
+ // It will "snoozed" when the below is run as well as reported to
+ // Google Analytics 4 that this survey was shown
+ analytics.surveyShown(survey);
+
+ // Get the file where this is persisted to show it getting updated
+ final persistedSurveyFile = home
+ .childDirectory(kDartToolDirectoryName)
+ .childFile(kDismissedSurveyFileName);
+ print('The contents of the json file '
+ 'after invoking `analytics.surveyShown(survey);`');
+ print('${persistedSurveyFile.readAsStringSync()}\n');
+
+ // Change the index below to decide which button to simulate pressing
+ //
+ // 0 - accept
+ // 1 - snooze
+ // 2 - dismiss
+ final selectedButtonIndex = 1;
+ assert([0, 1, 2].contains(selectedButtonIndex));
+
+ // Get the survey button by index that will need to be passed along with
+ // the survey to simulate an interaction with the survey
+ final selectedSurveyButton = survey.buttonList[selectedButtonIndex];
+ print('The simulated button pressed was: '
+ '"${selectedSurveyButton.buttonText}" '
+ '(action = ${selectedSurveyButton.action})\n');
+
+ // The below method will handle whatever action the button
+ analytics.surveyInteracted(
+ survey: survey,
+ surveyButton: selectedSurveyButton,
+ );
+
+ // Conditional to check if there is a URl to route to
+ if (selectedSurveyButton.url != null) {
+ print('***This button also has a survey URL link '
+ 'to route to at "${selectedSurveyButton.url}"***\n');
+ }
+
+ // Conditional to check what simulating a popup to stay up
+ if (selectedSurveyButton.promptRemainsVisible) {
+ print('***This button has its promptRemainsVisible field set to `true` '
+ 'so this simulates what seeing a pop up again would look like***\n');
+ }
+
+ print('The contents of the json file '
+ 'after invoking '
+ '`analytics.surveyInteracted(survey: survey, '
+ 'surveyButton: selectedSurveyButton);`');
+ print('${persistedSurveyFile.readAsStringSync()}\n');
+
+ // Demonstrating that the survey doesn't get returned again
+ print('Attempting to fetch surveys again will result in an empty list');
+ print(await analytics.fetchAvailableSurveys());
+}
diff --git a/pkgs/unified_analytics/example/unified_analytics_example.dart b/pkgs/unified_analytics/example/unified_analytics_example.dart
new file mode 100644
index 0000000..e0ddaff
--- /dev/null
+++ b/pkgs/unified_analytics/example/unified_analytics_example.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2023, 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:unified_analytics/unified_analytics.dart';
+
+// Globally instantiate the analytics class at the entry
+// point of the tool
+//
+// Development constructor used here so we don't push
+// to production when running
+final Analytics analytics = Analytics.development(
+ tool: DashTool.flutterTool,
+ flutterChannel: 'ey-test-channel',
+ flutterVersion: 'Flutter 3.6.0-7.0.pre.47',
+ clientIde: 'VSCode',
+ dartVersion: 'Dart 2.19.0',
+ // This can be set to true while testing to validate
+ // against GA4 usage limitations (character limits, etc.)
+ enableAsserts: false,
+ enabledFeatures: 'feature-1,feature-2',
+);
+
+// Timing a process and sending the event
+void main() async {
+ final start = DateTime.now();
+
+ // Each client using this package will have it's own
+ // method to show the message but the below is a trivial
+ // example of how to properly initialize the analytics instance
+ if (analytics.shouldShowMessage) {
+ // Simulates displaying the message, this will vary from
+ // client to client; ie. stdout, popup in IDE, etc.
+ print(analytics.getConsentMessage);
+
+ // After receiving confirmation that the message has been
+ // displayed, invoking the below method will successfully
+ // onboard the tool into the config file and allow for
+ // events to be sent on the next creation of the analytics
+ // instance
+ //
+ // The rest of the example below assumes that the tool has
+ // already been onboarded in a previous run
+ analytics.clientShowedMessage();
+ }
+
+ print('Current user ${analytics.clientId} '
+ 'is opted in: ${analytics.telemetryEnabled}');
+
+ // Example of long running process
+ await Future<void>.delayed(const Duration(milliseconds: 100));
+
+ // Calculate the metric to send
+ final runTime = DateTime.now().difference(start).inMilliseconds;
+
+ // Create the event that will be sent for the hot reload time
+ // as an example
+ final hotReloadEvent = Event.hotReloadTime(timeMs: runTime);
+
+ // Make a call to the [Analytics] api to send the data
+ analytics.send(hotReloadEvent);
+
+ // Close the client connection on exit
+ await analytics.close();
+}
diff --git a/pkgs/unified_analytics/lib/src/analytics.dart b/pkgs/unified_analytics/lib/src/analytics.dart
new file mode 100644
index 0000000..cc8b4bc
--- /dev/null
+++ b/pkgs/unified_analytics/lib/src/analytics.dart
@@ -0,0 +1,857 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io' as io;
+
+import 'package:file/file.dart';
+import 'package:file/local.dart';
+import 'package:file/memory.dart';
+import 'package:http/http.dart';
+import 'package:meta/meta.dart';
+
+import 'asserts.dart';
+import 'config_handler.dart';
+import 'constants.dart';
+import 'enums.dart';
+import 'event.dart';
+import 'ga_client.dart';
+import 'initializer.dart';
+import 'log_handler.dart';
+import 'survey_handler.dart';
+import 'user_property.dart';
+import 'utils.dart';
+
+abstract class Analytics {
+ /// The default factory constructor that will return an implementation
+ /// of the [Analytics] abstract class using the [LocalFileSystem].
+ ///
+ /// If [enableAsserts] is set to `true`, then asserts for GA4 limitations
+ /// will be enabled.
+ ///
+ /// [flutterChannel] and [flutterVersion] are nullable in case the client
+ /// using this package is unable to resolve those values.
+ ///
+ /// An optional parameter [clientIde] is also available for dart and flutter
+ /// tooling that are running from IDEs can be resolved. Such as "VSCode"
+ /// running the flutter-tool.
+ ///
+ /// [enabledFeatures] is also an optional field that can be added to collect
+ /// any features that are enabled for a user. For example,
+ /// "enable-linux-desktop,cli-animations" are two features that can be enabled
+ /// for the flutter-tool.
+ factory Analytics({
+ required DashTool tool,
+ required String dartVersion,
+ String? flutterChannel,
+ String? flutterVersion,
+ String? clientIde,
+ String? enabledFeatures,
+ bool enableAsserts = false,
+ }) {
+ // Create the instance of the file system so clients don't need
+ // resolve on their own
+ const FileSystem fs = LocalFileSystem();
+
+ // Ensure that the home directory has permissions enabled to write
+ final homeDirectory = getHomeDirectory(fs);
+ if (homeDirectory == null ||
+ !checkDirectoryForWritePermissions(homeDirectory)) {
+ return const NoOpAnalytics();
+ }
+
+ // Resolve the OS using dart:io
+ final DevicePlatform platform;
+ if (io.Platform.operatingSystem == 'linux') {
+ platform = DevicePlatform.linux;
+ } else if (io.Platform.operatingSystem == 'macos') {
+ platform = DevicePlatform.macos;
+ } else {
+ platform = DevicePlatform.windows;
+ }
+
+ // Create the instance of the GA Client which will create
+ // an [http.Client] to send requests
+ final gaClient = GAClient(
+ measurementId: kGoogleAnalyticsMeasurementId,
+ apiSecret: kGoogleAnalyticsApiSecret,
+ );
+
+ final firstRun = runInitialization(homeDirectory: homeDirectory);
+
+ return AnalyticsImpl(
+ tool: tool,
+ homeDirectory: homeDirectory,
+ flutterChannel: flutterChannel,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ platform: platform,
+ toolsMessageVersion: kToolsMessageVersion,
+ fs: fs,
+ gaClient: gaClient,
+ surveyHandler: SurveyHandler(
+ dismissedSurveyFile: homeDirectory
+ .childDirectory(kDartToolDirectoryName)
+ .childFile(kDismissedSurveyFileName),
+ ),
+ enableAsserts: enableAsserts,
+ clientIde: clientIde,
+ enabledFeatures: enabledFeatures,
+ firstRun: firstRun,
+ );
+ }
+
+ /// Factory constructor to return the [AnalyticsImpl] class with
+ /// Google Analytics credentials that point to a test instance and
+ /// not the production instance where live data will be sent.
+ ///
+ /// By default, [enableAsserts] is set to `true` to check against
+ /// GA4 limitations.
+ ///
+ /// [flutterChannel] and [flutterVersion] are nullable in case the client
+ /// using this package is unable to resolve those values.
+ factory Analytics.development({
+ required DashTool tool,
+ required String dartVersion,
+ String? flutterChannel,
+ String? flutterVersion,
+ String? clientIde,
+ String? enabledFeatures,
+ bool enableAsserts = true,
+ }) {
+ // Create the instance of the file system so clients don't need
+ // resolve on their own
+ const FileSystem fs = LocalFileSystem();
+
+ // Ensure that the home directory has permissions enabled to write
+ final homeDirectory = getHomeDirectory(fs);
+ if (homeDirectory == null) {
+ throw Exception('Unable to determine the home directory, '
+ 'ensure it is available in the environment');
+ }
+ if (!checkDirectoryForWritePermissions(homeDirectory)) {
+ throw Exception('Permissions error on the home directory!');
+ }
+
+ // Resolve the OS using dart:io
+ final DevicePlatform platform;
+ if (io.Platform.operatingSystem == 'linux') {
+ platform = DevicePlatform.linux;
+ } else if (io.Platform.operatingSystem == 'macos') {
+ platform = DevicePlatform.macos;
+ } else {
+ platform = DevicePlatform.windows;
+ }
+
+ // Credentials defined below for the test Google Analytics instance
+ const kTestMeasurementId = 'G-N1NXG28J5B';
+ const kTestApiSecret = '4yT8__oER3Cd84dtx6r-_A';
+
+ // Create the instance of the GA Client which will create
+ // an [http.Client] to send requests
+ final gaClient = GAClient(
+ measurementId: kTestMeasurementId,
+ apiSecret: kTestApiSecret,
+ );
+
+ final firstRun = runInitialization(homeDirectory: homeDirectory);
+
+ return AnalyticsImpl(
+ tool: tool,
+ homeDirectory: homeDirectory,
+ flutterChannel: flutterChannel,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ platform: platform,
+ toolsMessageVersion: kToolsMessageVersion,
+ fs: fs,
+ gaClient: gaClient,
+ surveyHandler: SurveyHandler(
+ dismissedSurveyFile: homeDirectory
+ .childDirectory(kDartToolDirectoryName)
+ .childFile(kDismissedSurveyFileName),
+ ),
+ enableAsserts: enableAsserts,
+ clientIde: clientIde,
+ enabledFeatures: enabledFeatures,
+ firstRun: firstRun,
+ );
+ }
+
+ /// The shared identifier for Flutter and Dart related tooling using
+ /// package:unified_analytics.
+ String get clientId;
+
+ /// Retrieves the consent message to prompt users with on first
+ /// run or when the message has been updated.
+ String get getConsentMessage;
+
+ /// Returns true if it is OK to send an analytics message. Do not cache,
+ /// as this depends on factors that can change, such as the configuration
+ /// file contents.
+ bool get okToSend;
+
+ /// Returns a map object with all of the tools that have been parsed
+ /// out of the configuration file.
+ Map<String, ToolInfo> get parsedTools;
+
+ /// Boolean that lets the client know if they should display the message.
+ bool get shouldShowMessage;
+
+ /// Boolean indicating whether or not telemetry is enabled.
+ bool get telemetryEnabled;
+
+ /// Returns a map representation of the [UserProperty] for the [Analytics]
+ /// instance.
+ ///
+ /// This is what will get sent to Google Analytics with every request.
+ Map<String, Map<String, Object?>> get userPropertyMap;
+
+ /// Method to be invoked by the client using this package to confirm
+ /// that the client has shown the message and that it can be added to
+ /// the config file and start sending events the next time it starts up.
+ void clientShowedMessage();
+
+ /// Call this method when the tool using this package is closed.
+ ///
+ /// Prevents the tool from hanging when if there are still requests
+ /// that need to be sent off.
+ ///
+ /// Providing [delayDuration] in milliseconds will allow the instance
+ /// to wait the provided time before closing the http connection. Keeping
+ /// the connection open for some time will allow any pending events that
+ /// are waiting to be sent to the Google Analytics server. Default value
+ /// of 250 ms applied.
+ Future<void> close({int delayDuration = kDelayDuration});
+
+ /// Method to fetch surveys from the endpoint [kContextualSurveyUrl].
+ ///
+ /// Any survey that is returned by this method has already passed
+ /// the survey conditions specified in the remote survey metadata file.
+ ///
+ /// If the method returns an empty list, then there are no surveys to be
+ /// shared with the user.
+ Future<List<Survey>> fetchAvailableSurveys();
+
+ /// Query the persisted event data stored on the user's machine.
+ ///
+ /// Returns null if there are no persisted logs.
+ LogFileStats? logFileStats();
+
+ /// Send preconfigured events using specific named constructors
+ /// on the [Event] class.
+ ///
+ /// Example
+ /// ```dart
+ /// analytics.send(Event.memory(periodSec: 123));
+ /// ```
+ void send(Event event);
+
+ /// Pass a boolean to either enable or disable telemetry and make
+ /// the necessary changes in the persisted configuration file.
+ ///
+ /// Setting the telemetry status will also send an event to GA
+ /// indicating the latest status of the telemetry from [reportingBool].
+ Future<void> setTelemetry(bool reportingBool);
+
+ /// Calling this will result in telemetry collection being suppressed for
+ /// the current invocation.
+ ///
+ /// If you would like to permanently disable telemetry
+ /// collection use:
+ ///
+ /// ```dart
+ /// analytics.setTelemetry(false)
+ /// ```
+ void suppressTelemetry();
+
+ /// Method to run after interacting with a [Survey] instance.
+ ///
+ /// Pass a [Survey] instance which can be retrieved from
+ /// [Analytics.fetchAvailableSurveys].
+ ///
+ /// [surveyButton] is the button that was interacted with by the user.
+ void surveyInteracted({
+ required Survey survey,
+ required SurveyButton surveyButton,
+ });
+
+ /// Method to be called after a survey has been shown to the user.
+ ///
+ /// Calling this will snooze the survey so it won't be shown immediately.
+ ///
+ /// The snooze period is defined by the [Survey.snoozeForMinutes] field.
+ void surveyShown(Survey survey);
+
+ /// Returns an instance of [FakeAnalytics] which can be used in tests to check
+ /// for certain [Event] instances within [FakeAnalytics.sentEvents].
+ @visibleForTesting
+ static FakeAnalytics fake({
+ required DashTool tool,
+ required Directory homeDirectory,
+ required String dartVersion,
+ required MemoryFileSystem fs,
+ String? flutterChannel,
+ String? flutterVersion,
+ String? clientIde,
+ String? enabledFeatures,
+ SurveyHandler? surveyHandler,
+ GAClient? gaClient,
+ DevicePlatform platform = DevicePlatform.linux,
+ int toolsMessageVersion = kToolsMessageVersion,
+ String toolsMessage = kToolsMessage,
+ bool enableAsserts = true,
+ }) {
+ final firstRun = runInitialization(homeDirectory: homeDirectory);
+
+ return FakeAnalytics._(
+ tool: tool,
+ homeDirectory: homeDirectory,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ platform: platform,
+ fs: fs,
+ surveyHandler: surveyHandler ??
+ FakeSurveyHandler.fromList(
+ dismissedSurveyFile: homeDirectory
+ .childDirectory(kDartToolDirectoryName)
+ .childFile(kDismissedSurveyFileName),
+ initializedSurveys: [],
+ ),
+ gaClient: gaClient ?? const FakeGAClient(),
+ clientIde: clientIde,
+ enabledFeatures: enabledFeatures,
+ firstRun: firstRun,
+ enableAsserts: enableAsserts,
+ );
+ }
+}
+
+class AnalyticsImpl implements Analytics {
+ final DashTool tool;
+ final FileSystem fs;
+ final int toolsMessageVersion;
+ final ConfigHandler _configHandler;
+ final GAClient _gaClient;
+ final SurveyHandler _surveyHandler;
+ final File _clientIdFile;
+ final UserProperty _userProperty;
+ final LogHandler _logHandler;
+
+ /// Tells the client if they need to show a message to the
+ /// user; this will return true if it is the first time the
+ /// package is being used for a developer or if the consent
+ /// message has been updated by the package.
+ bool _showMessage = false;
+
+ /// When set to `true`, various assert statements will be enabled
+ /// to ensure usage of this class is within GA4 limitations.
+ final bool _enableAsserts;
+
+ /// Telemetry suppression flag that is set via [Analytics.suppressTelemetry].
+ bool _telemetrySuppressed = false;
+
+ /// Indicates if this is the first run for a given tool.
+ bool _firstRun = false;
+
+ /// The list of futures that will contain all of the send events
+ /// from the [GAClient].
+ final _futures = <Future<Response>>[];
+
+ /// Internal value for the client id which will be lazily loaded.
+ String? _clientId;
+
+ /// Internal collection of [Event]s that have been sent
+ /// for errors encountered within package:unified_analytics.
+ ///
+ /// Stores each of the events that have been sent to GA4 so that the
+ /// same error doesn't get sent twice.
+ final Set<Event> _sentErrorEvents = {};
+
+ AnalyticsImpl({
+ required this.tool,
+ required Directory homeDirectory,
+ required String? flutterChannel,
+ required String? flutterVersion,
+ required String? clientIde,
+ required String? enabledFeatures,
+ required String dartVersion,
+ required DevicePlatform platform,
+ required this.toolsMessageVersion,
+ required this.fs,
+ required GAClient gaClient,
+ required SurveyHandler surveyHandler,
+ required bool enableAsserts,
+ required bool firstRun,
+ }) : _gaClient = gaClient,
+ _surveyHandler = surveyHandler,
+ _enableAsserts = enableAsserts,
+ _clientIdFile = homeDirectory
+ .childDirectory(kDartToolDirectoryName)
+ .childFile(kClientIdFileName),
+ _userProperty = UserProperty(
+ sessionFile: homeDirectory
+ .childDirectory(kDartToolDirectoryName)
+ .childFile(kSessionFileName),
+ flutterChannel: flutterChannel,
+ host: platform.label,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ tool: tool.label,
+ // We truncate this to a maximum of 36 characters since this can
+ // a very long string for some operating systems
+ hostOsVersion:
+ truncateStringToLength(io.Platform.operatingSystemVersion, 36),
+ locale: io.Platform.localeName,
+ clientIde: clientIde,
+ enabledFeatures: enabledFeatures,
+ ),
+ _configHandler = ConfigHandler(
+ homeDirectory: homeDirectory,
+ configFile: homeDirectory
+ .childDirectory(kDartToolDirectoryName)
+ .childFile(kConfigFileName),
+ ),
+ _logHandler = LogHandler(
+ logFile: homeDirectory
+ .childDirectory(kDartToolDirectoryName)
+ .childFile(kLogFileName),
+ ) {
+ // This initializer class will let the instance know
+ // if it was the first run; if it is, nothing will be sent
+ // on the first run
+ if (firstRun) {
+ _showMessage = true;
+ _firstRun = true;
+ } else {
+ _showMessage = false;
+ _firstRun = false;
+ }
+
+ // Check if the tool has already been onboarded, and if it
+ // has, check if the latest message version is greater to
+ // prompt the client to show a message
+ //
+ // If the tool has not been added to the config file, then
+ // we will show the message as well
+ final currentVersion =
+ _configHandler.parsedTools[tool.label]?.versionNumber ?? -1;
+ if (currentVersion < toolsMessageVersion) {
+ _showMessage = true;
+
+ // If the message version has been updated, it will be considered
+ // as if it was a first run and any events attempting to get sent
+ // will be blocked
+ _firstRun = true;
+ }
+ }
+
+ @override
+ String get clientId {
+ if (!_clientIdFile.existsSync()) {
+ createClientIdFile(clientIdFile: _clientIdFile);
+ }
+ _clientId ??= _clientIdFile.readAsStringSync();
+
+ return _clientId!;
+ }
+
+ @override
+ String get getConsentMessage {
+ // The command to swap in the consent message
+ final commandString =
+ tool == DashTool.flutterTool || tool == DashTool.devtools
+ ? 'flutter'
+ : 'dart';
+
+ return kToolsMessage
+ .replaceAll('{{ toolDescription }}', tool.description)
+ .replaceAll('{{ toolName }}', commandString);
+ }
+
+ /// Checking the [telemetryEnabled] boolean reflects what the
+ /// config file reflects.
+ ///
+ /// Checking the [_showMessage] boolean indicates if the consent
+ /// message has been shown for the user, this boolean is set to `true`
+ /// when the tool using this package invokes the [clientShowedMessage]
+ /// method.
+ ///
+ /// If the user has suppressed telemetry [_telemetrySuppressed] will
+ /// return `true` to prevent events from being sent for current invocation.
+ ///
+ /// Checking if it is the first time a tool is running with this package
+ /// as indicated by [_firstRun].
+ @override
+ bool get okToSend =>
+ telemetryEnabled && !_showMessage && !_telemetrySuppressed && !_firstRun;
+
+ @override
+ Map<String, ToolInfo> get parsedTools => _configHandler.parsedTools;
+
+ @override
+ bool get shouldShowMessage => _showMessage;
+
+ @override
+ bool get telemetryEnabled => _configHandler.telemetryEnabled;
+
+ @override
+ Map<String, Map<String, Object?>> get userPropertyMap =>
+ _userProperty.preparePayload();
+
+ @override
+ void clientShowedMessage() {
+ // Check the tool needs to be added to the config file
+ if (!_configHandler.parsedTools.containsKey(tool.label)) {
+ _configHandler.addTool(
+ tool: tool.label,
+ versionNumber: toolsMessageVersion,
+ );
+ }
+
+ // When the tool already exists but the consent message version
+ // has been updated
+ if (_configHandler.parsedTools[tool.label]!.versionNumber <
+ toolsMessageVersion) {
+ _configHandler.incrementToolVersion(
+ tool: tool.label,
+ newVersionNumber: toolsMessageVersion,
+ );
+ }
+ _showMessage = false;
+ }
+
+ @override
+ Future<void> close({int delayDuration = kDelayDuration}) async {
+ // Collect any errors encountered and send
+ _sendPendingErrorEvents();
+
+ await Future.wait(_futures).timeout(
+ Duration(milliseconds: delayDuration),
+ onTimeout: () => [],
+ );
+ _gaClient.close();
+ }
+
+ @override
+ Future<List<Survey>> fetchAvailableSurveys() async {
+ final surveysToShow = <Survey>[];
+ if (!okToSend) return surveysToShow;
+
+ final logFileStats = _logHandler.logFileStats();
+
+ // Call for surveys that have already been dismissed from
+ // persisted survey ids on disk
+ final persistedSurveyMap = _surveyHandler.fetchPersistedSurveys();
+
+ for (final survey in await _surveyHandler.fetchSurveyList()) {
+ // If the survey has listed the tool running this package in the exclude
+ // list, it will not be returned
+ if (survey.excludeDashToolList.contains(tool)) continue;
+
+ // Apply the survey's sample rate; if the generated value from
+ // the client id and survey's uniqueId are less, it will not get
+ // sent to the user
+ if (survey.samplingRate < sampleRate(clientId, survey.uniqueId)) {
+ continue;
+ }
+
+ // If the survey has been permanently dismissed or has temporarily
+ // been snoozed, skip it
+ if (surveySnoozedOrDismissed(survey, persistedSurveyMap)) continue;
+
+ // Counter to check each survey condition, if all are met, then
+ // this integer will be equal to the number of conditions in
+ // [Survey.conditionList]
+ var conditionsMet = 0;
+ if (logFileStats != null) {
+ for (final condition in survey.conditionList) {
+ // Retrieve the value from the [LogFileStats] with
+ // the label provided in the condtion
+ final logFileStatsValue =
+ logFileStats.getValueByString(condition.field);
+
+ if (logFileStatsValue == null) continue;
+
+ switch (condition.operatorString) {
+ case '>=':
+ if (logFileStatsValue >= condition.value) conditionsMet++;
+ case '<=':
+ if (logFileStatsValue <= condition.value) conditionsMet++;
+ case '>':
+ if (logFileStatsValue > condition.value) conditionsMet++;
+ case '<':
+ if (logFileStatsValue < condition.value) conditionsMet++;
+ case '==':
+ if (logFileStatsValue == condition.value) conditionsMet++;
+ case '!=':
+ if (logFileStatsValue != condition.value) conditionsMet++;
+ }
+ }
+ }
+
+ if (conditionsMet == survey.conditionList.length) {
+ surveysToShow.add(survey);
+ }
+ }
+
+ return surveysToShow;
+ }
+
+ @override
+ LogFileStats? logFileStats() => _logHandler.logFileStats();
+
+ @override
+ void send(Event event) {
+ if (!okToSend) return;
+
+ // Construct the body of the request
+ final body = generateRequestBody(
+ clientId: clientId,
+ eventName: event.eventName,
+ eventData: event.eventData,
+ userProperty: _userProperty,
+ );
+
+ if (_enableAsserts) checkBody(body);
+
+ _logHandler.save(data: body);
+
+ final gaClientFuture = _gaClient.sendData(body);
+ _futures.add(gaClientFuture);
+ gaClientFuture.whenComplete(() => _futures.remove(gaClientFuture));
+ }
+
+ @override
+ Future<void> setTelemetry(bool reportingBool) {
+ _configHandler.setTelemetry(reportingBool);
+
+ // Creation of the [Event] for opting out
+ final collectionEvent =
+ Event.analyticsCollectionEnabled(status: reportingBool);
+
+ // The body of the request that will be sent to GA4
+ final Map<String, Object?> body;
+
+ if (reportingBool) {
+ // Recreate the session and client id file; no need to
+ // recreate the log file since it will only receives events
+ // to persist from events sent
+ createClientIdFile(clientIdFile: _clientIdFile);
+ createSessionFile(sessionFile: _userProperty.sessionFile);
+
+ // Reread the client ID string so an empty string is not being
+ // sent to GA4 since the persisted files are cleared when a user
+ // decides to opt out of telemetry collection
+ _clientId = _clientIdFile.readAsStringSync();
+
+ // We must construct the body at this point after we have read in the
+ // new client id string that was generated
+ body = generateRequestBody(
+ clientId: clientId,
+ eventName: collectionEvent.eventName,
+ eventData: collectionEvent.eventData,
+ userProperty: _userProperty,
+ );
+
+ _logHandler.save(data: body);
+ } else {
+ // Construct the body of the request to signal
+ // telemetry status toggling
+ body = generateRequestBody(
+ clientId: clientId,
+ eventName: collectionEvent.eventName,
+ eventData: collectionEvent.eventData,
+ userProperty: _userProperty,
+ );
+
+ // For opted out users, data in the persisted files is cleared
+ _userProperty.sessionFile.writeAsStringSync('');
+ _logHandler.logFile.writeAsStringSync('');
+ _clientIdFile.writeAsStringSync('');
+
+ _clientId = '';
+ }
+
+ // Pass to the google analytics client to send with a
+ // timeout incase http clients hang
+ return _gaClient.sendData(body).timeout(
+ const Duration(milliseconds: kDelayDuration),
+ onTimeout: () => Response('', 200),
+ );
+ }
+
+ @override
+ void suppressTelemetry() => _telemetrySuppressed = true;
+
+ @override
+ void surveyInteracted({
+ required Survey survey,
+ required SurveyButton surveyButton,
+ }) {
+ // Any action, except for 'snooze' will permanently dismiss a given survey
+ final permanentlyDismissed = surveyButton.action == 'snooze' ? false : true;
+ _surveyHandler.dismiss(survey, permanentlyDismissed);
+ send(Event.surveyAction(
+ surveyId: survey.uniqueId,
+ status: surveyButton.action,
+ ));
+ }
+
+ @override
+ void surveyShown(Survey survey) {
+ _surveyHandler.dismiss(survey, false);
+ send(Event.surveyShown(surveyId: survey.uniqueId));
+ }
+
+ /// Send any pending error events, useful for tests to avoid closing
+ /// the connection.
+ ///
+ /// In the main implementation, [AnalyticsImpl], error events are only
+ /// sent on exit when [close] is invoked. This helper method can instead
+ /// have those error events sent immediately to help with tests that check
+ /// [FakeAnalytics.sentEvents].
+ void _sendPendingErrorEvents() {
+ // Collect any errors encountered and send
+ final errorEvents = {..._userProperty.errorSet, ..._logHandler.errorSet};
+ errorEvents
+ .where((event) =>
+ event.eventName == DashEvent.analyticsException &&
+ !_sentErrorEvents.contains(event))
+ .forEach(send);
+
+ // Ensure the same event doesn't get sent again
+ _sentErrorEvents.addAll(errorEvents);
+
+ // Clear error sets
+ _userProperty.errorSet.clear();
+ _logHandler.errorSet.clear();
+ }
+}
+
+/// This fake instance of [Analytics] is intended to be used by clients of
+/// this package for testing purposes. It exposes a list [sentEvents] that
+/// keeps track of all events that have been sent.
+///
+/// This is useful for confirming that events are being sent for a given
+/// workflow. Invoking the [send] method on this instance will not make any
+/// network requests to Google Analytics.
+class FakeAnalytics extends AnalyticsImpl {
+ /// Use this list to check for events that have been emitted when
+ /// invoking the send method
+ final List<Event> sentEvents = [];
+
+ /// Class to use when you want to see which events were sent
+ FakeAnalytics._({
+ required super.tool,
+ required super.homeDirectory,
+ required super.dartVersion,
+ required super.platform,
+ required super.fs,
+ required super.surveyHandler,
+ required super.firstRun,
+ super.flutterChannel,
+ super.flutterVersion,
+ super.clientIde,
+ super.enabledFeatures,
+ super.toolsMessageVersion = kToolsMessageVersion,
+ super.gaClient = const FakeGAClient(),
+ super.enableAsserts = true,
+ });
+
+ /// Getter to reference the private [UserProperty].
+ UserProperty get userProperty => _userProperty;
+
+ @override
+ void send(Event event) {
+ if (!okToSend) return;
+
+ // Construct the body of the request
+ final body = generateRequestBody(
+ clientId: clientId,
+ eventName: event.eventName,
+ eventData: event.eventData,
+ userProperty: _userProperty,
+ );
+
+ if (_enableAsserts) checkBody(body);
+
+ _logHandler.save(data: body);
+
+ // Using this list to validate that events are being sent
+ // for internal methods in the `Analytics` instance
+ sentEvents.add(event);
+ }
+
+ /// Public instance method to invoke private method that sends any
+ /// pending error events.
+ ///
+ /// If this is never invoked, any pending error events will be sent
+ /// when invoking the [close] method.
+ void sendPendingErrorEvents() => _sendPendingErrorEvents();
+}
+
+/// An implementation that will never send events.
+///
+/// This is for clients that opt to either not send analytics, or will migrate
+/// to use [AnalyticsImpl] at a later time.
+class NoOpAnalytics implements Analytics {
+ /// The hard-coded client ID value for each NoOp instance.
+ static String get staticClientId => 'xxxx-xxxx';
+
+ @override
+ final String getConsentMessage = '';
+
+ @override
+ final bool okToSend = false;
+
+ @override
+ final Map<String, ToolInfo> parsedTools = const <String, ToolInfo>{};
+
+ @override
+ final bool shouldShowMessage = false;
+
+ @override
+ final bool telemetryEnabled = false;
+
+ @override
+ final Map<String, Map<String, Object?>> userPropertyMap =
+ const <String, Map<String, Object?>>{};
+
+ const NoOpAnalytics();
+
+ @override
+ String get clientId => staticClientId;
+
+ @override
+ void clientShowedMessage() {}
+
+ @override
+ Future<void> close({int delayDuration = kDelayDuration}) async {}
+
+ @override
+ Future<List<Survey>> fetchAvailableSurveys() async => const <Survey>[];
+
+ @override
+ LogFileStats? logFileStats() => null;
+
+ @override
+ Future<Response>? send(Event event) => null;
+
+ @override
+ Future<void> setTelemetry(bool reportingBool) async {}
+
+ @override
+ void suppressTelemetry() {}
+
+ @override
+ void surveyInteracted({
+ required Survey survey,
+ required SurveyButton surveyButton,
+ }) {}
+
+ @override
+ void surveyShown(Survey survey) {}
+}
diff --git a/pkgs/unified_analytics/lib/src/asserts.dart b/pkgs/unified_analytics/lib/src/asserts.dart
new file mode 100644
index 0000000..199f4ee
--- /dev/null
+++ b/pkgs/unified_analytics/lib/src/asserts.dart
@@ -0,0 +1,172 @@
+// Copyright (c) 2023, 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.
+
+/// Matches only alphabetic characters.
+final RegExp alphabeticPattern = RegExp(r'^[A-Za-z]+$');
+
+/// Matches strings that contain alphanumeric characters and underscores.
+final RegExp alphaNumericPattern = RegExp(r'^[A-Za-z0-9_]+$');
+
+/// Checks that the body of the request being sent to
+/// GA4 is within the limitations.
+///
+/// Limitations can be found:
+/// https://developers.google.com/analytics/devguides/collection/protocol/ga4/sending-events?client_type=gtag#limitations
+void checkBody(Map<String, Object?> body) {
+ // Ensure we have the correct top level keys
+ if (!body.keys.contains('client_id')) {
+ throw AnalyticsException('client_id missing from top level keys');
+ }
+ if (!body.keys.contains('events')) {
+ throw AnalyticsException('events missing from top level keys');
+ }
+ if (!body.keys.contains('user_properties')) {
+ throw AnalyticsException('user_properties missing from top level keys');
+ }
+
+ final events = body['events'] as List;
+ final userProperties = body['user_properties'] as Map<String, Object?>;
+
+ // GA4 Limitation:
+ // Requests can have a maximum of 25 events
+ if (events.length > 25) {
+ throw AnalyticsException('25 is the max number of events');
+ }
+
+ // Checks for each event object
+ for (final eventMap in events.cast<Map<String, Object?>>()) {
+ final eventName = eventMap['name'] as String;
+
+ // GA4 Limitation:
+ // Event names must be 40 characters or fewer, may only contain
+ // alpha-numeric characters and underscores, and must start
+ // with an alphabetic character
+ if (eventName.length > 40) {
+ throw AnalyticsException(
+ 'Limit event names to 40 chars or less\n'
+ 'Event name: "$eventName" is too long',
+ );
+ }
+ if (!alphaNumericPattern.hasMatch(eventName)) {
+ throw AnalyticsException(
+ 'Event name can only have alphanumeric chars and underscores\n'
+ 'Event name: "$eventName" contains invalid characters',
+ );
+ }
+ if (!alphabeticPattern.hasMatch(eventName[0])) {
+ throw AnalyticsException(
+ 'Event name first char must be alphabetic char\n'
+ 'Event name: "$eventName" must begin with a valid character',
+ );
+ }
+
+ final eventParams = eventMap['params'] as Map<String, Object?>;
+
+ // GA4 Limitation:
+ // Events can have a maximum of 25 parameters
+ if (eventParams.length > 25) {
+ throw AnalyticsException(
+ 'Limit params for each event to less than 25\n'
+ 'Event: "$eventName" has too many parameters',
+ );
+ }
+
+ // Loop through each of the event parameters
+ for (final entry in eventParams.entries) {
+ final key = entry.key;
+ final value = entry.value;
+
+ // GA4 Limitation:
+ // Ensure that each value for the event params is one
+ // of the following types:
+ // `String`, `int`, `double`, or `bool`
+ if (!(value is String ||
+ value is int ||
+ value is double ||
+ value is bool)) {
+ throw AnalyticsException(
+ 'Values for event params have to be String, int, double, or bool\n'
+ 'Value for "$key" is not a valid type for event: "$eventName"',
+ );
+ }
+
+ // GA4 Limitation:
+ // Parameter names (including item parameters) must be 40 characters
+ // or fewer, may only contain alpha-numeric characters and underscores,
+ // and must start with an alphabetic character
+ if (key.length > 40) {
+ throw AnalyticsException(
+ 'Limit event param names to 40 chars or less\n'
+ 'The key: "$key" under the event: "$eventName" is too long',
+ );
+ }
+ if (!alphaNumericPattern.hasMatch(key)) {
+ throw AnalyticsException(
+ 'Event param name can only have alphanumeric chars and underscores\n'
+ 'The key: "$key" under the event: "$eventName" contains '
+ 'invalid characters',
+ );
+ }
+ if (!alphabeticPattern.hasMatch(key[0])) {
+ throw AnalyticsException(
+ 'Event param name first char must be alphabetic char\n'
+ 'The key: "$key" under the event: "$eventName" must begin '
+ 'in a valid character',
+ );
+ }
+
+ // GA4 Limitation:
+ // Parameter values (including item parameter values) must be 100
+ // characters or fewer
+ if (value.runtimeType == String) {
+ value as String;
+ if (value.length > 100) {
+ throw AnalyticsException(
+ 'Limit characters in event param value to 100 chars or less\n'
+ 'Value for "$key" is too long, value="$value"',
+ );
+ }
+ }
+ }
+ }
+
+ // GA4 Limitation:
+ // Events can have a maximum of 25 user properties
+ if (userProperties.length > 25) {
+ throw AnalyticsException('Limit user properties to 25 or less');
+ }
+
+ // Checks for each user property item
+ for (final entry in userProperties.entries) {
+ final key = entry.key;
+ final value = entry.value as Map<String, Object?>;
+
+ // GA4 Limitation:
+ // User property names must be 24 characters or fewer
+ if (key.length > 24) {
+ throw AnalyticsException('Limit user property names to 24 chars or less\n'
+ 'The user property key: "$key" is too long');
+ }
+
+ // GA4 Limitation:
+ // User property values must be 36 characters or fewer
+ final userPropValue = value['value'];
+ if (userPropValue is String && userPropValue.length > 36) {
+ throw AnalyticsException(
+ 'Limit user property values to 36 chars or less\n'
+ 'For the user property key "$key", the value "${value['value']}" '
+ 'is too long',
+ );
+ }
+ }
+}
+
+class AnalyticsException implements Exception {
+ final String message;
+
+ AnalyticsException(this.message);
+
+ @override
+ String toString() => 'AnalyticsException: $message';
+}
diff --git a/pkgs/unified_analytics/lib/src/config_handler.dart b/pkgs/unified_analytics/lib/src/config_handler.dart
new file mode 100644
index 0000000..8db4660
--- /dev/null
+++ b/pkgs/unified_analytics/lib/src/config_handler.dart
@@ -0,0 +1,224 @@
+// Copyright (c) 2023, 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 'package:clock/clock.dart';
+import 'package:convert/convert.dart';
+import 'package:file/file.dart';
+
+import 'initializer.dart';
+import 'utils.dart';
+
+/// The regex pattern used to parse the disable analytics line.
+const String telemetryFlagPattern = r'^reporting=([0|1]) *$';
+
+/// The regex pattern used to parse the tools info
+/// from the configuration file.
+///
+/// Example:
+/// ```text
+/// flutter-tool=2022-10-26,1
+/// devtools=2022-11-26,1
+/// ```
+const String toolPattern =
+ r'^([A-Za-z0-9]+[A-Za-z0-9_-]*)=([0-9]{4}-[0-9]{2}-[0-9]{2}),([0-9]+)$';
+
+class ConfigHandler {
+ /// Regex pattern implementation for matching a line in the config file.
+ static RegExp telemetryFlagRegex =
+ RegExp(telemetryFlagPattern, multiLine: true);
+ static RegExp toolRegex = RegExp(toolPattern, multiLine: true);
+
+ final Directory homeDirectory;
+ final File configFile;
+
+ final Map<String, ToolInfo> parsedTools = <String, ToolInfo>{};
+
+ DateTime configFileLastModified;
+
+ /// Reporting enabled unless specified by user
+ bool _telemetryEnabled = true;
+
+ ConfigHandler({
+ required this.homeDirectory,
+ required this.configFile,
+ }) : configFileLastModified = configFile.lastModifiedSync() {
+ // Call the method to parse the contents of the config file when
+ // this class is initialized
+ parseConfig();
+ }
+
+ /// Returns the telemetry state from the config file.
+ ///
+ /// Method will reparse the config file if it detects that the
+ /// last modified datetime is different from what was parsed when
+ /// the class was initialized.
+ bool get telemetryEnabled {
+ if (configFileLastModified.isBefore(configFile.lastModifiedSync())) {
+ parseConfig();
+ configFileLastModified = configFile.lastModifiedSync();
+ }
+
+ return _telemetryEnabled;
+ }
+
+ /// Responsibe for the creation of the configuration line
+ /// for the tool being passed in by the user and adding a
+ /// [ToolInfo] object.
+ void addTool({
+ required String tool,
+ required int versionNumber,
+ }) {
+ // Create the new instance of [ToolInfo] to be added
+ // to the [parsedTools] map
+ parsedTools[tool] = ToolInfo(
+ lastRun: clock.now(),
+ versionNumber: versionNumber,
+ );
+
+ // New string to be appended to the bottom of the configuration file
+ // with a newline character for new tools to be added
+ var newTool = '$tool=$dateStamp,$versionNumber\n';
+ if (!configFile.readAsStringSync().endsWith('\n')) {
+ newTool = '\n$newTool';
+ }
+ configFile.writeAsStringSync(newTool, mode: FileMode.append);
+ configFileLastModified = configFile.lastModifiedSync();
+ }
+
+ /// Will increment the version number and update the date
+ /// in the config file for the provided tool name while
+ /// also incrementing the version number in [ToolInfo].
+ void incrementToolVersion({
+ required String tool,
+ required int newVersionNumber,
+ }) {
+ if (!parsedTools.containsKey(tool)) {
+ return;
+ }
+
+ // Read in the config file contents and use a regex pattern to
+ // match the line for the current tool (ie. flutter-tools=2023-01-05,1)
+ final configString = configFile.readAsStringSync();
+ final pattern = '^($tool)=([0-9]{4}-[0-9]{2}-[0-9]{2}),([0-9]+)\$';
+
+ final regex = RegExp(pattern, multiLine: true);
+ final matches = regex.allMatches(configString);
+
+ // If there isn't exactly one match for the given tool, that suggests the
+ // file has been altered and needs to be reset
+ if (matches.length != 1) {
+ resetConfig();
+ return;
+ }
+
+ // Construct the new tool line for the config line and replace it
+ // in the original config string to prep for writing back out
+ final newToolString = '$tool=$dateStamp,$newVersionNumber';
+ final newConfigString = configString.replaceAll(regex, newToolString);
+ configFile.writeAsStringSync(newConfigString);
+
+ final toolInfo = parsedTools[tool];
+ if (toolInfo == null) {
+ return;
+ }
+
+ // Update the [ToolInfo] object for the current tool
+ toolInfo.lastRun = clock.now();
+ toolInfo.versionNumber = newVersionNumber;
+ }
+
+ /// Method responsible for reading in the config file stored on
+ /// user's machine and parsing out the following: all the tools that
+ /// have been logged in the file, the dates they were last run, and
+ /// determining if telemetry is enabled by parsing the file.
+ void parseConfig() {
+ // Begin with the assumption that telemetry is always enabled
+ _telemetryEnabled = true;
+
+ // Read the configuration file as a string and run the two regex patterns
+ // on it to get information around which tools have been parsed and whether
+ // or not telemetry has been disabled by the user
+ final configString = configFile.readAsStringSync();
+
+ // Collect the tools logged in the configuration file
+ toolRegex.allMatches(configString).forEach((RegExpMatch element) {
+ // Extract the information relevant for the [ToolInfo] class
+ final tool = element.group(1) as String;
+ final lastRun = DateTime.parse(element.group(2) as String);
+ final versionNumber = int.parse(element.group(3) as String);
+
+ // Initialize an instance of the [ToolInfo] class to store
+ // in the [parsedTools] map object
+ parsedTools[tool] = ToolInfo(
+ lastRun: lastRun,
+ versionNumber: versionNumber,
+ );
+ });
+
+ // Check for lines signaling that the user has disabled analytics,
+ // if multiple lines are found, the more conservative value will be used
+ telemetryFlagRegex.allMatches(configString).forEach((RegExpMatch element) {
+ // Conditional for recording telemetry as being disabled
+ if (element.group(1) == '0') {
+ _telemetryEnabled = false;
+ }
+ });
+ }
+
+ /// This will reset the configuration file and clear the
+ /// [parsedTools] map and trigger parsing the config again.
+ void resetConfig() {
+ createConfigFile(
+ configFile: configFile,
+ homeDirectory: homeDirectory,
+ );
+ parsedTools.clear();
+ parseConfig();
+ }
+
+ /// Disables the reporting capabilities if [reportingBool] is set to `false`.
+ Future<void> setTelemetry(bool reportingBool) async {
+ final flag = reportingBool ? '1' : '0';
+ final configString = await configFile.readAsString();
+
+ final matches = telemetryFlagRegex.allMatches(configString);
+
+ // If there isn't exactly one match for the reporting flag, that suggests
+ // the file has been altered and needs to be reset
+ if (matches.length != 1) {
+ resetConfig();
+ return;
+ }
+
+ final newTelemetryString = 'reporting=$flag';
+
+ final newConfigString =
+ configString.replaceAll(telemetryFlagRegex, newTelemetryString);
+
+ await configFile.writeAsString(newConfigString);
+ configFileLastModified = configFile.lastModifiedSync();
+
+ _telemetryEnabled = reportingBool;
+ }
+}
+
+class ToolInfo {
+ DateTime lastRun;
+ int versionNumber;
+
+ ToolInfo({
+ required this.lastRun,
+ required this.versionNumber,
+ });
+
+ @override
+ String toString() {
+ return json.encode(<String, Object?>{
+ 'lastRun': FixedDateTimeFormatter('YYYY-MM-DD').encode(lastRun),
+ 'versionNumber': versionNumber,
+ });
+ }
+}
diff --git a/pkgs/unified_analytics/lib/src/constants.dart b/pkgs/unified_analytics/lib/src/constants.dart
new file mode 100644
index 0000000..fde9c21
--- /dev/null
+++ b/pkgs/unified_analytics/lib/src/constants.dart
@@ -0,0 +1,119 @@
+// Copyright (c) 2023, 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.
+
+/// URL endpoint for sending Google Analytics Events.
+const String kAnalyticsUrl = 'https://www.google-analytics.com/mp/collect';
+
+/// Name for the text file that will contain the user's randomly generated
+/// client id.
+const String kClientIdFileName = 'CLIENT_ID';
+
+/// Name for the file where telemetry status and tools data will be stored.
+const String kConfigFileName = 'dart-flutter-telemetry.config';
+
+/// The string that will provide the boilerplate for the configuration file
+/// stored on the user's machine.
+const String kConfigString = '''
+# INTRODUCTION
+#
+# This is the Flutter and Dart telemetry reporting
+# configuration file.
+#
+# Lines starting with a #" are documentation that
+# the tools maintain automatically.
+#
+# All other lines are configuration lines. They have
+# the form "name=value". If multiple lines contain
+# the same configuration name with different values,
+# the parser will default to a conservative value.
+
+# DISABLING TELEMETRY REPORTING
+#
+# To disable telemetry reporting, set "reporting" to
+# the value "0" and to enable, set to "1":
+reporting=1
+
+# NOTIFICATIONS
+#
+# Each tool records when it last informed the user about
+# analytics reporting and the privacy policy.
+#
+# The following tools have so far read this file:
+#
+# dart-tools (Dart CLI developer tool)
+# devtools (DevTools debugging and performance tools)
+# flutter-tools (Flutter CLI developer tool)
+#
+# For each one, the file may contain a configuration line
+# where the name is the code in the list above, e.g. "dart-tool",
+# and the value is a date in the form YYYY-MM-DD, a comma, and
+# a number representing the version of the message that was
+# displayed.''';
+
+/// Link to contextual survey metadata file.
+const String kContextualSurveyUrl =
+ 'https://storage.googleapis.com/flutter-uxr/surveys/contextual-survey-metadata.json';
+
+/// Name of the directory where all of the files necessary for this package
+/// will be located.
+const String kDartToolDirectoryName = '.dart-tool';
+
+/// The default time to wait before closing the http connection to allow for
+/// pending events to be sent.
+const int kDelayDuration = 250;
+
+/// Name of the file where we persist dismissed survey ids.
+const String kDismissedSurveyFileName =
+ 'dart-flutter-telemetry-dismissed-surveys.json';
+
+/// The API secret associated with the GA4 instance's Measurement Protocol.
+const String kGoogleAnalyticsApiSecret = 'Ka1jc8tZSzWc_GXMWHfPHA';
+
+/// The measurement ID related to the GA4 instance.
+///
+/// Serves as an identifier for a web data stream.
+const String kGoogleAnalyticsMeasurementId = 'G-04BXPVBCWJ';
+
+/// How many data records to store in the log file.
+const int kLogFileLength = 2500;
+
+/// The maximum allowed size of the telemetry log file.
+///
+/// 25 MiB.
+const int kMaxLogFileSize = 25 * (1 << 20);
+
+/// Filename for the log file to persist sent events on user's machine.
+const String kLogFileName = 'dart-flutter-telemetry.log';
+
+/// The current version of the package, should be in line with pubspec version.
+const String kPackageVersion = '6.1.4';
+
+/// The minimum length for a session.
+const int kSessionDurationMinutes = 30;
+
+/// Name for the json file where the session details will be stored.
+const String kSessionFileName = 'dart-flutter-telemetry-session.json';
+
+/// The message that should be shown to the user.
+const String kToolsMessage = '''
+The {{ toolDescription }} uses Google Analytics to report usage and diagnostic
+data along with package dependencies, and crash reporting to send basic crash
+reports. This data is used to help improve the Dart platform, Flutter framework,
+and related tools.
+
+Telemetry is not sent on the very first run. To disable reporting of telemetry,
+run this terminal command:
+
+ {{ toolName }} --disable-analytics
+
+If you opt out of telemetry, an opt-out event will be sent, and then no further
+information will be sent. This data is collected in accordance with the Google
+Privacy Policy (https://policies.google.com/privacy).
+''';
+
+/// The version number for the message below.
+///
+/// If the message below is altered, the version should be incremented so that
+/// users can be prompted with the updated messaging.
+const int kToolsMessageVersion = 1;
diff --git a/pkgs/unified_analytics/lib/src/enums.dart b/pkgs/unified_analytics/lib/src/enums.dart
new file mode 100644
index 0000000..d67ab66
--- /dev/null
+++ b/pkgs/unified_analytics/lib/src/enums.dart
@@ -0,0 +1,234 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// The valid dash tool labels stored in the [DashTool] enum.
+List<String> get validDashTools =>
+ DashTool.values.map((e) => e.label).toList()..sort();
+
+/// Values for the event name to be sent to Google Analytics.
+///
+/// The [label] for each enum value is what will be logged, the [description]
+/// is here for documentation purposes.
+///
+/// Set the nullable [toolOwner] parameter if the event belongs to one specific
+/// tool, otherwise, if multiple tools will be sending the event, leave it null.
+enum DashEvent {
+ // Events that can be sent by all tools; these
+ // events should not be tool specific; toolOwner
+ // not necessary for these events
+
+ analyticsCollectionEnabled(
+ label: 'analytics_collection_enabled',
+ description: 'The opt-in status for analytics collection',
+ ),
+ analyticsException(
+ label: 'analytics_exception',
+ description: 'Errors that are encountered within package:unified_analytics',
+ ),
+ exception(
+ label: 'exception',
+ description: 'General errors to log',
+ ),
+ surveyAction(
+ label: 'survey_action',
+ description: 'Actions taken by users when shown survey',
+ ),
+ surveyShown(
+ label: 'survey_shown',
+ description: 'Survey shown to the user',
+ ),
+ timing(
+ label: 'timing',
+ description: 'Events for timing how long a process takes',
+ ),
+
+ // Events for the Dart CLI
+
+ dartCliCommandExecuted(
+ label: 'dart_cli_command_executed',
+ description: 'Information about the execution of a Dart CLI command',
+ toolOwner: DashTool.dartTool,
+ ),
+ pubGet(
+ label: 'pub_get',
+ description: 'Pub package resolution details',
+ toolOwner: DashTool.dartTool,
+ ),
+
+ // Events for Flutter devtools
+
+ devtoolsEvent(
+ label: 'devtools_event',
+ description: 'Information for various devtools events',
+ toolOwner: DashTool.devtools,
+ ),
+
+ // Events for the Flutter CLI
+
+ appleUsageEvent(
+ label: 'apple_usage_event',
+ description:
+ 'Events related to iOS/macOS workflows within the flutter tool',
+ toolOwner: DashTool.flutterTool,
+ ),
+ codeSizeAnalysis(
+ label: 'code_size_analysis',
+ description: 'Indicates when the "--analyize-size" command is run',
+ toolOwner: DashTool.flutterTool,
+ ),
+ commandUsageValues(
+ label: 'command_usage_values',
+ description: 'Contains command level custom dimensions from legacy '
+ 'flutter analytics',
+ toolOwner: DashTool.flutterTool,
+ ),
+ doctorValidatorResult(
+ label: 'doctor_validator_result',
+ description: 'Results from a specific doctor validator',
+ toolOwner: DashTool.flutterTool,
+ ),
+ flutterBuildInfo(
+ label: 'flutter_build_info',
+ description: 'Information for a flutter build invocation',
+ toolOwner: DashTool.flutterTool,
+ ),
+ flutterCommandResult(
+ label: 'flutter_command_result',
+ description: 'Provides information about flutter commands that ran',
+ toolOwner: DashTool.flutterTool,
+ ),
+ hotReloadTime(
+ label: 'hot_reload_time',
+ description: 'Hot reload duration',
+ toolOwner: DashTool.flutterTool,
+ ),
+ hotRunnerInfo(
+ label: 'hot_runner_info',
+ description: 'Information related to the Flutter hot runner',
+ toolOwner: DashTool.flutterTool,
+ ),
+
+ // Events for language_server below
+
+ clientNotification(
+ label: 'client_notification',
+ description: 'Notifications sent from the client',
+ ),
+ clientRequest(
+ label: 'client_request',
+ description: 'Requests sent from the client',
+ ),
+ commandExecuted(
+ label: 'command_executed',
+ description: 'Number of times a command is executed',
+ ),
+ contextStructure(
+ label: 'context_structure',
+ description: 'Structure of the analysis contexts being analyzed',
+ ),
+ lintUsageCount(
+ label: 'lint_usage_count',
+ description: 'Number of times a given lint is enabled',
+ ),
+ memoryInfo(
+ label: 'memory_info',
+ description: 'Memory usage information',
+ ),
+ pluginRequest(
+ label: 'plugin_request',
+ description: 'Request responses from plugins',
+ ),
+ pluginUse(
+ label: 'plugin_use',
+ description: 'Information about how often a plugin was used',
+ ),
+ serverSession(
+ label: 'server_session',
+ description: 'Dart Analyzer Server session data',
+ ),
+ severityAdjustment(
+ label: 'severity_adjustment',
+ description: 'Number of times diagnostic severity is changed',
+ ),
+ ;
+
+ final String label;
+ final String description;
+ final DashTool? toolOwner;
+ const DashEvent({
+ required this.label,
+ required this.description,
+ this.toolOwner,
+ });
+
+ /// This takes in the string label for a given [DashEvent] and returns the
+ /// enum for that string label.
+ static DashEvent? fromLabel(String label) =>
+ DashEvent.values.where((e) => e.label == label).firstOrNull;
+}
+
+/// Officially-supported clients of this package as logical
+/// tools, grouped by user point of view. Derived directly
+/// from the PDD.
+enum DashTool {
+ androidStudioPlugins(
+ label: 'android-studio-plugins',
+ description: 'Android Studio IDE plugins for Dart and Flutter',
+ ),
+ dartTool(
+ label: 'dart-tool',
+ description: 'Dart CLI developer tool',
+ ),
+ devtools(
+ label: 'devtools',
+ description: 'DevTools debugging and performance tools',
+ ),
+ flutterTool(
+ label: 'flutter-tool',
+ description: 'Flutter CLI developer tool',
+ ),
+ intellijPlugins(
+ label: 'intellij-plugins',
+ description: 'IntelliJ IDE plugins for Dart and Flutter',
+ ),
+ vscodePlugins(
+ label: 'vscode-plugins',
+ description: 'VS Code IDE extensions for Dart and Flutter',
+ );
+
+ /// String used as the control flag and the value of the tool key in
+ /// analytics.
+ final String label;
+
+ /// The "notice string", a human-readable description of the logical tool
+ /// grouping.
+ final String description;
+
+ const DashTool({
+ required this.label,
+ required this.description,
+ });
+
+ /// This takes in the string label for a given [DashTool] and returns the
+ /// enum for that string label.
+ static DashTool fromLabel(String label) {
+ final tool = DashTool.values.where((t) => t.label == label).firstOrNull;
+ if (tool != null) return tool;
+
+ throw Exception('The tool $label from the survey metadata file is not '
+ 'a valid DashTool enum value\n'
+ 'Valid labels for dash tools: ${validDashTools.join(', ')}');
+ }
+}
+
+/// Enumerate options for platforms supported.
+enum DevicePlatform {
+ windows('Windows'),
+ macos('macOS'),
+ linux('Linux'),
+ ;
+
+ final String label;
+ const DevicePlatform(this.label);
+}
diff --git a/pkgs/unified_analytics/lib/src/event.dart b/pkgs/unified_analytics/lib/src/event.dart
new file mode 100644
index 0000000..a24fe0c
--- /dev/null
+++ b/pkgs/unified_analytics/lib/src/event.dart
@@ -0,0 +1,889 @@
+// Copyright (c) 2023, 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 'enums.dart';
+
+final class Event {
+ final DashEvent eventName;
+ final Map<String, Object?> eventData;
+
+ /// Event that is emitted whenever a user has opted in
+ /// or out of the analytics collection.
+ ///
+ /// [status] - boolean value where `true` indicates user is opting in.
+ Event.analyticsCollectionEnabled({required bool status})
+ : eventName = DashEvent.analyticsCollectionEnabled,
+ eventData = {'status': status};
+
+ /// Event that is emitted when an error occurs within
+ /// `package:unified_analytics`, tools that are using this package
+ /// should not use this event constructor.
+ ///
+ /// Tools using this package should instead use the more generic
+ /// [Event.exception] constructor.
+ ///
+ /// [workflow] - refers to what process caused the error, such as
+ /// "LogHandler.logFileStats".
+ ///
+ /// [error] - the name of the error, such as "FormatException".
+ ///
+ /// [description] - the description of the error being caught.
+ Event.analyticsException({
+ required String workflow,
+ required String error,
+ String? description,
+ }) : eventName = DashEvent.analyticsException,
+ eventData = {
+ 'workflow': workflow,
+ 'error': error,
+ if (description != null) 'description': description,
+ };
+
+ /// This is for various workflows within the flutter tool related
+ /// to iOS and macOS workflows.
+ ///
+ /// [workflow] - which workflow is running, such as "assemble".
+ ///
+ /// [parameter] - subcategory of the workflow, such as "ios-archive".
+ ///
+ /// [result] - usually to indicate success or failure of the workflow.
+ Event.appleUsageEvent({
+ required String workflow,
+ required String parameter,
+ String? result,
+ }) : eventName = DashEvent.appleUsageEvent,
+ eventData = {
+ 'workflow': workflow,
+ 'parameter': parameter,
+ if (result != null) 'result': result,
+ };
+
+ /// Event that is emitted periodically to report the performance of the
+ /// analysis server's handling of a specific kind of notification from the
+ /// client.
+ ///
+ /// [duration] - json encoded percentile values indicating how long it took
+ /// from the time the server started handling the notification until the
+ /// server had finished handling the notification.
+ ///
+ /// [latency] - json encoded percentile values indicating how long it took
+ /// from the time the notification was sent until the server started
+ /// handling it.
+ ///
+ /// [method] - the name of the notification method that was sent.
+ Event.clientNotification({
+ required String duration,
+ required String latency,
+ required String method,
+ }) : eventName = DashEvent.clientNotification,
+ eventData = {
+ 'duration': duration,
+ 'latency': latency,
+ 'method': method,
+ };
+
+ /// Event that is emitted periodically to report the performance of the
+ /// analysis server's handling of a specific kind of request from the client.
+ ///
+ /// [duration] - json encoded percentile values indicating how long it took
+ /// from the time the server started handling the request until the server
+ /// had send a response.
+ ///
+ /// [latency] - json encoded percentile values indicating how long it took
+ /// from the time the request was sent until the server started handling
+ /// it.
+ ///
+ /// [method] - the name of the request method that was sent.
+ ///
+ /// If the method is `workspace/didChangeWorkspaceFolders`, then the following
+ /// parameters should be included:
+ ///
+ /// [added] - json encoded percentile values indicating the number of folders
+ /// that were added.
+ ///
+ /// [removed] - json encoded percentile values indicating the number of
+ /// folders that were removed.
+ ///
+ /// If the method is `initialized`, then the following parameters should be
+ /// included:
+ ///
+ /// [openWorkspacePaths] - json encoded percentile values indicating the
+ /// number of workspace paths that were opened.
+ ///
+ /// If the method is `analysis.setAnalysisRoots`, then the following
+ /// parameters should be included:
+ ///
+ /// [included] - json encoded percentile values indicating the number of
+ /// analysis roots in the included list.
+ ///
+ /// [excluded] - json encoded percentile values indicating the number of
+ /// analysis roots in the excluded list.
+ ///
+ /// If the method is `analysis.setPriorityFiles`, then the following
+ /// parameters should be included:
+ ///
+ /// [files] - json encoded percentile values indicating the number of priority
+ /// files.
+ ///
+ Event.clientRequest({
+ required String duration,
+ required String latency,
+ required String method,
+ String? added,
+ String? excluded,
+ String? files,
+ String? included,
+ String? openWorkspacePaths,
+ String? removed,
+ }) : eventName = DashEvent.clientRequest,
+ eventData = {
+ if (added != null) 'added': added,
+ 'duration': duration,
+ if (excluded != null) 'excluded': excluded,
+ if (files != null) 'files': files,
+ if (included != null) 'included': included,
+ 'latency': latency,
+ 'method': method,
+ if (openWorkspacePaths != null)
+ 'openWorkspacePaths': openWorkspacePaths,
+ if (removed != null) 'removed': removed,
+ };
+
+ /// An event that reports when the code size measurement is run
+ /// via `--analyze-size`.
+ ///
+ /// [platform] - string identifier for which platform was run "ios", "apk",
+ /// "aab", etc.
+ Event.codeSizeAnalysis({required String platform})
+ : eventName = DashEvent.codeSizeAnalysis,
+ eventData = {
+ 'platform': platform,
+ };
+
+ /// Event that is emitted periodically to report the number of times a given
+ /// command has been executed.
+ ///
+ /// [count] - the number of times the command was executed.
+ ///
+ /// [name] - the name of the command that was executed.
+ Event.commandExecuted({
+ required int count,
+ required String name,
+ }) : eventName = DashEvent.commandExecuted,
+ eventData = {
+ 'count': count,
+ 'name': name,
+ };
+
+ /// Event to capture usage values for different flutter commands.
+ ///
+ /// There are several implementations of the `FlutterCommand` class within the
+ /// flutter-tool that pass information based on the [workflow] being ran. An
+ /// example of a [workflow] can be "create". The optional parameters for this
+ /// constructor are a superset of all the implementations of `FlutterCommand`.
+ /// There should never be a time where all of the parameters are passed to
+ /// this constructor.
+ Event.commandUsageValues({
+ required String workflow,
+ required bool commandHasTerminal,
+
+ // Assemble && build bundle implementation parameters
+ String? buildBundleTargetPlatform,
+ bool? buildBundleIsModule,
+
+ // Build aar implementation parameters
+ String? buildAarProjectType,
+ String? buildAarTargetPlatform,
+
+ // Build apk implementation parameters
+ String? buildApkTargetPlatform,
+ String? buildApkBuildMode,
+ bool? buildApkSplitPerAbi,
+
+ // Build app bundle implementation parameters
+ String? buildAppBundleTargetPlatform,
+ String? buildAppBundleBuildMode,
+
+ // Create implementation parameters
+ String? createProjectType,
+ String? createAndroidLanguage,
+ String? createIosLanguage,
+
+ // Packages implementation parameters
+ int? packagesNumberPlugins,
+ bool? packagesProjectModule,
+ String? packagesAndroidEmbeddingVersion,
+
+ // Run implementation parameters
+ bool? runIsEmulator,
+ String? runTargetName,
+ String? runTargetOsVersion,
+ String? runModeName,
+ bool? runProjectModule,
+ String? runProjectHostLanguage,
+ String? runAndroidEmbeddingVersion,
+ bool? runEnableImpeller,
+ String? runIOSInterfaceType,
+ bool? runIsTest,
+ }) : eventName = DashEvent.commandUsageValues,
+ eventData = {
+ 'workflow': workflow,
+ 'commandHasTerminal': commandHasTerminal,
+ if (buildBundleTargetPlatform != null)
+ 'buildBundleTargetPlatform': buildBundleTargetPlatform,
+ if (buildBundleIsModule != null)
+ 'buildBundleIsModule': buildBundleIsModule,
+ if (buildAarProjectType != null)
+ 'buildAarProjectType': buildAarProjectType,
+ if (buildAarTargetPlatform != null)
+ 'buildAarTargetPlatform': buildAarTargetPlatform,
+ if (buildApkTargetPlatform != null)
+ 'buildApkTargetPlatform': buildApkTargetPlatform,
+ if (buildApkBuildMode != null) 'buildApkBuildMode': buildApkBuildMode,
+ if (buildApkSplitPerAbi != null)
+ 'buildApkSplitPerAbi': buildApkSplitPerAbi,
+ if (buildAppBundleTargetPlatform != null)
+ 'buildAppBundleTargetPlatform': buildAppBundleTargetPlatform,
+ if (buildAppBundleBuildMode != null)
+ 'buildAppBundleBuildMode': buildAppBundleBuildMode,
+ if (createProjectType != null) 'createProjectType': createProjectType,
+ if (createAndroidLanguage != null)
+ 'createAndroidLanguage': createAndroidLanguage,
+ if (createIosLanguage != null) 'createIosLanguage': createIosLanguage,
+ if (packagesNumberPlugins != null)
+ 'packagesNumberPlugins': packagesNumberPlugins,
+ if (packagesProjectModule != null)
+ 'packagesProjectModule': packagesProjectModule,
+ if (packagesAndroidEmbeddingVersion != null)
+ 'packagesAndroidEmbeddingVersion': packagesAndroidEmbeddingVersion,
+ if (runIsEmulator != null) 'runIsEmulator': runIsEmulator,
+ if (runTargetName != null) 'runTargetName': runTargetName,
+ if (runTargetOsVersion != null)
+ 'runTargetOsVersion': runTargetOsVersion,
+ if (runModeName != null) 'runModeName': runModeName,
+ if (runProjectModule != null) 'runProjectModule': runProjectModule,
+ if (runProjectHostLanguage != null)
+ 'runProjectHostLanguage': runProjectHostLanguage,
+ if (runAndroidEmbeddingVersion != null)
+ 'runAndroidEmbeddingVersion': runAndroidEmbeddingVersion,
+ if (runEnableImpeller != null) 'runEnableImpeller': runEnableImpeller,
+ if (runIOSInterfaceType != null)
+ 'runIOSInterfaceType': runIOSInterfaceType,
+ if (runIsTest != null) 'runIsTest': runIsTest,
+ };
+
+ /// Event that is emitted on shutdown to report the structure of the analysis
+ /// contexts created immediately after startup.
+ ///
+ /// [contextsFromBothFiles] - the number of contexts that were created because
+ /// of both a package config and an analysis options file.
+ ///
+ /// [contextsFromOptionsFiles] - the number of contexts that were created
+ /// because of an analysis options file.
+ ///
+ /// [contextsFromPackagesFiles] - the number of contexts that were created
+ /// because of a package config file.
+ ///
+ /// [contextsWithoutFiles] - the number of contexts that were created because
+ /// of the lack of either a package config or an analysis options file.
+ ///
+ /// [immediateFileCount] - the number of files in one of the analysis
+ /// contexts.
+ ///
+ /// [immediateFileLineCount] - the number of lines in the immediate files.
+ ///
+ /// [numberOfContexts] - the number of analysis context created.
+ ///
+ /// [transitiveFileCount] - the number of files reachable from the files in
+ /// each analysis context, where files can be counted multiple times if
+ /// they are reachable from multiple contexts.
+ ///
+ /// [transitiveFileLineCount] - the number of lines in the transitive files,
+ /// where files can be counted multiple times if they are reachable from
+ /// multiple contexts.
+ ///
+ /// [transitiveFileUniqueCount] - the number of unique files reachable from
+ /// the files in each analysis context.
+ ///
+ /// [transitiveFileUniqueLineCount] - the number of lines in the unique
+ /// transitive files.
+ Event.contextStructure({
+ required int contextsFromBothFiles,
+ required int contextsFromOptionsFiles,
+ required int contextsFromPackagesFiles,
+ required int contextsWithoutFiles,
+ required int immediateFileCount,
+ required int immediateFileLineCount,
+ required int numberOfContexts,
+ required int transitiveFileCount,
+ required int transitiveFileLineCount,
+ required int transitiveFileUniqueCount,
+ required int transitiveFileUniqueLineCount,
+ }) : eventName = DashEvent.contextStructure,
+ eventData = {
+ 'contextsFromBothFiles': contextsFromBothFiles,
+ 'contextsFromOptionsFiles': contextsFromOptionsFiles,
+ 'contextsFromPackagesFiles': contextsFromPackagesFiles,
+ 'contextsWithoutFiles': contextsWithoutFiles,
+ 'immediateFileCount': immediateFileCount,
+ 'immediateFileLineCount': immediateFileLineCount,
+ 'numberOfContexts': numberOfContexts,
+ 'transitiveFileCount': transitiveFileCount,
+ 'transitiveFileLineCount': transitiveFileLineCount,
+ 'transitiveFileUniqueCount': transitiveFileUniqueCount,
+ 'transitiveFileUniqueLineCount': transitiveFileUniqueLineCount,
+ };
+
+ /// Event that is emitted when a Dart CLI command has been executed.
+ ///
+ /// [name] - the name of the command that was executed
+ ///
+ /// [enabledExperiments] - a set of Dart language experiments enabled when
+ /// running the command.
+ ///
+ /// [exitCode] - the process exit code set as a result of running the command.
+ Event.dartCliCommandExecuted({
+ required String name,
+ required String enabledExperiments,
+ int? exitCode,
+ }) : eventName = DashEvent.dartCliCommandExecuted,
+ eventData = {
+ 'name': name,
+ 'enabledExperiments': enabledExperiments,
+ if (exitCode != null) 'exitCode': exitCode,
+ };
+
+ /// Event that is sent from devtools for various different actions as
+ /// indicated by the [eventCategory].
+ Event.devtoolsEvent({
+ required String eventCategory,
+ required String label,
+ required int value,
+
+ // Defaulted values
+ bool userInitiatedInteraction = true,
+
+ // Optional parameters
+ String? g3Username,
+ String? userApp,
+ String? userBuild,
+ String? userPlatform,
+ String? devtoolsPlatform,
+ String? devtoolsChrome,
+ String? devtoolsVersion,
+ String? ideLaunched,
+ String? isExternalBuild,
+ String? isEmbedded,
+ String? ideLaunchedFeature,
+ String? isWasm,
+
+ // PerformanceScreenMetrics
+ int? uiDurationMicros,
+ int? rasterDurationMicros,
+ int? shaderCompilationDurationMicros,
+ int? traceEventCount,
+
+ // ProfilerScreenMetrics
+ int? cpuSampleCount,
+ int? cpuStackDepth,
+
+ // MemoryScreenMetrics
+ int? heapDiffObjectsBefore,
+ int? heapDiffObjectsAfter,
+ int? heapObjectsTotal,
+
+ // InspectorScreenMetrics
+ int? rootSetCount,
+ int? rowCount,
+ int? inspectorTreeControllerId,
+
+ // DeepLinkScreenMetrics
+ String? androidAppId,
+ String? iosBundleId,
+ }) : eventName = DashEvent.devtoolsEvent,
+ eventData = {
+ 'eventCategory': eventCategory,
+ 'label': label,
+ 'value': value,
+
+ 'userInitiatedInteraction': userInitiatedInteraction,
+
+ // Optional parameters
+ if (g3Username != null) 'g3Username': g3Username,
+ if (userApp != null) 'userApp': userApp,
+ if (userBuild != null) 'userBuild': userBuild,
+ if (userPlatform != null) 'userPlatform': userPlatform,
+ if (devtoolsPlatform != null) 'devtoolsPlatform': devtoolsPlatform,
+ if (devtoolsChrome != null) 'devtoolsChrome': devtoolsChrome,
+ if (devtoolsVersion != null) 'devtoolsVersion': devtoolsVersion,
+ if (ideLaunched != null) 'ideLaunched': ideLaunched,
+ if (isExternalBuild != null) 'isExternalBuild': isExternalBuild,
+ if (isEmbedded != null) 'isEmbedded': isEmbedded,
+ if (ideLaunchedFeature != null)
+ 'ideLaunchedFeature': ideLaunchedFeature,
+ if (isWasm != null) 'isWasm': isWasm,
+
+ // PerformanceScreenMetrics
+ if (uiDurationMicros != null) 'uiDurationMicros': uiDurationMicros,
+ if (rasterDurationMicros != null)
+ 'rasterDurationMicros': rasterDurationMicros,
+ if (shaderCompilationDurationMicros != null)
+ 'shaderCompilationDurationMicros': shaderCompilationDurationMicros,
+ if (traceEventCount != null) 'traceEventCount': traceEventCount,
+
+ // ProfilerScreenMetrics
+ if (cpuSampleCount != null) 'cpuSampleCount': cpuSampleCount,
+ if (cpuStackDepth != null) 'cpuStackDepth': cpuStackDepth,
+
+ // MemoryScreenMetrics
+ if (heapDiffObjectsBefore != null)
+ 'heapDiffObjectsBefore': heapDiffObjectsBefore,
+ if (heapDiffObjectsAfter != null)
+ 'heapDiffObjectsAfter': heapDiffObjectsAfter,
+ if (heapObjectsTotal != null) 'heapObjectsTotal': heapObjectsTotal,
+
+ // InspectorScreenMetrics
+ if (rootSetCount != null) 'rootSetCount': rootSetCount,
+ if (rowCount != null) 'rowCount': rowCount,
+ if (inspectorTreeControllerId != null)
+ 'inspectorTreeControllerId': inspectorTreeControllerId,
+ // DeepLinkScreenMetrics
+ if (androidAppId != null) 'androidAppId': androidAppId,
+ if (iosBundleId != null) 'iosBundleId': iosBundleId,
+ };
+
+ /// Event that contains the results for a specific doctor validator.
+ ///
+ /// [validatorName] - the name for the doctor validator.
+ ///
+ /// [result] - the final result for a specific doctor validator.
+ ///
+ /// [partOfGroupedValidator] - `true` indicates that this validator belongs
+ /// to a grouped validator.
+ ///
+ /// [doctorInvocationId] - epoch formatted timestamp that can be used in
+ /// combination with the client ID in GA4 to group the validators that
+ /// ran in one doctor invocation.
+ ///
+ /// [statusInfo] - optional description of the result from the
+ /// doctor validator.
+ Event.doctorValidatorResult({
+ required String validatorName,
+ required String result,
+ required bool partOfGroupedValidator,
+ required int doctorInvocationId,
+ String? statusInfo,
+ }) : eventName = DashEvent.doctorValidatorResult,
+ eventData = {
+ 'validatorName': validatorName,
+ 'result': result,
+ 'partOfGroupedValidator': partOfGroupedValidator,
+ 'doctorInvocationId': doctorInvocationId,
+ if (statusInfo != null) 'statusInfo': statusInfo,
+ };
+
+ /// Generic event for all dash tools to use when encountering an
+ /// exception that we want to log.
+ ///
+ /// [exception] - string representation of the exception that occured.
+ /// [data] - optional structured data to include with the exception event.
+ Event.exception({
+ required String exception,
+ Map<String, Object?> data = const <String, Object?>{},
+ }) : eventName = DashEvent.exception,
+ eventData = {
+ 'exception': exception,
+ ...data,
+ };
+
+ /// Event that is emitted from the flutter tool when a build invocation
+ /// has been run by the user.
+ ///
+ /// [label] - the identifier for that build event.
+ ///
+ /// [buildType] - the identifier for which platform the build event was for,
+ /// examples include "ios", "gradle", and "web".
+ ///
+ /// [command] - the command that was ran to kick off the build event.
+ ///
+ /// [settings] - the settings used for the build event related to
+ /// configuration and other relevant build information.
+ ///
+ /// [error] - short identifier used to explain the cause of the build error,
+ /// stacktraces should not be passed to this parameter.
+ Event.flutterBuildInfo({
+ required String label,
+ required String buildType,
+ String? command,
+ String? settings,
+ String? error,
+ }) : eventName = DashEvent.flutterBuildInfo,
+ eventData = {
+ 'label': label,
+ 'buildType': buildType,
+ if (command != null) 'command': command,
+ if (settings != null) 'settings': settings,
+ if (error != null) 'error': error,
+ };
+
+ /// Provides information about which flutter command was run
+ /// and whether it was successful.
+ ///
+ /// [commandPath] - information about the flutter command, such as "build/apk".
+ ///
+ /// [result] - if the command failed or succeeded.
+ ///
+ /// [commandHasTerminal] - boolean indicating if the flutter command ran with
+ /// a terminal.
+ ///
+ /// [maxRss] - maximum resident size for a given flutter command.
+ Event.flutterCommandResult({
+ required String commandPath,
+ required String result,
+ required bool commandHasTerminal,
+ int? maxRss,
+ }) : eventName = DashEvent.flutterCommandResult,
+ eventData = {
+ 'commandPath': commandPath,
+ 'result': result,
+ 'commandHasTerminal': commandHasTerminal,
+ if (maxRss != null) 'maxRss': maxRss,
+ };
+
+ // TODO: eliasyishak, remove this or replace once we have a generic
+ // timing event that can be used by potentially more than one DashTool
+ Event.hotReloadTime({required int timeMs})
+ : eventName = DashEvent.hotReloadTime,
+ eventData = {'timeMs': timeMs};
+
+ /// Events to be sent for the Flutter Hot Runner.
+ Event.hotRunnerInfo({
+ required String label,
+ required String targetPlatform,
+ required String sdkName,
+ required bool emulator,
+ required bool fullRestart,
+ String? reason,
+ int? finalLibraryCount,
+ int? syncedLibraryCount,
+ int? syncedClassesCount,
+ int? syncedProceduresCount,
+ int? syncedBytes,
+ int? invalidatedSourcesCount,
+ int? transferTimeInMs,
+ int? overallTimeInMs,
+ int? compileTimeInMs,
+ int? findInvalidatedTimeInMs,
+ int? scannedSourcesCount,
+ int? reassembleTimeInMs,
+ int? reloadVMTimeInMs,
+ }) : eventName = DashEvent.hotRunnerInfo,
+ eventData = {
+ 'label': label,
+ 'targetPlatform': targetPlatform,
+ 'sdkName': sdkName,
+ 'emulator': emulator,
+ 'fullRestart': fullRestart,
+ if (reason != null) 'reason': reason,
+ if (finalLibraryCount != null) 'finalLibraryCount': finalLibraryCount,
+ if (syncedLibraryCount != null)
+ 'syncedLibraryCount': syncedLibraryCount,
+ if (syncedClassesCount != null)
+ 'syncedClassesCount': syncedClassesCount,
+ if (syncedProceduresCount != null)
+ 'syncedProceduresCount': syncedProceduresCount,
+ if (syncedBytes != null) 'syncedBytes': syncedBytes,
+ if (invalidatedSourcesCount != null)
+ 'invalidatedSourcesCount': invalidatedSourcesCount,
+ if (transferTimeInMs != null) 'transferTimeInMs': transferTimeInMs,
+ if (overallTimeInMs != null) 'overallTimeInMs': overallTimeInMs,
+ if (compileTimeInMs != null) 'compileTimeInMs': compileTimeInMs,
+ if (findInvalidatedTimeInMs != null)
+ 'findInvalidatedTimeInMs': findInvalidatedTimeInMs,
+ if (scannedSourcesCount != null)
+ 'scannedSourcesCount': scannedSourcesCount,
+ if (reassembleTimeInMs != null)
+ 'reassembleTimeInMs': reassembleTimeInMs,
+ if (reloadVMTimeInMs != null) 'reloadVMTimeInMs': reloadVMTimeInMs,
+ };
+
+ // TODO: eliasyishak, add better dartdocs to explain each param
+ /// Event that is emitted periodically to report the number of times each lint
+ /// has been enabled.
+ ///
+ /// [count] - the number of contexts in which the lint was enabled.
+ ///
+ /// [name] - the name of the lint.
+ Event.lintUsageCount({
+ required int count,
+ required String name,
+ }) : eventName = DashEvent.lintUsageCount,
+ eventData = {
+ 'count': count,
+ 'name': name,
+ };
+
+ /// Event that is emitted periodically to report the amount of memory being
+ /// used.
+ ///
+ /// [rss] - the resident set size in megabytes.
+ ///
+ /// If this is not the first time memory has been reported for this session,
+ /// then the following parameters should be included:
+ ///
+ /// [periodSec] - the number of seconds since the last memory usage data was
+ /// gathered.
+ ///
+ /// [mbPerSec] - the number of megabytes of memory that were added or
+ /// subtracted per second since the last report.
+ Event.memoryInfo({
+ required int rss,
+ int? periodSec,
+ double? mbPerSec,
+ }) : eventName = DashEvent.memoryInfo,
+ eventData = {
+ 'rss': rss,
+ if (periodSec != null) 'periodSec': periodSec,
+ if (mbPerSec != null) 'mbPerSec': mbPerSec
+ };
+
+ /// Event that is emitted periodically to report the performance of plugins
+ /// when handling requests.
+ ///
+ /// [duration] - json encoded percentile values indicating how long it took
+ /// from the time the request was sent to the plugin until the response
+ /// was processed by the server.
+ ///
+ /// [method] - the name of the request sent to the plugin.
+ ///
+ /// [pluginId] - the id of the plugin whose performance is being reported.
+ Event.pluginRequest({
+ required String duration,
+ required String method,
+ required String pluginId,
+ }) : eventName = DashEvent.pluginRequest,
+ eventData = {
+ 'duration': duration,
+ 'method': method,
+ 'pluginId': pluginId,
+ };
+
+ /// Event that is emitted periodically to report the frequency with which a
+ /// given plugin has been used.
+ ///
+ /// [count] - the number of times plugins usage was changed, which will always
+ /// be at least one.
+ ///
+ /// [enabled] - json encoded percentile values indicating the number of
+ /// contexts for which the plugin was enabled.
+ ///
+ /// [pluginId] - the id of the plugin associated with the data.
+ Event.pluginUse({
+ required int count,
+ required String enabled,
+ required String pluginId,
+ }) : eventName = DashEvent.pluginUse,
+ eventData = {
+ 'count': count,
+ 'enabled': enabled,
+ 'pluginId': pluginId,
+ };
+
+ /// Event that is emitted when `pub get` is run.
+ ///
+ /// [packageName] - the name of the package that was resolved
+ ///
+ /// [version] - the resolved, canonicalized package version
+ ///
+ /// [dependencyType] - the kind of dependency that resulted in this package
+ /// being resolved (e.g., direct, transitive, or dev dependencies).
+ Event.pubGet({
+ required String packageName,
+ required String version,
+ required String dependencyType,
+ }) : eventName = DashEvent.pubGet,
+ eventData = {
+ 'packageName': packageName,
+ 'version': version,
+ 'dependencyType': dependencyType,
+ };
+
+ /// Event that is emitted on shutdown to report information about the whole
+ /// session for which the analysis server was running.
+ ///
+ /// [clientId] - the id of the client that started the server.
+ ///
+ /// [clientVersion] - the version of the client that started the server.
+ ///
+ /// [duration] - the number of milliseconds for which the server was running.
+ ///
+ /// [flags] - the flags passed to the analysis server on startup, without any
+ /// argument values for flags that take values, or an empty string if
+ /// there were no arguments.
+ ///
+ /// [parameters] - the names of the parameters passed to the `initialize`
+ /// request, or an empty string if the `initialize` request was not sent
+ /// or if there were no parameters given.
+ Event.serverSession({
+ required String clientId,
+ required String clientVersion,
+ required int duration,
+ required String flags,
+ required String parameters,
+ }) : eventName = DashEvent.serverSession,
+ eventData = {
+ 'clientId': clientId,
+ 'clientVersion': clientVersion,
+ 'duration': duration,
+ 'flags': flags,
+ 'parameters': parameters,
+ };
+
+ /// Event that is emitted periodically to report the number of times the
+ /// severity of a diagnostic was changed in the analysis options file.
+ ///
+ /// [diagnostic] - the name of the diagnostic whose severity was changed.
+ ///
+ /// [adjustments] - json encoded map of severities to the number of times the
+ /// diagnostic's severity was changed to the key.
+ Event.severityAdjustment({
+ required String diagnostic,
+ required String adjustments,
+ }) : eventName = DashEvent.severityAdjustment,
+ eventData = {
+ 'diagnostic': diagnostic,
+ 'adjustments': adjustments,
+ };
+
+ /// Event that is emitted by `package:unified_analytics` when
+ /// the user takes action when prompted with a survey.
+ ///
+ /// [surveyId] - the unique id for a given survey.
+ ///
+ /// [status] - the string identifier for a given `SurveyButton` under the
+ /// `action` field.
+ Event.surveyAction({
+ required String surveyId,
+ required String status,
+ }) : eventName = DashEvent.surveyAction,
+ eventData = {
+ 'surveyId': surveyId,
+ 'status': status,
+ };
+
+ /// Event that is emitted by `package:unified_analytics` when the
+ /// user has been shown a survey.
+ ///
+ /// [surveyId] - the unique id for a given survey.
+ Event.surveyShown({
+ required String surveyId,
+ }) : eventName = DashEvent.surveyShown,
+ eventData = {
+ 'surveyId': surveyId,
+ };
+
+ /// Event that records how long a given process takes to complete.
+ ///
+ /// [workflow] - the overall process or command being run, for example
+ /// "build" is a possible value for the flutter tool.
+ ///
+ /// [variableName] - the specific variable being measured, for example
+ /// "gradle" would indicate how long it took for a gradle build under the
+ /// "build" [workflow].
+ ///
+ /// [elapsedMilliseconds] - how long the process took in milliseconds.
+ ///
+ /// [label] - an optional field that can be used for further filtering, for
+ /// example, "success" can indicate how long a successful build in gradle
+ /// takes to complete.
+ Event.timing({
+ required String workflow,
+ required String variableName,
+ required int elapsedMilliseconds,
+ String? label,
+ }) : eventName = DashEvent.timing,
+ eventData = {
+ 'workflow': workflow,
+ 'variableName': variableName,
+ 'elapsedMilliseconds': elapsedMilliseconds,
+ if (label != null) 'label': label,
+ };
+
+ /// Private constructor to be used when deserializing JSON into an instance
+ /// of [Event].
+ Event._({required this.eventName, required this.eventData});
+
+ @override
+ int get hashCode => Object.hash(eventName, jsonEncode(eventData));
+
+ @override
+ bool operator ==(Object other) =>
+ other is Event &&
+ other.runtimeType == runtimeType &&
+ other.eventName == eventName &&
+ _compareEventData(other.eventData, eventData);
+
+ /// Converts an instance of [Event] to JSON.
+ String toJson() => jsonEncode({
+ 'eventName': eventName.label,
+ 'eventData': eventData,
+ });
+
+ @override
+ String toString() => toJson();
+
+ /// Utility function to take in two maps [a] and [b] and compares them
+ /// to ensure that they have the same keys and values
+ bool _compareEventData(Map<String, Object?> a, Map<String, Object?> b) {
+ final keySetA = a.keys.toSet();
+ final keySetB = b.keys.toSet();
+ final intersection = keySetA.intersection(keySetB);
+
+ // Ensure that the keys are the same for each object
+ if (intersection.length != keySetA.length ||
+ intersection.length != keySetB.length) {
+ return false;
+ }
+
+ // Ensure that each of the key's values are the same
+ for (final key in a.keys) {
+ if (a[key] != b[key]) return false;
+ }
+
+ return true;
+ }
+
+ /// Returns a valid instance of [Event] if [json] follows the correct schema.
+ ///
+ /// Common use case for this static method involves clients of this package
+ /// that have a client-server setup where the server sends events that the
+ /// client creates.
+ static Event? fromJson(String json) {
+ try {
+ final jsonMap = jsonDecode(json) as Map<String, Object?>;
+
+ // Ensure that eventName is a string and a valid label and
+ // eventData is a nested object
+ if (jsonMap
+ case {
+ 'eventName': final String eventName,
+ 'eventData': final Map<String, Object?> eventData,
+ }) {
+ final dashEvent = DashEvent.fromLabel(eventName);
+ if (dashEvent == null) return null;
+
+ return Event._(
+ eventName: dashEvent,
+ eventData: eventData,
+ );
+ }
+
+ return null;
+ } on FormatException {
+ return null;
+ }
+ }
+}
diff --git a/pkgs/unified_analytics/lib/src/ga_client.dart b/pkgs/unified_analytics/lib/src/ga_client.dart
new file mode 100644
index 0000000..2c3e83e
--- /dev/null
+++ b/pkgs/unified_analytics/lib/src/ga_client.dart
@@ -0,0 +1,86 @@
+// Copyright (c) 2023, 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 'package:http/http.dart' as http;
+
+import 'constants.dart';
+
+class FakeGAClient implements GAClient {
+ const FakeGAClient();
+
+ @override
+ String get apiSecret => throw UnimplementedError();
+
+ @override
+ String get measurementId => throw UnimplementedError();
+
+ @override
+ String get postUrl => throw UnimplementedError();
+
+ @override
+ http.Client get _client => throw UnimplementedError();
+
+ @override
+ void close() {}
+
+ @override
+ Future<http.Response> sendData(Map<String, Object?> body) =>
+ Future<http.Response>.value(http.Response('', 200));
+}
+
+class GAClient {
+ final String measurementId;
+ final String apiSecret;
+ final String postUrl;
+ final http.Client _client;
+
+ GAClient({
+ required this.measurementId,
+ required this.apiSecret,
+ }) : postUrl = '$kAnalyticsUrl?'
+ 'measurement_id=$measurementId&api_secret=$apiSecret',
+ _client = http.Client();
+
+ /// Closes the http client's connection to prevent lingering requests.
+ void close() => _client.close();
+
+ /// Receive the payload in Map form and parse
+ /// into JSON to send to GA.
+ ///
+ /// The [http.Response] returned from this method can be
+ /// checked to ensure that events have been sent. A response
+ /// status code of `2xx` indicates a successful send event.
+ /// A response status code of `500` indicates an error occured on the send
+ /// can the error message can be found in the [http.Response.body].
+ Future<http.Response> sendData(Map<String, Object?> body) async {
+ final uri = Uri.parse(postUrl);
+
+ // Using a try catch all since post method can result in several
+ // errors; clients using this method can check the awaited status
+ // code to get a specific error message if the status code returned
+ // is a 500 error status code
+ try {
+ return await _client.post(
+ uri,
+ headers: <String, String>{
+ 'Content-Type': 'application/json; charset=UTF-8',
+ },
+ body: jsonEncode(body),
+ );
+ // ignore: avoid_catches_without_on_clauses
+ } catch (error) {
+ return Future<http.Response>.value(
+ http.Response(
+ error.toString(),
+ 500,
+ headers: <String, String>{
+ 'content-type': 'text/plain; charset=utf-8',
+ },
+ ),
+ );
+ }
+ }
+}
diff --git a/pkgs/unified_analytics/lib/src/initializer.dart b/pkgs/unified_analytics/lib/src/initializer.dart
new file mode 100644
index 0000000..131968b
--- /dev/null
+++ b/pkgs/unified_analytics/lib/src/initializer.dart
@@ -0,0 +1,118 @@
+// Copyright (c) 2023, 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:clock/clock.dart';
+import 'package:file/file.dart';
+
+import 'constants.dart';
+import 'utils.dart';
+
+/// Creates the text file that will contain the client ID
+/// which will be used across all related tools for analytics
+/// reporting in GA.
+void createClientIdFile({required File clientIdFile}) {
+ clientIdFile.createSync(recursive: true);
+ clientIdFile.writeAsStringSync(Uuid().generateV4());
+}
+
+/// Creates the configuration file with the default message
+/// in the user's home directory.
+void createConfigFile({
+ required File configFile,
+ required Directory homeDirectory,
+}) {
+ configFile.createSync(recursive: true);
+
+ // If the user was previously opted out, then we will
+ // replace the line that assumes automatic opt in with
+ // an opt out from the start
+ if (legacyOptOut(homeDirectory: homeDirectory)) {
+ configFile.writeAsStringSync(
+ kConfigString.replaceAll('reporting=1', 'reporting=0'));
+ } else {
+ configFile.writeAsStringSync(kConfigString);
+ }
+}
+
+/// Creates that file that will persist dismissed survey ids.
+void createDismissedSurveyFile({required File dismissedSurveyFile}) {
+ dismissedSurveyFile.createSync(recursive: true);
+ dismissedSurveyFile.writeAsStringSync('{}');
+}
+
+/// Creates that log file that will store the record formatted
+/// events locally on the user's machine.
+void createLogFile({required File logFile}) {
+ logFile.createSync(recursive: true);
+}
+
+/// Creates the session file which will contain
+/// the current session id which is the current timestamp.
+///
+/// It also returns the timestamp used for the session if it needs
+/// to be accessed.
+DateTime createSessionFile({required File sessionFile}) {
+ final now = clock.now();
+ sessionFile.createSync(recursive: true);
+ writeSessionContents(sessionFile: sessionFile);
+
+ return now;
+}
+
+/// Performs all of the initialization checks for the required files.
+///
+/// Returns `true` if the config file was created indicating it is the first
+/// time this package was run on a user's machine.
+///
+/// Checks for the following:
+/// - Config file
+/// - Client ID file
+/// - Session JSON file
+/// - Log file
+/// - Dismissed survey JSON file
+bool runInitialization({
+ required Directory homeDirectory,
+}) {
+ var firstRun = false;
+ final dartToolDirectory =
+ homeDirectory.childDirectory(kDartToolDirectoryName);
+
+ // When the config file doesn't exist, initialize it with the default tools
+ // and the current date.
+ final configFile = dartToolDirectory.childFile(kConfigFileName);
+ if (!configFile.existsSync()) {
+ firstRun = true;
+ createConfigFile(
+ configFile: configFile,
+ homeDirectory: homeDirectory,
+ );
+ }
+
+ // Begin initialization checks for the client id.
+ final clientFile = dartToolDirectory.childFile(kClientIdFileName);
+ if (!clientFile.existsSync()) {
+ createClientIdFile(clientIdFile: clientFile);
+ }
+
+ // Begin initialization checks for the session file.
+ final sessionFile = dartToolDirectory.childFile(kSessionFileName);
+ if (!sessionFile.existsSync()) {
+ createSessionFile(sessionFile: sessionFile);
+ }
+
+ // Begin initialization checks for the log file to persist events locally.
+ final logFile = dartToolDirectory.childFile(kLogFileName);
+ if (!logFile.existsSync()) {
+ createLogFile(logFile: logFile);
+ }
+
+ // Begin initialization checks for the dismissed survey file.
+ final dismissedSurveyFile =
+ dartToolDirectory.childFile(kDismissedSurveyFileName);
+ if (!dismissedSurveyFile.existsSync()) {
+ createDismissedSurveyFile(dismissedSurveyFile: dismissedSurveyFile);
+ }
+
+ return firstRun;
+}
diff --git a/pkgs/unified_analytics/lib/src/log_handler.dart b/pkgs/unified_analytics/lib/src/log_handler.dart
new file mode 100644
index 0000000..a6ef2f5
--- /dev/null
+++ b/pkgs/unified_analytics/lib/src/log_handler.dart
@@ -0,0 +1,464 @@
+// Copyright (c) 2023, 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 'package:clock/clock.dart';
+import 'package:file/file.dart';
+
+import 'constants.dart';
+import 'event.dart';
+import 'initializer.dart';
+
+/// Data class that will be returned when analyzing the
+/// persisted log file on the client's machine.
+class LogFileStats {
+ /// The oldest timestamp in the log file.
+ final DateTime startDateTime;
+
+ /// Number of minutes from [startDateTime] to now using [clock].
+ final int minsFromStartDateTime;
+
+ /// The latest timestamp in the log file.
+ final DateTime endDateTime;
+
+ /// Number of minutes from [endDateTime] to now using [clock].
+ final int minsFromEndDateTime;
+
+ /// The number of unique session ids found in the log file.
+ final int sessionCount;
+
+ /// The map containing all of the flutter channels and a count
+ /// of how many events were under each channel.
+ ///
+ /// ```
+ /// {
+ /// 'stable': 123,
+ /// 'beta': 50,
+ /// 'master': 5,
+ /// }
+ /// ```
+ final Map<String, int> flutterChannelCount;
+
+ /// The map containing all of the tools that have sent events
+ /// and how many events were sent by each tool.
+ ///
+ /// ```
+ /// {
+ /// 'flutter-tool': 500,
+ /// 'dart-tool': 45,
+ /// 'vscode-plugins': 321,
+ /// }
+ /// ```
+ final Map<String, int> toolCount;
+
+ /// The map containing all of the events in the file along with
+ /// how many times they have occured.
+ ///
+ /// ```
+ /// {
+ /// 'client_request': 345,
+ /// 'hot_reload_time': 765,
+ /// 'memory_info': 90,
+ /// }
+ /// ```
+ final Map<String, int> eventCount;
+
+ /// Total number of records in the log file.
+ final int recordCount;
+
+ /// Contains the data from the [LogHandler.logFileStats] method.
+ const LogFileStats({
+ required this.startDateTime,
+ required this.minsFromStartDateTime,
+ required this.endDateTime,
+ required this.minsFromEndDateTime,
+ required this.sessionCount,
+ required this.flutterChannelCount,
+ required this.toolCount,
+ required this.recordCount,
+ required this.eventCount,
+ });
+
+ /// Pass in a string label for one of the instance variables
+ /// and return the integer value of that label.
+ ///
+ /// If label passed for [DateTime] instance variable, integer
+ /// in the form of [DateTime.millisecondsSinceEpoch] will be
+ /// returned.
+ ///
+ /// Returns null if the label passed does not match anything.
+ int? getValueByString(String label) {
+ // When querying counts, the label will include the
+ // key for the appropriate map
+ //
+ // Example: logFileStats.toolCount.flutter-tool is asking
+ // for the number of events sent via flutter cli
+ final parts = label.split('.');
+ String? key;
+ if (parts.length >= 3) {
+ // Assign the first two parts of the string as the label
+ // ie. logFileStats.toolCount.flutter-tool -> logFileStats.toolCount
+ label = parts.sublist(0, 2).join('.');
+ key = parts.sublist(2, parts.length).join('.');
+ }
+
+ switch (label) {
+ case 'logFileStats.startDateTime':
+ return startDateTime.millisecondsSinceEpoch;
+ case 'logFileStats.minsFromStartDateTime':
+ return minsFromStartDateTime;
+ case 'logFileStats.endDateTime':
+ return endDateTime.millisecondsSinceEpoch;
+ case 'logFileStats.minsFromEndDateTime':
+ return minsFromEndDateTime;
+ case 'logFileStats.sessionCount':
+ return sessionCount;
+ case 'logFileStats.recordCount':
+ return recordCount;
+ case 'logFileStats.flutterChannelCount':
+ if (key != null && flutterChannelCount.containsKey(key)) {
+ return flutterChannelCount[key];
+ }
+ case 'logFileStats.toolCount':
+ if (key != null && toolCount.containsKey(key)) {
+ return toolCount[key];
+ }
+ case 'logFileStats.eventCount':
+ if (key != null && eventCount.containsKey(key)) {
+ return eventCount[key];
+ }
+ }
+
+ return null;
+ }
+
+ @override
+ String toString() {
+ const encoder = JsonEncoder.withIndent(' ');
+ return encoder.convert({
+ 'startDateTime': startDateTime.toString(),
+ 'minsFromStartDateTime': minsFromStartDateTime,
+ 'endDateTime': endDateTime.toString(),
+ 'minsFromEndDateTime': minsFromEndDateTime,
+ 'sessionCount': sessionCount,
+ 'recordCount': recordCount,
+ 'eventCount': eventCount,
+ 'toolCount': toolCount,
+ 'flutterChannelCount': flutterChannelCount,
+ });
+ }
+}
+
+/// This class is responsible for writing to a log
+/// file that has been initialized by the [createLogFile].
+///
+/// It will be treated as an append only log and will be limited
+/// to have has many data records as specified by [kLogFileLength].
+class LogHandler {
+ final File logFile;
+
+ /// Contains instances of [Event.analyticsException] that were encountered
+ /// during a workflow and will be sent to GA4 for collection.
+ final Set<Event> errorSet = {};
+
+ /// A log handler constructor that will delegate saving
+ /// logs and retrieving stats from the persisted log.
+ LogHandler({required this.logFile});
+
+ /// Get stats from the persisted log file.
+ ///
+ /// Note that some developers may only be Dart
+ /// developers and will not have any data for flutter
+ /// related metrics.
+ LogFileStats? logFileStats() {
+ // Parse each line of the log file through [LogItem],
+ // some returned records may be null if malformed, they will be
+ // removed later through `whereType<LogItem>`
+ final records = logFile
+ .readAsLinesSync()
+ .map((String e) {
+ try {
+ return LogItem.fromRecord(jsonDecode(e) as Map<String, Object?>);
+ } on FormatException catch (err) {
+ errorSet.add(Event.analyticsException(
+ workflow: 'LogFileStats.logFileStats',
+ error: err.runtimeType.toString(),
+ description: 'message: ${err.message}\nsource: ${err.source}',
+ ));
+
+ return null;
+ // ignore: avoid_catching_errors
+ } on TypeError catch (err) {
+ errorSet.add(Event.analyticsException(
+ workflow: 'LogFileStats.logFileStats',
+ error: err.runtimeType.toString(),
+ ));
+
+ return null;
+ }
+ })
+ .whereType<LogItem>()
+ .toList();
+
+ if (records.isEmpty) return null;
+
+ // Get the start and end dates for the log file
+ final startDateTime = records.first.localTime;
+ final endDateTime = records.last.localTime;
+
+ // Map with counters for user properties
+ final counter = <String, Set<Object>>{
+ 'sessions': <int>{},
+ 'flutter_channel': <String>{},
+ 'tool': <String>{},
+ };
+
+ // Map of counters for each event
+ final eventCount = <String, int>{};
+ final flutterChannelCount = <String, int>{};
+ final toolCount = <String, int>{};
+ for (final record in records) {
+ counter['sessions']!.add(record.sessionId);
+ counter['tool']!.add(record.tool);
+ if (record.flutterChannel != null) {
+ counter['flutter_channel']!.add(record.flutterChannel!);
+ }
+
+ // Count each event, if it doesn't exist in the [eventCount]
+ // it will be added first
+ if (!eventCount.containsKey(record.eventName)) {
+ eventCount[record.eventName] = 0;
+ }
+ eventCount[record.eventName] = eventCount[record.eventName]! + 1;
+
+ // Counting how many events were recorded for each tool
+ if (!toolCount.containsKey(record.tool)) {
+ toolCount[record.tool] = 0;
+ }
+ toolCount[record.tool] = toolCount[record.tool]! + 1;
+
+ // Necessary to perform a null check for flutter channel because
+ // not all events will have information about flutter
+ if (record.flutterChannel != null) {
+ final flutterChannel = record.flutterChannel!;
+ if (!flutterChannelCount.containsKey(flutterChannel)) {
+ flutterChannelCount[flutterChannel] = 0;
+ }
+
+ flutterChannelCount[flutterChannel] =
+ flutterChannelCount[flutterChannel]! + 1;
+ }
+ }
+
+ final now = clock.now();
+
+ return LogFileStats(
+ startDateTime: startDateTime,
+ minsFromStartDateTime: now.difference(startDateTime).inMinutes,
+ endDateTime: endDateTime,
+ minsFromEndDateTime: now.difference(endDateTime).inMinutes,
+ sessionCount: counter['sessions']!.length,
+ flutterChannelCount: flutterChannelCount,
+ toolCount: toolCount,
+ eventCount: eventCount,
+ recordCount: records.length,
+ );
+ }
+
+ /// Saves the data passed in as a single line in the log file.
+ ///
+ /// This will keep the max number of records limited to equal to
+ /// or less than [kLogFileLength] records.
+ void save({required Map<String, Object?> data}) {
+ try {
+ final stat = logFile.statSync();
+ List<String> records;
+ if (stat.size > kMaxLogFileSize) {
+ logFile.deleteSync();
+ logFile.createSync();
+ records = [];
+ } else {
+ records = logFile.readAsLinesSync();
+ }
+ final content = '${jsonEncode(data)}\n';
+
+ // When the record count is less than the max, add as normal;
+ // else drop the oldest records until equal to max
+ if (records.length < kLogFileLength) {
+ logFile.writeAsStringSync(content, mode: FileMode.writeOnlyAppend);
+ } else {
+ records.add(content);
+ records = records.skip(records.length - kLogFileLength).toList();
+
+ logFile.writeAsStringSync(records.join('\n'));
+ }
+ } on FileSystemException {
+ // Logging isn't important enough to warrant raising a
+ // FileSystemException that will surprise consumers of this package.
+ }
+ }
+}
+
+/// Data class for each record persisted on the client's machine.
+class LogItem {
+ final String eventName;
+ final int sessionId;
+ final String? flutterChannel;
+ final String host;
+ final String? flutterVersion;
+ final String dartVersion;
+ final String tool;
+ final DateTime localTime;
+ final String hostOsVersion;
+ final String locale;
+ final String? clientIde;
+
+ LogItem({
+ required this.eventName,
+ required this.sessionId,
+ this.flutterChannel,
+ required this.host,
+ this.flutterVersion,
+ required this.dartVersion,
+ required this.tool,
+ required this.localTime,
+ required this.hostOsVersion,
+ required this.locale,
+ required this.clientIde,
+ });
+
+ /// Serves a parser for each record in the log file.
+ ///
+ /// Using this method guarantees that we have parsed out
+ /// fields that are necessary for the [LogHandler.logFileStats]
+ /// method.
+ ///
+ /// If the returned value is null, that indicates a malformed
+ /// record which can be discarded during analysis.
+ ///
+ /// Example of what a record looks like:
+ /// ```
+ /// {
+ /// "client_id": "ffcea97b-db5e-4c66-98c2-3942de4fac40",
+ /// "events": [
+ /// {
+ /// "name": "hot_reload_time",
+ /// "params": {
+ /// "timeMs": 135
+ /// }
+ /// }
+ /// ],
+ /// "user_properties": {
+ /// "session_id": {
+ /// "value": 1699385899950
+ /// },
+ /// "flutter_channel": {
+ /// "value": "ey-test-channel"
+ /// },
+ /// "host": {
+ /// "value": "macOS"
+ /// },
+ /// "flutter_version": {
+ /// "value": "Flutter 3.6.0-7.0.pre.47"
+ /// },
+ /// "dart_version": {
+ /// "value": "Dart 2.19.0"
+ /// },
+ /// "analytics_pkg_version": {
+ /// "value": "5.2.0"
+ /// },
+ /// "tool": {
+ /// "value": "flutter-tool"
+ /// },
+ /// "local_time": {
+ /// "value": "2023-11-07 15:09:03.025559 -0500"
+ /// },
+ /// "host_os_version": {
+ /// "value": "Version 14.1 (Build 23B74)"
+ /// },
+ /// "locale": {
+ /// "value": "en"
+ /// },
+ /// "clientIde": {
+ /// "value": "VSCode"
+ /// }
+ /// }
+ /// }
+ /// ```
+ static LogItem? fromRecord(Map<String, Object?> record) {
+ if (!record.containsKey('user_properties') ||
+ !record.containsKey('events')) {
+ return null;
+ }
+
+ // Parse out values from the top level key = 'events' and return
+ // a map for the one event in the value
+ final eventProp =
+ (record['events']! as List<Object?>).first as Map<String, Object?>;
+ final eventName = eventProp['name'] as String;
+
+ // Parse the data out of the `user_properties` value
+ final userProps = record['user_properties'] as Map<String, Object?>;
+
+ // Parse out the values from the top level key = 'user_properties`
+ final sessionId =
+ (userProps['session_id']! as Map<String, Object?>)['value'] as int?;
+ final flutterChannel = (userProps['flutter_channel']!
+ as Map<String, Object?>)['value'] as String?;
+ final host =
+ (userProps['host']! as Map<String, Object?>)['value'] as String?;
+ final flutterVersion = (userProps['flutter_version']!
+ as Map<String, Object?>)['value'] as String?;
+ final dartVersion = (userProps['dart_version']!
+ as Map<String, Object?>)['value'] as String?;
+ final tool =
+ (userProps['tool']! as Map<String, Object?>)['value'] as String?;
+ final localTimeString =
+ (userProps['local_time']! as Map<String, Object?>)['value'] as String?;
+ final hostOsVersion = (userProps['host_os_version']!
+ as Map<String, Object?>)['value'] as String?;
+ final locale =
+ (userProps['locale']! as Map<String, Object?>)['value'] as String?;
+ final clientIde =
+ (userProps['client_ide']! as Map<String, Object?>)['value'] as String?;
+
+ // If any of the above values are null, return null since that
+ // indicates the record is malformed; note that `flutter_version`,
+ // `flutter_channel`, and `client_ide` are nullable fields in the log file
+ final values = <Object?>[
+ // Values associated with the top level key = 'events'
+ eventName,
+
+ // Values associated with the top level key = 'events'
+ sessionId,
+ host,
+ dartVersion,
+ tool,
+ localTimeString,
+ hostOsVersion,
+ locale,
+ ];
+ for (final value in values) {
+ if (value == null) return null;
+ }
+
+ // Parse the local time from the string extracted
+ final localTime = DateTime.parse(localTimeString!).toLocal();
+
+ return LogItem(
+ eventName: eventName,
+ sessionId: sessionId!,
+ flutterChannel: flutterChannel,
+ host: host!,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion!,
+ tool: tool!,
+ localTime: localTime,
+ hostOsVersion: hostOsVersion!,
+ locale: locale!,
+ clientIde: clientIde,
+ );
+ }
+}
diff --git a/pkgs/unified_analytics/lib/src/survey_handler.dart b/pkgs/unified_analytics/lib/src/survey_handler.dart
new file mode 100644
index 0000000..7461dfc
--- /dev/null
+++ b/pkgs/unified_analytics/lib/src/survey_handler.dart
@@ -0,0 +1,366 @@
+// Copyright (c) 2023, 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 'package:clock/clock.dart';
+import 'package:file/file.dart';
+import 'package:http/http.dart' as http;
+
+import 'constants.dart';
+import 'enums.dart';
+import 'initializer.dart';
+import 'log_handler.dart';
+
+class Condition {
+ /// How to query the log file.
+ ///
+ ///
+ /// Example: logFileStats.recordCount refers to the
+ /// total record count being returned by [LogFileStats].
+ final String field;
+
+ /// String representation of operator.
+ ///
+ ///
+ /// Allowed values:
+ /// - '>=' `greater than or equal to`
+ /// - '<=' `less than or equal to`
+ /// - '>' `greater than`
+ /// - '<' `less then`
+ /// - '==' `equals`
+ /// - '!=' `not equal`
+ final String operatorString;
+
+ /// The value we will be comparing against using the [operatorString].
+ final int value;
+
+ /// One of the conditions that need to be valid for
+ /// a survey to be returned to the user.
+ ///
+ /// Example of raw json:
+ /// ```
+ /// {
+ /// "field": "logFileStats.recordCount",
+ /// "operator": ">=",
+ /// "value": 1000
+ /// }
+ /// ```
+ Condition(
+ this.field,
+ this.operatorString,
+ this.value,
+ );
+
+ Condition.fromJson(Map<String, dynamic> json)
+ : field = json['field'] as String,
+ operatorString = json['operator'] as String,
+ value = json['value'] as int;
+
+ Map<String, Object?> toMap() => <String, Object?>{
+ 'field': field,
+ 'operator': operatorString,
+ 'value': value,
+ };
+
+ @override
+ String toString() => jsonEncode(toMap());
+}
+
+/// Data class for the persisted survey contents.
+///
+/// [uniqueId] is the identifier for each survey, [timestamp] refers
+/// to when the survey was added to the persisted file.
+///
+/// The boolean [snoozed] is set to `true` if the survey has been dismissed
+/// temporarily by the user. When set to `false` this indicates that the survey
+/// has been dismissed permanently and will not be shown to the user again.
+class PersistedSurvey {
+ final String uniqueId;
+ final bool snoozed;
+ final DateTime timestamp;
+
+ PersistedSurvey({
+ required this.uniqueId,
+ required this.snoozed,
+ required this.timestamp,
+ });
+
+ @override
+ String toString() => jsonEncode({
+ 'uniqueId': uniqueId,
+ 'snoozed': snoozed,
+ 'timestamp': timestamp.toString(),
+ });
+}
+
+class Survey {
+ final String uniqueId;
+ final DateTime startDate;
+ final DateTime endDate;
+ final String description;
+ final int snoozeForMinutes;
+ final double samplingRate;
+ final List<DashTool> excludeDashToolList;
+ final List<Condition> conditionList;
+ final List<SurveyButton> buttonList;
+
+ /// A data class that contains the relevant information for a given
+ /// survey parsed from the survey's metadata file.
+ const Survey({
+ required this.uniqueId,
+ required this.startDate,
+ required this.endDate,
+ required this.description,
+ required this.snoozeForMinutes,
+ required this.samplingRate,
+ required this.excludeDashToolList,
+ required this.conditionList,
+ required this.buttonList,
+ });
+
+ /// Parse the contents of the json metadata file hosted externally.
+ Survey.fromJson(Map<String, dynamic> json)
+ : uniqueId = json['uniqueId'] as String,
+ startDate = DateTime.parse(json['startDate'] as String),
+ endDate = DateTime.parse(json['endDate'] as String),
+ description = json['description'] as String,
+ // Handle both string and integer fields
+ snoozeForMinutes = json['snoozeForMinutes'] is String
+ ? int.parse(json['snoozeForMinutes'] as String)
+ : json['snoozeForMinutes'] as int,
+ // Handle both string and double fields
+ samplingRate = json['samplingRate'] is String
+ ? double.parse(json['samplingRate'] as String)
+ : json['samplingRate'] as double,
+ excludeDashToolList = (json['excludeDashTools'] as List<dynamic>)
+ .map((e) => DashTool.fromLabel(e as String))
+ .toList(),
+ conditionList = (json['conditions'] as List<dynamic>).map((e) {
+ return Condition.fromJson(e as Map<String, dynamic>);
+ }).toList(),
+ buttonList = (json['buttons'] as List<dynamic>).map((e) {
+ return SurveyButton.fromJson(e as Map<String, dynamic>);
+ }).toList();
+
+ @override
+ String toString() {
+ const encoder = JsonEncoder.withIndent(' ');
+ return encoder.convert({
+ 'uniqueId': uniqueId,
+ 'startDate': startDate.toString(),
+ 'endDate': endDate.toString(),
+ 'description': description,
+ 'snoozeForMinutes': snoozeForMinutes,
+ 'samplingRate': samplingRate,
+ 'conditionList': conditionList.map((e) => e.toMap()).toList(),
+ 'buttonList': buttonList.map((e) => e.toMap()).toList(),
+ });
+ }
+}
+
+class SurveyButton {
+ final String buttonText;
+ final String action;
+ final bool promptRemainsVisible;
+ final String? url;
+
+ SurveyButton({
+ required this.buttonText,
+ required this.action,
+ required this.promptRemainsVisible,
+ this.url,
+ });
+
+ SurveyButton.fromJson(Map<String, dynamic> json)
+ : buttonText = json['buttonText'] as String,
+ action = json['action'] as String,
+ promptRemainsVisible = json['promptRemainsVisible'] as bool,
+ url = json['url'] as String?;
+
+ Map<String, Object?> toMap() => <String, Object?>{
+ 'buttonText': buttonText,
+ 'action': action,
+ 'promptRemainsVisible': promptRemainsVisible,
+ 'url': url,
+ };
+}
+
+class SurveyHandler {
+ final File dismissedSurveyFile;
+
+ SurveyHandler({required this.dismissedSurveyFile});
+
+ /// Invoking this method will persist the survey's id in
+ /// the local file with either a snooze or permanently dismissed
+ /// indicator.
+ ///
+ /// In the snoozed state, the survey will be prompted again after
+ /// the survey's specified snooze period.
+ ///
+ /// Each entry for a survey will have the following format:
+ /// ```
+ /// {
+ /// "survey-unique-id": {
+ /// "status": "snoozed", // status is either snoozed or dismissed
+ /// "timestamp": 1690219834859
+ /// }
+ /// }
+ /// ```
+ void dismiss(Survey survey, bool permanently) {
+ final contents = _parseJsonFile();
+
+ // Add the new data and write back out to the file
+ final status = permanently ? 'dismissed' : 'snoozed';
+ contents[survey.uniqueId] = {
+ 'status': status,
+ 'timestamp': clock.now().millisecondsSinceEpoch,
+ };
+
+ dismissedSurveyFile.writeAsStringSync(jsonEncode(contents));
+ }
+
+ /// Retrieve a list of strings for each [Survey] persisted on disk.
+ ///
+ /// The survey may be in a snoozed or dismissed state based on user action.
+ Map<String, PersistedSurvey> fetchPersistedSurveys() {
+ final contents = _parseJsonFile();
+
+ // Initialize the list of persisted surveys and add to them
+ // as they are being parsed
+ final persistedSurveys = <String, PersistedSurvey>{};
+ contents.forEach((key, value) {
+ value as Map<String, dynamic>;
+
+ final uniqueId = key;
+ final snoozed = value['status'] == 'snoozed' ? true : false;
+ final timestamp =
+ DateTime.fromMillisecondsSinceEpoch(value['timestamp'] as int);
+
+ persistedSurveys[uniqueId] = PersistedSurvey(
+ uniqueId: uniqueId,
+ snoozed: snoozed,
+ timestamp: timestamp,
+ );
+ });
+
+ return persistedSurveys;
+ }
+
+ /// Retrieves the survey metadata file from [kContextualSurveyUrl].
+ Future<List<Survey>> fetchSurveyList() async {
+ final List<dynamic> body;
+ try {
+ final payload = await _fetchContents();
+ body = jsonDecode(payload) as List<dynamic>;
+ // ignore: avoid_catches_without_on_clauses
+ } catch (err) {
+ return [];
+ }
+
+ final surveyList = parseSurveysFromJson(body);
+
+ return surveyList;
+ }
+
+ /// Fetches the json in string form from the remote location.
+ Future<String> _fetchContents() async {
+ final uri = Uri.parse(kContextualSurveyUrl);
+ final response = await http.get(uri);
+ return response.body;
+ }
+
+ /// Method to return a Map representation of the json persisted file.
+ Map<String, dynamic> _parseJsonFile() {
+ Map<String, dynamic> contents;
+ try {
+ contents = jsonDecode(dismissedSurveyFile.readAsStringSync())
+ as Map<String, dynamic>;
+ } on FormatException {
+ createDismissedSurveyFile(dismissedSurveyFile: dismissedSurveyFile);
+ contents = {};
+ } on FileSystemException {
+ createDismissedSurveyFile(dismissedSurveyFile: dismissedSurveyFile);
+ contents = {};
+ }
+
+ return contents;
+ }
+
+ /// Function to ensure that each survey is still valid by
+ /// checking the [Survey.startDate] and [Survey.endDate]
+ /// against the current [clock] now date.
+ static bool checkSurveyDate(Survey survey) {
+ final now = clock.now();
+ return survey.startDate.isBefore(now) && survey.endDate.isAfter(now);
+ }
+
+ /// Function that takes in a json data structure that is in
+ /// the form of a list and returns a list of [Survey] items.
+ ///
+ /// This will also check the survey's dates to make sure it
+ /// has not expired.
+ static List<Survey> parseSurveysFromJson(List<dynamic> body) => body
+ .map((element) {
+ // Error handling to skip any surveys from the remote location
+ // that fail to parse
+ try {
+ return Survey.fromJson(element as Map<String, dynamic>);
+ // ignore: avoid_catching_errors
+ } on TypeError {
+ return null;
+ } on FormatException {
+ return null;
+ } on Exception {
+ return null;
+ }
+ })
+ .whereType<Survey>()
+ .where(checkSurveyDate)
+ .toList();
+}
+
+class FakeSurveyHandler extends SurveyHandler {
+ final List<Survey> _fakeInitializedSurveys = [];
+
+ /// Use this class in tests if you can provide the
+ /// list of [Survey] objects.
+ ///
+ /// Important: the surveys in the [initializedSurveys] list
+ /// will have their dates checked to ensure they are valid; it is
+ /// recommended to use `package:clock` to set a fixed time for testing.
+ FakeSurveyHandler.fromList({
+ required super.dismissedSurveyFile,
+ required List<Survey> initializedSurveys,
+ }) {
+ // We must pass the surveys from the list to the
+ // `checkSurveyDate` function here and not for the
+ // `.fromString()` constructor because the `parseSurveysFromJson`
+ // method already checks their date
+ for (final survey in initializedSurveys) {
+ if (SurveyHandler.checkSurveyDate(survey)) {
+ _fakeInitializedSurveys.add(survey);
+ }
+ }
+ }
+
+ /// Use this class in tests if you can provide raw
+ /// json strings to simulate a response from a remote server.
+ FakeSurveyHandler.fromString({
+ required super.dismissedSurveyFile,
+ required String content,
+ }) {
+ final body = jsonDecode(content) as List<dynamic>;
+ for (final fakeSurvey in SurveyHandler.parseSurveysFromJson(body)) {
+ _fakeInitializedSurveys.add(fakeSurvey);
+ }
+ }
+
+ @override
+ Future<List<Survey>> fetchSurveyList() =>
+ Future<List<Survey>>.value(_fakeInitializedSurveys);
+
+ @override
+ Future<String> _fetchContents() => throw UnimplementedError();
+}
diff --git a/pkgs/unified_analytics/lib/src/user_property.dart b/pkgs/unified_analytics/lib/src/user_property.dart
new file mode 100644
index 0000000..f0e177d
--- /dev/null
+++ b/pkgs/unified_analytics/lib/src/user_property.dart
@@ -0,0 +1,162 @@
+// Copyright (c) 2023, 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 'package:clock/clock.dart';
+import 'package:file/file.dart';
+
+import 'constants.dart';
+import 'event.dart';
+import 'initializer.dart';
+import 'utils.dart';
+
+class UserProperty {
+ final String? flutterChannel;
+ final String host;
+ final String? flutterVersion;
+ final String dartVersion;
+ final String tool;
+ final String hostOsVersion;
+ final String locale;
+ final String? clientIde;
+ final String? enabledFeatures;
+
+ final File sessionFile;
+
+ /// Contains instances of [Event.analyticsException] that were encountered
+ /// during a workflow and will be sent to GA4 for collection.
+ final Set<Event> errorSet = {};
+
+ int? _sessionId;
+
+ /// This class is intended to capture all of the user's
+ /// metadata when the class gets initialized as well as collecting
+ /// session data to send in the json payload to Google Analytics.
+ UserProperty({
+ required this.flutterChannel,
+ required this.host,
+ required this.flutterVersion,
+ required this.dartVersion,
+ required this.tool,
+ required this.hostOsVersion,
+ required this.locale,
+ required this.clientIde,
+ required this.enabledFeatures,
+ required this.sessionFile,
+ });
+
+ /// This will use the data parsed from the
+ /// session file in the dart-tool directory
+ /// to get the session id if the last ping was within
+ /// [kSessionDurationMinutes].
+ ///
+ /// If time since last ping exceeds the duration, then the file
+ /// will be updated with a new session id and that will be returned.
+ ///
+ /// Note, the file will always be updated when calling this method
+ /// because the last ping variable will always need to be persisted.
+ int? getSessionId() {
+ _refreshSessionData();
+ final now = clock.now();
+
+ // Convert the epoch time from the last ping into datetime and check if we
+ // are within the kSessionDurationMinutes.
+ final lastPingDateTime = sessionFile.lastModifiedSync();
+ if (now.difference(lastPingDateTime).inMinutes > kSessionDurationMinutes) {
+ // Update the session file with the latest session id
+ _sessionId = now.millisecondsSinceEpoch;
+ writeSessionContents(sessionFile: sessionFile);
+ } else {
+ // Update the last modified timestamp with the current timestamp so that
+ // we can use it for the next _lastPing calculation
+ sessionFile.setLastModifiedSync(now);
+ }
+
+ return _sessionId;
+ }
+
+ /// This method will take the data in this class and convert it into
+ /// a Map that is suitable for the POST request schema.
+ ///
+ /// This will call the [UserProperty] object's [UserProperty.getSessionId]
+ /// method which will update the session file and get a new session id
+ /// if necessary.
+ ///
+ /// https://developers.google.com/analytics/devguides/collection/protocol/ga4/user-properties?client_type=gtag
+ Map<String, Map<String, Object?>> preparePayload() {
+ return <String, Map<String, Object?>>{
+ for (final entry in _toMap().entries)
+ entry.key: <String, Object?>{'value': entry.value}
+ };
+ }
+
+ @override
+ String toString() {
+ return jsonEncode(_toMap());
+ }
+
+ /// This will go to the session file within the dart-tool
+ /// directory and fetch the latest data from the session file to update
+ /// the class's variables. If the session file is malformed, a new
+ /// session file will be recreated.
+ ///
+ /// This allows the session data in this class to always be up
+ /// to date incase another tool is also calling this package and
+ /// making updates to the session file.
+ void _refreshSessionData() {
+ /// Using a nested function here to reduce verbosity
+ void parseContents() {
+ final sessionFileContents = sessionFile.readAsStringSync();
+ final sessionObj =
+ jsonDecode(sessionFileContents) as Map<String, Object?>;
+ _sessionId = sessionObj['session_id'] as int;
+ }
+
+ try {
+ // Failing to parse the contents will result in the current timestamp
+ // being used as the session id and will get used to recreate the file
+ parseContents();
+ } on FormatException catch (err) {
+ final now = createSessionFile(sessionFile: sessionFile);
+
+ errorSet.add(Event.analyticsException(
+ workflow: 'UserProperty._refreshSessionData',
+ error: err.runtimeType.toString(),
+ description: 'message: ${err.message}\nsource: ${err.source}',
+ ));
+
+ // Fallback to setting the session id as the current time
+ _sessionId = now.millisecondsSinceEpoch;
+ } on FileSystemException catch (err) {
+ final now = createSessionFile(sessionFile: sessionFile);
+
+ errorSet.add(Event.analyticsException(
+ workflow: 'UserProperty._refreshSessionData',
+ error: err.runtimeType.toString(),
+ description: err.osError?.toString(),
+ ));
+
+ // Fallback to setting the session id as the current time
+ _sessionId = now.millisecondsSinceEpoch;
+ }
+ }
+
+ /// Convert the data stored in this class into a map while also
+ /// getting the latest session id using the [UserProperty] class.
+ Map<String, Object?> _toMap() => <String, Object?>{
+ 'session_id': getSessionId(),
+ 'flutter_channel': flutterChannel,
+ 'host': host,
+ 'flutter_version': flutterVersion,
+ 'dart_version': dartVersion,
+ 'analytics_pkg_version': kPackageVersion,
+ 'tool': tool,
+ 'local_time': formatDateTime(clock.now()),
+ 'host_os_version': hostOsVersion,
+ 'locale': locale,
+ 'client_ide': clientIde,
+ 'enabled_features': enabledFeatures,
+ };
+}
diff --git a/pkgs/unified_analytics/lib/src/utils.dart b/pkgs/unified_analytics/lib/src/utils.dart
new file mode 100644
index 0000000..41848a2
--- /dev/null
+++ b/pkgs/unified_analytics/lib/src/utils.dart
@@ -0,0 +1,340 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+import 'dart:io' as io;
+import 'dart:math' show Random;
+
+import 'package:clock/clock.dart';
+import 'package:convert/convert.dart';
+import 'package:file/file.dart';
+
+import 'enums.dart';
+import 'event.dart';
+import 'survey_handler.dart';
+import 'user_property.dart';
+
+/// Get a string representation of the current date in the following format:
+/// ```text
+/// yyyy-MM-dd (2023-01-09)
+/// ```
+String get dateStamp {
+ return FixedDateTimeFormatter('YYYY-MM-DD').encode(clock.now());
+}
+
+/// Reads in a directory and returns `true` if write permissions are enabled.
+///
+/// Uses the [FileStat] method `modeString()` to return a string in the form
+/// of `rwxrwxrwx` where the second character in the string indicates if write
+/// is enabled with a `w` or disabled with `-`.
+bool checkDirectoryForWritePermissions(Directory directory) {
+ if (!directory.existsSync()) return false;
+
+ final fileStat = directory.statSync();
+ return fileStat.modeString()[1] == 'w';
+}
+
+/// Format time as 'yyyy-MM-dd HH:mm:ss Z' where Z is the difference between the
+/// timezone of t and UTC formatted according to RFC 822.
+String formatDateTime(DateTime t) {
+ final sign = t.timeZoneOffset.isNegative ? '-' : '+';
+ final tzOffset = t.timeZoneOffset.abs();
+ final hoursOffset = tzOffset.inHours;
+ final minutesOffset =
+ tzOffset.inMinutes - (Duration.minutesPerHour * hoursOffset);
+ assert(hoursOffset < 24);
+ assert(minutesOffset < 60);
+
+ String twoDigits(int n) => (n >= 10) ? '$n' : '0$n';
+ return '$t $sign${twoDigits(hoursOffset)}${twoDigits(minutesOffset)}';
+}
+
+/// Construct the Map that will be converted to json for the
+/// body of the request.
+///
+/// Follows the following schema:
+///
+/// ```
+/// {
+/// "client_id": "46cc0ba6-f604-4fd9-aa2f-8a20beb24cd4",
+/// "events": [{ "name": "testing", "params": { "time_ns": 345 } }],
+/// "user_properties": {
+/// "session_id": { "value": 1673466750423 },
+/// "flutter_channel": { "value": "ey-test-channel" },
+/// "host": { "value": "macos" },
+/// "flutter_version": { "value": "Flutter 3.6.0-7.0.pre.47" },
+/// "dart_version": { "value": "Dart 2.19.0" },
+/// "tool": { "value": "flutter-tools" },
+/// "local_time": { "value": "2023-01-11 14:53:31.471816 -0500" }
+/// }
+/// }
+/// ```
+/// https://developers.google.com/analytics/devguides/collection/protocol/ga4/sending-events?client_type=gtag
+Map<String, Object?> generateRequestBody({
+ required String clientId,
+ required DashEvent eventName,
+ required Map<String, Object?> eventData,
+ required UserProperty userProperty,
+}) =>
+ <String, Object?>{
+ 'client_id': clientId,
+ 'events': <Map<String, Object?>>[
+ <String, Object?>{
+ 'name': eventName.label,
+ 'params': eventData,
+ }
+ ],
+ 'user_properties': userProperty.preparePayload()
+ };
+
+/// This will use environment variables to get the user's
+/// home directory where all the directory will be created that will
+/// contain all of the analytics files.
+Directory? getHomeDirectory(FileSystem fs) {
+ String? home;
+ final envVars = io.Platform.environment;
+
+ if (io.Platform.isMacOS) {
+ home = envVars['HOME'];
+ } else if (io.Platform.isLinux) {
+ home = envVars['HOME'];
+ } else if (io.Platform.isWindows) {
+ home = envVars['AppData'];
+ }
+
+ if (home == null) return null;
+
+ return fs.directory(home);
+}
+
+/// Returns `true` if user has opted out of legacy analytics in
+/// Dart or Flutter.
+///
+/// Checks legacy opt-out status for the Flutter
+/// and Dart in the following locations.
+///
+/// Dart: `$HOME/.dart/dartdev.json`
+/// ```
+/// {
+/// "firstRun": false,
+/// "enabled": false, <-- THIS USER HAS OPTED OUT
+/// "disclosureShown": true,
+/// "clientId": "52710e60-7c70-4335-b3a4-9d922630f12a"
+/// }
+/// ```
+///
+/// Flutter: `$HOME/.flutter`
+/// ```
+/// {
+/// "firstRun": false,
+/// "clientId": "4c3a3d1e-e545-47e7-b4f8-10129f6ab169",
+/// "enabled": false <-- THIS USER HAS OPTED OUT
+/// }
+/// ```
+///
+/// Devtools: `$HOME/.flutter-devtools/.devtools`
+/// ```
+/// {
+/// "analyticsEnabled": false, <-- THIS USER HAS OPTED OUT
+/// "isFirstRun": false,
+/// "lastReleaseNotesVersion": "2.31.0",
+/// "2023-Q4": {
+/// "surveyActionTaken": false,
+/// "surveyShownCount": 0
+/// }
+/// }
+/// ```
+bool legacyOptOut({required Directory homeDirectory}) {
+ // List of Maps for each of the config file, `key` refers to the
+ // key in the json file that indicates if the user has been opted
+ // out or not
+ final legacyConfigFiles = [
+ (
+ tool: DashTool.dartTool,
+ file: homeDirectory.childDirectory('.dart').childFile('dartdev.json'),
+ key: 'enabled',
+ ),
+ (
+ tool: DashTool.flutterTool,
+ file: homeDirectory.childFile('.flutter'),
+ key: 'enabled',
+ ),
+ (
+ tool: DashTool.devtools,
+ file: homeDirectory
+ .childDirectory('.flutter-devtools')
+ .childFile('.devtools'),
+ key: 'analyticsEnabled',
+ ),
+ ];
+ for (final legacyConfigObj in legacyConfigFiles) {
+ final legacyFile = legacyConfigObj.file;
+ final lookupKey = legacyConfigObj.key;
+
+ if (legacyFile.existsSync()) {
+ try {
+ final legacyFileObj =
+ jsonDecode(legacyFile.readAsStringSync()) as Map<String, Object?>;
+ if (legacyFileObj.containsKey(lookupKey) &&
+ legacyFileObj[lookupKey] == false) {
+ return true;
+ }
+ } on FormatException {
+ // In the case of an error when parsing the json file, return true
+ // which will result in the user being opted out of unified_analytics
+ //
+ // A corrupted file could mean they opted out previously but for some
+ // reason, the file was written incorrectly
+ return true;
+ } on FileSystemException {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+/// Helper method that can be used to resolve the Dart SDK version for clients
+/// of package:unified_analytics.
+///
+/// Input [versionString] for this method should be the returned string from
+/// [io.Platform.version].
+///
+/// For tools that don't already have a method for resolving the Dart
+/// SDK version in semver notation, this helper can be used. This uses
+/// the [io.Platform.version] to parse the semver.
+///
+/// Example for stable version:
+/// `3.3.0 (stable) (Tue Feb 13 10:25:19 2024 +0000) on "macos_arm64"` into
+/// `3.3.0`.
+///
+/// Example for non-stable version:
+/// `2.1.0-dev.8.0.flutter-312ae32` into `2.1.0 (build 2.1.0-dev.8.0 312ae32)`.
+String parseDartSDKVersion(String versionString) {
+ versionString = versionString.trim();
+ final justVersion = versionString.split(' ')[0];
+
+ // For non-stable versions, this regex will include build information
+ return justVersion.replaceFirstMapped(RegExp(r'(\d+\.\d+\.\d+)(.+)'),
+ (Match match) {
+ final noFlutter = match[2]!.replaceAll('.flutter-', ' ');
+ return '${match[1]} (build ${match[1]}$noFlutter)'.trim();
+ });
+}
+
+/// Will use two strings to produce a double for applying a sampling
+/// rate for [Survey] to be returned to the user.
+double sampleRate(String string1, String string2) =>
+ ((string1.hashCode + string2.hashCode) % 101) / 100;
+
+/// Function to check if a given [Survey] can be shown again
+/// by checking if it was snoozed or permanently dismissed.
+///
+/// If the [Survey] doesn't exist in the persisted file, then it
+/// will be shown to the user.
+///
+/// If the [Survey] has been permanently dismissed, we will not
+/// show it to the user.
+///
+/// If the [Survey] has been snoozed, we will check the timestamp
+/// that it was snoozed at with the current time from [clock]
+/// and if the snooze period has elapsed, then we will show it to the user.
+bool surveySnoozedOrDismissed(
+ Survey survey,
+ Map<String, PersistedSurvey> persistedSurveyMap,
+) {
+ // If this survey hasn't been persisted yet, it is okay to pass
+ // to the user
+ if (!persistedSurveyMap.containsKey(survey.uniqueId)) return false;
+
+ final persistedSurveyObj = persistedSurveyMap[survey.uniqueId]!;
+
+ // If the survey has been dismissed permanently, we will not show the
+ // survey
+ if (!persistedSurveyObj.snoozed) return true;
+
+ // Find how many minutes has elapsed from the timestamp and now
+ final minutesElapsed =
+ clock.now().difference(persistedSurveyObj.timestamp).inMinutes;
+
+ return survey.snoozeForMinutes > minutesElapsed;
+}
+
+/// Due to some limitations for GA4, this function can be used to
+/// truncate fields that we may not care about truncating, such as
+/// the host os details.
+///
+/// [maxLength] represents the maximum length allowed for the string.
+///
+/// Example:
+/// "Linux 6.2.0-1015-azure #15~22.04.1-Ubuntu SMP Fri Oct 6 13:20:44 UTC 2023"
+///
+/// The above string is what is returned by [io.Platform.operatingSystemVersion]
+/// for certain machines running GitHub Actions, this function will truncate
+/// that value down to the maximum length at 36 characters and return the below
+///
+/// Return:
+/// "Linux 6.2.0-1015-azure #15~22."
+///
+/// This should only be used on fields that are okay to be truncated, this
+/// should not be used for parameters on the [Event] constructors.
+String truncateStringToLength(String str, int maxLength) {
+ if (maxLength <= 0) {
+ throw ArgumentError(
+ 'The length to truncate a string must be greater than 0');
+ }
+
+ if (maxLength > str.length) return str;
+
+ return str.substring(0, maxLength);
+}
+
+/// Writes the JSON string payload to the provided [sessionFile].
+///
+/// The `last_ping` key:value pair has been deprecated, it remains included
+/// for backward compatibility.
+void writeSessionContents({required File sessionFile}) {
+ final now = clock.now();
+ sessionFile.writeAsStringSync('{"session_id": ${now.millisecondsSinceEpoch}, '
+ '"last_ping": ${now.millisecondsSinceEpoch}}');
+}
+
+/// A UUID generator.
+///
+/// This will generate unique IDs in the format:
+///
+/// f47ac10b-58cc-4372-a567-0e02b2c3d479
+///
+/// The generated uuids are 128 bit numbers encoded in a specific string format.
+/// For more information, see
+/// [en.wikipedia.org/wiki/Universally_unique_identifier](http://en.wikipedia.org/wiki/Universally_unique_identifier).
+///
+/// This class was taken from the previous `usage` package (https://github.com/dart-lang/usage/blob/master/lib/uuid/uuid.dart).
+class Uuid {
+ final Random _random;
+
+ Uuid([int? seed]) : _random = Random(seed);
+
+ /// Generate a version 4 (random) uuid. This is a uuid scheme that only uses
+ /// random numbers as the source of the generated uuid.
+ String generateV4() {
+ // Generate xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx / 8-4-4-4-12.
+ final special = 8 + _random.nextInt(4);
+
+ return '${_bitsDigits(16, 4)}${_bitsDigits(16, 4)}-'
+ '${_bitsDigits(16, 4)}-'
+ '4${_bitsDigits(12, 3)}-'
+ '${_printDigits(special, 1)}${_bitsDigits(12, 3)}-'
+ '${_bitsDigits(16, 4)}${_bitsDigits(16, 4)}${_bitsDigits(16, 4)}';
+ }
+
+ String _bitsDigits(int bitCount, int digitCount) =>
+ _printDigits(_generateBits(bitCount), digitCount);
+
+ int _generateBits(int bitCount) => _random.nextInt(1 << bitCount);
+
+ String _printDigits(int value, int count) =>
+ value.toRadixString(16).padLeft(count, '0');
+}
diff --git a/pkgs/unified_analytics/lib/testing.dart b/pkgs/unified_analytics/lib/testing.dart
new file mode 100644
index 0000000..900212f
--- /dev/null
+++ b/pkgs/unified_analytics/lib/testing.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2024, 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.
+
+export 'src/enums.dart';
diff --git a/pkgs/unified_analytics/lib/unified_analytics.dart b/pkgs/unified_analytics/lib/unified_analytics.dart
new file mode 100644
index 0000000..7cc4562
--- /dev/null
+++ b/pkgs/unified_analytics/lib/unified_analytics.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2023, 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.
+
+export 'src/analytics.dart' show Analytics, FakeAnalytics, NoOpAnalytics;
+export 'src/config_handler.dart' show ToolInfo;
+export 'src/enums.dart' show DashTool;
+export 'src/event.dart' show Event;
+export 'src/log_handler.dart' show LogFileStats;
+export 'src/survey_handler.dart' show Survey, SurveyButton, SurveyHandler;
+export 'src/utils.dart' show parseDartSDKVersion;
diff --git a/pkgs/unified_analytics/pubspec.yaml b/pkgs/unified_analytics/pubspec.yaml
new file mode 100644
index 0000000..172f5b2
--- /dev/null
+++ b/pkgs/unified_analytics/pubspec.yaml
@@ -0,0 +1,25 @@
+name: unified_analytics
+description: >-
+ A package for logging analytics for all Dart and Flutter related tooling
+ to Google Analytics.
+# LINT.IfChange
+# When updating this, keep the version consistent with the changelog and the
+# value in lib/src/constants.dart.
+version: 6.1.4
+# LINT.ThenChange(lib/src/constants.dart)
+repository: https://github.com/dart-lang/tools/tree/main/pkgs/unified_analytics
+
+environment:
+ sdk: ^3.4.0
+
+dependencies:
+ clock: ^1.1.1
+ convert: ^3.1.1
+ file: '>=6.1.4 <8.0.0'
+ http: '>=0.13.5 <2.0.0'
+ meta: ^1.9.0
+
+dev_dependencies:
+ dart_flutter_team_lints: ^3.0.0
+ test: ^1.16.6
+ yaml: ^3.1.1
diff --git a/pkgs/unified_analytics/test/asserts_test.dart b/pkgs/unified_analytics/test/asserts_test.dart
new file mode 100644
index 0000000..9230fc6
--- /dev/null
+++ b/pkgs/unified_analytics/test/asserts_test.dart
@@ -0,0 +1,413 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test/test.dart';
+import 'package:unified_analytics/src/asserts.dart';
+
+void main() {
+ test('Failure if client_id top level key is missing', () {
+ final body = <String, Object?>{};
+
+ final expectedErrorMessage = 'client_id missing from top level keys';
+ expect(
+ () => checkBody(body),
+ throwsA(predicate(
+ (AnalyticsException e) => e.message == expectedErrorMessage,
+ expectedErrorMessage)));
+ });
+
+ test('Failure if events top level key is missing', () {
+ final body = <String, Object?>{'client_id': 'xxxxxxx'};
+
+ final expectedErrorMessage = 'events missing from top level keys';
+ expect(
+ () => checkBody(body),
+ throwsA(predicate(
+ (AnalyticsException e) => e.message == expectedErrorMessage,
+ expectedErrorMessage)));
+ });
+
+ test('Failure if user_properties top level key is missing', () {
+ final body = <String, Object?>{'client_id': 'xxxxxxx', 'events': []};
+
+ final expectedErrorMessage = 'user_properties missing from top level keys';
+ expect(
+ () => checkBody(body),
+ throwsA(predicate(
+ (AnalyticsException e) => e.message == expectedErrorMessage,
+ expectedErrorMessage)));
+ });
+
+ test('Failure if more than 25 events found in events list', () {
+ final body = <String, Object?>{
+ 'client_id': 'xxxxxxx',
+ 'events': <Map<String, Object?>>[],
+ 'user_properties': <String, Object?>{}
+ };
+
+ // Add more than the 25 allowed events
+ for (var i = 0; i < 30; i++) {
+ (body['events'] as List).add({'name': i});
+ }
+
+ final expectedErrorMessage = '25 is the max number of events';
+ expect(
+ () => checkBody(body),
+ throwsA(predicate(
+ (AnalyticsException e) => e.message == expectedErrorMessage,
+ expectedErrorMessage)));
+ });
+
+ test('Failure when event name is greater than 40 chars', () {
+ final body = <String, Object?>{
+ 'client_id': 'xxxxxxx',
+ 'events': <Map<String, Object?>>[
+ {
+ 'name':
+ 'hot_reload_timehot_reload_timehot_reload_timehot_reload_time',
+ 'params': {'time_ms': 133, 'count': 1999000}
+ }
+ ],
+ 'user_properties': <String, Object?>{}
+ };
+
+ final expectedErrorMessage = 'Limit event names to 40 chars or less\n'
+ 'Event name: '
+ '"hot_reload_timehot_reload_timehot_reload_timehot_reload_time"'
+ ' is too long';
+ expect(
+ () => checkBody(body),
+ throwsA(predicate(
+ (AnalyticsException e) => e.message == expectedErrorMessage,
+ expectedErrorMessage)));
+ });
+
+ test('Failure when event name has invalid chars', () {
+ final body = <String, Object?>{
+ 'client_id': 'xxxxxxx',
+ 'events': <Map<String, Object?>>[
+ {
+ 'name': 'hot_reload_time!!',
+ 'params': {'time_ms': 133, 'count': 1999000}
+ }
+ ],
+ 'user_properties': <String, Object?>{}
+ };
+
+ final expectedErrorMessage =
+ 'Event name can only have alphanumeric chars and underscores\n'
+ 'Event name: "hot_reload_time!!" contains invalid characters';
+ expect(
+ () => checkBody(body),
+ throwsA(predicate(
+ (AnalyticsException e) => e.message == expectedErrorMessage,
+ expectedErrorMessage)));
+ });
+
+ test('Failure when event name does not start with alphabetic char', () {
+ final body = <String, Object?>{
+ 'client_id': 'xxxxxxx',
+ 'events': <Map<String, Object?>>[
+ {
+ 'name': '2hot_reload_time',
+ 'params': {'time_ms': 133, 'count': 1999000}
+ }
+ ],
+ 'user_properties': <String, Object?>{}
+ };
+
+ final expectedErrorMessage =
+ 'Event name first char must be alphabetic char\n'
+ 'Event name: "2hot_reload_time" must begin with a valid character';
+ expect(
+ () => checkBody(body),
+ throwsA(predicate(
+ (AnalyticsException e) => e.message == expectedErrorMessage,
+ expectedErrorMessage)));
+ });
+
+ test('Failure when an event has more than 25 event params', () {
+ final body = <String, Object?>{
+ 'client_id': 'xxxxxxx',
+ 'events': <Map<String, Object?>>[
+ {
+ 'name': 'hot_reload_time',
+ // 'params': {...} SUBBING THIS VALUE OUT 30 Maps
+ }
+ ],
+ 'user_properties': <String, Object?>{}
+ };
+
+ final params = <String, Object?>{};
+ for (var i = 0; i < 30; i++) {
+ params['$i'] = i;
+ }
+
+ // Add the params to the first event in the body
+ ((body['events'] as List).first as Map)['params'] = params;
+
+ final expectedErrorMessage = 'Limit params for each event to less than 25\n'
+ 'Event: "hot_reload_time" has too many parameters';
+ expect(
+ () => checkBody(body),
+ throwsA(predicate(
+ (AnalyticsException e) => e.message == expectedErrorMessage,
+ expectedErrorMessage)));
+ });
+
+ test('Failure when an value for event params is not a supported type (list)',
+ () {
+ final body = <String, Object?>{
+ 'client_id': 'xxxxxxx',
+ 'events': <Map<String, Object?>>[
+ {
+ 'name': 'hot_reload_time',
+ 'params': {
+ 'time_ms': 133,
+ // Lists and Maps are not supported
+ 'count': <int>[1999000],
+ }
+ }
+ ],
+ 'user_properties': <String, Object?>{}
+ };
+
+ final expectedErrorMessage =
+ 'Values for event params have to be String, int, double, or bool\n'
+ 'Value for "count" is not a valid type for event: "hot_reload_time"';
+ expect(
+ () => checkBody(body),
+ throwsA(predicate(
+ (AnalyticsException e) => e.message == expectedErrorMessage,
+ expectedErrorMessage)));
+ });
+
+ test('Failure when an value for event params is not a supported type (map)',
+ () {
+ final body = <String, Object?>{
+ 'client_id': 'xxxxxxx',
+ 'events': <Map<String, Object?>>[
+ {
+ 'name': 'hot_reload_time',
+ 'params': {
+ 'time_ms': 133,
+ // Lists and Maps are not supported
+ 'count': <int, int>{5: 20},
+ }
+ }
+ ],
+ 'user_properties': <String, Object?>{}
+ };
+
+ final expectedErrorMessage =
+ 'Values for event params have to be String, int, double, or bool\n'
+ 'Value for "count" is not a valid type for event: "hot_reload_time"';
+ expect(
+ () => checkBody(body),
+ throwsA(predicate(
+ (AnalyticsException e) => e.message == expectedErrorMessage,
+ expectedErrorMessage)));
+ });
+
+ test('Failure when event param name is more than 40 chars', () {
+ final body = <String, Object?>{
+ 'client_id': 'xxxxxxx',
+ 'events': <Map<String, Object?>>[
+ {
+ 'name': 'hot_reload_time',
+ 'params': {'time_mstime_mstime_mstime_mstime_mstime_ms': 133}
+ }
+ ],
+ 'user_properties': <String, Object?>{}
+ };
+
+ final expectedErrorMessage = 'Limit event param names to 40 chars or less\n'
+ 'The key: "time_mstime_mstime_mstime_mstime_mstime_ms" '
+ 'under the event: "hot_reload_time" is too long';
+ expect(
+ () => checkBody(body),
+ throwsA(predicate(
+ (AnalyticsException e) => e.message == expectedErrorMessage,
+ expectedErrorMessage)));
+ });
+
+ test('Failure for event param name that has invalid chars', () {
+ final body = <String, Object?>{
+ 'client_id': 'xxxxxxx',
+ 'events': <Map<String, Object?>>[
+ {
+ 'name': 'hot_reload_time',
+ 'params': {'time_ns!': 133}
+ }
+ ],
+ 'user_properties': <String, Object?>{}
+ };
+
+ final expectedErrorMessage =
+ 'Event param name can only have alphanumeric chars and underscores\n'
+ 'The key: "time_ns!" under the event: "hot_reload_time" contains '
+ 'invalid characters';
+
+ expect(
+ () => checkBody(body),
+ throwsA(predicate(
+ (AnalyticsException e) => e.message == expectedErrorMessage,
+ expectedErrorMessage)));
+ });
+
+ test(
+ 'Failure for event param name that does not start with an alphabetic char',
+ () {
+ final body = <String, Object?>{
+ 'client_id': 'xxxxxxx',
+ 'events': <Map<String, Object?>>[
+ {
+ 'name': 'hot_reload_time',
+ 'params': {'22time_ns': 133}
+ }
+ ],
+ 'user_properties': <String, Object?>{}
+ };
+
+ final expectedErrorMessage =
+ 'Event param name first char must be alphabetic char\n'
+ 'The key: "22time_ns" under the event: "hot_reload_time" must begin '
+ 'in a valid character';
+ expect(
+ () => checkBody(body),
+ throwsA(predicate(
+ (AnalyticsException e) => e.message == expectedErrorMessage,
+ expectedErrorMessage)));
+ },
+ );
+
+ test('Failure for event param values that are greater than 100 chars', () {
+ final body = <String, Object?>{
+ 'client_id': 'xxxxxxx',
+ 'events': <Map<String, Object?>>[
+ {
+ 'name': 'hot_reload_time',
+ 'params': {
+ 'time_ns': 'dsfjlksdjfajlfdsfjlks'
+ 'djfajlfdsfjlksdjfajlfdsfjlksdjfaj'
+ 'lfdsfjlksdjfajlfdsfjlksdjfajlfdsf'
+ 'jlksdjfajlfdsfjlksdjfajlf'
+ }
+ }
+ ],
+ 'user_properties': <String, Object?>{}
+ };
+
+ final expectedErrorMessage =
+ 'Limit characters in event param value to 100 chars or less\n'
+ 'Value for "time_ns" is too long, value="'
+ 'dsfjlksdjfajlfdsfjlks'
+ 'djfajlfdsfjlksdjfajlfdsfjlksdjfaj'
+ 'lfdsfjlksdjfajlfdsfjlksdjfajlfdsf'
+ 'jlksdjfajlfdsfjlksdjfajlf"';
+ expect(
+ () => checkBody(body),
+ throwsA(predicate(
+ (AnalyticsException e) => e.message == expectedErrorMessage,
+ expectedErrorMessage)));
+ });
+
+ test('Failure when body has more than 25 user properties', () {
+ final body = <String, Object?>{
+ 'client_id': 'xxxxxxx',
+ 'events': <Map<String, Object?>>[
+ {
+ 'name': 'hot_reload_time',
+ 'params': {'time_ns': 123}
+ }
+ ],
+ 'user_properties': <String, Object?>{}
+ };
+
+ for (var i = 0; i < 30; i++) {
+ (body['user_properties']! as Map<String, Object?>)['$i'] = i;
+ }
+
+ final expectedErrorMessage = 'Limit user properties to 25 or less';
+ expect(
+ () => checkBody(body),
+ throwsA(predicate(
+ (AnalyticsException e) => e.message == expectedErrorMessage,
+ expectedErrorMessage)));
+ });
+
+ test('Failure when user properties names are greater than 24 chars', () {
+ final body = <String, Object?>{
+ 'client_id': 'xxxxxxx',
+ 'events': <Map<String, Object?>>[
+ {
+ 'name': 'hot_reload_time',
+ 'params': {'time_ns': 123}
+ }
+ ],
+ 'user_properties': <String, Object?>{
+ 'testtesttesttesttesttesttest': <String, Object?>{}, // TOO LONG
+ }
+ };
+
+ final expectedErrorMessage =
+ 'Limit user property names to 24 chars or less\n'
+ 'The user property key: "testtesttesttesttesttesttest" is too long';
+ expect(
+ () => checkBody(body),
+ throwsA(predicate(
+ (AnalyticsException e) => e.message == expectedErrorMessage,
+ expectedErrorMessage)));
+ });
+
+ test('Failure when user properties values are greater than 36 chars', () {
+ final body = <String, Object?>{
+ 'client_id': 'xxxxxxx',
+ 'events': <Map<String, Object?>>[
+ {
+ 'name': 'hot_reload_time',
+ 'params': {'time_ns': 123}
+ }
+ ],
+ 'user_properties': <String, Object?>{
+ 'test': <String, Object?>{
+ 'value': 'testtesttesttesttesttesttesttesttesttest' // TOO LONG
+ },
+ }
+ };
+
+ final expectedErrorMessage =
+ 'Limit user property values to 36 chars or less\n'
+ 'For the user property key "test", the value '
+ '"testtesttesttesttesttesttesttesttesttest" is too long';
+ expect(
+ () => checkBody(body),
+ throwsA(predicate(
+ (AnalyticsException e) => e.message == expectedErrorMessage,
+ expectedErrorMessage)));
+ });
+
+ test('Successful body passes all asserts', () {
+ final body = <String, Object?>{
+ 'client_id': '46cc0ba6-f604-4fd9-aa2f-8a20beb24cd4',
+ 'events': [
+ {
+ 'name': 'testing',
+ 'params': {'time_ns': 345}
+ }
+ ],
+ 'user_properties': {
+ 'session_id': {'value': 1673466750423},
+ 'flutter_channel': {'value': 'ey-test-channel'},
+ 'host': {'value': 'macos'},
+ 'flutter_version': {'value': 'Flutter 3.6.0-7.0.pre.47'},
+ 'dart_version': {'value': 'Dart 2.19.0'},
+ 'tool': {'value': 'flutter-tools'},
+ 'local_time': {'value': '2023-01-11 14:53:31.471816 -0500'}
+ }
+ };
+
+ expect(() => checkBody(body), returnsNormally);
+ });
+}
diff --git a/pkgs/unified_analytics/test/error_handler_test.dart b/pkgs/unified_analytics/test/error_handler_test.dart
new file mode 100644
index 0000000..39b2df8
--- /dev/null
+++ b/pkgs/unified_analytics/test/error_handler_test.dart
@@ -0,0 +1,346 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io' as io;
+
+import 'package:file/file.dart';
+import 'package:file/memory.dart';
+import 'package:test/test.dart';
+
+import 'package:unified_analytics/src/constants.dart';
+import 'package:unified_analytics/src/enums.dart';
+import 'package:unified_analytics/unified_analytics.dart';
+
+void main() {
+ late MemoryFileSystem fs;
+ late Directory home;
+ late FakeAnalytics initializationAnalytics;
+ late FakeAnalytics analytics;
+ late File sessionFile;
+ late File logFile;
+
+ const homeDirName = 'home';
+ const initialTool = DashTool.flutterTool;
+ const toolsMessageVersion = 1;
+ const toolsMessage = 'toolsMessage';
+ const flutterChannel = 'flutterChannel';
+ const flutterVersion = 'flutterVersion';
+ const dartVersion = 'dartVersion';
+ const platform = DevicePlatform.macos;
+ const clientIde = 'VSCode';
+
+ final testEvent = Event.codeSizeAnalysis(platform: 'platform');
+
+ setUp(() {
+ // Setup the filesystem with the home directory
+ final fsStyle =
+ io.Platform.isWindows ? FileSystemStyle.windows : FileSystemStyle.posix;
+ fs = MemoryFileSystem.test(style: fsStyle);
+ home = fs.directory(homeDirName);
+
+ // This is the first analytics instance that will be used to demonstrate
+ // that events will not be sent with the first run of analytics
+ initializationAnalytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ );
+ expect(initializationAnalytics.shouldShowMessage, true);
+ initializationAnalytics.clientShowedMessage();
+ expect(initializationAnalytics.shouldShowMessage, false);
+
+ // The main analytics instance, other instances can be spawned within tests
+ // to test how to instances running together work
+ //
+ // This instance should have the same parameters as the one above for
+ // [initializationAnalytics]
+ analytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ clientIde: clientIde,
+ );
+ analytics.clientShowedMessage();
+
+ // The files that should have been generated that will be used for tests
+ sessionFile =
+ home.childDirectory(kDartToolDirectoryName).childFile(kSessionFileName);
+ logFile =
+ home.childDirectory(kDartToolDirectoryName).childFile(kLogFileName);
+ });
+
+ group('Session handler:', () {
+ test('no error when opted out already and opting in', () async {
+ // When we opt out from an analytics instance, we clear the contents of
+ // session file, as required by the privacy document. When creating a
+ // second instance of [Analytics], it should not detect that the file is
+ // empty and recreate it, it should remain opted out and no error event
+ // should have been sent
+ await analytics.setTelemetry(false);
+ expect(analytics.telemetryEnabled, false);
+ expect(sessionFile.readAsStringSync(), isEmpty);
+
+ final secondAnalytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ clientIde: clientIde,
+ );
+ expect(sessionFile.readAsStringSync(), isEmpty);
+ expect(secondAnalytics.telemetryEnabled, false);
+
+ expect(
+ analytics.sentEvents.where(
+ (element) => element.eventName == DashEvent.analyticsException),
+ isEmpty,
+ );
+ expect(
+ secondAnalytics.sentEvents.where(
+ (element) => element.eventName == DashEvent.analyticsException),
+ isEmpty,
+ );
+
+ await secondAnalytics.setTelemetry(true);
+ expect(sessionFile.readAsStringSync(), isNotEmpty,
+ reason: 'Toggling telemetry should bring back the session data');
+ });
+ test('only sends one event for FormatException', () {
+ // Begin with the session file empty, it should recreate the file
+ // and send an error event
+ sessionFile.writeAsStringSync('');
+ expect(sessionFile.readAsStringSync(), isEmpty);
+ analytics.send(testEvent);
+ expect(sessionFile.readAsStringSync(), isNotEmpty);
+
+ analytics.sendPendingErrorEvents();
+ expect(
+ analytics.sentEvents.where(
+ (element) => element.eventName == DashEvent.analyticsException),
+ hasLength(1));
+
+ // Making the file empty again and sending an event should not send
+ // an additional event
+ sessionFile.writeAsStringSync('');
+ expect(sessionFile.readAsStringSync(), isEmpty);
+ analytics.send(testEvent);
+ expect(sessionFile.readAsStringSync(), isNotEmpty);
+
+ expect(
+ analytics.sentEvents.where(
+ (element) => element.eventName == DashEvent.analyticsException),
+ hasLength(1),
+ reason: 'We should not have added a new error event');
+ });
+
+ test('only sends one event for FileSystemException', () {
+ // Deleting the session file should cause the file system exception and
+ // sending a new event should log the error the first time and recreate
+ // the file. If we delete the file again and attempt to send an event,
+ // the session file should get recreated without sending a second error.
+ sessionFile.deleteSync();
+ expect(sessionFile.existsSync(), isFalse);
+ analytics.send(testEvent);
+
+ analytics.sendPendingErrorEvents();
+ expect(
+ analytics.sentEvents.where(
+ (element) => element.eventName == DashEvent.analyticsException),
+ hasLength(1),
+ );
+ expect(sessionFile.existsSync(), isTrue);
+ expect(sessionFile.readAsStringSync(), isNotEmpty);
+
+ // Remove the file again and send an event
+ sessionFile.deleteSync();
+ expect(sessionFile.existsSync(), isFalse);
+ analytics.send(testEvent);
+
+ expect(
+ analytics.sentEvents.where(
+ (element) => element.eventName == DashEvent.analyticsException),
+ hasLength(1),
+ reason: 'Only the first error event should exist',
+ );
+ expect(sessionFile.existsSync(), isTrue);
+ expect(sessionFile.readAsStringSync(), isNotEmpty);
+ });
+
+ test('sends two unique errors', () {
+ // Begin with the session file empty, it should recreate the file
+ // and send an error event
+ sessionFile.writeAsStringSync('');
+ expect(sessionFile.readAsStringSync(), isEmpty);
+ analytics.send(testEvent);
+ expect(sessionFile.readAsStringSync(), isNotEmpty);
+
+ analytics.sendPendingErrorEvents();
+ expect(
+ analytics.sentEvents.where(
+ (element) => element.eventName == DashEvent.analyticsException),
+ hasLength(1));
+
+ // Deleting the file now before sending an additional event should
+ // cause a different test error
+ sessionFile.deleteSync();
+ expect(sessionFile.existsSync(), isFalse);
+
+ analytics.send(testEvent);
+ expect(sessionFile.readAsStringSync(), isNotEmpty);
+ analytics.sendPendingErrorEvents();
+ expect(
+ analytics.sentEvents.where(
+ (element) => element.eventName == DashEvent.analyticsException),
+ hasLength(2));
+ expect(analytics.sentEvents, hasLength(4));
+
+ sessionFile.deleteSync();
+ expect(sessionFile.existsSync(), isFalse);
+
+ analytics.send(testEvent);
+ expect(sessionFile.readAsStringSync(), isNotEmpty);
+ expect(
+ analytics.sentEvents.where(
+ (element) => element.eventName == DashEvent.analyticsException),
+ hasLength(2));
+ });
+ });
+
+ group('Log handler:', () {
+ test('only sends one event for FormatException', () {
+ expect(logFile.existsSync(), isTrue);
+
+ // Write invalid lines to the log file to have a FormatException
+ // thrown when trying to parse the log file
+ logFile.writeAsStringSync('''
+{{}
+{{}
+''');
+
+ // Send one event so that the logFileStats method returns a valid value
+ analytics.send(testEvent);
+ expect(analytics.sentEvents, hasLength(1));
+ expect(logFile.readAsLinesSync(), hasLength(3));
+ analytics.sendPendingErrorEvents();
+ expect(
+ analytics.sentEvents.where(
+ (element) => element.eventName == DashEvent.analyticsException),
+ isEmpty,
+ );
+
+ // This call below will cause a FormatException while parsing the log file
+ final logFileStats = analytics.logFileStats();
+ expect(logFileStats, isNotNull);
+ expect(logFileStats!.recordCount, 1,
+ reason: 'The error event is not counted');
+ analytics.sendPendingErrorEvents();
+ expect(
+ analytics.sentEvents.where(
+ (element) => element.eventName == DashEvent.analyticsException),
+ hasLength(1),
+ );
+ expect(logFile.readAsLinesSync(), hasLength(4));
+ });
+
+ test('only sends one event for TypeError', () {
+ expect(logFile.existsSync(), isTrue);
+ // Write valid json but have one of the types wrong for
+ // the keys so that we throw a TypeError while casting the values
+ //
+ // In the json below, we have made the session id value a string when
+ // it should be an integer
+ logFile.writeAsStringSync('''
+{"client_id":"fcd6c0d5-6582-4c36-b09e-3ecedee9145c","events":[{"name":"command_usage_values","params":{"workflow":"doctor","commandHasTerminal":true}}],"user_properties":{"session_id":{"value":"this should be a string"},"flutter_channel":{"value":"master"},"host":{"value":"macOS"},"flutter_version":{"value":"3.20.0-2.0.pre.9"},"dart_version":{"value":"3.4.0 (build 3.4.0-99.0.dev)"},"analytics_pkg_version":{"value":"5.8.1"},"tool":{"value":"flutter-tool"},"local_time":{"value":"2024-02-07 15:46:19.920784 -0500"},"host_os_version":{"value":"Version 14.3 (Build 23D56)"},"locale":{"value":"en"},"client_ide":{"value":null},"enabled_features":{"value":"enable-native-assets"}}}
+''');
+ expect(logFile.readAsLinesSync(), hasLength(1));
+
+ // Send the test event so that the LogFileStats object is not null
+ analytics.send(testEvent);
+
+ final logFileStats = analytics.logFileStats();
+ analytics.sendPendingErrorEvents();
+ expect(
+ analytics.sentEvents.where(
+ (element) => element.eventName == DashEvent.analyticsException),
+ hasLength(1),
+ );
+ expect(logFileStats, isNotNull);
+ expect(logFileStats!.recordCount, 1);
+ });
+
+ test('sends two unique errors', () {
+ expect(logFile.existsSync(), isTrue);
+
+ // Write invalid lines to the log file to have a FormatException
+ // thrown when trying to parse the log file
+ logFile.writeAsStringSync('''
+{{}
+{{}
+''');
+
+ // Send one event so that the logFileStats method returns a valid value
+ analytics.send(testEvent);
+ expect(analytics.sentEvents, hasLength(1));
+ expect(logFile.readAsLinesSync(), hasLength(3));
+ analytics.sendPendingErrorEvents();
+ expect(
+ analytics.sentEvents.where(
+ (element) => element.eventName == DashEvent.analyticsException),
+ isEmpty,
+ );
+
+ // This will cause the first error
+ analytics.logFileStats();
+ analytics.sendPendingErrorEvents();
+ expect(
+ analytics.sentEvents.where(
+ (element) => element.eventName == DashEvent.analyticsException),
+ hasLength(1),
+ );
+
+ // Overwrite the contents of the log file now to include something that
+ // will cause a TypeError by changing the expected value for session id
+ // from integer to a string
+ logFile.writeAsStringSync('''
+{"client_id":"fcd6c0d5-6582-4c36-b09e-3ecedee9145c","events":[{"name":"command_usage_values","params":{"workflow":"doctor","commandHasTerminal":true}}],"user_properties":{"session_id":{"value":"this should be a string"},"flutter_channel":{"value":"master"},"host":{"value":"macOS"},"flutter_version":{"value":"3.20.0-2.0.pre.9"},"dart_version":{"value":"3.4.0 (build 3.4.0-99.0.dev)"},"analytics_pkg_version":{"value":"5.8.1"},"tool":{"value":"flutter-tool"},"local_time":{"value":"2024-02-07 15:46:19.920784 -0500"},"host_os_version":{"value":"Version 14.3 (Build 23D56)"},"locale":{"value":"en"},"client_ide":{"value":null},"enabled_features":{"value":"enable-native-assets"}}}
+''');
+ expect(logFile.readAsLinesSync(), hasLength(1));
+
+ // This will cause the second error
+ analytics.logFileStats();
+ analytics.sendPendingErrorEvents();
+ expect(
+ analytics.sentEvents.where(
+ (element) => element.eventName == DashEvent.analyticsException),
+ hasLength(2),
+ );
+
+ // Attempting to cause the same error won't send another error event
+ analytics.logFileStats();
+ analytics.sendPendingErrorEvents();
+ expect(
+ analytics.sentEvents.where(
+ (element) => element.eventName == DashEvent.analyticsException),
+ hasLength(2),
+ );
+ });
+ });
+}
diff --git a/pkgs/unified_analytics/test/event_test.dart b/pkgs/unified_analytics/test/event_test.dart
new file mode 100644
index 0000000..1e9344f
--- /dev/null
+++ b/pkgs/unified_analytics/test/event_test.dart
@@ -0,0 +1,702 @@
+// Copyright (c) 2023, 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:mirrors';
+
+import 'package:test/test.dart';
+import 'package:unified_analytics/src/enums.dart';
+import 'package:unified_analytics/unified_analytics.dart';
+
+void main() {
+ test('Event.analyticsCollectionEnabled constructed', () {
+ Event generateEvent() => Event.analyticsCollectionEnabled(status: false);
+
+ final constructedEvent = generateEvent();
+
+ expect(generateEvent, returnsNormally);
+ expect(constructedEvent.eventName, DashEvent.analyticsCollectionEnabled);
+ expect(constructedEvent.eventData['status'], false);
+ expect(constructedEvent.eventData.length, 1);
+ });
+
+ test('Event.clientNotification constructed', () {
+ Event generateEvent() => Event.clientNotification(
+ duration: 'duration',
+ latency: 'latency',
+ method: 'method',
+ );
+
+ final constructedEvent = generateEvent();
+
+ expect(generateEvent, returnsNormally);
+ expect(constructedEvent.eventName, DashEvent.clientNotification);
+ expect(constructedEvent.eventData['duration'], 'duration');
+ expect(constructedEvent.eventData['latency'], 'latency');
+ expect(constructedEvent.eventData['method'], 'method');
+ expect(constructedEvent.eventData.length, 3);
+ });
+
+ test('Event.clientRequest constructed', () {
+ Event generateEvent() => Event.clientRequest(
+ duration: 'duration',
+ latency: 'latency',
+ method: 'method',
+ added: 'added',
+ excluded: 'excluded',
+ files: 'files',
+ included: 'included',
+ openWorkspacePaths: 'openWorkspacePaths',
+ removed: 'removed',
+ );
+
+ final constructedEvent = generateEvent();
+
+ expect(generateEvent, returnsNormally);
+ expect(constructedEvent.eventName, DashEvent.clientRequest);
+ expect(constructedEvent.eventData['duration'], 'duration');
+ expect(constructedEvent.eventData['latency'], 'latency');
+ expect(constructedEvent.eventData['method'], 'method');
+ expect(constructedEvent.eventData['added'], 'added');
+ expect(constructedEvent.eventData['excluded'], 'excluded');
+ expect(constructedEvent.eventData['files'], 'files');
+ expect(constructedEvent.eventData['included'], 'included');
+ expect(
+ constructedEvent.eventData['openWorkspacePaths'], 'openWorkspacePaths');
+ expect(constructedEvent.eventData['removed'], 'removed');
+ expect(constructedEvent.eventData.length, 9);
+ });
+
+ test('Event.commandExecuted constructed', () {
+ Event generateEvent() => Event.commandExecuted(
+ count: 5,
+ name: 'name',
+ );
+
+ final constructedEvent = generateEvent();
+
+ expect(generateEvent, returnsNormally);
+ expect(constructedEvent.eventName, DashEvent.commandExecuted);
+ expect(constructedEvent.eventData['count'], 5);
+ expect(constructedEvent.eventData['name'], 'name');
+ expect(constructedEvent.eventData.length, 2);
+ });
+
+ test('Event.contextStructure constructed', () {
+ Event generateEvent() => Event.contextStructure(
+ contextsFromBothFiles: 1,
+ contextsFromOptionsFiles: 2,
+ contextsFromPackagesFiles: 3,
+ contextsWithoutFiles: 4,
+ immediateFileCount: 5,
+ immediateFileLineCount: 6,
+ numberOfContexts: 7,
+ transitiveFileCount: 8,
+ transitiveFileLineCount: 9,
+ transitiveFileUniqueCount: 10,
+ transitiveFileUniqueLineCount: 11,
+ );
+
+ final constructedEvent = generateEvent();
+
+ expect(generateEvent, returnsNormally);
+ expect(constructedEvent.eventName, DashEvent.contextStructure);
+ expect(constructedEvent.eventData['contextsFromBothFiles'], 1);
+ expect(constructedEvent.eventData['contextsFromOptionsFiles'], 2);
+ expect(constructedEvent.eventData['contextsFromPackagesFiles'], 3);
+ expect(constructedEvent.eventData['contextsWithoutFiles'], 4);
+ expect(constructedEvent.eventData['immediateFileCount'], 5);
+ expect(constructedEvent.eventData['immediateFileLineCount'], 6);
+ expect(constructedEvent.eventData['numberOfContexts'], 7);
+ expect(constructedEvent.eventData['transitiveFileCount'], 8);
+ expect(constructedEvent.eventData['transitiveFileLineCount'], 9);
+ expect(constructedEvent.eventData['transitiveFileUniqueCount'], 10);
+ expect(constructedEvent.eventData['transitiveFileUniqueLineCount'], 11);
+ expect(constructedEvent.eventData.length, 11);
+ });
+
+ test('Event.dartCliCommandExecuted constructed', () {
+ Event generateEvent() => Event.dartCliCommandExecuted(
+ name: 'name',
+ enabledExperiments: 'enabledExperiments',
+ exitCode: 0,
+ );
+
+ final constructedEvent = generateEvent();
+
+ expect(generateEvent, returnsNormally);
+ expect(constructedEvent.eventName, DashEvent.dartCliCommandExecuted);
+ expect(constructedEvent.eventData['name'], 'name');
+ expect(
+ constructedEvent.eventData['enabledExperiments'], 'enabledExperiments');
+ expect(constructedEvent.eventData['exitCode'], 0);
+ expect(constructedEvent.eventData.length, 3);
+ });
+
+ test('Event.doctorValidatorResult constructed', () {
+ Event generateEvent() => Event.doctorValidatorResult(
+ validatorName: 'validatorName',
+ result: 'success',
+ partOfGroupedValidator: false,
+ doctorInvocationId: 123,
+ statusInfo: 'statusInfo',
+ );
+
+ final constructedEvent = generateEvent();
+
+ expect(generateEvent, returnsNormally);
+ expect(constructedEvent.eventName, DashEvent.doctorValidatorResult);
+ expect(constructedEvent.eventData['validatorName'], 'validatorName');
+ expect(constructedEvent.eventData['result'], 'success');
+ expect(constructedEvent.eventData['partOfGroupedValidator'], false);
+ expect(constructedEvent.eventData['doctorInvocationId'], 123);
+ expect(constructedEvent.eventData['statusInfo'], 'statusInfo');
+ expect(constructedEvent.eventData.length, 5);
+ });
+
+ test('Event.hotReloadTime constructed', () {
+ Event generateEvent() => Event.hotReloadTime(timeMs: 500);
+
+ final constructedEvent = generateEvent();
+
+ expect(generateEvent, returnsNormally);
+ expect(constructedEvent.eventName, DashEvent.hotReloadTime);
+ expect(constructedEvent.eventData['timeMs'], 500);
+ expect(constructedEvent.eventData.length, 1);
+ });
+
+ test('Event.lintUsageCount constructed', () {
+ Event generateEvent() => Event.lintUsageCount(
+ count: 5,
+ name: 'name',
+ );
+
+ final constructedEvent = generateEvent();
+
+ expect(generateEvent, returnsNormally);
+ expect(constructedEvent.eventName, DashEvent.lintUsageCount);
+ expect(constructedEvent.eventData['count'], 5);
+ expect(constructedEvent.eventData['name'], 'name');
+ expect(constructedEvent.eventData.length, 2);
+ });
+
+ test('Event.memoryInfo constructed', () {
+ Event generateEvent() => Event.memoryInfo(
+ rss: 4,
+ periodSec: 5,
+ mbPerSec: 5.55,
+ );
+
+ final constructedEvent = generateEvent();
+
+ expect(generateEvent, returnsNormally);
+ expect(constructedEvent.eventName, DashEvent.memoryInfo);
+ expect(constructedEvent.eventData['rss'], 4);
+ expect(constructedEvent.eventData['periodSec'], 5);
+ expect(constructedEvent.eventData['mbPerSec'], 5.55);
+ expect(constructedEvent.eventData.length, 3);
+ });
+
+ test('Event.pluginRequest constructed', () {
+ Event generateEvent() => Event.pluginRequest(
+ duration: 'duration',
+ method: 'method',
+ pluginId: 'pluginId',
+ );
+
+ final constructedEvent = generateEvent();
+
+ expect(generateEvent, returnsNormally);
+ expect(constructedEvent.eventName, DashEvent.pluginRequest);
+ expect(constructedEvent.eventData['duration'], 'duration');
+ expect(constructedEvent.eventData['method'], 'method');
+ expect(constructedEvent.eventData['pluginId'], 'pluginId');
+ expect(constructedEvent.eventData.length, 3);
+ });
+
+ test('Event.pluginUse constructed', () {
+ Event generateEvent() => Event.pluginUse(
+ count: 5,
+ enabled: 'enabled',
+ pluginId: 'pluginId',
+ );
+
+ final constructedEvent = generateEvent();
+
+ expect(generateEvent, returnsNormally);
+ expect(constructedEvent.eventName, DashEvent.pluginUse);
+ expect(constructedEvent.eventData['count'], 5);
+ expect(constructedEvent.eventData['enabled'], 'enabled');
+ expect(constructedEvent.eventData['pluginId'], 'pluginId');
+ expect(constructedEvent.eventData.length, 3);
+ });
+
+ test('Event.pubGet constructed', () {
+ Event generateEvent() => Event.pubGet(
+ packageName: 'packageName',
+ version: 'version',
+ dependencyType: 'dependencyType',
+ );
+
+ final constructedEvent = generateEvent();
+
+ expect(generateEvent, returnsNormally);
+ expect(constructedEvent.eventName, DashEvent.pubGet);
+ expect(constructedEvent.eventData['packageName'], 'packageName');
+ expect(constructedEvent.eventData['version'], 'version');
+ expect(constructedEvent.eventData['dependencyType'], 'dependencyType');
+ expect(constructedEvent.eventData.length, 3);
+ });
+
+ test('Event.serverSession constructed', () {
+ Event generateEvent() => Event.serverSession(
+ clientId: 'clientId',
+ clientVersion: 'clientVersion',
+ duration: 5,
+ flags: 'flags',
+ parameters: 'parameters',
+ );
+
+ final constructedEvent = generateEvent();
+
+ expect(generateEvent, returnsNormally);
+ expect(constructedEvent.eventName, DashEvent.serverSession);
+ expect(constructedEvent.eventData['clientId'], 'clientId');
+ expect(constructedEvent.eventData['clientVersion'], 'clientVersion');
+ expect(constructedEvent.eventData['duration'], 5);
+ expect(constructedEvent.eventData['flags'], 'flags');
+ expect(constructedEvent.eventData['parameters'], 'parameters');
+ expect(constructedEvent.eventData.length, 5);
+ });
+
+ test('Event.severityAdjustment constructed', () {
+ Event generateEvent() => Event.severityAdjustment(
+ diagnostic: 'diagnostic',
+ adjustments: 'adjustments',
+ );
+
+ final constructedEvent = generateEvent();
+
+ expect(generateEvent, returnsNormally);
+ expect(constructedEvent.eventName, DashEvent.severityAdjustment);
+ expect(constructedEvent.eventData['diagnostic'], 'diagnostic');
+ expect(constructedEvent.eventData['adjustments'], 'adjustments');
+ expect(constructedEvent.eventData.length, 2);
+ });
+
+ test('Event.surveyAction constructed', () {
+ Event generateEvent() => Event.surveyAction(
+ surveyId: 'surveyId',
+ status: 'status',
+ );
+
+ final constructedEvent = generateEvent();
+
+ expect(generateEvent, returnsNormally);
+ expect(constructedEvent.eventName, DashEvent.surveyAction);
+ expect(constructedEvent.eventData['surveyId'], 'surveyId');
+ expect(constructedEvent.eventData['status'], 'status');
+ expect(constructedEvent.eventData.length, 2);
+ });
+
+ test('Event.surveyShown constructed', () {
+ Event generateEvent() => Event.surveyShown(surveyId: 'surveyId');
+
+ final constructedEvent = generateEvent();
+
+ expect(generateEvent, returnsNormally);
+ expect(constructedEvent.eventName, DashEvent.surveyShown);
+ expect(constructedEvent.eventData['surveyId'], 'surveyId');
+ expect(constructedEvent.eventData.length, 1);
+ });
+
+ test('Event.flutterBuildInfo constructed', () {
+ Event generateEvent() => Event.flutterBuildInfo(
+ label: 'label',
+ buildType: 'buildType',
+ command: 'command',
+ settings: 'settings',
+ error: 'error',
+ );
+
+ final constructedEvent = generateEvent();
+
+ expect(generateEvent, returnsNormally);
+ expect(constructedEvent.eventName, DashEvent.flutterBuildInfo);
+ expect(constructedEvent.eventData['label'], 'label');
+ expect(constructedEvent.eventData['buildType'], 'buildType');
+ expect(constructedEvent.eventData['command'], 'command');
+ expect(constructedEvent.eventData['settings'], 'settings');
+ expect(constructedEvent.eventData['error'], 'error');
+ expect(constructedEvent.eventData.length, 5);
+ });
+
+ test('Event.hotRunnerInfo constructed', () {
+ Event generateEvent() => Event.hotRunnerInfo(
+ label: 'label',
+ targetPlatform: 'targetPlatform',
+ sdkName: 'sdkName',
+ emulator: false,
+ fullRestart: true,
+ reason: 'reason',
+ finalLibraryCount: 5,
+ syncedLibraryCount: 6,
+ syncedClassesCount: 7,
+ syncedProceduresCount: 8,
+ syncedBytes: 9,
+ invalidatedSourcesCount: 10,
+ transferTimeInMs: 11,
+ overallTimeInMs: 12,
+ compileTimeInMs: 13,
+ findInvalidatedTimeInMs: 14,
+ scannedSourcesCount: 15,
+ reassembleTimeInMs: 16,
+ reloadVMTimeInMs: 17,
+ );
+
+ final constructedEvent = generateEvent();
+
+ expect(generateEvent, returnsNormally);
+ expect(constructedEvent.eventName, DashEvent.hotRunnerInfo);
+ expect(constructedEvent.eventData['label'], 'label');
+ expect(constructedEvent.eventData['targetPlatform'], 'targetPlatform');
+ expect(constructedEvent.eventData['sdkName'], 'sdkName');
+ expect(constructedEvent.eventData['emulator'], false);
+ expect(constructedEvent.eventData['fullRestart'], true);
+ expect(constructedEvent.eventData['reason'], 'reason');
+ expect(constructedEvent.eventData['finalLibraryCount'], 5);
+ expect(constructedEvent.eventData['syncedLibraryCount'], 6);
+ expect(constructedEvent.eventData['syncedClassesCount'], 7);
+ expect(constructedEvent.eventData['syncedProceduresCount'], 8);
+ expect(constructedEvent.eventData['syncedBytes'], 9);
+ expect(constructedEvent.eventData['invalidatedSourcesCount'], 10);
+ expect(constructedEvent.eventData['transferTimeInMs'], 11);
+ expect(constructedEvent.eventData['overallTimeInMs'], 12);
+ expect(constructedEvent.eventData['compileTimeInMs'], 13);
+ expect(constructedEvent.eventData['findInvalidatedTimeInMs'], 14);
+ expect(constructedEvent.eventData['scannedSourcesCount'], 15);
+ expect(constructedEvent.eventData['reassembleTimeInMs'], 16);
+ expect(constructedEvent.eventData['reloadVMTimeInMs'], 17);
+ expect(constructedEvent.eventData.length, 19);
+ });
+
+ test('Event.flutterCommandResult constructed', () {
+ Event generateEvent() => Event.flutterCommandResult(
+ commandPath: 'commandPath',
+ result: 'result',
+ commandHasTerminal: true,
+ maxRss: 123,
+ );
+
+ final constructedEvent = generateEvent();
+
+ expect(generateEvent, returnsNormally);
+ expect(constructedEvent.eventName, DashEvent.flutterCommandResult);
+ expect(constructedEvent.eventData['commandPath'], 'commandPath');
+ expect(constructedEvent.eventData['result'], 'result');
+ expect(constructedEvent.eventData['commandHasTerminal'], true);
+ expect(constructedEvent.eventData['maxRss'], 123);
+ expect(constructedEvent.eventData.length, 4);
+ });
+
+ test('Event.codeSizeAnalysis constructed', () {
+ Event generateEvent() => Event.codeSizeAnalysis(platform: 'platform');
+
+ final constructedEvent = generateEvent();
+
+ expect(generateEvent, returnsNormally);
+ expect(constructedEvent.eventName, DashEvent.codeSizeAnalysis);
+ expect(constructedEvent.eventData['platform'], 'platform');
+ expect(constructedEvent.eventData.length, 1);
+ });
+
+ test('Event.appleUsageEvent constructed', () {
+ Event generateEvent() => Event.appleUsageEvent(
+ workflow: 'workflow',
+ parameter: 'parameter',
+ result: 'result',
+ );
+
+ final constructedEvent = generateEvent();
+
+ expect(generateEvent, returnsNormally);
+ expect(constructedEvent.eventName, DashEvent.appleUsageEvent);
+ expect(constructedEvent.eventData['workflow'], 'workflow');
+ expect(constructedEvent.eventData['parameter'], 'parameter');
+ expect(constructedEvent.eventData['result'], 'result');
+ expect(constructedEvent.eventData.length, 3);
+ });
+
+ test('Event.exception constructed', () {
+ Event generateEvent() => Event.exception(
+ exception: 'exception',
+ data: {'foo': 'bar', 'baz': 1},
+ );
+
+ final constructedEvent = generateEvent();
+
+ expect(generateEvent, returnsNormally);
+ expect(constructedEvent.eventName, DashEvent.exception);
+ expect(constructedEvent.eventData['exception'], 'exception');
+ expect(constructedEvent.eventData['foo'], 'bar');
+ expect(constructedEvent.eventData['baz'], 1);
+ expect(constructedEvent.eventData.length, 3);
+ });
+
+ test('Event.timing constructed', () {
+ Event generateEvent() => Event.timing(
+ workflow: 'workflow',
+ variableName: 'variableName',
+ elapsedMilliseconds: 123,
+ label: 'label',
+ );
+
+ final constructedEvent = generateEvent();
+
+ expect(generateEvent, returnsNormally);
+ expect(constructedEvent.eventName, DashEvent.timing);
+ expect(constructedEvent.eventData['workflow'], 'workflow');
+ expect(constructedEvent.eventData['variableName'], 'variableName');
+ expect(constructedEvent.eventData['elapsedMilliseconds'], 123);
+ expect(constructedEvent.eventData['label'], 'label');
+ expect(constructedEvent.eventData.length, 4);
+ });
+
+ test('Event.commandUsageValues constructed', () {
+ Event generateEvent() => Event.commandUsageValues(
+ workflow: 'workflow',
+ commandHasTerminal: true,
+ buildBundleTargetPlatform: 'buildBundleTargetPlatform',
+ buildBundleIsModule: true,
+ buildAarProjectType: 'buildAarProjectType',
+ buildAarTargetPlatform: 'buildAarTargetPlatform',
+ buildApkTargetPlatform: 'buildApkTargetPlatform',
+ buildApkBuildMode: 'buildApkBuildMode',
+ buildApkSplitPerAbi: true,
+ buildAppBundleTargetPlatform: 'buildAppBundleTargetPlatform',
+ buildAppBundleBuildMode: 'buildAppBundleBuildMode',
+ createProjectType: 'createProjectType',
+ createAndroidLanguage: 'createAndroidLanguage',
+ createIosLanguage: 'createIosLanguage',
+ packagesNumberPlugins: 123,
+ packagesProjectModule: true,
+ packagesAndroidEmbeddingVersion: 'packagesAndroidEmbeddingVersion',
+ runIsEmulator: true,
+ runTargetName: 'runTargetName',
+ runTargetOsVersion: 'runTargetOsVersion',
+ runModeName: 'runModeName',
+ runProjectModule: true,
+ runProjectHostLanguage: 'runProjectHostLanguage',
+ runAndroidEmbeddingVersion: 'runAndroidEmbeddingVersion',
+ runEnableImpeller: true,
+ runIOSInterfaceType: 'runIOSInterfaceType',
+ runIsTest: true,
+ );
+
+ final constructedEvent = generateEvent();
+
+ expect(generateEvent, returnsNormally);
+ expect(constructedEvent.eventName, DashEvent.commandUsageValues);
+ expect(constructedEvent.eventData['workflow'], 'workflow');
+ expect(constructedEvent.eventData['buildBundleTargetPlatform'],
+ 'buildBundleTargetPlatform');
+ expect(constructedEvent.eventData['buildBundleIsModule'], true);
+ expect(constructedEvent.eventData['buildAarProjectType'],
+ 'buildAarProjectType');
+ expect(constructedEvent.eventData['buildAarTargetPlatform'],
+ 'buildAarTargetPlatform');
+ expect(constructedEvent.eventData['buildApkTargetPlatform'],
+ 'buildApkTargetPlatform');
+ expect(
+ constructedEvent.eventData['buildApkBuildMode'], 'buildApkBuildMode');
+ expect(constructedEvent.eventData['buildApkSplitPerAbi'], true);
+ expect(constructedEvent.eventData['buildAppBundleTargetPlatform'],
+ 'buildAppBundleTargetPlatform');
+ expect(constructedEvent.eventData['buildAppBundleBuildMode'],
+ 'buildAppBundleBuildMode');
+ expect(
+ constructedEvent.eventData['createProjectType'], 'createProjectType');
+ expect(constructedEvent.eventData['createAndroidLanguage'],
+ 'createAndroidLanguage');
+ expect(
+ constructedEvent.eventData['createIosLanguage'], 'createIosLanguage');
+ expect(constructedEvent.eventData['packagesNumberPlugins'], 123);
+ expect(constructedEvent.eventData['packagesProjectModule'], true);
+ expect(constructedEvent.eventData['packagesAndroidEmbeddingVersion'],
+ 'packagesAndroidEmbeddingVersion');
+ expect(constructedEvent.eventData['runIsEmulator'], true);
+ expect(constructedEvent.eventData['runTargetName'], 'runTargetName');
+ expect(
+ constructedEvent.eventData['runTargetOsVersion'], 'runTargetOsVersion');
+ expect(constructedEvent.eventData['runModeName'], 'runModeName');
+ expect(constructedEvent.eventData['runProjectModule'], true);
+ expect(constructedEvent.eventData['runProjectHostLanguage'],
+ 'runProjectHostLanguage');
+ expect(constructedEvent.eventData['runAndroidEmbeddingVersion'],
+ 'runAndroidEmbeddingVersion');
+ expect(constructedEvent.eventData['runEnableImpeller'], true);
+ expect(constructedEvent.eventData['runIOSInterfaceType'],
+ 'runIOSInterfaceType');
+ expect(constructedEvent.eventData.length, 27);
+ });
+
+ test('Event.analyticsException constructed', () {
+ Event generateEvent() => Event.analyticsException(
+ workflow: 'workflow',
+ error: 'error',
+ description: 'description',
+ );
+
+ final constructedEvent = generateEvent();
+
+ expect(generateEvent, returnsNormally);
+ expect(constructedEvent.eventName, DashEvent.analyticsException);
+ expect(constructedEvent.eventData['workflow'], 'workflow');
+ expect(constructedEvent.eventData['error'], 'error');
+ expect(constructedEvent.eventData['description'], 'description');
+ expect(constructedEvent.eventData.length, 3);
+ });
+
+ test('Event.devtoolsEvent constructed', () {
+ Event generateEvent() => Event.devtoolsEvent(
+ eventCategory: 'eventCategory',
+ label: 'label',
+ value: 1,
+ userInitiatedInteraction: true,
+ g3Username: 'g3Username',
+ userApp: 'userApp',
+ userBuild: 'userBuild',
+ userPlatform: 'userPlatform',
+ devtoolsPlatform: 'devtoolsPlatform',
+ devtoolsChrome: 'devtoolsChrome',
+ devtoolsVersion: 'devtoolsVersion',
+ ideLaunched: 'ideLaunched',
+ isExternalBuild: 'isExternalBuild',
+ isEmbedded: 'isEmbedded',
+ ideLaunchedFeature: 'ideLaunchedFeature',
+ isWasm: 'true',
+ uiDurationMicros: 123,
+ rasterDurationMicros: 123,
+ shaderCompilationDurationMicros: 123,
+ traceEventCount: 123,
+ cpuSampleCount: 123,
+ cpuStackDepth: 123,
+ heapDiffObjectsBefore: 123,
+ heapDiffObjectsAfter: 123,
+ heapObjectsTotal: 123,
+ rootSetCount: 123,
+ rowCount: 123,
+ inspectorTreeControllerId: 123,
+ androidAppId: 'androidAppId',
+ iosBundleId: 'iosBundleId',
+ );
+
+ final constructedEvent = generateEvent();
+
+ expect(generateEvent, returnsNormally);
+ expect(constructedEvent.eventData['eventCategory'], 'eventCategory');
+ expect(constructedEvent.eventData['label'], 'label');
+ expect(constructedEvent.eventData['value'], 1);
+ expect(constructedEvent.eventData['userInitiatedInteraction'], true);
+ expect(constructedEvent.eventData['g3Username'], 'g3Username');
+ expect(constructedEvent.eventData['userApp'], 'userApp');
+ expect(constructedEvent.eventData['userBuild'], 'userBuild');
+ expect(constructedEvent.eventData['userPlatform'], 'userPlatform');
+ expect(constructedEvent.eventData['devtoolsPlatform'], 'devtoolsPlatform');
+ expect(constructedEvent.eventData['devtoolsChrome'], 'devtoolsChrome');
+ expect(constructedEvent.eventData['devtoolsVersion'], 'devtoolsVersion');
+ expect(constructedEvent.eventData['ideLaunched'], 'ideLaunched');
+ expect(constructedEvent.eventData['isExternalBuild'], 'isExternalBuild');
+ expect(constructedEvent.eventData['isEmbedded'], 'isEmbedded');
+ expect(
+ constructedEvent.eventData['ideLaunchedFeature'], 'ideLaunchedFeature');
+ expect(constructedEvent.eventData['isWasm'], 'true');
+
+ expect(constructedEvent.eventData['uiDurationMicros'], 123);
+ expect(constructedEvent.eventData['rasterDurationMicros'], 123);
+ expect(constructedEvent.eventData['shaderCompilationDurationMicros'], 123);
+ expect(constructedEvent.eventData['traceEventCount'], 123);
+ expect(constructedEvent.eventData['cpuSampleCount'], 123);
+ expect(constructedEvent.eventData['cpuStackDepth'], 123);
+ expect(constructedEvent.eventData['heapDiffObjectsBefore'], 123);
+ expect(constructedEvent.eventData['heapDiffObjectsAfter'], 123);
+ expect(constructedEvent.eventData['heapObjectsTotal'], 123);
+ expect(constructedEvent.eventData['rootSetCount'], 123);
+ expect(constructedEvent.eventData['rowCount'], 123);
+ expect(constructedEvent.eventData['inspectorTreeControllerId'], 123);
+ expect(constructedEvent.eventData['androidAppId'], 'androidAppId');
+ expect(constructedEvent.eventData['iosBundleId'], 'iosBundleId');
+ expect(constructedEvent.eventData.length, 30);
+ });
+
+ test('Confirm all constructors were checked', () {
+ var constructorCount = 0;
+ for (final declaration in reflectClass(Event).declarations.keys) {
+ // Count public constructors but omit private constructors
+ if (declaration.toString().contains('Event.') &&
+ !declaration.toString().contains('Event._')) {
+ constructorCount++;
+ }
+ }
+
+ // Change this integer below if your PR either adds or removes
+ // an Event constructor
+ final eventsAccountedForInTests = 27;
+ expect(eventsAccountedForInTests, constructorCount,
+ reason: 'If you added or removed an event constructor, '
+ 'ensure you have updated '
+ '`pkgs/unified_analytics/test/event_test.dart` '
+ 'to reflect the changes made');
+ });
+
+ test('Serializing event to json successful', () {
+ final event = Event.analyticsException(
+ workflow: 'workflow',
+ error: 'error',
+ description: 'description',
+ );
+
+ final expectedResult = '{"eventName":"analytics_exception",'
+ '"eventData":{"workflow":"workflow",'
+ '"error":"error",'
+ '"description":"description"}}';
+
+ expect(event.toJson(), expectedResult);
+ });
+
+ test('Deserializing string to event successful', () {
+ final eventJson = '{"eventName":"analytics_exception",'
+ '"eventData":{"workflow":"workflow",'
+ '"error":"error",'
+ '"description":"description"}}';
+
+ final eventConstructed = Event.fromJson(eventJson);
+ expect(eventConstructed, isNotNull);
+ eventConstructed!;
+
+ expect(eventConstructed.eventName, DashEvent.analyticsException);
+ expect(eventConstructed.eventData, {
+ 'workflow': 'workflow',
+ 'error': 'error',
+ 'description': 'description',
+ });
+ });
+
+ test('Deserializing string to event unsuccessful for invalid eventName', () {
+ final eventJson = '{"eventName":"NOT_VALID_NAME",'
+ '"eventData":{"workflow":"workflow",'
+ '"error":"error",'
+ '"description":"description"}}';
+
+ final eventConstructed = Event.fromJson(eventJson);
+ expect(eventConstructed, isNull);
+ });
+
+ test('Deserializing string to event unsuccessful for invalid eventData', () {
+ final eventJson = '{"eventName":"analytics_exception",'
+ '"eventData": "not_valid_event_data"}';
+
+ final eventConstructed = Event.fromJson(eventJson);
+ expect(eventConstructed, isNull);
+ });
+}
diff --git a/pkgs/unified_analytics/test/events_with_fake_test.dart b/pkgs/unified_analytics/test/events_with_fake_test.dart
new file mode 100644
index 0000000..9794275
--- /dev/null
+++ b/pkgs/unified_analytics/test/events_with_fake_test.dart
@@ -0,0 +1,146 @@
+// Copyright (c) 2023, 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:clock/clock.dart';
+import 'package:file/file.dart';
+import 'package:file/memory.dart';
+import 'package:test/test.dart';
+
+import 'package:unified_analytics/src/constants.dart';
+import 'package:unified_analytics/src/enums.dart';
+import 'package:unified_analytics/src/survey_handler.dart';
+import 'package:unified_analytics/unified_analytics.dart';
+
+void main() {
+ // The fake analytics instance can be used to ensure events
+ // are being sent when invoking methods on the `Analytics` instance
+
+ late FakeAnalytics fakeAnalytics;
+ late MemoryFileSystem fs;
+ late Directory homeDirectory;
+ late File dismissedSurveyFile;
+
+ /// Survey to load into the fake instance to fetch
+ ///
+ /// The 1.0 sample rate means that this will always show
+ /// up from the method to fetch available surveys
+ final testSurvey = Survey(
+ uniqueId: 'uniqueId',
+ startDate: DateTime(2022, 1, 1),
+ endDate: DateTime(2022, 12, 31),
+ description: 'description',
+ snoozeForMinutes: 10,
+ samplingRate: 1.0, // 100% sample rate
+ excludeDashToolList: [],
+ conditionList: <Condition>[],
+ buttonList: [
+ SurveyButton(
+ buttonText: 'buttonText',
+ action: 'accept',
+ promptRemainsVisible: false,
+ ),
+ SurveyButton(
+ buttonText: 'buttonText',
+ action: 'dismiss',
+ promptRemainsVisible: false,
+ ),
+ ],
+ );
+
+ setUp(() async {
+ fs = MemoryFileSystem.test(style: FileSystemStyle.posix);
+ homeDirectory = fs.directory('home');
+ dismissedSurveyFile = homeDirectory
+ .childDirectory(kDartToolDirectoryName)
+ .childFile(kDismissedSurveyFileName);
+
+ final initialAnalytics = Analytics.fake(
+ tool: DashTool.flutterTool,
+ homeDirectory: homeDirectory,
+ dartVersion: 'dartVersion',
+ toolsMessageVersion: 1,
+ fs: fs,
+ platform: DevicePlatform.macos,
+ );
+ initialAnalytics.clientShowedMessage();
+
+ // Recreate a second instance since events cannot be sent on
+ // the first run
+ withClock(Clock.fixed(DateTime(2022, 3, 3)), () {
+ final toolsMessageVersion = kToolsMessageVersion;
+ fakeAnalytics = Analytics.fake(
+ tool: DashTool.flutterTool,
+ homeDirectory: homeDirectory,
+ dartVersion: 'dartVersion',
+ platform: DevicePlatform.macos,
+ fs: fs,
+ toolsMessageVersion: toolsMessageVersion,
+ surveyHandler: FakeSurveyHandler.fromList(
+ dismissedSurveyFile: dismissedSurveyFile,
+ initializedSurveys: [testSurvey],
+ ),
+ );
+ });
+ });
+
+ test('event sent when survey shown', () async {
+ final surveyList = await fakeAnalytics.fetchAvailableSurveys();
+ expect(surveyList.length, 1);
+ expect(fakeAnalytics.sentEvents.length, 0);
+
+ final survey = surveyList.first;
+ expect(survey.uniqueId, 'uniqueId');
+
+ // Simulate the survey being shown
+ fakeAnalytics.surveyShown(survey);
+
+ expect(fakeAnalytics.sentEvents.length, 1);
+ expect(fakeAnalytics.sentEvents.last.eventName, DashEvent.surveyShown);
+ expect(fakeAnalytics.sentEvents.last.eventData, {'surveyId': 'uniqueId'});
+ });
+
+ test('event sent when survey accepted', () async {
+ final surveyList = await fakeAnalytics.fetchAvailableSurveys();
+ expect(surveyList.length, 1);
+ expect(fakeAnalytics.sentEvents.length, 0);
+
+ final survey = surveyList.first;
+ expect(survey.uniqueId, 'uniqueId');
+
+ // Simulate the survey being shown
+ //
+ // The first button is the accept button
+ fakeAnalytics.surveyInteracted(
+ survey: survey,
+ surveyButton: survey.buttonList.first,
+ );
+
+ expect(fakeAnalytics.sentEvents.length, 1);
+ expect(fakeAnalytics.sentEvents.last.eventName, DashEvent.surveyAction);
+ expect(fakeAnalytics.sentEvents.last.eventData,
+ {'surveyId': 'uniqueId', 'status': 'accept'});
+ });
+
+ test('event sent when survey rejected', () async {
+ final surveyList = await fakeAnalytics.fetchAvailableSurveys();
+ expect(surveyList.length, 1);
+ expect(fakeAnalytics.sentEvents.length, 0);
+
+ final survey = surveyList.first;
+ expect(survey.uniqueId, 'uniqueId');
+
+ // Simulate the survey being shown
+ //
+ // The last button is the reject button
+ fakeAnalytics.surveyInteracted(
+ survey: survey,
+ surveyButton: survey.buttonList.last,
+ );
+
+ expect(fakeAnalytics.sentEvents.length, 1);
+ expect(fakeAnalytics.sentEvents.last.eventName, DashEvent.surveyAction);
+ expect(fakeAnalytics.sentEvents.last.eventData,
+ {'surveyId': 'uniqueId', 'status': 'dismiss'});
+ });
+}
diff --git a/pkgs/unified_analytics/test/legacy_analytics_test.dart b/pkgs/unified_analytics/test/legacy_analytics_test.dart
new file mode 100644
index 0000000..36acee9
--- /dev/null
+++ b/pkgs/unified_analytics/test/legacy_analytics_test.dart
@@ -0,0 +1,325 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io' as io;
+
+import 'package:file/file.dart';
+import 'package:file/memory.dart';
+import 'package:test/test.dart';
+
+import 'package:unified_analytics/src/enums.dart';
+import 'package:unified_analytics/unified_analytics.dart';
+
+void main() {
+ late MemoryFileSystem fs;
+ late Directory home;
+ late Analytics analytics;
+
+ const homeDirName = 'home';
+ const initialTool = DashTool.flutterTool;
+ const toolsMessageVersion = 1;
+ const toolsMessage = 'toolsMessage';
+ const flutterChannel = 'flutterChannel';
+ const flutterVersion = 'flutterVersion';
+ const dartVersion = 'dartVersion';
+ const platform = DevicePlatform.macos;
+
+ setUp(() {
+ // Setup the filesystem with the home directory
+ final fsStyle =
+ io.Platform.isWindows ? FileSystemStyle.windows : FileSystemStyle.posix;
+ fs = MemoryFileSystem.test(style: fsStyle);
+ home = fs.directory(homeDirName);
+ });
+
+ test('Honor legacy dart analytics opt out', () {
+ // Create the file for the dart legacy opt out
+ final dartLegacyConfigFile =
+ home.childDirectory('.dart').childFile('dartdev.json');
+ dartLegacyConfigFile.createSync(recursive: true);
+ dartLegacyConfigFile.writeAsStringSync('''
+{
+ "firstRun": false,
+ "enabled": false,
+ "disclosureShown": true,
+ "clientId": "52710e60-7c70-4335-b3a4-9d922630f12a"
+}
+''');
+
+ // The main analytics instance, other instances can be spawned within tests
+ // to test how to instances running together work
+ analytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ );
+
+ expect(analytics.telemetryEnabled, false);
+ });
+
+ test('Telemetry enabled if legacy dart analytics is enabled', () {
+ // Create the file for the dart legacy opt out
+ final dartLegacyConfigFile =
+ home.childDirectory('.dart').childFile('dartdev.json');
+ dartLegacyConfigFile.createSync(recursive: true);
+ dartLegacyConfigFile.writeAsStringSync('''
+{
+ "firstRun": false,
+ "enabled": true,
+ "disclosureShown": true,
+ "clientId": "52710e60-7c70-4335-b3a4-9d922630f12a"
+}
+''');
+
+ // The main analytics instance, other instances can be spawned within tests
+ // to test how to instances running together work
+ analytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ );
+
+ expect(analytics.telemetryEnabled, true);
+ });
+
+ test('Honor legacy flutter analytics opt out', () {
+ // Create the file for the flutter legacy opt out
+ final flutterLegacyConfigFile =
+ home.childDirectory('.dart').childFile('dartdev.json');
+ flutterLegacyConfigFile.createSync(recursive: true);
+ flutterLegacyConfigFile.writeAsStringSync('''
+{
+ "firstRun": false,
+ "clientId": "4c3a3d1e-e545-47e7-b4f8-10129f6ab169",
+ "enabled": false
+}
+''');
+
+ // The main analytics instance, other instances can be spawned within tests
+ // to test how to instances running together work
+ analytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ );
+
+ expect(analytics.telemetryEnabled, false);
+ });
+
+ test('Telemetry enabled if legacy flutter analytics is enabled', () {
+ // Create the file for the flutter legacy opt out
+ final flutterLegacyConfigFile =
+ home.childDirectory('.dart').childFile('dartdev.json');
+ flutterLegacyConfigFile.createSync(recursive: true);
+ flutterLegacyConfigFile.writeAsStringSync('''
+{
+ "firstRun": false,
+ "clientId": "4c3a3d1e-e545-47e7-b4f8-10129f6ab169",
+ "enabled": true
+}
+''');
+
+ // The main analytics instance, other instances can be spawned within tests
+ // to test how to instances running together work
+ analytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ );
+
+ expect(analytics.telemetryEnabled, true);
+ });
+
+ test('Honor legacy devtools analytics opt out', () {
+ // Create the file for the devtools legacy opt out
+ final devtoolsLegacyConfigFile =
+ home.childDirectory('.flutter-devtools').childFile('.devtools');
+ devtoolsLegacyConfigFile.createSync(recursive: true);
+ devtoolsLegacyConfigFile.writeAsStringSync('''
+{
+ "analyticsEnabled": false,
+ "isFirstRun": false,
+ "lastReleaseNotesVersion": "2.31.0",
+ "2023-Q4": {
+ "surveyActionTaken": false,
+ "surveyShownCount": 0
+ }
+}
+''');
+
+ // The main analytics instance, other instances can be spawned within tests
+ // to test how to instances running together work
+ analytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ );
+
+ expect(analytics.telemetryEnabled, false);
+ });
+
+ test('Telemetry enabled if legacy devtools analytics is enabled', () {
+ // Create the file for the devtools legacy opt out
+ final devtoolsLegacyConfigFile =
+ home.childDirectory('.flutter-devtools').childFile('.devtools');
+ devtoolsLegacyConfigFile.createSync(recursive: true);
+ devtoolsLegacyConfigFile.writeAsStringSync('''
+{
+ "analyticsEnabled": true,
+ "isFirstRun": false,
+ "lastReleaseNotesVersion": "2.31.0",
+ "2023-Q4": {
+ "surveyActionTaken": false,
+ "surveyShownCount": 0
+ }
+}
+''');
+
+ // The main analytics instance, other instances can be spawned within tests
+ // to test how to instances running together work
+ analytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ );
+
+ expect(analytics.telemetryEnabled, true);
+ });
+
+ test('Telemetry disabled if dart config file corrupted', () {
+ // Create the file for the dart legacy opt out with text that
+ // is not valid JSON
+ final dartLegacyConfigFile =
+ home.childDirectory('.dart').childFile('dartdev.json');
+ dartLegacyConfigFile.createSync(recursive: true);
+ dartLegacyConfigFile.writeAsStringSync('''
+NOT VALID JSON
+{
+ "firstRun": false,
+ "clientId": "4c3a3d1e-e545-47e7-b4f8-10129f6ab169",
+ "enabled": true
+}
+''');
+
+ // The main analytics instance, other instances can be spawned within tests
+ // to test how to instances running together work
+ analytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ );
+
+ expect(analytics.telemetryEnabled, false);
+ });
+
+ test('Telemetry disabled if devtools config file corrupted', () {
+ // Create the file for the devtools legacy opt out with text that
+ // is not valid JSON
+ final devtoolsLegacyConfigFile =
+ home.childDirectory('.flutter-devtools').childFile('.devtools');
+ devtoolsLegacyConfigFile.createSync(recursive: true);
+ devtoolsLegacyConfigFile.writeAsStringSync('''
+NOT VALID JSON
+{
+ "analyticsEnabled": true,
+ "isFirstRun": false,
+ "lastReleaseNotesVersion": "2.31.0",
+ "2023-Q4": {
+ "surveyActionTaken": false,
+ "surveyShownCount": 0
+ }
+}
+''');
+
+ // The main analytics instance, other instances can be spawned within tests
+ // to test how to instances running together work
+ analytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ );
+
+ expect(analytics.telemetryEnabled, false);
+ });
+
+ test('Telemetry disabled if flutter config file corrupted', () {
+ // Create the file for the flutter legacy opt out with text that
+ // is not valid JSON
+ final fluttterLegacyConfigFile =
+ home.childDirectory('.dart').childFile('dartdev.json');
+ fluttterLegacyConfigFile.createSync(recursive: true);
+ fluttterLegacyConfigFile.writeAsStringSync('''
+NOT VALID JSON
+{
+ "firstRun": false,
+ "clientId": "4c3a3d1e-e545-47e7-b4f8-10129f6ab169",
+ "enabled": true
+}
+''');
+
+ // The main analytics instance, other instances can be spawned within tests
+ // to test how to instances running together work
+ analytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ );
+
+ expect(analytics.telemetryEnabled, false);
+ });
+}
diff --git a/pkgs/unified_analytics/test/log_handler_test.dart b/pkgs/unified_analytics/test/log_handler_test.dart
new file mode 100644
index 0000000..db14d96
--- /dev/null
+++ b/pkgs/unified_analytics/test/log_handler_test.dart
@@ -0,0 +1,381 @@
+// Copyright (c) 2023, 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 'package:file/file.dart';
+import 'package:file/memory.dart';
+import 'package:test/fake.dart';
+import 'package:test/test.dart';
+
+import 'package:unified_analytics/src/constants.dart';
+import 'package:unified_analytics/src/enums.dart';
+import 'package:unified_analytics/src/log_handler.dart';
+import 'package:unified_analytics/src/utils.dart';
+import 'package:unified_analytics/unified_analytics.dart';
+
+void main() {
+ late FakeAnalytics analytics;
+ late Directory homeDirectory;
+ late MemoryFileSystem fs;
+ late File logFile;
+
+ final testEvent = Event.hotReloadTime(timeMs: 10);
+
+ setUp(() {
+ fs = MemoryFileSystem.test(style: FileSystemStyle.posix);
+ homeDirectory = fs.directory('home');
+ logFile = homeDirectory
+ .childDirectory(kDartToolDirectoryName)
+ .childFile(kLogFileName);
+
+ // Create the initialization analytics instance to onboard the tool
+ final initializationAnalytics = Analytics.fake(
+ tool: DashTool.flutterTool,
+ homeDirectory: homeDirectory,
+ dartVersion: 'dartVersion',
+ fs: fs,
+ platform: DevicePlatform.macos,
+ );
+ initializationAnalytics.clientShowedMessage();
+
+ // This instance is free to send events since the instance above
+ // has confirmed that the client has shown the message
+ analytics = Analytics.fake(
+ tool: DashTool.flutterTool,
+ homeDirectory: homeDirectory,
+ dartVersion: 'dartVersion',
+ fs: fs,
+ platform: DevicePlatform.macos,
+ );
+ });
+
+ test('Ensure that log file is created', () {
+ expect(logFile.existsSync(), true);
+ });
+
+ test('LogFileStats is null before events are sent', () {
+ expect(analytics.logFileStats(), isNull);
+ });
+
+ test('LogFileStats returns valid response after sent events', () async {
+ final countOfEventsToSend = 10;
+
+ for (var i = 0; i < countOfEventsToSend; i++) {
+ analytics.send(testEvent);
+ }
+
+ expect(analytics.logFileStats(), isNotNull);
+ expect(logFile.readAsLinesSync().length, countOfEventsToSend);
+ expect(analytics.logFileStats()!.recordCount, countOfEventsToSend);
+ });
+
+ test('The only record in the log file is malformed', () async {
+ // Write invalid json for the only log record
+ logFile.writeAsStringSync('{{\n');
+
+ expect(logFile.readAsLinesSync().length, 1);
+ final logFileStats = analytics.logFileStats();
+ expect(logFileStats, isNull,
+ reason: 'Null should be returned since only '
+ 'one record is in there and it is malformed');
+
+ analytics.sendPendingErrorEvents();
+ expect(
+ analytics.sentEvents,
+ contains(
+ Event.analyticsException(
+ workflow: 'LogFileStats.logFileStats',
+ error: 'FormatException',
+ description: 'message: Unexpected character\nsource: {{',
+ ),
+ ));
+ });
+
+ test('The first record is malformed, but rest are valid', () async {
+ // Write invalid json for the only log record
+ logFile.writeAsStringSync('{{\n');
+
+ final countOfEventsToSend = 10;
+
+ for (var i = 0; i < countOfEventsToSend; i++) {
+ analytics.send(testEvent);
+ }
+ expect(logFile.readAsLinesSync().length, countOfEventsToSend + 1);
+ final logFileStats = analytics.logFileStats();
+
+ expect(logFileStats, isNotNull);
+ expect(logFileStats!.recordCount, countOfEventsToSend);
+ });
+
+ test('Several records are malformed', () async {
+ final countOfMalformedRecords = 4;
+ for (var i = 0; i < countOfMalformedRecords; i++) {
+ final currentContents = logFile.readAsStringSync();
+ logFile.writeAsStringSync('$currentContents{{\n');
+ }
+
+ final countOfEventsToSend = 10;
+
+ for (var i = 0; i < countOfEventsToSend; i++) {
+ analytics.send(testEvent);
+ }
+
+ expect(logFile.readAsLinesSync().length,
+ countOfEventsToSend + countOfMalformedRecords);
+ final logFileStats = analytics.logFileStats();
+
+ analytics.sendPendingErrorEvents();
+ expect(logFile.readAsLinesSync().length,
+ countOfEventsToSend + countOfMalformedRecords + 1,
+ reason:
+ 'There should have been on error event sent when getting stats');
+
+ expect(logFileStats, isNotNull);
+ expect(logFileStats!.recordCount, countOfEventsToSend);
+ });
+
+ test('Valid json but invalid keys', () {
+ // The second line here is missing the "events" top level
+ // key which should cause an error for that record only
+ //
+ // Important to note that this won't actually cause a FormatException
+ // like the other malformed records, instead the LogItem.fromRecord
+ // constructor will return null if all the keys are not available
+ final contents = '''
+{"client_id":"ffcea97b-db5e-4c66-98c2-3942de4fac40","events":[{"name":"hot_reload_time","params":{"timeMs":136}}],"user_properties":{"session_id":{"value":1699385899950},"flutter_channel":{"value":"ey-test-channel"},"host":{"value":"macOS"},"flutter_version":{"value":"Flutter 3.6.0-7.0.pre.47"},"dart_version":{"value":"Dart 2.19.0"},"analytics_pkg_version":{"value":"5.2.0"},"tool":{"value":"flutter-tool"},"local_time":{"value":"2023-11-07 15:37:26.685761 -0500"},"host_os_version":{"value":"Version 14.1 (Build 23B74)"},"locale":{"value":"en"},"client_ide":{"value":"VSCode"}}}
+{"client_id":"ffcea97b-db5e-4c66-98c2-3942de4fac40","WRONG_EVENT_KEY":[{"name":"hot_reload_time","params":{"timeMs":136}}],"user_properties":{"session_id":{"value":1699385899950},"flutter_channel":{"value":"ey-test-channel"},"host":{"value":"macOS"},"flutter_version":{"value":"Flutter 3.6.0-7.0.pre.47"},"dart_version":{"value":"Dart 2.19.0"},"analytics_pkg_version":{"value":"5.2.0"},"tool":{"value":"flutter-tool"},"local_time":{"value":"2023-11-07 15:37:26.685761 -0500"},"host_os_version":{"value":"Version 14.1 (Build 23B74)"},"locale":{"value":"en"},"client_ide":{"value":"VSCode"}}}
+{"client_id":"ffcea97b-db5e-4c66-98c2-3942de4fac40","events":[{"name":"hot_reload_time","params":{"timeMs":136}}],"user_properties":{"session_id":{"value":1699385899950},"flutter_channel":{"value":"ey-test-channel"},"host":{"value":"macOS"},"flutter_version":{"value":"Flutter 3.6.0-7.0.pre.47"},"dart_version":{"value":"Dart 2.19.0"},"analytics_pkg_version":{"value":"5.2.0"},"tool":{"value":"flutter-tool"},"local_time":{"value":"2023-11-07 15:37:26.685761 -0500"},"host_os_version":{"value":"Version 14.1 (Build 23B74)"},"locale":{"value":"en"},"client_ide":{"value":"VSCode"}}}
+''';
+ logFile.writeAsStringSync(contents);
+
+ final logFileStats = analytics.logFileStats();
+
+ expect(logFile.readAsLinesSync().length, 3);
+ expect(logFileStats, isNotNull);
+ expect(logFileStats!.recordCount, 2);
+ });
+
+ test('Malformed record gets phased out after several events', () async {
+ // Write invalid json for the only log record
+ logFile.writeAsStringSync('{{\n');
+
+ // Send the max number of events minus two so that we have
+ // one malformed record on top of the logs and the rest
+ // are valid log records
+ //
+ // We need to account for the event that is sent when
+ // calling [logFileStats()] fails and sends an instance
+ // of [Event.analyticsException]
+ final recordsToSendInitially = kLogFileLength - 2;
+ for (var i = 0; i < recordsToSendInitially; i++) {
+ analytics.send(testEvent);
+ }
+ final logFileStats = analytics.logFileStats();
+ analytics.sendPendingErrorEvents();
+ expect(analytics.sentEvents.last.eventName, DashEvent.analyticsException,
+ reason: 'Calling for the stats should have caused an error');
+ expect(logFile.readAsLinesSync().length, kLogFileLength);
+ expect(logFileStats, isNotNull);
+ expect(logFileStats!.recordCount, recordsToSendInitially,
+ reason: 'The first record should be malformed');
+ expect(logFile.readAsLinesSync()[0].trim(), '{{');
+
+ // Sending one more event should flush out the malformed record
+ analytics.send(testEvent);
+
+ final secondLogFileStats = analytics.logFileStats();
+ expect(analytics.sentEvents.last, testEvent);
+ expect(secondLogFileStats, isNotNull);
+ expect(secondLogFileStats!.recordCount, kLogFileLength);
+ expect(logFile.readAsLinesSync()[0].trim(), isNot('{{'));
+ });
+
+ test(
+ 'Catches and discards any FileSystemException raised from attempting '
+ 'to write to the log file', () async {
+ final logFilePath = 'log.txt';
+ final fs = MemoryFileSystem.test(opHandle: (context, operation) {
+ if (context == logFilePath && operation == FileSystemOp.write) {
+ throw FileSystemException(
+ 'writeFrom failed',
+ logFilePath,
+ const OSError('No space left on device', 28),
+ );
+ }
+ });
+ final logFile = fs.file(logFilePath);
+ logFile.createSync();
+ final logHandler = LogHandler(logFile: logFile);
+
+ logHandler.save(data: {});
+ });
+
+ test('deletes log file larger than kMaxLogFileSize', () async {
+ var deletedLargeLogFile = false;
+ var wroteDataToLogFile = false;
+ const data = <String, Object?>{};
+ final logFile = _FakeFile('log.txt')
+ .._deleteSyncImpl = (() => deletedLargeLogFile = true)
+ .._createSyncImpl = () {}
+ .._statSyncImpl = (() => _FakeFileStat(kMaxLogFileSize + 1))
+ .._writeAsStringSync = (contents, {mode = FileMode.append}) {
+ expect(contents.trim(), data.toString());
+ expect(mode, FileMode.writeOnlyAppend);
+ wroteDataToLogFile = true;
+ };
+ final logHandler = LogHandler(logFile: logFile);
+
+ logHandler.save(data: data);
+ expect(deletedLargeLogFile, isTrue);
+ expect(wroteDataToLogFile, isTrue);
+ });
+
+ test('does not delete log file if smaller than kMaxLogFileSize', () async {
+ var wroteDataToLogFile = false;
+ const data = <String, Object?>{};
+ final logFile = _FakeFile('log.txt')
+ .._deleteSyncImpl =
+ (() => fail('called logFile.deleteSync() when file was less than '
+ 'kMaxLogFileSize'))
+ .._createSyncImpl = () {}
+ .._readAsLinesSyncImpl = (() => ['three', 'previous', 'lines'])
+ .._statSyncImpl = (() => _FakeFileStat(kMaxLogFileSize - 1))
+ .._writeAsStringSync = (contents, {mode = FileMode.append}) {
+ expect(contents.trim(), data.toString());
+ expect(mode, FileMode.writeOnlyAppend);
+ wroteDataToLogFile = true;
+ };
+ final logHandler = LogHandler(logFile: logFile);
+
+ logHandler.save(data: data);
+ expect(wroteDataToLogFile, isTrue);
+ });
+
+ test('Catching cast errors for each log record silently', () async {
+ // Write a json array to the log file which will cause
+ // a cast error when parsing each line
+ logFile.writeAsStringSync('[{}, 1, 2, 3]\n');
+
+ final logFileStats = analytics.logFileStats();
+ expect(logFileStats, isNull);
+
+ // Ensure it will work as expected after writing correct logs
+ final countOfEventsToSend = 10;
+ for (var i = 0; i < countOfEventsToSend; i++) {
+ analytics.send(testEvent);
+ }
+ analytics.sendPendingErrorEvents();
+ final secondLogFileStats = analytics.logFileStats();
+
+ expect(secondLogFileStats, isNotNull);
+ expect(secondLogFileStats!.recordCount, countOfEventsToSend + 1,
+ reason: 'Plus one for the error event that is sent '
+ 'from the first logFileStats call');
+ });
+
+ test(
+ 'truncateStringToLength returns same string when '
+ 'max length greater than string length', () {
+ final testString = 'Version 14.1 (Build 23B74)';
+ final maxLength = 100;
+
+ expect(testString.length < maxLength, true);
+
+ String runTruncateString() => truncateStringToLength(testString, maxLength);
+
+ expect(runTruncateString, returnsNormally);
+
+ final newString = runTruncateString();
+ expect(newString, testString);
+ });
+
+ test(
+ 'truncateStringToLength returns truncated string when '
+ 'max length less than string length', () {
+ final testString = 'Version 14.1 (Build 23B74)';
+ final maxLength = 10;
+
+ expect(testString.length > maxLength, true);
+
+ String runTruncateString() => truncateStringToLength(testString, maxLength);
+
+ expect(runTruncateString, returnsNormally);
+
+ final newString = runTruncateString();
+ expect(newString.length, maxLength);
+ expect(newString, 'Version 14');
+ });
+
+ test('truncateStringToLength handle errors for invalid max length', () {
+ final testString = 'Version 14.1 (Build 23B74)';
+ var maxLength = 0;
+ String runTruncateString() => truncateStringToLength(testString, maxLength);
+
+ expect(runTruncateString, throwsArgumentError);
+
+ maxLength = -1;
+ expect(runTruncateString, throwsArgumentError);
+ });
+
+ test('truncateStringToLength same string when max length is the same', () {
+ final testString = 'Version 14.1 (Build 23B74)';
+ final maxLength = testString.length;
+
+ String runTruncateString() => truncateStringToLength(testString, maxLength);
+ expect(runTruncateString, returnsNormally);
+
+ final newString = runTruncateString();
+ expect(newString.length, maxLength);
+ expect(newString, testString);
+ });
+}
+
+class _FakeFileStat extends Fake implements FileStat {
+ _FakeFileStat(this.size);
+
+ @override
+ final int size;
+}
+
+class _FakeFile extends Fake implements File {
+ _FakeFile(this.path);
+
+ List<String> Function()? _readAsLinesSyncImpl;
+
+ @override
+ List<String> readAsLinesSync({Encoding encoding = utf8}) =>
+ _readAsLinesSyncImpl!();
+
+ @override
+ final String path;
+
+ FileStat Function()? _statSyncImpl;
+
+ @override
+ FileStat statSync() => _statSyncImpl!();
+
+ void Function()? _deleteSyncImpl;
+
+ @override
+ void deleteSync({bool recursive = false}) => _deleteSyncImpl!();
+
+ void Function()? _createSyncImpl;
+
+ @override
+ void createSync({bool recursive = false, bool exclusive = false}) {
+ return _createSyncImpl!();
+ }
+
+ void Function(String contents, {FileMode mode})? _writeAsStringSync;
+
+ @override
+ void writeAsStringSync(
+ String contents, {
+ FileMode mode = FileMode.write,
+ Encoding encoding = utf8,
+ bool flush = false,
+ }) =>
+ _writeAsStringSync!(contents, mode: mode);
+}
diff --git a/pkgs/unified_analytics/test/no_op_analytics_test.dart b/pkgs/unified_analytics/test/no_op_analytics_test.dart
new file mode 100644
index 0000000..66c1ef6
--- /dev/null
+++ b/pkgs/unified_analytics/test/no_op_analytics_test.dart
@@ -0,0 +1,103 @@
+// Copyright (c) 2023, 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:file/file.dart';
+import 'package:test/fake.dart';
+import 'package:test/test.dart';
+
+import 'package:unified_analytics/src/utils.dart';
+import 'package:unified_analytics/unified_analytics.dart';
+
+void main() {
+ final testEvent = Event.hotReloadTime(timeMs: 50);
+
+ test('NoOpAnalytics.telemetryEnabled is always false', () async {
+ final analytics = const NoOpAnalytics();
+
+ expect(analytics.telemetryEnabled, isFalse);
+ await analytics.setTelemetry(true);
+ expect(analytics.telemetryEnabled, isFalse);
+ });
+
+ test('NoOpAnalytics.shouldShowMessage is always false', () async {
+ final analytics = const NoOpAnalytics();
+
+ expect(analytics.shouldShowMessage, isFalse);
+ analytics.clientShowedMessage();
+ expect(analytics.shouldShowMessage, isFalse);
+ });
+
+ test('NoOpAnalytics.sendEvent() always returns null', () async {
+ final analytics = const NoOpAnalytics();
+
+ await analytics.setTelemetry(true);
+ analytics.clientShowedMessage();
+ expect(
+ analytics.send(testEvent),
+ isNull,
+ );
+ });
+
+ test('NoOpAnalytics.logFileStats() always returns null', () async {
+ final analytics = const NoOpAnalytics();
+
+ expect(analytics.logFileStats(), isNull);
+
+ await analytics.setTelemetry(true);
+ analytics.clientShowedMessage();
+ await analytics.send(testEvent);
+
+ expect(analytics.logFileStats(), isNull);
+ });
+
+ test('Home directory without write permissions', () {
+ final home = FakeDirectory(writeEnabled: false);
+
+ expect(checkDirectoryForWritePermissions(home), false);
+ });
+
+ test('Home directory with write permissions', () {
+ final home = FakeDirectory(writeEnabled: true);
+
+ expect(checkDirectoryForWritePermissions(home), true);
+ });
+
+ test('Fetching the client id', () {
+ final analytics = const NoOpAnalytics();
+ expect(analytics.clientId, 'xxxx-xxxx');
+ });
+}
+
+class FakeDirectory extends Fake implements Directory {
+ final String _fakeModeString;
+
+ /// This fake directory class allows you to pass the permissions for
+ /// the user level, the group and global permissions will default to
+ /// being denied as indicated by the last 6 characters in the mode string.
+ FakeDirectory({
+ required bool writeEnabled,
+ bool readEnabled = true,
+ bool executeEnabled = true,
+ }) : _fakeModeString = '${readEnabled ? "r" : "-"}'
+ '${writeEnabled ? "w" : "-"}'
+ '${executeEnabled ? "x" : "-"}'
+ '------' {
+ assert(_fakeModeString.length == 9);
+ }
+
+ @override
+ bool existsSync() => true;
+
+ @override
+ FileStat statSync() => FakeFileStat(_fakeModeString);
+}
+
+class FakeFileStat extends Fake implements FileStat {
+ final String _fakeModeString;
+
+ FakeFileStat(this._fakeModeString);
+
+ @override
+ String modeString() => _fakeModeString;
+}
diff --git a/pkgs/unified_analytics/test/suppression_test.dart b/pkgs/unified_analytics/test/suppression_test.dart
new file mode 100644
index 0000000..05fab15
--- /dev/null
+++ b/pkgs/unified_analytics/test/suppression_test.dart
@@ -0,0 +1,132 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io' as io;
+
+import 'package:file/file.dart';
+import 'package:file/memory.dart';
+import 'package:test/test.dart';
+import 'package:unified_analytics/src/enums.dart';
+import 'package:unified_analytics/unified_analytics.dart';
+
+void main() {
+ late MemoryFileSystem fs;
+ late Directory home;
+ late Analytics initializationAnalytics;
+ late Analytics analytics;
+
+ const homeDirName = 'home';
+ const initialTool = DashTool.flutterTool;
+ const toolsMessageVersion = 1;
+ const toolsMessage = 'toolsMessage';
+ const flutterChannel = 'flutterChannel';
+ const flutterVersion = 'flutterVersion';
+ const dartVersion = 'dartVersion';
+ const platform = DevicePlatform.macos;
+
+ final testEvent = Event.hotReloadTime(timeMs: 50);
+
+ setUp(() {
+ // Setup the filesystem with the home directory
+ final fsStyle =
+ io.Platform.isWindows ? FileSystemStyle.windows : FileSystemStyle.posix;
+ fs = MemoryFileSystem.test(style: fsStyle);
+ home = fs.directory(homeDirName);
+
+ // This is the first analytics instance that will be used to demonstrate
+ // that events will not be sent with the first run of analytics
+ initializationAnalytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ );
+ initializationAnalytics.clientShowedMessage();
+
+ // The main analytics instance, other instances can be spawned within tests
+ // to test how to instances running together work
+ //
+ // This instance should have the same parameters as the one above for
+ // [initializationAnalytics]
+ analytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ );
+ analytics.clientShowedMessage();
+ });
+
+ test('Suppression works as expected', () async {
+ analytics.suppressTelemetry();
+ analytics.send(testEvent);
+
+ final logFileStats = analytics.logFileStats();
+
+ expect(logFileStats, isNull,
+ reason: 'Returns null because no records have been recorded');
+ });
+
+ test('Second instance is not suppressed', () async {
+ analytics.suppressTelemetry();
+ analytics.send(testEvent);
+
+ final logFileStats = analytics.logFileStats();
+
+ expect(logFileStats, isNull,
+ reason: 'Returns null because no records have been recorded');
+
+ // The newly created instance will not be suppressed
+ final secondAnalytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ );
+
+ // Using a new event here to differentiate from the first one
+ final newEvent = Event.commandExecuted(count: 2, name: 'commandName');
+ secondAnalytics.send(newEvent);
+
+ // Both instances of `Analytics` should now have data retrieved
+ // from `LogFileStats()` even though only the second instance
+ // was the instance to send an event
+ final secondLogFileStats = analytics.logFileStats()!;
+ final thirdLogFileStats = secondAnalytics.logFileStats()!;
+
+ // Series of checks for each parameter in logFileStats
+ expect(secondLogFileStats.startDateTime, thirdLogFileStats.startDateTime);
+ expect(secondLogFileStats.minsFromStartDateTime,
+ thirdLogFileStats.minsFromStartDateTime);
+ expect(secondLogFileStats.endDateTime, thirdLogFileStats.endDateTime);
+ expect(secondLogFileStats.minsFromEndDateTime,
+ thirdLogFileStats.minsFromEndDateTime);
+ expect(secondLogFileStats.sessionCount, thirdLogFileStats.sessionCount);
+ expect(secondLogFileStats.flutterChannelCount,
+ thirdLogFileStats.flutterChannelCount);
+ expect(secondLogFileStats.toolCount, thirdLogFileStats.toolCount);
+ expect(secondLogFileStats.recordCount, thirdLogFileStats.recordCount);
+ expect(secondLogFileStats.eventCount, thirdLogFileStats.eventCount);
+
+ // Ensure the correct data is in the object
+ expect(secondLogFileStats.eventCount.containsKey(newEvent.eventName.label),
+ true);
+ expect(secondLogFileStats.eventCount[newEvent.eventName.label], 1);
+ });
+}
diff --git a/pkgs/unified_analytics/test/survey_handler_test.dart b/pkgs/unified_analytics/test/survey_handler_test.dart
new file mode 100644
index 0000000..3d8c8dd
--- /dev/null
+++ b/pkgs/unified_analytics/test/survey_handler_test.dart
@@ -0,0 +1,1229 @@
+// Copyright (c) 2023, 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 'package:clock/clock.dart';
+import 'package:file/file.dart';
+import 'package:file/memory.dart';
+import 'package:test/test.dart';
+
+import 'package:unified_analytics/src/constants.dart';
+import 'package:unified_analytics/src/enums.dart';
+import 'package:unified_analytics/src/survey_handler.dart';
+import 'package:unified_analytics/src/utils.dart';
+import 'package:unified_analytics/unified_analytics.dart';
+
+void main() {
+ final testEvent = Event.hotReloadTime(timeMs: 10);
+
+ group('Unit testing function sampleRate:', () {
+ // Set a string that can be used in place of a survey's unique ID
+ final iterations = 1000;
+ final uuid = Uuid(123);
+ final uniqueSurveyId = uuid.generateV4();
+
+ // Set how much the actual sampled rate can be (allowing 5% of variability)
+ final marginOfError = 0.05;
+
+ test('Unit testing the sampleRate method', () {
+ // These strings had a predetermined output from the utility function
+ final string1 = 'string1';
+ final string2 = 'string2';
+ expect(sampleRate(string1, string2), 0.40);
+ });
+
+ test('Simulating with various sample rates', () {
+ final sampleRateToTestList = [
+ 0.10,
+ 0.25,
+ 0.50,
+ 0.75,
+ 0.80,
+ 0.95,
+ ];
+ for (final sampleRateToTest in sampleRateToTestList) {
+ var count = 0;
+ for (var i = 0; i < iterations; i++) {
+ // Regenerate the client id to simulate a unique user
+ final generatedClientId = uuid.generateV4();
+ if (sampleRate(uniqueSurveyId, generatedClientId) <=
+ sampleRateToTest) {
+ count += 1;
+ }
+ }
+
+ final actualSampledRate = count / iterations;
+ final actualMarginOfError =
+ (sampleRateToTest - actualSampledRate).abs();
+
+ expect(actualMarginOfError < marginOfError, true,
+ reason: 'Failed on sample rate = $sampleRateToTest with'
+ ' actual rate $actualMarginOfError '
+ 'and a margin of error = $marginOfError');
+ }
+ });
+ });
+
+ group('Unit testing function checkSurveyDate:', () {
+ final date = DateTime(2023, 5, 1);
+ // Two surveys created, one that is within the survey date
+ // range, and one that is not
+ final validSurvey = Survey(
+ uniqueId: 'uniqueId',
+ startDate: DateTime(2023, 1, 1),
+ endDate: DateTime(2023, 12, 31),
+ description: 'description',
+ snoozeForMinutes: 10,
+ samplingRate: 1.0,
+ excludeDashToolList: [],
+ conditionList: <Condition>[],
+ buttonList: [],
+ );
+ final invalidSurvey = Survey(
+ uniqueId: 'uniqueId',
+ startDate: DateTime(2022, 1, 1),
+ endDate: DateTime(2022, 12, 31),
+ description: 'description',
+ snoozeForMinutes: 10,
+ samplingRate: 1.0,
+ excludeDashToolList: [],
+ conditionList: <Condition>[],
+ buttonList: [],
+ );
+
+ test('expired survey', () {
+ final clock = Clock.fixed(date);
+ withClock(clock, () {
+ expect(SurveyHandler.checkSurveyDate(invalidSurvey), false);
+ });
+ });
+
+ test('valid survey', () {
+ final clock = Clock.fixed(date);
+ withClock(clock, () {
+ expect(SurveyHandler.checkSurveyDate(validSurvey), true);
+ });
+ });
+ });
+
+ group('Unit testing function parseSurveysFromJson', () {
+ final validContents = '''
+[
+ {
+ "uniqueId": "xxxxx",
+ "startDate": "2023-06-01T09:00:00-07:00",
+ "endDate": "2023-06-30T09:00:00-07:00",
+ "description": "xxxxxxx",
+ "snoozeForMinutes": "10",
+ "samplingRate": "1.0",
+ "excludeDashTools": [],
+ "conditions": [
+ {
+ "field": "logFileStats.recordCount",
+ "operator": ">=",
+ "value": 1000
+ },
+ {
+ "field": "logFileStats.toolCount.flutter-tool",
+ "operator": "<",
+ "value": 3
+ }
+ ],
+ "buttons": [
+ {
+ "buttonText": "Take Survey",
+ "action": "accept",
+ "url": "https://google.qualtrics.com/jfe/form/SV_5gsB2EuG324y2",
+ "promptRemainsVisible": false
+ }
+ ]
+ }
+]
+''';
+
+ // The value for the condition is not a valid integer
+ final invalidConditionValueContents = '''
+[
+ {
+ "uniqueId": "xxxxx",
+ "startDate": "2023-06-01T09:00:00-07:00",
+ "endDate": "2023-06-30T09:00:00-07:00",
+ "description": "xxxxxxx",
+ "snoozeForMinutes": "10",
+ "samplingRate": "1.0",
+ "excludeDashTools": [],
+ "conditions": [
+ {
+ "field": "logFileStats.recordCount",
+ "operator": ">=",
+ "value": "1000xxxx"
+ }
+ ],
+ "buttons": [
+ {
+ "buttonText": "Take Survey",
+ "action": "accept",
+ "url": "https://google.qualtrics.com/jfe/form/SV_5gsB2EuG324y2",
+ "promptRemainsVisible": false
+ }
+ ]
+ }
+]
+''';
+
+ // Using a dash tool in the excludeDashTools array that is not a valid
+ // DashTool label
+ final invalidDashToolContents = '''
+[
+ {
+ "uniqueId": "xxxxx",
+ "startDate": "2023-06-01T09:00:00-07:00",
+ "endDate": "2023-06-30T09:00:00-07:00",
+ "description": "xxxxxxx",
+ "snoozeForMinutes": "10",
+ "samplingRate": "1.0",
+ "excludeDashTools": [
+ "not-a-valid-dash-tool"
+ ],
+ "conditions": [
+ {
+ "field": "logFileStats.recordCount",
+ "operator": ">=",
+ "value": 1000
+ },
+ {
+ "field": "logFileStats.toolCount.flutter-tool",
+ "operator": "<",
+ "value": 3
+ }
+ ],
+ "buttons": [
+ {
+ "buttonText": "Take Survey",
+ "action": "accept",
+ "url": "https://google.qualtrics.com/jfe/form/SV_5gsB2EuG324y2",
+ "promptRemainsVisible": false
+ }
+ ]
+ }
+]
+''';
+
+ test('valid json', () {
+ withClock(Clock.fixed(DateTime(2023, 6, 15)), () {
+ final parsedSurveys = SurveyHandler.parseSurveysFromJson(
+ jsonDecode(validContents) as List);
+
+ expect(parsedSurveys.length, 1);
+ expect(parsedSurveys.first.conditionList.length, 2);
+
+ final firstCondition = parsedSurveys.first.conditionList.first;
+ final secondCondition = parsedSurveys.first.conditionList[1];
+
+ expect(firstCondition.field, 'logFileStats.recordCount');
+ expect(firstCondition.operatorString, '>=');
+ expect(firstCondition.value, 1000);
+
+ expect(secondCondition.field, 'logFileStats.toolCount.flutter-tool');
+ expect(secondCondition.operatorString, '<');
+ expect(secondCondition.value, 3);
+
+ expect(parsedSurveys.first.buttonList.length, 1);
+ expect(
+ parsedSurveys.first.buttonList.first.promptRemainsVisible, false);
+ });
+ });
+
+ test('invalid condition json', () {
+ withClock(Clock.fixed(DateTime(2023, 6, 15)), () {
+ final parsedSurveys = SurveyHandler.parseSurveysFromJson(
+ jsonDecode(invalidConditionValueContents) as List);
+
+ expect(parsedSurveys.length, 0,
+ reason: 'The condition value is not a '
+ 'proper integer so it should error returning no surveys');
+ });
+ });
+
+ test('invalid dash tool json', () {
+ withClock(Clock.fixed(DateTime(2023, 6, 15)), () {
+ final parsedSurveys = SurveyHandler.parseSurveysFromJson(
+ jsonDecode(invalidDashToolContents) as List);
+
+ expect(parsedSurveys.length, 0,
+ reason: 'The dash tool in the exclude array is not valid '
+ 'so it should error returning no surveys');
+ });
+ });
+ });
+
+ group('Testing with FakeSurveyHandler', () {
+ late Analytics analytics;
+ late Directory homeDirectory;
+ late MemoryFileSystem fs;
+ late File clientIdFile;
+ late File dismissedSurveyFile;
+
+ setUp(() {
+ fs = MemoryFileSystem.test(style: FileSystemStyle.posix);
+ homeDirectory = fs.directory('home');
+
+ // Write the client ID file out so that we don't get
+ // a randomly assigned id for this test generated within
+ // the analytics constructor
+ clientIdFile = homeDirectory
+ .childDirectory(kDartToolDirectoryName)
+ .childFile(kClientIdFileName);
+ clientIdFile.createSync(recursive: true);
+ clientIdFile.writeAsStringSync('string1');
+
+ // Assign the json file that will hold the persisted surveys
+ dismissedSurveyFile = homeDirectory
+ .childDirectory(kDartToolDirectoryName)
+ .childFile(kDismissedSurveyFileName);
+
+ // Setup two tools to be onboarded with this package so
+ // that we can simulate two different tools interacting with
+ // surveys
+ //
+ // This is especially useful when testing the "excludeDashTools" array
+ // to prevent certain tools from getting a survey from this package
+ final initialAnalyticsFlutter = Analytics.fake(
+ tool: DashTool.flutterTool,
+ homeDirectory: homeDirectory,
+ dartVersion: 'dartVersion',
+ fs: fs,
+ platform: DevicePlatform.macos,
+ );
+ final initialAnalyticsDart = Analytics.fake(
+ tool: DashTool.dartTool,
+ homeDirectory: homeDirectory,
+ dartVersion: 'dartVersion',
+ fs: fs,
+ platform: DevicePlatform.macos,
+ );
+ initialAnalyticsFlutter.clientShowedMessage();
+ initialAnalyticsDart.clientShowedMessage();
+ });
+
+ test('returns valid survey', () async {
+ await withClock(Clock.fixed(DateTime(2023, 3, 3)), () async {
+ analytics = Analytics.fake(
+ tool: DashTool.flutterTool,
+ homeDirectory: homeDirectory,
+ dartVersion: 'dartVersion',
+ fs: fs,
+ platform: DevicePlatform.macos,
+ surveyHandler: FakeSurveyHandler.fromList(
+ dismissedSurveyFile: dismissedSurveyFile,
+ initializedSurveys: <Survey>[
+ Survey(
+ uniqueId: 'uniqueId',
+ startDate: DateTime(2023, 1, 1),
+ endDate: DateTime(2023, 12, 31),
+ description: 'description',
+ snoozeForMinutes: 10,
+ samplingRate: 1.0,
+ excludeDashToolList: [],
+ conditionList: <Condition>[
+ Condition('logFileStats.recordCount', '>=', 50),
+ Condition('logFileStats.toolCount.flutter-tool', '>', 0),
+ ],
+ buttonList: [
+ SurveyButton(
+ buttonText: 'buttonText',
+ action: 'accept',
+ url: 'http://example.com',
+ promptRemainsVisible: false,
+ ),
+ ],
+ ),
+ ],
+ ),
+ );
+
+ // Simulate 60 events to send so that the first condition is satisified
+ for (var i = 0; i < 60; i++) {
+ analytics.send(testEvent);
+ }
+
+ final fetchedSurveys = await analytics.fetchAvailableSurveys();
+
+ expect(fetchedSurveys.length, 1);
+
+ final survey = fetchedSurveys.first;
+ expect(survey.conditionList.length, 2);
+ expect(survey.buttonList.length, 1);
+ });
+ });
+
+ test('does not return expired survey', () async {
+ await withClock(Clock.fixed(DateTime(2023, 3, 3)), () async {
+ analytics = Analytics.fake(
+ tool: DashTool.flutterTool,
+ homeDirectory: homeDirectory,
+ dartVersion: 'dartVersion',
+ fs: fs,
+ platform: DevicePlatform.macos,
+ surveyHandler: FakeSurveyHandler.fromList(
+ dismissedSurveyFile: dismissedSurveyFile,
+ initializedSurveys: <Survey>[
+ Survey(
+ uniqueId: 'uniqueId',
+ startDate: DateTime(2022, 1, 1),
+ endDate: DateTime(2022, 12, 31),
+ description: 'description',
+ snoozeForMinutes: 10,
+ samplingRate: 1.0,
+ excludeDashToolList: [],
+ conditionList: <Condition>[
+ Condition('logFileStats.recordCount', '>=', 50),
+ Condition('logFileStats.toolCount.flutter-tool', '>', 0),
+ ],
+ buttonList: [],
+ ),
+ ],
+ ),
+ );
+
+ // Simulate 60 events to send so that the first condition is satisified
+ for (var i = 0; i < 60; i++) {
+ analytics.send(testEvent);
+ }
+
+ final fetchedSurveys = await analytics.fetchAvailableSurveys();
+
+ expect(fetchedSurveys.length, 0);
+ });
+ });
+
+ test('does not return survey if opted out of telemetry', () async {
+ await withClock(Clock.fixed(DateTime(2023, 3, 3)), () async {
+ analytics = Analytics.fake(
+ tool: DashTool.flutterTool,
+ homeDirectory: homeDirectory,
+ dartVersion: 'dartVersion',
+ fs: fs,
+ platform: DevicePlatform.macos,
+ surveyHandler: FakeSurveyHandler.fromList(
+ dismissedSurveyFile: dismissedSurveyFile,
+ initializedSurveys: <Survey>[
+ Survey(
+ uniqueId: 'uniqueId',
+ startDate: DateTime(2023, 1, 1),
+ endDate: DateTime(2023, 12, 31),
+ description: 'description',
+ snoozeForMinutes: 10,
+ samplingRate: 1.0,
+ excludeDashToolList: [],
+ conditionList: <Condition>[
+ Condition('logFileStats.recordCount', '>=', 50),
+ Condition('logFileStats.toolCount.flutter-tool', '>', 0),
+ ],
+ buttonList: [],
+ ),
+ ],
+ ),
+ );
+
+ // Simulate 60 events to send so that the first condition is satisified
+ for (var i = 0; i < 60; i++) {
+ analytics.send(testEvent);
+ }
+
+ await analytics.setTelemetry(false);
+ expect(analytics.okToSend, false);
+
+ final fetchedSurveys = await analytics.fetchAvailableSurveys();
+
+ expect(fetchedSurveys.length, 0);
+ });
+ });
+
+ test('returns valid survey from json', () async {
+ await withClock(Clock.fixed(DateTime(2023, 3, 3)), () async {
+ analytics = Analytics.fake(
+ tool: DashTool.flutterTool,
+ homeDirectory: homeDirectory,
+ dartVersion: 'dartVersion',
+ fs: fs,
+ platform: DevicePlatform.macos,
+ surveyHandler: FakeSurveyHandler.fromString(
+ dismissedSurveyFile: dismissedSurveyFile, content: '''
+[
+ {
+ "uniqueId": "uniqueId123",
+ "startDate": "2023-01-01T09:00:00-07:00",
+ "endDate": "2023-12-31T09:00:00-07:00",
+ "description": "description123",
+ "snoozeForMinutes": "10",
+ "samplingRate": "1.0",
+ "excludeDashTools": [],
+ "conditions": [
+ {
+ "field": "logFileStats.recordCount",
+ "operator": ">=",
+ "value": 50
+ }
+ ],
+ "buttons": [
+ {
+ "buttonText": "Take Survey",
+ "action": "accept",
+ "url": "https://google.qualtrics.com/jfe/form/SV_5gsB2EuG324y2",
+ "promptRemainsVisible": false
+ },
+ {
+ "buttonText": "Dismiss",
+ "action": "dismiss",
+ "url": null,
+ "promptRemainsVisible": false
+ },
+ {
+ "buttonText": "More Info",
+ "action": "snooze",
+ "url": "https://docs.flutter.dev/reference/crash-reporting",
+ "promptRemainsVisible": true
+ }
+ ]
+ }
+]
+'''),
+ );
+
+ // Simulate 60 events to send so that the first condition is satisified
+ for (var i = 0; i < 60; i++) {
+ analytics.send(testEvent);
+ }
+
+ final fetchedSurveys = await analytics.fetchAvailableSurveys();
+
+ expect(fetchedSurveys.length, 1);
+
+ final survey = fetchedSurveys.first;
+ expect(survey.uniqueId, 'uniqueId123');
+ expect(survey.startDate.year, 2023);
+ expect(survey.startDate.month, 1);
+ expect(survey.startDate.day, 1);
+ expect(survey.endDate.year, 2023);
+ expect(survey.endDate.month, 12);
+ expect(survey.endDate.day, 31);
+ expect(survey.description, 'description123');
+ expect(survey.snoozeForMinutes, 10);
+ expect(survey.samplingRate, 1.0);
+ expect(survey.conditionList.length, 1);
+
+ final condition = survey.conditionList.first;
+ expect(condition.field, 'logFileStats.recordCount');
+ expect(condition.operatorString, '>=');
+ expect(condition.value, 50);
+
+ final buttonList = survey.buttonList;
+ expect(buttonList.length, 3);
+ expect(buttonList.first.buttonText, 'Take Survey');
+ expect(buttonList.first.action, 'accept');
+ expect(buttonList.first.url,
+ 'https://google.qualtrics.com/jfe/form/SV_5gsB2EuG324y2');
+ expect(buttonList.first.promptRemainsVisible, false);
+
+ expect(buttonList.elementAt(1).buttonText, 'Dismiss');
+ expect(buttonList.elementAt(1).action, 'dismiss');
+ expect(buttonList.elementAt(1).url, isNull);
+ expect(buttonList.elementAt(1).promptRemainsVisible, false);
+
+ expect(buttonList.last.buttonText, 'More Info');
+ expect(buttonList.last.action, 'snooze');
+ expect(buttonList.last.url,
+ 'https://docs.flutter.dev/reference/crash-reporting');
+ expect(buttonList.last.promptRemainsVisible, true);
+ });
+ });
+
+ test('no survey returned from malformed json', () async {
+ // The date is not valid for the start date
+ await withClock(Clock.fixed(DateTime(2023, 3, 3)), () async {
+ analytics = Analytics.fake(
+ tool: DashTool.flutterTool,
+ homeDirectory: homeDirectory,
+ dartVersion: 'dartVersion',
+ fs: fs,
+ platform: DevicePlatform.macos,
+ surveyHandler: FakeSurveyHandler.fromString(
+ dismissedSurveyFile: dismissedSurveyFile, content: '''
+[
+ {
+ "uniqueId": "uniqueId123",
+ "startDate": "NOT A REAL DATE",
+ "endDate": "2023-07-30T09:00:00-07:00",
+ "description": "Help improve Flutter's release builds with this 3-question survey!",
+ "snoozeForMinutes": "7200",
+ "samplingRate": "0.1",
+ "excludeDashTools": [],
+ "conditions": [
+ {
+ "field": "logFileStats.recordCount",
+ "operator": ">=",
+ "value": 50
+ }
+ ],
+ "buttons": [
+ {
+ "buttonText": "Take Survey",
+ "action": "accept",
+ "url": "https://google.qualtrics.com/jfe/form/SV_5gsB2EuG5Et5Yy2",
+ "promptRemainsVisible": false
+ },
+ {
+ "buttonText": "Dismiss",
+ "action": "dismiss",
+ "url": null,
+ "promptRemainsVisible": false
+ },
+ {
+ "buttonText": "More Info",
+ "action": "snooze",
+ "url": "https://docs.flutter.dev/reference/crash-reporting",
+ "promptRemainsVisible": false
+ }
+ ]
+ }
+]
+'''),
+ );
+
+ // Simulate 60 events to send so that the first condition is satisified
+ for (var i = 0; i < 60; i++) {
+ analytics.send(testEvent);
+ }
+
+ final fetchedSurveys = await analytics.fetchAvailableSurveys();
+
+ expect(fetchedSurveys.length, 0);
+ });
+ });
+
+ test('returns two valid survey from json', () async {
+ await withClock(Clock.fixed(DateTime(2023, 3, 3)), () async {
+ analytics = Analytics.fake(
+ tool: DashTool.flutterTool,
+ homeDirectory: homeDirectory,
+ dartVersion: 'dartVersion',
+ fs: fs,
+ platform: DevicePlatform.macos,
+ surveyHandler: FakeSurveyHandler.fromString(
+ dismissedSurveyFile: dismissedSurveyFile, content: '''
+[
+ {
+ "uniqueId": "12345",
+ "startDate": "2023-01-01T09:00:00-07:00",
+ "endDate": "2023-12-31T09:00:00-07:00",
+ "description": "xxxxxxx",
+ "snoozeForMinutes": "10",
+ "samplingRate": "1.0",
+ "excludeDashTools": [],
+ "conditions": [
+ {
+ "field": "logFileStats.recordCount",
+ "operator": ">=",
+ "value": 50
+ }
+ ],
+ "buttons": []
+ },
+ {
+ "uniqueId": "67890",
+ "startDate": "2023-01-01T09:00:00-07:00",
+ "endDate": "2023-12-31T09:00:00-07:00",
+ "description": "xxxxxxx",
+ "snoozeForMinutes": "10",
+ "samplingRate": "1.0",
+ "excludeDashTools": [],
+ "conditions": [
+ {
+ "field": "logFileStats.recordCount",
+ "operator": ">=",
+ "value": 50
+ }
+ ],
+ "buttons": [
+ {
+ "buttonText": "More Info",
+ "action": "snooze",
+ "url": "https://docs.flutter.dev/reference/crash-reporting",
+ "promptRemainsVisible": true
+ }
+ ]
+ }
+]
+'''),
+ );
+
+ // Simulate 60 events to send so that the first condition is satisified
+ for (var i = 0; i < 60; i++) {
+ analytics.send(testEvent);
+ }
+
+ final fetchedSurveys = await analytics.fetchAvailableSurveys();
+
+ expect(fetchedSurveys.length, 2);
+
+ final firstSurvey = fetchedSurveys.first;
+ final secondSurvey = fetchedSurveys.last;
+
+ expect(firstSurvey.uniqueId, '12345');
+ expect(secondSurvey.uniqueId, '67890');
+
+ final secondSurveyButtons = secondSurvey.buttonList;
+ expect(secondSurveyButtons.length, 1);
+ expect(secondSurveyButtons.first.buttonText, 'More Info');
+ expect(secondSurveyButtons.first.action, 'snooze');
+ expect(secondSurveyButtons.first.url,
+ 'https://docs.flutter.dev/reference/crash-reporting');
+ expect(secondSurveyButtons.first.promptRemainsVisible, true);
+ });
+ });
+
+ test('valid survey not returned if opted out', () async {
+ await withClock(Clock.fixed(DateTime(2023, 3, 3)), () async {
+ analytics = Analytics.fake(
+ tool: DashTool.flutterTool,
+ homeDirectory: homeDirectory,
+ dartVersion: 'dartVersion',
+ fs: fs,
+ platform: DevicePlatform.macos,
+ surveyHandler: FakeSurveyHandler.fromList(
+ dismissedSurveyFile: dismissedSurveyFile,
+ initializedSurveys: <Survey>[
+ Survey(
+ uniqueId: 'uniqueId',
+ startDate: DateTime(2023, 1, 1),
+ endDate: DateTime(2023, 12, 31),
+ description: 'description',
+ snoozeForMinutes: 10,
+ samplingRate: 1.0,
+ excludeDashToolList: [],
+ conditionList: <Condition>[
+ Condition('logFileStats.recordCount', '>=', 50),
+ Condition('logFileStats.toolCount.flutter-tool', '>', 0),
+ ],
+ buttonList: [],
+ ),
+ ],
+ ),
+ );
+
+ // Simulate 60 events to send so that the first condition is satisified
+ for (var i = 0; i < 60; i++) {
+ analytics.send(testEvent);
+ }
+
+ // Setting to false will prevent anything from getting returned
+ await analytics.setTelemetry(false);
+ var fetchedSurveys = await analytics.fetchAvailableSurveys();
+ expect(fetchedSurveys.length, 0);
+
+ // Setting telemetry back to true should enable the surveys to get
+ // returned again; we will also need to send the fake events again
+ // because on opt out, the log file will get cleared and one of
+ // the conditions for the fake survey loaded is that we need
+ // at least 50 records for one of the conditions
+ await analytics.setTelemetry(true);
+ for (var i = 0; i < 60; i++) {
+ analytics.send(testEvent);
+ }
+ fetchedSurveys = await analytics.fetchAvailableSurveys();
+ expect(fetchedSurveys.length, 1);
+ });
+ });
+
+ test('Sampling rate correctly returns a valid survey', () async {
+ // This test will use a predefined client ID string of `string1`
+ // which has been set in the setup along with a predefined
+ // string for the survey ID of `string2` to get a sample rate value
+ //
+ // The combination of `string1` and `string2` will return 0.40
+ // from the sampleRate utility function so we have set the threshold
+ // to be 0.6 which should return surveys
+ await withClock(Clock.fixed(DateTime(2023, 3, 3)), () async {
+ final survey = Survey(
+ uniqueId: 'string2',
+ startDate: DateTime(2023, 1, 1),
+ endDate: DateTime(2023, 12, 31),
+ description: 'description',
+ snoozeForMinutes: 10,
+ samplingRate: 0.6,
+ excludeDashToolList: [],
+ conditionList: <Condition>[
+ Condition('logFileStats.recordCount', '>=', 50),
+ Condition('logFileStats.toolCount.flutter-tool', '>', 0),
+ ],
+ buttonList: [],
+ );
+ analytics = Analytics.fake(
+ tool: DashTool.flutterTool,
+ homeDirectory: homeDirectory,
+ dartVersion: 'dartVersion',
+ fs: fs,
+ platform: DevicePlatform.macos,
+ surveyHandler: FakeSurveyHandler.fromList(
+ dismissedSurveyFile: dismissedSurveyFile,
+ initializedSurveys: <Survey>[survey],
+ ),
+ );
+
+ // Simulate 60 events to send so that the first condition is satisified
+ for (var i = 0; i < 60; i++) {
+ analytics.send(testEvent);
+ }
+
+ final fetchedSurveys = await analytics.fetchAvailableSurveys();
+
+ expect(survey.samplingRate, 0.6);
+ expect(fetchedSurveys.length, 1);
+ });
+ });
+
+ test('Sampling rate filters out a survey', () async {
+ // We will reduce the survey's sampling rate to be 0.3 which is
+ // less than value returned from the predefined client ID and
+ // survey sample
+ await withClock(Clock.fixed(DateTime(2023, 3, 3)), () async {
+ final survey = Survey(
+ uniqueId: 'string2',
+ startDate: DateTime(2023, 1, 1),
+ endDate: DateTime(2023, 12, 31),
+ description: 'description',
+ snoozeForMinutes: 10,
+ samplingRate: 0.15,
+ excludeDashToolList: [],
+ conditionList: <Condition>[
+ Condition('logFileStats.recordCount', '>=', 50),
+ Condition('logFileStats.toolCount.flutter-tool', '>', 0),
+ ],
+ buttonList: [],
+ );
+ analytics = Analytics.fake(
+ tool: DashTool.flutterTool,
+ homeDirectory: homeDirectory,
+ dartVersion: 'dartVersion',
+ fs: fs,
+ platform: DevicePlatform.macos,
+ surveyHandler: FakeSurveyHandler.fromList(
+ dismissedSurveyFile: dismissedSurveyFile,
+ initializedSurveys: <Survey>[survey],
+ ),
+ );
+
+ // Simulate 60 events to send so that the first condition is satisified
+ for (var i = 0; i < 60; i++) {
+ analytics.send(testEvent);
+ }
+
+ final fetchedSurveys = await analytics.fetchAvailableSurveys();
+
+ expect(survey.samplingRate, 0.15);
+ expect(fetchedSurveys.length, 0);
+ });
+ });
+
+ test('Snoozing survey is successful with snooze timeout from survey',
+ () async {
+ expect(dismissedSurveyFile.readAsStringSync(), '{}',
+ reason: 'Should be an empty object');
+
+ // Initialize the survey class that we will use for this test
+ final minutesToSnooze = 30;
+ final surveyToLoad = Survey(
+ uniqueId: 'uniqueId',
+ startDate: DateTime(2023, 1, 1),
+ endDate: DateTime(2023, 12, 31),
+ description: 'description',
+ snoozeForMinutes:
+ minutesToSnooze, // Initialized survey with `minutesToSnooze`
+ samplingRate: 1.0,
+ excludeDashToolList: [],
+ conditionList: <Condition>[],
+ buttonList: [],
+ );
+
+ await withClock(Clock.fixed(DateTime(2023, 3, 3, 12, 0)), () async {
+ analytics = Analytics.fake(
+ tool: DashTool.flutterTool,
+ homeDirectory: homeDirectory,
+ dartVersion: 'dartVersion',
+ fs: fs,
+ platform: DevicePlatform.macos,
+ surveyHandler: FakeSurveyHandler.fromList(
+ dismissedSurveyFile: dismissedSurveyFile,
+ initializedSurveys: <Survey>[surveyToLoad],
+ ),
+ );
+
+ final fetchedSurveys = await analytics.fetchAvailableSurveys();
+ expect(fetchedSurveys.length, 1);
+
+ final survey = fetchedSurveys.first;
+ expect(survey.snoozeForMinutes, minutesToSnooze);
+
+ // We will snooze the survey now and it should not show up
+ // if we fetch surveys again before the minutes to snooze time
+ // has finished
+ analytics.surveyShown(survey);
+ });
+
+ // This analytics instance will be simulated to be shortly after the first
+ // snooze, but before the snooze period has elapsed
+ await withClock(Clock.fixed(DateTime(2023, 3, 3, 12, 15)), () async {
+ analytics = Analytics.fake(
+ tool: DashTool.flutterTool,
+ homeDirectory: homeDirectory,
+ dartVersion: 'dartVersion',
+ fs: fs,
+ platform: DevicePlatform.macos,
+ surveyHandler: FakeSurveyHandler.fromList(
+ dismissedSurveyFile: dismissedSurveyFile,
+ initializedSurveys: <Survey>[surveyToLoad],
+ ),
+ );
+
+ final fetchedSurveys = await analytics.fetchAvailableSurveys();
+ expect(fetchedSurveys.length, 0,
+ reason: 'The snooze period has not elapsed yet');
+ });
+
+ // This analytics instance will be simulated to be after the snooze period
+ await withClock(Clock.fixed(DateTime(2023, 3, 3, 12, 35)), () async {
+ analytics = Analytics.fake(
+ tool: DashTool.flutterTool,
+ homeDirectory: homeDirectory,
+ dartVersion: 'dartVersion',
+ fs: fs,
+ platform: DevicePlatform.macos,
+ surveyHandler: FakeSurveyHandler.fromList(
+ dismissedSurveyFile: dismissedSurveyFile,
+ initializedSurveys: <Survey>[surveyToLoad],
+ ),
+ );
+
+ final fetchedSurveys = await analytics.fetchAvailableSurveys();
+ expect(fetchedSurveys.length, 1,
+ reason: 'The snooze period has elapsed');
+ });
+ });
+
+ test('Dimissing permanently is successful', () async {
+ final minutesToSnooze = 10;
+ final surveyToLoad = Survey(
+ uniqueId: 'uniqueId',
+ startDate: DateTime(2023, 1, 1),
+ endDate: DateTime(2023, 12, 31),
+ description: 'description',
+ snoozeForMinutes: minutesToSnooze,
+ samplingRate: 1.0,
+ excludeDashToolList: [],
+ conditionList: <Condition>[],
+ buttonList: [
+ SurveyButton(
+ buttonText: 'buttonText',
+ action: 'accept',
+ promptRemainsVisible: false,
+ ),
+ SurveyButton(
+ buttonText: 'buttonText',
+ action: 'dismiss',
+ promptRemainsVisible: false,
+ ),
+ ],
+ );
+
+ await withClock(Clock.fixed(DateTime(2023, 3, 3, 12, 0)), () async {
+ analytics = Analytics.fake(
+ tool: DashTool.flutterTool,
+ homeDirectory: homeDirectory,
+ dartVersion: 'dartVersion',
+ fs: fs,
+ platform: DevicePlatform.macos,
+ surveyHandler: FakeSurveyHandler.fromList(
+ dismissedSurveyFile: dismissedSurveyFile,
+ initializedSurveys: <Survey>[surveyToLoad],
+ ),
+ );
+
+ final fetchedSurveys = await analytics.fetchAvailableSurveys();
+ expect(fetchedSurveys.length, 1);
+
+ // Dismissing permanently will ensure that this survey is not
+ // shown again
+ final survey = fetchedSurveys.first;
+ analytics.surveyInteracted(
+ survey: survey,
+ surveyButton: survey.buttonList.first,
+ );
+ });
+
+ // Moving out a week
+ await withClock(Clock.fixed(DateTime(2023, 3, 10, 12, 0)), () async {
+ analytics = Analytics.fake(
+ tool: DashTool.flutterTool,
+ homeDirectory: homeDirectory,
+ dartVersion: 'dartVersion',
+ fs: fs,
+ platform: DevicePlatform.macos,
+ surveyHandler: FakeSurveyHandler.fromList(
+ dismissedSurveyFile: dismissedSurveyFile,
+ initializedSurveys: <Survey>[surveyToLoad],
+ ),
+ );
+
+ final fetchedSurveys = await analytics.fetchAvailableSurveys();
+ expect(fetchedSurveys.length, 0);
+ });
+ });
+
+ test('malformed persisted json file for surveys', () async {
+ // When the survey handler encounters an error when parsing the
+ // persisted json file, it will reset it using the static method
+ // under the [Initializer] class and reset it to be an empty json object
+ final minutesToSnooze = 10;
+ final surveyToLoad = Survey(
+ uniqueId: 'uniqueId',
+ startDate: DateTime(2023, 1, 1),
+ endDate: DateTime(2023, 12, 31),
+ description: 'description',
+ snoozeForMinutes: minutesToSnooze,
+ samplingRate: 1.0,
+ excludeDashToolList: [],
+ conditionList: <Condition>[],
+ buttonList: [
+ SurveyButton(
+ buttonText: 'buttonText',
+ action: 'accept',
+ promptRemainsVisible: false,
+ ),
+ SurveyButton(
+ buttonText: 'buttonText',
+ action: 'dismiss',
+ promptRemainsVisible: false,
+ ),
+ ],
+ );
+
+ await withClock(Clock.fixed(DateTime(2023, 3, 3, 12, 0)), () async {
+ analytics = Analytics.fake(
+ tool: DashTool.flutterTool,
+ homeDirectory: homeDirectory,
+ dartVersion: 'dartVersion',
+ fs: fs,
+ platform: DevicePlatform.macos,
+ surveyHandler: FakeSurveyHandler.fromList(
+ dismissedSurveyFile: dismissedSurveyFile,
+ initializedSurveys: <Survey>[surveyToLoad],
+ ),
+ );
+
+ final fetchedSurveys = await analytics.fetchAvailableSurveys();
+ expect(fetchedSurveys.length, 1);
+
+ // Dismissing permanently will ensure that this survey is not
+ // shown again
+ final survey = fetchedSurveys.first;
+ expect(survey.buttonList.length, 2);
+ analytics.surveyInteracted(
+ survey: survey,
+ surveyButton: survey.buttonList.first,
+ );
+ });
+
+ // Purposefully write invalid json into the persisted file
+ dismissedSurveyFile.writeAsStringSync('{');
+
+ // Moving out a week
+ await withClock(Clock.fixed(DateTime(2023, 3, 10, 12, 0)), () async {
+ analytics = Analytics.fake(
+ tool: DashTool.flutterTool,
+ homeDirectory: homeDirectory,
+ dartVersion: 'dartVersion',
+ fs: fs,
+ platform: DevicePlatform.macos,
+ surveyHandler: FakeSurveyHandler.fromList(
+ dismissedSurveyFile: dismissedSurveyFile,
+ initializedSurveys: <Survey>[surveyToLoad],
+ ),
+ );
+
+ final fetchedSurveys = await analytics.fetchAvailableSurveys();
+ expect(fetchedSurveys.length, 1);
+ });
+ });
+
+ test('persisted json file goes missing handled', () async {
+ // If the persisted json file with the dismissed surveys is missing
+ // there should be error handling to recreate the file again with
+ // an empty json object
+ final minutesToSnooze = 10;
+ final surveyToLoad = Survey(
+ uniqueId: 'uniqueId',
+ startDate: DateTime(2023, 1, 1),
+ endDate: DateTime(2023, 12, 31),
+ description: 'description',
+ snoozeForMinutes: minutesToSnooze,
+ samplingRate: 1.0,
+ excludeDashToolList: [],
+ conditionList: <Condition>[],
+ buttonList: [
+ SurveyButton(
+ buttonText: 'buttonText',
+ action: 'accept',
+ promptRemainsVisible: false,
+ ),
+ SurveyButton(
+ buttonText: 'buttonText',
+ action: 'dismiss',
+ promptRemainsVisible: false,
+ ),
+ ],
+ );
+
+ await withClock(Clock.fixed(DateTime(2023, 3, 3, 12, 0)), () async {
+ analytics = Analytics.fake(
+ tool: DashTool.flutterTool,
+ homeDirectory: homeDirectory,
+ dartVersion: 'dartVersion',
+ fs: fs,
+ platform: DevicePlatform.macos,
+ surveyHandler: FakeSurveyHandler.fromList(
+ dismissedSurveyFile: dismissedSurveyFile,
+ initializedSurveys: <Survey>[surveyToLoad],
+ ),
+ );
+
+ final fetchedSurveys = await analytics.fetchAvailableSurveys();
+ expect(fetchedSurveys.length, 1);
+
+ // Dismissing permanently will ensure that this survey is not
+ // shown again
+ final survey = fetchedSurveys.first;
+ expect(survey.buttonList.length, 2);
+ analytics.surveyInteracted(
+ survey: survey,
+ surveyButton: survey.buttonList.first,
+ );
+ });
+
+ // Moving out a week
+ await withClock(Clock.fixed(DateTime(2023, 3, 10, 12, 0)), () async {
+ analytics = Analytics.fake(
+ tool: DashTool.flutterTool,
+ homeDirectory: homeDirectory,
+ dartVersion: 'dartVersion',
+ fs: fs,
+ platform: DevicePlatform.macos,
+ surveyHandler: FakeSurveyHandler.fromList(
+ dismissedSurveyFile: dismissedSurveyFile,
+ initializedSurveys: <Survey>[surveyToLoad],
+ ),
+ );
+
+ // Purposefully delete the file
+ dismissedSurveyFile.deleteSync();
+
+ final fetchedSurveys = await analytics.fetchAvailableSurveys();
+ expect(fetchedSurveys.length, 1);
+ });
+ });
+
+ test('Filtering out with excludeDashTool array', () async {
+ await withClock(Clock.fixed(DateTime(2023, 3, 3)), () async {
+ analytics = Analytics.fake(
+ tool: DashTool.flutterTool,
+ homeDirectory: homeDirectory,
+ dartVersion: 'dartVersion',
+ fs: fs,
+ platform: DevicePlatform.macos,
+ surveyHandler: FakeSurveyHandler.fromList(
+ dismissedSurveyFile: dismissedSurveyFile,
+ initializedSurveys: <Survey>[
+ Survey(
+ uniqueId: 'uniqueId',
+ startDate: DateTime(2023, 1, 1),
+ endDate: DateTime(2023, 12, 31),
+ description: 'description',
+ snoozeForMinutes: 10,
+ samplingRate: 1.0,
+ // This should be the same as the tool in the
+ // Analytics constructor above
+ excludeDashToolList: [
+ DashTool.flutterTool,
+ ],
+ conditionList: [],
+ buttonList: [
+ SurveyButton(
+ buttonText: 'buttonText',
+ action: 'accept',
+ url: 'http://example.com',
+ promptRemainsVisible: false,
+ ),
+ ],
+ ),
+ ],
+ ),
+ );
+
+ final fetchedSurveys = await analytics.fetchAvailableSurveys();
+
+ expect(fetchedSurveys.length, 0);
+ });
+ });
+
+ test(
+ 'Filter from excludeDashTool array does not '
+ 'apply for different tool', () async {
+ await withClock(Clock.fixed(DateTime(2023, 3, 3)), () async {
+ analytics = Analytics.fake(
+ tool: DashTool.flutterTool,
+ homeDirectory: homeDirectory,
+ dartVersion: 'dartVersion',
+ fs: fs,
+ platform: DevicePlatform.macos,
+ surveyHandler: FakeSurveyHandler.fromList(
+ dismissedSurveyFile: dismissedSurveyFile,
+ initializedSurveys: <Survey>[
+ Survey(
+ uniqueId: 'uniqueId',
+ startDate: DateTime(2023, 1, 1),
+ endDate: DateTime(2023, 12, 31),
+ description: 'description',
+ snoozeForMinutes: 10,
+ samplingRate: 1.0,
+ // This should be different from the tool in the
+ // Analytics constructor above
+ excludeDashToolList: [
+ DashTool.devtools,
+ ],
+ conditionList: [],
+ buttonList: [
+ SurveyButton(
+ buttonText: 'buttonText',
+ action: 'accept',
+ url: 'http://example.com',
+ promptRemainsVisible: false,
+ ),
+ ],
+ ),
+ ],
+ ),
+ );
+
+ final fetchedSurveys = await analytics.fetchAvailableSurveys();
+
+ expect(fetchedSurveys.length, 1);
+
+ final survey = fetchedSurveys.first;
+ expect(survey.excludeDashToolList.length, 1);
+ expect(survey.excludeDashToolList.contains(DashTool.devtools), true);
+ });
+ });
+ });
+}
diff --git a/pkgs/unified_analytics/test/unified_analytics_test.dart b/pkgs/unified_analytics/test/unified_analytics_test.dart
new file mode 100644
index 0000000..2e78df4
--- /dev/null
+++ b/pkgs/unified_analytics/test/unified_analytics_test.dart
@@ -0,0 +1,1275 @@
+// Copyright (c) 2023, 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.
+
+// ignore_for_file: lines_longer_than_80_chars, avoid_dynamic_calls
+
+import 'dart:convert';
+import 'dart:io' as io;
+import 'dart:math';
+
+import 'package:clock/clock.dart';
+import 'package:file/file.dart';
+import 'package:file/memory.dart';
+import 'package:test/test.dart';
+import 'package:unified_analytics/src/constants.dart';
+import 'package:unified_analytics/src/enums.dart';
+import 'package:unified_analytics/src/utils.dart';
+import 'package:unified_analytics/unified_analytics.dart';
+import 'package:yaml/yaml.dart';
+
+void main() {
+ late MemoryFileSystem fs;
+ late Directory home;
+ late Directory dartToolDirectory;
+ late Analytics initializationAnalytics;
+ late FakeAnalytics analytics;
+ late File clientIdFile;
+ late File sessionFile;
+ late File configFile;
+ late File logFile;
+ late File dismissedSurveyFile;
+
+ const homeDirName = 'home';
+ const initialTool = DashTool.flutterTool;
+ const secondTool = DashTool.dartTool;
+ const toolsMessageVersion = 1;
+ const toolsMessage = 'toolsMessage';
+ const flutterChannel = 'flutterChannel';
+ const flutterVersion = 'flutterVersion';
+ const dartVersion = 'dartVersion';
+ const platform = DevicePlatform.macos;
+ const clientIde = 'VSCode';
+
+ final testEvent = Event.hotReloadTime(timeMs: 50);
+
+ setUp(() {
+ // Setup the filesystem with the home directory
+ final fsStyle =
+ io.Platform.isWindows ? FileSystemStyle.windows : FileSystemStyle.posix;
+ fs = MemoryFileSystem.test(style: fsStyle);
+ home = fs.directory(homeDirName);
+ dartToolDirectory = home.childDirectory(kDartToolDirectoryName);
+
+ // This is the first analytics instance that will be used to demonstrate
+ // that events will not be sent with the first run of analytics
+ initializationAnalytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ );
+ expect(initializationAnalytics.shouldShowMessage, true);
+ initializationAnalytics.clientShowedMessage();
+ expect(initializationAnalytics.shouldShowMessage, false);
+
+ // The main analytics instance, other instances can be spawned within tests
+ // to test how to instances running together work
+ //
+ // This instance should have the same parameters as the one above for
+ // [initializationAnalytics]
+ analytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ clientIde: clientIde,
+ );
+ analytics.clientShowedMessage();
+
+ // The 5 files that should have been generated
+ clientIdFile = home
+ .childDirectory(kDartToolDirectoryName)
+ .childFile(kClientIdFileName);
+ sessionFile =
+ home.childDirectory(kDartToolDirectoryName).childFile(kSessionFileName);
+ configFile =
+ home.childDirectory(kDartToolDirectoryName).childFile(kConfigFileName);
+ logFile =
+ home.childDirectory(kDartToolDirectoryName).childFile(kLogFileName);
+ dismissedSurveyFile = home
+ .childDirectory(kDartToolDirectoryName)
+ .childFile(kDismissedSurveyFileName);
+ });
+
+ test('Initializer properly sets up on first run', () {
+ expect(dartToolDirectory.existsSync(), true,
+ reason: 'The directory should have been created');
+ expect(clientIdFile.existsSync(), true,
+ reason: 'The $kClientIdFileName file was not found');
+ expect(sessionFile.existsSync(), true,
+ reason: 'The $kSessionFileName file was not found');
+ expect(configFile.existsSync(), true,
+ reason: 'The $kConfigFileName was not found');
+ expect(logFile.existsSync(), true,
+ reason: 'The $kLogFileName file was not found');
+ expect(dismissedSurveyFile.existsSync(), true,
+ reason: 'The $dismissedSurveyFile file was not found');
+ expect(dartToolDirectory.listSync().length, equals(5),
+ reason:
+ 'There should only be 5 files in the $kDartToolDirectoryName directory');
+ expect(configFile.readAsLinesSync().length,
+ kConfigString.split('\n').length + 1,
+ reason: 'The number of lines should equal lines in constant value + 1 '
+ 'for the initialized tool');
+ });
+
+ test('Resetting session file when data is malformed', () {
+ // Purposefully write content to the session file that
+ // can't be decoded as an integer
+ sessionFile.writeAsStringSync('contents');
+
+ // Define the initial time to start
+ final start = DateTime(1995, 3, 3, 12, 0);
+
+ // Set the clock to the start value defined above
+ withClock(Clock.fixed(start), () {
+ final timestamp = clock.now().millisecondsSinceEpoch.toString();
+ expect(sessionFile.readAsStringSync(), 'contents');
+ analytics.userProperty.preparePayload();
+ expect(sessionFile.readAsStringSync(),
+ '{"session_id": $timestamp, "last_ping": $timestamp}');
+
+ analytics.sendPendingErrorEvents();
+
+ // Attempting to fetch the session id when malformed should also
+ // send an error event while parsing
+ final lastEvent = analytics.sentEvents.last;
+ expect(lastEvent, isNotNull);
+ expect(lastEvent.eventName, DashEvent.analyticsException);
+ expect(
+ lastEvent.eventData['workflow']!, 'UserProperty._refreshSessionData');
+ expect(lastEvent.eventData['error']!, 'FormatException');
+ });
+ });
+
+ test('Handles malformed session file on startup', () {
+ // Ensure that we are able to send an error message on startup if
+ // we encounter an error while parsing the contents of the session file
+ // for session data
+ sessionFile.writeAsStringSync('not a valid session id');
+
+ analytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ clientIde: clientIde,
+ );
+ analytics.clientShowedMessage();
+
+ // Invoking a send command should reset the session file to a good state
+ //
+ // Having it reformat the session file before any send event happens will just
+ // add additional work on startup
+ analytics.send(testEvent);
+
+ analytics.sendPendingErrorEvents();
+ final errorEvent = analytics.sentEvents
+ .where((element) => element.eventName == DashEvent.analyticsException)
+ .firstOrNull;
+ expect(errorEvent, isNotNull);
+ expect(
+ errorEvent!.eventData['workflow'], 'UserProperty._refreshSessionData');
+ expect(errorEvent.eventData['error'], 'FormatException');
+ expect(errorEvent.eventData['description'],
+ 'message: Unexpected character\nsource: not a valid session id');
+ });
+
+ test('Resetting session file when file is removed', () {
+ // Purposefully write delete the file
+ sessionFile.deleteSync();
+
+ // Define the initial time to start
+ final start = DateTime(1995, 3, 3, 12, 0);
+
+ // Set the clock to the start value defined above
+ withClock(Clock.fixed(start), () {
+ final timestamp = clock.now().millisecondsSinceEpoch.toString();
+ expect(sessionFile.existsSync(), false);
+ analytics.userProperty.preparePayload();
+ expect(sessionFile.readAsStringSync(),
+ '{"session_id": $timestamp, "last_ping": $timestamp}');
+
+ analytics.sendPendingErrorEvents();
+
+ // Attempting to fetch the session id when malformed should also
+ // send an error event while parsing
+ final lastEvent = analytics.sentEvents.last;
+ expect(lastEvent, isNotNull);
+ expect(lastEvent.eventName, DashEvent.analyticsException);
+ expect(
+ lastEvent.eventData['workflow']!, 'UserProperty._refreshSessionData');
+ expect(lastEvent.eventData['error']!, 'FileSystemException');
+ });
+ });
+
+ test('New tool is successfully added to config file', () {
+ // Create a new instance of the analytics class with the new tool
+ final secondAnalytics = Analytics.fake(
+ tool: secondTool,
+ homeDirectory: home,
+ flutterChannel: 'ey-test-channel',
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: 'Flutter 3.6.0-7.0.pre.47',
+ dartVersion: 'Dart 2.19.0',
+ fs: fs,
+ platform: platform,
+ );
+ secondAnalytics.clientShowedMessage();
+
+ expect(secondAnalytics.parsedTools.length, equals(2),
+ reason: 'There should be only 2 tools that have '
+ 'been parsed into the config file');
+ expect(secondAnalytics.parsedTools.containsKey(initialTool.label), true,
+ reason: 'The first tool: ${initialTool.label} should be in the map');
+ expect(secondAnalytics.parsedTools.containsKey(secondTool.label), true,
+ reason: 'The second tool: $secondAnalytics should be in the map');
+ expect(configFile.readAsStringSync().startsWith(kConfigString), true,
+ reason:
+ 'The config file should have the same message from the constants file');
+ });
+
+ test('First time analytics run will not send events, second time will', () {
+ // Send an event with the first analytics class; this should result
+ // in no logs in the log file which keeps track of all the events
+ // that have been sent
+ initializationAnalytics.send(testEvent);
+ initializationAnalytics.send(testEvent);
+
+ // Use the second instance of analytics defined in setUp() to send the actual
+ // events to simulate the second time the tool ran
+ analytics.send(testEvent);
+
+ expect(logFile.readAsLinesSync().length, 1,
+ reason: 'The second analytics instance should have logged an event');
+ });
+
+ test('Toggling telemetry boolean through Analytics class api', () async {
+ final originalClientId = clientIdFile.readAsStringSync();
+
+ expect(analytics.telemetryEnabled, true,
+ reason: 'Telemetry should be enabled by default '
+ 'when initialized for the first time');
+ // Use the API to disable analytics
+ expect(logFile.readAsLinesSync().length, 0);
+ await analytics.setTelemetry(false);
+ expect(analytics.telemetryEnabled, false,
+ reason: 'Analytics telemetry should be disabled');
+ expect(logFile.readAsLinesSync().length, 0,
+ reason: 'Log file should have been cleared after opting out');
+ expect(clientIdFile.readAsStringSync().length, 0,
+ reason: 'CLIENT ID file gets cleared on opt out');
+ expect(sessionFile.readAsStringSync().length, 0,
+ reason: 'Session file gets cleared on opt out');
+
+ // Toggle it back to being enabled
+ await analytics.setTelemetry(true);
+ expect(analytics.telemetryEnabled, true,
+ reason: 'Analytics telemetry should be enabled');
+ expect(logFile.readAsLinesSync().length, 1,
+ reason: 'There should only one event since it was cleared on opt out');
+ expect(clientIdFile.readAsStringSync().length, greaterThan(0),
+ reason: 'CLIENT ID file gets regenerated on opt in');
+ expect(sessionFile.readAsStringSync().length, greaterThan(0),
+ reason: 'Session file gets regenerated on opt in');
+
+ // Extract the last log item to check for the keys
+ final lastLogItem =
+ jsonDecode(logFile.readAsLinesSync().last) as Map<String, Object?>;
+ expect((lastLogItem['events'] as List).last['name'],
+ 'analytics_collection_enabled',
+ reason: 'Check on event name');
+ expect((lastLogItem['events'] as List).last['params']['status'], true,
+ reason: 'Status should be false');
+ expect((lastLogItem['client_id'] as String).isNotEmpty, true);
+ expect(originalClientId != lastLogItem['client_id'], true,
+ reason: 'When opting in again, the client id should be regenerated');
+ });
+
+ test('Confirm client id is not empty string after opting in', () async {
+ await analytics.setTelemetry(false);
+ expect(logFile.readAsLinesSync().length, 0,
+ reason: 'Log file should have been cleared after opting out');
+ expect(clientIdFile.readAsStringSync().length, 0,
+ reason: 'CLIENT ID file gets cleared on opt out');
+
+ // Start up a second instance to simulate starting another
+ // command being run
+ final secondAnalytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ );
+
+ // Setting telemetry back on will emit a new event
+ // where the client id string should not be empty
+ await secondAnalytics.setTelemetry(true);
+ expect(analytics.telemetryEnabled, true,
+ reason: 'Analytics telemetry should be enabled');
+ expect(logFile.readAsLinesSync().length, 1,
+ reason: 'There should only one event since it was cleared on opt out');
+ expect(clientIdFile.readAsStringSync().length, greaterThan(0),
+ reason: 'CLIENT ID file gets regenerated on opt in');
+
+ // Extract the last log item to check for the keys
+ final lastLogItem =
+ jsonDecode(logFile.readAsLinesSync().last) as Map<String, Object?>;
+ expect((lastLogItem['client_id'] as String).isNotEmpty, true,
+ reason: 'The client id should have been regenerated and '
+ 'emitted in the opt in event');
+ });
+
+ test(
+ 'Telemetry has been disabled by one '
+ 'tool and second tool correctly shows telemetry is disabled', () async {
+ expect(analytics.telemetryEnabled, true,
+ reason: 'Analytics telemetry should be enabled on initialization');
+ // Use the API to disable analytics
+ await analytics.setTelemetry(false);
+ expect(analytics.telemetryEnabled, false,
+ reason: 'Analytics telemetry should be disabled');
+
+ // Initialize a second analytics class, which simulates a second tool
+ // Create a new instance of the analytics class with the new tool
+ final secondAnalytics = Analytics.fake(
+ tool: secondTool,
+ homeDirectory: home,
+ flutterChannel: 'ey-test-channel',
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: 'Flutter 3.6.0-7.0.pre.47',
+ dartVersion: 'Dart 2.19.0',
+ fs: fs,
+ platform: platform,
+ );
+ secondAnalytics.clientShowedMessage();
+
+ expect(secondAnalytics.telemetryEnabled, false,
+ reason: 'Analytics telemetry should be disabled by the first class '
+ 'and the second class should show telemetry is disabled');
+ });
+
+ test(
+ 'Two concurrent instances are running '
+ 'and reflect an accurate up to date telemetry status', () async {
+ // Initialize a second analytics class, which simulates a second tool
+ final secondAnalytics = Analytics.fake(
+ tool: secondTool,
+ homeDirectory: home,
+ flutterChannel: 'ey-test-channel',
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: 'Flutter 3.6.0-7.0.pre.47',
+ dartVersion: 'Dart 2.19.0',
+ fs: fs,
+ platform: platform,
+ );
+ secondAnalytics.clientShowedMessage();
+
+ expect(analytics.telemetryEnabled, true,
+ reason: 'Telemetry should be enabled on initialization for '
+ 'first analytics instance');
+ expect(secondAnalytics.telemetryEnabled, true,
+ reason: 'Telemetry should be enabled on initialization for '
+ 'second analytics instance');
+
+ // Use the API to disable analytics on the first instance
+ await analytics.setTelemetry(false);
+ expect(analytics.telemetryEnabled, false,
+ reason: 'Analytics telemetry should be disabled on first instance');
+
+ expect(secondAnalytics.telemetryEnabled, false,
+ reason: 'Analytics telemetry should be disabled by the first class '
+ 'and the second class should show telemetry is disabled'
+ ' by checking the timestamp on the config file');
+ });
+
+ test('New line character is added if missing', () {
+ String currentConfigFileString;
+
+ expect(configFile.readAsStringSync().endsWith('\n'), true,
+ reason: 'When initialized, the tool should correctly '
+ 'add a trailing new line character');
+
+ // Remove the trailing new line character before initializing a second
+ // analytics class; the new class should correctly format the config file
+ currentConfigFileString = configFile.readAsStringSync();
+ currentConfigFileString = currentConfigFileString.substring(
+ 0, currentConfigFileString.length - 1);
+
+ // Write back out to the config file to be processed again
+ configFile.writeAsStringSync(currentConfigFileString);
+
+ expect(configFile.readAsStringSync().endsWith('\n'), false,
+ reason: 'The trailing new line should be missing');
+
+ // Initialize a second analytics class, which simulates a second tool
+ // which should correct the missing trailing new line character
+ final secondAnalytics = Analytics.fake(
+ tool: secondTool,
+ homeDirectory: home,
+ flutterChannel: 'ey-test-channel',
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: 'Flutter 3.6.0-7.0.pre.47',
+ dartVersion: 'Dart 2.19.0',
+ fs: fs,
+ platform: platform,
+ );
+ secondAnalytics.clientShowedMessage();
+
+ expect(secondAnalytics.telemetryEnabled, true);
+
+ expect(configFile.readAsStringSync().endsWith('\n'), true,
+ reason: 'The second analytics class will correct '
+ 'the missing new line character');
+ });
+
+ test('Incrementing the version for a tool is successful', () {
+ expect(analytics.parsedTools[initialTool.label]?.versionNumber,
+ toolsMessageVersion,
+ reason: 'On initialization, the first version number should '
+ 'be what is set in the setup method');
+
+ // Initialize a second analytics class for the same tool as
+ // the first analytics instance except with a newer version for
+ // the tools message and version
+ final secondAnalytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion + 1,
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ );
+ expect(secondAnalytics.shouldShowMessage, true);
+ expect(secondAnalytics.okToSend, false);
+ secondAnalytics.clientShowedMessage();
+ expect(secondAnalytics.shouldShowMessage, false);
+ expect(secondAnalytics.okToSend, false,
+ reason: 'New version for the message will be treated as a first run');
+
+ expect(secondAnalytics.parsedTools[initialTool.label]?.versionNumber,
+ toolsMessageVersion + 1,
+ reason:
+ 'The second analytics instance should have incremented the version');
+ });
+
+ test(
+ 'Config file resets when there is not exactly one match for the reporting flag',
+ () async {
+ // Write to the config file a string that is not formatted correctly
+ // (ie. there is more than one match for the reporting flag)
+ configFile.writeAsStringSync('''
+# INTRODUCTION
+#
+# This is the Flutter and Dart telemetry reporting
+# configuration file.
+#
+# Lines starting with a #" are documentation that
+# the tools maintain automatically.
+#
+# All other lines are configuration lines. They have
+# the form "name=value". If multiple lines contain
+# the same configuration name with different values,
+# the parser will default to a conservative value.
+
+# DISABLING TELEMETRY REPORTING
+#
+# To disable telemetry reporting, set "reporting" to
+# the value "0" and to enable, set to "1":
+reporting=1
+reporting=1
+
+# NOTIFICATIONS
+#
+# Each tool records when it last informed the user about
+# analytics reporting and the privacy policy.
+#
+# The following tools have so far read this file:
+#
+# dart-tools (Dart CLI developer tool)
+# devtools (DevTools debugging and performance tools)
+# flutter-tools (Flutter CLI developer tool)
+#
+# For each one, the file may contain a configuration line
+# where the name is the code in the list above, e.g. "dart-tool",
+# and the value is a date in the form YYYY-MM-DD, a comma, and
+# a number representing the version of the message that was
+# displayed.''');
+
+ // Disable telemetry which should result in a reset of the config file
+ await analytics.setTelemetry(false);
+
+ expect(configFile.readAsStringSync().startsWith(kConfigString), true,
+ reason: 'The tool should have reset the config file '
+ 'because it was not formatted correctly');
+ });
+
+ test('Config file resets when there is not exactly one match for the tool',
+ () {
+ // Write to the config file a string that is not formatted correctly
+ // (ie. there is more than one match for the reporting flag)
+ configFile.writeAsStringSync('''
+# INTRODUCTION
+#
+# This is the Flutter and Dart telemetry reporting
+# configuration file.
+#
+# Lines starting with a #" are documentation that
+# the tools maintain automatically.
+#
+# All other lines are configuration lines. They have
+# the form "name=value". If multiple lines contain
+# the same configuration name with different values,
+# the parser will default to a conservative value.
+
+# DISABLING TELEMETRY REPORTING
+#
+# To disable telemetry reporting, set "reporting" to
+# the value "0" and to enable, set to "1":
+reporting=1
+
+# NOTIFICATIONS
+#
+# Each tool records when it last informed the user about
+# analytics reporting and the privacy policy.
+#
+# The following tools have so far read this file:
+#
+# dart-tools (Dart CLI developer tool)
+# devtools (DevTools debugging and performance tools)
+# flutter-tools (Flutter CLI developer tool)
+#
+# For each one, the file may contain a configuration line
+# where the name is the code in the list above, e.g. "dart-tool",
+# and the value is a date in the form YYYY-MM-DD, a comma, and
+# a number representing the version of the message that was
+# displayed.
+${initialTool.label}=$dateStamp,$toolsMessageVersion
+${initialTool.label}=$dateStamp,$toolsMessageVersion
+''');
+
+ // Initialize a second analytics class for the same tool as
+ // the first analytics instance except with a newer version for
+ // the tools message and version
+ //
+ // This second instance should reset the config file when it goes
+ // to increment the version in the file
+ final secondAnalytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion + 1,
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ );
+ secondAnalytics.clientShowedMessage();
+
+ expect(
+ configFile.readAsStringSync(),
+ kConfigString,
+ reason: 'The config file should have been reset completely '
+ 'due to a malformed file that contained two lines for the same tool',
+ );
+
+ // Creating a third instance after the second instance
+ // has reset the config file should include the newly added
+ // tool again with its incremented version number
+ final thirdAnalytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion + 1,
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ );
+ thirdAnalytics.clientShowedMessage();
+
+ expect(
+ configFile.readAsStringSync().endsWith(
+ '# displayed.\n${initialTool.label}=$dateStamp,${toolsMessageVersion + 1}\n'),
+ true,
+ reason: 'The config file ends with the correctly formatted ending '
+ 'after removing the duplicate lines for a given tool',
+ );
+ expect(
+ thirdAnalytics.parsedTools[initialTool.label]?.versionNumber,
+ toolsMessageVersion + 1,
+ reason: 'The new version should have been incremented',
+ );
+ });
+
+ test('Check that UserProperty class has all the necessary keys', () {
+ const userPropertyKeys = <String>[
+ 'session_id',
+ 'flutter_channel',
+ 'host',
+ 'flutter_version',
+ 'dart_version',
+ 'analytics_pkg_version',
+ 'tool',
+ 'local_time',
+ 'host_os_version',
+ 'locale',
+ 'client_ide',
+ 'enabled_features',
+ ];
+ expect(analytics.userPropertyMap.keys.length, userPropertyKeys.length,
+ reason: 'There should only be ${userPropertyKeys.length} keys');
+ for (final key in userPropertyKeys) {
+ expect(analytics.userPropertyMap.keys.contains(key), true,
+ reason: 'The $key variable is required');
+ }
+ });
+
+ test('The minimum session duration should be at least 30 minutes', () {
+ expect(kSessionDurationMinutes < 30, false,
+ reason: 'Session is less than 30 minutes');
+ });
+
+ test(
+ 'The session id stays the same when duration'
+ ' is less than the constraint', () {
+ // For this test, we will need control clock time so we will delete
+ // the [dartToolDirectory] and all of its contents and reconstruct a
+ // new [Analytics] instance at a specific time
+ dartToolDirectory.deleteSync(recursive: true);
+ expect(dartToolDirectory.existsSync(), false,
+ reason: 'The directory should have been cleared');
+
+ // Define the initial time to start
+ final start = DateTime(1995, 3, 3, 12, 0);
+
+ // Set the clock to the start value defined above
+ withClock(Clock.fixed(start), () {
+ // This class will be constructed at a fixed time
+ final secondAnalytics = Analytics.fake(
+ tool: secondTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: 'Flutter 3.6.0-7.0.pre.47',
+ dartVersion: 'Dart 2.19.0',
+ fs: fs,
+ platform: platform,
+ );
+ secondAnalytics.clientShowedMessage();
+
+ expect(secondAnalytics.userPropertyMap['session_id']?['value'],
+ start.millisecondsSinceEpoch);
+ expect(sessionFile.lastModifiedSync().millisecondsSinceEpoch,
+ start.millisecondsSinceEpoch);
+ });
+
+ // Add time to the start time that is less than the duration
+ final end = start.add(const Duration(minutes: kSessionDurationMinutes - 1));
+
+ // Use a new clock to ensure that the session id didn't change
+ withClock(Clock.fixed(end), () {
+ // A new instance will need to be created since the second
+ // instance in the previous block is scoped - this new instance
+ // should not reset the files generated by the second instance
+ final thirdAnalytics = Analytics.fake(
+ tool: secondTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: 'Flutter 3.6.0-7.0.pre.47',
+ dartVersion: 'Dart 2.19.0',
+ fs: fs,
+ platform: platform,
+ );
+ thirdAnalytics.clientShowedMessage();
+
+ // Calling the send event method will result in the session file
+ // getting updated but because we use the `Analytics.fake()` constructor
+ // no events will be sent
+ thirdAnalytics.send(testEvent);
+
+ expect(thirdAnalytics.userPropertyMap['session_id']?['value'],
+ start.millisecondsSinceEpoch,
+ reason: 'The session id should not have changed since it was made '
+ 'within the duration');
+ expect(sessionFile.lastModifiedSync().millisecondsSinceEpoch,
+ end.millisecondsSinceEpoch,
+ reason: 'The last modified value should have been updated');
+ });
+ });
+
+ test('The session id is refreshed once event is sent after duration', () {
+ // For this test, we will need control clock time so we will delete
+ // the [dartToolDirectory] and all of its contents and reconstruct a
+ // new [Analytics] instance at a specific time
+ dartToolDirectory.deleteSync(recursive: true);
+ expect(dartToolDirectory.existsSync(), false,
+ reason: 'The directory should have been cleared');
+
+ // Define the initial time to start
+ final start = DateTime(1995, 3, 3, 12, 0);
+
+ // Set the clock to the start value defined above
+ withClock(Clock.fixed(start), () {
+ // This class will be constructed at a fixed time
+ final secondAnalytics = Analytics.fake(
+ tool: secondTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: 'Flutter 3.6.0-7.0.pre.47',
+ dartVersion: 'Dart 2.19.0',
+ fs: fs,
+ platform: platform,
+ );
+ secondAnalytics.clientShowedMessage();
+
+ expect(secondAnalytics.userPropertyMap['session_id']?['value'],
+ start.millisecondsSinceEpoch);
+ expect(sessionFile.lastModifiedSync().millisecondsSinceEpoch,
+ start.millisecondsSinceEpoch);
+
+ secondAnalytics.send(testEvent);
+ expect(sessionFile.readAsStringSync(),
+ '{"session_id": ${start.millisecondsSinceEpoch}, "last_ping": ${start.millisecondsSinceEpoch}}');
+ });
+
+ // Add time to the start time that is less than the duration
+ final end = start.add(const Duration(minutes: kSessionDurationMinutes + 1));
+
+ // Use a new clock to ensure that the session id didn't change
+ withClock(Clock.fixed(end), () {
+ // A new instance will need to be created since the second
+ // instance in the previous block is scoped - this new instance
+ // should not reset the files generated by the second instance
+ final thirdAnalytics = Analytics.fake(
+ tool: secondTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: 'Flutter 3.6.0-7.0.pre.47',
+ dartVersion: 'Dart 2.19.0',
+ fs: fs,
+ platform: platform,
+ );
+ thirdAnalytics.clientShowedMessage();
+
+ // Calling the send event method will result in the session file
+ // getting updated but because we use the `Analytics.fake()` constructor
+ // no events will be sent
+ thirdAnalytics.send(testEvent);
+
+ expect(thirdAnalytics.userPropertyMap['session_id']?['value'],
+ end.millisecondsSinceEpoch,
+ reason: 'The session id should have changed since it was made '
+ 'outside the duration');
+ expect(sessionFile.lastModifiedSync().millisecondsSinceEpoch,
+ end.millisecondsSinceEpoch,
+ reason: 'The last modified value should have been updated');
+ expect(sessionFile.readAsStringSync(),
+ '{"session_id": ${end.millisecondsSinceEpoch}, "last_ping": ${end.millisecondsSinceEpoch}}');
+ });
+ });
+
+ test('Validate the available enum types for DevicePlatform', () {
+ expect(DevicePlatform.values.length, 3,
+ reason: 'There should only be 3 supported device platforms');
+ expect(DevicePlatform.values.contains(DevicePlatform.windows), true);
+ expect(DevicePlatform.values.contains(DevicePlatform.macos), true);
+ expect(DevicePlatform.values.contains(DevicePlatform.linux), true);
+ });
+
+ test('Validate the request body', () {
+ // Sample map for event data
+ final eventData = <String, dynamic>{
+ 'time': 5,
+ 'command': 'run',
+ };
+
+ final Map<String, dynamic> body = generateRequestBody(
+ clientId: Uuid().generateV4(),
+ eventName: DashEvent.hotReloadTime,
+ eventData: eventData,
+ userProperty: analytics.userProperty,
+ );
+
+ // Checks for the top level keys
+ expect(body.containsKey('client_id'), true,
+ reason: '"client_id" is required at the top level');
+ expect(body.containsKey('events'), true,
+ reason: '"events" is required at the top level');
+ expect(body.containsKey('user_properties'), true,
+ reason: '"user_properties" is required at the top level');
+
+ // Regex for the client id
+ final clientIdPattern = RegExp(
+ r'^[0-9a-z]{8}\-[0-9a-z]{4}\-[0-9a-z]{4}\-[0-9a-z]{4}\-[0-9a-z]{12}$');
+
+ // Checks for the top level values
+ expect(body['client_id'].runtimeType, String,
+ reason: 'The client id must be a string');
+ expect(clientIdPattern.hasMatch(body['client_id'] as String), true,
+ reason: 'The client id is not properly formatted, ie '
+ '46cc0ba6-f604-4fd9-aa2f-8a20beb24cd4');
+ expect(
+ (body['events'][0] as Map<String, dynamic>).containsKey('name'), true,
+ reason: 'Each event in the events array needs a name');
+ expect(
+ (body['events'][0] as Map<String, dynamic>).containsKey('params'), true,
+ reason: 'Each event in the events array needs a params key');
+ });
+
+ test('Check that log file is correctly persisting events sent', () {
+ final int numberOfEvents = max((kLogFileLength * 0.1).floor(), 5);
+
+ for (var i = 0; i < numberOfEvents; i++) {
+ analytics.send(testEvent);
+ }
+
+ expect(logFile.readAsLinesSync().length, numberOfEvents,
+ reason: 'The number of events should be $numberOfEvents');
+
+ // Add the max number of events to confirm it does not exceed the max
+ for (var i = 0; i < kLogFileLength; i++) {
+ analytics.send(testEvent);
+ }
+
+ expect(logFile.readAsLinesSync().length, kLogFileLength,
+ reason: 'The number of events should be capped at $kLogFileLength');
+ });
+
+ test('Check the query on the log file works as expected', () {
+ // Define a new clock so that we can check the output of the
+ // log file stats method explicitly
+ final start = DateTime(1995, 3, 3, 12, 0);
+ final firstClock = Clock.fixed(start);
+
+ // Run with the simulated clock for the initial events
+ withClock(firstClock, () {
+ expect(analytics.logFileStats(), isNull,
+ reason: 'The result for the log file stats should be null when '
+ 'there are no logs');
+ analytics.send(testEvent);
+
+ final firstQuery = analytics.logFileStats()!;
+ expect(firstQuery.sessionCount, 1,
+ reason:
+ 'There should only be one session after the initial send event');
+ expect(firstQuery.flutterChannelCount, {'flutterChannel': 1},
+ reason: 'There should only be one flutter channel logged');
+ expect(firstQuery.toolCount, {'flutter-tool': 1},
+ reason: 'There should only be one tool logged');
+ });
+
+ // Define a new clock that is outside of the session duration
+ final secondClock =
+ start.add(const Duration(minutes: kSessionDurationMinutes + 1));
+
+ // Use the new clock to send an event that will change the session identifier
+ withClock(Clock.fixed(secondClock), () {
+ analytics.send(testEvent);
+
+ final secondQuery = analytics.logFileStats()!;
+
+ // Construct the expected response for the second query
+ expect(secondQuery.startDateTime, DateTime(1995, 3, 3, 12, 0));
+ expect(secondQuery.minsFromStartDateTime, 31);
+ expect(secondQuery.endDateTime, DateTime(1995, 3, 3, 12, 31));
+ expect(secondQuery.minsFromEndDateTime, 0);
+ expect(secondQuery.sessionCount, 2);
+ expect(secondQuery.flutterChannelCount, {'flutterChannel': 2});
+ expect(secondQuery.toolCount, {'flutter-tool': 2});
+ expect(secondQuery.recordCount, 2);
+ expect(secondQuery.eventCount, {'hot_reload_time': 2});
+ });
+ });
+
+ test('Check that the log file shows two different tools being used', () {
+ // Use a for loop two initialize the second analytics instance
+ // twice to account for no events being sent on the first instance
+ // run for a given tool
+ Analytics? secondAnalytics;
+ for (var i = 0; i < 2; i++) {
+ secondAnalytics = Analytics.fake(
+ tool: secondTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: 'Flutter 3.6.0-7.0.pre.47',
+ dartVersion: 'Dart 2.19.0',
+ fs: fs,
+ platform: platform,
+ );
+ secondAnalytics.clientShowedMessage();
+ }
+
+ // Send events with both instances of the classes
+ analytics.send(testEvent);
+ secondAnalytics!.send(testEvent);
+
+ // Query the log file stats to verify that there are two tools
+ final query = analytics.logFileStats()!;
+
+ expect(query.toolCount, {'flutter-tool': 1, 'dart-tool': 1},
+ reason: 'There should have been two tools in the persisted logs');
+ });
+
+ test('Check that log data missing some keys results in null for stats', () {
+ // The following string represents a log item that is malformed (missing the `tool` key)
+ const malformedLog = '{"client_id":"d40133a0-7ea6-4347-b668-ffae94bb8774",'
+ '"events":[{"name":"hot_reload_time","params":{"time_ns":345}}],'
+ '"user_properties":{'
+ '"session_id":{"value":1675193534342},'
+ '"flutter_channel":{"value":"ey-test-channel"},'
+ '"host":{"value":"macOS"},'
+ '"flutter_version":{"value":"Flutter 3.6.0-7.0.pre.47"},'
+ '"dart_version":{"value":"Dart 2.19.0"},'
+ // '"tool":{"value":"flutter-tools"},' NEEDS REMAIN REMOVED
+ '"local_time":{"value":"2023-01-31 14:32:14.592898 -0500"}}}';
+
+ logFile.writeAsStringSync(malformedLog);
+ final query = analytics.logFileStats();
+
+ expect(query, isNull,
+ reason:
+ 'The query should be null because `tool` is missing under `user_properties`');
+ });
+
+ test('Malformed local_time string should result in null for stats', () {
+ // The following string represents a log item that is malformed (missing the `tool` key)
+ const malformedLog = '{"client_id":"d40133a0-7ea6-4347-b668-ffae94bb8774",'
+ '"events":[{"name":"hot_reload_time","params":{"time_ns":345}}],'
+ '"user_properties":{'
+ '"session_id":{"value":1675193534342},'
+ '"flutter_channel":{"value":"ey-test-channel"},'
+ '"host":{"value":"macOS"},'
+ '"flutter_version":{"value":"Flutter 3.6.0-7.0.pre.47"},'
+ '"dart_version":{"value":"Dart 2.19.0"},'
+ '"tool":{"value":"flutter-tools"},'
+ '"local_time":{"value":"2023-xx-31 14:32:14.592898 -0500"}}}'; // PURPOSEFULLY MALFORMED
+
+ logFile.writeAsStringSync(malformedLog);
+ final query = analytics.logFileStats();
+
+ expect(query, isNull,
+ reason:
+ 'The query should be null because the `local_time` value is malformed');
+ });
+
+ test('Version is the same in the change log, pubspec, and constants.dart',
+ () {
+ // Parse the contents of the pubspec.yaml
+ final pubspecYamlString = io.File('pubspec.yaml').readAsStringSync();
+
+ // Parse into a yaml document to extract the version number
+ final doc = loadYaml(pubspecYamlString) as YamlMap;
+ final version = doc['version'] as String;
+
+ expect(version, kPackageVersion,
+ reason: 'The package version in the pubspec and '
+ 'constants.dart need to match\n'
+ 'Pubspec: $version && constants.dart: $kPackageVersion\n\n'
+ 'Make sure both are the same');
+
+ // Parse the contents of the change log file
+ final changeLogFirstLineString =
+ io.File('CHANGELOG.md').readAsLinesSync().first;
+ expect(changeLogFirstLineString.substring(3), kPackageVersion,
+ reason: 'The CHANGELOG.md file needs the first line to '
+ 'be the same version as the pubspec and constants.dart');
+ });
+
+ test('Null values for flutter parameters is reflected properly in log file',
+ () {
+ // Because we are using the `MemoryFileSystem.test` constructor,
+ // we don't have a real clock in the filesystem, and because we
+ // are checking the last modified timestamp for the session file
+ // to determine if we need to update the session id, manually setting
+ // that timestamp will ensure we are not updating session id when it
+ // first gets created
+ sessionFile.setLastModifiedSync(DateTime.now());
+
+ // Use a for loop two initialize the second analytics instance
+ // twice to account for no events being sent on the first instance
+ // run for a given tool
+ Analytics? secondAnalytics;
+ for (var i = 0; i < 2; i++) {
+ secondAnalytics = Analytics.fake(
+ tool: secondTool,
+ homeDirectory: home,
+ // flutterChannel: flutterChannel, THIS NEEDS TO REMAIN REMOVED
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: 'Flutter 3.6.0-7.0.pre.47',
+ dartVersion: 'Dart 2.19.0',
+ fs: fs,
+ platform: platform,
+ );
+ secondAnalytics.clientShowedMessage();
+ }
+
+ // Send an event and check that the query stats reflects what is expected
+ secondAnalytics!.send(testEvent);
+
+ // Query the log file stats to verify that there are two tools
+ final query = analytics.logFileStats()!;
+
+ expect(query.toolCount, {'dart-tool': 1},
+ reason: 'There should have only been on tool that sent events');
+ expect(query.flutterChannelCount.isEmpty, true,
+ reason:
+ 'The instance does not have flutter information so it should be 0');
+
+ // Sending a query with the first analytics instance which has flutter information
+ // available should reflect in the query that there is 1 flutter channel present
+ analytics.send(testEvent);
+ final query2 = analytics.logFileStats()!;
+
+ expect(query2.toolCount, {'dart-tool': 1, 'flutter-tool': 1},
+ reason: 'Two different analytics instances have '
+ 'been initialized and sent events');
+ expect(query2.sessionCount, query.sessionCount,
+ reason: 'The session should have remained the same');
+ expect(query2.flutterChannelCount, {'flutterChannel': 1},
+ reason: 'The first instance has flutter information initialized');
+ });
+
+ group('Testing against Google Analytics limitations:', () {
+ // Link to limitations documentation
+ // https://developers.google.com/analytics/devguides/collection/protocol/ga4/sending-events?client_type=gtag#limitations
+ //
+ // Only the limitations specified below have been added, the other
+ // are not able to be validated because it will vary by each tool
+ //
+ // 1. Events can have a maximum of 25 user properties
+ // 2. User property names must be 24 characters or fewer
+ // 3. (Only for `tool` name) User property values must be 36 characters or fewer
+ // 4. Event names must be 40 characters or fewer, may only contain alpha-numeric
+ // characters and underscores, and must start with an alphabetic character
+ test('max 25 user properties per event', () {
+ final Map<String, Object> userPropPayload =
+ analytics.userProperty.preparePayload();
+ const maxUserPropKeys = 25;
+
+ expect(userPropPayload.keys.length < maxUserPropKeys, true,
+ reason: 'There are too many keys in the UserProperty payload');
+ });
+
+ test('max 24 characters for user prop keys', () {
+ final Map<String, Object> userPropPayload =
+ analytics.userProperty.preparePayload();
+ const maxUserPropLength = 24;
+
+ var userPropLengthValid = true;
+ final invalidUserProps = <String>[];
+ for (final key in userPropPayload.keys) {
+ if (key.length > maxUserPropLength) {
+ userPropLengthValid = false;
+ invalidUserProps.add(key);
+ }
+ }
+ expect(userPropLengthValid, true,
+ reason:
+ 'The max length for each user prop is $maxUserPropLength chars\n'
+ 'The below keys are too long:\n$invalidUserProps');
+ });
+
+ test('max 36 characters for user prop values (only `tool` key)', () {
+ // Checks item 3
+ // All tools must be under 36 characters (and enforce each tool
+ // begins with a letter)
+ final toolLabelPattern = RegExp(r'^[a-zA-Z][a-zA-Z\_-]{0,35}$');
+ var toolLengthValid = true;
+ final invalidTools = <DashTool>[];
+ for (final tool in DashTool.values) {
+ if (!toolLabelPattern.hasMatch(tool.label)) {
+ toolLengthValid = false;
+ invalidTools.add(tool);
+ }
+ }
+
+ expect(toolLengthValid, true,
+ reason:
+ 'All tool labels must be under 36 characters and begin with a letter\n'
+ 'The following are invalid\n$invalidTools');
+ });
+
+ test('max 40 characters for event names', () {
+ // Check that each event name is less than 40 chars and starts with
+ // an alphabetic character; the entire string has to be alphanumeric
+ // and underscores
+ final eventLabelPattern = RegExp(r'^[a-zA-Z]{1}[a-zA-Z0-9\_]{0,39}$');
+ var eventValid = true;
+ final invalidEvents = <DashEvent>[];
+ for (final event in DashEvent.values) {
+ if (!eventLabelPattern.hasMatch(event.label)) {
+ eventValid = false;
+ invalidEvents.add(event);
+ }
+ }
+
+ expect(eventValid, true,
+ reason: 'All event labels should have letters and underscores '
+ 'as a delimiter if needed; invalid events below\n$invalidEvents');
+ });
+ });
+
+ test('Confirm credentials for GA', () {
+ expect(kGoogleAnalyticsApiSecret, 'Ka1jc8tZSzWc_GXMWHfPHA');
+ expect(kGoogleAnalyticsMeasurementId, 'G-04BXPVBCWJ');
+ });
+
+ test('Consent message is formatted correctly for the flutter tool', () {
+ // Retrieve the consent message for flutter tools
+ final consentMessage = analytics.getConsentMessage;
+
+ expect(consentMessage, equalsIgnoringWhitespace(r'''
+The Flutter CLI developer tool uses Google Analytics to report usage and diagnostic
+data along with package dependencies, and crash reporting to send basic crash
+reports. This data is used to help improve the Dart platform, Flutter framework,
+and related tools.
+
+Telemetry is not sent on the very first run. To disable reporting of telemetry,
+run this terminal command:
+
+ flutter --disable-analytics
+
+If you opt out of telemetry, an opt-out event will be sent, and then no further
+information will be sent. This data is collected in accordance with the Google
+Privacy Policy (https://policies.google.com/privacy).
+'''));
+ });
+
+ test('Consent message is formatted correctly for any tool other than flutter',
+ () {
+ // Create a new instance of the analytics class with the new tool
+ final secondAnalytics = Analytics.fake(
+ tool: secondTool,
+ homeDirectory: home,
+ flutterChannel: 'ey-test-channel',
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: 'Flutter 3.6.0-7.0.pre.47',
+ dartVersion: 'Dart 2.19.0',
+ fs: fs,
+ platform: platform,
+ );
+
+ // Retrieve the consent message for flutter tools
+ final consentMessage = secondAnalytics.getConsentMessage;
+
+ expect(consentMessage, equalsIgnoringWhitespace(r'''
+The Dart CLI developer tool uses Google Analytics to report usage and diagnostic
+data along with package dependencies, and crash reporting to send basic crash
+reports. This data is used to help improve the Dart platform, Flutter framework,
+and related tools.
+
+Telemetry is not sent on the very first run. To disable reporting of telemetry,
+run this terminal command:
+
+ dart --disable-analytics
+
+If you opt out of telemetry, an opt-out event will be sent, and then no further
+information will be sent. This data is collected in accordance with the Google
+Privacy Policy (https://policies.google.com/privacy).
+'''));
+ });
+
+ test('Equality operator works for identical events', () {
+ final eventOne = Event.clientRequest(
+ duration: 'duration',
+ latency: 'latency',
+ method: 'method',
+ );
+ final eventTwo = Event.clientRequest(
+ duration: 'duration',
+ latency: 'latency',
+ method: 'method',
+ );
+
+ expect(eventOne == eventTwo, true);
+ });
+
+ test('Equality operator works for non-identical events', () {
+ final eventOne = Event.clientRequest(
+ duration: 'duration',
+ latency: 'latency',
+ method: 'method',
+ added: 'DIFFERENT FROM EVENT TWO',
+ );
+ final eventTwo = Event.clientRequest(
+ duration: 'duration',
+ latency: 'latency',
+ method: 'method',
+ );
+
+ expect(eventOne == eventTwo, false);
+ });
+
+ test('Find a match for an event in a list of events', () {
+ final eventList = [
+ Event.analyticsCollectionEnabled(status: true),
+ Event.memoryInfo(rss: 500),
+ Event.clientRequest(
+ duration: 'duration', latency: 'latency', method: 'method'),
+ ];
+
+ final eventToMatch = Event.memoryInfo(rss: 500);
+
+ expect(eventList.contains(eventToMatch), true);
+ expect(eventList.where((element) => element == eventToMatch).length, 1);
+ });
+
+ group('Unit tests for util dartSDKVersion', () {
+ test('parses correctly for non-stable version', () {
+ final originalVersion =
+ '3.4.0-148.0.dev (dev) (Thu Feb 15 12:05:45 2024 -0800) on "macos_arm64"';
+
+ expect(parseDartSDKVersion(originalVersion),
+ '3.4.0 (build 3.4.0-148.0.dev)');
+ });
+
+ test('parses correctly for stable version', () {
+ final originalVersion =
+ '3.3.0 (stable) (Tue Feb 13 10:25:19 2024 +0000) on "macos_arm64"';
+
+ expect(parseDartSDKVersion(originalVersion), '3.3.0');
+ });
+ });
+}
diff --git a/pkgs/unified_analytics/test/workflow_test.dart b/pkgs/unified_analytics/test/workflow_test.dart
new file mode 100644
index 0000000..3a623a0
--- /dev/null
+++ b/pkgs/unified_analytics/test/workflow_test.dart
@@ -0,0 +1,382 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io' as io;
+
+import 'package:file/file.dart';
+import 'package:file/memory.dart';
+import 'package:test/test.dart';
+import 'package:unified_analytics/src/constants.dart';
+import 'package:unified_analytics/src/enums.dart';
+import 'package:unified_analytics/src/utils.dart';
+import 'package:unified_analytics/unified_analytics.dart';
+
+void main() {
+ late MemoryFileSystem fs;
+ late Directory home;
+ late Directory dartToolDirectory;
+ late File clientIdFile;
+ late File sessionFile;
+ late File configFile;
+ late File logFile;
+ late File dismissedSurveyFile;
+
+ const homeDirName = 'home';
+ const initialTool = DashTool.flutterTool;
+ const secondTool = DashTool.dartTool;
+ const toolsMessageVersion = 1;
+ const toolsMessage = 'toolsMessage';
+ const flutterChannel = 'flutterChannel';
+ const flutterVersion = 'flutterVersion';
+ const dartVersion = 'dartVersion';
+ const platform = DevicePlatform.macos;
+
+ final testEvent = Event.hotReloadTime(timeMs: 50);
+
+ setUp(() {
+ // Setup the filesystem with the home directory
+ final fsStyle =
+ io.Platform.isWindows ? FileSystemStyle.windows : FileSystemStyle.posix;
+ fs = MemoryFileSystem.test(style: fsStyle);
+ home = fs.directory(homeDirName);
+ dartToolDirectory = home.childDirectory(kDartToolDirectoryName);
+
+ // The 3 files that should have been generated
+ clientIdFile = home
+ .childDirectory(kDartToolDirectoryName)
+ .childFile(kClientIdFileName);
+ sessionFile =
+ home.childDirectory(kDartToolDirectoryName).childFile(kSessionFileName);
+ configFile =
+ home.childDirectory(kDartToolDirectoryName).childFile(kConfigFileName);
+ logFile =
+ home.childDirectory(kDartToolDirectoryName).childFile(kLogFileName);
+ dismissedSurveyFile = home
+ .childDirectory(kDartToolDirectoryName)
+ .childFile(kDismissedSurveyFileName);
+ });
+
+ test('Confirm workflow for first run', () {
+ final firstAnalytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ );
+
+ expect(firstAnalytics.shouldShowMessage, true);
+ expect(firstAnalytics.okToSend, false);
+
+ firstAnalytics.clientShowedMessage();
+ expect(firstAnalytics.shouldShowMessage, false);
+ expect(firstAnalytics.okToSend, false,
+ reason: 'On the first run, we should not be ok '
+ 'to send any events, even if the user accepts');
+ });
+
+ test('Confirm workflow for updated tools message version + new tool', () {
+ // Helper function to check the state of the instance
+ void checkAnalyticsInstance(Analytics instance) {
+ expect(instance.shouldShowMessage, true);
+ expect(instance.okToSend, false);
+
+ instance.clientShowedMessage();
+ expect(instance.shouldShowMessage, false);
+ expect(instance.okToSend, false,
+ reason: 'On the first run, we should not be ok '
+ 'to send any events, even if the user accepts');
+ }
+
+ final firstAnalytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ );
+
+ checkAnalyticsInstance(firstAnalytics);
+
+ // Instance where we increment the version of the message
+ final secondAnalytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion + 1, // Incrementing version
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ );
+
+ // Running the same checks for the second instance, it should
+ // behave the same as if it was a first run
+ checkAnalyticsInstance(secondAnalytics);
+
+ // Instance for a different tool with the incremented version
+ final thirdAnalytics = Analytics.fake(
+ tool: secondTool, // Different tool
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion + 1, // Incrementing version
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ );
+
+ // The instance with a new tool getting onboarded should be
+ // treated the same as the 2 previous instances
+ checkAnalyticsInstance(thirdAnalytics);
+ });
+
+ test('Confirm workflow for checking tools into the config file', () {
+ final firstAnalytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ );
+
+ // Host of assertions to ensure all required artifacts
+ // are created
+ expect(dartToolDirectory.existsSync(), true,
+ reason: 'The directory should have been created');
+ expect(clientIdFile.existsSync(), true,
+ reason: 'The $kClientIdFileName file was not found');
+ expect(sessionFile.existsSync(), true,
+ reason: 'The $kSessionFileName file was not found');
+ expect(configFile.existsSync(), true,
+ reason: 'The $kConfigFileName was not found');
+ expect(logFile.existsSync(), true,
+ reason: 'The $kLogFileName file was not found');
+ expect(dismissedSurveyFile.existsSync(), true,
+ reason: 'The $dismissedSurveyFile file was not found');
+ expect(
+ dartToolDirectory.listSync().length,
+ equals(5),
+ reason: 'There should only be 5 files in the $kDartToolDirectoryName '
+ 'directory',
+ );
+ expect(configFile.readAsStringSync(), kConfigString);
+
+ expect(firstAnalytics.shouldShowMessage, true);
+
+ // Attempting to send a message with this instance should be
+ // blocked because it has not invoked `clientShowedMessage()`
+ // and it is the first run
+ //
+ // Even after invoking the method, it should be prevented from
+ // sending a message because it is the first time the tool was
+ // run in this instance
+ firstAnalytics.send(testEvent);
+ expect(logFile.readAsLinesSync().length, 0);
+ firstAnalytics.clientShowedMessage();
+
+ // Attempt to send two events, both should be blocked because it is
+ // part of the first instance
+ firstAnalytics.send(testEvent);
+ firstAnalytics.send(testEvent);
+ expect(logFile.readAsLinesSync().length, 0);
+
+ // Creating a second analytics instance from the same tool now should
+ // allow for events to be sent
+ final secondAnalytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ );
+
+ expect(secondAnalytics.shouldShowMessage, false);
+ secondAnalytics.send(testEvent);
+ expect(logFile.readAsLinesSync().length, 1,
+ reason: 'Events will be blocked until invoking method '
+ 'ensuring client has seen message');
+
+ secondAnalytics.send(testEvent);
+ secondAnalytics.send(testEvent);
+ expect(logFile.readAsLinesSync().length, 3);
+
+ // Next, we will want to confirm that the message should be showing when
+ // a new analytics instance has been created with a newer version for
+ // message that should be shown
+ //
+ // In this case, it should be treated as a new tool being added for the
+ // first time and all events should be blocked
+
+ // Delete the log file to reset the counter of events sent
+ logFile.deleteSync();
+ final thirdAnalytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion + 1, // Incrementing version
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ );
+
+ expect(logFile.existsSync(), true,
+ reason: 'The $kLogFileName file was not found');
+ expect(thirdAnalytics.shouldShowMessage, true,
+ reason: 'New version number should require showing message');
+ thirdAnalytics.send(testEvent);
+ expect(logFile.readAsLinesSync().length, 0);
+ thirdAnalytics.clientShowedMessage();
+
+ // Attempt to send two events, both should be blocked because it is
+ // part of the third instance which has a new version for the consent
+ // message which will be treated as a new tool being onboarded
+ thirdAnalytics.send(testEvent);
+ thirdAnalytics.send(testEvent);
+ expect(logFile.readAsLinesSync().length, 0);
+
+ // The fourth instance of the analytics class with the consent message
+ // version incremented should now be able to send messages
+ final fourthAnalytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion + 1, // Incrementing version
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ );
+
+ expect(fourthAnalytics.shouldShowMessage, false);
+ fourthAnalytics.send(testEvent);
+ expect(logFile.readAsLinesSync().length, 1,
+ reason: 'Events will be blocked until invoking method '
+ 'ensuring client has seen message');
+
+ fourthAnalytics.send(testEvent);
+ fourthAnalytics.send(testEvent);
+ expect(logFile.readAsLinesSync().length, 3);
+ });
+
+ test('Disable second instance if first one did not show message', () {
+ final firstAnalytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ );
+
+ expect(firstAnalytics.shouldShowMessage, true);
+
+ final secondAnalytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ );
+
+ expect(secondAnalytics.shouldShowMessage, true);
+
+ secondAnalytics.clientShowedMessage();
+
+ final thirdAnalytics = Analytics.fake(
+ tool: initialTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: toolsMessageVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: flutterVersion,
+ dartVersion: dartVersion,
+ fs: fs,
+ platform: platform,
+ );
+
+ expect(thirdAnalytics.shouldShowMessage, false);
+ });
+
+ test('Passing large version number gets logged in config', () {
+ final firstVersion = toolsMessageVersion + 3;
+ final secondAnalytics = Analytics.fake(
+ tool: secondTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: firstVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: 'Flutter 3.6.0-7.0.pre.47',
+ dartVersion: 'Dart 2.19.0',
+ fs: fs,
+ platform: platform,
+ );
+ secondAnalytics.clientShowedMessage();
+
+ expect(
+ configFile
+ .readAsStringSync()
+ .endsWith('${secondTool.label}=$dateStamp,$firstVersion\n'),
+ true);
+
+ // Create a new instane of the secondTool with an even
+ // bigger version
+ final secondVersion = firstVersion + 3;
+ final thirdAnalytics = Analytics.fake(
+ tool: secondTool,
+ homeDirectory: home,
+ flutterChannel: flutterChannel,
+ toolsMessageVersion: secondVersion,
+ toolsMessage: toolsMessage,
+ flutterVersion: 'Flutter 3.6.0-7.0.pre.47',
+ dartVersion: 'Dart 2.19.0',
+ fs: fs,
+ platform: platform,
+ );
+
+ expect(
+ configFile
+ .readAsStringSync()
+ .endsWith('${secondTool.label}=$dateStamp,$firstVersion\n'),
+ true);
+
+ // After invoking this method, it will get updated
+ // in the config with the next version
+ thirdAnalytics.clientShowedMessage();
+
+ expect(
+ configFile
+ .readAsStringSync()
+ .endsWith('${secondTool.label}=$dateStamp,$secondVersion\n'),
+ true);
+ });
+}