diff --git a/.bazelignore b/.bazelignore index b7f92cee892f..6ac41bd33565 100644 --- a/.bazelignore +++ b/.bazelignore @@ -1,5 +1,8 @@ node_modules +integration/harness-e2e-cli/.angular +integration/harness-e2e-cli/node_modules + integration/ng-update-v13/.angular integration/ng-update-v13/node_modules diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index b3d36e29d263..2103311a0e55 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,86 +1,86 @@ # Angular Material components -/src/material/* @jelbourn +/src/material/* @andrewseguin /src/material/autocomplete/** @crisbeto /src/material/badge/** @jelbourn /src/material/bottom-sheet/** @jelbourn @crisbeto -/src/material/button-toggle/** @jelbourn -/src/material/button/** @jelbourn -/src/material/card/** @jelbourn -/src/material/checkbox/** @jelbourn @devversion -/src/material/chips/** @jelbourn +/src/material/button-toggle/** @andrewseguin +/src/material/button/** @andrewseguin +/src/material/card/** @andrewseguin +/src/material/checkbox/** @andrewseguin @devversion +/src/material/chips/** @andrewseguin /src/material/datepicker/** @mmalerba -/src/material/dialog/** @jelbourn @crisbeto -/src/material/divider/** @jelbourn @crisbeto -/src/material/expansion/** @jelbourn +/src/material/dialog/** @andrewseguin @crisbeto +/src/material/divider/** @andrewseguin @crisbeto +/src/material/expansion/** @andrewseguin /src/material/form-field/** @mmalerba -/src/material/grid-list/** @jelbourn -/src/material/icon/** @jelbourn +/src/material/grid-list/** @andrewseguin +/src/material/icon/** @andrewseguin /src/material/input/** @mmalerba -/src/material/list/** @jelbourn @crisbeto @devversion +/src/material/list/** @andrewseguin @crisbeto @devversion /src/material/menu/** @crisbeto /src/material/paginator/** @andrewseguin -/src/material/prebuilt-themes/** @jelbourn -/src/material/progress-bar/** @jelbourn @crisbeto -/src/material/progress-spinner/** @jelbourn @crisbeto -/src/material/radio/** @jelbourn @devversion -/src/material/schematics/** @devversion @jelbourn +/src/material/prebuilt-themes/** @andrewseguin +/src/material/progress-bar/** @andrewseguin @crisbeto +/src/material/progress-spinner/** @andrewseguin @crisbeto +/src/material/radio/** @andrewseguin @devversion +/src/material/schematics/** @devversion @andrewseguin /src/material/select/** @crisbeto /src/material/sidenav/** @mmalerba /src/material/slide-toggle/** @devversion /src/material/slider/** @mmalerba -/src/material/snack-bar/** @jelbourn @crisbeto +/src/material/snack-bar/** @andrewseguin @crisbeto /src/material/sort/** @andrewseguin /src/material/stepper/** @mmalerba /src/material/table/** @andrewseguin /src/material/tabs/** @andrewseguin -/src/material/testing/** @jelbourn +/src/material/testing/** @andrewseguin /src/material/toolbar/** @devversion /src/material/tooltip/** @andrewseguin /src/material/tree/** @jelbourn @andrewseguin # Angular Material core -/src/material/core/* @jelbourn +/src/material/core/* @andrewseguin /src/material/core/testing/** @crisbeto -/src/material/core/animation/** @jelbourn -/src/material/core/color/** @jelbourn @devversion -/src/material/core/common-behaviors/** @jelbourn @devversion +/src/material/core/animation/** @andrewseguin +/src/material/core/color/** @andrewseguin @devversion +/src/material/core/common-behaviors/** @andrewseguin @devversion /src/material/core/datetime/** @mmalerba /src/material/core/density/** @devversion /src/material/core/error/** @crisbeto @mmalerba /src/material/core/focus-indicators/** @jelbourn @zelliott -/src/material/core/gestures/** @jelbourn +/src/material/core/gestures/** @andrewseguin /src/material/core/label/** @mmalerba -/src/material/core/line/** @jelbourn +/src/material/core/line/** @andrewseguin /src/material/core/option/** @crisbeto /src/material/core/placeholder/** @mmalerba /src/material/core/ripple/** @devversion -/src/material/core/selection/** @jelbourn -/src/material/core/selection/pseudo*/** @crisbeto @jelbourn -/src/material/core/style/** @jelbourn -/src/material/core/theming/** @jelbourn +/src/material/core/selection/** @andrewseguin +/src/material/core/selection/pseudo*/** @crisbeto @andrewseguin +/src/material/core/style/** @andrewseguin +/src/material/core/theming/** @andrewseguin @jelbourn /src/material/core/typography/** @crisbeto -/src/material/core/util/** @jelbourn +/src/material/core/util/** @andrewseguin # Miscellaneous components -/src/google-maps/** @mbehrlich -/src/youtube-player/** @nathantate +/src/google-maps/** @crisbeto @mbehrlich +/src/youtube-player/** @crisbeto @nathantate # CDK -/src/cdk/* @jelbourn +/src/cdk/* @andrewseguin /src/cdk/a11y/** @jelbourn @devversion -/src/cdk/accordion/** @jelbourn -/src/cdk/bidi/** @jelbourn -/src/cdk/clipboard/** @jelbourn @xkxx -/src/cdk/coercion/** @jelbourn -/src/cdk/collections/** @jelbourn @crisbeto @andrewseguin +/src/cdk/accordion/** @andrewseguin +/src/cdk/bidi/** @andrewseguin +/src/cdk/clipboard/** @andrewseguin @xkxx +/src/cdk/coercion/** @andrewseguin +/src/cdk/collections/** @crisbeto @andrewseguin /src/cdk/drag-drop/** @crisbeto -/src/cdk/keycodes/** @jelbourn -/src/cdk/layout/** @jelbourn -/src/cdk/observers/** @jelbourn @crisbeto +/src/cdk/keycodes/** @andrewseguin +/src/cdk/layout/** @andrewseguin +/src/cdk/observers/** @andrewseguin @crisbeto /src/cdk/overlay/** @jelbourn @crisbeto -/src/cdk/platform/** @jelbourn @devversion -/src/cdk/portal/** @jelbourn -/src/cdk/schematics/** @devversion @jelbourn +/src/cdk/platform/** @andrewseguin @devversion +/src/cdk/portal/** @andrewseguin +/src/cdk/schematics/** @devversion @andrewseguin /src/cdk/scrolling/** @andrewseguin @crisbeto /src/cdk/stepper/** @mmalerba /src/cdk/table/** @andrewseguin @@ -94,14 +94,14 @@ /src/material-date-fns-adapter/** @crisbeto # Material experimental package -/src/material-experimental/* @jelbourn +/src/material-experimental/* @andrewseguin /src/material-experimental/column-resize/** @kseamon @andrewseguin /src/material-experimental/mdc-autocomplete/** @crisbeto /src/material-experimental/mdc-button/** @andrewseguin /src/material-experimental/mdc-card/** @mmalerba /src/material-experimental/mdc-checkbox/** @mmalerba /src/material-experimental/mdc-chips/** @mmalerba -/src/material-experimental/mdc-color/** @jelbourn @devversion +/src/material-experimental/mdc-color/** @andrewseguin @devversion /src/material-experimental/mdc-core/** @crisbeto /src/material-experimental/mdc-density/** @devversion /src/material-experimental/mdc-dialog/** @devversion @@ -124,21 +124,21 @@ /src/material-experimental/mdc-table/** @andrewseguin /src/material-experimental/mdc-theming/** @mmalerba /src/material-experimental/mdc-typography/** @mmalerba -/src/material-experimental/menubar/** @jelbourn @andy9775 +/src/material-experimental/menubar/** @jelbourn /src/material-experimental/popover-edit/** @kseamon @andrewseguin -/src/material-experimental/selection/** @yifange @jelbourn +/src/material-experimental/selection/** @yifange @andrewseguin # CDK experimental package -/src/cdk-experimental/* @jelbourn +/src/cdk-experimental/* @andrewseguin /src/cdk-experimental/column-resize/** @kseamon @andrewseguin -/src/cdk-experimental/combobox/** @nielsr98 @jelbourn +/src/cdk-experimental/combobox/** @jelbourn /src/cdk-experimental/dialog/** @jelbourn @crisbeto -/src/cdk-experimental/menu/** @jelbourn @andy9775 +/src/cdk-experimental/menu/** @jelbourn /src/cdk-experimental/popover-edit/** @kseamon @andrewseguin /src/cdk-experimental/scrolling/** @mmalerba /src/cdk-experimental/table-scroll-container/** @kseamon @andrewseguin -/src/cdk-experimental/listbox/** @nielsr98 @jelbourn -/src/cdk-experimental/selection/** @yifange @jelbourn +/src/cdk-experimental/listbox/** @jelbourn +/src/cdk-experimental/selection/** @yifange @andrewseguin # Docs examples & guides /guides/** @jelbourn @@ -147,39 +147,39 @@ # Dev-app /src/dev-app/* @devversion /src/dev-app/autocomplete/** @crisbeto -/src/dev-app/badge/** @jelbourn +/src/dev-app/badge/** @andrewseguin /src/dev-app/baseline/** @mmalerba -/src/dev-app/bottom-sheet/** @jelbourn @crisbeto -/src/dev-app/button-toggle/** @jelbourn +/src/dev-app/bottom-sheet/** @andrewseguin @crisbeto +/src/dev-app/button-toggle/** @andrewseguin /src/dev-app/mdc-autocomplete/** @crisbeto -/src/dev-app/button/** @jelbourn -/src/dev-app/card/** @jelbourn -/src/dev-app/cdk-experimental-combobox/** @jelbourn @nielsr98 -/src/dev-app/cdk-experimental-listbox/** @jelbourn @nielsr98 -/src/dev-app/cdk-experimental-menu/** @jelbourn @andy9775 +/src/dev-app/button/** @andrewseguin +/src/dev-app/card/** @andrewseguin +/src/dev-app/cdk-experimental-combobox/** @jelbourn +/src/dev-app/cdk-experimental-listbox/** @jelbourn +/src/dev-app/cdk-experimental-menu/** @jelbourn /src/dev-app/checkbox/** @jelbourn @devversion -/src/dev-app/chips/** @jelbourn -/src/dev-app/clipboard/** @jelbourn @xkxx +/src/dev-app/chips/** @andrewseguin +/src/dev-app/clipboard/** @andrewseguin @xkxx /src/dev-app/column-resize/** @kseamon @andrewseguin /src/dev-app/connected-overlay/** @jelbourn @crisbeto /src/dev-app/dataset/** @andrewseguin /src/dev-app/datepicker/** @mmalerba /src/dev-app/dev-app/** @mmalerba -/src/dev-app/dialog/** @jelbourn @crisbeto +/src/dev-app/dialog/** @andrewseguin @crisbeto /src/dev-app/drag-drop/** @crisbeto /src/dev-app/drawer/** @mmalerba /src/dev-app/example/** @andrewseguin /src/dev-app/examples-page/** @andrewseguin -/src/dev-app/expansion/** @jelbourn +/src/dev-app/expansion/** @andrewseguin /src/dev-app/focus-origin/** @mmalerba /src/dev-app/focus-trap/** @jelbourn /src/dev-app/google-map/** @mbehrlich -/src/dev-app/grid-list/** @jelbourn -/src/dev-app/icon/** @jelbourn +/src/dev-app/grid-list/** @andrewseguin +/src/dev-app/icon/** @andrewseguin /src/dev-app/input/** @mmalerba -/src/dev-app/layout/** @jelbourn +/src/dev-app/layout/** @andrewseguin /src/dev-app/input-modality/** @jelbourn @zelliott -/src/dev-app/list/** @jelbourn @crisbeto @devversion +/src/dev-app/list/** @andrewseguin @crisbeto @devversion /src/dev-app/live-announcer/** @jelbourn /src/dev-app/mdc-button/** @andrewseguin # Note to implementer: please repossess @@ -204,50 +204,50 @@ /src/dev-app/mdc-tabs/** @crisbeto /src/dev-app/mdc-tooltip/** @crisbeto /src/dev-app/menu/** @crisbeto -/src/dev-app/menubar/** @jelbourn @andy9775 +/src/dev-app/menubar/** @jelbourn /src/dev-app/overlay/** @jelbourn @crisbeto /src/dev-app/paginator/** @andrewseguin -/src/dev-app/platform/** @jelbourn @devversion -/src/dev-app/portal/** @jelbourn +/src/dev-app/platform/** @andrewseguin @devversion +/src/dev-app/portal/** @andrewseguin /src/dev-app/popover-edit/** @kseamon @andrewseguin -/src/dev-app/progress-bar/** @jelbourn @crisbeto -/src/dev-app/progress-spinner/** @jelbourn @crisbeto -/src/dev-app/radio/** @jelbourn @devversion +/src/dev-app/progress-bar/** @andrewseguin @crisbeto +/src/dev-app/progress-spinner/** @andrewseguin @crisbeto +/src/dev-app/radio/** @andrewseguin @devversion /src/dev-app/ripple/** @devversion -/src/dev-app/screen-type/** @jelbourn +/src/dev-app/screen-type/** @andrewseguin /src/dev-app/select/** @crisbeto /src/dev-app/sidenav/** @mmalerba /src/dev-app/slide-toggle/** @devversion /src/dev-app/slider/** @mmalerba -/src/dev-app/snack-bar/** @jelbourn @crisbeto +/src/dev-app/snack-bar/** @andrewseguin @crisbeto /src/dev-app/stepper/** @mmalerba /src/dev-app/table/** @andrewseguin /src/dev-app/table-scroll-container/** @kseamon @andrewseguin /src/dev-app/tabs/** @andrewseguin /src/dev-app/toolbar/** @devversion /src/dev-app/tooltip/** @andrewseguin -/src/dev-app/tree/** @jelbourn +/src/dev-app/tree/** @andrewseguin /src/dev-app/typography/** @crisbeto /src/dev-app/virtual-scroll/** @mmalerba /src/dev-app/youtube-player/** @nathantate -/src/dev-app/selection/** @yifange @jelbourn +/src/dev-app/selection/** @yifange @andrewseguin # E2E app -/src/e2e-app/* @jelbourn +/src/e2e-app/* @andrewseguin /src/e2e-app/block-scroll-strategy/** @andrewseguin @crisbeto -/src/e2e-app/button/** @jelbourn -/src/e2e-app/button-toggle/** @jelbourn -/src/e2e-app/card/** @jelbourn -/src/e2e-app/checkbox/** @jelbourn @devversion +/src/e2e-app/button/** @andrewseguin +/src/e2e-app/button-toggle/** @andrewseguin +/src/e2e-app/card/** @andrewseguin +/src/e2e-app/checkbox/** @andrewseguin @devversion /src/e2e-app/component-harness/** @mmalerba -/src/e2e-app/dialog/** @jelbourn @crisbeto -/src/e2e-app/e2e-app/** @jelbourn +/src/e2e-app/dialog/** @andrewseguin @crisbeto +/src/e2e-app/e2e-app/** @andrewseguin /src/e2e-app/example-viewer/** @andrewseguin -/src/e2e-app/expansion/** @jelbourn -/src/e2e-app/grid-list/** @jelbourn -/src/e2e-app/icon/** @jelbourn +/src/e2e-app/expansion/** @andrewseguin +/src/e2e-app/grid-list/** @andrewseguin +/src/e2e-app/icon/** @andrewseguin /src/e2e-app/input/** @mmalerba -/src/e2e-app/list/** @jelbourn +/src/e2e-app/list/** @andrewseguin /src/e2e-app/mdc-button/** @andrewseguin # Note to implementer: please repossess /src/e2e-app/mdc-card/** @mmalerba @@ -264,14 +264,14 @@ /src/e2e-app/mdc-tabs/** @crisbeto /src/e2e-app/mdc-table/** @andrewseguin /src/e2e-app/menu/** @crisbeto -/src/e2e-app/progress-bar/** @jelbourn @crisbeto -/src/e2e-app/progress-spinner/** @jelbourn @crisbeto -/src/e2e-app/radio/** @jelbourn @devversion +/src/e2e-app/progress-bar/** @andrewseguin @crisbeto +/src/e2e-app/progress-spinner/** @andrewseguin @crisbeto +/src/e2e-app/radio/** @andrewseguin @devversion /src/e2e-app/sidenav/** @mmalerba /src/e2e-app/slide-toggle/** @devversion /src/e2e-app/stepper/** @mmalerba /src/e2e-app/tabs/** @andrewseguin -/src/e2e-app/test-util/** @jelbourn +/src/e2e-app/test-util/** @andrewseguin /src/e2e-app/toolbar/** @devversion /src/e2e-app/virtual-scroll/** @mmalerba @@ -279,7 +279,7 @@ /src/universal-app/** @devversion # Integration tests -/integration/** @jelbourn @devversion +/integration/** @andrewseguin @devversion # Tooling /.circleci/** @angular/dev-infra-components @@ -290,52 +290,52 @@ # Public API golden files /tools/public_api_guard/cdk/a11y.d.ts @jelbourn @devversion -/tools/public_api_guard/cdk/accordion.d.ts @jelbourn -/tools/public_api_guard/cdk/bidi.d.ts @jelbourn -/tools/public_api_guard/cdk/cdk.d.ts @jelbourn -/tools/public_api_guard/cdk/clipboard.d.ts @jelbourn @xkxx -/tools/public_api_guard/cdk/coercion.d.ts @jelbourn -/tools/public_api_guard/cdk/collections.d.ts @jelbourn @crisbeto @andrewseguin +/tools/public_api_guard/cdk/accordion.d.ts @andrewseguin +/tools/public_api_guard/cdk/bidi.d.ts @andrewseguin +/tools/public_api_guard/cdk/cdk.d.ts @andrewseguin +/tools/public_api_guard/cdk/clipboard.d.ts @andrewseguin @xkxx +/tools/public_api_guard/cdk/coercion.d.ts @andrewseguin +/tools/public_api_guard/cdk/collections.d.ts @crisbeto @andrewseguin /tools/public_api_guard/cdk/drag-drop.d.ts @crisbeto -/tools/public_api_guard/cdk/keycodes.d.ts @jelbourn -/tools/public_api_guard/cdk/layout.d.ts @jelbourn -/tools/public_api_guard/cdk/observers.d.ts @jelbourn @crisbeto -/tools/public_api_guard/cdk/overlay.d.ts @jelbourn @crisbeto -/tools/public_api_guard/cdk/platform.d.ts @jelbourn @devversion +/tools/public_api_guard/cdk/keycodes.d.ts @andrewseguin +/tools/public_api_guard/cdk/layout.d.ts @andrewseguin +/tools/public_api_guard/cdk/observers.d.ts @andrewseguin @crisbeto +/tools/public_api_guard/cdk/overlay.d.ts @andrewseguin @crisbeto +/tools/public_api_guard/cdk/platform.d.ts @andrewseguin @devversion /tools/public_api_guard/cdk/scrolling.d.ts @andrewseguin @crisbeto /tools/public_api_guard/cdk/stepper.d.ts @mmalerba /tools/public_api_guard/cdk/table.d.ts @andrewseguin /tools/public_api_guard/cdk/text-field.d.ts @mmalerba /tools/public_api_guard/cdk/tree.d.ts @jelbourn @andrewseguin /tools/public_api_guard/material/autocomplete.d.ts @crisbeto -/tools/public_api_guard/material/badge.d.ts @jelbourn -/tools/public_api_guard/material/bottom-sheet.d.ts @jelbourn @crisbeto -/tools/public_api_guard/material/button-toggle.d.ts @jelbourn -/tools/public_api_guard/material/button.d.ts @jelbourn -/tools/public_api_guard/material/card.d.ts @jelbourn -/tools/public_api_guard/material/checkbox.d.ts @jelbourn @devversion -/tools/public_api_guard/material/chips.d.ts @jelbourn -/tools/public_api_guard/material/chips/testing.d.ts @jelbourn -/tools/public_api_guard/material/core.d.ts @jelbourn +/tools/public_api_guard/material/badge.d.ts @andrewseguin +/tools/public_api_guard/material/bottom-sheet.d.ts @andrewseguin @crisbeto +/tools/public_api_guard/material/button-toggle.d.ts @andrewseguin +/tools/public_api_guard/material/button.d.ts @andrewseguin +/tools/public_api_guard/material/card.d.ts @andrewseguin +/tools/public_api_guard/material/checkbox.d.ts @andrewseguin @devversion +/tools/public_api_guard/material/chips.d.ts @andrewseguin +/tools/public_api_guard/material/chips/testing.d.ts @andrewseguin +/tools/public_api_guard/material/core.d.ts @andrewseguin /tools/public_api_guard/material/datepicker.d.ts @mmalerba -/tools/public_api_guard/material/dialog.d.ts @jelbourn @crisbeto -/tools/public_api_guard/material/divider.d.ts @jelbourn @crisbeto -/tools/public_api_guard/material/expansion.d.ts @jelbourn +/tools/public_api_guard/material/dialog.d.ts @andrewseguin @crisbeto +/tools/public_api_guard/material/divider.d.ts @andrewseguin @crisbeto +/tools/public_api_guard/material/expansion.d.ts @andrewseguin /tools/public_api_guard/material/form-field.d.ts @mmalerba -/tools/public_api_guard/material/grid-list.d.ts @jelbourn -/tools/public_api_guard/material/icon.d.ts @jelbourn +/tools/public_api_guard/material/grid-list.d.ts @andrewseguin +/tools/public_api_guard/material/icon.d.ts @andrewseguin /tools/public_api_guard/material/input.d.ts @mmalerba -/tools/public_api_guard/material/list.d.ts @jelbourn @crisbeto @devversion +/tools/public_api_guard/material/list.d.ts @andrewseguin @crisbeto @devversion /tools/public_api_guard/material/menu.d.ts @crisbeto /tools/public_api_guard/material/paginator.d.ts @andrewseguin -/tools/public_api_guard/material/progress-bar.d.ts @jelbourn @crisbeto -/tools/public_api_guard/material/progress-spinner.d.ts @jelbourn @crisbeto -/tools/public_api_guard/material/radio.d.ts @jelbourn @devversion +/tools/public_api_guard/material/progress-bar.d.ts @andrewseguin @crisbeto +/tools/public_api_guard/material/progress-spinner.d.ts @andrewseguin @crisbeto +/tools/public_api_guard/material/radio.d.ts @andrewseguin @devversion /tools/public_api_guard/material/select.d.ts @crisbeto /tools/public_api_guard/material/sidenav.d.ts @mmalerba /tools/public_api_guard/material/slide-toggle.d.ts @devversion /tools/public_api_guard/material/slider.d.ts @mmalerba -/tools/public_api_guard/material/snack-bar.d.ts @jelbourn @crisbeto +/tools/public_api_guard/material/snack-bar.d.ts @andrewseguin @crisbeto /tools/public_api_guard/material/sort.d.ts @andrewseguin /tools/public_api_guard/material/stepper.d.ts @mmalerba /tools/public_api_guard/material/table.d.ts @andrewseguin @@ -343,17 +343,17 @@ /tools/public_api_guard/material/toolbar.d.ts @devversion /tools/public_api_guard/material/tooltip.d.ts @andrewseguin /tools/public_api_guard/material/tree.d.ts @jelbourn @andrewseguin -/tools/public_api_guard/material/material.d.ts @jelbourn -/tools/public_api_guard/youtube-player/youtube-player.d.ts @jelbourn @nathantate +/tools/public_api_guard/material/material.d.ts @andrewseguin +/tools/public_api_guard/youtube-player/youtube-player.d.ts @andrewseguin @nathantate # Misc /.github/** @angular/dev-infra-components /.husky/** @angular/dev-infra-components -/.github/CODEOWNERS @angular/dev-infra-components @jelbourn +/.github/CODEOWNERS @angular/dev-infra-components @andrewseguin @jelbourn /.github/ISSUE_TEMPLATE/** @andrewseguin @jelbourn /.vscode/** @angular/dev-infra-components @mmalerba /.ng-dev/** @angular/dev-infra-components -/goldens/size-test.yml @jelbourn @mmalerba @crisbeto +/goldens/size-test.yml @andrewseguin @mmalerba @crisbeto /goldens/** @angular/dev-infra-components /src/* @angular/dev-infra-components /* @angular/dev-infra-components diff --git a/.github/workflows/dev-infra.yml b/.github/workflows/dev-infra.yml index 081e698ab0af..fda7a4fa2047 100644 --- a/.github/workflows/dev-infra.yml +++ b/.github/workflows/dev-infra.yml @@ -9,6 +9,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: angular/dev-infra/github-actions/commit-message-based-labels@f0f363cb4ce5b5faf14e3d3bb7eeb7c7aee72da7 + - uses: angular/dev-infra/github-actions/commit-message-based-labels@8298e121c51960857ef39abc16b743775ff6be68 with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/lock-closed.yml b/.github/workflows/lock-closed.yml index f19b35c6f13b..f890dfe5d9fd 100644 --- a/.github/workflows/lock-closed.yml +++ b/.github/workflows/lock-closed.yml @@ -9,6 +9,6 @@ jobs: lock_closed: runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/lock-closed@f0f363cb4ce5b5faf14e3d3bb7eeb7c7aee72da7 + - uses: angular/dev-infra/github-actions/lock-closed@8298e121c51960857ef39abc16b743775ff6be68 with: lock-bot-key: ${{ secrets.LOCK_BOT_PRIVATE_KEY }} diff --git a/.gitignore b/.gitignore index 2a71b14567d2..b2de1566cfc9 100644 --- a/.gitignore +++ b/.gitignore @@ -50,6 +50,3 @@ testem.log *.log .ng-dev.user* .husky/_ - -# Variables that are inlined into the dev app index.html -/src/dev-app/variables.json diff --git a/.ng-dev/release.ts b/.ng-dev/release.ts index c07485e8f494..038907f82acc 100644 --- a/.ng-dev/release.ts +++ b/.ng-dev/release.ts @@ -90,7 +90,8 @@ export const release: ReleaseConfig = { }, }, publishRegistry: 'https://wombat-dressing-room.appspot.com', - npmPackages: releasePackages.map(pkg => `@angular/${pkg}`), + representativeNpmPackage: '@angular/cdk', + npmPackages: releasePackages.map(pkg => ({name: `@angular/${pkg}`})), buildPackages: async () => { // The `performNpmReleaseBuild` function is loaded at runtime as loading of the // script results in an invocation of Bazel for any `yarn ng-dev` command. diff --git a/CHANGELOG.md b/CHANGELOG.md index a5a04985ff16..10685967e8c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,138 @@ - -# 13.2.0-next.0 "pine-pepperoni" (2021-12-16) + +# 14.0.0-next.0 "moss-mansion" (2022-01-26) +### material +| Commit | Type | Description | +| -- | -- | -- | +| [e03a77065d](https://github.com/angular/components/commit/e03a77065d81c5af62b60f351aa11a1444cad7bc) | fix | **core:** ripples not being clipped on safari in shadow dom ([#24029](https://github.com/angular/components/pull/24029)) | +### material-experimental +| Commit | Type | Description | +| -- | -- | -- | +| [b3c957941a](https://github.com/angular/components/commit/b3c957941a14555eb7adaeb10af3db4f80c0e10a) | fix | **mdc-form-field:** incorrect alignment with border-box alignment ([#24222](https://github.com/angular/components/pull/24222)) | +## Special Thanks +Andrew Seguin, Joey Perrott, Kristiyan Kostadinov and Miles Malerba + + + + +# 13.2.0 "terracotta-tiramisu" (2022-01-26) +### material +| Commit | Type | Description | +| -- | -- | -- | +| [b9a3908fcf](https://github.com/angular/components/commit/b9a3908fcf1abb3c1d11c888581e193768960b35) | feat | **tabs:** add API to update the pagination ([#23288](https://github.com/angular/components/pull/23288)) | +| [f10d245cca](https://github.com/angular/components/commit/f10d245cca22930e6d88aad03ede12f50f96746f) | feat | **tabs:** label & body classes ([#23691](https://github.com/angular/components/pull/23691)) | +| [ea78a473a1](https://github.com/angular/components/commit/ea78a473a17e0b5c23936af7772914f9db8cd058) | feat | **tabs:** Refactor MatTabNav to follow the ARIA tabs pattern ([#24062](https://github.com/angular/components/pull/24062)) | +| [337634f899](https://github.com/angular/components/commit/337634f899ee4d573643627be79c3d986384389f) | fix | **chips:** don't stop propagation on all click events ([#19763](https://github.com/angular/components/pull/19763)) | +| [2b6739742b](https://github.com/angular/components/commit/2b6739742bd3ac138c06a4a69e305cc34504be69) | fix | **datepicker:** change calendar cells to buttons ([#24171](https://github.com/angular/components/pull/24171)) | +| [c55524a8eb](https://github.com/angular/components/commit/c55524a8eb89e211559f5488559d8a25761b295c) | fix | **list:** add isDisabled to all list item harnesses ([#24212](https://github.com/angular/components/pull/24212)) | +| [fa7cd154d0](https://github.com/angular/components/commit/fa7cd154d04427229a663fc22f37b514bdd3355e) | fix | **list:** fix duplicate focus with chromevox on action-list items ([#23361](https://github.com/angular/components/pull/23361)) | +| [0477022d2c](https://github.com/angular/components/commit/0477022d2c467753a0d6d94236745bc9cbf5c067) | fix | **slide-toggle:** remove divs nested inside label ([#21224](https://github.com/angular/components/pull/21224)) | +### google-maps +| Commit | Type | Description | +| -- | -- | -- | +| [e6359cdc67](https://github.com/angular/components/commit/e6359cdc67617be940201dd9fc5660d2997e20c3) | feat | allow for info window focus behavior to be customized ([#23831](https://github.com/angular/components/pull/23831)) | ### material-experimental | Commit | Type | Description | | -- | -- | -- | +| [c5482c945f](https://github.com/angular/components/commit/c5482c945f9f2b80ada2942a4e4f70d65626b32f) | feat | **mdc-chips:** switch to evolution API ([#23931](https://github.com/angular/components/pull/23931)) | | [723b77ad1f](https://github.com/angular/components/commit/723b77ad1fbff5c372202e8340011dcd1703ed20) | feat | **mdc-core:** add missing color, density, typography mixins ([#24063](https://github.com/angular/components/pull/24063)) | +| [407682012d](https://github.com/angular/components/commit/407682012df0e661898a3114d513b50eac805d83) | feat | **mdc-form-field:** Add option for dynamic su… ([#24241](https://github.com/angular/components/pull/24241)) | +| [871a500fb8](https://github.com/angular/components/commit/871a500fb808aaa9823ecac86df20ce8740c92fa) | feat | **mdc-list:** rework API to support secondary text with wrapping | +| [b0f38b7a64](https://github.com/angular/components/commit/b0f38b7a6425d99375a1e4ac7a986c8f4ceab9a7) | fix | **mdc-button:** remove unwanted native button styles ([#24186](https://github.com/angular/components/pull/24186)) | +| [c9ab38bcae](https://github.com/angular/components/commit/c9ab38bcaed0756ebe6c6ba537cc2f830924b4a2) | fix | **mdc-chips:** fix changed after checked error when restoring focus to input ([#24243](https://github.com/angular/components/pull/24243)) | +| [68a29ff1dd](https://github.com/angular/components/commit/68a29ff1dd059ab51b73ed5bcd2eec0c6432c16e) | fix | **mdc-core:** make mat-option typography easier to override ([#24247](https://github.com/angular/components/pull/24247)) | +| [b79406fee8](https://github.com/angular/components/commit/b79406fee8f36d93026dcdd617a142881b125f3a) | fix | **mdc-form-field:** Properly handle when defaults setting is 'dynamic' and the subscriptSizing input is not present. ([#24263](https://github.com/angular/components/pull/24263)) | +| [38affc3d43](https://github.com/angular/components/commit/38affc3d43f75e2608ee1530e6cd360b8b42073a) | fix | **mdc-list:** ensure selection change event fires properly ([#24174](https://github.com/angular/components/pull/24174)) | +| [c199aa2544](https://github.com/angular/components/commit/c199aa2544f0f0ca5b43e2fd9fa76bec17eea523) | fix | **mdc-list:** incorrect active/hover color for selected items | +| [1ce3e5e905](https://github.com/angular/components/commit/1ce3e5e905bcb7f019e3f2ed3f1ffa62021dc594) | perf | **mdc-checkbox:** reduce bundle size ([#24256](https://github.com/angular/components/pull/24256)) | +| [152c60ba12](https://github.com/angular/components/commit/152c60ba12dfc0e17b76ab1cb460dfb910c1868e) | perf | **mdc-radio:** reduce bundle size ([#24267](https://github.com/angular/components/pull/24267)) | +| [02c8f2aa02](https://github.com/angular/components/commit/02c8f2aa02fe90eef64dc074017c22d5703e943c) | perf | **mdc-tabs:** reduce bundle size ([#24262](https://github.com/angular/components/pull/24262)) | +### expansion-panel +| Commit | Type | Description | +| -- | -- | -- | +| [4ec34b5400](https://github.com/angular/components/commit/4ec34b5400efe38fab1b13d544d1bba618b8079e) | fix | title text not centered with taller description ([#12161](https://github.com/angular/components/pull/12161)) | +## Special Thanks +Amy Sorto, Andrew Seguin, Karl Seamon, Kristiyan Kostadinov, Miles Malerba, Paul Gschwendtner, Ruslan Lekhman, Wagner Maciel, Zach Arend, Zack Elliott, coopermeitz and renovate[bot] + + + + +# 13.1.3 "plastic-koala" (2022-01-19) +### cdk +| Commit | Type | Description | +| -- | -- | -- | +| [109d5a150f](https://github.com/angular/components/commit/109d5a150f7d59f8a10fd52a783d024ac4441493) | fix | **a11y:** not detecting fake mousedown on firefox ([#23493](https://github.com/angular/components/pull/23493)) | +| [c48742eb4e](https://github.com/angular/components/commit/c48742eb4e97979bd0030559236d7ab63f86dbe9) | fix | **table:** revert breaking change of CdkTable constructor ([#24202](https://github.com/angular/components/pull/24202)) | +### material +| Commit | Type | Description | +| -- | -- | -- | +| [70e0170b95](https://github.com/angular/components/commit/70e0170b950b00efdf3071bf24a2a32b199390b6) | fix | **autocomplete:** don't handle enter events with modifier keys ([#14717](https://github.com/angular/components/pull/14717)) | +| [eae436fdab](https://github.com/angular/components/commit/eae436fdab503f9d533f473812460b607ebe156a) | fix | **autocomplete:** optionSelections not emitting when the list of options changes ([#14813](https://github.com/angular/components/pull/14813)) | +| [402c07b3c7](https://github.com/angular/components/commit/402c07b3c7691edf6f8caae11fc3ca1113382a00) | fix | **autocomplete** restore focus after emitting option selected event ([#18707](https://github.com/angular/components/pull/18707)) | +| [761f9f25a8](https://github.com/angular/components/commit/761f9f25a8d6adce80ac7185dd21bef57669a1b9) | fix | **card:** handle picture element as mat-card-image ([#23678](https://github.com/angular/components/pull/23678)) | +| [3565cfac59](https://github.com/angular/components/commit/3565cfac59146612b9defb71531c91a104f07671) | fix | **core:** make MatOption generic ([#20242](https://github.com/angular/components/pull/20242)) | +| [f0272cf5eb](https://github.com/angular/components/commit/f0272cf5eb3a969f879ab1c538c633bd729aa976) | fix | **core:** throw error if hue does not exist ([#23612](https://github.com/angular/components/pull/23612)) | +| [304afaef1d](https://github.com/angular/components/commit/304afaef1d711c4e861a8603d10229a0b2a5637a) | fix | **datepicker:** add focus indication to calendar selected date in high contrast mode ([#22889](https://github.com/angular/components/pull/22889)) | +| [805eee8d07](https://github.com/angular/components/commit/805eee8d07ed12d1030ac0b0759029ab52036dc9) | fix | **form-field:** outline gap not recalculated when switching to empty label ([#23949](https://github.com/angular/components/pull/23949)) | +| [feac08f138](https://github.com/angular/components/commit/feac08f13843e3476245535a7fa5f3dfee04b027) | fix | **input:** inconsistently reading name from input with ngModel ([#19233](https://github.com/angular/components/pull/19233)) | +| [439ad2c59d](https://github.com/angular/components/commit/439ad2c59db31824ed6f4dcec16823f704852923) | fix | **list:** fix up disabled list item styles ([#18881](https://github.com/angular/components/pull/18881)) | +| [4182717c57](https://github.com/angular/components/commit/4182717c57abcfd5e93558ad368fb3dd143fb86d) | fix | **menu:** not interrupting keyboard events to other overlays ([#23310](https://github.com/angular/components/pull/23310)) | +| [a4f655856e](https://github.com/angular/components/commit/a4f655856ec4389d1e6b1f58d0884d3e54e42f93) | fix | **paginator:** allow readonly options ([#24054](https://github.com/angular/components/pull/24054)) | +| [966b2c52b7](https://github.com/angular/components/commit/966b2c52b7f8c8cd193114e33ab22c7b9569359a) | fix | **progress-bar:** unable to change value through property setter ([#19025](https://github.com/angular/components/pull/19025)) | +| [462cb6d713](https://github.com/angular/components/commit/462cb6d71322b41c91b06d179831f23cc3204206) | fix | **progress-spinner:** animation not working on some zoom levels in Safari ([#23674](https://github.com/angular/components/pull/23674)) | +| [94d466235a](https://github.com/angular/components/commit/94d466235abfdf9001c551dfd329a7cfbf4e58f3) | fix | **select** component value not in sync with control value on init ([#18443](https://github.com/angular/components/pull/18443)) | +| [ce9d8caa1f](https://github.com/angular/components/commit/ce9d8caa1f70aaf797c8d6f3c003561b10a00f8e) | fix | **sidenav:** end position sidenav tab order not matching visual order ([#18101](https://github.com/angular/components/pull/18101)) | +| [cb0a2ad940](https://github.com/angular/components/commit/cb0a2ad9400d1fd15deee1e596a093d99498ab82) | fix | **sidenav** implicit content element being registered twice with scroll dispatcher ([#13973](https://github.com/angular/components/pull/13973)) | +| [7be61b6357](https://github.com/angular/components/commit/7be61b6357af413a8c22e8ea949db7bc70d894ea) | fix | **slider:** avoid error on some touchstart events ([#23823](https://github.com/angular/components/pull/23823)) | +| [81528bc6a1](https://github.com/angular/components/commit/81528bc6a1fd8fa20f55620fdefb10d50db9ff1a) | fix | **slider:** first keypress ignored if out-of-bounds value is assigned ([#23827](https://github.com/angular/components/pull/23827)) | +| [64dd8ed8b5](https://github.com/angular/components/commit/64dd8ed8b5505ce0115bb81caa0d48a0647aa2e7) | fix | **slider:** incorrectly inheriting color when nested inside component with theme ([#21334](https://github.com/angular/components/pull/21334)) | +| [99e77829cc](https://github.com/angular/components/commit/99e77829cc51c85c60c768061e4b1c02cac6fe8f) | fix | **snack-bar:** handle long single-line content ([#24135](https://github.com/angular/components/pull/24135)) | +| [ad21ee20ae](https://github.com/angular/components/commit/ad21ee20aefb8d0744e9098b565422d987c808ed) | fix | **table** not clearing some internal references on destroy ([#16051](https://github.com/angular/components/pull/16051)) | +| [9752b1d18f](https://github.com/angular/components/commit/9752b1d18fae422c9eedc3ba81683697da93f18d) | fix | **table:** better handling of invalid data ([#18953](https://github.com/angular/components/pull/18953)) | +| [e01e579a49](https://github.com/angular/components/commit/e01e579a498b39577b618c3e8e0a01b69477b087) | fix | **tooltip:** not closing if escape is pressed while trigger isn't focused ([#14434](https://github.com/angular/components/pull/14434)) | +| [4972dc5585](https://github.com/angular/components/commit/4972dc5585d7ae8c66ccb819367f27d87f0a2d74) | perf | **button:** do not run change detection when the anchor is clicked ([#23992](https://github.com/angular/components/pull/23992)) | +### material-experimental +| Commit | Type | Description | +| -- | -- | -- | +| [fe39b55f93](https://github.com/angular/components/commit/fe39b55f934a75bb2f8c9786da6a67245010102d) | fix | **mdc-checkbox:** emitting fallback values for density CSS variables ([#24184](https://github.com/angular/components/pull/24184)) | +| [0ab3dce58a](https://github.com/angular/components/commit/0ab3dce58a8ac35b328537b9ef76403dfff02969) | fix | **mdc-snack-bar:** avoid hard reference to base components and align API ([#21425](https://github.com/angular/components/pull/21425)) | + +## Special Thanks +Andrew Seguin, Artur Androsovych, Jeri Peier, Joey Perrott, Kristiyan Kostadinov, Paul Gschwendtner and Ruslan Lekhman + + + + +# 13.1.2 "rubber-road" (2022-01-12) +### cdk +| Commit | Type | Description | +| -- | -- | -- | +| [37898c3c1](https://github.com/angular/components/commit/37898c3c1e1919487b21a5fe4b3c3a94c906aba8) | fix | **overlay:** fix positioning when zooming in Safari ([#24160](https://github.com/angular/components/pull/24160)) | +| [af1882311](https://github.com/angular/components/commit/af18823115c6958fe69b20496af47cfaee46c765) | fix | **schematics:** remove file extensions in tilde migration ([#24169](https://github.com/angular/components/pull/24169)) | +| [db5d8cea2](https://github.com/angular/components/commit/db5d8cea2bed25a61c3865aae41b9ecd8945508f) | fix | **table:** Measure column width for sticky columns after new data has rendered. ([#23885](https://github.com/angular/components/pull/23885)) | +| [7705cae78](https://github.com/angular/components/commit/7705cae785803dd17fab47774ef305a1c39f074d) | fix | **text-field:** handle undefined placeholder ([#24159](https://github.com/angular/components/pull/24159)) | +### material +| Commit | Type | Description | +| -- | -- | -- | +| [69753d711](https://github.com/angular/components/commit/69753d71133f8297036fe0773bb759c7e2e02716) | fix | **core:** disable strong focus indicators in high contrast mode ([#24120](https://github.com/angular/components/pull/24120)) | +| [0631976ca](https://github.com/angular/components/commit/0631976ca79513807902e240f4378a17fa884c7b) | fix | **core:** move pseudo-checkbox module to same directory ([#24132](https://github.com/angular/components/pull/24132)) | +| [c6f7b9468](https://github.com/angular/components/commit/c6f7b946888568a36c56d2db7dd708fd82b08c85) | fix | **datepicker:** fix duplicate nav stop with Voiceover ([#24085](https://github.com/angular/components/pull/24085)) | +| [2ca59f8a6](https://github.com/angular/components/commit/2ca59f8a6a8028bd42759d9e1de803bdaeca034a) | fix | **stepper:** icon not centered in header if direction changes ([#24131](https://github.com/angular/components/pull/24131)) | +### material-experimental +| Commit | Type | Description | +| -- | -- | -- | +| [a7d97d618](https://github.com/angular/components/commit/a7d97d618f9104367775d304a81d04db55e33071) | fix | **mdc-button:** incorrect metadata for fab anchor ([#24179](https://github.com/angular/components/pull/24179)) | +| [ae9f3d5f5](https://github.com/angular/components/commit/ae9f3d5f5119c3c24e5d6d0efad64a298cb1719c) | fix | **mdc-checkbox:** switch to non-deprecated styles ([#23218](https://github.com/angular/components/pull/23218)) | +| [2f668888f](https://github.com/angular/components/commit/2f668888fefa9ed68f872b2f9a49af95b17e54b6) | fix | **mdc-dialog:** remove extra outline in high contrast mode ([#24140](https://github.com/angular/components/pull/24140)) | +| [12f427cdc](https://github.com/angular/components/commit/12f427cdca4e436ee55a6adcc0ece2f77d53db22) | fix | **mdc-list:** export missing harness symbols ([#24175](https://github.com/angular/components/pull/24175)) | +| [eb508be13](https://github.com/angular/components/commit/eb508be1365d21140ebbd56d57bb454d38681bf8) | fix | **mdc-select:** change max height to show scrollability ([#24129](https://github.com/angular/components/pull/24129)) | +| [997589dd8](https://github.com/angular/components/commit/997589dd8dee5ab21e711caa07e2275c77e4b6b3) | fix | **mdc-slide-toggle:** remove aria-required rather than setting to false ([#24105](https://github.com/angular/components/pull/24105)) | +| [be21308bb](https://github.com/angular/components/commit/be21308bbffe7dd5764ea01a34de887720b6efcd) | fix | **mdc-slider:** keep value indicator within bounds ([#24167](https://github.com/angular/components/pull/24167)) | +### multiple +| Commit | Type | Description | +| -- | -- | -- | +| [32f33c6dc](https://github.com/angular/components/commit/32f33c6dcc850c8e7b8623af06107601e70f1ae7) | fix | correct tooltip and table MDC style import paths ([#24077](https://github.com/angular/components/pull/24077)) | ## Special Thanks -Amy Sorto, Miles Malerba and Wagner Maciel +Andrew Seguin, Jeremy Elbourn, Jeri Peier, Karl Seamon, Kristiyan Kostadinov, Lukas Spirig, Miles Malerba, Paul Gschwendtner, Pei Wang, Wagner Maciel, Zach Arend and batnyu @@ -5408,4 +5535,4 @@ You can view a beta version of the docs at https://beta-angular-material-io.fire # Changes Prior to 7.0.0 -To view changes that occurred prior to 7.0.0, see [CHANGELOG_ARCHIVE.md](https://github.com/angular/components/blob/master/CHANGELOG_ARCHIVE.md). \ No newline at end of file +To view changes that occurred prior to 7.0.0, see [CHANGELOG_ARCHIVE.md](https://github.com/angular/components/blob/master/CHANGELOG_ARCHIVE.md). diff --git a/DEV_ENVIRONMENT.md b/DEV_ENVIRONMENT.md index 2b5024063fe2..d8313f9c82e6 100644 --- a/DEV_ENVIRONMENT.md +++ b/DEV_ENVIRONMENT.md @@ -78,8 +78,18 @@ export HUSKY=0 ``` ### Injecting variables into the dev app -Variables can be injected into the dev app by creating the `src/dev-app/variables.json` file. -They'll be made available under the `window.DEV_APP_VARIABLES` object. The file isn't checked into -Git and it can be used to pass private configuration like API keys. Variables currently being used: + +A set of environment variables is made available within the dev-app. Such variables +will be injected into the dev-app, so that e.g. API keys can be used for development +without requiring secrets to be committed. + +The following variables are currently used in the dev-app: * `GOOGLE_MAPS_KEY` - Optional key for the Google Maps API. + +For example, you can store a personal development Google Maps API key for the +dev-app within your `.bashrc` or `.zshrc` file. + +```bash +export GOOGLE_MAPS_KEY= +``` \ No newline at end of file diff --git a/WORKSPACE b/WORKSPACE index 6ddbefcc1193..9b937e035efe 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -16,10 +16,10 @@ http_archive( # Add sass rules http_archive( name = "io_bazel_rules_sass", - sha256 = "435efe759f1c8baffadc320ecc1830454da181fa790aa83bb4326f07e903a0f4", - strip_prefix = "rules_sass-1.41.0", + sha256 = "903858e0fb5eda0b36d37e1ce4cbcfbe03f65a5f153d894dc8a9894a4884e564", + strip_prefix = "rules_sass-1.49.0", urls = [ - "https://github.com/bazelbuild/rules_sass/archive/1.41.0.zip", + "https://github.com/bazelbuild/rules_sass/archive/1.49.0.zip", ], ) diff --git a/guides/using-component-harnesses.md b/guides/using-component-harnesses.md index b362df7ff3ba..f763722e190d 100644 --- a/guides/using-component-harnesses.md +++ b/guides/using-component-harnesses.md @@ -28,14 +28,14 @@ The following sections will illustrate these benefits in more detail. ## Which kinds of tests can use harnesses? The Angular CDK's component harnesses are designed to work in multiple different test environments. -Support currently includes Angular's Testbed environment in Karma unit tests and Protractor +Support currently includes Angular's Testbed environment in Karma unit tests and Selenium WebDriver end-to-end (e2e) tests. You can also support additional environments by creating custom extensions of the CDK's `HarnessEnvironment` and `TestElement` classes. ## Getting started The foundation for all test harnesses lives in `@angular/cdk/testing`. Start by importing either -`TestbedHarnessEnvironment` or `ProtractorHarnessEnvironment` based on whether you're writing a +`TestbedHarnessEnvironment` or `SeleniumWebDriverHarnessEnvironment` based on whether you're writing a unit test or an e2e test. From the `HarnessEnvironment`, you can get a `HarnessLoader` instance, which you will use to load Angular Material component harnesses. For example, if we're writing unit tests for a `UserProfile` component, the code might look like this: @@ -64,8 +64,8 @@ different paths. - `@angular/cdk/testing` contains symbols that are shared regardless of the environment your tests are in. - `@angular/cdk/testing/testbed` contains symbols that are used only in Karma tests. -- `@angular/cdk/testing/protractor` (not shown above) contains symbols that are used only in - Protractor tests. +- `@angular/cdk/testing/selenium-webdriver` (not shown above) contains symbols that are used only in + Selenium WebDriver tests. ## Loading an Angular Material harness diff --git a/integration/harness-e2e-cli/.browserslistrc b/integration/harness-e2e-cli/.browserslistrc new file mode 100644 index 000000000000..4f9ac26980c1 --- /dev/null +++ b/integration/harness-e2e-cli/.browserslistrc @@ -0,0 +1,16 @@ +# This file is used by the build system to adjust CSS and JS output to support the specified browsers below. +# For additional information regarding the format and rule options, please see: +# https://github.com/browserslist/browserslist#queries + +# For the full list of supported browsers by the Angular framework, please see: +# https://angular.io/guide/browser-support + +# You can see what browsers were selected by your queries by running: +# npx browserslist + +last 1 Chrome version +last 1 Firefox version +last 2 Edge major versions +last 2 Safari major versions +last 2 iOS major versions +Firefox ESR diff --git a/integration/harness-e2e-cli/.editorconfig b/integration/harness-e2e-cli/.editorconfig new file mode 100644 index 000000000000..59d9a3a3e73f --- /dev/null +++ b/integration/harness-e2e-cli/.editorconfig @@ -0,0 +1,16 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.ts] +quote_type = single + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/integration/harness-e2e-cli/.gitignore b/integration/harness-e2e-cli/.gitignore new file mode 100644 index 000000000000..105c00f22e08 --- /dev/null +++ b/integration/harness-e2e-cli/.gitignore @@ -0,0 +1,46 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# compiled output +/dist +/tmp +/out-tsc +# Only exists if Bazel was run +/bazel-out + +# dependencies +/node_modules + +# profiling files +chrome-profiler-events*.json + +# IDEs and editors +/.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +.history/* + +# misc +/.angular/cache +/.sass-cache +/connect.lock +/coverage +/libpeerconnection.log +npm-debug.log +yarn-error.log +testem.log +/typings + +# System Files +.DS_Store +Thumbs.db diff --git a/integration/harness-e2e-cli/BUILD.bazel b/integration/harness-e2e-cli/BUILD.bazel new file mode 100644 index 000000000000..96db42e63d2b --- /dev/null +++ b/integration/harness-e2e-cli/BUILD.bazel @@ -0,0 +1,30 @@ +load("@bazel_skylib//lib:dicts.bzl", "dicts") +load("//tools:integration.bzl", "CLI_PROJECT_MAPPINGS") +load("//tools:defaults.bzl", "node_integration_test") + +npmPackageMappings = dicts.add( + CLI_PROJECT_MAPPINGS, + { + "//src/cdk:npm_package_archive": "@angular/cdk", + "//src/material:npm_package_archive": "@angular/material", + }, +) + +node_integration_test( + name = "test", + srcs = glob(["**/*"]), + commands = [ + # Note: We use a cache folder within the integration test as otherwise + # the NPM package mapped archive would be cached in the system. + # See: https://github.com/yarnpkg/yarn/issues/2165. + # TODO(devversion): determine if a solution/workaround could live in the test runner. + "yarn install --cache-folder .yarn_cache_folder/", + "yarn e2e", + ], + npm_packages = npmPackageMappings, + setup_chromium = True, + tags = [ + # This test relies on `yarn` so there needs to be internet access. + "requires-network", + ], +) diff --git a/integration/harness-e2e-cli/README.md b/integration/harness-e2e-cli/README.md new file mode 100644 index 000000000000..f439edb6007f --- /dev/null +++ b/integration/harness-e2e-cli/README.md @@ -0,0 +1,27 @@ +# HarnessE2eCli + +This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 13.2.0-next.1. + +## Development server + +Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. + +## Code scaffolding + +Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. + +## Build + +Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. + +## Running unit tests + +Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). + +## Running end-to-end tests + +Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities. + +## Further help + +To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page. diff --git a/integration/harness-e2e-cli/angular.json b/integration/harness-e2e-cli/angular.json new file mode 100644 index 000000000000..b3a1e66d2325 --- /dev/null +++ b/integration/harness-e2e-cli/angular.json @@ -0,0 +1,111 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "harness-e2e-cli": { + "projectType": "application", + "schematics": { + "@schematics/angular:component": { + "style": "scss" + }, + "@schematics/angular:application": { + "strict": true + } + }, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "dist/harness-e2e-cli", + "index": "src/index.html", + "main": "src/main.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "src/favicon.ico", + "src/assets" + ], + "styles": [ + "src/styles.scss" + ], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "browserTarget": "harness-e2e-cli:build:production" + }, + "development": { + "browserTarget": "harness-e2e-cli:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "browserTarget": "harness-e2e-cli:build" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "src/test.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "tsconfig.spec.json", + "karmaConfig": "karma.conf.js", + "inlineStyleLanguage": "scss", + "assets": [ + "src/favicon.ico", + "src/assets" + ], + "styles": [ + "src/styles.scss" + ], + "scripts": [] + } + } + } + } + }, + "defaultProject": "harness-e2e-cli" +} diff --git a/integration/harness-e2e-cli/e2e/driver.ts b/integration/harness-e2e-cli/e2e/driver.ts new file mode 100644 index 000000000000..4290ab111508 --- /dev/null +++ b/integration/harness-e2e-cli/e2e/driver.ts @@ -0,0 +1,19 @@ +import {Builder} from 'selenium-webdriver'; +import { + ServiceBuilder, + Options as ChromeOptions, + setDefaultService, +} from 'selenium-webdriver/chrome.js'; + +export function configureDriver() { + const options = new ChromeOptions(); + const service = new ServiceBuilder(process.env['CHROMEDRIVER_BIN']!); + + options.headless(); + options.addArguments('--no-sandbox'); + options.setChromeBinaryPath(process.env['CHROME_BIN']!); + + setDefaultService(service.build()); + + return new Builder().forBrowser('chrome').setChromeOptions(options).build(); +} diff --git a/integration/harness-e2e-cli/e2e/jasmine.json b/integration/harness-e2e-cli/e2e/jasmine.json new file mode 100644 index 000000000000..a48eaf5e5f57 --- /dev/null +++ b/integration/harness-e2e-cli/e2e/jasmine.json @@ -0,0 +1,9 @@ +{ + "spec_dir": "e2e", + "spec_files": [ + "**/*.spec.ts" + ], + "env": { + "random": true + } +} diff --git a/integration/harness-e2e-cli/e2e/package.json b/integration/harness-e2e-cli/e2e/package.json new file mode 100644 index 000000000000..472002573ef7 --- /dev/null +++ b/integration/harness-e2e-cli/e2e/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/integration/harness-e2e-cli/e2e/select-harness.spec.ts b/integration/harness-e2e-cli/e2e/select-harness.spec.ts new file mode 100644 index 000000000000..ef214cff63bc --- /dev/null +++ b/integration/harness-e2e-cli/e2e/select-harness.spec.ts @@ -0,0 +1,32 @@ +import {MatSelectHarness} from '@angular/material/select/testing'; +import {SeleniumWebDriverHarnessEnvironment} from '@angular/cdk/testing/selenium-webdriver'; +import {HarnessLoader} from '@angular/cdk/testing'; +import {configureDriver} from './driver.js'; + +describe('app test', () => { + let loader: HarnessLoader; + + beforeEach(async () => { + const driver = await configureDriver(); + + await driver.get('http://localhost:4200'); + + loader = SeleniumWebDriverHarnessEnvironment.loader(driver); + }); + + it('should work', async () => { + const select = await loader.getHarness(MatSelectHarness); + + expect(select).toBeDefined(); + expect(await select.getValueText()).toBe(''); + + await select.open(); + + const options = await select.getOptions(); + + await options[0].click(); + await select.close(); + + expect(await select.getValueText()).toBe('First'); + }); +}); diff --git a/integration/harness-e2e-cli/e2e/tsconfig.json b/integration/harness-e2e-cli/e2e/tsconfig.json new file mode 100644 index 000000000000..6b985880fd35 --- /dev/null +++ b/integration/harness-e2e-cli/e2e/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "module": "es2020", + "target": "es2020", + "moduleResolution": "node", + } +} diff --git a/integration/harness-e2e-cli/karma.conf.js b/integration/harness-e2e-cli/karma.conf.js new file mode 100644 index 000000000000..1f700a8e6126 --- /dev/null +++ b/integration/harness-e2e-cli/karma.conf.js @@ -0,0 +1,41 @@ +// Karma configuration file, see link for more information +// https://karma-runner.github.io/1.0/config/configuration-file.html + +module.exports = function (config) { + config.set({ + basePath: '', + frameworks: ['jasmine', '@angular-devkit/build-angular'], + plugins: [ + require('karma-jasmine'), + require('karma-chrome-launcher'), + require('karma-jasmine-html-reporter'), + require('karma-coverage'), + require('@angular-devkit/build-angular/plugins/karma'), + ], + client: { + jasmine: { + // you can add configuration options for Jasmine here + // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html + // for example, you can disable the random execution with `random: false` + // or set a specific seed with `seed: 4321` + }, + clearContext: false, // leave Jasmine Spec Runner output visible in browser + }, + jasmineHtmlReporter: { + suppressAll: true, // removes the duplicated traces + }, + coverageReporter: { + dir: require('path').join(__dirname, './coverage/harness-e2e-cli'), + subdir: '.', + reporters: [{type: 'html'}, {type: 'text-summary'}], + }, + reporters: ['progress', 'kjhtml'], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: true, + browsers: ['Chrome'], + singleRun: false, + restartOnFileChange: true, + }); +}; diff --git a/integration/harness-e2e-cli/package.json b/integration/harness-e2e-cli/package.json new file mode 100644 index 000000000000..1d379b9888a5 --- /dev/null +++ b/integration/harness-e2e-cli/package.json @@ -0,0 +1,50 @@ +{ + "name": "harness-e2e-cli", + "version": "0.0.0", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "watch": "ng build --watch --configuration development", + "test": "ng test", + "run-e2e-specs": "node --loader ts-node/esm node_modules/jasmine/bin/jasmine --config=e2e/jasmine.json", + "wait-and-run-e2e": "wait-on http://localhost:4200 && yarn run-e2e-specs", + "e2e": "concurrently -s first -k 'ng serve' 'yarn wait-and-run-e2e'" + }, + "private": true, + "dependencies": { + "@angular/animations": "file:../../node_modules/@angular/animations", + "@angular/cdk": "file:../../dist/releases/cdk", + "@angular/common": "file:../../node_modules/@angular/common", + "@angular/compiler": "file:../../node_modules/@angular/compiler", + "@angular/core": "file:../../node_modules/@angular/core", + "@angular/forms": "file:../../node_modules/@angular/forms", + "@angular/material": "file:../../dist/releases/material", + "@angular/platform-browser": "file:../../node_modules/@angular/platform-browser", + "@angular/platform-browser-dynamic": "file:../../node_modules/@angular/platform-browser-dynamic", + "@angular/router": "file:../../node_modules/@angular/router", + "rxjs": "file:../../node_modules/rxjs", + "tslib": "^2.3.0", + "zone.js": "~0.11.4" + }, + "devDependencies": { + "@angular-devkit/build-angular": "file:../../node_modules/@angular-devkit/build-angular", + "@angular/cli": "file:../../node_modules/@angular/cli", + "@angular/compiler-cli": "file:../../node_modules/@angular/compiler-cli", + "@types/jasmine": "~3.10.0", + "@types/node": "^12.11.1", + "@types/selenium-webdriver": "3.0.19", + "concurrently": "^7.0.0", + "jasmine": "^4.0.2", + "jasmine-core": "~3.10.0", + "karma": "~6.3.0", + "karma-chrome-launcher": "~3.1.0", + "karma-coverage": "~2.1.0", + "karma-jasmine": "~4.0.0", + "karma-jasmine-html-reporter": "~1.7.0", + "selenium-webdriver": "3.6.0", + "ts-node": "~9.1.1", + "typescript": "file:../../node_modules/typescript", + "wait-on": "^6.0.0" + } +} diff --git a/integration/harness-e2e-cli/src/app/app.component.html b/integration/harness-e2e-cli/src/app/app.component.html new file mode 100644 index 000000000000..821796b3e8d3 --- /dev/null +++ b/integration/harness-e2e-cli/src/app/app.component.html @@ -0,0 +1,7 @@ + + Select + + First + Second + + \ No newline at end of file diff --git a/integration/harness-e2e-cli/src/app/app.component.scss b/integration/harness-e2e-cli/src/app/app.component.scss new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/integration/harness-e2e-cli/src/app/app.component.ts b/integration/harness-e2e-cli/src/app/app.component.ts new file mode 100644 index 000000000000..f88943010790 --- /dev/null +++ b/integration/harness-e2e-cli/src/app/app.component.ts @@ -0,0 +1,10 @@ +import {Component} from '@angular/core'; + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.scss'], +}) +export class AppComponent { + title = 'harness-e2e-cli'; +} diff --git a/integration/harness-e2e-cli/src/app/app.module.ts b/integration/harness-e2e-cli/src/app/app.module.ts new file mode 100644 index 000000000000..51f8c24f3962 --- /dev/null +++ b/integration/harness-e2e-cli/src/app/app.module.ts @@ -0,0 +1,15 @@ +import {NgModule} from '@angular/core'; +import {BrowserModule} from '@angular/platform-browser'; +import {NoopAnimationsModule} from '@angular/platform-browser/animations'; + +import {AppComponent} from './app.component'; +import {MatSelectModule} from '@angular/material/select'; +import {MatFormFieldModule} from '@angular/material/form-field'; + +@NgModule({ + declarations: [AppComponent], + imports: [MatSelectModule, MatFormFieldModule, NoopAnimationsModule, BrowserModule], + providers: [], + bootstrap: [AppComponent], +}) +export class AppModule {} diff --git a/integration/harness-e2e-cli/src/assets/.gitkeep b/integration/harness-e2e-cli/src/assets/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/integration/harness-e2e-cli/src/environments/environment.prod.ts b/integration/harness-e2e-cli/src/environments/environment.prod.ts new file mode 100644 index 000000000000..c9669790be17 --- /dev/null +++ b/integration/harness-e2e-cli/src/environments/environment.prod.ts @@ -0,0 +1,3 @@ +export const environment = { + production: true, +}; diff --git a/integration/harness-e2e-cli/src/environments/environment.ts b/integration/harness-e2e-cli/src/environments/environment.ts new file mode 100644 index 000000000000..66998ae9a7c2 --- /dev/null +++ b/integration/harness-e2e-cli/src/environments/environment.ts @@ -0,0 +1,16 @@ +// This file can be replaced during build by using the `fileReplacements` array. +// `ng build` replaces `environment.ts` with `environment.prod.ts`. +// The list of file replacements can be found in `angular.json`. + +export const environment = { + production: false, +}; + +/* + * For easier debugging in development mode, you can import the following file + * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. + * + * This import should be commented out in production mode because it will have a negative impact + * on performance if an error is thrown. + */ +// import 'zone.js/plugins/zone-error'; // Included with Angular CLI. diff --git a/integration/harness-e2e-cli/src/favicon.ico b/integration/harness-e2e-cli/src/favicon.ico new file mode 100644 index 000000000000..997406ad22c2 Binary files /dev/null and b/integration/harness-e2e-cli/src/favicon.ico differ diff --git a/integration/harness-e2e-cli/src/index.html b/integration/harness-e2e-cli/src/index.html new file mode 100644 index 000000000000..60b9e739421b --- /dev/null +++ b/integration/harness-e2e-cli/src/index.html @@ -0,0 +1,13 @@ + + + + + HarnessE2eCli + + + + + + + + diff --git a/integration/harness-e2e-cli/src/main.ts b/integration/harness-e2e-cli/src/main.ts new file mode 100644 index 000000000000..947bb036a501 --- /dev/null +++ b/integration/harness-e2e-cli/src/main.ts @@ -0,0 +1,13 @@ +import {enableProdMode} from '@angular/core'; +import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; + +import {AppModule} from './app/app.module'; +import {environment} from './environments/environment'; + +if (environment.production) { + enableProdMode(); +} + +platformBrowserDynamic() + .bootstrapModule(AppModule) + .catch(err => console.error(err)); diff --git a/integration/harness-e2e-cli/src/polyfills.ts b/integration/harness-e2e-cli/src/polyfills.ts new file mode 100644 index 000000000000..e4555ed11fa2 --- /dev/null +++ b/integration/harness-e2e-cli/src/polyfills.ts @@ -0,0 +1,52 @@ +/** + * This file includes polyfills needed by Angular and is loaded before the app. + * You can add your own extra polyfills to this file. + * + * This file is divided into 2 sections: + * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. + * 2. Application imports. Files imported after ZoneJS that should be loaded before your main + * file. + * + * The current setup is for so-called "evergreen" browsers; the last versions of browsers that + * automatically update themselves. This includes recent versions of Safari, Chrome (including + * Opera), Edge on the desktop, and iOS and Chrome on mobile. + * + * Learn more in https://angular.io/guide/browser-support + */ + +/*************************************************************************************************** + * BROWSER POLYFILLS + */ + +/** + * By default, zone.js will patch all possible macroTask and DomEvents + * user can disable parts of macroTask/DomEvents patch by setting following flags + * because those flags need to be set before `zone.js` being loaded, and webpack + * will put import in the top of bundle, so user need to create a separate file + * in this directory (for example: zone-flags.ts), and put the following flags + * into that file, and then add the following code before importing zone.js. + * import './zone-flags'; + * + * The flags allowed in zone-flags.ts are listed here. + * + * The following flags will work for all browsers. + * + * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame + * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick + * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames + * + * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js + * with the following flag, it will bypass `zone.js` patch for IE/Edge + * + * (window as any).__Zone_enable_cross_context_check = true; + * + */ + +/*************************************************************************************************** + * Zone JS is required by default for Angular itself. + */ +import 'zone.js'; // Included with Angular CLI. + +/*************************************************************************************************** + * APPLICATION IMPORTS + */ diff --git a/integration/harness-e2e-cli/src/styles.scss b/integration/harness-e2e-cli/src/styles.scss new file mode 100644 index 000000000000..3294246f8703 --- /dev/null +++ b/integration/harness-e2e-cli/src/styles.scss @@ -0,0 +1 @@ +@import '@angular/material/prebuilt-themes/indigo-pink.css'; \ No newline at end of file diff --git a/integration/harness-e2e-cli/src/test.ts b/integration/harness-e2e-cli/src/test.ts new file mode 100644 index 000000000000..ce6458d19576 --- /dev/null +++ b/integration/harness-e2e-cli/src/test.ts @@ -0,0 +1,27 @@ +// This file is required by karma.conf.js and loads recursively all the .spec and framework files + +import 'zone.js/testing'; +import {getTestBed} from '@angular/core/testing'; +import { + BrowserDynamicTestingModule, + platformBrowserDynamicTesting, +} from '@angular/platform-browser-dynamic/testing'; + +declare const require: { + context( + path: string, + deep?: boolean, + filter?: RegExp, + ): { + (id: string): T; + keys(): string[]; + }; +}; + +// First, initialize the Angular testing environment. +getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting()); + +// Then we find all the tests. +const context = require.context('./', true, /\.spec\.ts$/); +// And load the modules. +context.keys().map(context); diff --git a/integration/harness-e2e-cli/tsconfig.app.json b/integration/harness-e2e-cli/tsconfig.app.json new file mode 100644 index 000000000000..82d91dc4a4de --- /dev/null +++ b/integration/harness-e2e-cli/tsconfig.app.json @@ -0,0 +1,15 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/app", + "types": [] + }, + "files": [ + "src/main.ts", + "src/polyfills.ts" + ], + "include": [ + "src/**/*.d.ts" + ] +} diff --git a/integration/harness-e2e-cli/tsconfig.json b/integration/harness-e2e-cli/tsconfig.json new file mode 100644 index 000000000000..f531992d6edc --- /dev/null +++ b/integration/harness-e2e-cli/tsconfig.json @@ -0,0 +1,32 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./", + "outDir": "./dist/out-tsc", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "sourceMap": true, + "declaration": false, + "downlevelIteration": true, + "experimentalDecorators": true, + "moduleResolution": "node", + "importHelpers": true, + "target": "es2017", + "module": "es2020", + "lib": [ + "es2020", + "dom" + ] + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/integration/harness-e2e-cli/tsconfig.spec.json b/integration/harness-e2e-cli/tsconfig.spec.json new file mode 100644 index 000000000000..092345b02e80 --- /dev/null +++ b/integration/harness-e2e-cli/tsconfig.spec.json @@ -0,0 +1,18 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/spec", + "types": [ + "jasmine" + ] + }, + "files": [ + "src/test.ts", + "src/polyfills.ts" + ], + "include": [ + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/integration/harness-e2e-cli/yarn.lock b/integration/harness-e2e-cli/yarn.lock new file mode 100644 index 000000000000..b46862b8708a --- /dev/null +++ b/integration/harness-e2e-cli/yarn.lock @@ -0,0 +1,6450 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@ampproject/remapping@1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-1.0.2.tgz#a7ebbadb71517dd63298420868f27d98fe230a0a" + integrity sha512-SncaVxs+E3EdoA9xJgHfWPxZfowAgeIsd71VpqCKP6KNKm6s7zSqqvUc70UpKUFsrV3dAmy6qxHoIj5NG+3DiA== + dependencies: + "@jridgewell/resolve-uri" "1.0.0" + sourcemap-codec "1.4.8" + +"@angular-devkit/architect@0.1302.0-next.1": + version "0.1302.0-next.1" + resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.1302.0-next.1.tgz#2668f797be01528b063892c7226dabc131f6f5af" + integrity sha512-iIoXlrview9QiMFx/g+p+OnfjPKNU71YwzPBoJRhI4c/yUv7d2dtCxOyZXK+d5a3aXdiDMccIM+DKEUon+LfCA== + dependencies: + "@angular-devkit/core" "13.2.0-next.1" + rxjs "6.6.7" + +"@angular-devkit/build-angular@file:../../node_modules/@angular-devkit/build-angular": + version "13.2.0-next.1" + dependencies: + "@ampproject/remapping" "1.0.2" + "@angular-devkit/architect" "0.1302.0-next.1" + "@angular-devkit/build-webpack" "0.1302.0-next.1" + "@angular-devkit/core" "13.2.0-next.1" + "@babel/core" "7.16.5" + "@babel/generator" "7.16.5" + "@babel/helper-annotate-as-pure" "7.16.0" + "@babel/plugin-proposal-async-generator-functions" "7.16.5" + "@babel/plugin-transform-async-to-generator" "7.16.5" + "@babel/plugin-transform-runtime" "7.16.5" + "@babel/preset-env" "7.16.5" + "@babel/runtime" "7.16.5" + "@babel/template" "7.16.0" + "@discoveryjs/json-ext" "0.5.6" + "@ngtools/webpack" "13.2.0-next.1" + ansi-colors "4.1.1" + babel-loader "8.2.3" + babel-plugin-istanbul "6.1.1" + browserslist "^4.9.1" + cacache "15.3.0" + circular-dependency-plugin "5.2.2" + copy-webpack-plugin "10.1.0" + core-js "3.19.3" + critters "0.0.15" + css-loader "6.5.1" + esbuild-wasm "0.14.5" + glob "7.2.0" + https-proxy-agent "5.0.0" + inquirer "8.2.0" + jsonc-parser "3.0.0" + karma-source-map-support "1.4.0" + less "4.1.2" + less-loader "10.2.0" + license-webpack-plugin "4.0.0" + loader-utils "3.2.0" + mini-css-extract-plugin "2.4.5" + minimatch "3.0.4" + open "8.4.0" + ora "5.4.1" + parse5-html-rewriting-stream "6.0.1" + piscina "3.2.0" + postcss "8.4.5" + postcss-import "14.0.2" + postcss-loader "6.2.1" + postcss-preset-env "6.7.0" + regenerator-runtime "0.13.9" + resolve-url-loader "4.0.0" + rxjs "6.6.7" + sass "1.45.0" + sass-loader "12.4.0" + semver "7.3.5" + source-map-loader "3.0.0" + source-map-support "0.5.21" + stylus "0.55.0" + stylus-loader "6.2.0" + terser "5.10.0" + text-table "0.2.0" + tree-kill "1.2.2" + tslib "2.3.1" + webpack "5.65.0" + webpack-dev-middleware "5.2.2" + webpack-dev-server "4.6.0" + webpack-merge "5.8.0" + webpack-subresource-integrity "5.0.0" + optionalDependencies: + esbuild "0.14.5" + +"@angular-devkit/build-webpack@0.1302.0-next.1": + version "0.1302.0-next.1" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.1302.0-next.1.tgz#f4b417f800f2a168eb49d1562c75d3bde6b912bd" + integrity sha512-+e0A6JkjFtGIOiC9duEGHvvqoNbpKu1TBxjyL26Ou8Kgd0vRoyuKvUdDBPO9pqQcrApcB50RCFH5SGkLB06ZkQ== + dependencies: + "@angular-devkit/architect" "0.1302.0-next.1" + rxjs "6.6.7" + +"@angular-devkit/core@13.2.0-next.1": + version "13.2.0-next.1" + resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-13.2.0-next.1.tgz#599b8ad65db6d19fef03aaacfe526f3d744e8db3" + integrity sha512-a0WbgZifWm+H8dIsODq2yS3MlLxMkPRr2nioxSPdk/l6JYqgpNms+E0jv/nU4WxBIiloPIFik/223VZoddrJww== + dependencies: + ajv "8.8.2" + ajv-formats "2.1.1" + fast-json-stable-stringify "2.1.0" + magic-string "0.25.7" + rxjs "6.6.7" + source-map "0.7.3" + +"@angular-devkit/schematics@13.2.0-next.1": + version "13.2.0-next.1" + resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-13.2.0-next.1.tgz#367a9d782107d5da1fc4a30ccdec4c135af2b09d" + integrity sha512-90UJD+kujR+zAOqfb942P0AQkMcEVdkkAihP7yNSsMSrN5tukTZ45aeBfMvM7gnivqg+ojzGk5mnToM7VhEEIg== + dependencies: + "@angular-devkit/core" "13.2.0-next.1" + jsonc-parser "3.0.0" + magic-string "0.25.7" + ora "5.4.1" + rxjs "6.6.7" + +"@angular/animations@file:../../node_modules/@angular/animations": + version "13.2.0-next.2" + dependencies: + tslib "^2.3.0" + +"@angular/cdk@file:../../dist/releases/cdk": + version "13.0.0-next.7" + dependencies: + tslib "^2.3.0" + optionalDependencies: + parse5 "^5.0.0" + +"@angular/cli@file:../../node_modules/@angular/cli": + version "13.2.0-next.1" + dependencies: + "@angular-devkit/architect" "0.1302.0-next.1" + "@angular-devkit/core" "13.2.0-next.1" + "@angular-devkit/schematics" "13.2.0-next.1" + "@schematics/angular" "13.2.0-next.1" + "@yarnpkg/lockfile" "1.1.0" + ansi-colors "4.1.1" + debug "4.3.3" + ini "2.0.0" + inquirer "8.2.0" + jsonc-parser "3.0.0" + npm-package-arg "8.1.5" + npm-pick-manifest "6.1.1" + open "8.4.0" + ora "5.4.1" + pacote "12.0.2" + resolve "1.20.0" + semver "7.3.5" + symbol-observable "4.0.0" + uuid "8.3.2" + +"@angular/common@file:../../node_modules/@angular/common": + version "13.2.0-next.2" + dependencies: + tslib "^2.3.0" + +"@angular/compiler-cli@file:../../node_modules/@angular/compiler-cli": + version "13.2.0-next.2" + dependencies: + "@babel/core" "^7.8.6" + canonical-path "1.0.0" + chokidar "^3.0.0" + convert-source-map "^1.5.1" + dependency-graph "^0.11.0" + magic-string "^0.25.0" + reflect-metadata "^0.1.2" + semver "^7.0.0" + sourcemap-codec "^1.4.8" + tslib "^2.3.0" + yargs "^17.2.1" + +"@angular/compiler@file:../../node_modules/@angular/compiler": + version "13.2.0-next.2" + dependencies: + tslib "^2.3.0" + +"@angular/core@file:../../node_modules/@angular/core": + version "13.2.0-next.2" + dependencies: + tslib "^2.3.0" + +"@angular/forms@file:../../node_modules/@angular/forms": + version "13.2.0-next.2" + dependencies: + tslib "^2.3.0" + +"@angular/material@file:../../dist/releases/material": + version "13.0.0-next.7" + dependencies: + tslib "^2.3.0" + +"@angular/platform-browser-dynamic@file:../../node_modules/@angular/platform-browser-dynamic": + version "13.2.0-next.2" + dependencies: + tslib "^2.3.0" + +"@angular/platform-browser@file:../../node_modules/@angular/platform-browser": + version "13.2.0-next.2" + dependencies: + tslib "^2.3.0" + +"@angular/router@file:../../node_modules/@angular/router": + version "13.2.0-next.2" + dependencies: + tslib "^2.3.0" + +"@assemblyscript/loader@^0.10.1": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@assemblyscript/loader/-/loader-0.10.1.tgz#70e45678f06c72fa2e350e8553ec4a4d72b92e06" + integrity sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg== + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.0", "@babel/code-frame@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" + integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== + dependencies: + "@babel/highlight" "^7.16.7" + +"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.16.4": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.8.tgz#31560f9f29fdf1868de8cb55049538a1b9732a60" + integrity sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q== + +"@babel/core@7.16.5": + version "7.16.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.16.5.tgz#924aa9e1ae56e1e55f7184c8bf073a50d8677f5c" + integrity sha512-wUcenlLzuWMZ9Zt8S0KmFwGlH6QKRh3vsm/dhDA3CHkiTA45YuG1XkHRcNRl73EFPXDp/d5kVOU0/y7x2w6OaQ== + dependencies: + "@babel/code-frame" "^7.16.0" + "@babel/generator" "^7.16.5" + "@babel/helper-compilation-targets" "^7.16.3" + "@babel/helper-module-transforms" "^7.16.5" + "@babel/helpers" "^7.16.5" + "@babel/parser" "^7.16.5" + "@babel/template" "^7.16.0" + "@babel/traverse" "^7.16.5" + "@babel/types" "^7.16.0" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.1.2" + semver "^6.3.0" + source-map "^0.5.0" + +"@babel/core@^7.12.3", "@babel/core@^7.7.5", "@babel/core@^7.8.6": + version "7.16.12" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.16.12.tgz#5edc53c1b71e54881315923ae2aedea2522bb784" + integrity sha512-dK5PtG1uiN2ikk++5OzSYsitZKny4wOCD0nrO4TqnW4BVBTQ2NGS3NgilvT/TEyxTST7LNyWV/T4tXDoD3fOgg== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.16.8" + "@babel/helper-compilation-targets" "^7.16.7" + "@babel/helper-module-transforms" "^7.16.7" + "@babel/helpers" "^7.16.7" + "@babel/parser" "^7.16.12" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.16.10" + "@babel/types" "^7.16.8" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.1.2" + semver "^6.3.0" + source-map "^0.5.0" + +"@babel/generator@7.16.5": + version "7.16.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.5.tgz#26e1192eb8f78e0a3acaf3eede3c6fc96d22bedf" + integrity sha512-kIvCdjZqcdKqoDbVVdt5R99icaRtrtYhYK/xux5qiWCBmfdvEYMFZ68QCrpE5cbFM1JsuArUNs1ZkuKtTtUcZA== + dependencies: + "@babel/types" "^7.16.0" + jsesc "^2.5.1" + source-map "^0.5.0" + +"@babel/generator@^7.16.5", "@babel/generator@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.8.tgz#359d44d966b8cd059d543250ce79596f792f2ebe" + integrity sha512-1ojZwE9+lOXzcWdWmO6TbUzDfqLD39CmEhN8+2cX9XkDo5yW1OpgfejfliysR2AWLpMamTiOiAp/mtroaymhpw== + dependencies: + "@babel/types" "^7.16.8" + jsesc "^2.5.1" + source-map "^0.5.0" + +"@babel/helper-annotate-as-pure@7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.0.tgz#9a1f0ebcda53d9a2d00108c4ceace6a5d5f1f08d" + integrity sha512-ItmYF9vR4zA8cByDocY05o0LGUkp1zhbTQOH1NFyl5xXEqlTJQCEJjieriw+aFpxo16swMxUnUiKS7a/r4vtHg== + dependencies: + "@babel/types" "^7.16.0" + +"@babel/helper-annotate-as-pure@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862" + integrity sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz#38d138561ea207f0f69eb1626a418e4f7e6a580b" + integrity sha512-C6FdbRaxYjwVu/geKW4ZeQ0Q31AftgRcdSnZ5/jsH6BzCJbtvXvhpfkbkThYSuutZA7nCXpPR6AD9zd1dprMkA== + dependencies: + "@babel/helper-explode-assignable-expression" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.16.3", "@babel/helper-compilation-targets@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz#06e66c5f299601e6c7da350049315e83209d551b" + integrity sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA== + dependencies: + "@babel/compat-data" "^7.16.4" + "@babel/helper-validator-option" "^7.16.7" + browserslist "^4.17.5" + semver "^6.3.0" + +"@babel/helper-create-class-features-plugin@^7.16.10", "@babel/helper-create-class-features-plugin@^7.16.7": + version "7.16.10" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.10.tgz#8a6959b9cc818a88815ba3c5474619e9c0f2c21c" + integrity sha512-wDeej0pu3WN/ffTxMNCPW5UCiOav8IcLRxSIyp/9+IF2xJUM9h/OYjg0IJLHaL6F8oU8kqMz9nc1vryXhMsgXg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-member-expression-to-functions" "^7.16.7" + "@babel/helper-optimise-call-expression" "^7.16.7" + "@babel/helper-replace-supers" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + +"@babel/helper-create-regexp-features-plugin@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.7.tgz#0cb82b9bac358eb73bfbd73985a776bfa6b14d48" + integrity sha512-fk5A6ymfp+O5+p2yCkXAu5Kyj6v0xh0RBeNcAkYUMDvvAAoxvSKXn+Jb37t/yWFiQVDFK1ELpUTD8/aLhCPu+g== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + regexpu-core "^4.7.1" + +"@babel/helper-define-polyfill-provider@^0.3.0", "@babel/helper-define-polyfill-provider@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz#52411b445bdb2e676869e5a74960d2d3826d2665" + integrity sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA== + dependencies: + "@babel/helper-compilation-targets" "^7.13.0" + "@babel/helper-module-imports" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/traverse" "^7.13.0" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" + semver "^6.1.2" + +"@babel/helper-environment-visitor@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7" + integrity sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-explode-assignable-expression@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz#12a6d8522fdd834f194e868af6354e8650242b7a" + integrity sha512-KyUenhWMC8VrxzkGP0Jizjo4/Zx+1nNZhgocs+gLzyZyB8SHidhoq9KK/8Ato4anhwsivfkBLftky7gvzbZMtQ== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-function-name@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz#f1ec51551fb1c8956bc8dd95f38523b6cf375f8f" + integrity sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA== + dependencies: + "@babel/helper-get-function-arity" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/helper-get-function-arity@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz#ea08ac753117a669f1508ba06ebcc49156387419" + integrity sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-hoist-variables@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246" + integrity sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-member-expression-to-functions@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz#42b9ca4b2b200123c3b7e726b0ae5153924905b0" + integrity sha512-VtJ/65tYiU/6AbMTDwyoXGPKHgTsfRarivm+YbB5uAzKUyuPjgZSgAFeG87FCigc7KNHu2Pegh1XIT3lXjvz3Q== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.0", "@babel/helper-module-imports@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" + integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-module-transforms@^7.16.5", "@babel/helper-module-transforms@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz#7665faeb721a01ca5327ddc6bba15a5cb34b6a41" + integrity sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng== + dependencies: + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-module-imports" "^7.16.7" + "@babel/helper-simple-access" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/helper-validator-identifier" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/helper-optimise-call-expression@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz#a34e3560605abbd31a18546bd2aad3e6d9a174f2" + integrity sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5" + integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== + +"@babel/helper-remap-async-to-generator@^7.16.5", "@babel/helper-remap-async-to-generator@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz#29ffaade68a367e2ed09c90901986918d25e57e3" + integrity sha512-fm0gH7Flb8H51LqJHy3HJ3wnE1+qtYR2A99K06ahwrawLdOFsCEWjZOrYricXJHoPSudNKxrMBUPEIPxiIIvBw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-wrap-function" "^7.16.8" + "@babel/types" "^7.16.8" + +"@babel/helper-replace-supers@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz#e9f5f5f32ac90429c1a4bdec0f231ef0c2838ab1" + integrity sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw== + dependencies: + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-member-expression-to-functions" "^7.16.7" + "@babel/helper-optimise-call-expression" "^7.16.7" + "@babel/traverse" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/helper-simple-access@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz#d656654b9ea08dbb9659b69d61063ccd343ff0f7" + integrity sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-skip-transparent-expression-wrappers@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz#0ee3388070147c3ae051e487eca3ebb0e2e8bb09" + integrity sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw== + dependencies: + "@babel/types" "^7.16.0" + +"@babel/helper-split-export-declaration@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" + integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-validator-identifier@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" + integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== + +"@babel/helper-validator-option@^7.14.5", "@babel/helper-validator-option@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" + integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== + +"@babel/helper-wrap-function@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz#58afda087c4cd235de92f7ceedebca2c41274200" + integrity sha512-8RpyRVIAW1RcDDGTA+GpPAwV22wXCfKOoM9bet6TLkGIFTkRQSkH1nMQ5Yet4MpoXe1ZwHPVtNasc2w0uZMqnw== + dependencies: + "@babel/helper-function-name" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.16.8" + "@babel/types" "^7.16.8" + +"@babel/helpers@^7.16.5", "@babel/helpers@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.16.7.tgz#7e3504d708d50344112767c3542fc5e357fffefc" + integrity sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw== + dependencies: + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/highlight@^7.16.7": + version "7.16.10" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.10.tgz#744f2eb81579d6eea753c227b0f570ad785aba88" + integrity sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.14.7", "@babel/parser@^7.16.0", "@babel/parser@^7.16.10", "@babel/parser@^7.16.12", "@babel/parser@^7.16.5", "@babel/parser@^7.16.7": + version "7.16.12" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.12.tgz#9474794f9a650cf5e2f892444227f98e28cdf8b6" + integrity sha512-VfaV15po8RiZssrkPweyvbGVSe4x2y+aciFCgn0n0/SJMR22cwofRV1mtnJQYcSB1wUTaA/X1LnA3es66MCO5A== + +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.2": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.7.tgz#4eda6d6c2a0aa79c70fa7b6da67763dfe2141050" + integrity sha512-anv/DObl7waiGEnC24O9zqL0pSuI9hljihqiDuFHC8d7/bjr/4RLGPWuc8rYOff/QPzbEPSkzG8wGG9aDuhHRg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.16.0": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.7.tgz#cc001234dfc139ac45f6bcf801866198c8c72ff9" + integrity sha512-di8vUHRdf+4aJ7ltXhaDbPoszdkh59AQtJM5soLsuHpQJdFQZOA4uGj0V2u/CZ8bJ/u8ULDL5yq6FO/bCXnKHw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + "@babel/plugin-proposal-optional-chaining" "^7.16.7" + +"@babel/plugin-proposal-async-generator-functions@7.16.5": + version "7.16.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.5.tgz#fd3bd7e0d98404a3d4cbca15a72d533f8c9a2f67" + integrity sha512-C/FX+3HNLV6sz7AqbTQqEo1L9/kfrKjxcVtgyBCmvIgOjvuBVUWooDoi7trsLxOzCEo5FccjRvKHkfDsJFZlfA== + dependencies: + "@babel/helper-plugin-utils" "^7.16.5" + "@babel/helper-remap-async-to-generator" "^7.16.5" + "@babel/plugin-syntax-async-generators" "^7.8.4" + +"@babel/plugin-proposal-async-generator-functions@^7.16.5": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.8.tgz#3bdd1ebbe620804ea9416706cd67d60787504bc8" + integrity sha512-71YHIvMuiuqWJQkebWJtdhQTfd4Q4mF76q2IX37uZPkG9+olBxsX+rH1vkhFto4UeJZ9dPY2s+mDvhDm1u2BGQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-remap-async-to-generator" "^7.16.8" + "@babel/plugin-syntax-async-generators" "^7.8.4" + +"@babel/plugin-proposal-class-properties@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz#925cad7b3b1a2fcea7e59ecc8eb5954f961f91b0" + integrity sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-proposal-class-static-block@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.16.7.tgz#712357570b612106ef5426d13dc433ce0f200c2a" + integrity sha512-dgqJJrcZoG/4CkMopzhPJjGxsIe9A8RlkQLnL/Vhhx8AA9ZuaRwGSlscSh42hazc7WSrya/IK7mTeoF0DP9tEw== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + +"@babel/plugin-proposal-dynamic-import@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.7.tgz#c19c897eaa46b27634a00fee9fb7d829158704b2" + integrity sha512-I8SW9Ho3/8DRSdmDdH3gORdyUuYnk1m4cMxUAdu5oy4n3OfN8flDEH+d60iG7dUfi0KkYwSvoalHzzdRzpWHTg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + +"@babel/plugin-proposal-export-namespace-from@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz#09de09df18445a5786a305681423ae63507a6163" + integrity sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + +"@babel/plugin-proposal-json-strings@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.7.tgz#9732cb1d17d9a2626a08c5be25186c195b6fa6e8" + integrity sha512-lNZ3EEggsGY78JavgbHsK9u5P3pQaW7k4axlgFLYkMd7UBsiNahCITShLjNQschPyjtO6dADrL24757IdhBrsQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-json-strings" "^7.8.3" + +"@babel/plugin-proposal-logical-assignment-operators@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz#be23c0ba74deec1922e639832904be0bea73cdea" + integrity sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + +"@babel/plugin-proposal-nullish-coalescing-operator@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz#141fc20b6857e59459d430c850a0011e36561d99" + integrity sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + +"@babel/plugin-proposal-numeric-separator@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz#d6b69f4af63fb38b6ca2558442a7fb191236eba9" + integrity sha512-vQgPMknOIgiuVqbokToyXbkY/OmmjAzr/0lhSIbG/KmnzXPGwW/AdhdKpi+O4X/VkWiWjnkKOBiqJrTaC98VKw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-proposal-object-rest-spread@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.7.tgz#94593ef1ddf37021a25bdcb5754c4a8d534b01d8" + integrity sha512-3O0Y4+dw94HA86qSg9IHfyPktgR7q3gpNVAeiKQd+8jBKFaU5NQS1Yatgo4wY+UFNuLjvxcSmzcsHqrhgTyBUA== + dependencies: + "@babel/compat-data" "^7.16.4" + "@babel/helper-compilation-targets" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.16.7" + +"@babel/plugin-proposal-optional-catch-binding@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.7.tgz#c623a430674ffc4ab732fd0a0ae7722b67cb74cf" + integrity sha512-eMOH/L4OvWSZAE1VkHbr1vckLG1WUcHGJSLqqQwl2GaUqG6QjddvrOaTUMNYiv77H5IKPMZ9U9P7EaHwvAShfA== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + +"@babel/plugin-proposal-optional-chaining@^7.16.5", "@babel/plugin-proposal-optional-chaining@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz#7cd629564724816c0e8a969535551f943c64c39a" + integrity sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + +"@babel/plugin-proposal-private-methods@^7.16.5": + version "7.16.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.11.tgz#e8df108288555ff259f4527dbe84813aac3a1c50" + integrity sha512-F/2uAkPlXDr8+BHpZvo19w3hLFKge+k75XUprE6jaqKxjGkSYcK+4c+bup5PdW/7W/Rpjwql7FTVEDW+fRAQsw== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.16.10" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-proposal-private-property-in-object@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.7.tgz#b0b8cef543c2c3d57e59e2c611994861d46a3fce" + integrity sha512-rMQkjcOFbm+ufe3bTZLyOfsOUOxyvLXZJCTARhJr+8UMSoZmqTe1K1BgkFcrW37rAchWg57yI69ORxiWvUINuQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-create-class-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + +"@babel/plugin-proposal-unicode-property-regex@^7.16.5", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz#635d18eb10c6214210ffc5ff4932552de08188a2" + integrity sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-class-static-block@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" + integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-dynamic-import@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" + integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-export-namespace-from@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" + integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-private-property-in-object@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" + integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-top-level-await@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-arrow-functions@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz#44125e653d94b98db76369de9c396dc14bef4154" + integrity sha512-9ffkFFMbvzTvv+7dTp/66xvZAWASuPD5Tl9LK3Z9vhOmANo6j94rik+5YMBt4CwHVMWLWpMsriIc2zsa3WW3xQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-async-to-generator@7.16.5": + version "7.16.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.5.tgz#89c9b501e65bb14c4579a6ce9563f859de9b34e4" + integrity sha512-TMXgfioJnkXU+XRoj7P2ED7rUm5jbnDWwlCuFVTpQboMfbSya5WrmubNBAMlk7KXvywpo8rd8WuYZkis1o2H8w== + dependencies: + "@babel/helper-module-imports" "^7.16.0" + "@babel/helper-plugin-utils" "^7.16.5" + "@babel/helper-remap-async-to-generator" "^7.16.5" + +"@babel/plugin-transform-async-to-generator@^7.16.5": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.8.tgz#b83dff4b970cf41f1b819f8b49cc0cfbaa53a808" + integrity sha512-MtmUmTJQHCnyJVrScNzNlofQJ3dLFuobYn3mwOTKHnSCMtbNsqvF71GQmJfFjdrXSsAA7iysFmYWw4bXZ20hOg== + dependencies: + "@babel/helper-module-imports" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-remap-async-to-generator" "^7.16.8" + +"@babel/plugin-transform-block-scoped-functions@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.7.tgz#4d0d57d9632ef6062cdf354bb717102ee042a620" + integrity sha512-JUuzlzmF40Z9cXyytcbZEZKckgrQzChbQJw/5PuEHYeqzCsvebDx0K0jWnIIVcmmDOAVctCgnYs0pMcrYj2zJg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-block-scoping@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz#f50664ab99ddeaee5bc681b8f3a6ea9d72ab4f87" + integrity sha512-ObZev2nxVAYA4bhyusELdo9hb3H+A56bxH3FZMbEImZFiEDYVHXQSJ1hQKFlDnlt8G9bBrCZ5ZpURZUrV4G5qQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-classes@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz#8f4b9562850cd973de3b498f1218796eb181ce00" + integrity sha512-WY7og38SFAGYRe64BrjKf8OrE6ulEHtr5jEYaZMwox9KebgqPi67Zqz8K53EKk1fFEJgm96r32rkKZ3qA2nCWQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-optimise-call-expression" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-replace-supers" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz#66dee12e46f61d2aae7a73710f591eb3df616470" + integrity sha512-gN72G9bcmenVILj//sv1zLNaPyYcOzUho2lIJBMh/iakJ9ygCo/hEF9cpGb61SCMEDxbbyBoVQxrt+bWKu5KGw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-destructuring@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.7.tgz#ca9588ae2d63978a4c29d3f33282d8603f618e23" + integrity sha512-VqAwhTHBnu5xBVDCvrvqJbtLUa++qZaWC0Fgr2mqokBlulZARGyIvZDoqbPlPaKImQ9dKAcCzbv+ul//uqu70A== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-dotall-regex@^7.16.5", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz#6b2d67686fab15fb6a7fd4bd895d5982cfc81241" + integrity sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-duplicate-keys@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz#2207e9ca8f82a0d36a5a67b6536e7ef8b08823c9" + integrity sha512-03DvpbRfvWIXyK0/6QiR1KMTWeT6OcQ7tbhjrXyFS02kjuX/mu5Bvnh5SDSWHxyawit2g5aWhKwI86EE7GUnTw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-exponentiation-operator@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz#efa9862ef97e9e9e5f653f6ddc7b665e8536fe9b" + integrity sha512-8UYLSlyLgRixQvlYH3J2ekXFHDFLQutdy7FfFAMm3CPZ6q9wHCwnUyiXpQCe3gVVnQlHc5nsuiEVziteRNTXEA== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-for-of@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz#649d639d4617dff502a9a158c479b3b556728d8c" + integrity sha512-/QZm9W92Ptpw7sjI9Nx1mbcsWz33+l8kuMIQnDwgQBG5s3fAfQvkRjQ7NqXhtNcKOnPkdICmUHyCaWW06HCsqg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-function-name@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.7.tgz#5ab34375c64d61d083d7d2f05c38d90b97ec65cf" + integrity sha512-SU/C68YVwTRxqWj5kgsbKINakGag0KTgq9f2iZEXdStoAbOzLHEBRYzImmA6yFo8YZhJVflvXmIHUO7GWHmxxA== + dependencies: + "@babel/helper-compilation-targets" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-literals@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz#254c9618c5ff749e87cb0c0cef1a0a050c0bdab1" + integrity sha512-6tH8RTpTWI0s2sV6uq3e/C9wPo4PTqqZps4uF0kzQ9/xPLFQtipynvmT1g/dOfEJ+0EQsHhkQ/zyRId8J2b8zQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-member-expression-literals@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.7.tgz#6e5dcf906ef8a098e630149d14c867dd28f92384" + integrity sha512-mBruRMbktKQwbxaJof32LT9KLy2f3gH+27a5XSuXo6h7R3vqltl0PgZ80C8ZMKw98Bf8bqt6BEVi3svOh2PzMw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-modules-amd@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz#b28d323016a7daaae8609781d1f8c9da42b13186" + integrity sha512-KaaEtgBL7FKYwjJ/teH63oAmE3lP34N3kshz8mm4VMAw7U3PxjVwwUmxEFksbgsNUaO3wId9R2AVQYSEGRa2+g== + dependencies: + "@babel/helper-module-transforms" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-commonjs@^7.16.5": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.8.tgz#cdee19aae887b16b9d331009aa9a219af7c86afe" + integrity sha512-oflKPvsLT2+uKQopesJt3ApiaIS2HW+hzHFcwRNtyDGieAeC/dIHZX8buJQ2J2X1rxGPy4eRcUijm3qcSPjYcA== + dependencies: + "@babel/helper-module-transforms" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-simple-access" "^7.16.7" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-systemjs@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.7.tgz#887cefaef88e684d29558c2b13ee0563e287c2d7" + integrity sha512-DuK5E3k+QQmnOqBR9UkusByy5WZWGRxfzV529s9nPra1GE7olmxfqO2FHobEOYSPIjPBTr4p66YDcjQnt8cBmw== + dependencies: + "@babel/helper-hoist-variables" "^7.16.7" + "@babel/helper-module-transforms" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-validator-identifier" "^7.16.7" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-umd@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.7.tgz#23dad479fa585283dbd22215bff12719171e7618" + integrity sha512-EMh7uolsC8O4xhudF2F6wedbSHm1HHZ0C6aJ7K67zcDNidMzVcxWdGr+htW9n21klm+bOn+Rx4CBsAntZd3rEQ== + dependencies: + "@babel/helper-module-transforms" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.16.5": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.8.tgz#7f860e0e40d844a02c9dcf9d84965e7dfd666252" + integrity sha512-j3Jw+n5PvpmhRR+mrgIh04puSANCk/T/UA3m3P1MjJkhlK906+ApHhDIqBQDdOgL/r1UYpz4GNclTXxyZrYGSw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.7" + +"@babel/plugin-transform-new-target@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.7.tgz#9967d89a5c243818e0800fdad89db22c5f514244" + integrity sha512-xiLDzWNMfKoGOpc6t3U+etCE2yRnn3SM09BXqWPIZOBpL2gvVrBWUKnsJx0K/ADi5F5YC5f8APFfWrz25TdlGg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-object-super@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz#ac359cf8d32cf4354d27a46867999490b6c32a94" + integrity sha512-14J1feiQVWaGvRxj2WjyMuXS2jsBkgB3MdSN5HuC2G5nRspa5RK9COcs82Pwy5BuGcjb+fYaUj94mYcOj7rCvw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-replace-supers" "^7.16.7" + +"@babel/plugin-transform-parameters@^7.16.5", "@babel/plugin-transform-parameters@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz#a1721f55b99b736511cb7e0152f61f17688f331f" + integrity sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-property-literals@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz#2dadac85155436f22c696c4827730e0fe1057a55" + integrity sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-regenerator@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.7.tgz#9e7576dc476cb89ccc5096fff7af659243b4adeb" + integrity sha512-mF7jOgGYCkSJagJ6XCujSQg+6xC1M77/03K2oBmVJWoFGNUtnVJO4WHKJk3dnPC8HCcj4xBQP1Egm8DWh3Pb3Q== + dependencies: + regenerator-transform "^0.14.2" + +"@babel/plugin-transform-reserved-words@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.7.tgz#1d798e078f7c5958eec952059c460b220a63f586" + integrity sha512-KQzzDnZ9hWQBjwi5lpY5v9shmm6IVG0U9pB18zvMu2i4H90xpT4gmqwPYsn8rObiadYe2M0gmgsiOIF5A/2rtg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-runtime@7.16.5": + version "7.16.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.16.5.tgz#0cc3f01d69f299d5a42cd9ec43b92ea7a777b8db" + integrity sha512-gxpfS8XQWDbQ8oP5NcmpXxtEgCJkbO+W9VhZlOhr0xPyVaRjAQPOv7ZDj9fg0d5s9+NiVvMCE6gbkEkcsxwGRw== + dependencies: + "@babel/helper-module-imports" "^7.16.0" + "@babel/helper-plugin-utils" "^7.16.5" + babel-plugin-polyfill-corejs2 "^0.3.0" + babel-plugin-polyfill-corejs3 "^0.4.0" + babel-plugin-polyfill-regenerator "^0.3.0" + semver "^6.3.0" + +"@babel/plugin-transform-shorthand-properties@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.7.tgz#e8549ae4afcf8382f711794c0c7b6b934c5fbd2a" + integrity sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-spread@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz#a303e2122f9f12e0105daeedd0f30fb197d8ff44" + integrity sha512-+pjJpgAngb53L0iaA5gU/1MLXJIfXcYepLgXB3esVRf4fqmj8f2cxM3/FKaHsZms08hFQJkFccEWuIpm429TXg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + +"@babel/plugin-transform-sticky-regex@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz#c84741d4f4a38072b9a1e2e3fd56d359552e8660" + integrity sha512-NJa0Bd/87QV5NZZzTuZG5BPJjLYadeSZ9fO6oOUoL4iQx+9EEuw/eEM92SrsT19Yc2jgB1u1hsjqDtH02c3Drw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-template-literals@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz#f3d1c45d28967c8e80f53666fc9c3e50618217ab" + integrity sha512-VwbkDDUeenlIjmfNeDX/V0aWrQH2QiVyJtwymVQSzItFDTpxfyJh3EVaQiS0rIN/CqbLGr0VcGmuwyTdZtdIsA== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-typeof-symbol@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz#9cdbe622582c21368bd482b660ba87d5545d4f7e" + integrity sha512-p2rOixCKRJzpg9JB4gjnG4gjWkWa89ZoYUnl9snJ1cWIcTH/hvxZqfO+WjG6T8DRBpctEol5jw1O5rA8gkCokQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-unicode-escapes@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.7.tgz#da8717de7b3287a2c6d659750c964f302b31ece3" + integrity sha512-TAV5IGahIz3yZ9/Hfv35TV2xEm+kaBDaZQCn2S/hG9/CZ0DktxJv9eKfPc7yYCvOYR4JGx1h8C+jcSOvgaaI/Q== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-unicode-regex@^7.16.5": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz#0f7aa4a501198976e25e82702574c34cfebe9ef2" + integrity sha512-oC5tYYKw56HO75KZVLQ+R/Nl3Hro9kf8iG0hXoaHP7tjAyCpvqBiSNe6vGrZni1Z6MggmUOC6A7VP7AVmw225Q== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/preset-env@7.16.5": + version "7.16.5" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.16.5.tgz#2e94d922f4a890979af04ffeb6a6b4e44ba90847" + integrity sha512-MiJJW5pwsktG61NDxpZ4oJ1CKxM1ncam9bzRtx9g40/WkLRkxFP6mhpkYV0/DxcciqoiHicx291+eUQrXb/SfQ== + dependencies: + "@babel/compat-data" "^7.16.4" + "@babel/helper-compilation-targets" "^7.16.3" + "@babel/helper-plugin-utils" "^7.16.5" + "@babel/helper-validator-option" "^7.14.5" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.16.2" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.16.0" + "@babel/plugin-proposal-async-generator-functions" "^7.16.5" + "@babel/plugin-proposal-class-properties" "^7.16.5" + "@babel/plugin-proposal-class-static-block" "^7.16.5" + "@babel/plugin-proposal-dynamic-import" "^7.16.5" + "@babel/plugin-proposal-export-namespace-from" "^7.16.5" + "@babel/plugin-proposal-json-strings" "^7.16.5" + "@babel/plugin-proposal-logical-assignment-operators" "^7.16.5" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.16.5" + "@babel/plugin-proposal-numeric-separator" "^7.16.5" + "@babel/plugin-proposal-object-rest-spread" "^7.16.5" + "@babel/plugin-proposal-optional-catch-binding" "^7.16.5" + "@babel/plugin-proposal-optional-chaining" "^7.16.5" + "@babel/plugin-proposal-private-methods" "^7.16.5" + "@babel/plugin-proposal-private-property-in-object" "^7.16.5" + "@babel/plugin-proposal-unicode-property-regex" "^7.16.5" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-class-properties" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-syntax-top-level-await" "^7.14.5" + "@babel/plugin-transform-arrow-functions" "^7.16.5" + "@babel/plugin-transform-async-to-generator" "^7.16.5" + "@babel/plugin-transform-block-scoped-functions" "^7.16.5" + "@babel/plugin-transform-block-scoping" "^7.16.5" + "@babel/plugin-transform-classes" "^7.16.5" + "@babel/plugin-transform-computed-properties" "^7.16.5" + "@babel/plugin-transform-destructuring" "^7.16.5" + "@babel/plugin-transform-dotall-regex" "^7.16.5" + "@babel/plugin-transform-duplicate-keys" "^7.16.5" + "@babel/plugin-transform-exponentiation-operator" "^7.16.5" + "@babel/plugin-transform-for-of" "^7.16.5" + "@babel/plugin-transform-function-name" "^7.16.5" + "@babel/plugin-transform-literals" "^7.16.5" + "@babel/plugin-transform-member-expression-literals" "^7.16.5" + "@babel/plugin-transform-modules-amd" "^7.16.5" + "@babel/plugin-transform-modules-commonjs" "^7.16.5" + "@babel/plugin-transform-modules-systemjs" "^7.16.5" + "@babel/plugin-transform-modules-umd" "^7.16.5" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.16.5" + "@babel/plugin-transform-new-target" "^7.16.5" + "@babel/plugin-transform-object-super" "^7.16.5" + "@babel/plugin-transform-parameters" "^7.16.5" + "@babel/plugin-transform-property-literals" "^7.16.5" + "@babel/plugin-transform-regenerator" "^7.16.5" + "@babel/plugin-transform-reserved-words" "^7.16.5" + "@babel/plugin-transform-shorthand-properties" "^7.16.5" + "@babel/plugin-transform-spread" "^7.16.5" + "@babel/plugin-transform-sticky-regex" "^7.16.5" + "@babel/plugin-transform-template-literals" "^7.16.5" + "@babel/plugin-transform-typeof-symbol" "^7.16.5" + "@babel/plugin-transform-unicode-escapes" "^7.16.5" + "@babel/plugin-transform-unicode-regex" "^7.16.5" + "@babel/preset-modules" "^0.1.5" + "@babel/types" "^7.16.0" + babel-plugin-polyfill-corejs2 "^0.3.0" + babel-plugin-polyfill-corejs3 "^0.4.0" + babel-plugin-polyfill-regenerator "^0.3.0" + core-js-compat "^3.19.1" + semver "^6.3.0" + +"@babel/preset-modules@^0.1.5": + version "0.1.5" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.5.tgz#ef939d6e7f268827e1841638dc6ff95515e115d9" + integrity sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" + "@babel/plugin-transform-dotall-regex" "^7.4.4" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + +"@babel/runtime@7.16.5": + version "7.16.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.5.tgz#7f3e34bf8bdbbadf03fbb7b1ea0d929569c9487a" + integrity sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/runtime@^7.8.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.7.tgz#03ff99f64106588c9c403c6ecb8c3bafbbdff1fa" + integrity sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/template@7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.0.tgz#d16a35ebf4cd74e202083356fab21dd89363ddd6" + integrity sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A== + dependencies: + "@babel/code-frame" "^7.16.0" + "@babel/parser" "^7.16.0" + "@babel/types" "^7.16.0" + +"@babel/template@^7.16.0", "@babel/template@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" + integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/parser" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/traverse@^7.13.0", "@babel/traverse@^7.16.10", "@babel/traverse@^7.16.5", "@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8": + version "7.16.10" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.10.tgz#448f940defbe95b5a8029975b051f75993e8239f" + integrity sha512-yzuaYXoRJBGMlBhsMJoUW7G1UmSb/eXr/JHYM/MsOJgavJibLwASijW7oXBdw3NQ6T0bW7Ty5P/VarOs9cHmqw== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.16.8" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-hoist-variables" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/parser" "^7.16.10" + "@babel/types" "^7.16.8" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.4.4": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.8.tgz#0ba5da91dd71e0a4e7781a30f22770831062e3c1" + integrity sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + to-fast-properties "^2.0.0" + +"@csstools/convert-colors@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7" + integrity sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw== + +"@discoveryjs/json-ext@0.5.6": + version "0.5.6" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz#d5e0706cf8c6acd8c6032f8d54070af261bbbb2f" + integrity sha512-ws57AidsDvREKrZKYffXddNkyaF14iHNHm8VQnZH6t99E8gczjNN0GpvcGny0imC80yQ0tHz1xVUKk/KFQSUyA== + +"@gar/promisify@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.2.tgz#30aa825f11d438671d585bd44e7fd564535fc210" + integrity sha512-82cpyJyKRoQoRi+14ibCeGPu0CwypgtBAdBhq1WfvagpCZNKqwXbKwXllYSMG91DhmG4jt9gN8eP6lGOtozuaw== + +"@hapi/hoek@^9.0.0": + version "9.2.1" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.2.1.tgz#9551142a1980503752536b5050fd99f4a7f13b17" + integrity sha512-gfta+H8aziZsm8pZa0vj04KO6biEiisppNgA1kbJvFrrWu9Vm7eaUEy76DIxsuTaWvti5fkJVhllWc6ZTE+Mdw== + +"@hapi/topo@^5.0.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.1.0.tgz#dc448e332c6c6e37a4dc02fd84ba8d44b9afb012" + integrity sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg== + dependencies: + "@hapi/hoek" "^9.0.0" + +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jridgewell/resolve-uri@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-1.0.0.tgz#3fdf5798f0b49e90155896f6291df186eac06c83" + integrity sha512-9oLAnygRMi8Q5QkYEU4XWK04B+nuoXoxjRvRxgjuChkLZFBja0YPSgdZ7dZtwhncLBcQe/I/E+fLuk5qxcYVJA== + +"@ngtools/webpack@13.2.0-next.1": + version "13.2.0-next.1" + resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-13.2.0-next.1.tgz#2a4bab214b0f5d8b7e89fd0c1dfca80983065c92" + integrity sha512-pM0pA8ENqDuPvjrjvhq14OzfO1uZ++4cUxQ1mm0gw46bVtWtyLcxqE2RFHSw+qnMeduTu9e70LqcGTjtmipvYA== + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@npmcli/fs@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-1.1.0.tgz#bec1d1b89c170d40e1b73ad6c943b0b75e7d2951" + integrity sha512-VhP1qZLXcrXRIaPoqb4YA55JQxLNF3jNR4T55IdOJa3+IFJKNYHtPvtXx8slmeMavj37vCzCfrqQM1vWLsYKLA== + dependencies: + "@gar/promisify" "^1.0.1" + semver "^7.3.5" + +"@npmcli/git@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-2.1.0.tgz#2fbd77e147530247d37f325930d457b3ebe894f6" + integrity sha512-/hBFX/QG1b+N7PZBFs0bi+evgRZcK9nWBxQKZkGoXUT5hJSwl5c4d7y8/hm+NQZRPhQ67RzFaj5UM9YeyKoryw== + dependencies: + "@npmcli/promise-spawn" "^1.3.2" + lru-cache "^6.0.0" + mkdirp "^1.0.4" + npm-pick-manifest "^6.1.1" + promise-inflight "^1.0.1" + promise-retry "^2.0.1" + semver "^7.3.5" + which "^2.0.2" + +"@npmcli/installed-package-contents@^1.0.6": + version "1.0.7" + resolved "https://registry.yarnpkg.com/@npmcli/installed-package-contents/-/installed-package-contents-1.0.7.tgz#ab7408c6147911b970a8abe261ce512232a3f4fa" + integrity sha512-9rufe0wnJusCQoLpV9ZPKIVP55itrM5BxOXs10DmdbRfgWtHy1LDyskbwRnBghuB0PrF7pNPOqREVtpz4HqzKw== + dependencies: + npm-bundled "^1.1.1" + npm-normalize-package-bin "^1.0.1" + +"@npmcli/move-file@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674" + integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg== + dependencies: + mkdirp "^1.0.4" + rimraf "^3.0.2" + +"@npmcli/node-gyp@^1.0.2": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-1.0.3.tgz#a912e637418ffc5f2db375e93b85837691a43a33" + integrity sha512-fnkhw+fmX65kiLqk6E3BFLXNC26rUhK90zVwe2yncPliVT/Qos3xjhTLE59Df8KnPlcwIERXKVlU1bXoUQ+liA== + +"@npmcli/promise-spawn@^1.2.0", "@npmcli/promise-spawn@^1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-1.3.2.tgz#42d4e56a8e9274fba180dabc0aea6e38f29274f5" + integrity sha512-QyAGYo/Fbj4MXeGdJcFzZ+FkDkomfRBrPM+9QYJSg+PxgAUL+LU3FneQk37rKR2/zjqkCV1BLHccX98wRXG3Sg== + dependencies: + infer-owner "^1.0.4" + +"@npmcli/run-script@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-2.0.0.tgz#9949c0cab415b17aaac279646db4f027d6f1e743" + integrity sha512-fSan/Pu11xS/TdaTpTB0MRn9guwGU8dye+x56mEVgBEd/QsybBbYcAL0phPXi8SGWFEChkQd6M9qL4y6VOpFig== + dependencies: + "@npmcli/node-gyp" "^1.0.2" + "@npmcli/promise-spawn" "^1.3.2" + node-gyp "^8.2.0" + read-package-json-fast "^2.0.1" + +"@schematics/angular@13.2.0-next.1": + version "13.2.0-next.1" + resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-13.2.0-next.1.tgz#e670e0c9d734dda81e5d712fbbab9a8e25fb3ba7" + integrity sha512-2VUYODbnPETqVyM1xCB4sISZKZNzE7c2uYd/ljMbIg21sFrBD7Ali4gIRpkBaen93+33eAwCFCD9L6wqheUTDA== + dependencies: + "@angular-devkit/core" "13.2.0-next.1" + "@angular-devkit/schematics" "13.2.0-next.1" + jsonc-parser "3.0.0" + +"@sideway/address@^4.1.3": + version "4.1.3" + resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.3.tgz#d93cce5d45c5daec92ad76db492cc2ee3c64ab27" + integrity sha512-8ncEUtmnTsMmL7z1YPB47kPUq7LpKWJNFPsRzHiIajGC5uXlWGn+AmkYPcHNl8S4tcEGx+cnORnNYaw2wvL+LQ== + dependencies: + "@hapi/hoek" "^9.0.0" + +"@sideway/formula@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.0.tgz#fe158aee32e6bd5de85044be615bc08478a0a13c" + integrity sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg== + +"@sideway/pinpoint@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" + integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== + +"@socket.io/base64-arraybuffer@~1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@socket.io/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz#568d9beae00b0d835f4f8c53fd55714986492e61" + integrity sha512-dOlCBKnDw4iShaIsH/bxujKTM18+2TOAsYz+KSc11Am38H4q5Xw8Bbz97ZYdrVNM+um3p7w86Bvvmcn9q+5+eQ== + +"@tootallnate/once@1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== + +"@types/component-emitter@^1.2.10": + version "1.2.11" + resolved "https://registry.yarnpkg.com/@types/component-emitter/-/component-emitter-1.2.11.tgz#50d47d42b347253817a39709fef03ce66a108506" + integrity sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ== + +"@types/cookie@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" + integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== + +"@types/cors@^2.8.12": + version "2.8.12" + resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080" + integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw== + +"@types/eslint-scope@^3.7.0": + version "3.7.3" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.3.tgz#125b88504b61e3c8bc6f870882003253005c3224" + integrity sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*": + version "8.4.1" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.1.tgz#c48251553e8759db9e656de3efc846954ac32304" + integrity sha512-GE44+DNEyxxh2Kc6ro/VkIj+9ma0pO0bwv9+uHSyBrikYOHr8zYcdPvnBOp1aw8s+CjRvuSx7CyWqRrNFQ59mA== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*", "@types/estree@^0.0.50": + version "0.0.50" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83" + integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw== + +"@types/http-proxy@^1.17.8": + version "1.17.8" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.8.tgz#968c66903e7e42b483608030ee85800f22d03f55" + integrity sha512-5kPLG5BKpWYkw/LVOGWpiq3nEVqxiN32rTgI53Sk12/xHFQ2rG3ehI9IO+O3W2QoKeyB92dJkoka8SUm6BX1pA== + dependencies: + "@types/node" "*" + +"@types/jasmine@~3.10.0": + version "3.10.3" + resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-3.10.3.tgz#a89798b3d5a8bd23ca56e855a9aee3e5a93bdaaa" + integrity sha512-SWyMrjgdAUHNQmutvDcKablrJhkDLy4wunTme8oYLjKp41GnHGxMRXr2MQMvy/qy8H3LdzwQk9gH4hZ6T++H8g== + +"@types/json-schema@*", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": + version "7.0.9" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" + integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== + +"@types/node@*", "@types/node@>=10.0.0": + version "17.0.10" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.10.tgz#616f16e9d3a2a3d618136b1be244315d95bd7cab" + integrity sha512-S/3xB4KzyFxYGCppyDt68yzBU9ysL88lSdIah4D6cptdcltc4NCPCAMc0+PCpg/lLIyC7IPvj2Z52OJWeIUkog== + +"@types/node@^12.11.1": + version "12.20.42" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.42.tgz#2f021733232c2130c26f9eabbdd3bfd881774733" + integrity sha512-aI3/oo5DzyiI5R/xAhxxRzfZlWlsbbqdgxfTPkqu/Zt+23GXiJvMCyPJT4+xKSXOnLqoL8jJYMLTwvK2M3a5hw== + +"@types/parse-json@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" + integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + +"@types/retry@^0.12.0": + version "0.12.1" + resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.1.tgz#d8f1c0d0dc23afad6dc16a9e993a0865774b4065" + integrity sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g== + +"@types/selenium-webdriver@3.0.19": + version "3.0.19" + resolved "https://registry.yarnpkg.com/@types/selenium-webdriver/-/selenium-webdriver-3.0.19.tgz#28ecede76f15b13553b4e86074d4cf9a0bbe49c4" + integrity sha512-OFUilxQg+rWL2FMxtmIgCkUDlJB6pskkpvmew7yeXfzzsOBb5rc+y2+DjHm+r3r1ZPPcJefK3DveNSYWGiy68g== + +"@webassemblyjs/ast@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" + integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + +"@webassemblyjs/floating-point-hex-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" + integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== + +"@webassemblyjs/helper-api-error@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" + integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== + +"@webassemblyjs/helper-buffer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" + integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== + +"@webassemblyjs/helper-numbers@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" + integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/helper-wasm-bytecode@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" + integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== + +"@webassemblyjs/helper-wasm-section@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" + integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + +"@webassemblyjs/ieee754@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" + integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" + integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" + integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== + +"@webassemblyjs/wasm-edit@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" + integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/helper-wasm-section" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-opt" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + "@webassemblyjs/wast-printer" "1.11.1" + +"@webassemblyjs/wasm-gen@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" + integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wasm-opt@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" + integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + +"@webassemblyjs/wasm-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" + integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wast-printer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" + integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@xtuc/long" "4.2.2" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +"@yarnpkg/lockfile@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" + integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== + +abab@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" + integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + +acorn-import-assertions@^1.7.6: + version "1.8.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" + integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== + +acorn@^8.4.1: + version "8.7.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" + integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== + +adjust-sourcemap-loader@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz#fc4a0fd080f7d10471f30a7320f25560ade28c99" + integrity sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A== + dependencies: + loader-utils "^2.0.0" + regex-parser "^2.2.11" + +agent-base@6, agent-base@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +agentkeepalive@^4.1.3: + version "4.2.0" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.2.0.tgz#616ce94ccb41d1a39a45d203d8076fe98713062d" + integrity sha512-0PhAp58jZNw13UJv7NVdTGb0ZcghHUb3DrZ046JiiJY/BOaTTpbwdHq2VObPCBV8M2GPh7sgrJ3AQ8Ey468LJw== + dependencies: + debug "^4.1.0" + depd "^1.1.2" + humanize-ms "^1.2.1" + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ajv-formats@2.1.1, ajv-formats@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" + integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== + dependencies: + ajv "^8.0.0" + +ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv-keywords@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" + integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== + dependencies: + fast-deep-equal "^3.1.3" + +ajv@8.8.2: + version "8.8.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.8.2.tgz#01b4fef2007a28bf75f0b7fc009f62679de4abbb" + integrity sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +ajv@^6.12.4, ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^8.0.0, ajv@^8.8.0: + version "8.9.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.9.0.tgz#738019146638824dea25edcf299dcba1b0e7eb18" + integrity sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +ansi-colors@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-escapes@^4.2.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-html-community@^0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" + integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +"aproba@^1.0.3 || ^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" + integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== + +are-we-there-yet@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c" + integrity sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw== + dependencies: + delegates "^1.0.0" + readable-stream "^3.6.0" + +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +array-flatten@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" + integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +array-union@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-3.0.1.tgz#da52630d327f8b88cfbfb57728e2af5cd9b6b975" + integrity sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw== + +async@^2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + dependencies: + lodash "^4.17.14" + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +autoprefixer@^9.6.1: + version "9.8.8" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.8.tgz#fd4bd4595385fa6f06599de749a4d5f7a474957a" + integrity sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA== + dependencies: + browserslist "^4.12.0" + caniuse-lite "^1.0.30001109" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + picocolors "^0.2.1" + postcss "^7.0.32" + postcss-value-parser "^4.1.0" + +axios@^0.21.1: + version "0.21.4" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" + integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== + dependencies: + follow-redirects "^1.14.0" + +babel-loader@8.2.3: + version "8.2.3" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.3.tgz#8986b40f1a64cacfcb4b8429320085ef68b1342d" + integrity sha512-n4Zeta8NC3QAsuyiizu0GkmRcQ6clkV9WFUnUf1iXP//IeSKbWjofW3UHyZVwlOB4y039YQKefawyTn64Zwbuw== + dependencies: + find-cache-dir "^3.3.1" + loader-utils "^1.4.0" + make-dir "^3.1.0" + schema-utils "^2.6.5" + +babel-plugin-dynamic-import-node@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" + integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== + dependencies: + object.assign "^4.1.0" + +babel-plugin-istanbul@6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^5.0.4" + test-exclude "^6.0.0" + +babel-plugin-polyfill-corejs2@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz#440f1b70ccfaabc6b676d196239b138f8a2cfba5" + integrity sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w== + dependencies: + "@babel/compat-data" "^7.13.11" + "@babel/helper-define-polyfill-provider" "^0.3.1" + semver "^6.1.1" + +babel-plugin-polyfill-corejs3@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.4.0.tgz#0b571f4cf3d67f911512f5c04842a7b8e8263087" + integrity sha512-YxFreYwUfglYKdLUGvIF2nJEsGwj+RhWSX/ije3D2vQPOXuyMLMtg/cCGMDpOA7Nd+MwlNdnGODbd2EwUZPlsw== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.3.0" + core-js-compat "^3.18.0" + +babel-plugin-polyfill-regenerator@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz#2c0678ea47c75c8cc2fbb1852278d8fb68233990" + integrity sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.3.1" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base64-js@^1.2.0, base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +base64id@2.0.0, base64id@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" + integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +bl@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + +body-parser@1.19.1, body-parser@^1.19.0: + version "1.19.1" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.1.tgz#1499abbaa9274af3ecc9f6f10396c995943e31d4" + integrity sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA== + dependencies: + bytes "3.1.1" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.8.1" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.9.6" + raw-body "2.4.2" + type-is "~1.6.18" + +bonjour@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" + integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= + dependencies: + array-flatten "^2.1.0" + deep-equal "^1.0.1" + dns-equal "^1.0.0" + dns-txt "^2.0.2" + multicast-dns "^6.0.1" + multicast-dns-service-types "^1.1.0" + +boolbase@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.1, braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.17.5, browserslist@^4.19.1, browserslist@^4.6.4, browserslist@^4.9.1: + version "4.19.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.19.1.tgz#4ac0435b35ab655896c31d53018b6dd5e9e4c9a3" + integrity sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A== + dependencies: + caniuse-lite "^1.0.30001286" + electron-to-chromium "^1.4.17" + escalade "^3.1.1" + node-releases "^2.0.1" + picocolors "^1.0.0" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer-indexof@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" + integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== + +buffer@^5.5.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +builtins@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" + integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og= + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= + +bytes@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.1.tgz#3f018291cb4cbad9accb6e6970bca9c8889e879a" + integrity sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg== + +cacache@15.3.0, cacache@^15.0.5, cacache@^15.2.0: + version "15.3.0" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.3.0.tgz#dc85380fb2f556fe3dda4c719bfa0ec875a7f1eb" + integrity sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ== + dependencies: + "@npmcli/fs" "^1.0.0" + "@npmcli/move-file" "^1.0.1" + chownr "^2.0.0" + fs-minipass "^2.0.0" + glob "^7.1.4" + infer-owner "^1.0.4" + lru-cache "^6.0.0" + minipass "^3.1.1" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.2" + mkdirp "^1.0.3" + p-map "^4.0.0" + promise-inflight "^1.0.1" + rimraf "^3.0.2" + ssri "^8.0.1" + tar "^6.0.2" + unique-filename "^1.1.1" + +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001286: + version "1.0.30001301" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001301.tgz#ebc9086026534cab0dab99425d9c3b4425e5f450" + integrity sha512-csfD/GpHMqgEL3V3uIgosvh+SVIQvCh43SNu9HRbP1lnxkKm1kjDG4f32PP571JplkLjfS+mg2p1gxR7MYrrIA== + +canonical-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/canonical-path/-/canonical-path-1.0.0.tgz#fcb470c23958def85081856be7a86e904f180d1d" + integrity sha512-feylzsbDxi1gPZ1IjystzIQZagYYLvfKrSuygUCgf7z6x790VEzze5QEkdSV1U58RA7Hi0+v6fv4K54atOzATg== + +chalk@^2.0.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.1.0, chalk@^4.1.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + +"chokidar@>=3.0.0 <4.0.0", chokidar@^3.0.0, chokidar@^3.5.1, chokidar@^3.5.2: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chownr@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" + integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== + +chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + +circular-dependency-plugin@5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/circular-dependency-plugin/-/circular-dependency-plugin-5.2.2.tgz#39e836079db1d3cf2f988dc48c5188a44058b600" + integrity sha512-g38K9Cm5WRwlaH6g03B9OEz/0qRizI+2I7n+Gz+L5DxXJAPAiWQvwlYNm1V1jkdpUv95bOe/ASm2vfi/G560jQ== + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-spinners@^2.5.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d" + integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g== + +cli-width@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" + integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + +clone@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +color-support@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== + +colorette@^2.0.10: + version "2.0.16" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" + integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== + +colors@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + +component-emitter@~1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concurrently@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-7.0.0.tgz#78d31b441cec338dab03316c221a2f9a67c529b0" + integrity sha512-WKM7PUsI8wyXpF80H+zjHP32fsgsHNQfPLw/e70Z5dYkV7hF+rf8q3D+ScWJIEr57CpkO3OWBko6hwhQLPR8Pw== + dependencies: + chalk "^4.1.0" + date-fns "^2.16.1" + lodash "^4.17.21" + rxjs "^6.6.3" + spawn-command "^0.0.2-1" + supports-color "^8.1.0" + tree-kill "^1.2.2" + yargs "^16.2.0" + +connect-history-api-fallback@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" + integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== + +connect@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" + integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ== + dependencies: + debug "2.6.9" + finalhandler "1.1.2" + parseurl "~1.3.3" + utils-merge "1.0.1" + +console-control-strings@^1.0.0, console-control-strings@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +convert-source-map@^1.5.1, convert-source-map@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== + dependencies: + safe-buffer "~5.1.1" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.4.1, cookie@~0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" + integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== + +copy-anything@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/copy-anything/-/copy-anything-2.0.3.tgz#842407ba02466b0df844819bbe3baebbe5d45d87" + integrity sha512-GK6QUtisv4fNS+XcI7shX0Gx9ORg7QqIznyfho79JTnX1XhLiyZHfftvGiziqzRiEi/Bjhgpi+D2o7HxJFPnDQ== + dependencies: + is-what "^3.12.0" + +copy-webpack-plugin@10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-10.1.0.tgz#d27cf1cbe1c9b4ac57f1f96312e6f7da00108d23" + integrity sha512-dPGo+zoW77wiF5LlwkQcZTY7FsrSm7dmovhLDHsjYyciiJ+ZhLFt2EQbw9LRUHJ586JXN0K1A70Kbudclvt00Q== + dependencies: + fast-glob "^3.2.7" + glob-parent "^6.0.1" + globby "^12.0.2" + normalize-path "^3.0.0" + schema-utils "^4.0.0" + serialize-javascript "^6.0.0" + +core-js-compat@^3.18.0, core-js-compat@^3.19.1: + version "3.20.3" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.20.3.tgz#d71f85f94eb5e4bea3407412e549daa083d23bd6" + integrity sha512-c8M5h0IkNZ+I92QhIpuSijOxGAcj3lgpsWdkCqmUTZNwidujF4r3pi6x1DCN+Vcs5qTS2XWWMfWSuCqyupX8gw== + dependencies: + browserslist "^4.19.1" + semver "7.0.0" + +core-js@3.19.3: + version "3.19.3" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.19.3.tgz#6df8142a996337503019ff3235a7022d7cdf4559" + integrity sha512-LeLBMgEGSsG7giquSzvgBrTS7V5UL6ks3eQlUSbN8dJStlLFiRzUm5iqsRyzUB8carhfKjkJ2vzKqE6z1Vga9g== + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +cors@~2.8.5: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + +cosmiconfig@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d" + integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.2.1" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.10.0" + +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + +critters@0.0.15: + version "0.0.15" + resolved "https://registry.yarnpkg.com/critters/-/critters-0.0.15.tgz#b1c8d18fd18e614471733d7d749deac0f386b738" + integrity sha512-AE7hkXb3eZUbEvS1SKZa+OU4o2kUOXtzVeE/2E/mjU/0mV1wpBT1HfUCWVRS4zwvkBNJ0AQYsVjAoFm+kIhfdw== + dependencies: + chalk "^4.1.0" + css-select "^4.1.3" + parse5 "^6.0.1" + parse5-htmlparser2-tree-adapter "^6.0.1" + postcss "^8.3.7" + pretty-bytes "^5.3.0" + +cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +css-blank-pseudo@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz#dfdefd3254bf8a82027993674ccf35483bfcb3c5" + integrity sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w== + dependencies: + postcss "^7.0.5" + +css-has-pseudo@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz#3c642ab34ca242c59c41a125df9105841f6966ee" + integrity sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ== + dependencies: + postcss "^7.0.6" + postcss-selector-parser "^5.0.0-rc.4" + +css-loader@6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.5.1.tgz#0c43d4fbe0d97f699c91e9818cb585759091d1b1" + integrity sha512-gEy2w9AnJNnD9Kuo4XAP9VflW/ujKoS9c/syO+uWMlm5igc7LysKzPXaDoR2vroROkSwsTS2tGr1yGGEbZOYZQ== + dependencies: + icss-utils "^5.1.0" + postcss "^8.2.15" + postcss-modules-extract-imports "^3.0.0" + postcss-modules-local-by-default "^4.0.0" + postcss-modules-scope "^3.0.0" + postcss-modules-values "^4.0.0" + postcss-value-parser "^4.1.0" + semver "^7.3.5" + +css-prefers-color-scheme@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz#6f830a2714199d4f0d0d0bb8a27916ed65cff1f4" + integrity sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg== + dependencies: + postcss "^7.0.5" + +css-select@^4.1.3: + version "4.2.1" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.2.1.tgz#9e665d6ae4c7f9d65dbe69d0316e3221fb274cdd" + integrity sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ== + dependencies: + boolbase "^1.0.0" + css-what "^5.1.0" + domhandler "^4.3.0" + domutils "^2.8.0" + nth-check "^2.0.1" + +css-what@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.1.0.tgz#3f7b707aadf633baf62c2ceb8579b545bb40f7fe" + integrity sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw== + +css@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/css/-/css-3.0.0.tgz#4447a4d58fdd03367c516ca9f64ae365cee4aa5d" + integrity sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ== + dependencies: + inherits "^2.0.4" + source-map "^0.6.1" + source-map-resolve "^0.6.0" + +cssdb@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-4.4.0.tgz#3bf2f2a68c10f5c6a08abd92378331ee803cddb0" + integrity sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ== + +cssesc@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-2.0.0.tgz#3b13bd1bb1cb36e1bcb5a4dcd27f54c5dcb35703" + integrity sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg== + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +custom-event@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" + integrity sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU= + +date-fns@^2.16.1: + version "2.28.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.28.0.tgz#9570d656f5fc13143e50c975a3b6bbeb46cd08b2" + integrity sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw== + +date-format@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-4.0.3.tgz#f63de5dc08dc02efd8ef32bf2a6918e486f35873" + integrity sha512-7P3FyqDcfeznLZp2b+OMitV9Sz2lUnsT87WaTat9nVwqsBkTzPG3lPLNwW3en6F4pHUiWzr6vb8CLhjdK9bcxQ== + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@4, debug@4.3.3, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.3, debug@~4.3.1, debug@~4.3.2: + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== + dependencies: + ms "2.1.2" + +debug@^3.1.1, debug@^3.2.6: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +debug@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +deep-equal@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" + integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== + dependencies: + is-arguments "^1.0.4" + is-date-object "^1.0.1" + is-regex "^1.0.4" + object-is "^1.0.1" + object-keys "^1.1.1" + regexp.prototype.flags "^1.2.0" + +default-gateway@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" + integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== + dependencies: + execa "^5.0.0" + +defaults@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" + integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= + dependencies: + clone "^1.0.2" + +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== + +define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +del@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/del/-/del-6.0.0.tgz#0b40d0332cea743f1614f818be4feb717714c952" + integrity sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ== + dependencies: + globby "^11.0.1" + graceful-fs "^4.2.4" + is-glob "^4.0.1" + is-path-cwd "^2.2.0" + is-path-inside "^3.0.2" + p-map "^4.0.0" + rimraf "^3.0.2" + slash "^3.0.0" + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +depd@^1.1.2, depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +dependency-graph@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/dependency-graph/-/dependency-graph-0.11.0.tgz#ac0ce7ed68a54da22165a85e97a01d53f5eb2e27" + integrity sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg== + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +detect-node@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== + +di@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" + integrity sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw= + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +dns-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" + integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= + +dns-packet@^1.3.1: + version "1.3.4" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.4.tgz#e3455065824a2507ba886c55a89963bb107dec6f" + integrity sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA== + dependencies: + ip "^1.1.0" + safe-buffer "^5.0.1" + +dns-txt@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" + integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= + dependencies: + buffer-indexof "^1.0.0" + +dom-serialize@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" + integrity sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs= + dependencies: + custom-event "~1.0.0" + ent "~2.2.0" + extend "^3.0.0" + void-elements "^2.0.0" + +dom-serializer@^1.0.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91" + integrity sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.2.0" + entities "^2.0.0" + +domelementtype@^2.0.1, domelementtype@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" + integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== + +domhandler@^4.2.0, domhandler@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.0.tgz#16c658c626cf966967e306f966b431f77d4a5626" + integrity sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g== + dependencies: + domelementtype "^2.2.0" + +domutils@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" + integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +electron-to-chromium@^1.4.17: + version "1.4.51" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.51.tgz#a432f5a5d983ace79278a33057300cf949627e63" + integrity sha512-JNEmcYl3mk1tGQmy0EvL5eik/CKSBuzAyGP0QFdG6LIgxQe3II0BL1m2zKc2MZMf3uGqHWE1TFddJML0RpjSHQ== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +encoding@^0.1.12: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + +engine.io-parser@~5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.0.3.tgz#ca1f0d7b11e290b4bfda251803baea765ed89c09" + integrity sha512-BtQxwF27XUNnSafQLvDi0dQ8s3i6VgzSoQMJacpIcGNrlUdfHSKbgm3jmjCVvQluGzqwujQMPAoMai3oYSTurg== + dependencies: + "@socket.io/base64-arraybuffer" "~1.0.2" + +engine.io@~6.1.0: + version "6.1.2" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.1.2.tgz#e7b9d546d90c62246ffcba4d88594be980d3855a" + integrity sha512-v/7eGHxPvO2AWsksyx2PUsQvBafuvqs0jJJQ0FdmJG1b9qIvgSbqDRGwNhfk2XHaTTbTXiC4quRE8Q9nRjsrQQ== + dependencies: + "@types/cookie" "^0.4.1" + "@types/cors" "^2.8.12" + "@types/node" ">=10.0.0" + accepts "~1.3.4" + base64id "2.0.0" + cookie "~0.4.1" + cors "~2.8.5" + debug "~4.3.1" + engine.io-parser "~5.0.0" + ws "~8.2.3" + +enhanced-resolve@^5.8.3: + version "5.8.3" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz#6d552d465cce0423f5b3d718511ea53826a7b2f0" + integrity sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +ent@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" + integrity sha1-6WQhkyWiHQX0RGai9obtbOX13R0= + +entities@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== + +env-paths@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" + integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== + +err-code@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" + integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== + +errno@^0.1.1: + version "0.1.8" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== + dependencies: + prr "~1.0.1" + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-module-lexer@^0.9.0: + version "0.9.3" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" + integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== + +esbuild-android-arm64@0.14.5: + version "0.14.5" + resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.5.tgz#a7bc2263e099b67d1d6bc10ad504f396b439a42a" + integrity sha512-Sl6ysm7OAZZz+X3Mv3tOPhjMuSxNmztgoXH4ZZ3Yhbje5emEY6qiTnv3vBSljDlUl/yGaIjqC44qlj8s8G71xA== + +esbuild-darwin-64@0.14.5: + version "0.14.5" + resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.5.tgz#589f4b8663feb044f2425e70618f6a9debebaf14" + integrity sha512-VHZl23sM9BOZXcLxk1vTYls8TCAY+/3llw9vHKIWAHDHzBBOlVv26ORK8gnStNMqTjCSGSMoq4T5jOZf2WrJPQ== + +esbuild-darwin-arm64@0.14.5: + version "0.14.5" + resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.5.tgz#c4def102fddd52ccaf23cf00c3274296de6b12db" + integrity sha512-ugPOLgEQPoPLSqAFBajaczt+lcbUZR+V2fby3572h5jf/kFV6UL8LAZ1Ze58hcbKwfvbh4C09kp0PhqPgXKwOg== + +esbuild-freebsd-64@0.14.5: + version "0.14.5" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.5.tgz#e5152bbf256942fe498dfe4a5f92b8bb148a64b5" + integrity sha512-uP0yOixSHF505o/Kzq9e4bvZblCZp9GGx+a7enLOVSuvIvLmtj2yhZLRPGfbVNkPJXktTKNRAnNGkXHl53M6sw== + +esbuild-freebsd-arm64@0.14.5: + version "0.14.5" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.5.tgz#7c1ad25ae9ed101df76dc64d83fcfd2ddba5aed0" + integrity sha512-M99NPu8hlirFo6Fgx0WfX6XxUFdGclUNv3MyyfDtTdNYbccMESwLSACGpE7HvJKWscdjaqajeMu2an9adGNfCw== + +esbuild-linux-32@0.14.5: + version "0.14.5" + resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.5.tgz#047a2d6d9dd5f85e6e6875b048c41ab2515e12ce" + integrity sha512-hfqln4yb/jf/vPvI/A6aCvpIzqF3PdDmrKiikTohEUuRtvEZz234krtNwEAw5ssCue4NX8BJqrMpCTAHOl3LQw== + +esbuild-linux-64@0.14.5: + version "0.14.5" + resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.5.tgz#03793b5a0ae450c725616fc724b3a406cd2da2fa" + integrity sha512-T+OuYPlhytjj5DsvjUXizNjbV+/IrZiaDc9SNUfqiUOXHu0URFqchjhPVbBiBnWykCMJFB6pqNap2Oxth4iuYw== + +esbuild-linux-arm64@0.14.5: + version "0.14.5" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.5.tgz#9217283b5ccaf2ec9a31f9b4eaeb5787607252a3" + integrity sha512-ANOzoaH4kfbhEZT0EGY9g1tsZhDA+I0FRwBsj7D8pCU900pXF/l8YAOy5jWFQIb3vjG5+orFc5SqSzAKCisvTQ== + +esbuild-linux-arm@0.14.5: + version "0.14.5" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.5.tgz#e048a681e7f42b12cac1db4a34a84ef17e219333" + integrity sha512-5b10jKJ3lU4BUchOw9TgRResu8UZJf8qVjAzV5muHedonCfBzClGTT4KCNuOcLTJomH3wz6gNVJt1AxMglXnJg== + +esbuild-linux-mips64le@0.14.5: + version "0.14.5" + resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.5.tgz#c1817c00023d8a1c8fe507e60c63cf8a602bce29" + integrity sha512-sSmGfOUNNB2Nd3tzp1RHSxiJmM5/RUIEP5aAtH+PpOP7FPp15Jcfwq7UNBJ82KLN3SJcwhUeEfcCaUFBzbTKxg== + +esbuild-linux-ppc64le@0.14.5: + version "0.14.5" + resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.5.tgz#5fa1178c7d7ebd13056c7ccd0604653b0ccc2264" + integrity sha512-usfQrVVIQcpuc/U2NWc7/Ry+m622v+PjJ5eErNPdjWBPlcvD6kXaBTv94uQkVzZOHX3uYqprRrOjseed9ApSYA== + +esbuild-netbsd-64@0.14.5: + version "0.14.5" + resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.5.tgz#757572c7664ae6122c8e4dd89a2b6d337c3c27b2" + integrity sha512-Q5KpvPZcPnNEaTjrvuWqvEnlhI2jyi1wWwYunlEUAhx60spQOTy10sdYOA+s1M+LPb6kwvasrZZDmYyQlcVZeA== + +esbuild-openbsd-64@0.14.5: + version "0.14.5" + resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.5.tgz#046827c211daa2b6a2241a9f910321e116d2cc24" + integrity sha512-RZzRUu1RYKextJgXkHhAsuhLDvm73YP/wogpUG9MaAGvKTxnKAKRuaw2zJfnbz8iBqBQB2no2PmpVBNbqUTQrw== + +esbuild-sunos-64@0.14.5: + version "0.14.5" + resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.5.tgz#3e2b0e79188069a366faec3d5b1b3065b792a733" + integrity sha512-J2ffKsBBWscQlye+/giEgKsQCppwHHFqqt/sh+ojVF+DZy1ve6RpPGwXGcGF6IaZTAI9+Vk4eHleiQxb+PC9Yw== + +esbuild-wasm@0.14.5: + version "0.14.5" + resolved "https://registry.yarnpkg.com/esbuild-wasm/-/esbuild-wasm-0.14.5.tgz#fdd22d953b5c746db4b22236092391fbca5a2a3a" + integrity sha512-oIC9zxAUE3ce1+2L5H6+ThFQ7sgZViAXGXCTo0i8r+1W+fS9STUp9YSLla/8cL0/HFxfFZ1qRR4XcmIvpxABQQ== + +esbuild-windows-32@0.14.5: + version "0.14.5" + resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.5.tgz#520f3737719177d76955b8f1c34eca8e8d005eba" + integrity sha512-OTZvuAc1JBnwmeT+hR1+Vmgz6LOD7DggpnwtKMAExruSLxUMl02Z3pyalJ7zKh3gJ/KBRM1JQZLSk4/mFWijeQ== + +esbuild-windows-64@0.14.5: + version "0.14.5" + resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.5.tgz#0100d8aa3c5d57e676aeb37975e948880f751650" + integrity sha512-ZM9rlBDsPEeMVJ1wcpNMXUad9VzYOFeOBUXBi+16HZTvFPy2DkcC2ZWcrByP3IESToD5lvHdjSX/w8rxphjqig== + +esbuild-windows-arm64@0.14.5: + version "0.14.5" + resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.5.tgz#c1d575f2c6d27159de9b5d273bcde02445f17a1d" + integrity sha512-iK41mKG2LG0AKHE+9g/jDYU5ZQpJObt1uIPSGTiiiJKI5qbHdEck6Gaqq2tmBI933F2zB9yqZIX7IAdxwN/q4A== + +esbuild@0.14.5: + version "0.14.5" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.5.tgz#45ef0287a94cc7a3d367621e4a7ba470a847669f" + integrity sha512-ofwgH4ITPXhkMo2AM39oXpSe5KIyWjxicdqYVy+tLa1lMgxzPCKwaepcrSRtYbgTUMXwquxB1C3xQYpUNaPAFA== + optionalDependencies: + esbuild-android-arm64 "0.14.5" + esbuild-darwin-64 "0.14.5" + esbuild-darwin-arm64 "0.14.5" + esbuild-freebsd-64 "0.14.5" + esbuild-freebsd-arm64 "0.14.5" + esbuild-linux-32 "0.14.5" + esbuild-linux-64 "0.14.5" + esbuild-linux-arm "0.14.5" + esbuild-linux-arm64 "0.14.5" + esbuild-linux-mips64le "0.14.5" + esbuild-linux-ppc64le "0.14.5" + esbuild-netbsd-64 "0.14.5" + esbuild-openbsd-64 "0.14.5" + esbuild-sunos-64 "0.14.5" + esbuild-windows-32 "0.14.5" + esbuild-windows-64 "0.14.5" + esbuild-windows-arm64 "0.14.5" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +eslint-scope@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +eventemitter-asyncresource@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/eventemitter-asyncresource/-/eventemitter-asyncresource-1.0.0.tgz#734ff2e44bf448e627f7748f905d6bdd57bdb65b" + integrity sha512-39F7TBIV0G7gTelxwbEqnwhp90eqCPON1k0NwNfwhgKn4Co4ybUbj2pECcXT0B3ztRKZ7Pw1JujUUgmQJHcVAQ== + +eventemitter3@^4.0.0: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +events@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +express@^4.17.1: + version "4.17.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.2.tgz#c18369f265297319beed4e5558753cc8c1364cb3" + integrity sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg== + dependencies: + accepts "~1.3.7" + array-flatten "1.1.1" + body-parser "1.19.1" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.4.1" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "~1.1.2" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.9.6" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.17.2" + serve-static "1.14.2" + setprototypeof "1.2.0" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +extend@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +external-editor@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^3.2.7, fast-glob@^3.2.9: + version "3.2.11" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" + integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@2.1.0, fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fastq@^1.6.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + dependencies: + reusify "^1.0.4" + +faye-websocket@^0.11.3: + version "0.11.4" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" + integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== + dependencies: + websocket-driver ">=0.5.1" + +figures@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" + integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== + dependencies: + escape-string-regexp "^1.0.5" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.1.2, finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +find-cache-dir@^3.3.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" + integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== + dependencies: + commondir "^1.0.1" + make-dir "^3.0.2" + pkg-dir "^4.1.0" + +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +flatted@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.4.tgz#28d9969ea90661b5134259f312ab6aa7929ac5e2" + integrity sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw== + +flatten@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b" + integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg== + +follow-redirects@^1.0.0, follow-redirects@^1.14.0: + version "1.14.7" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.7.tgz#2004c02eb9436eee9a21446a6477debf17e81685" + integrity sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ== + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +fs-extra@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.0.tgz#9ff61b655dde53fb34a82df84bb214ce802e17c1" + integrity sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-minipass@^2.0.0, fs-minipass@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" + integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== + dependencies: + minipass "^3.0.0" + +fs-monkey@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" + integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +gauge@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-4.0.0.tgz#afba07aa0374a93c6219603b1fb83eaa2264d8f8" + integrity sha512-F8sU45yQpjQjxKkm1UOAhf0U/O0aFt//Fl7hsrNVto+patMHjs7dPI9mFOGUKbhrgKm0S3EjW3scMFuQmWSROw== + dependencies: + ansi-regex "^5.0.1" + aproba "^1.0.3 || ^2.0.0" + color-support "^1.1.2" + console-control-strings "^1.0.0" + has-unicode "^2.0.1" + signal-exit "^3.0.0" + string-width "^4.2.3" + strip-ansi "^6.0.1" + wide-align "^1.1.2" + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + +glob@7.2.0, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.1.7: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globby@^11.0.1: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + +globby@^12.0.2: + version "12.2.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-12.2.0.tgz#2ab8046b4fba4ff6eede835b29f678f90e3d3c22" + integrity sha512-wiSuFQLZ+urS9x2gGPl1H5drc5twabmm4m2gTR27XDFyjUHJUNsS8o/2aKyIF6IoBaR630atdher0XJ5g6OMmA== + dependencies: + array-union "^3.0.1" + dir-glob "^3.0.1" + fast-glob "^3.2.7" + ignore "^5.1.9" + merge2 "^1.4.1" + slash "^4.0.0" + +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6: + version "4.2.9" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" + integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== + +handle-thing@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" + integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.1, has-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + +has-unicode@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hdr-histogram-js@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/hdr-histogram-js/-/hdr-histogram-js-2.0.3.tgz#0b860534655722b6e3f3e7dca7b78867cf43dcb5" + integrity sha512-Hkn78wwzWHNCp2uarhzQ2SGFLU3JY8SBDDd3TAABK4fc30wm+MuPOrg5QVFVfkKOQd6Bfz3ukJEI+q9sXEkK1g== + dependencies: + "@assemblyscript/loader" "^0.10.1" + base64-js "^1.2.0" + pako "^1.0.3" + +hdr-histogram-percentiles-obj@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/hdr-histogram-percentiles-obj/-/hdr-histogram-percentiles-obj-3.0.0.tgz#9409f4de0c2dda78e61de2d9d78b1e9f3cba283c" + integrity sha512-7kIufnBqdsBGcSZLPJwqHT3yhk1QTsSlFsVD3kx5ixH/AlgBs9yM1q6DPhXZ8f8gtdqgh7N7/5btRLpQsS2gHw== + +hosted-git-info@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz#827b82867e9ff1c8d0c4d9d53880397d2c86d224" + integrity sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA== + dependencies: + lru-cache "^6.0.0" + +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +html-entities@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.2.tgz#760b404685cb1d794e4f4b744332e3b00dcfe488" + integrity sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ== + +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + +http-cache-semantics@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" + integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== + +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= + +http-errors@1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" + integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.1" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-parser-js@>=0.5.1: + version "0.5.5" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.5.tgz#d7c30d5d3c90d865b4a2e870181f9d6f22ac7ac5" + integrity sha512-x+JVEkO2PoM8qqpbPbOL3cqHPwerep7OwzK7Ay+sMQjKzaKCqWvjoXm5tqMP9tXWWTnTzAjIhXg+J99XYuPhPA== + +http-proxy-agent@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== + dependencies: + "@tootallnate/once" "1" + agent-base "6" + debug "4" + +http-proxy-middleware@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.2.tgz#94d7593790aad6b3de48164f13792262f656c332" + integrity sha512-XtmDN5w+vdFTBZaYhdJAbMqn0DP/EhkUaAeo963mojwpKMMbw6nivtFKw07D7DDOH745L5k0VL0P8KRYNEVF/g== + dependencies: + "@types/http-proxy" "^1.17.8" + http-proxy "^1.18.1" + is-glob "^4.0.1" + is-plain-obj "^3.0.0" + micromatch "^4.0.2" + +http-proxy@^1.18.1: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +https-proxy-agent@5.0.0, https-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== + dependencies: + agent-base "6" + debug "4" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +humanize-ms@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + integrity sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0= + dependencies: + ms "^2.0.0" + +iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@^0.6.2: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +icss-utils@^5.0.0, icss-utils@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" + integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== + +ieee754@^1.1.13: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +ignore-walk@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-4.0.1.tgz#fc840e8346cf88a3a9380c5b17933cd8f4d39fa3" + integrity sha512-rzDQLaW4jQbh2YrOFlJdCtX8qgJTehFRYiUB2r1osqTeDzV/3+Jh8fz1oAPzUThf3iku8Ds4IDqawI5d8mUiQw== + dependencies: + minimatch "^3.0.4" + +ignore@^5.1.9, ignore@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== + +image-size@~0.5.0: + version "0.5.5" + resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c" + integrity sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w= + +immediate@~3.0.5: + version "3.0.6" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + integrity sha1-nbHb0Pr43m++D13V5Wu2BigN5ps= + +immutable@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.0.0.tgz#b86f78de6adef3608395efb269a91462797e2c23" + integrity sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw== + +import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +indexes-of@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" + integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= + +infer-owner@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +ini@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" + integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== + +inquirer@8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.0.tgz#f44f008dd344bbfc4b30031f45d984e034a3ac3a" + integrity sha512-0crLweprevJ02tTuA6ThpoAERAGyVILC4sS74uib58Xf/zSr1/ZWtmm7D5CI+bSQEaA04f0K7idaHpQbSWgiVQ== + dependencies: + ansi-escapes "^4.2.1" + chalk "^4.1.1" + cli-cursor "^3.1.0" + cli-width "^3.0.0" + external-editor "^3.0.3" + figures "^3.0.0" + lodash "^4.17.21" + mute-stream "0.0.8" + ora "^5.4.1" + run-async "^2.4.0" + rxjs "^7.2.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + through "^2.3.6" + +ip@^1.1.0, ip@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +ipaddr.js@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" + integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== + +is-arguments@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-core-module@^2.2.0, is-core-module@^2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" + integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== + dependencies: + has "^1.0.3" + +is-date-object@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + +is-docker@^2.0.0, is-docker@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-interactive@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" + integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== + +is-lambda@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" + integrity sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU= + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-path-cwd@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" + integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== + +is-path-inside@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-plain-obj@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" + integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== + +is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-regex@^1.0.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +is-what@^3.12.0: + version "3.14.1" + resolved "https://registry.yarnpkg.com/is-what/-/is-what-3.14.1.tgz#e1222f46ddda85dead0fd1c9df131760e77755c1" + integrity sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA== + +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isbinaryfile@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.8.tgz#5d34b94865bd4946633ecc78a026fc76c5b11fcf" + integrity sha512-53h6XFniq77YdW+spoRrebh0mnmTxRPTlcuIArO57lmMdq4uBKFKaeTjnb92oYWrSn/LVL+LT+Hap2tFQj8V+w== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" + integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== + +istanbul-lib-instrument@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d" + integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ== + dependencies: + "@babel/core" "^7.7.5" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.0.0" + semver "^6.3.0" + +istanbul-lib-instrument@^5.0.4: + version "5.1.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz#7b49198b657b27a730b8e9cb601f1e1bff24c59a" + integrity sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" + +istanbul-lib-report@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" + integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^3.0.0" + supports-color "^7.1.0" + +istanbul-lib-source-maps@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + +istanbul-reports@^3.0.5: + version "3.1.3" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.3.tgz#4bcae3103b94518117930d51283690960b50d3c2" + integrity sha512-x9LtDVtfm/t1GFiLl3NffC7hz+I1ragvgX1P/Lg1NlIagifZDKUkuuaAxH/qpwj2IuEfD8G2Bs/UKp+sZ/pKkg== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + +jasmine-core@^3.6.0: + version "3.99.0" + resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-3.99.0.tgz#99a3da0d38ba2de82614d9198b7b1bc1c32a5960" + integrity sha512-+ZDaJlEfRopINQqgE+hvzRyDIQDeKfqqTvF8RzXsvU1yE3pBDRud2+Qfh9WvGgRpuzqxyQJVI6Amy5XQ11r/3w== + +jasmine-core@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-4.0.0.tgz#8299ed38a100c47a1d154af63449a40967a7be5c" + integrity sha512-tq24OCqHElgU9KDpb/8O21r1IfotgjIzalfW9eCmRR40LZpvwXT68iariIyayMwi0m98RDt16aljdbwK0sBMmQ== + +jasmine-core@~3.10.0: + version "3.10.1" + resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-3.10.1.tgz#7aa6fa2b834a522315c651a128d940eca553989a" + integrity sha512-ooZWSDVAdh79Rrj4/nnfklL3NQVra0BcuhcuWoAwwi+znLDoUeH87AFfeX8s+YeYi6xlv5nveRyaA1v7CintfA== + +jasmine@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/jasmine/-/jasmine-4.0.2.tgz#6f5ff7fbf6b67f56600235fdb7d299ac52876c4b" + integrity sha512-YsrgxJQEggxzByYe4j68eQLOiQeSrPDYGv4sHhGBp3c6HHdq+uPXeAQ73kOAQpdLZ3/0zN7x/TZTloqeE1/qIA== + dependencies: + glob "^7.1.6" + jasmine-core "^4.0.0" + +jest-worker@^27.4.1: + version "27.4.6" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.4.6.tgz#5d2d93db419566cb680752ca0792780e71b3273e" + integrity sha512-gHWJF/6Xi5CTG5QCvROr6GcmpIqNYpDJyc8A1h/DyXqH1tD6SnRCM0d3U5msV31D2LB/U+E0M+W4oyvKV44oNw== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +joi@^17.4.0: + version "17.5.0" + resolved "https://registry.yarnpkg.com/joi/-/joi-17.5.0.tgz#7e66d0004b5045d971cf416a55fb61d33ac6e011" + integrity sha512-R7hR50COp7StzLnDi4ywOXHrBrgNXuUUfJWIR5lPY5Bm/pOD3jZaTwpluUXVLRWcoWZxkrHBBJ5hLxgnlehbdw== + dependencies: + "@hapi/hoek" "^9.0.0" + "@hapi/topo" "^5.0.0" + "@sideway/address" "^4.1.3" + "@sideway/formula" "^3.0.0" + "@sideway/pinpoint" "^2.0.0" + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + +json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + +json5@^2.1.2: + version "2.2.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" + integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== + dependencies: + minimist "^1.2.5" + +jsonc-parser@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.0.0.tgz#abdd785701c7e7eaca8a9ec8cf070ca51a745a22" + integrity sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA== + +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +jsonparse@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" + integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= + +jszip@^3.1.3: + version "3.7.1" + resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.7.1.tgz#bd63401221c15625a1228c556ca8a68da6fda3d9" + integrity sha512-ghL0tz1XG9ZEmRMcEN2vt7xabrDdqHHeykgARpmZ0BiIctWxM47Vt63ZO2dnp4QYt/xJVLLy5Zv1l/xRdh2byg== + dependencies: + lie "~3.3.0" + pako "~1.0.2" + readable-stream "~2.3.6" + set-immediate-shim "~1.0.1" + +karma-chrome-launcher@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-3.1.0.tgz#805a586799a4d05f4e54f72a204979f3f3066738" + integrity sha512-3dPs/n7vgz1rxxtynpzZTvb9y/GIaW8xjAwcIGttLbycqoFtI7yo1NGnQi6oFTherRE+GIhCAHZC4vEqWGhNvg== + dependencies: + which "^1.2.1" + +karma-coverage@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/karma-coverage/-/karma-coverage-2.1.0.tgz#843564578d9e1fb889ec141a582c019bb6db14db" + integrity sha512-uIejpnArNFQIovB6EPsKO/T4XofELdJWXcA2ADXztFlKhHbr0Ws6ba7wKTMVWsIhEs4iJxdhQkCQrkkhFJSZCw== + dependencies: + istanbul-lib-coverage "^3.2.0" + istanbul-lib-instrument "^4.0.3" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.1" + istanbul-reports "^3.0.5" + minimatch "^3.0.4" + +karma-jasmine-html-reporter@~1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-1.7.0.tgz#52c489a74d760934a1089bfa5ea4a8fcb84cc28b" + integrity sha512-pzum1TL7j90DTE86eFt48/s12hqwQuiD+e5aXx2Dc9wDEn2LfGq6RoAxEZZjFiN0RDSCOnosEKRZWxbQ+iMpQQ== + +karma-jasmine@~4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/karma-jasmine/-/karma-jasmine-4.0.1.tgz#b99e073b6d99a5196fc4bffc121b89313b0abd82" + integrity sha512-h8XDAhTiZjJKzfkoO1laMH+zfNlra+dEQHUAjpn5JV1zCPtOIVWGQjLBrqhnzQa/hrU2XrZwSyBa6XjEBzfXzw== + dependencies: + jasmine-core "^3.6.0" + +karma-source-map-support@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz#58526ceccf7e8730e56effd97a4de8d712ac0d6b" + integrity sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A== + dependencies: + source-map-support "^0.5.5" + +karma@~6.3.0: + version "6.3.11" + resolved "https://registry.yarnpkg.com/karma/-/karma-6.3.11.tgz#2c2fb09f1a9f52e1a0739adeedace2a68d4c0d34" + integrity sha512-QGUh4yXgizzDNPLB5nWTvP+wysKexngbyLVWFOyikB661hpa2RZLf5anZQzqliWtAQuYVep0ot0D1U7UQKpsxQ== + dependencies: + body-parser "^1.19.0" + braces "^3.0.2" + chokidar "^3.5.1" + colors "1.4.0" + connect "^3.7.0" + di "^0.0.1" + dom-serialize "^2.2.1" + glob "^7.1.7" + graceful-fs "^4.2.6" + http-proxy "^1.18.1" + isbinaryfile "^4.0.8" + lodash "^4.17.21" + log4js "^6.3.0" + mime "^2.5.2" + minimatch "^3.0.4" + qjobs "^1.2.0" + range-parser "^1.2.1" + rimraf "^3.0.2" + socket.io "^4.2.0" + source-map "^0.6.1" + tmp "^0.2.1" + ua-parser-js "^0.7.30" + yargs "^16.1.1" + +kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +klona@^2.0.4, klona@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.5.tgz#d166574d90076395d9963aa7a928fabb8d76afbc" + integrity sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ== + +less-loader@10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-10.2.0.tgz#97286d8797dc3dc05b1d16b0ecec5f968bdd4e32" + integrity sha512-AV5KHWvCezW27GT90WATaDnfXBv99llDbtaj4bshq6DvAihMdNjaPDcUMa6EXKLRF+P2opFenJp89BXg91XLYg== + dependencies: + klona "^2.0.4" + +less@4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/less/-/less-4.1.2.tgz#6099ee584999750c2624b65f80145f8674e4b4b0" + integrity sha512-EoQp/Et7OSOVu0aJknJOtlXZsnr8XE8KwuzTHOLeVSEx8pVWUICc8Q0VYRHgzyjX78nMEyC/oztWFbgyhtNfDA== + dependencies: + copy-anything "^2.0.1" + parse-node-version "^1.0.1" + tslib "^2.3.0" + optionalDependencies: + errno "^0.1.1" + graceful-fs "^4.1.2" + image-size "~0.5.0" + make-dir "^2.1.0" + mime "^1.4.1" + needle "^2.5.2" + source-map "~0.6.0" + +license-webpack-plugin@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/license-webpack-plugin/-/license-webpack-plugin-4.0.0.tgz#11cf6ac96559f4a987cf55d3d2a33f295ae8f13b" + integrity sha512-b9iMrROrw2fTOJBZ57h0xJfT5/1Cxg4ucYbtpWoukv4Awb2TFPfDDFVHNM8w6SYQpVfB13a5tQJxgGamqwrsyw== + dependencies: + webpack-sources "^3.0.0" + +lie@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a" + integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ== + dependencies: + immediate "~3.0.5" + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +loader-runner@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" + integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw== + +loader-utils@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-3.2.0.tgz#bcecc51a7898bee7473d4bc6b845b23af8304d4f" + integrity sha512-HVl9ZqccQihZ7JM85dco1MvO9G+ONvxoGa9rkhzFsneGLKSUg1gJf9bWzhRhcvm2qChhWpebQhP44qxjKIUCaQ== + +loader-utils@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" + integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^1.0.1" + +loader-utils@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.2.tgz#d6e3b4fb81870721ae4e0868ab11dd638368c129" + integrity sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= + +lodash@^4.17.14, lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log-symbols@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +log4js@^6.3.0: + version "6.4.1" + resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.4.1.tgz#9d3a8bf2c31c1e213fe3fc398a6053f7a2bc53e8" + integrity sha512-iUiYnXqAmNKiIZ1XSAitQ4TmNs8CdZYTAWINARF3LjnsLN8tY5m0vRwd6uuWj/yNY0YHxeZodnbmxKFUOM2rMg== + dependencies: + date-format "^4.0.3" + debug "^4.3.3" + flatted "^3.2.4" + rfdc "^1.3.0" + streamroller "^3.0.2" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +magic-string@0.25.7, magic-string@^0.25.0: + version "0.25.7" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051" + integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA== + dependencies: + sourcemap-codec "^1.4.4" + +make-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + +make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +make-fetch-happen@^9.0.1, make-fetch-happen@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz#53085a09e7971433e6765f7971bf63f4e05cb968" + integrity sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg== + dependencies: + agentkeepalive "^4.1.3" + cacache "^15.2.0" + http-cache-semantics "^4.1.0" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-lambda "^1.0.1" + lru-cache "^6.0.0" + minipass "^3.1.3" + minipass-collect "^1.0.2" + minipass-fetch "^1.3.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + negotiator "^0.6.2" + promise-retry "^2.0.1" + socks-proxy-agent "^6.0.0" + ssri "^8.0.0" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +memfs@^3.2.2: + version "3.4.1" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.1.tgz#b78092f466a0dce054d63d39275b24c71d3f1305" + integrity sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw== + dependencies: + fs-monkey "1.0.3" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +micromatch@^4.0.2, micromatch@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" + integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== + dependencies: + braces "^3.0.1" + picomatch "^2.2.3" + +mime-db@1.51.0, "mime-db@>= 1.43.0 < 2": + version "1.51.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" + integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== + +mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24: + version "2.1.34" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24" + integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A== + dependencies: + mime-db "1.51.0" + +mime@1.6.0, mime@^1.4.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mime@^2.5.2: + version "2.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mini-css-extract-plugin@2.4.5: + version "2.4.5" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.4.5.tgz#191d6c170226037212c483af1180b4010b7b9eef" + integrity sha512-oEIhRucyn1JbT/1tU2BhnwO6ft1jjH1iCX9Gc59WFMg0n5773rQU0oyQ0zzeYFFuBfONaRbQJyGoPtuNseMxjA== + dependencies: + schema-utils "^4.0.0" + +minimalistic-assert@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimatch@3.0.4, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +minipass-collect@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" + integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== + dependencies: + minipass "^3.0.0" + +minipass-fetch@^1.3.0, minipass-fetch@^1.3.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-1.4.1.tgz#d75e0091daac1b0ffd7e9d41629faff7d0c1f1b6" + integrity sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw== + dependencies: + minipass "^3.1.0" + minipass-sized "^1.0.3" + minizlib "^2.0.0" + optionalDependencies: + encoding "^0.1.12" + +minipass-flush@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" + integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== + dependencies: + minipass "^3.0.0" + +minipass-json-stream@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz#7edbb92588fbfc2ff1db2fc10397acb7b6b44aa7" + integrity sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg== + dependencies: + jsonparse "^1.3.1" + minipass "^3.0.0" + +minipass-pipeline@^1.2.2, minipass-pipeline@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" + integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== + dependencies: + minipass "^3.0.0" + +minipass-sized@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" + integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== + dependencies: + minipass "^3.0.0" + +minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3: + version "3.1.6" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.6.tgz#3b8150aa688a711a1521af5e8779c1d3bb4f45ee" + integrity sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ== + dependencies: + yallist "^4.0.0" + +minizlib@^2.0.0, minizlib@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" + integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== + dependencies: + minipass "^3.0.0" + yallist "^4.0.0" + +mkdirp@^0.5.5: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +mkdirp@^1.0.3, mkdirp@^1.0.4, mkdirp@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3, ms@^2.0.0, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +multicast-dns-service-types@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" + integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= + +multicast-dns@^6.0.1: + version "6.2.3" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" + integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g== + dependencies: + dns-packet "^1.3.1" + thunky "^1.0.2" + +mute-stream@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + +nanoid@^3.1.30: + version "3.2.0" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" + integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== + +needle@^2.5.2: + version "2.9.1" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.9.1.tgz#22d1dffbe3490c2b83e301f7709b6736cd8f2684" + integrity sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ== + dependencies: + debug "^3.2.6" + iconv-lite "^0.4.4" + sax "^1.2.4" + +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== + +negotiator@^0.6.2: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +nice-napi@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nice-napi/-/nice-napi-1.0.2.tgz#dc0ab5a1eac20ce548802fc5686eaa6bc654927b" + integrity sha512-px/KnJAJZf5RuBGcfD+Sp2pAKq0ytz8j+1NehvgIGFkvtvFrDM3T8E4x/JJODXK9WZow8RRGrbA9QQ3hs+pDhA== + dependencies: + node-addon-api "^3.0.0" + node-gyp-build "^4.2.2" + +node-addon-api@^3.0.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161" + integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== + +node-forge@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" + integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== + +node-gyp-build@^4.2.2: + version "4.3.0" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.3.0.tgz#9f256b03e5826150be39c764bf51e993946d71a3" + integrity sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q== + +node-gyp@^8.2.0: + version "8.4.1" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-8.4.1.tgz#3d49308fc31f768180957d6b5746845fbd429937" + integrity sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w== + dependencies: + env-paths "^2.2.0" + glob "^7.1.4" + graceful-fs "^4.2.6" + make-fetch-happen "^9.1.0" + nopt "^5.0.0" + npmlog "^6.0.0" + rimraf "^3.0.2" + semver "^7.3.5" + tar "^6.1.2" + which "^2.0.2" + +node-releases@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" + integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== + +nopt@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" + integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== + dependencies: + abbrev "1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= + +npm-bundled@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.2.tgz#944c78789bd739035b70baa2ca5cc32b8d860bc1" + integrity sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ== + dependencies: + npm-normalize-package-bin "^1.0.1" + +npm-install-checks@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-4.0.0.tgz#a37facc763a2fde0497ef2c6d0ac7c3fbe00d7b4" + integrity sha512-09OmyDkNLYwqKPOnbI8exiOZU2GVVmQp7tgez2BPi5OZC8M82elDAps7sxC4l//uSUtotWqoEIDwjRvWH4qz8w== + dependencies: + semver "^7.1.1" + +npm-normalize-package-bin@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" + integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== + +npm-package-arg@8.1.5, npm-package-arg@^8.0.0, npm-package-arg@^8.0.1, npm-package-arg@^8.1.2: + version "8.1.5" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.5.tgz#3369b2d5fe8fdc674baa7f1786514ddc15466e44" + integrity sha512-LhgZrg0n0VgvzVdSm1oiZworPbTxYHUJCgtsJW8mGvlDpxTM1vSJc3m5QZeUkhAHIzbz3VCHd/R4osi1L1Tg/Q== + dependencies: + hosted-git-info "^4.0.1" + semver "^7.3.4" + validate-npm-package-name "^3.0.0" + +npm-packlist@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-3.0.0.tgz#0370df5cfc2fcc8f79b8f42b37798dd9ee32c2a9" + integrity sha512-L/cbzmutAwII5glUcf2DBRNY/d0TFd4e/FnaZigJV6JD85RHZXJFGwCndjMWiiViiWSsWt3tiOLpI3ByTnIdFQ== + dependencies: + glob "^7.1.6" + ignore-walk "^4.0.1" + npm-bundled "^1.1.1" + npm-normalize-package-bin "^1.0.1" + +npm-pick-manifest@6.1.1, npm-pick-manifest@^6.0.0, npm-pick-manifest@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-6.1.1.tgz#7b5484ca2c908565f43b7f27644f36bb816f5148" + integrity sha512-dBsdBtORT84S8V8UTad1WlUyKIY9iMsAmqxHbLdeEeBNMLQDlDWWra3wYUx9EBEIiG/YwAy0XyNHDd2goAsfuA== + dependencies: + npm-install-checks "^4.0.0" + npm-normalize-package-bin "^1.0.1" + npm-package-arg "^8.1.2" + semver "^7.3.4" + +npm-registry-fetch@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-11.0.0.tgz#68c1bb810c46542760d62a6a965f85a702d43a76" + integrity sha512-jmlgSxoDNuhAtxUIG6pVwwtz840i994dL14FoNVZisrmZW5kWd63IUTNv1m/hyRSGSqWjCUp/YZlS1BJyNp9XA== + dependencies: + make-fetch-happen "^9.0.1" + minipass "^3.1.3" + minipass-fetch "^1.3.0" + minipass-json-stream "^1.0.1" + minizlib "^2.0.0" + npm-package-arg "^8.0.0" + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +npmlog@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.0.tgz#ba9ef39413c3d936ea91553db7be49c34ad0520c" + integrity sha512-03ppFRGlsyUaQFbGC2C8QWJN/C/K7PsfyD9aQdhVKAQIH4sQBc8WASqFBP7O+Ut4d2oo5LoeoboB3cGdBZSp6Q== + dependencies: + are-we-there-yet "^2.0.0" + console-control-strings "^1.1.0" + gauge "^4.0.0" + set-blocking "^2.0.0" + +nth-check@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.1.tgz#2efe162f5c3da06a28959fbd3db75dbeea9f0fc2" + integrity sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w== + dependencies: + boolbase "^1.0.0" + +num2fraction@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" + integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= + +object-assign@^4: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-is@^1.0.1: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^5.1.0, onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +open@8.4.0, open@^8.0.9: + version "8.4.0" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" + integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + +ora@5.4.1, ora@^5.4.1: + version "5.4.1" + resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" + integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== + dependencies: + bl "^4.1.0" + chalk "^4.1.0" + cli-cursor "^3.1.0" + cli-spinners "^2.5.0" + is-interactive "^1.0.0" + is-unicode-supported "^0.1.0" + log-symbols "^4.1.0" + strip-ansi "^6.0.0" + wcwidth "^1.0.1" + +os-tmpdir@~1.0.1, os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + +p-retry@^4.5.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.1.tgz#8fcddd5cdf7a67a0911a9cf2ef0e5df7f602316c" + integrity sha512-e2xXGNhZOZ0lfgR9kL34iGlU8N/KO0xZnQxVEwdeOvpqNDQfdnxIYizvWtK8RglUa3bGqI8g0R/BdfzLMxRkiA== + dependencies: + "@types/retry" "^0.12.0" + retry "^0.13.1" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +pacote@12.0.2: + version "12.0.2" + resolved "https://registry.yarnpkg.com/pacote/-/pacote-12.0.2.tgz#14ae30a81fe62ec4fc18c071150e6763e932527c" + integrity sha512-Ar3mhjcxhMzk+OVZ8pbnXdb0l8+pimvlsqBGRNkble2NVgyqOGE3yrCGi/lAYq7E7NRDMz89R1Wx5HIMCGgeYg== + dependencies: + "@npmcli/git" "^2.1.0" + "@npmcli/installed-package-contents" "^1.0.6" + "@npmcli/promise-spawn" "^1.2.0" + "@npmcli/run-script" "^2.0.0" + cacache "^15.0.5" + chownr "^2.0.0" + fs-minipass "^2.1.0" + infer-owner "^1.0.4" + minipass "^3.1.3" + mkdirp "^1.0.3" + npm-package-arg "^8.0.1" + npm-packlist "^3.0.0" + npm-pick-manifest "^6.0.0" + npm-registry-fetch "^11.0.0" + promise-retry "^2.0.1" + read-package-json-fast "^2.0.1" + rimraf "^3.0.2" + ssri "^8.0.1" + tar "^6.1.0" + +pako@^1.0.3, pako@~1.0.2: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-json@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +parse-node-version@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" + integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA== + +parse5-html-rewriting-stream@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-6.0.1.tgz#de1820559317ab4e451ea72dba05fddfd914480b" + integrity sha512-vwLQzynJVEfUlURxgnf51yAJDQTtVpNyGD8tKi2Za7m+akukNHxCcUQMAa/mUGLhCeicFdpy7Tlvj8ZNKadprg== + dependencies: + parse5 "^6.0.1" + parse5-sax-parser "^6.0.1" + +parse5-htmlparser2-tree-adapter@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6" + integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA== + dependencies: + parse5 "^6.0.1" + +parse5-sax-parser@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5-sax-parser/-/parse5-sax-parser-6.0.1.tgz#98b4d366b5b266a7cd90b4b58906667af882daba" + integrity sha512-kXX+5S81lgESA0LsDuGjAlBybImAChYRMT+/uKCEXFBFOeEhS52qUCydGhU3qLRD8D9DVjaUo821WK7DM4iCeg== + dependencies: + parse5 "^6.0.1" + +parse5@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" + integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== + +parse5@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== + +parseurl@~1.3.2, parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.6, path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +picocolors@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" + integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +piscina@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/piscina/-/piscina-3.2.0.tgz#f5a1dde0c05567775690cccefe59d9223924d154" + integrity sha512-yn/jMdHRw+q2ZJhFhyqsmANcbF6V2QwmD84c6xRau+QpQOmtrBCoRGdvTfeuFDYXB5W2m6MfLkjkvQa9lUSmIA== + dependencies: + eventemitter-asyncresource "^1.0.0" + hdr-histogram-js "^2.0.1" + hdr-histogram-percentiles-obj "^3.0.0" + optionalDependencies: + nice-napi "^1.0.2" + +pkg-dir@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +portfinder@^1.0.28: + version "1.0.28" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778" + integrity sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA== + dependencies: + async "^2.6.2" + debug "^3.1.1" + mkdirp "^0.5.5" + +postcss-attribute-case-insensitive@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.2.tgz#d93e46b504589e94ac7277b0463226c68041a880" + integrity sha512-clkFxk/9pcdb4Vkn0hAHq3YnxBQ2p0CGD1dy24jN+reBck+EWxMbxSUqN4Yj7t0w8csl87K6p0gxBe1utkJsYA== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^6.0.2" + +postcss-color-functional-notation@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-2.0.1.tgz#5efd37a88fbabeb00a2966d1e53d98ced93f74e0" + integrity sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-color-gray@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-color-gray/-/postcss-color-gray-5.0.0.tgz#532a31eb909f8da898ceffe296fdc1f864be8547" + integrity sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw== + dependencies: + "@csstools/convert-colors" "^1.4.0" + postcss "^7.0.5" + postcss-values-parser "^2.0.0" + +postcss-color-hex-alpha@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/postcss-color-hex-alpha/-/postcss-color-hex-alpha-5.0.3.tgz#a8d9ca4c39d497c9661e374b9c51899ef0f87388" + integrity sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw== + dependencies: + postcss "^7.0.14" + postcss-values-parser "^2.0.1" + +postcss-color-mod-function@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/postcss-color-mod-function/-/postcss-color-mod-function-3.0.3.tgz#816ba145ac11cc3cb6baa905a75a49f903e4d31d" + integrity sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ== + dependencies: + "@csstools/convert-colors" "^1.4.0" + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-color-rebeccapurple@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-4.0.1.tgz#c7a89be872bb74e45b1e3022bfe5748823e6de77" + integrity sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-custom-media@^7.0.8: + version "7.0.8" + resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-7.0.8.tgz#fffd13ffeffad73621be5f387076a28b00294e0c" + integrity sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg== + dependencies: + postcss "^7.0.14" + +postcss-custom-properties@^8.0.11: + version "8.0.11" + resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz#2d61772d6e92f22f5e0d52602df8fae46fa30d97" + integrity sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA== + dependencies: + postcss "^7.0.17" + postcss-values-parser "^2.0.1" + +postcss-custom-selectors@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-5.1.2.tgz#64858c6eb2ecff2fb41d0b28c9dd7b3db4de7fba" + integrity sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^5.0.0-rc.3" + +postcss-dir-pseudo-class@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-5.0.0.tgz#6e3a4177d0edb3abcc85fdb6fbb1c26dabaeaba2" + integrity sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^5.0.0-rc.3" + +postcss-double-position-gradients@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz#fc927d52fddc896cb3a2812ebc5df147e110522e" + integrity sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA== + dependencies: + postcss "^7.0.5" + postcss-values-parser "^2.0.0" + +postcss-env-function@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/postcss-env-function/-/postcss-env-function-2.0.2.tgz#0f3e3d3c57f094a92c2baf4b6241f0b0da5365d7" + integrity sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-focus-visible@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-focus-visible/-/postcss-focus-visible-4.0.0.tgz#477d107113ade6024b14128317ade2bd1e17046e" + integrity sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g== + dependencies: + postcss "^7.0.2" + +postcss-focus-within@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-focus-within/-/postcss-focus-within-3.0.0.tgz#763b8788596cee9b874c999201cdde80659ef680" + integrity sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w== + dependencies: + postcss "^7.0.2" + +postcss-font-variant@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-4.0.1.tgz#42d4c0ab30894f60f98b17561eb5c0321f502641" + integrity sha512-I3ADQSTNtLTTd8uxZhtSOrTCQ9G4qUVKPjHiDk0bV75QSxXjVWiJVJ2VLdspGUi9fbW9BcjKJoRvxAH1pckqmA== + dependencies: + postcss "^7.0.2" + +postcss-gap-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz#431c192ab3ed96a3c3d09f2ff615960f902c1715" + integrity sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg== + dependencies: + postcss "^7.0.2" + +postcss-image-set-function@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/postcss-image-set-function/-/postcss-image-set-function-3.0.1.tgz#28920a2f29945bed4c3198d7df6496d410d3f288" + integrity sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-import@14.0.2: + version "14.0.2" + resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-14.0.2.tgz#60eff77e6be92e7b67fe469ec797d9424cae1aa1" + integrity sha512-BJ2pVK4KhUyMcqjuKs9RijV5tatNzNa73e/32aBVE/ejYPe37iH+6vAu9WvqUkB5OAYgLHzbSvzHnorybJCm9g== + dependencies: + postcss-value-parser "^4.0.0" + read-cache "^1.0.0" + resolve "^1.1.7" + +postcss-initial@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-3.0.4.tgz#9d32069a10531fe2ecafa0b6ac750ee0bc7efc53" + integrity sha512-3RLn6DIpMsK1l5UUy9jxQvoDeUN4gP939tDcKUHD/kM8SGSKbFAnvkpFpj3Bhtz3HGk1jWY5ZNWX6mPta5M9fg== + dependencies: + postcss "^7.0.2" + +postcss-lab-function@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz#bb51a6856cd12289ab4ae20db1e3821ef13d7d2e" + integrity sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg== + dependencies: + "@csstools/convert-colors" "^1.4.0" + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-loader@6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-6.2.1.tgz#0895f7346b1702103d30fdc66e4d494a93c008ef" + integrity sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q== + dependencies: + cosmiconfig "^7.0.0" + klona "^2.0.5" + semver "^7.3.5" + +postcss-logical@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-logical/-/postcss-logical-3.0.0.tgz#2495d0f8b82e9f262725f75f9401b34e7b45d5b5" + integrity sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA== + dependencies: + postcss "^7.0.2" + +postcss-media-minmax@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-media-minmax/-/postcss-media-minmax-4.0.0.tgz#b75bb6cbc217c8ac49433e12f22048814a4f5ed5" + integrity sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw== + dependencies: + postcss "^7.0.2" + +postcss-modules-extract-imports@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" + integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== + +postcss-modules-local-by-default@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" + integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== + dependencies: + icss-utils "^5.0.0" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + +postcss-modules-scope@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" + integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== + dependencies: + postcss-selector-parser "^6.0.4" + +postcss-modules-values@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" + integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== + dependencies: + icss-utils "^5.0.0" + +postcss-nesting@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-7.0.1.tgz#b50ad7b7f0173e5b5e3880c3501344703e04c052" + integrity sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg== + dependencies: + postcss "^7.0.2" + +postcss-overflow-shorthand@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-overflow-shorthand/-/postcss-overflow-shorthand-2.0.0.tgz#31ecf350e9c6f6ddc250a78f0c3e111f32dd4c30" + integrity sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g== + dependencies: + postcss "^7.0.2" + +postcss-page-break@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-page-break/-/postcss-page-break-2.0.0.tgz#add52d0e0a528cabe6afee8b46e2abb277df46bf" + integrity sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ== + dependencies: + postcss "^7.0.2" + +postcss-place@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-place/-/postcss-place-4.0.1.tgz#e9f39d33d2dc584e46ee1db45adb77ca9d1dcc62" + integrity sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-preset-env@6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-6.7.0.tgz#c34ddacf8f902383b35ad1e030f178f4cdf118a5" + integrity sha512-eU4/K5xzSFwUFJ8hTdTQzo2RBLbDVt83QZrAvI07TULOkmyQlnYlpwep+2yIK+K+0KlZO4BvFcleOCCcUtwchg== + dependencies: + autoprefixer "^9.6.1" + browserslist "^4.6.4" + caniuse-lite "^1.0.30000981" + css-blank-pseudo "^0.1.4" + css-has-pseudo "^0.10.0" + css-prefers-color-scheme "^3.1.1" + cssdb "^4.4.0" + postcss "^7.0.17" + postcss-attribute-case-insensitive "^4.0.1" + postcss-color-functional-notation "^2.0.1" + postcss-color-gray "^5.0.0" + postcss-color-hex-alpha "^5.0.3" + postcss-color-mod-function "^3.0.3" + postcss-color-rebeccapurple "^4.0.1" + postcss-custom-media "^7.0.8" + postcss-custom-properties "^8.0.11" + postcss-custom-selectors "^5.1.2" + postcss-dir-pseudo-class "^5.0.0" + postcss-double-position-gradients "^1.0.0" + postcss-env-function "^2.0.2" + postcss-focus-visible "^4.0.0" + postcss-focus-within "^3.0.0" + postcss-font-variant "^4.0.0" + postcss-gap-properties "^2.0.0" + postcss-image-set-function "^3.0.1" + postcss-initial "^3.0.0" + postcss-lab-function "^2.0.1" + postcss-logical "^3.0.0" + postcss-media-minmax "^4.0.0" + postcss-nesting "^7.0.0" + postcss-overflow-shorthand "^2.0.0" + postcss-page-break "^2.0.0" + postcss-place "^4.0.1" + postcss-pseudo-class-any-link "^6.0.0" + postcss-replace-overflow-wrap "^3.0.0" + postcss-selector-matches "^4.0.0" + postcss-selector-not "^4.0.0" + +postcss-pseudo-class-any-link@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-6.0.0.tgz#2ed3eed393b3702879dec4a87032b210daeb04d1" + integrity sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^5.0.0-rc.3" + +postcss-replace-overflow-wrap@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-3.0.0.tgz#61b360ffdaedca84c7c918d2b0f0d0ea559ab01c" + integrity sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw== + dependencies: + postcss "^7.0.2" + +postcss-selector-matches@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-selector-matches/-/postcss-selector-matches-4.0.0.tgz#71c8248f917ba2cc93037c9637ee09c64436fcff" + integrity sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww== + dependencies: + balanced-match "^1.0.0" + postcss "^7.0.2" + +postcss-selector-not@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-4.0.1.tgz#263016eef1cf219e0ade9a913780fc1f48204cbf" + integrity sha512-YolvBgInEK5/79C+bdFMyzqTg6pkYqDbzZIST/PDMqa/o3qtXenD05apBG2jLgT0/BQ77d4U2UK12jWpilqMAQ== + dependencies: + balanced-match "^1.0.0" + postcss "^7.0.2" + +postcss-selector-parser@^5.0.0-rc.3, postcss-selector-parser@^5.0.0-rc.4: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz#249044356697b33b64f1a8f7c80922dddee7195c" + integrity sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ== + dependencies: + cssesc "^2.0.0" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: + version "6.0.9" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz#ee71c3b9ff63d9cd130838876c13a2ec1a992b2f" + integrity sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +postcss-values-parser@^2.0.0, postcss-values-parser@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz#da8b472d901da1e205b47bdc98637b9e9e550e5f" + integrity sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg== + dependencies: + flatten "^1.0.2" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss@8.4.5, postcss@^8.2.15, postcss@^8.3.7: + version "8.4.5" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.5.tgz#bae665764dfd4c6fcc24dc0fdf7e7aa00cc77f95" + integrity sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg== + dependencies: + nanoid "^3.1.30" + picocolors "^1.0.0" + source-map-js "^1.0.1" + +postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.32, postcss@^7.0.35, postcss@^7.0.5, postcss@^7.0.6: + version "7.0.39" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309" + integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA== + dependencies: + picocolors "^0.2.1" + source-map "^0.6.1" + +pretty-bytes@^5.3.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" + integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= + +promise-retry@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" + integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== + dependencies: + err-code "^2.0.2" + retry "^0.12.0" + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qjobs@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" + integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg== + +qs@6.9.6: + version "6.9.6" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.6.tgz#26ed3c8243a431b2924aca84cc90471f35d5a0ee" + integrity sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ== + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.2.tgz#baf3e9c21eebced59dd6533ac872b71f7b61cb32" + integrity sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ== + dependencies: + bytes "3.1.1" + http-errors "1.8.1" + iconv-lite "0.4.24" + unpipe "1.0.0" + +read-cache@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774" + integrity sha1-5mTvMRYRZsl1HNvo28+GtftY93Q= + dependencies: + pify "^2.3.0" + +read-package-json-fast@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/read-package-json-fast/-/read-package-json-fast-2.0.3.tgz#323ca529630da82cb34b36cc0b996693c98c2b83" + integrity sha512-W/BKtbL+dUjTuRL2vziuYhp76s5HZ9qQhd/dKfWIZveD0O40453QNyZhC0e63lqZrAQ4jiOapVoeJ7JrszenQQ== + dependencies: + json-parse-even-better-errors "^2.3.0" + npm-normalize-package-bin "^1.0.1" + +readable-stream@^2.0.1, readable-stream@~2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.0.6, readable-stream@^3.4.0, readable-stream@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +reflect-metadata@^0.1.2: + version "0.1.13" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" + integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== + +regenerate-unicode-properties@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz#54d09c7115e1f53dc2314a974b32c1c344efe326" + integrity sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA== + dependencies: + regenerate "^1.4.2" + +regenerate@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== + +regenerator-runtime@0.13.9, regenerator-runtime@^0.13.4: + version "0.13.9" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" + integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== + +regenerator-transform@^0.14.2: + version "0.14.5" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4" + integrity sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw== + dependencies: + "@babel/runtime" "^7.8.4" + +regex-parser@^2.2.11: + version "2.2.11" + resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.11.tgz#3b37ec9049e19479806e878cabe7c1ca83ccfe58" + integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q== + +regexp.prototype.flags@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz#b3f4c0059af9e47eca9f3f660e51d81307e72307" + integrity sha512-pMR7hBVUUGI7PMA37m2ofIdQCsomVnas+Jn5UPGAHQ+/LlwKm/aTLJHdasmHRzlfeZwHiAOaRSo2rbBDm3nNUQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +regexpu-core@^4.7.1: + version "4.8.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.8.0.tgz#e5605ba361b67b1718478501327502f4479a98f0" + integrity sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg== + dependencies: + regenerate "^1.4.2" + regenerate-unicode-properties "^9.0.0" + regjsgen "^0.5.2" + regjsparser "^0.7.0" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.0.0" + +regjsgen@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" + integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== + +regjsparser@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.7.0.tgz#a6b667b54c885e18b52554cb4960ef71187e9968" + integrity sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ== + dependencies: + jsesc "~0.5.0" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve-url-loader@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz#d50d4ddc746bb10468443167acf800dcd6c3ad57" + integrity sha512-05VEMczVREcbtT7Bz+C+96eUO5HDNvdthIiMB34t7FcF8ehcu4wC0sSgPUubs3XW2Q3CNLJk/BJrCU9wVRymiA== + dependencies: + adjust-sourcemap-loader "^4.0.0" + convert-source-map "^1.7.0" + loader-utils "^2.0.0" + postcss "^7.0.35" + source-map "0.6.1" + +resolve@1.20.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== + dependencies: + is-core-module "^2.2.0" + path-parse "^1.0.6" + +resolve@^1.1.7, resolve@^1.14.2: + version "1.22.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" + integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== + dependencies: + is-core-module "^2.8.1" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= + +retry@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rfdc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" + integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== + +rimraf@^2.5.4: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +rimraf@^3.0.0, rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +run-async@^2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" + integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +rxjs@6.6.7, rxjs@^6.6.3, "rxjs@file:../../node_modules/rxjs": + version "6.6.7" + dependencies: + tslib "^1.9.0" + +rxjs@^7.1.0, rxjs@^7.2.0: + version "7.5.2" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.2.tgz#11e4a3a1dfad85dbf7fb6e33cbba17668497490b" + integrity sha512-PwDt186XaL3QN5qXj/H9DGyHhP3/RYYgZZwqBv9Tv8rsAaiwFH1IsJJlcgD37J7UW5a6O67qX0KWKS3/pu0m4w== + dependencies: + tslib "^2.1.0" + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sass-loader@12.4.0: + version "12.4.0" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-12.4.0.tgz#260b0d51a8a373bb8e88efc11f6ba5583fea0bcf" + integrity sha512-7xN+8khDIzym1oL9XyS6zP6Ges+Bo2B2xbPrjdMHEYyV3AQYhd/wXeru++3ODHF0zMjYmVadblSKrPrjEkL8mg== + dependencies: + klona "^2.0.4" + neo-async "^2.6.2" + +sass@1.45.0: + version "1.45.0" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.45.0.tgz#192ede1908324bb293a3e403d1841dbcaafdd323" + integrity sha512-ONy5bjppoohtNkFJRqdz1gscXamMzN3wQy1YH9qO2FiNpgjLhpz/IPRGg0PpCjyz/pWfCOaNEaiEGCcjOFAjqw== + dependencies: + chokidar ">=3.0.0 <4.0.0" + immutable "^4.0.0" + source-map-js ">=0.6.2 <2.0.0" + +sax@>=0.6.0, sax@^1.2.4, sax@~1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +schema-utils@^2.6.5: + version "2.7.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" + integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== + dependencies: + "@types/json-schema" "^7.0.5" + ajv "^6.12.4" + ajv-keywords "^3.5.2" + +schema-utils@^3.1.0, schema-utils@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" + integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +schema-utils@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.0.0.tgz#60331e9e3ae78ec5d16353c467c34b3a0a1d3df7" + integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg== + dependencies: + "@types/json-schema" "^7.0.9" + ajv "^8.8.0" + ajv-formats "^2.1.1" + ajv-keywords "^5.0.0" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= + +selenium-webdriver@3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz#2ba87a1662c020b8988c981ae62cb2a01298eafc" + integrity sha512-WH7Aldse+2P5bbFBO4Gle/nuQOdVwpHMTL6raL3uuBj/vPG07k6uzt3aiahu352ONBr5xXh0hDlM3LhtXPOC4Q== + dependencies: + jszip "^3.1.3" + rimraf "^2.5.4" + tmp "0.0.30" + xml2js "^0.4.17" + +selfsigned@^1.10.11: + version "1.10.14" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.14.tgz#ee51d84d9dcecc61e07e4aba34f229ab525c1574" + integrity sha512-lkjaiAye+wBZDCBsu5BGi0XiLRxeUlsGod5ZP924CRSEoGuZAw/f7y9RKu28rwTfiHVhdavhB0qH0INV6P1lEA== + dependencies: + node-forge "^0.10.0" + +semver@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== + +semver@7.3.5, semver@^7.0.0, semver@^7.1.1, semver@^7.3.4, semver@^7.3.5: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + +semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +send@0.17.2: + version "0.17.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.2.tgz#926622f76601c41808012c8bf1688fe3906f7820" + integrity sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "1.8.1" + mime "1.6.0" + ms "2.1.3" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +serialize-javascript@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +serve-index@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.14.2: + version "1.14.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.2.tgz#722d6294b1d62626d41b43a013ece4598d292bfa" + integrity sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.2" + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +set-immediate-shim@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" + integrity sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E= + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: + version "3.0.6" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" + integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slash@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" + integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== + +smart-buffer@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" + integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== + +socket.io-adapter@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.3.3.tgz#4d6111e4d42e9f7646e365b4f578269821f13486" + integrity sha512-Qd/iwn3VskrpNO60BeRyCyr8ZWw9CPZyitW4AQwmRZ8zCiyDiL+znRnWX6tDHXnWn1sJrM1+b6Mn6wEDJJ4aYQ== + +socket.io-parser@~4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.0.4.tgz#9ea21b0d61508d18196ef04a2c6b9ab630f4c2b0" + integrity sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g== + dependencies: + "@types/component-emitter" "^1.2.10" + component-emitter "~1.3.0" + debug "~4.3.1" + +socket.io@^4.2.0: + version "4.4.1" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.4.1.tgz#cd6de29e277a161d176832bb24f64ee045c56ab8" + integrity sha512-s04vrBswdQBUmuWJuuNTmXUVJhP0cVky8bBDhdkf8y0Ptsu7fKU2LuLbts9g+pdmAdyMMn8F/9Mf1/wbtUN0fg== + dependencies: + accepts "~1.3.4" + base64id "~2.0.0" + debug "~4.3.2" + engine.io "~6.1.0" + socket.io-adapter "~2.3.3" + socket.io-parser "~4.0.4" + +sockjs@^0.3.21: + version "0.3.24" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" + integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== + dependencies: + faye-websocket "^0.11.3" + uuid "^8.3.2" + websocket-driver "^0.7.4" + +socks-proxy-agent@^6.0.0: + version "6.1.1" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-6.1.1.tgz#e664e8f1aaf4e1fb3df945f09e3d94f911137f87" + integrity sha512-t8J0kG3csjA4g6FTbsMOWws+7R7vuRC8aQ/wy3/1OWmsgwA68zs/+cExQ0koSitUDXqhufF/YJr9wtNMZHw5Ew== + dependencies: + agent-base "^6.0.2" + debug "^4.3.1" + socks "^2.6.1" + +socks@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.1.tgz#989e6534a07cf337deb1b1c94aaa44296520d30e" + integrity sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA== + dependencies: + ip "^1.1.5" + smart-buffer "^4.1.0" + +"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + +source-map-js@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" + integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== + +source-map-loader@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-3.0.0.tgz#f2a04ee2808ad01c774dea6b7d2639839f3b3049" + integrity sha512-GKGWqWvYr04M7tn8dryIWvb0s8YM41z82iQv01yBtIylgxax0CwvSy6gc2Y02iuXwEfGWRlMicH0nvms9UZphw== + dependencies: + abab "^2.0.5" + iconv-lite "^0.6.2" + source-map-js "^0.6.2" + +source-map-resolve@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.6.0.tgz#3d9df87e236b53f16d01e58150fc7711138e5ed2" + integrity sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + +source-map-support@0.5.21, source-map-support@^0.5.17, source-map-support@^0.5.5, source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@0.7.3, source-map@^0.7.3, source-map@~0.7.2: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +source-map@^0.5.0: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +sourcemap-codec@1.4.8, sourcemap-codec@^1.4.4, sourcemap-codec@^1.4.8: + version "1.4.8" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" + integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== + +spawn-command@^0.0.2-1: + version "0.0.2-1" + resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0" + integrity sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A= + +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + +spdy@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" + integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +ssri@^8.0.0, ssri@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" + integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== + dependencies: + minipass "^3.1.1" + +"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +streamroller@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-3.0.2.tgz#30418d0eee3d6c93ec897f892ed098e3a81e68b7" + integrity sha512-ur6y5S5dopOaRXBuRIZ1u6GC5bcEXHRZKgfBjfCglMhmIf+roVCECjvkEYzNQOXIN2/JPnkMPW/8B3CZoKaEPA== + dependencies: + date-format "^4.0.3" + debug "^4.1.1" + fs-extra "^10.0.0" + +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" + integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== + dependencies: + ansi-regex "^6.0.1" + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +stylus-loader@6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/stylus-loader/-/stylus-loader-6.2.0.tgz#0ba499e744e7fb9d9b3977784c8639728a7ced8c" + integrity sha512-5dsDc7qVQGRoc6pvCL20eYgRUxepZ9FpeK28XhdXaIPP6kXr6nI1zAAKFQgP5OBkOfKaURp4WUpJzspg1f01Gg== + dependencies: + fast-glob "^3.2.7" + klona "^2.0.4" + normalize-path "^3.0.0" + +stylus@0.55.0: + version "0.55.0" + resolved "https://registry.yarnpkg.com/stylus/-/stylus-0.55.0.tgz#bd404a36dd93fa87744a9dd2d2b1b8450345e5fc" + integrity sha512-MuzIIVRSbc8XxHH7FjkvWqkIcr1BvoMZoR/oFuAJDlh7VSaNJzrB4uJ38GRQa+mWjLXODAMzeDe0xi9GYbGwnw== + dependencies: + css "^3.0.0" + debug "~3.1.0" + glob "^7.1.6" + mkdirp "~1.0.4" + safer-buffer "^2.1.2" + sax "~1.2.4" + semver "^6.3.0" + source-map "^0.7.3" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.0.0, supports-color@^8.1.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +symbol-observable@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-4.0.0.tgz#5b425f192279e87f2f9b937ac8540d1984b39205" + integrity sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ== + +tapable@^2.1.1, tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + +tar@^6.0.2, tar@^6.1.0, tar@^6.1.2: + version "6.1.11" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" + integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^3.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + +terser-webpack-plugin@^5.1.3: + version "5.3.0" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.0.tgz#21641326486ecf91d8054161c816e464435bae9f" + integrity sha512-LPIisi3Ol4chwAaPP8toUJ3L4qCM1G0wao7L3qNv57Drezxj6+VEyySpPw4B1HSO2Eg/hDY/MNF5XihCAoqnsQ== + dependencies: + jest-worker "^27.4.1" + schema-utils "^3.1.1" + serialize-javascript "^6.0.0" + source-map "^0.6.1" + terser "^5.7.2" + +terser@5.10.0, terser@^5.7.2: + version "5.10.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.10.0.tgz#b86390809c0389105eb0a0b62397563096ddafcc" + integrity sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA== + dependencies: + commander "^2.20.0" + source-map "~0.7.2" + source-map-support "~0.5.20" + +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + +text-table@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +thunky@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" + integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== + +tmp@0.0.30: + version "0.0.30" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.30.tgz#72419d4a8be7d6ce75148fd8b324e593a711c2ed" + integrity sha1-ckGdSovn1s51FI/YsyTlk6cRwu0= + dependencies: + os-tmpdir "~1.0.1" + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +tmp@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +tree-kill@1.2.2, tree-kill@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" + integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== + +ts-node@~9.1.1: + version "9.1.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-9.1.1.tgz#51a9a450a3e959401bda5f004a72d54b936d376d" + integrity sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg== + dependencies: + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + source-map-support "^0.5.17" + yn "3.1.1" + +tslib@2.3.1, tslib@^2.0.0, tslib@^2.1.0, tslib@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" + integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== + +tslib@^1.9.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +typed-assert@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/typed-assert/-/typed-assert-1.0.8.tgz#4bf9f1ce7f3f974d09c3afd7c68d12e1391a233c" + integrity sha512-5NkbXZUlmCE73Fs7gvkp1XXJWHYetPkg60QnQ2NXQmBYNFxbBr2zA8GCtaH4K2s2WhOmSlgiSTmrjrcm5tnM5g== + +"typescript@file:../../node_modules/typescript": + version "4.5.2" + +ua-parser-js@^0.7.30: + version "0.7.31" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6" + integrity sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ== + +unicode-canonical-property-names-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" + integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== + +unicode-match-property-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" + integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== + dependencies: + unicode-canonical-property-names-ecmascript "^2.0.0" + unicode-property-aliases-ecmascript "^2.0.0" + +unicode-match-property-value-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz#1a01aa57247c14c568b89775a54938788189a714" + integrity sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw== + +unicode-property-aliases-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8" + integrity sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ== + +uniq@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" + integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= + +unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" + integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== + dependencies: + imurmurhash "^0.1.4" + +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@8.3.2, uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +validate-npm-package-name@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" + integrity sha1-X6kS2B630MdK/BQN5zF/DKffQ34= + dependencies: + builtins "^1.0.3" + +vary@^1, vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +void-elements@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" + integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w= + +wait-on@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-6.0.0.tgz#7e9bf8e3d7fe2daecbb7a570ac8ca41e9311c7e7" + integrity sha512-tnUJr9p5r+bEYXPUdRseolmz5XqJTTj98JgOsfBn7Oz2dxfE2g3zw1jE+Mo8lopM3j3et/Mq1yW7kKX6qw7RVw== + dependencies: + axios "^0.21.1" + joi "^17.4.0" + lodash "^4.17.21" + minimist "^1.2.5" + rxjs "^7.1.0" + +watchpack@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.3.1.tgz#4200d9447b401156eeca7767ee610f8809bc9d25" + integrity sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + +wcwidth@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" + integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= + dependencies: + defaults "^1.0.3" + +webpack-dev-middleware@5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.2.2.tgz#eb5193faa5479ca1086b9f7bed68b89c731bff62" + integrity sha512-DjZyYrsHhkikAFNvSNKrpnziXukU1EChFAh9j4LAm6ndPLPW8cN0KhM7T+RAiOqsQ6ABfQ8hoKIs9IWMTjov+w== + dependencies: + colorette "^2.0.10" + memfs "^3.2.2" + mime-types "^2.1.31" + range-parser "^1.2.1" + schema-utils "^4.0.0" + +webpack-dev-middleware@^5.2.1: + version "5.3.0" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.0.tgz#8fc02dba6e72e1d373eca361623d84610f27be7c" + integrity sha512-MouJz+rXAm9B1OTOYaJnn6rtD/lWZPy2ufQCH3BPs8Rloh/Du6Jze4p7AeLYHkVi0giJnYLaSGDC7S+GM9arhg== + dependencies: + colorette "^2.0.10" + memfs "^3.2.2" + mime-types "^2.1.31" + range-parser "^1.2.1" + schema-utils "^4.0.0" + +webpack-dev-server@4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.6.0.tgz#e8648601c440172d9b6f248d28db98bed335315a" + integrity sha512-oojcBIKvx3Ya7qs1/AVWHDgmP1Xml8rGsEBnSobxU/UJSX1xP1GPM3MwsAnDzvqcVmVki8tV7lbcsjEjk0PtYg== + dependencies: + ansi-html-community "^0.0.8" + bonjour "^3.5.0" + chokidar "^3.5.2" + colorette "^2.0.10" + compression "^1.7.4" + connect-history-api-fallback "^1.6.0" + default-gateway "^6.0.3" + del "^6.0.0" + express "^4.17.1" + graceful-fs "^4.2.6" + html-entities "^2.3.2" + http-proxy-middleware "^2.0.0" + ipaddr.js "^2.0.1" + open "^8.0.9" + p-retry "^4.5.0" + portfinder "^1.0.28" + schema-utils "^4.0.0" + selfsigned "^1.10.11" + serve-index "^1.9.1" + sockjs "^0.3.21" + spdy "^4.0.2" + strip-ansi "^7.0.0" + url "^0.11.0" + webpack-dev-middleware "^5.2.1" + ws "^8.1.0" + +webpack-merge@5.8.0: + version "5.8.0" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61" + integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q== + dependencies: + clone-deep "^4.0.1" + wildcard "^2.0.0" + +webpack-sources@^3.0.0, webpack-sources@^3.2.2: + version "3.2.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" + integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== + +webpack-subresource-integrity@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/webpack-subresource-integrity/-/webpack-subresource-integrity-5.0.0.tgz#8268b9cc1a229a8f8129ca9eeb59cde52185b6b1" + integrity sha512-x9514FpLRydO+UAQ8DY4aLtCjxmdLkuQVcDFN1kGzuusREYJ1B0rzk/iIlWiL6dnvrhEGFj2+UsdxDkP8Z4UKg== + dependencies: + typed-assert "^1.0.8" + +webpack@5.65.0: + version "5.65.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.65.0.tgz#ed2891d9145ba1f0d318e4ea4f89c3fa18e6f9be" + integrity sha512-Q5or2o6EKs7+oKmJo7LaqZaMOlDWQse9Tm5l1WAfU/ujLGN5Pb0SqGeVkN/4bpPmEqEP5RnVhiqsOtWtUVwGRw== + dependencies: + "@types/eslint-scope" "^3.7.0" + "@types/estree" "^0.0.50" + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/wasm-edit" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + acorn "^8.4.1" + acorn-import-assertions "^1.7.6" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.8.3" + es-module-lexer "^0.9.0" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.4" + json-parse-better-errors "^1.0.2" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.1.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.1.3" + watchpack "^2.3.1" + webpack-sources "^3.2.2" + +websocket-driver@>=0.5.1, websocket-driver@^0.7.4: + version "0.7.4" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" + integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== + dependencies: + http-parser-js ">=0.5.1" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.4" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== + +which@^1.2.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^2.0.1, which@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" + integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== + dependencies: + string-width "^1.0.2 || 2 || 3 || 4" + +wildcard@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" + integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +ws@^8.1.0: + version "8.4.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.4.2.tgz#18e749868d8439f2268368829042894b6907aa0b" + integrity sha512-Kbk4Nxyq7/ZWqr/tarI9yIt/+iNNFOjBXEWgTb4ydaNHBNGgvf2QHbS9fdfsndfjFlFwEd4Al+mw83YkaD10ZA== + +ws@~8.2.3: + version "8.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" + integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA== + +xml2js@^0.4.17: + version "0.4.23" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" + integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== + dependencies: + sax ">=0.6.0" + xmlbuilder "~11.0.0" + +xmlbuilder@~11.0.0: + version "11.0.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" + integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml@^1.10.0: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs-parser@^21.0.0: + version "21.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.0.0.tgz#a485d3966be4317426dd56bdb6a30131b281dc55" + integrity sha512-z9kApYUOCwoeZ78rfRYYWdiU/iNL6mwwYlkkZfJoyMR1xps+NEBX5X7XmRpxkZHhXJ6+Ey00IwKxBBSW9FIjyA== + +yargs@^16.1.1, yargs@^16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yargs@^17.2.1: + version "17.3.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.3.1.tgz#da56b28f32e2fd45aefb402ed9c26f42be4c07b9" + integrity sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.0.0" + +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + +zone.js@~0.11.4: + version "0.11.4" + resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.11.4.tgz#0f70dcf6aba80f698af5735cbb257969396e8025" + integrity sha512-DDh2Ab+A/B+9mJyajPjHFPWfYU1H+pdun4wnnk0OcQTNjem1XQSZ2CDW+rfZEUDjv5M19SBqAkjZi0x5wuB5Qw== + dependencies: + tslib "^2.0.0" diff --git a/package.json b/package.json index cb0d40011277..677687fd463a 100644 --- a/package.json +++ b/package.json @@ -50,39 +50,38 @@ "tsc": "node ./node_modules/typescript/bin/tsc", "prepare": "husky install" }, - "version": "13.2.0-next.0", + "version": "14.0.0-next.0", "dependencies": { - "@angular/animations": "^13.1.0", - "@angular/common": "^13.1.0", - "@angular/compiler": "^13.1.0", - "@angular/core": "^13.1.0", - "@angular/forms": "^13.1.0", - "@angular/platform-browser": "^13.1.0", - "@types/google.maps": "^3.45.6", - "@types/youtube": "^0.0.42", - "core-js-bundle": "^3.8.2", + "@angular/animations": "13.2.0", + "@angular/common": "13.2.0", + "@angular/compiler": "13.2.0", + "@angular/core": "13.2.0", + "@angular/forms": "13.2.0", + "@angular/platform-browser": "13.2.0", + "@types/google.maps": "^3.47.3", + "@types/youtube": "^0.0.46", "material-components-web": "14.0.0-canary.c047f7c19.0", "rxjs": "^6.6.7", - "rxjs-tslint-rules": "^4.33.1", - "tslib": "^2.3.0", - "zone.js": "~0.11.3" + "rxjs-tslint-rules": "^4.34.8", + "tslib": "^2.3.1", + "zone.js": "~0.11.4" }, "devDependencies": { - "@angular-devkit/build-angular": "^13.1.0", - "@angular-devkit/core": "^13.1.0", - "@angular-devkit/schematics": "^13.1.0", - "@angular/bazel": "^13.1.0", - "@angular/cli": "^13.1.0", - "@angular/compiler-cli": "^13.1.0", - "@angular/dev-infra-private": "https://github.com/angular/dev-infra-private-builds.git#c55a3937d45945489714273bfbbe9b803ceff89e", - "@angular/localize": "^13.1.0", - "@angular/platform-browser-dynamic": "^13.1.0", - "@angular/platform-server": "^13.1.0", - "@angular/router": "^13.1.0", - "@axe-core/webdriverjs": "^4.1.0", - "@babel/core": "^7.16.0", - "@bazel/bazelisk": "1.10.1", - "@bazel/buildifier": "4.2.3", + "@angular-devkit/build-angular": "13.2.0", + "@angular-devkit/core": "13.2.0", + "@angular-devkit/schematics": "13.2.0", + "@angular/bazel": "13.2.0", + "@angular/cli": "13.2.0", + "@angular/compiler-cli": "13.2.0", + "@angular/dev-infra-private": "https://github.com/angular/dev-infra-private-builds.git#2b0196f6ebf6de2e62836e962b9f42007e6cf5d6", + "@angular/localize": "13.2.0", + "@angular/platform-browser-dynamic": "13.2.0", + "@angular/platform-server": "13.2.0", + "@angular/router": "13.2.0", + "@axe-core/webdriverjs": "^4.3.2", + "@babel/core": "^7.16.12", + "@bazel/bazelisk": "1.11.0", + "@bazel/buildifier": "4.2.5", "@bazel/concatjs": "4.4.5", "@bazel/esbuild": "4.4.5", "@bazel/ibazel": "0.15.10", @@ -92,7 +91,7 @@ "@bazel/runfiles": "4.4.5", "@bazel/terser": "4.4.5", "@bazel/typescript": "4.4.5", - "@firebase/app-types": "^0.6.1", + "@firebase/app-types": "^0.7.0", "@material/animation": "14.0.0-canary.c047f7c19.0", "@material/auto-init": "14.0.0-canary.c047f7c19.0", "@material/banner": "14.0.0-canary.c047f7c19.0", @@ -142,45 +141,44 @@ "@material/typography": "14.0.0-canary.c047f7c19.0", "@octokit/rest": "18.3.5", "@rollup/plugin-commonjs": "^21.0.0", - "@rollup/plugin-node-resolve": "^13.0.5", - "@schematics/angular": "^13.1.0", - "@types/babel__core": "^7.1.16", - "@types/browser-sync": "^2.26.1", - "@types/fs-extra": "^9.0.5", - "@types/glob": "^7.1.3", - "@types/inquirer": "^7.3.1", - "@types/jasmine": "^3.6.0", + "@rollup/plugin-node-resolve": "^13.1.3", + "@schematics/angular": "13.2.0", + "@types/babel__core": "^7.1.18", + "@types/browser-sync": "^2.26.3", + "@types/fs-extra": "^9.0.13", + "@types/glob": "^7.2.0", + "@types/jasmine": "^3.10.3", "@types/luxon": "^1.27.0", "@types/marked": "^2.0.0", - "@types/minimist": "^1.2.0", - "@types/node": "^14.14.22", + "@types/node": "^16.10.9", "@types/node-fetch": "^2.5.5", - "@types/parse5": "^6.0.0", - "@types/sass": "^1.16.0", + "@types/parse5": "^6.0.3", + "@types/sass": "^1.43.1", "@types/selenium-webdriver": "^3.0.17", - "@types/semver": "^7.3.4", - "@types/send": "^0.14.5", - "@types/shelljs": "^0.8.9", + "@types/semver": "^7.3.9", + "@types/send": "^0.17.1", + "@types/shelljs": "^0.8.11", "@types/yaml": "^1.9.7", - "autoprefixer": "^10.2.5", + "@types/yargs": "^17.0.8", + "autoprefixer": "^10.4.2", "browser-sync": "2.26.13", "chalk": "^4.1.0", "codelyzer": "^6.0.2", - "date-fns": "^2.23.0", - "dgeni": "^0.4.11", - "dgeni-packages": "^0.28.4", - "esbuild": "^0.13.3", + "date-fns": "^2.28.0", + "dgeni": "^0.4.14", + "dgeni-packages": "^0.29.3", + "esbuild": "^0.14.14", "firebase-tools": "^9.2.1", "fs-extra": "^9.0.1", - "glob": "^7.1.2", + "glob": "^7.2.0", "highlight.js": "^10.7.0", - "husky": "^7.0.1", - "inquirer": "^8.0.0", + "husky": "^7.0.4", + "inquirer": "^8.2.0", "jasmine": "^3.6.0", "jasmine-core": "^3.6.0", "jsonc-parser": "^3.0.0", "kagekiri": "^1.4.1", - "karma": "^6.3.8", + "karma": "^6.3.12", "karma-browserstack-launcher": "^1.6.0", "karma-chrome-launcher": "^3.1.0", "karma-firefox-launcher": "^2.1.2", @@ -189,37 +187,37 @@ "karma-requirejs": "^1.1.0", "karma-sauce-launcher": "^4.3.6", "karma-sourcemap-loader": "^0.3.8", - "luxon": "^2.0.0", + "luxon": "^2.3.0", "madge": "^4.0.0", "marked": "^2.0.0", "minimatch": "^3.0.4", - "minimist": "^1.2.0", - "moment": "^2.18.1", + "moment": "^2.29.1", "node-fetch": "^2.6.0", "parse5": "^6.0.1", - "postcss": "^8.2.1", - "postcss-scss": "^4.0.2", + "postcss": "^8.4.5", + "postcss-scss": "^4.0.3", "protractor": "^7.0.0", - "reflect-metadata": "^0.1.3", + "reflect-metadata": "^0.1.13", "requirejs": "^2.3.6", - "rollup": "^2.58.0", + "rollup": "^2.66.1", "rollup-plugin-sourcemaps": "^0.6.3", - "sass": "^1.41.0", + "sass": "^1.49.0", "selenium-webdriver": "^3.6.0", - "semver": "^7.3.4", - "send": "^0.17.1", - "shelljs": "^0.8.3", - "stylelint": "^14.0.1", - "terser": "^5.9.0", - "ts-node": "^10.2.1", + "semver": "^7.3.5", + "send": "^0.17.2", + "shelljs": "^0.8.5", + "stylelint": "^14.3.0", + "terser": "^5.10.0", + "ts-node": "^10.4.0", "tsec": "0.2.1", "tsickle": "0.39.1", "tslint": "^6.1.3", "tsutils": "^3.21.0", + "typescript": "~4.5.5", "typescript-4.4": "npm:typescript@4.4.2", - "typescript": "~4.5.2", "vrsource-tslint-rules": "6.0.0", - "yaml": "^1.10.0" + "yaml": "^1.10.2", + "yargs": "^17.3.1" }, "resolutions": { "@angular/dev-infra-private/typescript": "~4.5.2", diff --git a/renovate.json b/renovate.json new file mode 100644 index 000000000000..9047f0d112ac --- /dev/null +++ b/renovate.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "automerge": false, + "baseBranches": ["master"], + "enabledManagers": ["npm", "bazel", "github-actions"], + "labels": ["target: patch", "merge safe"], + "lockFileMaintenance": { + "enabled": true + }, + "pinDigests": true, + "prHourlyLimit": 2, + "rebaseWhen": "behind-base-branch", + "semanticCommits": "enabled", + "semanticCommitScope": "", + "semanticCommitType": "build", + "separateMajorMinor": false, + "ignorePaths": [ + "integration/**" + ], + "packageRules": [ + { + "matchPackagePatterns": ["*"], + "enabled": false + }, + { + "matchPackageNames": ["@angular/dev-infra-private", "angular/dev-infra"], + "groupName": "angular shared dev-infra code", + "enabled": true + } + ] +} diff --git a/scripts/check-entry-point-setup.js b/scripts/check-entry-point-setup.js index 15c5c7f1e327..96782f9081be 100644 --- a/scripts/check-entry-point-setup.js +++ b/scripts/check-entry-point-setup.js @@ -21,7 +21,13 @@ const packagesDir = join(__dirname, '../src'); * Globs that matches directories which should never be considered * as entry-points. */ -const excludeGlobs = ['cdk/testing/private', '*/schematics/**']; +const excludeGlobs = [ + 'cdk/testing/private', + '*/schematics/**', + // The protractor testing entry-point is no longer publicly available, + // but exists in the repository until it can be removed in g3. + 'cdk/testing/protractor', +]; /** List of detected entry-points which are not properly configured. */ const nonConfigured = []; diff --git a/scripts/check-mdc-tests-config.ts b/scripts/check-mdc-tests-config.ts index 40c3a43d9599..04592566f8a5 100644 --- a/scripts/check-mdc-tests-config.ts +++ b/scripts/check-mdc-tests-config.ts @@ -36,6 +36,12 @@ export const config = { // This test checks something that isn't supported in the MDC form field. 'should propagate the dynamic `placeholder` value to the form field', + + // Disabled, because the MDC-based chip input doesn't deal with focus escaping anymore. + 'should not allow focus to escape when tabbing backwards', + + // Disabled, because preventing the default action isn't required. + 'should prevent the default click action when the chip is disabled', ], 'mdc-dialog': [ // These tests are verifying implementation details that are not relevant for MDC. @@ -75,6 +81,7 @@ export const config = { 'should update the outline gap if the direction changes', 'should update the outline gap correctly if the direction changes multiple times', 'should calculate the outline gaps inside the shadow DOM', + 'should recalculate the outline gap when the label changes to empty after init', 'should be legacy appearance if no default options provided', 'should be legacy appearance if empty default options provided', ], diff --git a/scripts/create-package-archives.js b/scripts/create-package-archives.js index 4373f7667409..b22904d75d4e 100755 --- a/scripts/create-package-archives.js +++ b/scripts/create-package-archives.js @@ -12,17 +12,15 @@ const {join} = require('path'); const {rm, mkdir, test, ls, set, exec, cd} = require('shelljs'); const {red, green} = require('chalk'); -const minimist = require('minimist'); +const yargs = require('yargs'); const projectDir = join(__dirname, '../'); const archivesDir = 'dist/release-archives'; const releasesDir = 'dist/releases'; -let {suffix} = minimist(process.argv.slice(2), {string: ['suffix']}); - -if (!suffix) { - console.error(red('No suffix specified. Pass one with --suffix ')); - process.exit(1); -} +const {suffix} = yargs(process.argv.slice(2)) + .option('suffix', {type: 'string', demandOption: true}) + .strict() + .parseSync(); // Fail if any ShellJS command fails. set('-e'); diff --git a/scripts/run-component-tests.js b/scripts/run-component-tests.js index f1a98c57e85d..6103428d25ea 100644 --- a/scripts/run-component-tests.js +++ b/scripts/run-component-tests.js @@ -17,7 +17,7 @@ * --no-watch | Watch mode is enabled by default. This flag opts-out to standard Bazel. */ -const minimist = require('minimist'); +const yargs = require('yargs'); const shelljs = require('shelljs'); const chalk = require('chalk'); const path = require('path'); @@ -35,15 +35,25 @@ shelljs.set('-e'); shelljs.cd(projectDir); // Extracts the supported command line options. -const { - _: components, - local, - firefox, - watch, -} = minimist(args, { - boolean: ['local', 'firefox', 'watch'], - default: {watch: true}, -}); +const {components, local, firefox, watch} = yargs(args) + .command('* ', 'Run tests for specified components', args => + args.positional('components', {type: 'array'}), + ) + .option('local', { + type: 'boolean', + description: 'Whether test should run in local mode. You can manually connect a browser then.', + }) + .option('firefox', { + type: 'boolean', + description: 'Whether browser tests should run within Firefox.', + }) + .option('watch', { + type: 'boolean', + default: true, + description: 'Whether tests should be re-run automatically upon changes.', + }) + .strict() + .parseSync(); // Whether tests for all components should be run. const all = components.length === 1 && components[0] === 'all'; diff --git a/src/bazel-tsconfig-build.json b/src/bazel-tsconfig-build.json index d67e14706e12..1a0c7ecbc4b3 100644 --- a/src/bazel-tsconfig-build.json +++ b/src/bazel-tsconfig-build.json @@ -15,6 +15,7 @@ "noImplicitReturns": true, "strictFunctionTypes": true, "noImplicitOverride": true, + "useUnknownInCatchVariables": true, "noFallthroughCasesInSwitch": true, "noImplicitAny": true, "noImplicitThis": true, diff --git a/src/cdk/a11y/fake-event-detection.ts b/src/cdk/a11y/fake-event-detection.ts index 2f7750a83a16..d4d6e80ae2af 100644 --- a/src/cdk/a11y/fake-event-detection.ts +++ b/src/cdk/a11y/fake-event-detection.ts @@ -10,10 +10,12 @@ export function isFakeMousedownFromScreenReader(event: MouseEvent): boolean { // Some screen readers will dispatch a fake `mousedown` event when pressing enter or space on // a clickable element. We can distinguish these events when both `offsetX` and `offsetY` are - // zero. Note that there's an edge case where the user could click the 0x0 spot of the screen - // themselves, but that is unlikely to contain interaction elements. Historically we used to - // check `event.buttons === 0`, however that no longer works on recent versions of NVDA. - return event.offsetX === 0 && event.offsetY === 0; + // zero or `event.buttons` is zero, depending on the browser: + // - `event.buttons` works on Firefox, but fails on Chrome. + // - `offsetX` and `offsetY` work on Chrome, but fail on Firefox. + // Note that there's an edge case where the user could click the 0x0 spot of the + // screen themselves, but that is unlikely to contain interactive elements. + return event.buttons === 0 || (event.offsetX === 0 && event.offsetY === 0); } /** Gets whether an event could be a faked `touchstart` event dispatched by a screen reader. */ diff --git a/src/cdk/a11y/focus-monitor/focus-monitor.spec.ts b/src/cdk/a11y/focus-monitor/focus-monitor.spec.ts index e26a03e1dd05..73e9ed4150f5 100644 --- a/src/cdk/a11y/focus-monitor/focus-monitor.spec.ts +++ b/src/cdk/a11y/focus-monitor/focus-monitor.spec.ts @@ -161,7 +161,7 @@ describe('FocusMonitor', () => { expect(changeHandler).toHaveBeenCalledWith('program'); })); - it('should detect fake mousedown from a screen reader', fakeAsync(() => { + it('should detect fake mousedown from a screen reader on Chrome', fakeAsync(() => { // Simulate focus via a fake mousedown from a screen reader. dispatchMouseEvent(buttonElement, 'mousedown'); const event = createMouseEvent('mousedown'); @@ -184,6 +184,29 @@ describe('FocusMonitor', () => { expect(changeHandler).toHaveBeenCalledWith('keyboard'); })); + it('should detect fake mousedown from a screen reader on Firefox', fakeAsync(() => { + // Simulate focus via a fake mousedown from a screen reader. + dispatchMouseEvent(buttonElement, 'mousedown'); + const event = createMouseEvent('mousedown'); + Object.defineProperties(event, {buttons: {get: () => 0}}); + dispatchEvent(buttonElement, event); + + buttonElement.focus(); + fixture.detectChanges(); + flush(); + + expect(buttonElement.classList.length) + .withContext('button should have exactly 2 focus classes') + .toBe(2); + expect(buttonElement.classList.contains('cdk-focused')) + .withContext('button should have cdk-focused class') + .toBe(true); + expect(buttonElement.classList.contains('cdk-keyboard-focused')) + .withContext('button should have cdk-keyboard-focused class') + .toBe(true); + expect(changeHandler).toHaveBeenCalledWith('keyboard'); + })); + it('focusVia keyboard should simulate keyboard focus', fakeAsync(() => { focusMonitor.focusVia(buttonElement, 'keyboard'); flush(); diff --git a/src/cdk/a11y/input-modality/input-modality-detector.spec.ts b/src/cdk/a11y/input-modality/input-modality-detector.spec.ts index b36ac402719b..b403c0d48937 100644 --- a/src/cdk/a11y/input-modality/input-modality-detector.spec.ts +++ b/src/cdk/a11y/input-modality/input-modality-detector.spec.ts @@ -133,7 +133,7 @@ describe('InputModalityDetector', () => { expect(emitted).toEqual(['keyboard', 'mouse', 'touch', 'keyboard']); }); - it('should detect fake screen reader mouse events as keyboard input modality', () => { + it('should detect fake screen reader mouse events as keyboard input modality on Chrome', () => { setupTest(); // Create a fake screen-reader mouse event. @@ -144,6 +144,17 @@ describe('InputModalityDetector', () => { expect(detector.mostRecentModality).toBe('keyboard'); }); + it('should detect fake screen reader mouse events as keyboard input modality on Firefox', () => { + setupTest(); + + // Create a fake screen-reader mouse event. + const event = createMouseEvent('mousedown'); + Object.defineProperties(event, {buttons: {get: () => 0}}); + dispatchEvent(document, event); + + expect(detector.mostRecentModality).toBe('keyboard'); + }); + it('should detect fake screen reader touch events as keyboard input modality', () => { setupTest(); diff --git a/src/cdk/config.bzl b/src/cdk/config.bzl index 583a9e317e07..ba749f162c2d 100644 --- a/src/cdk/config.bzl +++ b/src/cdk/config.bzl @@ -19,7 +19,6 @@ CDK_ENTRYPOINTS = [ "text-field", "tree", "testing", - "testing/protractor", "testing/testbed", "testing/selenium-webdriver", ] diff --git a/src/cdk/layout/breakpoints-observer.ts b/src/cdk/layout/breakpoints-observer.ts index 51537dce0257..003e3c078b72 100644 --- a/src/cdk/layout/breakpoints-observer.ts +++ b/src/cdk/layout/breakpoints-observer.ts @@ -105,13 +105,13 @@ export class BreakpointObserver implements OnDestroy { const mql = this._mediaMatcher.matchMedia(query); // Create callback for match changes and add it is as a listener. - const queryObservable = new Observable((observer: Observer) => { + const queryObservable = new Observable((observer: Observer) => { // Listener callback methods are wrapped to be placed back in ngZone. Callbacks must be placed // back into the zone because matchMedia is only included in Zone.js by loading the // webapis-media-query.js file alongside the zone.js file. Additionally, some browsers do not // have MediaQueryList inherit from EventTarget, which causes inconsistencies in how Zone.js // patches it. - const handler = (e: any) => this._zone.run(() => observer.next(e)); + const handler = (e: MediaQueryListEvent): void => this._zone.run(() => observer.next(e)); mql.addListener(handler); return () => { diff --git a/src/cdk/schematics/tsconfig.json b/src/cdk/schematics/tsconfig.json index e7c3f4393b4b..ad4a933f4ce2 100644 --- a/src/cdk/schematics/tsconfig.json +++ b/src/cdk/schematics/tsconfig.json @@ -7,6 +7,7 @@ "outDir": "../../../dist/packages/cdk/schematics", "noEmitOnError": false, "strictNullChecks": true, + "useUnknownInCatchVariables": true, "noImplicitOverride": true, "noImplicitReturns": true, "noImplicitAny": true, diff --git a/src/cdk/schematics/utils/html-manipulation.ts b/src/cdk/schematics/utils/html-manipulation.ts index 9aa5af51139a..10af7abdf28e 100644 --- a/src/cdk/schematics/utils/html-manipulation.ts +++ b/src/cdk/schematics/utils/html-manipulation.ts @@ -70,7 +70,9 @@ export function addBodyClass(host: Tree, htmlFilePath: string, className: string .includes(className); if (!hasClass) { - const classAttributeLocation = body.sourceCodeLocation!.attrs.class; + // We have source code location info enabled, and we pre-checked that the element + // has attributes, specifically the `class` attribute. + const classAttributeLocation = body.sourceCodeLocation!.attrs!.class; const recordedChange = host .beginUpdate(htmlFilePath) .insertRight(classAttributeLocation.endOffset - 1, ` ${className}`); diff --git a/src/cdk/schematics/utils/project-tsconfig-paths.ts b/src/cdk/schematics/utils/project-tsconfig-paths.ts index 36bd1bb53ba7..cbcb5daad7f6 100644 --- a/src/cdk/schematics/utils/project-tsconfig-paths.ts +++ b/src/cdk/schematics/utils/project-tsconfig-paths.ts @@ -43,7 +43,7 @@ export async function getWorkspaceConfigGracefully( return await readJsonWorkspace(path, { readFile: async filePath => tree.read(filePath)!.toString(), } as WorkspaceHost); - } catch (e) { + } catch { return null; } } diff --git a/src/cdk/table/table.ts b/src/cdk/table/table.ts index 9effc47d5f24..2c0d55061715 100644 --- a/src/cdk/table/table.ts +++ b/src/cdk/table/table.ts @@ -40,6 +40,7 @@ import { IterableChangeRecord, IterableDiffer, IterableDiffers, + NgZone, OnDestroy, OnInit, Optional, @@ -60,7 +61,7 @@ import { Subject, Subscription, } from 'rxjs'; -import {takeUntil} from 'rxjs/operators'; +import {take, takeUntil} from 'rxjs/operators'; import {CdkColumnDef} from './cell'; import {_CoalescedStyleScheduler, _COALESCED_STYLE_SCHEDULER} from './coalesced-style-scheduler'; import { @@ -525,6 +526,12 @@ export class CdkTable implements AfterContentChecked, CollectionViewer, OnDes @SkipSelf() @Inject(STICKY_POSITIONING_LISTENER) protected readonly _stickyPositioningListener: StickyPositioningListener, + /** + * @deprecated `_ngZone` parameter to become required. + * @breaking-change 14.0.0 + */ + @Optional() + protected readonly _ngZone?: NgZone, ) { if (!role) { this._elementRef.nativeElement.setAttribute('role', 'table'); @@ -604,13 +611,23 @@ export class CdkTable implements AfterContentChecked, CollectionViewer, OnDes } ngOnDestroy() { - this._rowOutlet.viewContainer.clear(); - this._noDataRowOutlet.viewContainer.clear(); - this._headerRowOutlet.viewContainer.clear(); - this._footerRowOutlet.viewContainer.clear(); - - this._cachedRenderRowsMap.clear(); + [ + this._rowOutlet.viewContainer, + this._headerRowOutlet.viewContainer, + this._footerRowOutlet.viewContainer, + this._cachedRenderRowsMap, + this._customColumnDefs, + this._customRowDefs, + this._customHeaderRowDefs, + this._customFooterRowDefs, + this._columnDefsByName, + ].forEach(def => { + def.clear(); + }); + this._headerRowDefs = []; + this._footerRowDefs = []; + this._defaultRowDef = null; this._onDestroy.next(); this._onDestroy.complete(); @@ -666,7 +683,16 @@ export class CdkTable implements AfterContentChecked, CollectionViewer, OnDes }); this._updateNoDataRow(); - this.updateStickyColumnStyles(); + + // Allow the new row data to render before measuring it. + // @breaking-change 14.0.0 Remove undefined check once _ngZone is required. + if (this._ngZone && NgZone.isInAngularZone()) { + this._ngZone.onStable.pipe(take(1), takeUntil(this._onDestroy)).subscribe(() => { + this.updateStickyColumnStyles(); + }); + } else { + this.updateStickyColumnStyles(); + } this.contentChanged.next(); } diff --git a/src/cdk/testing/protractor/README.md b/src/cdk/testing/protractor/README.md new file mode 100644 index 000000000000..2df7d650ee89 --- /dev/null +++ b/src/cdk/testing/protractor/README.md @@ -0,0 +1,4 @@ +### No longer publicly available + +The protractor harness environment is no longer part of the public API. It was +deprecated in v12 and removed from the API in v14. diff --git a/src/cdk/testing/protractor/protractor-harness-environment.ts b/src/cdk/testing/protractor/protractor-harness-environment.ts index befe96aeb698..916550103c1f 100644 --- a/src/cdk/testing/protractor/protractor-harness-environment.ts +++ b/src/cdk/testing/protractor/protractor-harness-environment.ts @@ -27,7 +27,8 @@ const defaultEnvironmentOptions: ProtractorHarnessEnvironmentOptions = { /** * A `HarnessEnvironment` implementation for Protractor. - * @deprecated + * @deprecated As of v13.0.0, this environment no longer works, as it is not + * compatible with the new [Angular Package Format](https://angular.io/guide/angular-package-format). * @breaking-change 13.0.0 */ export class ProtractorHarnessEnvironment extends HarnessEnvironment { diff --git a/src/cdk/testing/test-harnesses.md b/src/cdk/testing/test-harnesses.md index 049d71862fc8..90e1ce011944 100644 --- a/src/cdk/testing/test-harnesses.md +++ b/src/cdk/testing/test-harnesses.md @@ -44,12 +44,12 @@ matches the harness class to instances of the component in the DOM. Beyond that, given harness is specific to its corresponding component; refer to the component's documentation to learn how to use a specific harness. -#### Using `TestbedHarnessEnvironment` and `ProtractorHarnessEnvironment` +#### Using `TestbedHarnessEnvironment` and `SeleniumWebDriverHarnessEnvironment` These classes correspond to different implementations of the component harness system with bindings for specific test environments. Any given test must only import _one_ of these classes. Karma-based -unit tests should use the `TestbedHarnessEnvironment`, while Protractor-based end-to-end tests -should use the `ProtractorHarnessEnvironment`. Additional environments require custom bindings; see +unit tests should use the `TestbedHarnessEnvironment`, while Selenium WebDriver-based end-to-end tests +should use the `SeleniumWebDriverHarnessEnvironment`. Additional environments require custom bindings; see [API for harness environment authors](#api-for-harness-environment-authors) for more information on alternate test environments. @@ -107,13 +107,13 @@ it('loads harnesses', async () => { }); ``` -`ProtractorHarnessEnvironment` has an API that offers a single static method: +`SeleniumWebDriverHarnessEnvironment` has an API that offers a single static method: | Method | Description | | ------ | ----------- | | `loader(): HarnessLoader` | Gets a `HarnessLoader` instance for the current HTML document, rooted at the document's root element. | -Since Protractor does not deal with fixtures, the API in this environment is simpler. The +Since Selenium WebDriver does not deal with fixtures, the API in this environment is simpler. The `HarnessLoader` returned by the `loader()` method should be sufficient for loading all necessary `ComponentHarness` instances. @@ -304,7 +304,7 @@ The functions created with the locator methods described above all return `TestE | `dispatchEvent(name: string, data?: Record): Promise;` | Dispatches an event with a particular name. | `TestElement` is an abstraction designed to work across different test environments (Karma, -Protractor, etc). When using harnesses, you should perform all DOM interaction via this interface. +Selenium WebDriver, etc). When using harnesses, you should perform all DOM interaction via this interface. Other means of accessing DOM elements (e.g. `document.querySelector`) will not work in all test environments. @@ -574,7 +574,7 @@ may need to explicitly wait for tasks outside `NgZone`, as this does not happen Harness environment authors are developers who want to add support for using component harnesses in additional testing environments. Out-of-the-box, Angular CDK's component harnesses can be used in -Protractor E2E tests and Karma unit tests. Developers can support additional environments by +Selenium WebDriver E2E tests and Karma unit tests. Developers can support additional environments by creating custom implementations of `TestElement` and `HarnessEnvironment`. #### Creating a `TestElement` implementation for the environment @@ -583,7 +583,7 @@ The first step in adding support for a new testing environment is to create a `T implementation. The `TestElement` interface serves as an environment-agnostic representation of a DOM element; it lets harnesses interact with DOM elements regardless of the underlying environment. Because some environments don't support interacting with DOM elements synchronously -(e.g. webdriver), all of the `TestElement` methods are asynchronous, returning a `Promise` with the +(e.g. WebDriver), all of the `TestElement` methods are asynchronous, returning a `Promise` with the result of the operation. | Method | Description | @@ -616,7 +616,7 @@ maintain a mapping from `TestKey` codes to the codes used in the particular test The [`UnitTestElement`](https://github.com/angular/components/blob/master/src/cdk/testing/testbed/unit-test-element.ts#L57) and -[`ProtractorElement`](https://github.com/angular/components/blob/master/src/cdk/testing/protractor/protractor-element.ts#L67) +[`SeleniumWebDriverElement`](https://github.com/angular/components/blob/master/src/cdk/testing/selenium-webdriver/selenium-web-driver-element.ts#L22) implementations in Angular CDK serve as good examples of implementations of this interface. #### Creating a `HarnessEnvironemnt` implementation for the environment @@ -654,7 +654,7 @@ require arguments to be passed. (e.g. the `loader` method on `TestbedHarnessEnvi The [`TestbedHarnessEnvironment`](https://github.com/angular/components/blob/master/src/cdk/testing/testbed/testbed-harness-environment.ts#L20) and -[`ProtractorHarnessEnvironment`](https://github.com/angular/components/blob/master/src/cdk/testing/protractor/protractor-harness-environment.ts#L16) +[`SeleniumWebDriverHarnessEnvironment`](https://github.com/angular/components/blob/master/src/cdk/testing/selenium-webdriver/selenium-web-driver-harness-environment.ts#L71) implementations in Angular CDK serve as good examples of implementations of this interface. #### Handling auto change detection status diff --git a/src/cdk/testing/tests/cross-environment.spec.ts b/src/cdk/testing/tests/cross-environment.spec.ts index fb2983db0d03..e6d6827670ce 100644 --- a/src/cdk/testing/tests/cross-environment.spec.ts +++ b/src/cdk/testing/tests/cross-environment.spec.ts @@ -58,7 +58,7 @@ export function crossEnvironmentSpecs( await loader.getChildLoader('error'); fail('Expected to throw'); } catch (e) { - expect(e.message).toBe( + expect((e as Error).message).toBe( 'Failed to find element matching one of the following queries:' + '\n(HarnessLoader for element matching selector: "error")', ); @@ -82,7 +82,7 @@ export function crossEnvironmentSpecs( await countersLoader.getHarness(SubComponentHarness); fail('Expected to throw'); } catch (e) { - expect(e.message).toBe( + expect((e as Error).message).toBe( 'Failed to find element matching one of the following queries:' + '\n(SubComponentHarness with host element matching selector: "test-sub")', ); @@ -112,7 +112,7 @@ export function crossEnvironmentSpecs( await harness.errorItem(); fail('Expected to throw'); } catch (e) { - expect(e.message).toBe( + expect((e as Error).message).toBe( 'Failed to find element matching one of the following queries:' + '\n(TestElement for element matching selector: "wrong locator")', ); @@ -147,7 +147,7 @@ export function crossEnvironmentSpecs( await harness.errorSubComponent(); fail('Expected to throw'); } catch (e) { - expect(e.message).toBe( + expect((e as Error).message).toBe( 'Failed to find element matching one of the following queries:' + '\n(WrongComponentHarness with host element matching selector: "wrong-selector")', ); @@ -211,7 +211,7 @@ export function crossEnvironmentSpecs( await harness.requiredAncestorRestrictedMissingSubcomponent(); fail('Expected to throw'); } catch (e) { - expect(e.message).toBe( + expect((e as Error).message).toBe( 'Failed to find element matching one of the following queries:' + '\n(SubComponentHarness with host element matching selector: "test-sub"' + ' satisfying the constraints: has ancestor matching selector ".not-found")', @@ -311,7 +311,7 @@ export function crossEnvironmentSpecs( await harness.requiredFourIteamToolsLists(); fail('Expected to throw'); } catch (e) { - expect(e.message).toBe( + expect((e as Error).message).toBe( 'Failed to find element matching one of the following queries:' + '\n(SubComponentHarness with host element matching selector: "test-sub" satisfying' + ' the constraints: title = "List of test tools", item count = 4)', @@ -640,7 +640,7 @@ export function crossEnvironmentSpecs( await harness.missingElementsAndHarnesses(); fail('Expected to throw.'); } catch (e) { - expect(e.message).toBe( + expect((e as Error).message).toBe( 'Failed to find element matching one of the following queries:' + '\n(TestElement for element matching selector: ".not-found"),' + '\n(SubComponentHarness with host element matching selector: "test-sub" satisfying' + diff --git a/src/cdk/testing/tests/webdriver-test.bzl b/src/cdk/testing/tests/webdriver-test.bzl index da917273eab7..4535d1846017 100644 --- a/src/cdk/testing/tests/webdriver-test.bzl +++ b/src/cdk/testing/tests/webdriver-test.bzl @@ -26,7 +26,7 @@ def webdriver_test(name, deps, tags = [], **kwargs): server_test( name = "%s_chromium" % name, - server = "//src/e2e-app:devserver", + server = "//src/e2e-app:server", test = ":%s_chromium_web_test" % name, tags = tags + ["e2e"], ) diff --git a/src/components-examples/material/radio/radio-ng-model/radio-ng-model-example.css b/src/components-examples/material/radio/radio-ng-model/radio-ng-model-example.css index 166387412734..092324c6ecb0 100644 --- a/src/components-examples/material/radio/radio-ng-model/radio-ng-model-example.css +++ b/src/components-examples/material/radio/radio-ng-model/radio-ng-model-example.css @@ -2,6 +2,7 @@ display: flex; flex-direction: column; margin: 15px 0; + align-items: flex-start; } .example-radio-button { diff --git a/src/components-examples/material/tabs/index.ts b/src/components-examples/material/tabs/index.ts index cb5279b3487b..60a688c946e5 100644 --- a/src/components-examples/material/tabs/index.ts +++ b/src/components-examples/material/tabs/index.ts @@ -17,6 +17,7 @@ import {TabGroupHarnessExample} from './tab-group-harness/tab-group-harness-exam import {TabGroupDynamicExample} from './tab-group-dynamic/tab-group-dynamic-example'; import {TabGroupHeaderBelowExample} from './tab-group-header-below/tab-group-header-below-example'; import {TabGroupLazyLoadedExample} from './tab-group-lazy-loaded/tab-group-lazy-loaded-example'; +import {TabGroupPreserveContentExample} from './tab-group-preserve-content/tab-group-preserve-content-example'; import {TabGroupStretchedExample} from './tab-group-stretched/tab-group-stretched-example'; import {TabGroupThemeExample} from './tab-group-theme/tab-group-theme-example'; import {TabNavBarBasicExample} from './tab-nav-bar-basic/tab-nav-bar-basic-example'; @@ -37,6 +38,7 @@ export { TabGroupThemeExample, TabNavBarBasicExample, TabNavBarWithPanelExample, + TabGroupPreserveContentExample, }; const EXAMPLES = [ @@ -54,6 +56,7 @@ const EXAMPLES = [ TabGroupThemeExample, TabNavBarBasicExample, TabNavBarWithPanelExample, + TabGroupPreserveContentExample, ]; @NgModule({ diff --git a/src/components-examples/material/tabs/tab-group-preserve-content/tab-group-preserve-content-example.html b/src/components-examples/material/tabs/tab-group-preserve-content/tab-group-preserve-content-example.html new file mode 100644 index 000000000000..3d58eef2e816 --- /dev/null +++ b/src/components-examples/material/tabs/tab-group-preserve-content/tab-group-preserve-content-example.html @@ -0,0 +1,14 @@ +

Start the video in the first tab and navigate to the second one to see how it keeps playing.

+ + + + + + Note how the video from the previous tab is still playing. + diff --git a/src/components-examples/material/tabs/tab-group-preserve-content/tab-group-preserve-content-example.ts b/src/components-examples/material/tabs/tab-group-preserve-content/tab-group-preserve-content-example.ts new file mode 100644 index 000000000000..8509b2d1fd04 --- /dev/null +++ b/src/components-examples/material/tabs/tab-group-preserve-content/tab-group-preserve-content-example.ts @@ -0,0 +1,10 @@ +import {Component} from '@angular/core'; + +/** + * @title Tab group that keeps its content inside the DOM when it's off-screen. + */ +@Component({ + selector: 'tab-group-preserve-content-example', + templateUrl: 'tab-group-preserve-content-example.html', +}) +export class TabGroupPreserveContentExample {} diff --git a/src/dev-app/BUILD.bazel b/src/dev-app/BUILD.bazel index 45d4465995df..34afe3bde21d 100644 --- a/src/dev-app/BUILD.bazel +++ b/src/dev-app/BUILD.bazel @@ -1,6 +1,5 @@ load("@build_bazel_rules_nodejs//:index.bzl", "pkg_web") -load("//tools:defaults.bzl", "devmode_esbuild", "esbuild_config", "ng_module", "sass_binary") -load("//tools/dev-server:index.bzl", "dev_server") +load("//tools:defaults.bzl", "devmode_esbuild", "esbuild_config", "http_server", "ng_module", "sass_binary") load("//src/components-examples:config.bzl", "ALL_EXAMPLES") load("//tools/angular:index.bzl", "LINKER_PROCESSED_FW_PACKAGES") @@ -158,14 +157,13 @@ filegroup( ":theme", ":variables", "//src/dev-app/icon:icon_demo_assets", - "@npm//:node_modules/core-js-bundle/index.js", "@npm//:node_modules/moment/min/moment-with-locales.min.js", "@npm//:node_modules/rxjs/bundles/rxjs.umd.min.js", "@npm//:node_modules/zone.js/dist/zone.js", ], ) -dev_server( +http_server( name = "devserver", srcs = [":dev_app_static_files"], additional_root_paths = [ @@ -174,6 +172,13 @@ dev_server( # artifact output as workspace root. "angular_material", ], + enable_dev_ui = True, + # List of environment variables that will be made available as `window.` in the + # served `index.html` throuhg an injected script. Useful for allowing developers to + # configure API keys without requiring secrets to be committed. + environment_variables = [ + "GOOGLE_MAPS_KEY", + ], tags = ["manual"], deps = [ ":bundles", diff --git a/src/dev-app/chips/chips-demo.html b/src/dev-app/chips/chips-demo.html index 77bd05a2341b..b5ebf78d29b4 100644 --- a/src/dev-app/chips/chips-demo.html +++ b/src/dev-app/chips/chips-demo.html @@ -70,12 +70,12 @@

With avatar and icons

- + Mal - + Husi + - -
- - - -
-
- + + + diff --git a/src/material-experimental/mdc-chips/chip-option.spec.ts b/src/material-experimental/mdc-chips/chip-option.spec.ts index 6a66bc9703f2..626f8f58494e 100644 --- a/src/material-experimental/mdc-chips/chip-option.spec.ts +++ b/src/material-experimental/mdc-chips/chip-option.spec.ts @@ -1,6 +1,5 @@ import {Directionality} from '@angular/cdk/bidi'; -import {SPACE} from '@angular/cdk/keycodes'; -import {createKeyboardEvent, dispatchFakeEvent} from '../../cdk/testing/private'; +import {dispatchFakeEvent, dispatchKeyboardEvent} from '@angular/cdk/testing/private'; import {Component, DebugElement, ViewChild} from '@angular/core'; import {waitForAsync, ComponentFixture, fakeAsync, flush, TestBed} from '@angular/core/testing'; import { @@ -8,7 +7,6 @@ import { RippleGlobalOptions, } from '@angular/material-experimental/mdc-core'; import {By} from '@angular/platform-browser'; -import {deprecated} from '@material/chips'; import {Subject} from 'rxjs'; import { MatChipEvent, @@ -17,11 +15,13 @@ import { MatChipSelectionChange, MatChipsModule, } from './index'; +import {SPACE} from '@angular/cdk/keycodes'; describe('MDC-based Option Chips', () => { let fixture: ComponentFixture; let chipDebugElement: DebugElement; let chipNativeElement: HTMLElement; + let primaryAction: HTMLElement; let chipInstance: MatChipOption; let globalRippleOptions: RippleGlobalOptions; let dir = 'ltr'; @@ -58,6 +58,7 @@ describe('MDC-based Option Chips', () => { chipDebugElement = fixture.debugElement.query(By.directive(MatChipOption))!; chipNativeElement = chipDebugElement.nativeElement; chipInstance = chipDebugElement.injector.get(MatChipOption); + primaryAction = chipNativeElement.querySelector('.mdc-evolution-chip__action--primary')!; testComponent = fixture.debugElement.componentInstance; }); @@ -72,8 +73,8 @@ describe('MDC-based Option Chips', () => { counter++; }); - chipNativeElement.focus(); - chipNativeElement.focus(); + primaryAction.focus(); + primaryAction.focus(); fixture.detectChanges(); expect(counter).toBe(1); @@ -121,16 +122,6 @@ describe('MDC-based Option Chips', () => { expect(event.defaultPrevented).toBe(false); }); - it('should prevent the default click action when the chip is disabled', () => { - chipInstance.disabled = true; - fixture.detectChanges(); - - const event = dispatchFakeEvent(chipNativeElement, 'click'); - fixture.detectChanges(); - - expect(event.defaultPrevented).toBe(true); - }); - it('should not dispatch `selectionChange` event when deselecting a non-selected chip', () => { chipInstance.deselect(); @@ -204,7 +195,6 @@ describe('MDC-based Option Chips', () => { }); it('should selects/deselects the currently focused chip on SPACE', () => { - const SPACE_EVENT = createKeyboardEvent('keydown', SPACE); const CHIP_SELECTED_EVENT: MatChipSelectionChange = { source: chipInstance, isUserInput: true, @@ -220,7 +210,7 @@ describe('MDC-based Option Chips', () => { spyOn(testComponent, 'chipSelectionChange'); // Use the spacebar to select the chip - chipInstance._keydown(SPACE_EVENT); + dispatchKeyboardEvent(primaryAction, 'keydown', SPACE); fixture.detectChanges(); expect(chipInstance.selected).toBeTruthy(); @@ -228,7 +218,7 @@ describe('MDC-based Option Chips', () => { expect(testComponent.chipSelectionChange).toHaveBeenCalledWith(CHIP_SELECTED_EVENT); // Use the spacebar to deselect the chip - chipInstance._keydown(SPACE_EVENT); + dispatchKeyboardEvent(primaryAction, 'keydown', SPACE); fixture.detectChanges(); expect(chipInstance.selected).toBeFalsy(); @@ -237,24 +227,24 @@ describe('MDC-based Option Chips', () => { }); it('should have correct aria-selected in single selection mode', () => { - expect(chipNativeElement.hasAttribute('aria-selected')).toBe(false); + expect(primaryAction.hasAttribute('aria-selected')).toBe(false); testComponent.selected = true; fixture.detectChanges(); - expect(chipNativeElement.getAttribute('aria-selected')).toBe('true'); + expect(primaryAction.getAttribute('aria-selected')).toBe('true'); }); it('should have the correct aria-selected in multi-selection mode', fakeAsync(() => { testComponent.chipList.multiple = true; flush(); fixture.detectChanges(); - expect(chipNativeElement.getAttribute('aria-selected')).toBe('false'); + expect(primaryAction.getAttribute('aria-selected')).toBe('false'); testComponent.selected = true; fixture.detectChanges(); - expect(chipNativeElement.getAttribute('aria-selected')).toBe('true'); + expect(primaryAction.getAttribute('aria-selected')).toBe('true'); })); it('should disable focus on the checkmark', fakeAsync(() => { @@ -263,7 +253,7 @@ describe('MDC-based Option Chips', () => { flush(); fixture.detectChanges(); - const checkmark = chipNativeElement.querySelector('.mdc-chip__checkmark-svg')!; + const checkmark = chipNativeElement.querySelector('.mdc-evolution-chip__checkmark-svg')!; expect(checkmark.getAttribute('focusable')).toBe('false'); })); }); @@ -275,51 +265,34 @@ describe('MDC-based Option Chips', () => { }); it('SPACE ignores selection', () => { - const SPACE_EVENT = createKeyboardEvent('keydown', SPACE); - spyOn(testComponent, 'chipSelectionChange'); // Use the spacebar to attempt to select the chip - chipInstance._keydown(SPACE_EVENT); + dispatchKeyboardEvent(primaryAction, 'keydown', SPACE); fixture.detectChanges(); - expect(chipInstance.selected).toBeFalsy(); + expect(chipInstance.selected).toBe(false); expect(testComponent.chipSelectionChange).not.toHaveBeenCalled(); }); it('should not have the aria-selected attribute', () => { - expect(chipNativeElement.hasAttribute('aria-selected')).toBe(false); + expect(primaryAction.hasAttribute('aria-selected')).toBe(false); }); }); - it('should update the aria-label for disabled chips', () => { - expect(chipNativeElement.getAttribute('aria-disabled')).toBe('false'); + it('should update the aria-disabled for disabled chips', () => { + expect(primaryAction.getAttribute('aria-disabled')).toBe('false'); testComponent.disabled = true; fixture.detectChanges(); - expect(chipNativeElement.getAttribute('aria-disabled')).toBe('true'); + expect(primaryAction.getAttribute('aria-disabled')).toBe('true'); }); }); - it('should hide the leading icon when initialized as selected', () => { - // We need to recreate the fixture before change detection has - // run so we can capture the behavior we're testing for. - fixture.destroy(); - fixture = TestBed.createComponent(SingleChip); - testComponent = fixture.debugElement.componentInstance; - testComponent.selected = true; - fixture.detectChanges(); - chipDebugElement = fixture.debugElement.query(By.directive(MatChipOption))!; - chipNativeElement = chipDebugElement.nativeElement; - chipInstance = chipDebugElement.injector.get(MatChipOption); - - const avatar = fixture.nativeElement.querySelector('.avatar'); - expect(avatar.classList).toContain(deprecated.chipCssClasses.HIDDEN_LEADING_ICON); - }); - - it('should have a focus indicator', () => { - expect(chipNativeElement.classList.contains('mat-mdc-focus-indicator')).toBe(true); + it('should contain a focus indicator inside the text label', () => { + const label = chipNativeElement.querySelector('.mdc-evolution-chip__text-label'); + expect(label?.querySelector('.mat-mdc-focus-indicator')).toBeTruthy(); }); }); }); diff --git a/src/material-experimental/mdc-chips/chip-option.ts b/src/material-experimental/mdc-chips/chip-option.ts index 3b9362ce17ac..dfca8a135d6c 100644 --- a/src/material-experimental/mdc-chips/chip-option.ts +++ b/src/material-experimental/mdc-chips/chip-option.ts @@ -7,7 +7,6 @@ */ import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion'; -import {SPACE} from '@angular/cdk/keycodes'; import { ChangeDetectionStrategy, Component, @@ -15,9 +14,15 @@ import { Input, Output, ViewEncapsulation, - AfterContentInit, + AfterViewInit, + OnInit, } from '@angular/core'; -import {deprecated} from '@material/chips'; +import { + ActionInteractionEvent, + MDCChipActionInteractionTrigger, + MDCChipActionType, + MDCChipCssClasses, +} from '@material/chips'; import {take} from 'rxjs/operators'; import {MatChip} from './chip'; @@ -40,32 +45,41 @@ export class MatChipSelectionChange { @Component({ selector: 'mat-basic-chip-option, mat-chip-option', templateUrl: 'chip-option.html', - styleUrls: ['chips.css'], + styleUrls: ['chip.css'], inputs: ['color', 'disableRipple', 'tabIndex'], host: { - 'role': 'option', - 'class': 'mat-mdc-focus-indicator mat-mdc-chip-option', - '[class.mat-mdc-chip-disabled]': 'disabled', - '[class.mat-mdc-chip-highlighted]': 'highlighted', - '[class.mat-mdc-chip-with-avatar]': 'leadingIcon', - '[class.mat-mdc-chip-with-trailing-icon]': 'trailingIcon || removeIcon', + 'class': 'mat-mdc-chip mat-mdc-chip-option mdc-evolution-chip mdc-evolution-chip--filter', '[class.mat-mdc-chip-selected]': 'selected', '[class.mat-mdc-chip-multiple]': '_chipListMultiple', + '[class.mat-mdc-chip-disabled]': 'disabled', + '[class.mat-mdc-chip-with-avatar]': 'leadingIcon', + '[class.mdc-evolution-chip--selectable]': 'selectable', + '[class.mdc-evolution-chip--disabled]': 'disabled', + '[class.mdc-evolution-chip--with-trailing-action]': '_hasTrailingIcon()', + '[class.mdc-evolution-chip--with-primary-graphic]': '_hasLeadingGraphic()', + '[class.mdc-evolution-chip--with-primary-icon]': 'leadingIcon', + '[class.mdc-evolution-chip--with-avatar]': 'leadingIcon', + '[class.mat-mdc-chip-highlighted]': 'highlighted', + '[class.mat-mdc-chip-with-trailing-icon]': '_hasTrailingIcon()', + '[attr.tabindex]': 'null', + '[attr.aria-label]': 'null', + '[attr.role]': 'role', '[id]': 'id', - '[tabIndex]': 'tabIndex', - '[attr.disabled]': 'disabled || null', - '[attr.aria-disabled]': 'disabled.toString()', - '[attr.aria-selected]': 'ariaSelected', - '(click)': '_click($event)', - '(keydown)': '_keydown($event)', - '(focus)': 'focus()', - '(blur)': '_blur()', }, providers: [{provide: MatChip, useExisting: MatChipOption}], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, }) -export class MatChipOption extends MatChip implements AfterContentInit { +export class MatChipOption extends MatChip implements OnInit, AfterViewInit { + /** Whether the component is done initializing. */ + private _isInitialized: boolean; + + /** + * Selected state that was assigned before the component was initializing + * and which needs to be synced back up with the foundation. + */ + private _pendingSelectedState: boolean | undefined; + /** Whether the chip list is selectable. */ chipListSelectable: boolean = true; @@ -91,16 +105,19 @@ export class MatChipOption extends MatChip implements AfterContentInit { /** Whether the chip is selected. */ @Input() get selected(): boolean { - return this._chipFoundation.isSelected(); + return ( + this._pendingSelectedState ?? this._chipFoundation.isActionSelected(MDCChipActionType.PRIMARY) + ); } set selected(value: BooleanInput) { - if (!this.selectable) { - return; - } - const coercedValue = coerceBooleanProperty(value); - if (coercedValue != this._chipFoundation.isSelected()) { - this._chipFoundation.setSelected(coerceBooleanProperty(value)); - this._dispatchSelectionChange(); + if (this.selectable) { + const coercedValue = coerceBooleanProperty(value); + + if (this._isInitialized) { + this._setSelectedState(coercedValue, false); + } else { + this._pendingSelectedState = coercedValue; + } } } @@ -120,77 +137,53 @@ export class MatChipOption extends MatChip implements AfterContentInit { @Output() readonly selectionChange: EventEmitter = new EventEmitter(); - override ngAfterContentInit() { - super.ngAfterContentInit(); + ngOnInit() { + this.role = 'presentation'; + } + + override ngAfterViewInit() { + super.ngAfterViewInit(); + this._isInitialized = true; - if (this.selected && this.leadingIcon) { - this.leadingIcon.setClass(deprecated.chipCssClasses.HIDDEN_LEADING_ICON, true); + if (this._pendingSelectedState != null) { + // Note that we want to clear the pending state before calling `_setSelectedState`, because + // we want it to read the actual selected state instead falling back to the pending one. + const selectedState = this._pendingSelectedState; + this._pendingSelectedState = undefined; + this._setSelectedState(selectedState, false); } } /** Selects the chip. */ select(): void { - if (!this.selectable) { - return; - } else if (!this.selected) { - this._chipFoundation.setSelected(true); - this._dispatchSelectionChange(); + if (this.selectable) { + this._setSelectedState(true, false); } } /** Deselects the chip. */ deselect(): void { - if (!this.selectable) { - return; - } else if (this.selected) { - this._chipFoundation.setSelected(false); - this._dispatchSelectionChange(); + if (this.selectable) { + this._setSelectedState(false, false); } } /** Selects this chip and emits userInputSelection event */ selectViaInteraction(): void { - if (!this.selectable) { - return; - } else if (!this.selected) { - this._chipFoundation.setSelected(true); - this._dispatchSelectionChange(true); + if (this.selectable) { + this._setSelectedState(true, true); } } /** Toggles the current selected state of this chip. */ toggleSelected(isUserInput: boolean = false): boolean { - if (!this.selectable) { - return this.selected; + if (this.selectable) { + this._setSelectedState(!this.selected, isUserInput); } - this._chipFoundation.setSelected(!this.selected); - this._dispatchSelectionChange(isUserInput); return this.selected; } - /** Emits a selection change event. */ - private _dispatchSelectionChange(isUserInput = false) { - this.selectionChange.emit({ - source: this, - isUserInput, - selected: this.selected, - }); - } - - /** Allows for programmatic focusing of the chip. */ - focus(): void { - if (this.disabled) { - return; - } - - if (!this._hasFocus()) { - this._elementRef.nativeElement.focus(); - this._onFocus.next({chip: this}); - } - this._hasFocusInternal = true; - } - /** Resets the state of the chip when it loses focus. */ _blur(): void { // When animations are enabled, Angular may end up removing the chip from the DOM a little @@ -205,31 +198,47 @@ export class MatChipOption extends MatChip implements AfterContentInit { }); } - /** Handles click events on the chip. */ - _click(event: MouseEvent) { - if (this.disabled) { - event.preventDefault(); - } else { - this._handleInteraction(event); - event.stopPropagation(); + protected override _onChipInteraction(event: ActionInteractionEvent) { + const {trigger, source} = event.detail; + + // Non-selection interactions should work the same as other chips. + if ( + source !== MDCChipActionType.PRIMARY || + (trigger !== MDCChipActionInteractionTrigger.CLICK && + trigger !== MDCChipActionInteractionTrigger.ENTER_KEY && + trigger !== MDCChipActionInteractionTrigger.SPACEBAR_KEY) + ) { + super._onChipInteraction(event); + } else if (this.selectable && !this.disabled) { + // Otherwise only let the event through if the chip is enabled and selectable. + this._chipFoundation.handleActionInteraction(event); + this.selectionChange.emit({ + source: this, + isUserInput: true, + selected: this.selected, + }); } } - /** Handles custom key presses. */ - _keydown(event: KeyboardEvent): void { - if (this.disabled) { - return; - } + _hasLeadingGraphic() { + // The checkmark graphic is built in for multi-select chip lists. + return this.leadingIcon || (this._chipListMultiple && this.selectable); + } - switch (event.keyCode) { - case SPACE: - this.toggleSelected(true); + private _setSelectedState(isSelected: boolean, isUserInput: boolean) { + if (isSelected !== this.selected) { + this._chipFoundation.setActionSelected(MDCChipActionType.PRIMARY, isSelected); + this.selectionChange.emit({ + source: this, + isUserInput, + selected: this.selected, + }); + } - // Always prevent space from scrolling the page since the list has focus - event.preventDefault(); - break; - default: - this._handleInteraction(event); + // MDC won't assign the selected class until the animation finishes, but that may not + // happen if animations are disabled. If we detect such a case, assign the class manually. + if (this._animationsDisabled) { + this._elementRef.nativeElement.classList.toggle(MDCChipCssClasses.SELECTED, isSelected); } } } diff --git a/src/material-experimental/mdc-chips/chip-remove.spec.ts b/src/material-experimental/mdc-chips/chip-remove.spec.ts index 17ebd0dae4e7..02060a4dce04 100644 --- a/src/material-experimental/mdc-chips/chip-remove.spec.ts +++ b/src/material-experimental/mdc-chips/chip-remove.spec.ts @@ -1,14 +1,15 @@ -import {dispatchKeyboardEvent, createKeyboardEvent, dispatchEvent} from '../../cdk/testing/private'; -import {Component, DebugElement} from '@angular/core'; +import {Component} from '@angular/core'; +import {waitForAsync, ComponentFixture, TestBed, fakeAsync, flush} from '@angular/core/testing'; +import {dispatchKeyboardEvent} from '@angular/cdk/testing/private'; import {By} from '@angular/platform-browser'; -import {waitForAsync, ComponentFixture, TestBed} from '@angular/core/testing'; -import {SPACE, ENTER, TAB} from '@angular/cdk/keycodes'; +import {SPACE, ENTER} from '@angular/cdk/keycodes'; +import {MDCChipAnimation, MDCChipCssClasses} from '@material/chips/chip'; import {MatChip, MatChipsModule} from './index'; describe('MDC-based Chip Remove', () => { let fixture: ComponentFixture; let testChip: TestChip; - let chipDebugElement: DebugElement; + let chipInstance: MatChip; let chipNativeElement: HTMLElement; beforeEach( @@ -28,148 +29,120 @@ describe('MDC-based Chip Remove', () => { testChip = fixture.debugElement.componentInstance; fixture.detectChanges(); - chipDebugElement = fixture.debugElement.query(By.directive(MatChip))!; + const chipDebugElement = fixture.debugElement.query(By.directive(MatChip))!; chipNativeElement = chipDebugElement.nativeElement; + chipInstance = chipDebugElement.componentInstance; }), ); - describe('basic behavior', () => { - it('should apply a CSS class to the remove icon', () => { - let buttonElement = chipNativeElement.querySelector('button')!; + function triggerRemoveSequence() { + // At the time of writing, MDC's removal sequence requires the following to happen: + // 1. Button is clicked, triggering the animation. + // 2. Before the animation has finished, the `--hidden` class is added. + // 3. Animation callback fires at some point. It doesn't really matter for the test, + // but it does queue up some `requestAnimationFrame` calls that we need to flush. + // 4. `transitionend` callback fires and finishes the removal sequence if the + // `--hidden` class exists. + fixture.detectChanges(); + (chipInstance as any)._handleAnimationend({ + animationName: MDCChipAnimation.EXIT, + target: chipNativeElement, + }); + flush(); + (chipInstance as any)._handleTransitionend({target: chipNativeElement}); + flush(); + fixture.detectChanges(); + } + describe('basic behavior', () => { + it('should apply a CSS class to the remove icon', fakeAsync(() => { + const buttonElement = chipNativeElement.querySelector('.mdc-evolution-chip__icon--trailing')!; expect(buttonElement.classList).toContain('mat-mdc-chip-remove'); - }); + })); - it('should ensure that the button cannot submit its parent form', () => { + it('should ensure that the button cannot submit its parent form', fakeAsync(() => { const buttonElement = chipNativeElement.querySelector('button')!; - expect(buttonElement.getAttribute('type')).toBe('button'); - }); + })); - it('should not set the `type` attribute on non-button elements', () => { + it('should not set the `type` attribute on non-button elements', fakeAsync(() => { const buttonElement = chipNativeElement.querySelector('span.mat-mdc-chip-remove')!; - expect(buttonElement.hasAttribute('type')).toBe(false); - }); - - it('should emit (removed) event when exit animation is complete', () => { - let buttonElement = chipNativeElement.querySelector('button')!; + })); + it('should emit (removed) event when exit animation is complete', fakeAsync(() => { testChip.removable = true; fixture.detectChanges(); - spyOn(testChip, 'didRemove'); - buttonElement.click(); - fixture.detectChanges(); + chipNativeElement.querySelector('button')!.click(); + triggerRemoveSequence(); expect(testChip.didRemove).toHaveBeenCalled(); - }); - - it('should not start MDC exit animation if parent chip is disabled', () => { - let buttonElement = chipNativeElement.querySelector('button')!; + })); + it('should not start MDC exit animation if parent chip is disabled', fakeAsync(() => { testChip.removable = true; testChip.disabled = true; fixture.detectChanges(); - buttonElement.click(); - fixture.detectChanges(); + chipNativeElement.querySelector('button')!.click(); - expect(chipNativeElement.classList.contains('mdc-chip--exit')).toBe(false); - }); + expect(chipNativeElement.classList.contains(MDCChipCssClasses.HIDDEN)).toBe(false); + })); - it('should not make the element aria-hidden when it is focusable', () => { + it('should not make the element aria-hidden when it is focusable', fakeAsync(() => { const buttonElement = chipNativeElement.querySelector('button')!; - expect(buttonElement.getAttribute('tabindex')).toBe('0'); + expect(buttonElement.getAttribute('tabindex')).toBe('-1'); expect(buttonElement.hasAttribute('aria-hidden')).toBe(false); - }); + })); - it('should prevent the default SPACE action', () => { + it('should prevent the default SPACE action', fakeAsync(() => { const buttonElement = chipNativeElement.querySelector('button')!; testChip.removable = true; fixture.detectChanges(); const event = dispatchKeyboardEvent(buttonElement, 'keydown', SPACE); - fixture.detectChanges(); + triggerRemoveSequence(); expect(event.defaultPrevented).toBe(true); - }); + })); - it('should not prevent the default SPACE action when a modifier key is pressed', () => { - const buttonElement = chipNativeElement.querySelector('button')!; - - testChip.removable = true; - fixture.detectChanges(); - - const event = createKeyboardEvent('keydown', SPACE, undefined, {shift: true}); - dispatchEvent(buttonElement, event); - fixture.detectChanges(); - - expect(event.defaultPrevented).toBe(false); - }); - - it('should prevent the default ENTER action', () => { + it('should prevent the default ENTER action', fakeAsync(() => { const buttonElement = chipNativeElement.querySelector('button')!; testChip.removable = true; fixture.detectChanges(); const event = dispatchKeyboardEvent(buttonElement, 'keydown', ENTER); - fixture.detectChanges(); + triggerRemoveSequence(); expect(event.defaultPrevented).toBe(true); - }); - - it('should not prevent the default ENTER action when a modifier key is pressed', () => { - const buttonElement = chipNativeElement.querySelector('button')!; - - testChip.removable = true; - fixture.detectChanges(); - - const event = createKeyboardEvent('keydown', ENTER, undefined, {shift: true}); - dispatchEvent(buttonElement, event); - fixture.detectChanges(); - - expect(event.defaultPrevented).toBe(false); - }); - - it('should not remove on any key press', () => { - let buttonElement = chipNativeElement.querySelector('button')!; - - testChip.removable = true; - fixture.detectChanges(); - - spyOn(testChip, 'didRemove'); - dispatchKeyboardEvent(buttonElement, 'keydown', TAB); - fixture.detectChanges(); - - expect(testChip.didRemove).not.toHaveBeenCalled(); - }); - - it('should have a focus indicator', () => { - const buttonElement = chipNativeElement.querySelector('button')!; + })); + it('should have a focus indicator', fakeAsync(() => { + const buttonElement = chipNativeElement.querySelector('.mdc-evolution-chip__icon--trailing')!; expect(buttonElement.classList.contains('mat-mdc-focus-indicator')).toBe(true); - }); + })); }); }); @Component({ template: ` - - - - + + + + + + `, }) class TestChip { removable: boolean; disabled = false; - - didRemove() {} + didRemove = jasmine.createSpy('didRemove spy'); } diff --git a/src/material-experimental/mdc-chips/chip-row.html b/src/material-experimental/mdc-chips/chip-row.html index ebc293d08a2d..2c8970d46aec 100644 --- a/src/material-experimental/mdc-chips/chip-row.html +++ b/src/material-experimental/mdc-chips/chip-row.html @@ -1,31 +1,37 @@ - - - + + -
-
-
+ + +
-
-
- -
-
+ + + + + + + + + + + + + -
- - - - -
+ + + diff --git a/src/material-experimental/mdc-chips/chip-row.spec.ts b/src/material-experimental/mdc-chips/chip-row.spec.ts index bad5387bc2b0..c130cda43d36 100644 --- a/src/material-experimental/mdc-chips/chip-row.spec.ts +++ b/src/material-experimental/mdc-chips/chip-row.spec.ts @@ -1,6 +1,11 @@ import {Directionality} from '@angular/cdk/bidi'; -import {BACKSPACE, DELETE, RIGHT_ARROW, ENTER} from '@angular/cdk/keycodes'; -import {createKeyboardEvent, dispatchEvent, dispatchFakeEvent} from '../../cdk/testing/private'; +import {BACKSPACE, DELETE, ENTER} from '@angular/cdk/keycodes'; +import { + createKeyboardEvent, + dispatchEvent, + dispatchFakeEvent, + dispatchKeyboardEvent, +} from '../../cdk/testing/private'; import {Component, DebugElement, ElementRef, ViewChild} from '@angular/core'; import {waitForAsync, ComponentFixture, TestBed, flush, fakeAsync} from '@angular/core/testing'; import {By} from '@angular/platform-browser'; @@ -10,7 +15,6 @@ import { MatChipEditInput, MatChipEvent, MatChipGrid, - MatChipRemove, MatChipRow, MatChipsModule, } from './index'; @@ -20,7 +24,6 @@ describe('MDC-based Row Chips', () => { let chipDebugElement: DebugElement; let chipNativeElement: HTMLElement; let chipInstance: MatChipRow; - let removeIconInstance: MatChipRemove; let dir = 'ltr'; @@ -55,9 +58,6 @@ describe('MDC-based Row Chips', () => { chipNativeElement = chipDebugElement.nativeElement; chipInstance = chipDebugElement.injector.get(MatChipRow); testComponent = fixture.debugElement.componentInstance; - - const removeIconDebugElement = fixture.debugElement.query(By.directive(MatChipRemove))!; - removeIconInstance = removeIconDebugElement.injector.get(MatChipRemove); }); describe('basic behaviors', () => { @@ -134,17 +134,6 @@ describe('MDC-based Row Chips', () => { expect(testComponent.chipRemove).toHaveBeenCalled(); }); - - it('arrow key navigation does not emit the (removed) event', () => { - const ARROW_KEY_EVENT = createKeyboardEvent('keydown', RIGHT_ARROW); - - spyOn(testComponent, 'chipRemove'); - - removeIconInstance.interaction.next(ARROW_KEY_EVENT); - fixture.detectChanges(); - - expect(testComponent.chipRemove).not.toHaveBeenCalled(); - }); }); describe('when removable is false', () => { @@ -178,12 +167,16 @@ describe('MDC-based Row Chips', () => { }); it('should update the aria-label for disabled chips', () => { - expect(chipNativeElement.getAttribute('aria-disabled')).toBe('false'); + const primaryActionElement = chipNativeElement.querySelector( + '.mdc-evolution-chip__action--primary', + )!; + + expect(primaryActionElement.getAttribute('aria-disabled')).toBe('false'); testComponent.disabled = true; fixture.detectChanges(); - expect(chipNativeElement.getAttribute('aria-disabled')).toBe('true'); + expect(primaryActionElement.getAttribute('aria-disabled')).toBe('true'); }); describe('focus management', () => { @@ -191,7 +184,7 @@ describe('MDC-based Row Chips', () => { dispatchFakeEvent(chipNativeElement, 'mousedown'); fixture.detectChanges(); - expect(document.activeElement).toHaveClass('mat-mdc-chip-row-focusable-text-content'); + expect(document.activeElement).toHaveClass('mdc-evolution-chip__action--primary'); }); it('emits focus only once for multiple focus() calls', () => { @@ -215,46 +208,46 @@ describe('MDC-based Row Chips', () => { fixture.detectChanges(); }); - it('should apply the mdc-chip--editable class', () => { - expect(chipNativeElement.classList).toContain('mdc-chip--editable'); - }); - it('should begin editing on double click', () => { + expect(chipNativeElement.querySelector('.mat-chip-edit-input')).toBeFalsy(); dispatchFakeEvent(chipNativeElement, 'dblclick'); - expect(chipNativeElement.classList).toContain('mdc-chip--editing'); + fixture.detectChanges(); + expect(chipNativeElement.querySelector('.mat-chip-edit-input')).toBeTruthy(); }); it('should begin editing on ENTER', () => { - chipInstance.focus(); - const primaryActionElement = chipNativeElement.querySelector('.mdc-chip__primary-action')!; - const enterEvent = createKeyboardEvent('keydown', ENTER, 'Enter'); - dispatchEvent(primaryActionElement, enterEvent); - expect(chipNativeElement.classList).toContain('mdc-chip--editing'); + expect(chipNativeElement.querySelector('.mat-chip-edit-input')).toBeFalsy(); + dispatchKeyboardEvent(chipNativeElement, 'keydown', ENTER); + fixture.detectChanges(); + expect(chipNativeElement.querySelector('.mat-chip-edit-input')).toBeTruthy(); }); }); describe('editing behavior', () => { let editInputInstance: MatChipEditInput; - let chipContentElement: HTMLElement; + let primaryAction: HTMLElement; - beforeEach(() => { + beforeEach(fakeAsync(() => { testComponent.editable = true; fixture.detectChanges(); dispatchFakeEvent(chipNativeElement, 'dblclick'); - spyOn(testComponent, 'chipEdit'); fixture.detectChanges(); + flush(); + spyOn(testComponent, 'chipEdit'); const editInputDebugElement = fixture.debugElement.query(By.directive(MatChipEditInput))!; editInputInstance = editInputDebugElement.injector.get(MatChipEditInput); - - const chipContentSelector = '.mat-mdc-chip-row-focusable-text-content'; - chipContentElement = chipNativeElement.querySelector(chipContentSelector) as HTMLElement; - }); + primaryAction = chipNativeElement.querySelector('.mdc-evolution-chip__action--primary')!; + })); function keyDownOnPrimaryAction(keyCode: number, key: string) { - const primaryActionElement = chipNativeElement.querySelector('.mdc-chip__primary-action')!; const keyDownEvent = createKeyboardEvent('keydown', keyCode, key); - dispatchEvent(primaryActionElement, keyDownEvent); + dispatchEvent(primaryAction, keyDownEvent); + fixture.detectChanges(); + } + + function getEditInput(): HTMLElement { + return chipNativeElement.querySelector('.mat-chip-edit-input')!; } it('should not delete the chip on DELETE or BACKSPACE', () => { @@ -264,33 +257,27 @@ describe('MDC-based Row Chips', () => { expect(testComponent.chipDestroy).not.toHaveBeenCalled(); }); - it('should ignore mousedown events', () => { - spyOn(testComponent, 'chipFocus'); - dispatchFakeEvent(chipNativeElement, 'mousedown'); - expect(testComponent.chipFocus).not.toHaveBeenCalled(); - }); - it('should stop editing on focusout', fakeAsync(() => { - const primaryActionElement = chipNativeElement.querySelector('.mdc-chip__primary-action')!; - dispatchFakeEvent(primaryActionElement, 'focusout', true); + dispatchFakeEvent(primaryAction, 'focusout', true); flush(); - expect(chipNativeElement.classList).not.toContain('mdc-chip--editing'); expect(testComponent.chipEdit).toHaveBeenCalled(); })); - it('should stop editing on ENTER', () => { - keyDownOnPrimaryAction(ENTER, 'Enter'); - expect(chipNativeElement.classList).not.toContain('mdc-chip--editing'); + it('should stop editing on ENTER', fakeAsync(() => { + dispatchKeyboardEvent(getEditInput(), 'keydown', ENTER); + fixture.detectChanges(); + flush(); expect(testComponent.chipEdit).toHaveBeenCalled(); - }); + })); - it('should emit the new chip value when editing completes', () => { + it('should emit the new chip value when editing completes', fakeAsync(() => { const chipValue = 'chip value'; editInputInstance.setValue(chipValue); - keyDownOnPrimaryAction(ENTER, 'Enter'); + dispatchKeyboardEvent(getEditInput(), 'keydown', ENTER); + flush(); const expectedValue = jasmine.objectContaining({value: chipValue}); expect(testComponent.chipEdit).toHaveBeenCalledWith(expectedValue); - }); + })); it('should use the projected edit input if provided', () => { expect(editInputInstance.getNativeElement()).toHaveClass('projected-edit-input'); @@ -308,28 +295,33 @@ describe('MDC-based Row Chips', () => { expect(editInputNoProject.getNativeElement()).not.toHaveClass('projected-edit-input'); }); - it('should focus the chip content if the edit input has focus on completion', () => { + it('should focus the chip content if the edit input has focus on completion', fakeAsync(() => { const chipValue = 'chip value'; editInputInstance.setValue(chipValue); - keyDownOnPrimaryAction(ENTER, 'Enter'); - expect(document.activeElement).toBe(chipContentElement); - }); + dispatchKeyboardEvent(getEditInput(), 'keydown', ENTER); + fixture.detectChanges(); + flush(); + expect(document.activeElement).toBe(primaryAction); + })); - it('should focus the chip content if the body has focus on completion', () => { + it('should focus the chip content if the body has focus on completion', fakeAsync(() => { const chipValue = 'chip value'; editInputInstance.setValue(chipValue); (document.activeElement as HTMLElement).blur(); - keyDownOnPrimaryAction(ENTER, 'Enter'); - expect(document.activeElement).toBe(chipContentElement); - }); + dispatchKeyboardEvent(getEditInput(), 'keydown', ENTER); + fixture.detectChanges(); + flush(); + expect(document.activeElement).toBe(primaryAction); + })); - it('should not change focus if another element has focus on completion', () => { + it('should not change focus if another element has focus on completion', fakeAsync(() => { const chipValue = 'chip value'; editInputInstance.setValue(chipValue); testComponent.chipInput.nativeElement.focus(); keyDownOnPrimaryAction(ENTER, 'Enter'); - expect(document.activeElement).not.toBe(chipContentElement); - }); + flush(); + expect(document.activeElement).not.toBe(primaryAction); + })); }); }); }); @@ -340,7 +332,7 @@ describe('MDC-based Row Chips', () => {
{{name}} @@ -361,7 +353,6 @@ class SingleChip { editable: boolean = false; useCustomEditInput: boolean = true; - chipFocus: (event?: MatChipEvent) => void = () => {}; chipDestroy: (event?: MatChipEvent) => void = () => {}; chipRemove: (event?: MatChipEvent) => void = () => {}; chipEdit: (event?: MatChipEditedEvent) => void = () => {}; diff --git a/src/material-experimental/mdc-chips/chip-row.ts b/src/material-experimental/mdc-chips/chip-row.ts index 08c57d940136..46a5308c7948 100644 --- a/src/material-experimental/mdc-chips/chip-row.ts +++ b/src/material-experimental/mdc-chips/chip-row.ts @@ -7,11 +7,11 @@ */ import {Directionality} from '@angular/cdk/bidi'; -import {BACKSPACE, DELETE} from '@angular/cdk/keycodes'; +import {BACKSPACE, DELETE, ENTER} from '@angular/cdk/keycodes'; import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations'; import { - AfterContentInit, AfterViewInit, + Attribute, ChangeDetectionStrategy, ChangeDetectorRef, Component, @@ -31,9 +31,9 @@ import { MAT_RIPPLE_GLOBAL_OPTIONS, RippleGlobalOptions, } from '@angular/material-experimental/mdc-core'; +import {FocusMonitor} from '@angular/cdk/a11y'; import {MatChip, MatChipEvent} from './chip'; import {MatChipEditInput} from './chip-edit-input'; -import {GridKeyManagerRow} from './grid-key-manager'; /** Represents an event fired on an individual `mat-chip` when it is edited. */ export interface MatChipEditedEvent extends MatChipEvent { @@ -48,23 +48,28 @@ export interface MatChipEditedEvent extends MatChipEvent { @Component({ selector: 'mat-chip-row, mat-basic-chip-row', templateUrl: 'chip-row.html', - styleUrls: ['chips.css'], + styleUrls: ['chip.css'], inputs: ['color', 'disableRipple', 'tabIndex'], host: { - 'role': 'row', - 'class': 'mat-mdc-chip-row', + 'class': 'mat-mdc-chip mat-mdc-chip-row mdc-evolution-chip', + '[class.mat-mdc-chip-with-avatar]': 'leadingIcon', '[class.mat-mdc-chip-disabled]': 'disabled', + '[class.mat-mdc-chip-editing]': '_isEditing', + '[class.mat-mdc-chip-editable]': 'editable', + '[class.mdc-evolution-chip--disabled]': 'disabled', + '[class.mdc-evolution-chip--with-trailing-action]': '_hasTrailingIcon()', + '[class.mdc-evolution-chip--with-primary-graphic]': 'leadingIcon', + '[class.mdc-evolution-chip--with-primary-icon]': 'leadingIcon', + '[class.mdc-evolution-chip--with-avatar]': 'leadingIcon', '[class.mat-mdc-chip-highlighted]': 'highlighted', - '[class.mat-mdc-chip-with-avatar]': 'leadingIcon', - '[class.mat-mdc-chip-with-trailing-icon]': 'trailingIcon || removeIcon', - '[class.mdc-chip--editable]': 'editable', + '[class.mat-mdc-chip-with-trailing-icon]': '_hasTrailingIcon()', '[id]': 'id', - '[attr.disabled]': 'disabled || null', - '[attr.aria-disabled]': 'disabled.toString()', - '[tabIndex]': 'tabIndex', + '[attr.tabindex]': 'null', + '[attr.aria-label]': 'null', + '[attr.role]': 'role', '(mousedown)': '_mousedown($event)', - '(dblclick)': '_dblclick($event)', '(keydown)': '_keydown($event)', + '(dblclick)': '_doubleclick()', '(focusin)': '_focusin($event)', '(focusout)': '_focusout($event)', }, @@ -72,10 +77,7 @@ export interface MatChipEditedEvent extends MatChipEvent { encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, }) -export class MatChipRow - extends MatChip - implements AfterContentInit, AfterViewInit, GridKeyManagerRow -{ +export class MatChipRow extends MatChip implements AfterViewInit { protected override basicChipAttrName = 'mat-basic-chip-row'; @Input() editable: boolean = false; @@ -84,20 +86,13 @@ export class MatChipRow @Output() readonly edited: EventEmitter = new EventEmitter(); - /** - * The focusable wrapper element in the first gridcell, which contains all - * chip content other than the remove icon. - */ - @ViewChild('chipContent') chipContent: ElementRef; - /** The default chip edit input that is used if none is projected into this chip row. */ @ViewChild(MatChipEditInput) defaultEditInput?: MatChipEditInput; /** The projected chip edit input. */ @ContentChild(MatChipEditInput) contentEditInput?: MatChipEditInput; - /** The focusable grid cells for this row. Implemented as part of GridKeyManagerRow. */ - cells!: HTMLElement[]; + _isEditing = false; /** * Timeout used to give some time between `focusin` and `focusout` @@ -106,100 +101,77 @@ export class MatChipRow private _focusoutTimeout: number | null; constructor( - @Inject(DOCUMENT) private readonly _document: any, changeDetectorRef: ChangeDetectorRef, elementRef: ElementRef, ngZone: NgZone, + focusMonitor: FocusMonitor, + @Inject(DOCUMENT) _document: any, @Optional() dir: Directionality, @Optional() @Inject(ANIMATION_MODULE_TYPE) animationMode?: string, @Optional() @Inject(MAT_RIPPLE_GLOBAL_OPTIONS) globalRippleOptions?: RippleGlobalOptions, + @Attribute('tabindex') tabIndex?: string, ) { - super(changeDetectorRef, elementRef, ngZone, dir, animationMode, globalRippleOptions); - } - - override ngAfterContentInit() { - super.ngAfterContentInit(); - - if (this.removeIcon) { - // Defer setting the value in order to avoid the "Expression - // has changed after it was checked" errors from Angular. - setTimeout(() => { - // removeIcon has tabIndex 0 for regular chips, but should only be focusable by - // the GridFocusKeyManager for row chips. - this.removeIcon.tabIndex = -1; - }); - } + super( + changeDetectorRef, + elementRef, + ngZone, + focusMonitor, + _document, + dir, + animationMode, + globalRippleOptions, + tabIndex, + ); + + this.role = 'row'; } - override ngAfterViewInit() { - super.ngAfterViewInit(); - this.cells = this.removeIcon - ? [this.chipContent.nativeElement, this.removeIcon._elementRef.nativeElement] - : [this.chipContent.nativeElement]; - } - - /** - * Allows for programmatic focusing of the chip. - * Sends focus to the first grid cell. The row chip element itself - * is never focused. - */ - focus(): void { - if (this.disabled) { - return; - } - - if (!this._hasFocusInternal) { - this._onFocus.next({chip: this}); - } - - this.chipContent.nativeElement.focus(); + override _hasTrailingIcon() { + // The trailing icon is hidden while editing. + return !this._isEditing && super._hasTrailingIcon(); } /** * Emits a blur event when one of the gridcells loses focus, unless focus moved * to the other gridcell. */ - _focusout(event: FocusEvent) { + _focusout() { if (this._focusoutTimeout) { clearTimeout(this._focusoutTimeout); } // Wait to see if focus moves to the other gridcell this._focusoutTimeout = window.setTimeout(() => { + if (this._isEditing) { + this._onEditFinish(); + } + this._hasFocusInternal = false; this._onBlur.next({chip: this}); - this._handleInteraction(event); }); } /** Records that the chip has focus when one of the gridcells is focused. */ - _focusin(event: FocusEvent) { + _focusin() { if (this._focusoutTimeout) { clearTimeout(this._focusoutTimeout); this._focusoutTimeout = null; } this._hasFocusInternal = true; - this._handleInteraction(event); } /** Sends focus to the first gridcell when the user clicks anywhere inside the chip. */ _mousedown(event: MouseEvent) { - if (this._isEditing()) { - return; - } + if (!this._isEditing) { + if (!this.disabled) { + this.focus(); + } - if (!this.disabled) { - this.focus(); + event.preventDefault(); } - - event.preventDefault(); - } - - _dblclick(event: MouseEvent) { - this._handleInteraction(event); } /** Handles custom key presses. */ @@ -207,44 +179,60 @@ export class MatChipRow if (this.disabled) { return; } - if (this._isEditing()) { - this._handleInteraction(event); - return; - } + switch (event.keyCode) { + case ENTER: + if (this._isEditing) { + event.preventDefault(); + // Wrap in a timeout so the timing is consistent as when it is emitted in `focusout`. + setTimeout(() => this._onEditFinish()); + } else if (this.editable) { + this._startEditing(); + } + break; case DELETE: case BACKSPACE: - // Remove the focused chip - this.remove(); - // Always prevent so page navigation does not occur - event.preventDefault(); + if (!this._isEditing) { + // Remove the focused chip + this.remove(); + // Always prevent so page navigation does not occur + event.preventDefault(); + } break; - default: - this._handleInteraction(event); } } - _isEditing() { - return this._chipFoundation.isEditing(); + _doubleclick() { + if (!this.disabled && this.editable) { + this._startEditing(); + } } - protected override _onEditStart() { + private _startEditing() { + // The value depends on the DOM so we need to extract it before we flip the flag. + const value = this.value; + + // Make the primary action non-interactive so that it doesn't + // navigate when the user presses the arrow keys while editing. + this.primaryAction.isInteractive = false; + this._isEditing = true; + // Defer initializing the input so it has time to be added to the DOM. - setTimeout(() => { - this._getEditInput().initialize(this.value); - }); + setTimeout(() => this._getEditInput().initialize(value)); } - protected override _onEditFinish() { + private _onEditFinish() { // If the edit input is still focused or focus was returned to the body after it was destroyed, // return focus to the chip contents. if ( this._document.activeElement === this._getEditInput().getNativeElement() || this._document.activeElement === this._document.body ) { - this.chipContent.nativeElement.focus(); + this.primaryAction.focus(); } this.edited.emit({chip: this, value: this._getEditInput().getValue()}); + this.primaryAction.isInteractive = true; + this._isEditing = false; } /** diff --git a/src/material-experimental/mdc-chips/chip-set.scss b/src/material-experimental/mdc-chips/chip-set.scss new file mode 100644 index 000000000000..4c4fc242066b --- /dev/null +++ b/src/material-experimental/mdc-chips/chip-set.scss @@ -0,0 +1,32 @@ +@use '@material/chips/chip-set' as mdc-chip-set; +@use '../mdc-helpers/mdc-helpers'; + +@include mdc-chip-set.core-styles($query: mdc-helpers.$mat-base-styles-query); + +// Ensures that the internal chip container spans the entire outer container width, if the +// outer container width is customized. This is used by some wrapper components in g3. +.mat-mdc-chip-set { + .mdc-evolution-chip-set__chips { + min-width: 100%; + } +} + +// Angular Material supports vertically-stacked chips, which MDC does not. +.mat-mdc-chip-set-stacked { + flex-direction: column; + align-items: flex-start; + + .mat-mdc-chip { + width: 100%; + } +} + +input.mat-mdc-chip-input { + flex: 1 0 150px; + margin-left: 8px; + + [dir='rtl'] & { + margin-left: 0; + margin-right: 8px; + } +} diff --git a/src/material-experimental/mdc-chips/chip-set.ts b/src/material-experimental/mdc-chips/chip-set.ts index ddbb16bada01..1b8787de063a 100644 --- a/src/material-experimental/mdc-chips/chip-set.ts +++ b/src/material-experimental/mdc-chips/chip-set.ts @@ -6,8 +6,9 @@ * found in the LICENSE file at https://angular.io/license */ -import {Directionality} from '@angular/cdk/bidi'; +import {LiveAnnouncer} from '@angular/cdk/a11y'; import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion'; +import {DOCUMENT} from '@angular/common'; import { AfterContentInit, AfterViewInit, @@ -16,19 +17,27 @@ import { Component, ContentChildren, ElementRef, + Inject, Input, OnDestroy, - Optional, QueryList, ViewEncapsulation, } from '@angular/core'; import {HasTabIndex, mixinTabIndex} from '@angular/material-experimental/mdc-core'; -import {deprecated} from '@material/chips'; -import {merge, Observable, Subject, Subscription} from 'rxjs'; -import {startWith, takeUntil} from 'rxjs/operators'; +import { + MDCChipSetFoundation, + MDCChipSetAdapter, + MDCChipFoundation, + MDCChipEvents, + ChipAnimationEvent, + ChipInteractionEvent, + ChipNavigationEvent, + MDCChipActionType, +} from '@material/chips'; +import {merge, Observable, Subject} from 'rxjs'; +import {startWith, switchMap, takeUntil} from 'rxjs/operators'; import {MatChip, MatChipEvent} from './chip'; - -let uid = 0; +import {emitCustomEvent} from './emit-event'; /** * Boilerplate for applying mixins to MatChipSet. @@ -47,14 +56,17 @@ const _MatChipSetMixinBase = mixinTabIndex(MatChipSetBase); */ @Component({ selector: 'mat-chip-set', - template: '', - styleUrls: ['chips.css'], + template: ` + + + + `, + styleUrls: ['chip-set.css'], host: { - 'class': 'mat-mdc-chip-set mdc-chip-set', + 'class': 'mat-mdc-chip-set mdc-evolution-chip-set', '[attr.role]': 'role', // TODO: replace this binding with use of AriaDescriber '[attr.aria-describedby]': '_ariaDescribedby || null', - '[id]': '_uid', }, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, @@ -63,15 +75,6 @@ export class MatChipSet extends _MatChipSetMixinBase implements AfterContentInit, AfterViewInit, HasTabIndex, OnDestroy { - /** Subscription to remove changes in chips. */ - private _chipRemoveSubscription: Subscription | null; - - /** Subscription to destroyed events in chips. */ - private _chipDestroyedSubscription: Subscription | null; - - /** Subscription to chip interactions. */ - private _chipInteractionSubscription: Subscription | null; - /** * When a chip is destroyed, we store the index of the destroyed chip until the chips * query list notifies about the update. This is necessary because we cannot determine an @@ -80,38 +83,61 @@ export class MatChipSet protected _lastDestroyedChipIndex: number | null = null; /** The MDC foundation containing business logic for MDC chip-set. */ - protected _chipSetFoundation: deprecated.MDCChipSetFoundation; + protected _chipSetFoundation: MDCChipSetFoundation; /** Subject that emits when the component has been destroyed. */ protected _destroyed = new Subject(); + /** Combined stream of all of the child chips' remove events. */ + get chipDestroyedChanges(): Observable { + return this._getChipStream(chip => chip.destroyed); + } + /** * Implementation of the MDC chip-set adapter interface. * These methods are called by the chip set foundation. */ - protected _chipSetAdapter: deprecated.MDCChipSetAdapter = { - hasClass: className => this._hasMdcClass(className), - // No-op. We keep track of chips via ContentChildren, which will be updated when a chip is - // removed. - removeChipAtIndex: () => {}, - // No-op for base chip set. MatChipListbox overrides the adapter to provide this method. - selectChipAtIndex: () => {}, - getIndexOfChipById: (id: string) => this._chips.toArray().findIndex(chip => chip.id === id), - focusChipPrimaryActionAtIndex: () => {}, - focusChipTrailingActionAtIndex: () => {}, - removeFocusFromChipAtIndex: () => {}, - isRTL: () => !!this._dir && this._dir.value === 'rtl', - getChipListCount: () => this._chips.length, - // TODO(mmalerba): Implement using LiveAnnouncer. - announceMessage: () => {}, + protected _chipSetAdapter: MDCChipSetAdapter = { + announceMessage: message => this._liveAnnouncer.announce(message), + emitEvent: (eventName, eventDetail) => { + emitCustomEvent(this._elementRef.nativeElement, this._document, eventName, eventDetail, true); + }, + getAttribute: name => this._elementRef.nativeElement.getAttribute(name), + getChipActionsAtIndex: index => this._chipFoundation(index)?.getActions() || [], + getChipCount: () => this._chips.length, + getChipIdAtIndex: index => this._chipFoundation(index)?.getElementID() || '', + getChipIndexById: id => { + return this._chips.toArray().findIndex(chip => chip._getFoundation().getElementID() === id); + }, + isChipFocusableAtIndex: (index, actionType) => { + return this._chipFoundation(index)?.isActionFocusable(actionType) || false; + }, + isChipSelectableAtIndex: (index, actionType) => { + return this._chipFoundation(index)?.isActionSelectable(actionType) || false; + }, + isChipSelectedAtIndex: (index, actionType) => { + return this._chipFoundation(index)?.isActionSelected(actionType) || false; + }, + removeChipAtIndex: index => this._chips.toArray()[index]?.remove(), + setChipFocusAtIndex: (index, action, behavior) => { + this._chipFoundation(index)?.setActionFocus(action, behavior); + }, + setChipSelectedAtIndex: (index, actionType, isSelected) => { + // Setting the trailing action as deselected ends up deselecting the entire chip. + // This is working as expected, but it's not something we want so we only apply the + // selected state to the primary chip. + if (actionType === MDCChipActionType.PRIMARY) { + this._chipFoundation(index)?.setActionSelected(actionType, isSelected); + } + }, + startChipAnimationAtIndex: (index, animation) => { + this._chipFoundation(index)?.startAnimation(animation); + }, }; /** The aria-describedby attribute on the chip list for improved a11y. */ _ariaDescribedby: string; - /** Uid of the chip set */ - _uid: string = `mat-mdc-chip-set-${uid++}`; - /** * Map from class to whether the class is enabled. * Enabled classes are set on the MDC chip-set div. @@ -154,21 +180,6 @@ export class MatChipSet return this._hasFocusedChip(); } - /** Combined stream of all of the child chips' remove events. */ - get chipRemoveChanges(): Observable { - return merge(...this._chips.map(chip => chip.removed)); - } - - /** Combined stream of all of the child chips' remove events. */ - get chipDestroyedChanges(): Observable { - return merge(...this._chips.map(chip => chip.destroyed)); - } - - /** Combined stream of all of the child chips' interaction events. */ - get chipInteractionChanges(): Observable { - return merge(...this._chips.map(chip => chip.interaction)); - } - /** The chips that are part of this chip set. */ @ContentChildren(MatChip, { // We need to use `descendants: true`, because Ivy will no longer match @@ -178,12 +189,17 @@ export class MatChipSet _chips: QueryList; constructor( - protected _elementRef: ElementRef, + private _liveAnnouncer: LiveAnnouncer, + @Inject(DOCUMENT) private _document: any, + protected _elementRef: ElementRef, protected _changeDetectorRef: ChangeDetectorRef, - @Optional() protected _dir: Directionality, ) { super(_elementRef); - this._chipSetFoundation = new deprecated.MDCChipSetFoundation(this._chipSetAdapter); + const element = _elementRef.nativeElement; + this._chipSetFoundation = new MDCChipSetFoundation(this._chipSetAdapter); + element.addEventListener(MDCChipEvents.ANIMATION, this._handleChipAnimation); + element.addEventListener(MDCChipEvents.INTERACTION, this._handleChipInteraction); + element.addEventListener(MDCChipEvents.NAVIGATION, this._handleChipNavigation); } ngAfterViewInit() { @@ -199,13 +215,26 @@ export class MatChipSet this._syncChipsState(); }); } + }); + + this.chipDestroyedChanges.pipe(takeUntil(this._destroyed)).subscribe((event: MatChipEvent) => { + const chip = event.chip; + const chipIndex = this._chips.toArray().indexOf(event.chip); - this._resetChips(); + // In case the chip that will be removed is currently focused, we temporarily store + // the index in order to be able to determine an appropriate sibling chip that will + // receive focus. + if (this._isValidIndex(chipIndex) && chip._hasFocus()) { + this._lastDestroyedChipIndex = chipIndex; + } }); } ngOnDestroy() { - this._dropSubscriptions(); + const element = this._elementRef.nativeElement; + element.removeEventListener(MDCChipEvents.ANIMATION, this._handleChipAnimation); + element.removeEventListener(MDCChipEvents.INTERACTION, this._handleChipInteraction); + element.removeEventListener(MDCChipEvents.NAVIGATION, this._handleChipNavigation); this._destroyed.next(); this._destroyed.complete(); this._chipSetFoundation.destroy(); @@ -226,82 +255,6 @@ export class MatChipSet } } - /** Sets whether the given CSS class should be applied to the MDC chip. */ - protected _setMdcClass(cssClass: string, active: boolean) { - const classes = this._elementRef.nativeElement.classList; - active ? classes.add(cssClass) : classes.remove(cssClass); - this._changeDetectorRef.markForCheck(); - } - - /** Adapter method that returns true if the chip set has the given MDC class. */ - protected _hasMdcClass(className: string) { - return this._elementRef.nativeElement.classList.contains(className); - } - - /** Updates subscriptions to chip events. */ - private _resetChips() { - this._dropSubscriptions(); - this._subscribeToChipEvents(); - } - - /** Subscribes to events on the child chips. */ - protected _subscribeToChipEvents() { - this._listenToChipsRemove(); - this._listenToChipsDestroyed(); - this._listenToChipsInteraction(); - } - - /** Subscribes to chip removal events. */ - private _listenToChipsRemove() { - this._chipRemoveSubscription = this.chipRemoveChanges.subscribe((event: MatChipEvent) => { - this._chipSetFoundation.handleChipRemoval({ - chipId: event.chip.id, - // TODO(mmalerba): Add removal message. - removedAnnouncement: null, - }); - }); - } - - /** Subscribes to chip destroyed events. */ - private _listenToChipsDestroyed() { - this._chipDestroyedSubscription = this.chipDestroyedChanges.subscribe((event: MatChipEvent) => { - const chip = event.chip; - const chipIndex: number = this._chips.toArray().indexOf(event.chip); - - // In case the chip that will be removed is currently focused, we temporarily store - // the index in order to be able to determine an appropriate sibling chip that will - // receive focus. - if (this._isValidIndex(chipIndex) && chip._hasFocus()) { - this._lastDestroyedChipIndex = chipIndex; - } - }); - } - - /** Subscribes to chip interaction events. */ - private _listenToChipsInteraction() { - this._chipInteractionSubscription = this.chipInteractionChanges.subscribe((id: string) => { - this._chipSetFoundation.handleChipInteraction({chipId: id}); - }); - } - - /** Unsubscribes from all chip events. */ - protected _dropSubscriptions() { - if (this._chipRemoveSubscription) { - this._chipRemoveSubscription.unsubscribe(); - this._chipRemoveSubscription = null; - } - - if (this._chipInteractionSubscription) { - this._chipInteractionSubscription.unsubscribe(); - this._chipInteractionSubscription = null; - } - - if (this._chipDestroyedSubscription) { - this._chipDestroyedSubscription.unsubscribe(); - this._chipDestroyedSubscription = null; - } - } - /** Dummy method for subclasses to override. Base chip set cannot be focused. */ focus() {} @@ -317,18 +270,41 @@ export class MatChipSet /** Checks whether an event comes from inside a chip element. */ protected _originatesFromChip(event: Event): boolean { - return this._checkForClassInHierarchy(event, 'mdc-chip'); + return this._checkForClassInHierarchy(event, 'mdc-evolution-chip'); } /** - * Checks whether an event comes from inside a chip element in the editing - * state. + * Removes the `tabindex` from the chip grid and resets it back afterwards, allowing the + * user to tab out of it. This prevents the grid from capturing focus and redirecting + * it back to the first chip, creating a focus trap, if it user tries to tab away. */ - protected _originatesFromEditingChip(event: Event): boolean { - return this._checkForClassInHierarchy(event, 'mdc-chip--editing'); + protected _allowFocusEscape() { + const previousTabIndex = this.tabIndex; + + if (this.tabIndex !== -1) { + this.tabIndex = -1; + + setTimeout(() => { + this.tabIndex = previousTabIndex; + this._changeDetectorRef.markForCheck(); + }); + } } - private _checkForClassInHierarchy(event: Event, className: string) { + /** + * Gets a stream of events from all the chips within the set. + * The stream will automatically incorporate any newly-added chips. + */ + protected _getChipStream( + mappingFunction: (chip: C) => Observable, + ): Observable { + return this._chips.changes.pipe( + startWith(null), + switchMap(() => merge(...(this._chips as QueryList).map(mappingFunction))), + ); + } + + protected _checkForClassInHierarchy(event: Event, className: string) { let currentElement = event.target as HTMLElement | null; while (currentElement && currentElement !== this._elementRef.nativeElement) { @@ -342,4 +318,20 @@ export class MatChipSet return false; } + + private _chipFoundation(index: number): MDCChipFoundation | undefined { + return this._chips.toArray()[index]?._getFoundation(); + } + + private _handleChipAnimation = (event: Event) => { + this._chipSetFoundation.handleChipAnimation(event as ChipAnimationEvent); + }; + + private _handleChipInteraction = (event: Event) => { + this._chipSetFoundation.handleChipInteraction(event as ChipInteractionEvent); + }; + + private _handleChipNavigation = (event: Event) => { + this._chipSetFoundation.handleChipNavigation(event as ChipNavigationEvent); + }; } diff --git a/src/material-experimental/mdc-chips/chip.html b/src/material-experimental/mdc-chips/chip.html index fd8b2c0278de..35283fd77ea0 100644 --- a/src/material-experimental/mdc-chips/chip.html +++ b/src/material-experimental/mdc-chips/chip.html @@ -1,12 +1,23 @@ - - + + + +
+ + + + + + + +
+
- -
-
-
- + + + diff --git a/src/material-experimental/mdc-chips/chip.scss b/src/material-experimental/mdc-chips/chip.scss new file mode 100644 index 000000000000..4fa66e348c5f --- /dev/null +++ b/src/material-experimental/mdc-chips/chip.scss @@ -0,0 +1,208 @@ +@use '@material/chips/chip' as mdc-chip; +@use '@material/chips/chip-theme' as mdc-chip-theme; +@use '../../material/core/style/layout-common'; +@use '../../cdk/a11y'; +@use '../mdc-helpers/mdc-helpers'; + +@include mdc-chip.without-ripple-styles($query: mdc-helpers.$mat-base-styles-query); + +.mat-mdc-standard-chip { + @include mdc-chip-theme.theme-styles(( + with-avatar-avatar-shape: ( + family: 'rounded', + radius: (14px, 14px, 14px, 14px) + ), + with-icon-icon-size: 18px, + with-leading-icon-disabled-leading-icon-opacity: 0.38, + with-leading-icon-leading-icon-size: 20px, + with-trailing-icon-disabled-trailing-icon-opacity: 0.38, + with-avatar-avatar-size: 28px, + with-avatar-disabled-avatar-opacity: 0.38, + with-icon-disabled-icon-opacity: 0.38, + with-trailing-icon-trailing-icon-size: 18px, + flat-disabled-outline-opacity: 0.12, + flat-disabled-unselected-outline-opacity: 0.12, + flat-selected-outline-width: 0, + outline-width: 1px, + flat-unselected-outline-width: 1px, + flat-outline-width: 1px, + disabled-label-text-opacity: 0.38, + disabled-outline-opacity: 0.12, + elevated-disabled-container-opacity: 0.12, + container-height: 32px, + container-shape: ( + family: 'rounded', + radius: (16px, 16px, 16px, 16px) + ), + )); + + @include a11y.high-contrast(active, off) { + outline: solid 1px; + + &.cdk-focused { + // Use 2px here since the dotted outline is a little thinner. + outline: dotted 2px; + } + + .mdc-evolution-chip__checkmark-path { + // SVG colors won't be changed in high contrast mode and since the checkmark is white + // by default, it'll blend in with the background in black-on-white mode. Override the + // color to ensure that it's visible. We need !important, because the theme styles are + // very specific. + stroke: #000 !important; + } + } + + // Angular Material supports disabled chips, which MDC does not. + // Dim the disabled chips and stop MDC from changing the icon color on click. + &.mdc-evolution-chip--disabled { + opacity: 0.4; + } + + // MDC sets `overflow: hidden` on these elements in order to truncate the text. This is + // unnecessary since our chips don't truncate their text and it makes it difficult to style + // the strong focus indicators so we need to override it. + .mdc-evolution-chip__cell--primary, + .mdc-evolution-chip__action--primary, + .mat-mdc-chip-action-label { + overflow: visible; + } + + // Ensures that the trailing icon is pushed to the end if the chip has a set width. + .mdc-evolution-chip__cell--primary { + width: 100%; + } + + // MDC sizes and positions this element using `width`, `height` and `padding`. + // This usually works, but it's common for apps to add `box-sizing: border-box` + // to all elements on the page which can cause the graphic to be clipped. + // Set an explicit `box-sizing` in order to avoid these issues. + .mat-mdc-chip-graphic, + .mat-mdc-chip-trailing-icon { + box-sizing: content-box; + } + + + &._mat-animation-noopable { + &, + .mdc-evolution-chip__graphic, + .mdc-evolution-chip__checkmark, + .mdc-evolution-chip__checkmark-path { + // MDC listens to `transitionend` events on some of these + // elements so we can't disable the transitions completely. + transition-duration: 1ms; + animation-duration: 1ms; + } + } +} + +// MDC's focus and hover indication is handled through their ripple which we currently +// don't use due to size concerns so we have to re-implement it ourselves. +.mat-mdc-chip-focus-overlay { + @include layout-common.fill; + pointer-events: none; + opacity: 0; + border-radius: inherit; + transition: opacity 150ms linear; + + ._mat-animation-noopable & { + transition: none; + } + + .mat-mdc-basic-chip & { + display: none; + } + + .mat-mdc-chip:hover & { + opacity: 0.04; + } + + .mat-mdc-chip.cdk-focused & { + opacity: 0.12; + } +} + +// The ripple container should match the bounds of the entire chip. +.mat-mdc-chip-ripple { + @include layout-common.fill; + + // Disable pointer events for the ripple container and state overlay because the container + // will overlay the user content and we don't want to disable mouse events on the user content. + // Pointer events can be safely disabled because the ripple trigger element is the host element. + pointer-events: none; + + // Inherit the border radius from the parent so that state overlay and ripples don't exceed the + // parent button boundaries. + border-radius: inherit; +} + +.mat-mdc-chip-avatar { + // In case an icon or text is used as an avatar. + text-align: center; + line-height: 1; +} + +// Required for the strong focus indicator to fill the chip. +.mat-mdc-chip { + position: relative; +} + +.mat-mdc-chip-action-label { + // MDC centers the text, but we have a lot of internal customers who have it at the start. + text-align: left; + + [dir='rtl'] & { + text-align: right; + } + + // When a chip has a trailing action, it'll have two focusable elements when navigating with + // the arrow keys: the primary action and the trailing one. If that's the case, we apply + // `position: relative` to the primary action container so that the indicators is only around + // the text label. This allows for it to be distinguished from the indicator on the trailing icon. + .mat-mdc-chip.mdc-evolution-chip--with-trailing-action & { + position: relative; + } + + .mat-mdc-chip-primary-focus-indicator { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + pointer-events: none; + } +} + +.mat-mdc-chip-remove { + .mat-icon { + width: inherit; + height: inherit; + font-size: inherit; + box-sizing: content-box; + } +} + +// Fades out the trailing icon slightly so that it can become darker when focused. +// The MDC theming has variables for this, but the focus/hover states don't seem to work. +.mat-mdc-chip-remove { + opacity: 0.54; + + &:focus { + opacity: 1; + } +} + +.mat-chip-edit-input { + cursor: text; + display: inline-block; + color: inherit; + outline: 0; +} + +// Single-selection chips show their selected state using a background color which won't be visible +// in high contrast mode. This isn't necessary in multi-selection since there's a checkmark. +.mat-mdc-chip-selected:not(.mat-mdc-chip-multiple) { + @include a11y.high-contrast(active, off) { + outline-width: 3px; + } +} diff --git a/src/material-experimental/mdc-chips/chip.spec.ts b/src/material-experimental/mdc-chips/chip.spec.ts index eba8e531fef8..47390203c972 100644 --- a/src/material-experimental/mdc-chips/chip.spec.ts +++ b/src/material-experimental/mdc-chips/chip.spec.ts @@ -58,19 +58,12 @@ describe('MDC-based MatChip', () => { expect(chip.getAttribute('tabindex')).toBe('3'); }); - it('should be able to set a static tabindex', () => { - fixture = TestBed.createComponent(BasicChipWithStaticTabindex); - fixture.detectChanges(); - - const chip = fixture.nativeElement.querySelector('mat-basic-chip'); - expect(chip.getAttribute('tabindex')).toBe('3'); - }); - it('should be able to set a dynamic tabindex', () => { fixture = TestBed.createComponent(BasicChipWithBoundTabindex); fixture.detectChanges(); const chip = fixture.nativeElement.querySelector('mat-basic-chip'); + expect(chip.getAttribute('tabindex')).toBe('12'); fixture.componentInstance.tabindex = 15; @@ -93,6 +86,7 @@ describe('MDC-based MatChip', () => { describe('MatChip', () => { let testComponent: SingleChip; + let primaryAction: HTMLElement; beforeEach(() => { fixture = TestBed.createComponent(SingleChip); @@ -104,6 +98,7 @@ describe('MDC-based MatChip', () => { chipRippleDebugElement = chipDebugElement.query(By.directive(MatRipple))!; chipRippleInstance = chipRippleDebugElement.injector.get(MatRipple); testComponent = fixture.debugElement.componentInstance; + primaryAction = chipNativeElement.querySelector('.mdc-evolution-chip__action--primary')!; }); it('adds the `mat-chip` class', () => { @@ -169,17 +164,10 @@ describe('MDC-based MatChip', () => { .toBe(true); }); - it('should update the aria-label for disabled chips', () => { - expect(chipNativeElement.getAttribute('aria-disabled')).toBe('false'); - + it('should make disabled chips non-focusable', () => { testComponent.disabled = true; fixture.detectChanges(); - - expect(chipNativeElement.getAttribute('aria-disabled')).toBe('true'); - }); - - it('should make disabled chips non-focusable', () => { - expect(chipNativeElement.getAttribute('tabindex')).toBeFalsy(); + expect(primaryAction.hasAttribute('tabindex')).toBe(false); }); it('should return the chip text if value is undefined', () => { @@ -236,12 +224,12 @@ class SingleChip { class BasicChip {} @Component({ - template: `Hello`, + template: `Hello`, }) class BasicChipWithStaticTabindex {} @Component({ - template: `Hello`, + template: `Hello`, }) class BasicChipWithBoundTabindex { tabindex = 12; diff --git a/src/material-experimental/mdc-chips/chip.ts b/src/material-experimental/mdc-chips/chip.ts index ecac78189c33..87af59368d6c 100644 --- a/src/material-experimental/mdc-chips/chip.ts +++ b/src/material-experimental/mdc-chips/chip.ts @@ -10,13 +10,11 @@ import {Directionality} from '@angular/cdk/bidi'; import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion'; import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations'; import { - AfterContentInit, AfterViewInit, Component, ChangeDetectionStrategy, ChangeDetectorRef, ContentChild, - Directive, ElementRef, EventEmitter, Inject, @@ -27,7 +25,9 @@ import { Output, ViewEncapsulation, ViewChild, + Attribute, } from '@angular/core'; +import {DOCUMENT} from '@angular/common'; import { CanColor, CanDisable, @@ -40,10 +40,19 @@ import { mixinTabIndex, RippleGlobalOptions, } from '@angular/material-experimental/mdc-core'; -import {deprecated} from '@material/chips'; -import {SPACE, ENTER, hasModifierKey} from '@angular/cdk/keycodes'; +import { + MDCChipFoundation, + MDCChipAdapter, + MDCChipActionType, + MDCChipActionFocusBehavior, + MDCChipActionFoundation, + MDCChipActionEvents, + ActionInteractionEvent, + ActionNavigationEvent, + MDCChipActionInteractionTrigger, +} from '@material/chips'; +import {FocusMonitor} from '@angular/cdk/a11y'; import {Subject} from 'rxjs'; -import {takeUntil} from 'rxjs/operators'; import { MatChipAvatar, MatChipTrailingIcon, @@ -52,6 +61,8 @@ import { MAT_CHIP_TRAILING_ICON, MAT_CHIP_REMOVE, } from './chip-icons'; +import {emitCustomEvent} from './emit-event'; +import {MatChipAction} from './chip-action'; let uid = 0; @@ -61,17 +72,6 @@ export interface MatChipEvent { chip: MatChip; } -/** - * Directive to add MDC CSS to non-basic chips. - * @docs-private - */ -@Directive({ - selector: `mat-chip, mat-chip-option, mat-chip-row, [mat-chip], [mat-chip-option], - [mat-chip-row]`, - host: {'class': 'mat-mdc-chip mdc-chip'}, -}) -export class MatChipCssInternalOnly {} - /** * Boilerplate for applying mixins to MatChip. * @docs-private @@ -90,37 +90,39 @@ const _MatChipMixinBase = mixinTabIndex(mixinColor(mixinDisableRipple(MatChipBas */ @Component({ selector: 'mat-basic-chip, mat-chip', - inputs: ['color', 'disableRipple'], + inputs: ['color', 'disableRipple', 'tabIndex'], exportAs: 'matChip', templateUrl: 'chip.html', - styleUrls: ['chips.css'], + styleUrls: ['chip.css'], host: { - '[class.mat-mdc-chip-disabled]': 'disabled', - '[class.mat-mdc-chip-highlighted]': 'highlighted', + 'class': 'mat-mdc-chip', + '[class.mdc-evolution-chip]': '!_isBasicChip', + '[class.mdc-evolution-chip--disabled]': 'disabled', + '[class.mdc-evolution-chip--with-trailing-action]': '_hasTrailingIcon()', + '[class.mdc-evolution-chip--with-primary-graphic]': 'leadingIcon', + '[class.mdc-evolution-chip--with-primary-icon]': 'leadingIcon', + '[class.mdc-evolution-chip--with-avatar]': 'leadingIcon', '[class.mat-mdc-chip-with-avatar]': 'leadingIcon', - '[class.mat-mdc-chip-with-trailing-icon]': 'trailingIcon || removeIcon', + '[class.mat-mdc-chip-highlighted]': 'highlighted', + '[class.mat-mdc-chip-disabled]': 'disabled', '[class.mat-mdc-basic-chip]': '_isBasicChip', '[class.mat-mdc-standard-chip]': '!_isBasicChip', + '[class.mat-mdc-chip-with-trailing-icon]': '_hasTrailingIcon()', '[class._mat-animation-noopable]': '_animationsDisabled', '[id]': 'id', - '[attr.disabled]': 'disabled || null', - '[attr.aria-disabled]': 'disabled.toString()', - '(transitionend)': '_handleTransitionEnd($event)', + '[attr.role]': 'role', + '[attr.tabindex]': 'role ? tabIndex : null', + '[attr.aria-label]': 'ariaLabel', }, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, }) export class MatChip extends _MatChipMixinBase - implements - AfterContentInit, - AfterViewInit, - CanColor, - CanDisableRipple, - CanDisable, - HasTabIndex, - OnDestroy + implements AfterViewInit, CanColor, CanDisableRipple, CanDisable, HasTabIndex, OnDestroy { + protected _document: Document; + /** Whether the ripple is centered on the chip. */ readonly _isRippleCentered = false; @@ -130,30 +132,30 @@ export class MatChip /** Emits when the chip is blurred. */ readonly _onBlur = new Subject(); - readonly REMOVE_ICON_HANDLED_KEYS: ReadonlySet = new Set([SPACE, ENTER]); - /** Whether this chip is a basic (unstyled) chip. */ readonly _isBasicChip: boolean; + /** Role for the root of the chip. */ + @Input() role: string | null = null; + /** Whether the chip has focus. */ protected _hasFocusInternal = false; + /** Whether moving focus into the chip is pending. */ + private _pendingFocus: boolean; + /** Whether animations for the chip are enabled. */ _animationsDisabled: boolean; - _handleTransitionEnd(event: TransitionEvent) { - this._chipFoundation.handleTransitionEnd(event); - } - _hasFocus() { return this._hasFocusInternal; } - /** Default unique id for the chip. */ - private _uniqueId = `mat-mdc-chip-${uid++}`; - /** A unique id for the chip. If none is supplied, it will be auto-generated. */ - @Input() id: string = this._uniqueId; + @Input() id: string = `mat-mdc-chip-${uid++}`; + + /** ARIA label for the content of the chip. */ + @Input('aria-label') ariaLabel: string | null = null; @Input() get disabled(): boolean { @@ -161,15 +163,21 @@ export class MatChip } set disabled(value: BooleanInput) { this._disabled = coerceBooleanProperty(value); + if (this.removeIcon) { this.removeIcon.disabled = this._disabled; } + + this._chipFoundation.setDisabled(this._disabled); } protected _disabled: boolean = false; private _textElement!: HTMLElement; - /** The value of the chip. Defaults to the content inside the mdc-chip__text element. */ + /** + * The value of the chip. Defaults to the content inside + * the `mat-mdc-chip-action-label` element. + */ @Input() get value(): any { return this._value !== undefined ? this._value : this._textElement.textContent!.trim(); @@ -203,17 +211,14 @@ export class MatChip } protected _highlighted: boolean = false; - /** Emitted when the user interacts with the chip. */ - @Output() readonly interaction = new EventEmitter(); + /** Emitted when a chip is to be removed. */ + @Output() readonly removed: EventEmitter = new EventEmitter(); /** Emitted when the chip is destroyed. */ @Output() readonly destroyed: EventEmitter = new EventEmitter(); - /** Emitted when a chip is to be removed. */ - @Output() readonly removed: EventEmitter = new EventEmitter(); - /** The MDC foundation containing business logic for MDC chip. */ - _chipFoundation: deprecated.MDCChipFoundation; + _chipFoundation: MDCChipFoundation; /** The unstyled chip selector for this component. */ protected basicChipAttrName = 'mat-basic-chip'; @@ -230,151 +235,118 @@ export class MatChip /** Reference to the MatRipple instance of the chip. */ @ViewChild(MatRipple) ripple: MatRipple; + /** Action receiving the primary set of user interactions. */ + @ViewChild(MatChipAction) primaryAction: MatChipAction; + /** * Implementation of the MDC chip adapter interface. * These methods are called by the chip foundation. */ - protected _chipAdapter: deprecated.MDCChipAdapter = { + protected _chipAdapter: MDCChipAdapter = { addClass: className => this._setMdcClass(className, true), removeClass: className => this._setMdcClass(className, false), hasClass: className => this._elementRef.nativeElement.classList.contains(className), - addClassToLeadingIcon: className => this.leadingIcon.setClass(className, true), - removeClassFromLeadingIcon: className => this.leadingIcon.setClass(className, false), - eventTargetHasClass: (target: EventTarget | null, className: string) => { - // We need to null check the `classList`, because IE and Edge don't - // support it on SVG elements and Edge seems to throw for ripple - // elements, because they're outside the DOM. - return target && (target as Element).classList - ? (target as Element).classList.contains(className) - : false; + emitEvent: (eventName: string, data: T) => { + emitCustomEvent(this._elementRef.nativeElement, this._document, eventName, data, true); }, - notifyInteraction: () => this._notifyInteraction(), - notifySelection: () => { - // No-op. We call dispatchSelectionEvent ourselves in MatChipOption, - // because we want to specify whether selection occurred via user - // input. + setStyleProperty: (propertyName: string, value: string) => { + this._elementRef.nativeElement.style.setProperty(propertyName, value); }, - notifyNavigation: () => this._notifyNavigation(), - notifyTrailingIconInteraction: () => {}, - notifyRemoval: () => this.remove(), - notifyEditStart: () => { - this._onEditStart(); - this._changeDetectorRef.markForCheck(); + isRTL: () => this._dir?.value === 'rtl', + getAttribute: attributeName => this._elementRef.nativeElement.getAttribute(attributeName), + getElementID: () => this._elementRef.nativeElement.id, + getOffsetWidth: () => this._elementRef.nativeElement.offsetWidth, + getActions: () => { + const result: MDCChipActionType[] = []; + + if (this._getAction(MDCChipActionType.PRIMARY)) { + result.push(MDCChipActionType.PRIMARY); + } + + if (this._getAction(MDCChipActionType.TRAILING)) { + result.push(MDCChipActionType.TRAILING); + } + + return result; }, - notifyEditFinish: () => { - this._onEditFinish(); - this._changeDetectorRef.markForCheck(); + isActionSelectable: (action: MDCChipActionType) => { + return this._getAction(action)?.isSelectable() || false; }, - getComputedStyleValue: propertyName => { - // This function is run when a chip is removed so it might be - // invoked during server-side rendering. Add some extra checks just in - // case. - if (typeof window !== 'undefined' && window) { - const getComputedStyle = window.getComputedStyle(this._elementRef.nativeElement); - return getComputedStyle.getPropertyValue(propertyName); - } - return ''; + isActionSelected: (action: MDCChipActionType) => { + return this._getAction(action)?.isSelected() || false; }, - setStyleProperty: (propertyName: string, value: string) => { - this._elementRef.nativeElement.style.setProperty(propertyName, value); + isActionDisabled: (action: MDCChipActionType) => { + return this._getAction(action)?.isDisabled() || false; }, - hasLeadingIcon: () => !!this.leadingIcon, - isTrailingActionNavigable: () => { - if (this.trailingIcon) { - return this.trailingIcon.isNavigable(); - } - return false; + isActionFocusable: (action: MDCChipActionType) => { + return this._getAction(action)?.isFocusable() || false; }, - isRTL: () => !!this._dir && this._dir.value === 'rtl', - focusPrimaryAction: () => { - // Angular Material MDC chips fully manage focus. TODO: Managing focus - // and handling keyboard events was added by MDC after our - // implementation; consider consolidating. + setActionSelected: (action: MDCChipActionType, isSelected: boolean) => { + this._getAction(action)?.setSelected(isSelected); }, - focusTrailingAction: () => {}, - removeTrailingActionFocus: () => {}, - setPrimaryActionAttr: (name: string, value: string) => { - // MDC is currently using this method to set aria-checked on choice - // and filter chips, which in the MDC templates have role="checkbox" - // and role="radio" respectively. We have role="option" on those chips - // instead, so we do not want aria-checked. Since we also manage the - // tabindex ourselves, we don't allow MDC to set it. - if (name === 'aria-checked' || name === 'tabindex') { - return; - } - this._elementRef.nativeElement.setAttribute(name, value); + setActionDisabled: (action: MDCChipActionType, isDisabled: boolean) => { + this._getAction(action)?.setDisabled(isDisabled); + }, + setActionFocus: (action: MDCChipActionType, behavior: MDCChipActionFocusBehavior) => { + this._getAction(action)?.setFocus(behavior); }, - // The 2 functions below are used by the MDC ripple, which we aren't using, - // so they will never be called - getRootBoundingClientRect: () => this._elementRef.nativeElement.getBoundingClientRect(), - getCheckmarkBoundingClientRect: () => null, - getAttribute: attr => this._elementRef.nativeElement.getAttribute(attr), }; constructor( public _changeDetectorRef: ChangeDetectorRef, - elementRef: ElementRef, + elementRef: ElementRef, protected _ngZone: NgZone, + private _focusMonitor: FocusMonitor, + @Inject(DOCUMENT) _document: any, @Optional() private _dir: Directionality, @Optional() @Inject(ANIMATION_MODULE_TYPE) animationMode?: string, @Optional() @Inject(MAT_RIPPLE_GLOBAL_OPTIONS) private _globalRippleOptions?: RippleGlobalOptions, + @Attribute('tabindex') tabIndex?: string, ) { super(elementRef); - this._chipFoundation = new deprecated.MDCChipFoundation(this._chipAdapter); + const element = elementRef.nativeElement; + this._document = _document; + this._chipFoundation = new MDCChipFoundation(this._chipAdapter); this._animationsDisabled = animationMode === 'NoopAnimations'; this._isBasicChip = - elementRef.nativeElement.hasAttribute(this.basicChipAttrName) || - elementRef.nativeElement.tagName.toLowerCase() === this.basicChipAttrName; - } - - ngAfterContentInit() { - this._initRemoveIcon(); + element.hasAttribute(this.basicChipAttrName) || + element.tagName.toLowerCase() === this.basicChipAttrName; + element.addEventListener(MDCChipActionEvents.INTERACTION, this._handleActionInteraction); + element.addEventListener(MDCChipActionEvents.NAVIGATION, this._handleActionNavigation); + _focusMonitor.monitor(elementRef, true); + + _ngZone.runOutsideAngular(() => { + element.addEventListener('transitionend', this._handleTransitionend); + element.addEventListener('animationend', this._handleAnimationend); + }); + + if (tabIndex != null) { + this.tabIndex = parseInt(tabIndex) ?? this.defaultTabIndex; + } } ngAfterViewInit() { this._chipFoundation.init(); - this._textElement = this._elementRef.nativeElement.querySelector('.mdc-chip__text'); + this._chipFoundation.setDisabled(this.disabled); + this._textElement = this._elementRef.nativeElement.querySelector('.mat-mdc-chip-action-label'); + + if (this._pendingFocus) { + this._pendingFocus = false; + this.focus(); + } } ngOnDestroy() { - this.destroyed.emit({chip: this}); + const element = this._elementRef.nativeElement; + element.removeEventListener(MDCChipActionEvents.INTERACTION, this._handleActionInteraction); + element.removeEventListener(MDCChipActionEvents.NAVIGATION, this._handleActionNavigation); + element.removeEventListener('transitionend', this._handleTransitionend); + element.removeEventListener('animationend', this._handleAnimationend); this._chipFoundation.destroy(); - } - - /** Sets up the remove icon chip foundation, and subscribes to remove icon events. */ - private _initRemoveIcon() { - if (this.removeIcon) { - this._chipFoundation.setShouldRemoveOnTrailingIconClick(true); - this.removeIcon.disabled = this.disabled; - - this.removeIcon.interaction.pipe(takeUntil(this.destroyed)).subscribe(event => { - // The MDC chip foundation calls stopPropagation() for any trailing icon interaction - // event, even ones it doesn't handle, so we want to avoid passing it keyboard events - // for which we have a custom handler. Note that we assert the type of the event using - // the `type`, because `instanceof KeyboardEvent` can throw during server-side rendering. - const isKeyboardEvent = event.type.startsWith('key'); - - if ( - this.disabled || - (isKeyboardEvent && !this.REMOVE_ICON_HANDLED_KEYS.has((event as KeyboardEvent).keyCode)) - ) { - return; - } - - this.remove(); - - if (isKeyboardEvent && !hasModifierKey(event as KeyboardEvent)) { - const keyCode = (event as KeyboardEvent).keyCode; - - // Prevent default space and enter presses so we don't scroll the page or submit forms. - if (keyCode === SPACE || keyCode === ENTER) { - event.preventDefault(); - } - } - }); - } + this._focusMonitor.stopMonitoring(this._elementRef); + this.destroyed.emit({chip: this}); } /** @@ -395,58 +367,98 @@ export class MatChip this._changeDetectorRef.markForCheck(); } - /** Forwards interaction events to the MDC chip foundation. */ - _handleInteraction(event: MouseEvent | KeyboardEvent | FocusEvent) { - if (this.disabled) { - return; - } + /** Whether or not the ripple should be disabled. */ + _isRippleDisabled(): boolean { + return ( + this.disabled || + this.disableRipple || + this._animationsDisabled || + this._isBasicChip || + !!this._globalRippleOptions?.disabled + ); + } - if (event.type === 'click') { - this._chipFoundation.handleClick(); - return; + _getAction(type: MDCChipActionType): MDCChipActionFoundation | undefined { + switch (type) { + case MDCChipActionType.PRIMARY: + return this.primaryAction?._getFoundation(); + case MDCChipActionType.TRAILING: + return (this.removeIcon || this.trailingIcon)?._getFoundation(); } - if (event.type === 'dblclick') { - this._chipFoundation.handleDoubleClick(); - } + return undefined; + } + + _getFoundation() { + return this._chipFoundation; + } - if (event.type === 'keydown') { - this._chipFoundation.handleKeydown(event as KeyboardEvent); + _hasTrailingIcon() { + return !!(this.trailingIcon || this.removeIcon); + } + + /** Allows for programmatic focusing of the chip. */ + focus(): void { + if (this.disabled) { return; } - if (event.type === 'focusout') { - this._chipFoundation.handleFocusOut(event as FocusEvent); + // If `focus` is called before `ngAfterViewInit`, we won't have access to the primary action. + // This can happen if the consumer tries to focus a chip immediately after it is added. + // Queue the method to be called again on init. + if (!this.primaryAction) { + this._pendingFocus = true; + return; } - if (event.type === 'focusin') { - this._chipFoundation.handleFocusIn(event as FocusEvent); + if (!this._hasFocus()) { + this._onFocus.next({chip: this}); + this._hasFocusInternal = true; } - } - /** Whether or not the ripple should be disabled. */ - _isRippleDisabled(): boolean { - return ( - this.disabled || - this.disableRipple || - this._animationsDisabled || - this._isBasicChip || - !!this._globalRippleOptions?.disabled - ); + this.primaryAction.focus(); } - _notifyInteraction() { - this.interaction.emit(this.id); + /** Overridden by MatChipOption. */ + protected _onChipInteraction(event: ActionInteractionEvent) { + const removeElement = this.removeIcon?._elementRef.nativeElement; + const trigger = event.detail.trigger; + + // MDC's removal process requires an `animationend` event followed by a `transitionend` + // event coming from the chip, which in turn will call `remove`. While we can stub + // out these events in our own tests, they can be difficult to fake for consumers that are + // testing our components or are wrapping them. We skip the entire sequence and trigger the + // removal directly in order to make the component easier to deal with. + if ( + removeElement && + (trigger === MDCChipActionInteractionTrigger.CLICK || + trigger === MDCChipActionInteractionTrigger.ENTER_KEY || + trigger === MDCChipActionInteractionTrigger.SPACEBAR_KEY) && + (event.target === removeElement || removeElement.contains(event.target)) + ) { + this.remove(); + } else { + this._chipFoundation.handleActionInteraction(event); + } } - _notifyNavigation() { - // TODO: This is a new feature added by MDC. Consider exposing it to users - // in the future. - } + private _handleActionInteraction = (event: Event) => { + this._onChipInteraction(event as ActionInteractionEvent); + }; - /** Overridden by MatChipRow. */ - protected _onEditStart() {} + private _handleActionNavigation = (event: Event) => { + this._chipFoundation.handleActionNavigation(event as ActionNavigationEvent); + }; - /** Overridden by MatChipRow. */ - protected _onEditFinish() {} + private _handleTransitionend = (event: TransitionEvent) => { + if (event.target === this._elementRef.nativeElement) { + this._ngZone.run(() => this._chipFoundation.handleTransitionEnd()); + } + }; + + private _handleAnimationend = (event: AnimationEvent) => { + if (event.target === this._elementRef.nativeElement) { + this._ngZone.run(() => this._chipFoundation.handleAnimationEnd(event)); + } + }; } diff --git a/src/material-experimental/mdc-chips/chips.scss b/src/material-experimental/mdc-chips/chips.scss deleted file mode 100644 index a54134b604a3..000000000000 --- a/src/material-experimental/mdc-chips/chips.scss +++ /dev/null @@ -1,184 +0,0 @@ -@use '@material/chips/deprecated' as mdc-chips; -@use '@material/ripple' as mdc-ripple; -@use '../../material/core/style/layout-common'; -@use '../../cdk/a11y'; -@use '../mdc-helpers/mdc-helpers'; - -@include mdc-chips.without-ripple($query: mdc-helpers.$mat-base-styles-query); -@include mdc-chips.set-core-styles($query: mdc-helpers.$mat-base-styles-query); - -.mat-mdc-chip { - // MDC uses a pointer cursor - cursor: default; - - &._mat-animation-noopable { - animation: none; - transition: none; - - .mdc-chip__checkmark-svg { - transition: none; - } - } - - @include a11y.high-contrast(active, off) { - outline: solid 1px; - - &:focus { - // Use 2px here since the dotted outline is a little thinner. - outline: dotted 2px; - } - } -} - -// The ripple container should match the bounds of the entire chip. -.mat-mdc-chip-ripple { - @include layout-common.fill; - - // Disable pointer events for the ripple container and state overlay because the container - // will overlay the user content and we don't want to disable mouse events on the user content. - // Pointer events can be safely disabled because the ripple trigger element is the host element. - pointer-events: none; - - // Inherit the border radius from the parent so that state overlay and ripples don't exceed the - // parent button boundaries. - border-radius: inherit; -} - -// The MDC chip styles related to hover and focus states are intertwined with the MDC ripple styles. -// We currently don't use the MDC ripple due to size concerns, therefore we need to add some -// additional styles to restore these states. -.mdc-chip__ripple { - @include mdc-ripple.target-common($query: structure); - - &::after, &::before { - @include layout-common.fill; - content: ''; - pointer-events: none; - opacity: 0; - border-radius: inherit; - - ._mat-animation-noopable & { - transition: none; - } - } -} - -// Angular Material supports disabled chips, which MDC does not. -// Dim the disabled chips and stop MDC from changing the icon color on click. -.mat-mdc-chip-disabled.mat-mdc-chip { - opacity: 0.4; - - .mat-mdc-chip-trailing-icon, .mat-mdc-chip-row-focusable-text-content { - pointer-events: none; - } - - // Do not show state interactions for disabled chips. - .mdc-chip__ripple::after, .mdc-chip__ripple::before { - display: none; - } -} - -// Angular Material supports vertically-stacked chips, which MDC does not. -.mat-mdc-chip-set-stacked { - flex-direction: column; - align-items: flex-start; - - .mat-mdc-chip { - width: 100%; - } -} - -// Add styles for the matChipInputFor input element. -$mat-chip-input-width: 150px; - -input.mat-mdc-chip-input { - flex: 1 0 $mat-chip-input-width; -} - -// The margin value is set in MDC. -$chip-margin: 4px; - -// Don't let the chip margin increase the mat-form-field height. -.mat-mdc-chip-grid { - margin: -$chip-margin; - - // Keep the mat-chip-grid height the same even when there are no chips. - input.mat-mdc-chip-input { - margin: $chip-margin; - } -} - -.mdc-chip__checkmark-path { - ._mat-animation-noopable & { - transition: none; - } - - @include a11y.high-contrast(black-on-white, off) { - // SVG colors won't be changed in high contrast mode and since the checkmark is white - // by default, it'll blend in with the background in black-on-white mode. Override the color - // to ensure that it's visible. We need !important, because the theme styles are very specific. - stroke: #000 !important; - } -} - -// Needed for the focus indicator. -.mat-mdc-chip-row-focusable-text-content { - position: relative; -} - -.mat-mdc-chip-remove { - // Reset the user agent styles in case a button is used. - border: none; - -webkit-appearance: none; - -moz-appearance: none; - padding: 0; - background: none; - - .mat-icon { - width: inherit; - height: inherit; - font-size: inherit; - } -} - -// Single-selection chips show their selected state using a background color which won't be visible -// in high contrast mode. This isn't necessary in multi-selection since there's a checkmark. -.mat-mdc-chip-selected:not(.mat-mdc-chip-multiple) { - @include a11y.high-contrast(active, off) { - outline-width: 3px; - } -} - -.mat-mdc-chip-row-focusable-text-content, -.mat-mdc-chip-remove-icon { - display: flex; - align-items: center; -} - -.mat-mdc-chip-content { - display: inline-flex; -} - -.mdc-chip--editing { - background-color: transparent; - display: flex; - flex-direction: column; - - .mat-mdc-chip-content { - pointer-events: none; - height: 0; - overflow: hidden; - } -} - -.mat-chip-edit-input { - cursor: text; - display: inline-block; -} - -.mat-mdc-chip-edit-input-container { - width: 100%; - height: 100%; - display: flex; - align-items: center; -} diff --git a/src/material-experimental/mdc-chips/emit-event.ts b/src/material-experimental/mdc-chips/emit-event.ts new file mode 100644 index 000000000000..b208b6d3f0d8 --- /dev/null +++ b/src/material-experimental/mdc-chips/emit-event.ts @@ -0,0 +1,33 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +/** + * Emits a custom event from an element. + * @param element Element from which to emit the event. + * @param _document Document that the element is placed in. + * @param eventName Name of the event. + * @param data Data attached to the event. + * @param shouldBubble Whether the event should bubble. + */ +export function emitCustomEvent( + element: HTMLElement, + _document: Document, + eventName: string, + data: T, + shouldBubble: boolean, +): void { + let event: CustomEvent; + if (typeof CustomEvent === 'function') { + event = new CustomEvent(eventName, {bubbles: shouldBubble, detail: data}); + } else { + event = _document.createEvent('CustomEvent'); + event.initCustomEvent(eventName, shouldBubble, false, data); + } + + element.dispatchEvent(event); +} diff --git a/src/material-experimental/mdc-chips/grid-focus-key-manager.ts b/src/material-experimental/mdc-chips/grid-focus-key-manager.ts deleted file mode 100644 index 40aa6d2280ba..000000000000 --- a/src/material-experimental/mdc-chips/grid-focus-key-manager.ts +++ /dev/null @@ -1,36 +0,0 @@ -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ - -import {GridKeyManager} from './grid-key-manager'; - -/** - * A version of GridKeyManager where the cells are HTMLElements, and focus() - * is called on a cell when it becomes active. - */ -export class GridFocusKeyManager extends GridKeyManager { - /** - * Sets the active cell to the cell at the specified - * indices and focuses the newly active cell. - * @param cell Row and column indices of the cell to be set as active. - */ - override setActiveCell(cell: {row: number; column: number}): void; - - /** - * Sets the active cell to the cell that is specified and focuses it. - * @param cell Cell to be set as active. - */ - override setActiveCell(cell: HTMLElement): void; - - override setActiveCell(cell: any): void { - super.setActiveCell(cell); - - if (this.activeCell) { - this.activeCell.focus(); - } - } -} diff --git a/src/material-experimental/mdc-chips/grid-key-manager.ts b/src/material-experimental/mdc-chips/grid-key-manager.ts deleted file mode 100644 index d956d2f05b91..000000000000 --- a/src/material-experimental/mdc-chips/grid-key-manager.ts +++ /dev/null @@ -1,285 +0,0 @@ -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ - -import {QueryList} from '@angular/core'; -import {Subject} from 'rxjs'; -import {UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW, HOME, END} from '@angular/cdk/keycodes'; - -/** The keys handled by the GridKeyManager keydown method. */ -export const NAVIGATION_KEYS = [DOWN_ARROW, UP_ARROW, RIGHT_ARROW, LEFT_ARROW]; - -/** This interface is for rows that can be passed to a GridKeyManager. */ -export interface GridKeyManagerRow { - cells: T[]; -} - -/** - * This class manages keyboard events for grids. If you pass it a query list - * of GridKeyManagerRow, it will set the active cell correctly when arrow events occur. - * - * GridKeyManager expects that rows may change dynamically, but the cells for a given row are - * static. It also expects that all rows have the same number of cells. - */ -export class GridKeyManager { - private _activeRowIndex = -1; - private _activeColumnIndex = -1; - private _activeRow: GridKeyManagerRow | null = null; - private _activeCell: T | null = null; - private _dir: 'ltr' | 'rtl' = 'ltr'; - private _homeAndEnd = false; - - constructor(private _rows: QueryList> | GridKeyManagerRow[]) { - // We allow for the rows to be an array because, in some cases, the consumer may - // not have access to a QueryList of the rows they want to manage (e.g. when the - // rows aren't being collected via `ViewChildren` or `ContentChildren`). - if (_rows instanceof QueryList) { - _rows.changes.subscribe((newRows: QueryList>) => { - if (this._activeRow) { - const newIndex = newRows.toArray().indexOf(this._activeRow); - - if (newIndex > -1 && newIndex !== this._activeRowIndex) { - this._activeRowIndex = newIndex; - } - } - }); - } - } - - /** Stream that emits whenever the active cell of the grid manager changes. */ - change = new Subject<{row: number; column: number}>(); - - /** - * Configures the directionality of the key manager's horizontal movement. - * @param direction Direction which is considered forward movement across a row. - * - * If withDirectionality is not set, the default is 'ltr'. - */ - withDirectionality(direction: 'ltr' | 'rtl'): this { - this._dir = direction; - return this; - } - - /** - * Sets the active cell to the cell at the indices specified. - * @param cell The row and column containing the cell to be set as active. - */ - setActiveCell(cell: {row: number; column: number}): void; - - /** - * Sets the active cell to the cell. - * @param cell The cell to be set as active. - */ - setActiveCell(cell: T): void; - - setActiveCell(cell: any): void { - const previousRowIndex = this._activeRowIndex; - const previousColumnIndex = this._activeColumnIndex; - - this.updateActiveCell(cell); - - if ( - this._activeRowIndex !== previousRowIndex || - this._activeColumnIndex !== previousColumnIndex - ) { - this.change.next({row: this._activeRowIndex, column: this._activeColumnIndex}); - } - } - - /** - * Configures the key manager to activate the first and last items - * respectively when the Home or End key is pressed. - * @param enabled Whether pressing the Home or End key activates the first/last item. - */ - withHomeAndEnd(enabled: boolean = true): this { - this._homeAndEnd = enabled; - return this; - } - - /** - * Sets the active cell depending on the key event passed in. - * @param event Keyboard event to be used for determining which element should be active. - */ - onKeydown(event: KeyboardEvent): void { - const keyCode = event.keyCode; - - switch (keyCode) { - case DOWN_ARROW: - this.setNextRowActive(); - break; - - case UP_ARROW: - this.setPreviousRowActive(); - break; - - case RIGHT_ARROW: - this._dir === 'rtl' ? this.setPreviousColumnActive() : this.setNextColumnActive(); - break; - - case LEFT_ARROW: - this._dir === 'rtl' ? this.setNextColumnActive() : this.setPreviousColumnActive(); - break; - - case HOME: - if (this._homeAndEnd) { - this.setFirstCellActive(); - break; - } else { - return; - } - - case END: - if (this._homeAndEnd) { - this.setLastCellActive(); - break; - } else { - return; - } - - default: - // Note that we return here, in order to avoid preventing - // the default action of non-navigational keys. - return; - } - - event.preventDefault(); - } - - /** Index of the currently active row. */ - get activeRowIndex(): number { - return this._activeRowIndex; - } - - /** Index of the currently active column. */ - get activeColumnIndex(): number { - return this._activeColumnIndex; - } - - /** The active cell. */ - get activeCell(): T | null { - return this._activeCell; - } - - /** Sets the active cell to the first cell in the grid. */ - setFirstCellActive(): void { - this._setActiveCellByIndex(0, 0); - } - - /** Sets the active cell to the last cell in the grid. */ - setLastCellActive(): void { - const lastRowIndex = this._rows.length - 1; - const lastRow = this._getRowsArray()[lastRowIndex]; - this._setActiveCellByIndex(lastRowIndex, lastRow.cells.length - 1); - } - - /** Sets the active row to the next row in the grid. Active column is unchanged. */ - setNextRowActive(): void { - this._activeRowIndex < 0 ? this.setFirstCellActive() : this._setActiveCellByDelta(1, 0); - } - - /** Sets the active row to the previous row in the grid. Active column is unchanged. */ - setPreviousRowActive(): void { - this._setActiveCellByDelta(-1, 0); - } - - /** - * Sets the active column to the next column in the grid. - * Active row is unchanged, unless we reach the end of a row. - */ - setNextColumnActive(): void { - this._activeRowIndex < 0 ? this.setFirstCellActive() : this._setActiveCellByDelta(0, 1); - } - - /** - * Sets the active column to the previous column in the grid. - * Active row is unchanged, unless we reach the end of a row. - */ - setPreviousColumnActive(): void { - this._setActiveCellByDelta(0, -1); - } - - /** - * Allows setting the active cell without any other effects. - * @param cell Row and column of the cell to be set as active. - */ - updateActiveCell(cell: {row: number; column: number}): void; - - /** - * Allows setting the active cell without any other effects. - * @param cell Cell to be set as active. - */ - updateActiveCell(cell: T): void; - - updateActiveCell(cell: any): void { - const rowArray = this._getRowsArray(); - - if ( - typeof cell === 'object' && - typeof cell.row === 'number' && - typeof cell.column === 'number' - ) { - this._activeRowIndex = cell.row; - this._activeColumnIndex = cell.column; - this._activeRow = rowArray[cell.row] || null; - this._activeCell = this._activeRow ? this._activeRow.cells[cell.column] || null : null; - } else { - rowArray.forEach((row, rowIndex) => { - const columnIndex = row.cells.indexOf(cell); - if (columnIndex !== -1) { - this._activeRowIndex = rowIndex; - this._activeColumnIndex = columnIndex; - this._activeRow = row; - this._activeCell = row.cells[columnIndex]; - } - }); - } - } - - /** - * This method sets the active cell, given the row and columns deltas - * between the currently active cell and the new active cell. - */ - private _setActiveCellByDelta(rowDelta: -1 | 0 | 1, columnDelta: -1 | 0 | 1): void { - // If delta puts us past the last cell in a row, move to the first cell of the next row. - if (this._activeRow && this._activeColumnIndex + columnDelta >= this._activeRow.cells.length) { - this._setActiveCellByIndex(this._activeRowIndex + 1, 0); - - // If delta puts us prior to the first cell in a row, move to the last cell of the previous row. - } else if (this._activeColumnIndex + columnDelta < 0) { - const previousRowIndex = this._activeRowIndex - 1; - const previousRow = this._getRowsArray()[previousRowIndex]; - if (previousRow) { - this._setActiveCellByIndex(previousRowIndex, previousRow.cells.length - 1); - } - } else { - this._setActiveCellByIndex( - this._activeRowIndex + rowDelta, - this._activeColumnIndex + columnDelta, - ); - } - } - - /** - * Sets the active cell to the cell at the indices specified, if they are valid. - */ - private _setActiveCellByIndex(rowIndex: number, columnIndex: number): void { - const rows = this._getRowsArray(); - - const targetRow = rows[rowIndex]; - - if (!targetRow || !targetRow.cells[columnIndex]) { - return; - } - - this.setActiveCell({row: rowIndex, column: columnIndex}); - } - - /** Returns the rows as an array. */ - private _getRowsArray(): GridKeyManagerRow[] { - return this._rows instanceof QueryList ? this._rows.toArray() : this._rows; - } -} diff --git a/src/material-experimental/mdc-chips/module.ts b/src/material-experimental/mdc-chips/module.ts index 7ce8256d6caf..ace98686a98e 100644 --- a/src/material-experimental/mdc-chips/module.ts +++ b/src/material-experimental/mdc-chips/module.ts @@ -14,7 +14,7 @@ import { MatCommonModule, MatRippleModule, } from '@angular/material-experimental/mdc-core'; -import {MatChip, MatChipCssInternalOnly} from './chip'; +import {MatChip} from './chip'; import {MAT_CHIPS_DEFAULT_OPTIONS, MatChipsDefaultOptions} from './chip-default-options'; import {MatChipEditInput} from './chip-edit-input'; import {MatChipGrid} from './chip-grid'; @@ -24,11 +24,11 @@ import {MatChipListbox} from './chip-listbox'; import {MatChipRow} from './chip-row'; import {MatChipOption} from './chip-option'; import {MatChipSet} from './chip-set'; +import {MatChipAction} from './chip-action'; const CHIP_DECLARATIONS = [ MatChip, MatChipAvatar, - MatChipCssInternalOnly, MatChipEditInput, MatChipGrid, MatChipInput, @@ -43,7 +43,7 @@ const CHIP_DECLARATIONS = [ @NgModule({ imports: [MatCommonModule, CommonModule, MatRippleModule], exports: [MatCommonModule, CHIP_DECLARATIONS], - declarations: CHIP_DECLARATIONS, + declarations: [MatChipAction, CHIP_DECLARATIONS], providers: [ ErrorStateMatcher, { diff --git a/src/material-experimental/mdc-chips/testing/chip-harness.ts b/src/material-experimental/mdc-chips/testing/chip-harness.ts index 735a5ac40aac..fa880ca782ba 100644 --- a/src/material-experimental/mdc-chips/testing/chip-harness.ts +++ b/src/material-experimental/mdc-chips/testing/chip-harness.ts @@ -17,6 +17,8 @@ import {MatChipRemoveHarness} from './chip-remove-harness'; /** Harness for interacting with a mat-chip in tests. */ export class MatChipHarness extends ContentContainerComponentHarness { + protected _primaryAction = this.locatorFor('.mdc-evolution-chip__action--primary'); + static hostSelector = '.mat-mdc-basic-chip, .mat-mdc-chip'; /** diff --git a/src/material-experimental/mdc-chips/testing/chip-option-harness.ts b/src/material-experimental/mdc-chips/testing/chip-option-harness.ts index c3e73e3485bb..8005a3c7573e 100644 --- a/src/material-experimental/mdc-chips/testing/chip-option-harness.ts +++ b/src/material-experimental/mdc-chips/testing/chip-option-harness.ts @@ -56,6 +56,6 @@ export class MatChipOptionHarness extends MatChipHarness { /** Toggles the selected state of the given chip. */ async toggle(): Promise { - return (await this.host()).sendKeys(' '); + return (await this._primaryAction()).click(); } } diff --git a/src/material-experimental/mdc-chips/testing/chip-row-harness.spec.ts b/src/material-experimental/mdc-chips/testing/chip-row-harness.spec.ts index 67ee6f528ef7..4a497932ad04 100644 --- a/src/material-experimental/mdc-chips/testing/chip-row-harness.spec.ts +++ b/src/material-experimental/mdc-chips/testing/chip-row-harness.spec.ts @@ -24,15 +24,25 @@ describe('MatChipRowHarness', () => { const harnesses = await loader.getAllHarnesses(MatChipRowHarness); expect(harnesses.length).toBe(2); }); + + it('should get whether the chip is editable', async () => { + const harness = await loader.getHarness(MatChipRowHarness); + expect(await harness.isEditable()).toBe(false); + + fixture.componentInstance.editable = true; + expect(await harness.isEditable()).toBe(true); + }); }); @Component({ template: ` - Basic Chip Row - Chip Row + Basic Chip Row + Chip Row `, }) -class ChipRowHarnessTest {} +class ChipRowHarnessTest { + editable = false; +} diff --git a/src/material-experimental/mdc-chips/testing/chip-row-harness.ts b/src/material-experimental/mdc-chips/testing/chip-row-harness.ts index 216d068847c5..39ed349bd5fe 100644 --- a/src/material-experimental/mdc-chips/testing/chip-row-harness.ts +++ b/src/material-experimental/mdc-chips/testing/chip-row-harness.ts @@ -10,6 +10,8 @@ import {HarnessPredicate} from '@angular/cdk/testing'; import {ChipRowHarnessFilters} from './chip-harness-filters'; import {MatChipHarness} from './chip-harness'; +// TODO(crisbeto): add harness for the chip edit input inside the row. + /** Harness for interacting with a mat-chip-row in tests. */ export class MatChipRowHarness extends MatChipHarness { static override hostSelector = '.mat-mdc-chip-row'; @@ -27,4 +29,14 @@ export class MatChipRowHarness extends MatChipHarness { InstanceType >; } + + /** Whether the chip is editable. */ + async isEditable(): Promise { + return (await this.host()).hasClass('mat-mdc-chip-editable'); + } + + /** Whether the chip is currently being edited. */ + async isEditing(): Promise { + return (await this.host()).hasClass('mat-mdc-chip-editing'); + } } diff --git a/src/material-experimental/mdc-core/option/_option-theme.scss b/src/material-experimental/mdc-core/option/_option-theme.scss index 93ca9f354e73..a178ba4e16cd 100644 --- a/src/material-experimental/mdc-core/option/_option-theme.scss +++ b/src/material-experimental/mdc-core/option/_option-theme.scss @@ -55,9 +55,9 @@ theming.get-typography-config($config-or-theme)); @include mdc-helpers.mat-using-mdc-typography($config) { - // MDC uses the `subtitle1` level for list items, but the spec shows `body1` as the correct - // level. Class is repeated for increased specificity. - .mat-mdc-option .mdc-list-item__primary-text { + // MDC uses the `subtitle1` level for list items, but + // the spec shows `body1` as the correct level. + .mat-mdc-option { @include mdc-typography.typography(body1, $query: mdc-helpers.$mat-typography-styles-query); } } diff --git a/src/material-experimental/mdc-core/option/option.scss b/src/material-experimental/mdc-core/option/option.scss index cedca159fef5..3c7fe08a9478 100644 --- a/src/material-experimental/mdc-core/option/option.scss +++ b/src/material-experimental/mdc-core/option/option.scss @@ -66,10 +66,21 @@ pointer-events: none; } - // Needs to be overwritten explicitly, because the style can + // Needs to be overwritten explicitly, because the style can // leak in from the list and cause the text to truncate. .mdc-list-item__primary-text { white-space: normal; + + // MDC assigns the typography to this element, rather than the option itself, which will break + // existing overrides. Set all of the typography-related properties to `inherit` so that any + // styles set on the host can propagate down. + font-size: inherit; + font-weight: inherit; + letter-spacing: inherit; + line-height: inherit; + font-family: inherit; + text-decoration: inherit; + text-transform: inherit; } } diff --git a/src/material-experimental/mdc-core/option/option.ts b/src/material-experimental/mdc-core/option/option.ts index 09166c785261..b4af3be36056 100644 --- a/src/material-experimental/mdc-core/option/option.ts +++ b/src/material-experimental/mdc-core/option/option.ts @@ -48,7 +48,7 @@ import {MatOptgroup} from './optgroup'; encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, }) -export class MatOption extends _MatOptionBase { +export class MatOption extends _MatOptionBase { constructor( element: ElementRef, changeDetectorRef: ChangeDetectorRef, diff --git a/src/material-experimental/mdc-form-field/_form-field-subscript.scss b/src/material-experimental/mdc-form-field/_form-field-subscript.scss index 4eaa74f2cb2d..57528e11c16f 100644 --- a/src/material-experimental/mdc-form-field/_form-field-subscript.scss +++ b/src/material-experimental/mdc-form-field/_form-field-subscript.scss @@ -23,12 +23,23 @@ padding: 0 mdc-textfield-variables.$padding-horizontal; } + .mat-mdc-form-field-subscript-dynamic-size { + .mat-mdc-form-field-hint-wrapper, + .mat-mdc-form-field-error-wrapper { + position: static; + } + } + .mat-mdc-form-field-bottom-align::before { content: ''; display: inline-block; height: 16px; } + .mat-mdc-form-field-bottom-align.mat-mdc-form-field-subscript-dynamic-size::before { + content: unset; + } + .mat-mdc-form-field-hint-end { order: 1; } diff --git a/src/material-experimental/mdc-form-field/form-field.html b/src/material-experimental/mdc-form-field/form-field.html index 8dde556e1776..b04dae1bc91e 100644 --- a/src/material-experimental/mdc-form-field/form-field.html +++ b/src/material-experimental/mdc-form-field/form-field.html @@ -71,6 +71,7 @@
diff --git a/src/material-experimental/mdc-form-field/form-field.scss b/src/material-experimental/mdc-form-field/form-field.scss index e1b573d8aea3..aea1b18d7b95 100644 --- a/src/material-experimental/mdc-form-field/form-field.scss +++ b/src/material-experimental/mdc-form-field/form-field.scss @@ -87,6 +87,9 @@ .mat-mdc-form-field-icon-suffix { & > .mat-icon { padding: 12px; + // It's common for apps to apply `box-sizing: border-box` + // globally which will break the alignment. + box-sizing: content-box; } } diff --git a/src/material-experimental/mdc-form-field/form-field.ts b/src/material-experimental/mdc-form-field/form-field.ts index 2efd38383c73..fa4d7a3ec2eb 100644 --- a/src/material-experimental/mdc-form-field/form-field.ts +++ b/src/material-experimental/mdc-form-field/form-field.ts @@ -61,6 +61,9 @@ export type FloatLabelType = 'always' | 'auto'; /** Possible appearance styles for the form field. */ export type MatFormFieldAppearance = 'fill' | 'outline'; +/** Behaviors for how the subscript height is set. */ +export type SubscriptSizing = 'fixed' | 'dynamic'; + /** * Represents the default options for the form field that can be configured * using the `MAT_FORM_FIELD_DEFAULT_OPTIONS` injection token. @@ -69,6 +72,7 @@ export interface MatFormFieldDefaultOptions { appearance?: MatFormFieldAppearance; hideRequiredMarker?: boolean; floatLabel?: FloatLabelType; + subscriptSizing?: SubscriptSizing; } /** @@ -87,6 +91,9 @@ const DEFAULT_APPEARANCE: MatFormFieldAppearance = 'fill'; /** Default appearance used by the form-field. */ const DEFAULT_FLOAT_LABEL: FloatLabelType = 'auto'; +/** Default way that the subscript element height is set. */ +const DEFAULT_SUBSCRIPT_SIZING: SubscriptSizing = 'fixed'; + /** * Default transform for docked floating labels in a MDC text-field. This value has been * extracted from the MDC text-field styles because we programmatically modify the docked @@ -206,6 +213,20 @@ export class MatFormField } private _appearance: MatFormFieldAppearance = DEFAULT_APPEARANCE; + /** + * Whether the form field should reserve space for one line of hint/error text (default) + * or to have the spacing grow from 0px as needed based on the size of the hint/error content. + * Note that when using dynamic sizing, layout shifts will occur when hint/error text changes. + */ + @Input() + get subscriptSizing(): SubscriptSizing { + return this._subscriptSizing || this._defaults?.subscriptSizing || DEFAULT_SUBSCRIPT_SIZING; + } + set subscriptSizing(value: SubscriptSizing) { + this._subscriptSizing = value || this._defaults?.subscriptSizing || DEFAULT_SUBSCRIPT_SIZING; + } + private _subscriptSizing: SubscriptSizing | null = null; + /** Text for the form field hint. */ @Input() get hintLabel(): string { diff --git a/src/material-experimental/mdc-helpers/_focus-indicators.scss b/src/material-experimental/mdc-helpers/_focus-indicators.scss index 4189d3486265..e30dfcc9303b 100644 --- a/src/material-experimental/mdc-helpers/_focus-indicators.scss +++ b/src/material-experimental/mdc-helpers/_focus-indicators.scss @@ -28,6 +28,10 @@ pointer-events: none; border: $border-width $border-style transparent; border-radius: $border-radius; + + .cdk-high-contrast-active & { + display: none; + } } // By default, all focus indicators are flush with the bounding box of their @@ -38,7 +42,7 @@ .mat-mdc-unelevated-button .mat-mdc-focus-indicator::before, .mat-mdc-raised-button .mat-mdc-focus-indicator::before, .mdc-fab .mat-mdc-focus-indicator::before, - .mat-mdc-focus-indicator.mdc-chip::before { + .mat-mdc-chip-action-label .mat-mdc-focus-indicator::before { margin: -($border-width + 2px); } @@ -46,11 +50,16 @@ margin: -($border-width + 3px); } - .mat-mdc-focus-indicator.mat-mdc-chip-remove::before, - .mat-mdc-focus-indicator.mat-mdc-chip-row-focusable-text-content::before { + .mat-mdc-focus-indicator.mat-mdc-chip-remove::before { margin: -$border-width; } + // MDC sets a padding a on the button which stretches out the focus indicator. + .mat-mdc-focus-indicator.mat-mdc-chip-remove::before { + left: 8px; + right: 8px; + } + .mat-mdc-focus-indicator.mat-mdc-tab::before, .mat-mdc-focus-indicator.mat-mdc-tab-link::before { margin: 5px; @@ -74,6 +83,9 @@ .mat-mdc-slide-toggle-focused .mat-mdc-focus-indicator::before, .mat-mdc-radio-button.cdk-focused .mat-mdc-focus-indicator::before, + // In the chips the individual actions have focus so we target a different element. + .mat-mdc-chip-action:focus .mat-mdc-focus-indicator::before, + // For buttons and list items, render the focus indicator when the parent // button or list item is focused. .mat-mdc-button-base:focus .mat-mdc-focus-indicator::before, diff --git a/src/material-experimental/mdc-input/input.spec.ts b/src/material-experimental/mdc-input/input.spec.ts index db72cfd45405..bb30b65e3eb2 100644 --- a/src/material-experimental/mdc-input/input.spec.ts +++ b/src/material-experimental/mdc-input/input.spec.ts @@ -32,6 +32,7 @@ import { MatFormField, MatFormFieldAppearance, MatFormFieldModule, + SubscriptSizing, } from '@angular/material-experimental/mdc-form-field'; import {MatIconModule} from '@angular/material/icon'; import {By} from '@angular/platform-browser'; @@ -1406,6 +1407,66 @@ describe('MatFormField default options', () => { expect(fixture.componentInstance.formField.hideRequiredMarker).toBe(true); expect(fixture.componentInstance.formField.appearance).toBe('outline'); }); + + it('defaults subscriptSizing to false', () => { + const fixture = createComponent(MatInputWithSubscriptSizing); + fixture.detectChanges(); + + const subscriptElement = fixture.nativeElement.querySelector( + '.mat-mdc-form-field-subscript-wrapper', + ); + + expect(fixture.componentInstance.formField.subscriptSizing).toBe('fixed'); + expect(subscriptElement.classList.contains('mat-mdc-form-field-subscript-dynamic-size')).toBe( + false, + ); + + fixture.componentInstance.sizing = 'dynamic'; + fixture.detectChanges(); + + expect(fixture.componentInstance.formField.subscriptSizing).toBe('dynamic'); + expect(subscriptElement.classList.contains('mat-mdc-form-field-subscript-dynamic-size')).toBe( + true, + ); + }); + + it('changes the default value of subscriptSizing (undefined input)', () => { + const fixture = createComponent(MatInputWithSubscriptSizing, [ + { + provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, + useValue: { + subscriptSizing: 'dynamic', + }, + }, + ]); + + fixture.detectChanges(); + expect(fixture.componentInstance.formField.subscriptSizing).toBe('dynamic'); + expect( + fixture.nativeElement + .querySelector('.mat-mdc-form-field-subscript-wrapper') + .classList.contains('mat-mdc-form-field-subscript-dynamic-size'), + ).toBe(true); + }); + + it('changes the default value of subscriptSizing (no input)', () => { + const fixture = createComponent(MatInputWithAppearance, [ + { + provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, + useValue: { + subscriptSizing: 'dynamic', + }, + }, + ]); + + fixture.detectChanges(); + expect(fixture.componentInstance.formField.subscriptSizing).toBe('dynamic'); + expect( + fixture.nativeElement + .querySelector('.mat-mdc-form-field-subscript-wrapper') + .classList.contains('mat-mdc-form-field-subscript-dynamic-size'), + ).toBe(true); + }); }); function configureTestingModule( @@ -1815,6 +1876,19 @@ class MatInputWithAppearance { appearance: MatFormFieldAppearance; } +@Component({ + template: ` + + My Label + + + `, +}) +class MatInputWithSubscriptSizing { + @ViewChild(MatFormField) formField: MatFormField; + sizing: SubscriptSizing; +} + @Component({ template: ` diff --git a/src/material-experimental/mdc-input/input.ts b/src/material-experimental/mdc-input/input.ts index 6bc4dc5248b7..1fe47f04914f 100644 --- a/src/material-experimental/mdc-input/input.ts +++ b/src/material-experimental/mdc-input/input.ts @@ -37,6 +37,7 @@ import {MatInput as BaseMatInput} from '@angular/material/input'; '[id]': 'id', '[disabled]': 'disabled', '[required]': 'required', + '[attr.name]': 'name', '[attr.placeholder]': 'placeholder', '[attr.readonly]': 'readonly && !_isNativeSelect || null', // Only mark the input as invalid for assistive technology if it has a value since the diff --git a/src/material-experimental/mdc-list/_list-option-theme.scss b/src/material-experimental/mdc-list/_list-option-theme.scss index cef9b98d85fc..7a6ccdcee09f 100644 --- a/src/material-experimental/mdc-list/_list-option-theme.scss +++ b/src/material-experimental/mdc-list/_list-option-theme.scss @@ -1,14 +1,14 @@ @use '@material/checkbox' as mdc-checkbox; -@use '../mdc-checkbox/checkbox-theme'; +@use '../mdc-checkbox/checkbox-private'; @use '../mdc-helpers/mdc-helpers'; @use './list-option-trailing-avatar-compat'; // Mixin that overrides the selected item and checkbox colors for list options. By // default, the MDC list uses the `primary` color for list items. The MDC checkbox // inside list options by default uses the `primary` color too. -@mixin private-list-option-color-override($color, $mdcColor) { +@mixin private-list-option-color-override($color, $mdc-color) { & .mdc-list-item__start, & .mdc-list-item__end { - @include checkbox-theme.private-checkbox-styles-with-color($color, $mdcColor); + @include checkbox-private.private-checkbox-styles-with-color($color, $mdc-color); } } diff --git a/src/material-experimental/mdc-list/_list-option-trailing-avatar-compat.scss b/src/material-experimental/mdc-list/_list-option-trailing-avatar-compat.scss index 24c84560b408..1a26a351bb0c 100644 --- a/src/material-experimental/mdc-list/_list-option-trailing-avatar-compat.scss +++ b/src/material-experimental/mdc-list/_list-option-trailing-avatar-compat.scss @@ -3,6 +3,7 @@ @use '@material/density/functions' as density-functions; @use '@material/list/evolution-mixins' as mdc-list; @use '@material/list/evolution-variables' as mdc-list-variables; +@use '../mdc-helpers/mdc-helpers'; // For compatibility with the non-MDC selection list, we support avatars that are // shown at the end of the list option. This is not supported by the MDC list as the @@ -15,19 +16,21 @@ @mixin core-styles($query) { $feat-structure: feature-targeting.create-target($query, structure); - .mat-mdc-list-option-with-trailing-avatar { - @include mdc-list.item-end-spacing(16px, $query: $query); - @include mdc-list.item-end-size(40px, $query: $query); + @include mdc-helpers.disable-fallback-declarations { + .mat-mdc-list-option-with-trailing-avatar { + @include mdc-list.item-end-spacing(16px, $query: $query); + @include mdc-list.item-end-size(40px, $query: $query); - &.mdc-list-item--with-two-lines { - .mdc-list-item__primary-text { - @include typography.text-baseline($top: 32px, $bottom: 20px, $query: $query); + &.mdc-list-item--with-two-lines { + .mdc-list-item__primary-text { + @include typography.text-baseline($top: 32px, $bottom: 20px, $query: $query); + } } - } - .mdc-list-item__end { - @include feature-targeting.targets($feat-structure) { - border-radius: 50%; + .mdc-list-item__end { + @include feature-targeting.targets($feat-structure) { + border-radius: 50%; + } } } } @@ -46,8 +49,10 @@ $property-name: height, ); - .mat-mdc-list-option-with-trailing-avatar { - @include mdc-list.one-line-item-height($one-line-tall-height); - @include mdc-list.two-line-item-height($two-line-tall-height); + @include mdc-helpers.disable-fallback-declarations { + .mat-mdc-list-option-with-trailing-avatar { + @include mdc-list.one-line-item-height($one-line-tall-height); + @include mdc-list.two-line-item-height($two-line-tall-height); + } } } diff --git a/src/material-experimental/mdc-list/_list-theme.scss b/src/material-experimental/mdc-list/_list-theme.scss index b8d6048d8650..95469ff47000 100644 --- a/src/material-experimental/mdc-list/_list-theme.scss +++ b/src/material-experimental/mdc-list/_list-theme.scss @@ -16,11 +16,10 @@ $accent: theming.get-color-from-palette(map.get($config, accent)); $warn: theming.get-color-from-palette(map.get($config, warn)); - // MDC's state styles are tied in with their ripple. Since we don't use the MDC - // ripple, we need to add the hover, focus and selected states manually. - @include interactive-list-theme.private-interactive-list-item-state-colors($config); - @include mdc-helpers.mat-using-mdc-theme($config) { + // MDC's state styles are tied in with their ripple. Since we don't use the MDC + // ripple, we need to add the hover, focus and selected states manually. + @include interactive-list-theme.private-interactive-list-item-state-colors($config); @include mdc-list.without-ripple($query: mdc-helpers.$mat-theme-styles-query); .mat-mdc-list-option { @@ -38,13 +37,15 @@ @mixin density($config-or-theme) { $density-scale: theming.get-density-config($config-or-theme); - .mat-mdc-list-item { - @include mdc-list.one-line-item-density($density-scale); - @include mdc-list.two-line-item-density($density-scale); - @include mdc-list.three-line-item-density($density-scale); - } + @include mdc-helpers.disable-fallback-declarations { + .mat-mdc-list-item { + @include mdc-list.one-line-item-density($density-scale); + @include mdc-list.two-line-item-density($density-scale); + @include mdc-list.three-line-item-density($density-scale); + } - @include list-option-theme.private-list-option-density-styles($density-scale); + @include list-option-theme.private-list-option-density-styles($density-scale); + } } @mixin typography($config-or-theme) { diff --git a/src/material-experimental/mdc-list/list-option.scss b/src/material-experimental/mdc-list/list-option.scss index 1a3f93841125..351a92dc04fa 100644 --- a/src/material-experimental/mdc-list/list-option.scss +++ b/src/material-experimental/mdc-list/list-option.scss @@ -1,9 +1,11 @@ -@use '@material/checkbox' as mdc-checkbox; +@use 'sass:map'; +@use '@material/checkbox/checkbox' as mdc-checkbox; @use '@material/list/evolution-variables' as mdc-list-variables; @use '@material/checkbox/checkbox-theme' as mdc-checkbox-theme; @use '../mdc-helpers/mdc-helpers'; @use '../../cdk/a11y'; @use './list-option-trailing-avatar-compat'; +@use '../mdc-checkbox/checkbox-private'; // For compatibility with the non-MDC list, we support avatars that are shown at the end // of the list option. We create a class similar to MDC's `--trailing-icon` one. @@ -12,19 +14,31 @@ .mat-mdc-list-option { // The MDC-based list-option uses the MDC checkbox for the selection indicators. // We need to ensure that the checkbox styles are not included for the list-option. - @include mdc-checkbox.without-ripple( - $query: mdc-helpers.$mat-base-styles-without-animation-query); + @include mdc-helpers.disable-fallback-declarations { + @include mdc-checkbox.static-styles( + $query: mdc-helpers.$mat-base-styles-without-animation-query); - &:not(._mat-animation-noopable) { - @include mdc-checkbox.without-ripple($query: animation); + &:not(._mat-animation-noopable) { + @include mdc-checkbox.static-styles($query: animation); + } } // We can't use the MDC checkbox here directly, because this checkbox is purely // decorative and including the MDC one will bring in unnecessary JS. .mdc-checkbox { + $config: map.merge(checkbox-private.$private-checkbox-theme-config, ( + // Since this checkbox isn't interactive, we can exclude the focus/hover/press styles. + selected-focus-icon-color: null, + selected-hover-icon-color: null, + selected-pressed-icon-color: null, + unselected-focus-icon-color: null, + unselected-hover-icon-color: null, + unselected-pressed-icon-color: null, + )); + // MDC theme styles also include structural styles so we have to include the theme at least // once here. The values will be overwritten by our own theme file afterwards. - @include mdc-checkbox-theme.theme-styles(mdc-checkbox-theme.$light-theme); + @include mdc-checkbox-theme.theme-styles($config); } // The internal checkbox is purely decorative, but because it's an `input`, the user can still diff --git a/src/material-experimental/mdc-list/list.scss b/src/material-experimental/mdc-list/list.scss index 039dc1c320a4..c31bf6888ce9 100644 --- a/src/material-experimental/mdc-list/list.scss +++ b/src/material-experimental/mdc-list/list.scss @@ -2,7 +2,9 @@ @use '../mdc-helpers/mdc-helpers'; @use '../../material/core/style/layout-common'; -@include mdc-list.without-ripple($query: mdc-helpers.$mat-base-styles-query); +@include mdc-helpers.disable-fallback-declarations { + @include mdc-list.without-ripple($query: mdc-helpers.$mat-base-styles-query); +} // MDC expects the list element to be a `
-
{ expect(trigger.textContent).not.toContain('Pizza'); })); + + it('should sync up the form control value with the component value', fakeAsync(() => { + const fixture = TestBed.createComponent(BasicSelectOnPushPreselected); + fixture.detectChanges(); + flush(); + + expect(fixture.componentInstance.control.value).toBe('pizza-1'); + expect(fixture.componentInstance.select.value).toBe('pizza-1'); + })); }); describe('with custom trigger', () => { @@ -4439,6 +4448,7 @@ class BasicSelectOnPush { `, }) class BasicSelectOnPushPreselected { + @ViewChild(MatSelect) select: MatSelect; foods: any[] = [ {value: 'steak-0', viewValue: 'Steak'}, {value: 'pizza-1', viewValue: 'Pizza'}, diff --git a/src/material-experimental/mdc-snack-bar/module.ts b/src/material-experimental/mdc-snack-bar/module.ts index 8c655c815b3d..d23f44380300 100644 --- a/src/material-experimental/mdc-snack-bar/module.ts +++ b/src/material-experimental/mdc-snack-bar/module.ts @@ -13,7 +13,7 @@ import {NgModule} from '@angular/core'; import {MatButtonModule} from '@angular/material-experimental/mdc-button'; import {MatCommonModule} from '@angular/material-experimental/mdc-core'; -import {MatSimpleSnackBar} from './simple-snack-bar'; +import {SimpleSnackBar} from './simple-snack-bar'; import {MatSnackBarContainer} from './snack-bar-container'; import {MatSnackBarAction, MatSnackBarActions, MatSnackBarLabel} from './snack-bar-content'; @@ -27,7 +27,7 @@ import {MatSnackBarAction, MatSnackBarActions, MatSnackBarLabel} from './snack-b MatSnackBarAction, ], declarations: [ - MatSimpleSnackBar, + SimpleSnackBar, MatSnackBarContainer, MatSnackBarLabel, MatSnackBarActions, diff --git a/src/material-experimental/mdc-snack-bar/public-api.ts b/src/material-experimental/mdc-snack-bar/public-api.ts index 923632a13d18..6f0656d33079 100644 --- a/src/material-experimental/mdc-snack-bar/public-api.ts +++ b/src/material-experimental/mdc-snack-bar/public-api.ts @@ -16,7 +16,6 @@ export { MatSnackBarConfig, MatSnackBarDismiss, MatSnackBarRef, - SimpleSnackBar, MAT_SNACK_BAR_DATA, MAT_SNACK_BAR_DEFAULT_OPTIONS, MAT_SNACK_BAR_DEFAULT_OPTIONS_FACTORY, diff --git a/src/material-experimental/mdc-snack-bar/simple-snack-bar.ts b/src/material-experimental/mdc-snack-bar/simple-snack-bar.ts index 0c5ff0ed55c4..38235d685090 100644 --- a/src/material-experimental/mdc-snack-bar/simple-snack-bar.ts +++ b/src/material-experimental/mdc-snack-bar/simple-snack-bar.ts @@ -7,15 +7,10 @@ */ import {ChangeDetectionStrategy, Component, Inject, ViewEncapsulation} from '@angular/core'; -import { - MAT_SNACK_BAR_DATA, - TextOnlySnackBar, - MatSnackBarRef, - SimpleSnackBar, -} from '@angular/material/snack-bar'; +import {MAT_SNACK_BAR_DATA, TextOnlySnackBar, MatSnackBarRef} from '@angular/material/snack-bar'; @Component({ - selector: 'mat-simple-snack-bar', + selector: 'simple-snack-bar', templateUrl: 'simple-snack-bar.html', styleUrls: ['simple-snack-bar.css'], exportAs: 'matSnackBar', @@ -25,7 +20,7 @@ import { 'class': 'mat-mdc-simple-snack-bar', }, }) -export class MatSimpleSnackBar implements TextOnlySnackBar { +export class SimpleSnackBar implements TextOnlySnackBar { constructor( public snackBarRef: MatSnackBarRef, @Inject(MAT_SNACK_BAR_DATA) public data: {message: string; action: string}, diff --git a/src/material-experimental/mdc-snack-bar/snack-bar.spec.ts b/src/material-experimental/mdc-snack-bar/snack-bar.spec.ts index b8fedddde6c7..d682b03804a8 100644 --- a/src/material-experimental/mdc-snack-bar/snack-bar.spec.ts +++ b/src/material-experimental/mdc-snack-bar/snack-bar.spec.ts @@ -14,7 +14,7 @@ import {NoopAnimationsModule} from '@angular/platform-browser/animations'; import { MAT_SNACK_BAR_DATA, MAT_SNACK_BAR_DEFAULT_OPTIONS, - MatSimpleSnackBar, + SimpleSnackBar, MatSnackBar, MatSnackBarConfig, MatSnackBarContainer, @@ -239,7 +239,7 @@ describe('MatSnackBar', () => { viewContainerFixture.detectChanges(); - expect(snackBarRef.instance instanceof MatSimpleSnackBar) + expect(snackBarRef.instance instanceof SimpleSnackBar) .withContext('Expected the snack bar content component to be SimpleSnackBar') .toBe(true); expect(snackBarRef.instance.snackBarRef) @@ -266,7 +266,7 @@ describe('MatSnackBar', () => { viewContainerFixture.detectChanges(); - expect(snackBarRef.instance instanceof MatSimpleSnackBar) + expect(snackBarRef.instance instanceof SimpleSnackBar) .withContext('Expected the snack bar content component to be SimpleSnackBar') .toBe(true); expect(snackBarRef.instance.snackBarRef) diff --git a/src/material-experimental/mdc-snack-bar/snack-bar.ts b/src/material-experimental/mdc-snack-bar/snack-bar.ts index 0dc7d550d101..4ac117696244 100644 --- a/src/material-experimental/mdc-snack-bar/snack-bar.ts +++ b/src/material-experimental/mdc-snack-bar/snack-bar.ts @@ -6,18 +6,36 @@ * found in the LICENSE file at https://angular.io/license */ -import {Injectable} from '@angular/core'; -import {MatSnackBar as BaseMatSnackBar} from '@angular/material/snack-bar'; +import {LiveAnnouncer} from '@angular/cdk/a11y'; +import {BreakpointObserver} from '@angular/cdk/layout'; +import {Overlay} from '@angular/cdk/overlay'; +import {Inject, Injectable, Injector, Optional, SkipSelf} from '@angular/core'; +import { + MatSnackBarConfig, + MAT_SNACK_BAR_DEFAULT_OPTIONS, + _MatSnackBarBase, +} from '@angular/material/snack-bar'; import {MatSnackBarModule} from './module'; -import {MatSimpleSnackBar} from './simple-snack-bar'; +import {SimpleSnackBar} from './simple-snack-bar'; import {MatSnackBarContainer} from './snack-bar-container'; /** * Service to dispatch Material Design snack bar messages. */ @Injectable({providedIn: MatSnackBarModule}) -export class MatSnackBar extends BaseMatSnackBar { - protected override simpleSnackBarComponent = MatSimpleSnackBar; +export class MatSnackBar extends _MatSnackBarBase { + protected override simpleSnackBarComponent = SimpleSnackBar; protected override snackBarContainerComponent = MatSnackBarContainer; protected override handsetCssClass = 'mat-mdc-snack-bar-handset'; + + constructor( + overlay: Overlay, + live: LiveAnnouncer, + injector: Injector, + breakpointObserver: BreakpointObserver, + @Optional() @SkipSelf() parentSnackBar: MatSnackBar, + @Inject(MAT_SNACK_BAR_DEFAULT_OPTIONS) defaultConfig: MatSnackBarConfig, + ) { + super(overlay, live, injector, breakpointObserver, parentSnackBar, defaultConfig); + } } diff --git a/src/material-experimental/mdc-snack-bar/testing/snack-bar-harness.spec.ts b/src/material-experimental/mdc-snack-bar/testing/snack-bar-harness.spec.ts index c301c9ad05bf..06d5e8ca8ede 100644 --- a/src/material-experimental/mdc-snack-bar/testing/snack-bar-harness.spec.ts +++ b/src/material-experimental/mdc-snack-bar/testing/snack-bar-harness.spec.ts @@ -12,7 +12,7 @@ import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed'; import {Component, TemplateRef, ViewChild} from '@angular/core'; describe('MDC-based MatSnackBarHarness', () => { - runHarnessTests(MatSnackBarModule, MatSnackBar, MatSnackBarHarness as any); + runHarnessTests(MatSnackBarModule, MatSnackBar as any, MatSnackBarHarness as any); }); describe('MDC-based MatSnackBarHarness (MDC only behavior)', () => { diff --git a/src/material-experimental/mdc-table/table.spec.ts b/src/material-experimental/mdc-table/table.spec.ts index 08d9f00adcee..471562196177 100644 --- a/src/material-experimental/mdc-table/table.spec.ts +++ b/src/material-experimental/mdc-table/table.spec.ts @@ -591,6 +591,45 @@ describe('MDC-based MatTable', () => { ['Footer A', 'Footer B', 'Footer C'], ]); }); + + it('should fall back to empty table if invalid data is passed in', () => { + component.underlyingDataSource.addData(); + fixture.detectChanges(); + expectTableToMatchContent(tableElement, [ + ['Column A', 'Column B', 'Column C'], + ['a_1', 'b_1', 'c_1'], + ['a_2', 'b_2', 'c_2'], + ['a_3', 'b_3', 'c_3'], + ['a_4', 'b_4', 'c_4'], + ['Footer A', 'Footer B', 'Footer C'], + ]); + + dataSource.data = null!; + fixture.detectChanges(); + expectTableToMatchContent(tableElement, [ + ['Column A', 'Column B', 'Column C'], + ['Footer A', 'Footer B', 'Footer C'], + ]); + + component.underlyingDataSource.addData(); + fixture.detectChanges(); + expectTableToMatchContent(tableElement, [ + ['Column A', 'Column B', 'Column C'], + ['a_1', 'b_1', 'c_1'], + ['a_2', 'b_2', 'c_2'], + ['a_3', 'b_3', 'c_3'], + ['a_4', 'b_4', 'c_4'], + ['a_5', 'b_5', 'c_5'], + ['Footer A', 'Footer B', 'Footer C'], + ]); + + dataSource.data = {} as any; + fixture.detectChanges(); + expectTableToMatchContent(tableElement, [ + ['Column A', 'Column B', 'Column C'], + ['Footer A', 'Footer B', 'Footer C'], + ]); + }); }); }); diff --git a/src/material-experimental/mdc-tabs/_tabs-common.scss b/src/material-experimental/mdc-tabs/_tabs-common.scss index 20488b19a793..1ae4d6589c3f 100644 --- a/src/material-experimental/mdc-tabs/_tabs-common.scss +++ b/src/material-experimental/mdc-tabs/_tabs-common.scss @@ -11,7 +11,7 @@ $mat-tab-animation-duration: 500ms !default; // Combines the various structural styles we need for the tab group and tab nav bar. @mixin structural-styles { @include mdc-helpers.disable-fallback-declarations { - @include mdc-tab.without-ripple($query: mdc-helpers.$mat-base-styles-query); + @include mdc-tab.static-styles($query: mdc-helpers.$mat-base-styles-query); @include mdc-tab-indicator.core-styles($query: mdc-helpers.$mat-base-styles-query); } @@ -51,6 +51,13 @@ $mat-tab-animation-duration: 500ms !default; pointer-events: none; } + // Required for `fitInkBarToContent` to work. This used to be included with MDC's `without-ripple` + // mixin, but that no longer appears to be the case with `static-styles`. Since the latter is + // ~10kb smaller, we include this one extra style ourselves. + .mdc-tab__content { + @include mdc-tab-indicator.surface; + } + // We need to handle the hover and focus indication ourselves, because we don't use MDC's ripple. &:hover .mdc-tab__ripple::before { opacity: map.get(mdc-ripple.$dark-ink-opacities, hover); diff --git a/src/material-experimental/mdc-tabs/_tabs-theme.scss b/src/material-experimental/mdc-tabs/_tabs-theme.scss index c9bca6b13355..7e386484329b 100644 --- a/src/material-experimental/mdc-tabs/_tabs-theme.scss +++ b/src/material-experimental/mdc-tabs/_tabs-theme.scss @@ -4,7 +4,7 @@ @use '@material/tab-indicator' as mdc-tab-indicator; @use '@material/tab-indicator/tab-indicator-theme' as mdc-tab-indicator-theme; @use '@material/tab' as mdc-tab; -@use '@material/tab/tab-theme' as mdc-tab-theme; +@use '@material/tab/mixins' as mdc-tab-mixins; @use '@material/tab-bar' as mdc-tab-bar; @use '../mdc-helpers/mdc-helpers'; @use '../../material/core/typography/typography'; @@ -18,39 +18,9 @@ @include mdc-helpers.mat-using-mdc-theme($config) { .mat-mdc-tab, .mat-mdc-tab-link { - $surface: mdc-theme-color.$surface; - $on-surface: rgba(mdc-theme-color.$on-surface, 0.6); - - // TODO(crisbeto): these styles should actually be set through the `theme` mixin while the - // `theme-styles` are included in the `tab` mixin inside `_tabs-common.scss`. Currently - // they are not, because `theme-styles` outputs the token values directly, rather than - // generating CSS variables. - @include mdc-tab-theme.primary-navigation-tab-theme-styles(map.merge( - mdc-tab-theme.$primary-light-theme, - ( - container-color: $surface, - inactive-focus-state-layer-color: $on-surface, - inactive-hover-state-layer-color: $on-surface, - inactive-pressed-state-layer-color: $on-surface, - with-icon-inactive-focus-icon-color: $on-surface, - with-icon-inactive-hover-icon-color: $on-surface, - with-icon-inactive-icon-color: $on-surface, - with-icon-inactive-pressed-icon-color: $on-surface, - with-label-text-inactive-focus-label-text-color: $on-surface, - with-label-text-inactive-hover-label-text-color: $on-surface, - with-label-text-inactive-label-text-color: $on-surface, - with-label-text-inactive-pressed-label-text-color: $on-surface, - - // TODO(crisbeto): MDC's styles are set up so that the icon size is set through a - // `font-size` at the root of the tab while the text size of the tab is set on - // `.mdc-tab__text-label` which overrides the one from the root. The problem is that - // the `$light-theme` is looking for a `subhead2` level which doesn't exist in MDC's - // code which in turn causes no text label styles to be emitted and for the icon size - // to be applied to the entire tab. Since we don't support icons inside the tab - // anyway, we can temporarily work around it by preventing MDC from emitting icon - // styles. The correct label typography will be applied by our theme instead. - with-icon-icon-size: null - ))); + &:not(.mat-mdc-tab-disabled) { + @include mdc-tab-mixins.text-label-color(rgba(mdc-theme-color.$on-surface, 0.6)); + } // MDC seems to include a background color on tabs which only stands out on dark themes. // Disable for now for backwards compatibility. These styles are inside the theme in order @@ -125,27 +95,10 @@ @mixin _palette-styles($color) { .mat-mdc-tab, .mat-mdc-tab-link { - // TODO(crisbeto): these styles should actually be set through the `theme` mixin while the - // `theme-styles` are included in the `tab` mixin inside `_tabs-common.scss`. Currently - // they are not, because `theme-styles` outputs the token values directly, rather than - // generating CSS variables. - @include mdc-tab-theme.primary-navigation-tab-theme-styles(( - active-focus-state-layer-color: $color, - active-hover-state-layer-color: $color, - active-pressed-state-layer-color: $color, - with-icon-active-focus-icon-color: $color, - with-icon-active-hover-icon-color: $color, - with-icon-active-icon-color: $color, - with-icon-active-pressed-icon-color: $color, - with-label-text-active-focus-label-text-color: $color, - with-label-text-active-hover-label-text-color: $color, - with-label-text-active-label-text-color: $color, - with-label-text-active-pressed-label-text-color: $color, - )); - - @include mdc-tab-indicator-theme.theme-styles(( - active-indicator-color: $color - )); + &:not(.mat-mdc-tab-disabled) { + @include mdc-tab-mixins.active-text-label-color($color); + @include mdc-tab-indicator-theme.theme-styles((active-indicator-color: $color)); + } } .mdc-tab__ripple::before, diff --git a/src/material-experimental/mdc-tabs/tab-body.scss b/src/material-experimental/mdc-tabs/tab-body.scss index 164ed84102fb..fd7ff38c9d55 100644 --- a/src/material-experimental/mdc-tabs/tab-body.scss +++ b/src/material-experimental/mdc-tabs/tab-body.scss @@ -22,6 +22,17 @@ .mat-mdc-tab-group.mat-mdc-tab-group-dynamic-height &.mat-mdc-tab-body-active { overflow-y: hidden; } + + // Usually the `visibility: hidden` added by the animation is enough to prevent focus from + // entering the collapsed content, but children with their own `visibility` can override it. + // This is a fallback that completely hides the content when the element becomes hidden. + // Note that we can't do this in the animation definition, because the style gets recomputed too + // late, breaking the animation because Angular didn't have time to figure out the target height. + // This can also be achieved with JS, but it has issues when when starting an animation before + // the previous one has finished. + &[style*='visibility: hidden'] { + display: none; + } } .mat-mdc-tab-body-content { diff --git a/src/material-experimental/mdc-tabs/tab-body.ts b/src/material-experimental/mdc-tabs/tab-body.ts index 3613e72edc5b..75d684f714e7 100644 --- a/src/material-experimental/mdc-tabs/tab-body.ts +++ b/src/material-experimental/mdc-tabs/tab-body.ts @@ -56,7 +56,8 @@ export class MatTabBodyPortal extends BaseMatTabBodyPortal { templateUrl: 'tab-body.html', styleUrls: ['tab-body.css'], encapsulation: ViewEncapsulation.None, - changeDetection: ChangeDetectionStrategy.OnPush, + // tslint:disable-next-line:validate-decorators + changeDetection: ChangeDetectionStrategy.Default, animations: [matTabsAnimations.translateTab], host: { 'class': 'mat-mdc-tab-body', diff --git a/src/material-experimental/mdc-tabs/tab-group.html b/src/material-experimental/mdc-tabs/tab-group.html index 8db3d19cd45b..157fe938c340 100644 --- a/src/material-experimental/mdc-tabs/tab-group.html +++ b/src/material-experimental/mdc-tabs/tab-group.html @@ -15,10 +15,11 @@ [attr.aria-posinset]="i + 1" [attr.aria-setsize]="_tabs.length" [attr.aria-controls]="_getTabContentId(i)" - [attr.aria-selected]="selectedIndex == i" + [attr.aria-selected]="selectedIndex === i" [attr.aria-label]="tab.ariaLabel || null" [attr.aria-labelledby]="(!tab.ariaLabel && tab.ariaLabelledby) ? tab.ariaLabelledby : null" - [class.mdc-tab--active]="selectedIndex == i" + [class.mdc-tab--active]="selectedIndex === i" + [ngClass]="tab.labelClass" [disabled]="tab.disabled" [fitInkBarToContent]="fitInkBarToContent" (click)="_handleClick(tab, tabHeader, i)" @@ -36,12 +37,12 @@ - + - {{tab.textLabel}} + {{tab.textLabel}}
@@ -57,10 +58,12 @@ [attr.tabindex]="(contentTabIndex != null && selectedIndex === i) ? contentTabIndex : null" [attr.aria-labelledby]="_getTabLabelId(i)" [class.mat-mdc-tab-body-active]="selectedIndex === i" + [ngClass]="tab.bodyClass" [content]="tab.content!" [position]="tab.position!" [origin]="tab.origin" [animationDuration]="animationDuration" + [preserveContent]="preserveContent" (_onCentered)="_removeTabBodyWrapperHeight()" (_onCentering)="_setTabBodyWrapperHeight($event)"> diff --git a/src/material-experimental/mdc-tabs/tab-group.spec.ts b/src/material-experimental/mdc-tabs/tab-group.spec.ts index 1b5930e815dd..dacd95956c01 100644 --- a/src/material-experimental/mdc-tabs/tab-group.spec.ts +++ b/src/material-experimental/mdc-tabs/tab-group.spec.ts @@ -1,6 +1,6 @@ import {LEFT_ARROW} from '@angular/cdk/keycodes'; import {dispatchFakeEvent, dispatchKeyboardEvent} from '../../cdk/testing/private'; -import {Component, OnInit, QueryList, ViewChild, ViewChildren} from '@angular/core'; +import {Component, DebugElement, OnInit, QueryList, ViewChild, ViewChildren} from '@angular/core'; import { waitForAsync, ComponentFixture, @@ -40,6 +40,7 @@ describe('MDC-based MatTabGroup', () => { TabGroupWithIndirectDescendantTabs, TabGroupWithSpaceAbove, NestedTabGroupWithLabel, + TabsWithClassesTestApp, ], }); @@ -420,11 +421,16 @@ describe('MDC-based MatTabGroup', () => { expect(tab.getAttribute('aria-label')).toBe('Fruit'); expect(tab.hasAttribute('aria-labelledby')).toBe(false); + + fixture.componentInstance.ariaLabel = 'Veggie'; + fixture.detectChanges(); + expect(tab.getAttribute('aria-label')).toBe('Veggie'); }); }); describe('disable tabs', () => { let fixture: ComponentFixture; + beforeEach(() => { fixture = TestBed.createComponent(DisabledTabsTestApp); }); @@ -660,6 +666,56 @@ describe('MDC-based MatTabGroup', () => { expect(tabGroupNode.classList).toContain('mat-mdc-tab-group-inverted-header'); }); + + it('should be able to opt into keeping the inactive tab content in the DOM', fakeAsync(() => { + fixture.componentInstance.preserveContent = true; + fixture.detectChanges(); + + expect(fixture.nativeElement.textContent).toContain('Pizza, fries'); + expect(fixture.nativeElement.textContent).not.toContain('Peanuts'); + + tabGroup.selectedIndex = 3; + fixture.detectChanges(); + tick(); + + expect(fixture.nativeElement.textContent).toContain('Pizza, fries'); + expect(fixture.nativeElement.textContent).toContain('Peanuts'); + })); + + it('should visibly hide the content of inactive tabs', fakeAsync(() => { + const contentElements: HTMLElement[] = Array.from( + fixture.nativeElement.querySelectorAll('.mat-mdc-tab-body-content'), + ); + + expect(contentElements.map(element => element.style.visibility)).toEqual([ + '', + 'hidden', + 'hidden', + 'hidden', + ]); + + tabGroup.selectedIndex = 2; + fixture.detectChanges(); + tick(); + + expect(contentElements.map(element => element.style.visibility)).toEqual([ + 'hidden', + 'hidden', + '', + 'hidden', + ]); + + tabGroup.selectedIndex = 1; + fixture.detectChanges(); + tick(); + + expect(contentElements.map(element => element.style.visibility)).toEqual([ + 'hidden', + '', + 'hidden', + 'hidden', + ]); + })); }); describe('lazy loaded tabs', () => { @@ -780,6 +836,62 @@ describe('MDC-based MatTabGroup', () => { })); }); + describe('tabs with custom css classes', () => { + let fixture: ComponentFixture; + let labelElements: DebugElement[]; + let bodyElements: DebugElement[]; + + beforeEach(() => { + fixture = TestBed.createComponent(TabsWithClassesTestApp); + fixture.detectChanges(); + labelElements = fixture.debugElement.queryAll(By.css('.mdc-tab')); + bodyElements = fixture.debugElement.queryAll(By.css('mat-tab-body')); + }); + + it('should apply label/body classes', () => { + expect(labelElements[1].nativeElement.classList).toContain('hardcoded-label-class'); + expect(bodyElements[1].nativeElement.classList).toContain('hardcoded-body-class'); + }); + + it('should set classes as strings dynamically', () => { + expect(labelElements[0].nativeElement.classList).not.toContain('custom-label-class'); + expect(bodyElements[0].nativeElement.classList).not.toContain('custom-body-class'); + + fixture.componentInstance.labelClassList = 'custom-label-class'; + fixture.componentInstance.bodyClassList = 'custom-body-class'; + fixture.detectChanges(); + + expect(labelElements[0].nativeElement.classList).toContain('custom-label-class'); + expect(bodyElements[0].nativeElement.classList).toContain('custom-body-class'); + + delete fixture.componentInstance.labelClassList; + delete fixture.componentInstance.bodyClassList; + fixture.detectChanges(); + + expect(labelElements[0].nativeElement.classList).not.toContain('custom-label-class'); + expect(bodyElements[0].nativeElement.classList).not.toContain('custom-body-class'); + }); + + it('should set classes as strings array dynamically', () => { + expect(labelElements[0].nativeElement.classList).not.toContain('custom-label-class'); + expect(bodyElements[0].nativeElement.classList).not.toContain('custom-body-class'); + + fixture.componentInstance.labelClassList = ['custom-label-class']; + fixture.componentInstance.bodyClassList = ['custom-body-class']; + fixture.detectChanges(); + + expect(labelElements[0].nativeElement.classList).toContain('custom-label-class'); + expect(bodyElements[0].nativeElement.classList).toContain('custom-body-class'); + + delete fixture.componentInstance.labelClassList; + delete fixture.componentInstance.bodyClassList; + fixture.detectChanges(); + + expect(labelElements[0].nativeElement.classList).not.toContain('custom-label-class'); + expect(bodyElements[0].nativeElement.classList).not.toContain('custom-body-class'); + }); + }); + /** * Checks that the `selectedIndex` has been updated; checks that the label and body have their * respective `active` classes @@ -1014,7 +1126,6 @@ class BindedTabsTestApp { } @Component({ - selector: 'test-app', template: ` @@ -1065,7 +1176,7 @@ class AsyncTabsTestApp implements OnInit { @Component({ template: ` - + Pizza, fries Broccoli, spinach {{otherContent}} @@ -1074,13 +1185,13 @@ class AsyncTabsTestApp implements OnInit { `, }) class TabGroupWithSimpleApi { + preserveContent = false; otherLabel = 'Fruit'; otherContent = 'Apples, grapes'; @ViewChild('legumes') legumes: any; } @Component({ - selector: 'nested-tabs', template: ` Tab one content @@ -1099,7 +1210,6 @@ class NestedTabs { } @Component({ - selector: 'template-tabs', template: ` @@ -1215,3 +1325,21 @@ class TabGroupWithSpaceAbove { `, }) class NestedTabGroupWithLabel {} + +@Component({ + template: ` + + + Tab one content + + + Tab two content + + + `, +}) +class TabsWithClassesTestApp { + labelClassList?: string | string[]; + bodyClassList?: string | string[]; +} diff --git a/src/material-experimental/mdc-tabs/tab-group.ts b/src/material-experimental/mdc-tabs/tab-group.ts index e268f713057f..2befb5837125 100644 --- a/src/material-experimental/mdc-tabs/tab-group.ts +++ b/src/material-experimental/mdc-tabs/tab-group.ts @@ -41,7 +41,8 @@ import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion'; templateUrl: 'tab-group.html', styleUrls: ['tab-group.css'], encapsulation: ViewEncapsulation.None, - changeDetection: ChangeDetectionStrategy.OnPush, + // tslint:disable-next-line:validate-decorators + changeDetection: ChangeDetectionStrategy.Default, inputs: ['color', 'disableRipple'], providers: [ { diff --git a/src/material-experimental/mdc-tabs/tab-header.ts b/src/material-experimental/mdc-tabs/tab-header.ts index e733577679fc..a5dce8c6e139 100644 --- a/src/material-experimental/mdc-tabs/tab-header.ts +++ b/src/material-experimental/mdc-tabs/tab-header.ts @@ -42,7 +42,8 @@ import {MatInkBar} from './ink-bar'; inputs: ['selectedIndex'], outputs: ['selectFocusedIndex', 'indexFocused'], encapsulation: ViewEncapsulation.None, - changeDetection: ChangeDetectionStrategy.OnPush, + // tslint:disable-next-line:validate-decorators + changeDetection: ChangeDetectionStrategy.Default, host: { 'class': 'mat-mdc-tab-header', '[class.mat-mdc-tab-header-pagination-controls-enabled]': '_showPaginationControls', diff --git a/src/material-experimental/mdc-tabs/tab-nav-bar/tab-nav-bar.ts b/src/material-experimental/mdc-tabs/tab-nav-bar/tab-nav-bar.ts index bb88dce83f2c..5b949b82e91e 100644 --- a/src/material-experimental/mdc-tabs/tab-nav-bar/tab-nav-bar.ts +++ b/src/material-experimental/mdc-tabs/tab-nav-bar/tab-nav-bar.ts @@ -66,7 +66,8 @@ import {takeUntil} from 'rxjs/operators'; '[class._mat-animation-noopable]': '_animationMode === "NoopAnimations"', }, encapsulation: ViewEncapsulation.None, - changeDetection: ChangeDetectionStrategy.OnPush, + // tslint:disable-next-line:validate-decorators + changeDetection: ChangeDetectionStrategy.Default, }) export class MatTabNav extends _MatTabNavBase implements AfterContentInit { /** Whether the ink bar should fit its width to the size of the tab label content. */ diff --git a/src/material-experimental/mdc-tabs/tab.ts b/src/material-experimental/mdc-tabs/tab.ts index 3d38e03c1a8e..b7384bb6b428 100644 --- a/src/material-experimental/mdc-tabs/tab.ts +++ b/src/material-experimental/mdc-tabs/tab.ts @@ -25,7 +25,8 @@ import {MatTabLabel} from './tab-label'; // that creating the extra class will generate more code than just duplicating the template. templateUrl: 'tab.html', inputs: ['disabled'], - changeDetection: ChangeDetectionStrategy.OnPush, + // tslint:disable-next-line:validate-decorators + changeDetection: ChangeDetectionStrategy.Default, encapsulation: ViewEncapsulation.None, exportAs: 'matTab', providers: [{provide: MAT_TAB, useExisting: MatTab}], diff --git a/src/material-experimental/mdc-tooltip/tooltip.spec.ts b/src/material-experimental/mdc-tooltip/tooltip.spec.ts index 4c2462d62bd0..272e70e165ef 100644 --- a/src/material-experimental/mdc-tooltip/tooltip.spec.ts +++ b/src/material-experimental/mdc-tooltip/tooltip.spec.ts @@ -697,9 +697,28 @@ describe('MDC-based MatTooltip', () => { expect(overlayContainerElement.textContent).toContain(initialTooltipMessage); })); + it('should hide when pressing escape', fakeAsync(() => { + tooltipDirective.show(); + tick(0); + fixture.detectChanges(); + tick(500); + + expect(tooltipDirective._isTooltipVisible()).toBe(true); + expect(overlayContainerElement.textContent).toContain(initialTooltipMessage); + + dispatchKeyboardEvent(document.body, 'keydown', ESCAPE); + tick(0); + fixture.detectChanges(); + tick(500); + fixture.detectChanges(); + + expect(tooltipDirective._isTooltipVisible()).toBe(false); + expect(overlayContainerElement.textContent).toBe(''); + })); + it('should not throw when pressing ESCAPE', fakeAsync(() => { expect(() => { - dispatchKeyboardEvent(buttonElement, 'keydown', ESCAPE); + dispatchKeyboardEvent(document.body, 'keydown', ESCAPE); fixture.detectChanges(); }).not.toThrow(); @@ -712,7 +731,7 @@ describe('MDC-based MatTooltip', () => { tick(0); fixture.detectChanges(); - const event = dispatchKeyboardEvent(buttonElement, 'keydown', ESCAPE); + const event = dispatchKeyboardEvent(document.body, 'keydown', ESCAPE); fixture.detectChanges(); flush(); @@ -725,7 +744,7 @@ describe('MDC-based MatTooltip', () => { fixture.detectChanges(); const event = createKeyboardEvent('keydown', ESCAPE, undefined, {alt: true}); - dispatchEvent(buttonElement, event); + dispatchEvent(document.body, event); fixture.detectChanges(); flush(); diff --git a/src/material/autocomplete/autocomplete-trigger.ts b/src/material/autocomplete/autocomplete-trigger.ts index ccb6078b32cb..fa6f0b15d39e 100644 --- a/src/material/autocomplete/autocomplete-trigger.ts +++ b/src/material/autocomplete/autocomplete-trigger.ts @@ -47,7 +47,7 @@ import { } from '@angular/material/core'; import {MAT_FORM_FIELD, MatFormField} from '@angular/material/form-field'; import {defer, fromEvent, merge, Observable, of as observableOf, Subject, Subscription} from 'rxjs'; -import {delay, filter, map, switchMap, take, tap} from 'rxjs/operators'; +import {delay, filter, map, switchMap, take, tap, startWith} from 'rxjs/operators'; import { _MatAutocompleteBase, @@ -309,10 +309,15 @@ export abstract class _MatAutocompleteTriggerBase ); } - /** Stream of autocomplete option selections. */ + /** Stream of changes to the selection state of the autocomplete options. */ readonly optionSelections: Observable = defer(() => { - if (this.autocomplete && this.autocomplete.options) { - return merge(...this.autocomplete.options.map(option => option.onSelectionChange)); + const options = this.autocomplete ? this.autocomplete.options : null; + + if (options) { + return options.changes.pipe( + startWith(options), + switchMap(() => merge(...options.map(option => option.onSelectionChange))), + ); } // If there are any subscribers before `ngAfterViewInit`, the `autocomplete` will be undefined. @@ -360,7 +365,7 @@ export abstract class _MatAutocompleteTriggerBase // Implemented as part of ControlValueAccessor. writeValue(value: any): void { - Promise.resolve(null).then(() => this._setTriggerValue(value)); + Promise.resolve().then(() => this._setTriggerValue(value)); } // Implemented as part of ControlValueAccessor. @@ -389,7 +394,7 @@ export abstract class _MatAutocompleteTriggerBase event.preventDefault(); } - if (this.activeOption && keyCode === ENTER && this.panelOpen) { + if (this.activeOption && keyCode === ENTER && this.panelOpen && !hasModifierKey(event)) { this.activeOption._selectViaInteraction(); this._resetActiveItem(); event.preventDefault(); @@ -551,12 +556,14 @@ export abstract class _MatAutocompleteTriggerBase * stemmed from the user. */ private _setValueAndClose(event: MatOptionSelectionChange | null): void { - if (event && event.source) { - this._clearPreviousSelectedOption(event.source); - this._setTriggerValue(event.source.value); - this._onChange(event.source.value); + const source = event && event.source; + + if (source) { + this._clearPreviousSelectedOption(source); + this._setTriggerValue(source.value); + this._onChange(source.value); + this.autocomplete._emitSelectEvent(source); this._element.nativeElement.focus(); - this.autocomplete._emitSelectEvent(event.source); } this.closePanel(); diff --git a/src/material/autocomplete/autocomplete.spec.ts b/src/material/autocomplete/autocomplete.spec.ts index 5ea9ab5bb257..b905b193b4a3 100644 --- a/src/material/autocomplete/autocomplete.spec.ts +++ b/src/material/autocomplete/autocomplete.spec.ts @@ -1081,6 +1081,27 @@ describe('MatAutocomplete', () => { .toBe(false); }); + it('should not interfere with the ENTER key when pressing a modifier', fakeAsync(() => { + const trigger = fixture.componentInstance.trigger; + + expect(input.value).withContext('Expected input to start off blank.').toBeFalsy(); + expect(trigger.panelOpen).withContext('Expected panel to start off open.').toBe(true); + + fixture.componentInstance.trigger._handleKeydown(DOWN_ARROW_EVENT); + flush(); + fixture.detectChanges(); + + Object.defineProperty(ENTER_EVENT, 'altKey', {get: () => true}); + fixture.componentInstance.trigger._handleKeydown(ENTER_EVENT); + fixture.detectChanges(); + + expect(trigger.panelOpen).withContext('Expected panel to remain open.').toBe(true); + expect(input.value).withContext('Expected input to remain blank.').toBeFalsy(); + expect(ENTER_EVENT.defaultPrevented) + .withContext('Expected the default ENTER action not to have been prevented.') + .toBe(false); + })); + it('should fill the text field, not select an option, when SPACE is entered', () => { typeInElement(input, 'New'); fixture.detectChanges(); @@ -2265,6 +2286,34 @@ describe('MatAutocomplete', () => { subscription!.unsubscribe(); })); + it('should emit to `optionSelections` if the list of options changes', fakeAsync(() => { + const spy = jasmine.createSpy('option selection spy'); + const subscription = fixture.componentInstance.trigger.optionSelections.subscribe(spy); + const openAndSelectFirstOption = () => { + fixture.detectChanges(); + fixture.componentInstance.trigger.openPanel(); + fixture.detectChanges(); + zone.simulateZoneExit(); + (overlayContainerElement.querySelector('mat-option') as HTMLElement).click(); + fixture.detectChanges(); + zone.simulateZoneExit(); + }; + + fixture.componentInstance.states = [{code: 'OR', name: 'Oregon'}]; + fixture.detectChanges(); + + openAndSelectFirstOption(); + expect(spy).toHaveBeenCalledTimes(1); + + fixture.componentInstance.states = [{code: 'WV', name: 'West Virginia'}]; + fixture.detectChanges(); + + openAndSelectFirstOption(); + expect(spy).toHaveBeenCalledTimes(2); + + subscription!.unsubscribe(); + })); + it('should reposition the panel when the amount of options changes', fakeAsync(() => { const formField = fixture.debugElement.query(By.css('.mat-form-field'))!.nativeElement; const inputReference = formField.querySelector('.mat-form-field-flex'); @@ -2824,6 +2873,29 @@ describe('MatAutocomplete', () => { expect(event.option.value).toBe('Washington'); })); + it('should refocus the input after the selection event is emitted', fakeAsync(() => { + const events: string[] = []; + const fixture = createComponent(AutocompleteWithSelectEvent); + fixture.detectChanges(); + const input = fixture.nativeElement.querySelector('input'); + + fixture.componentInstance.trigger.openPanel(); + zone.simulateZoneExit(); + fixture.detectChanges(); + + const options = overlayContainerElement.querySelectorAll( + 'mat-option', + ) as NodeListOf; + spyOn(input, 'focus').and.callFake(() => events.push('focus')); + fixture.componentInstance.optionSelected.and.callFake(() => events.push('select')); + + options[1].click(); + tick(); + fixture.detectChanges(); + + expect(events).toEqual(['select', 'focus']); + })); + it('should emit an event when a newly-added option is selected', fakeAsync(() => { const fixture = createComponent(AutocompleteWithSelectEvent); diff --git a/src/material/button/BUILD.bazel b/src/material/button/BUILD.bazel index 1302f96a0374..f411fdcf24de 100644 --- a/src/material/button/BUILD.bazel +++ b/src/material/button/BUILD.bazel @@ -52,6 +52,7 @@ ng_test_library( ), deps = [ ":button", + "//src/cdk/testing/private", "//src/material/core", "@npm//@angular/platform-browser", ], diff --git a/src/material/button/button.spec.ts b/src/material/button/button.spec.ts index a0eced1ece92..e4c5bcd179a9 100644 --- a/src/material/button/button.spec.ts +++ b/src/material/button/button.spec.ts @@ -1,8 +1,9 @@ import {waitForAsync, ComponentFixture, TestBed} from '@angular/core/testing'; -import {Component, DebugElement} from '@angular/core'; +import {ApplicationRef, Component, DebugElement} from '@angular/core'; import {By} from '@angular/platform-browser'; import {MatButtonModule, MatButton} from './index'; import {MatRipple, ThemePalette} from '@angular/material/core'; +import {createMouseEvent, dispatchEvent} from '@angular/cdk/testing/private'; describe('MatButton', () => { beforeEach( @@ -243,6 +244,28 @@ describe('MatButton', () => { .withContext('Expected custom tabindex to be overwritten when disabled.') .toBe('-1'); }); + + describe('change detection behavior', () => { + it('should not run change detection for disabled anchor but should prevent the default behavior and stop event propagation', () => { + const appRef = TestBed.inject(ApplicationRef); + const fixture = TestBed.createComponent(TestApp); + fixture.componentInstance.isDisabled = true; + fixture.detectChanges(); + const anchorElement = fixture.debugElement.query(By.css('a'))!.nativeElement; + + spyOn(appRef, 'tick'); + + const event = createMouseEvent('click'); + spyOn(event, 'preventDefault').and.callThrough(); + spyOn(event, 'stopImmediatePropagation').and.callThrough(); + + dispatchEvent(anchorElement, event); + + expect(appRef.tick).not.toHaveBeenCalled(); + expect(event.preventDefault).toHaveBeenCalled(); + expect(event.stopImmediatePropagation).toHaveBeenCalled(); + }); + }); }); // Ripple tests. diff --git a/src/material/button/button.ts b/src/material/button/button.ts index 96b24e98f7e7..ca1100b324eb 100644 --- a/src/material/button/button.ts +++ b/src/material/button/button.ts @@ -18,6 +18,7 @@ import { Inject, Input, AfterViewInit, + NgZone, } from '@angular/core'; import { CanColor, @@ -164,7 +165,6 @@ export class MatButton '[attr.tabindex]': 'disabled ? -1 : (tabIndex || 0)', '[attr.disabled]': 'disabled || null', '[attr.aria-disabled]': 'disabled.toString()', - '(click)': '_haltDisabledEvents($event)', '[class._mat-animation-noopable]': '_animationMode === "NoopAnimations"', '[class.mat-button-disabled]': 'disabled', 'class': 'mat-focus-indicator', @@ -175,7 +175,7 @@ export class MatButton encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, }) -export class MatAnchor extends MatButton { +export class MatAnchor extends MatButton implements AfterViewInit, OnDestroy { /** Tabindex of the button. */ @Input() tabIndex: number; @@ -183,15 +183,35 @@ export class MatAnchor extends MatButton { focusMonitor: FocusMonitor, elementRef: ElementRef, @Optional() @Inject(ANIMATION_MODULE_TYPE) animationMode: string, + /** @breaking-change 14.0.0 _ngZone will be required. */ + @Optional() private _ngZone?: NgZone, ) { super(elementRef, focusMonitor, animationMode); } - _haltDisabledEvents(event: Event) { + override ngAfterViewInit(): void { + super.ngAfterViewInit(); + + /** @breaking-change 14.0.0 _ngZone will be required. */ + if (this._ngZone) { + this._ngZone.runOutsideAngular(() => { + this._elementRef.nativeElement.addEventListener('click', this._haltDisabledEvents); + }); + } else { + this._elementRef.nativeElement.addEventListener('click', this._haltDisabledEvents); + } + } + + override ngOnDestroy(): void { + super.ngOnDestroy(); + this._elementRef.nativeElement.removeEventListener('click', this._haltDisabledEvents); + } + + _haltDisabledEvents = (event: Event): void => { // A disabled button shouldn't apply any actions if (this.disabled) { event.preventDefault(); event.stopImmediatePropagation(); } - } + }; } diff --git a/src/material/card/card.scss b/src/material/card/card.scss index e208e4a6d098..20fb0ce20f79 100644 --- a/src/material/card/card.scss +++ b/src/material/card/card.scss @@ -73,6 +73,14 @@ $header-size: 40px !default; .mat-card-image { width: calc(100% + #{$padding * 2}); margin: 0 (-$padding) 16px (-$padding); + + // The following properties are to handle `mat-card-image` on a `picture` element. + display: block; + overflow: hidden; + + img { + width: 100%; + } } .mat-card-footer { diff --git a/src/material/chips/chip.ts b/src/material/chips/chip.ts index d0a9114af50e..1307926cba3b 100644 --- a/src/material/chips/chip.ts +++ b/src/material/chips/chip.ts @@ -404,8 +404,6 @@ export class MatChip _handleClick(event: Event) { if (this.disabled) { event.preventDefault(); - } else { - event.stopPropagation(); } } diff --git a/src/material/core/common-behaviors/common-module.ts b/src/material/core/common-behaviors/common-module.ts index d864c099535b..85c07a50e282 100644 --- a/src/material/core/common-behaviors/common-module.ts +++ b/src/material/core/common-behaviors/common-module.ts @@ -8,16 +8,11 @@ import {HighContrastModeDetector} from '@angular/cdk/a11y'; import {BidiModule} from '@angular/cdk/bidi'; -import {Inject, InjectionToken, NgModule, Optional, Version} from '@angular/core'; +import {Inject, InjectionToken, NgModule, Optional} from '@angular/core'; import {VERSION as CDK_VERSION} from '@angular/cdk'; import {DOCUMENT} from '@angular/common'; import {_isTestEnvironment} from '@angular/cdk/platform'; - -// Private version constant to circumvent test/build issues, -// i.e. avoid core to depend on the @angular/material primary entry-point -// Can be removed once the Material primary entry-point no longer -// re-exports all secondary entry-points -const VERSION = new Version('0.0.0-PLACEHOLDER'); +import {VERSION} from '../version'; /** @docs-private */ export function MATERIAL_SANITY_CHECKS_FACTORY(): SanityChecks { diff --git a/src/material/core/focus-indicators/_focus-indicators.scss b/src/material/core/focus-indicators/_focus-indicators.scss index ac68751be83a..0062400610b0 100644 --- a/src/material/core/focus-indicators/_focus-indicators.scss +++ b/src/material/core/focus-indicators/_focus-indicators.scss @@ -28,6 +28,10 @@ pointer-events: none; border: $border-width $border-style transparent; border-radius: $border-radius; + + .cdk-high-contrast-active & { + display: none; + } } // By default, all focus indicators are flush with the bounding box of their diff --git a/src/material/core/option/option.ts b/src/material/core/option/option.ts index cdab4794355d..445982250fc8 100644 --- a/src/material/core/option/option.ts +++ b/src/material/core/option/option.ts @@ -36,17 +36,17 @@ import {MatOptionParentComponent, MAT_OPTION_PARENT_COMPONENT} from './option-pa let _uniqueIdCounter = 0; /** Event object emitted by MatOption when selected or deselected. */ -export class MatOptionSelectionChange { +export class MatOptionSelectionChange { constructor( /** Reference to the option that emitted the event. */ - public source: _MatOptionBase, + public source: _MatOptionBase, /** Whether the change in the option's value was a result of a user action. */ public isUserInput = false, ) {} } @Directive() -export class _MatOptionBase implements FocusableOption, AfterViewChecked, OnDestroy { +export class _MatOptionBase implements FocusableOption, AfterViewChecked, OnDestroy { private _selected = false; private _active = false; private _disabled = false; @@ -63,7 +63,7 @@ export class _MatOptionBase implements FocusableOption, AfterViewChecked, OnDest } /** The form value of the option. */ - @Input() value: any; + @Input() value: T; /** The unique ID of the option. */ @Input() id: string = `mat-option-${_uniqueIdCounter++}`; @@ -84,7 +84,7 @@ export class _MatOptionBase implements FocusableOption, AfterViewChecked, OnDest /** Event emitted when the option is selected or deselected. */ // tslint:disable-next-line:no-output-on-prefix - @Output() readonly onSelectionChange = new EventEmitter(); + @Output() readonly onSelectionChange = new EventEmitter>(); /** Emits when the state of the option changes and any parents have to be notified. */ readonly _stateChanges = new Subject(); @@ -237,7 +237,7 @@ export class _MatOptionBase implements FocusableOption, AfterViewChecked, OnDest /** Emits the selection change event. */ private _emitSelectionChangeEvent(isUserInput = false): void { - this.onSelectionChange.emit(new MatOptionSelectionChange(this, isUserInput)); + this.onSelectionChange.emit(new MatOptionSelectionChange(this, isUserInput)); } } @@ -266,7 +266,7 @@ export class _MatOptionBase implements FocusableOption, AfterViewChecked, OnDest encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, }) -export class MatOption extends _MatOptionBase { +export class MatOption extends _MatOptionBase { constructor( element: ElementRef, changeDetectorRef: ChangeDetectorRef, diff --git a/src/material/core/ripple/_ripple.scss b/src/material/core/ripple/_ripple.scss index 536f15c826ef..f4485547fbc8 100644 --- a/src/material/core/ripple/_ripple.scss +++ b/src/material/core/ripple/_ripple.scss @@ -30,7 +30,10 @@ pointer-events: none; transition: opacity, transform 0ms cubic-bezier(0, 0, 0.2, 1); - transform: scale(0); + + // We use a 3d transform here in order to avoid an issue in Safari where + // the ripples aren't clipped when inside the shadow DOM (see #24028). + transform: scale3d(0, 0, 0); // In high contrast mode the ripple is opaque, causing it to obstruct the content. @include a11y.high-contrast(active, off) { diff --git a/src/material/core/ripple/ripple-renderer.ts b/src/material/core/ripple/ripple-renderer.ts index 1941bb970d3b..8887d83b4d96 100644 --- a/src/material/core/ripple/ripple-renderer.ts +++ b/src/material/core/ripple/ripple-renderer.ts @@ -138,7 +138,9 @@ export class RippleRenderer implements EventListenerObject { // ripple elements. This is critical because then the `scale` would not animate properly. enforceStyleRecalculation(ripple); - ripple.style.transform = 'scale(1)'; + // We use a 3d transform here in order to avoid an issue in Safari where + // the ripples aren't clipped when inside the shadow DOM (see #24028). + ripple.style.transform = 'scale3d(1, 1, 1)'; // Exposed reference to the ripple that will be returned. const rippleRef = new RippleRef(this, ripple, config); diff --git a/src/material/core/selection/index.ts b/src/material/core/selection/index.ts index 31f98de88d59..102eaefd2bab 100644 --- a/src/material/core/selection/index.ts +++ b/src/material/core/selection/index.ts @@ -6,15 +6,5 @@ * found in the LICENSE file at https://angular.io/license */ -import {NgModule} from '@angular/core'; -import {MatPseudoCheckbox} from './pseudo-checkbox/pseudo-checkbox'; -import {MatCommonModule} from '../common-behaviors/common-module'; - -@NgModule({ - imports: [MatCommonModule], - exports: [MatPseudoCheckbox], - declarations: [MatPseudoCheckbox], -}) -export class MatPseudoCheckboxModule {} - export * from './pseudo-checkbox/pseudo-checkbox'; +export * from './pseudo-checkbox/pseudo-checkbox-module'; diff --git a/src/material/core/selection/pseudo-checkbox/pseudo-checkbox-module.ts b/src/material/core/selection/pseudo-checkbox/pseudo-checkbox-module.ts new file mode 100644 index 000000000000..4a35ebc701dc --- /dev/null +++ b/src/material/core/selection/pseudo-checkbox/pseudo-checkbox-module.ts @@ -0,0 +1,18 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +import {NgModule} from '@angular/core'; +import {MatPseudoCheckbox} from './pseudo-checkbox'; +import {MatCommonModule} from '../../common-behaviors/common-module'; + +@NgModule({ + imports: [MatCommonModule], + exports: [MatPseudoCheckbox], + declarations: [MatPseudoCheckbox], +}) +export class MatPseudoCheckboxModule {} diff --git a/src/material/core/theming/_palette.scss b/src/material/core/theming/_palette.scss index 10fa42bf4553..e2b5faada05c 100644 --- a/src/material/core/theming/_palette.scss +++ b/src/material/core/theming/_palette.scss @@ -705,7 +705,7 @@ $dark-theme-background-palette: ( selected-disabled-button: map.get($grey-palette, 800), disabled-button-toggle: black, unselected-chip: map.get($grey-palette, 700), - disabled-list-option: black, + disabled-list-option: rgba(white, 0.12), tooltip: map.get($grey-palette, 700), ); diff --git a/src/material/core/theming/_theming.scss b/src/material/core/theming/_theming.scss index 0773c7f966fc..eca5a6819091 100644 --- a/src/material/core/theming/_theming.scss +++ b/src/material/core/theming/_theming.scss @@ -20,6 +20,17 @@ $_emitted-color: () !default; $_emitted-typography: () !default; $_emitted-density: () !default; +/// Extracts a color from a palette or throws an error if it doesn't exist. +/// @param {Map} $palette The palette from which to extract a color. +/// @param {String | Number} $hue The hue for which to get the color. +@function _get-color-from-palette($palette, $hue) { + @if map.has-key($palette, $hue) { + @return map.get($palette, $hue); + } + + @error 'Hue "' + $hue + '" does not exist in palette. Available hues are: ' + map.keys($palette); +} + /// For a given hue in a palette, return the contrast color from the map of contrast palettes. /// @param {Map} $palette The palette from which to extract a color. /// @param {String | Number} $hue The hue for which to get a contrast color. @@ -40,10 +51,10 @@ $_emitted-density: () !default; @function define-palette($base-palette, $default: 500, $lighter: 100, $darker: 700, $text: $default) { $result: map.merge($base-palette, ( - default: map.get($base-palette, $default), - lighter: map.get($base-palette, $lighter), - darker: map.get($base-palette, $darker), - text: map.get($base-palette, $text), + default: _get-color-from-palette($base-palette, $default), + lighter: _get-color-from-palette($base-palette, $lighter), + darker: _get-color-from-palette($base-palette, $darker), + text: _get-color-from-palette($base-palette, $text), default-contrast: get-contrast-color-from-palette($base-palette, $default), lighter-contrast: get-contrast-color-from-palette($base-palette, $lighter), diff --git a/src/material/datepicker/calendar-body.html b/src/material/datepicker/calendar-body.html index ffdfef27c1cd..1b0f5f0b1a4a 100644 --- a/src/material/datepicker/calendar-body.html +++ b/src/material/datepicker/calendar-body.html @@ -26,40 +26,51 @@ [style.paddingBottom]="_cellPadding"> {{_firstRowOffset >= labelMinRequiredCells ? label : ''}} - -
- {{item.displayValue}} -
- + + + diff --git a/src/material/datepicker/calendar-body.scss b/src/material/datepicker/calendar-body.scss index c2d2f78df048..334585fcd42b 100644 --- a/src/material/datepicker/calendar-body.scss +++ b/src/material/datepicker/calendar-body.scss @@ -1,4 +1,5 @@ @use 'sass:math'; +@use '../core/style/button-common'; @use '../../cdk/a11y'; $calendar-body-label-padding-start: 5% !default; @@ -31,13 +32,24 @@ $calendar-range-end-body-cell-size: padding-right: $calendar-body-label-side-padding; } -.mat-calendar-body-cell { +.mat-calendar-body-cell-container { position: relative; height: 0; line-height: 0; +} + +.mat-calendar-body-cell { + @include button-common.reset(); + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: none; text-align: center; outline: none; - cursor: pointer; + font-family: inherit; + margin: 0; } // We use ::before to apply a background to the body cell, because we need to apply a border @@ -208,8 +220,12 @@ $calendar-range-end-body-cell-size: .cdk-keyboard-focused .mat-calendar-body-active, .cdk-program-focused .mat-calendar-body-active { - & > .mat-calendar-body-cell-content:not(.mat-calendar-body-selected) { + & > .mat-calendar-body-cell-content { outline: dotted 2px; + + &.mat-calendar-body-selected { + outline: solid 3px; + } } } diff --git a/src/material/datepicker/calendar-body.spec.ts b/src/material/datepicker/calendar-body.spec.ts index df10b757c081..52ff40e20359 100644 --- a/src/material/datepicker/calendar-body.spec.ts +++ b/src/material/datepicker/calendar-body.spec.ts @@ -92,15 +92,13 @@ describe('MatCalendarBody', () => { expect(selectedCell.innerHTML.trim()).toBe('4'); }); - it('should set aria-selected correctly', () => { - const selectedCells = cellEls.filter(c => c.getAttribute('aria-selected') === 'true'); - const deselectedCells = cellEls.filter(c => c.getAttribute('aria-selected') === 'false'); - - expect(selectedCells.length) - .withContext('Expected one cell to be marked as selected.') - .toBe(1); - expect(deselectedCells.length) - .withContext('Expected remaining cells to be marked as deselected.') + it('should set aria-pressed correctly', () => { + const pressedCells = cellEls.filter(c => c.getAttribute('aria-pressed') === 'true'); + const depressedCells = cellEls.filter(c => c.getAttribute('aria-pressed') === 'false'); + + expect(pressedCells.length).withContext('Expected one cell to be marked as pressed.').toBe(1); + expect(depressedCells.length) + .withContext('Expected remaining cells to be marked as not pressed.') .toBe(cellEls.length - 1); }); diff --git a/src/material/datepicker/calendar-body.ts b/src/material/datepicker/calendar-body.ts index 895db4b41472..ef34dc45fbff 100644 --- a/src/material/datepicker/calendar-body.ts +++ b/src/material/datepicker/calendar-body.ts @@ -337,7 +337,7 @@ export class MatCalendarBody implements OnChanges, OnDestroy { // Only reset the preview end value when leaving cells. This looks better, because // we have a gap between the cells and the rows and we don't want to remove the // range just for it to show up again when the user moves a few pixels to the side. - if (event.target && isTableCell(event.target as HTMLElement)) { + if (event.target && this._getCellFromElement(event.target as HTMLElement)) { this._ngZone.run(() => this.previewChange.emit({value: null, event})); } } diff --git a/src/material/datepicker/datepicker-content.html b/src/material/datepicker/datepicker-content.html index 97109f1f59df..182377885cf7 100644 --- a/src/material/datepicker/datepicker-content.html +++ b/src/material/datepicker/datepicker-content.html @@ -1,6 +1,7 @@
- - Date type - Date - - - Supported locales - en-US - - - Dependencies - None - - - Import from - @angular/material/core - + + Date type + Date + + + Supported locales + en-US + + + Dependencies + None + + + Import from + @angular/material/core + @@ -329,22 +329,22 @@ The easiest way to ensure this is to import one of the provided date modules: - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + +
Date typeDate
Supported localesSee project for details
Dependenciesdate-fns
Import from@angular/material-date-fns-adapter
Date typeDate
Supported localesSee project for details
Dependenciesdate-fns
Import from@angular/material-date-fns-adapter
@@ -352,22 +352,22 @@ The easiest way to ensure this is to import one of the provided date modules: - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + +
Date typeDateTime
Supported localesSee project for details
DependenciesLuxon
Import from@angular/material-luxon-adapter
Date typeDateTime
Supported localesSee project for details
DependenciesLuxon
Import from@angular/material-luxon-adapter
@@ -375,22 +375,22 @@ The easiest way to ensure this is to import one of the provided date modules: - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + +
Date typeMoment
Supported localesSee project for details
DependenciesMoment.js
Import from@angular/material-moment-adapter
Date typeMoment
Supported localesSee project for details
DependenciesMoment.js
Import from@angular/material-moment-adapter
diff --git a/src/material/datepicker/testing/calendar-cell-harness.ts b/src/material/datepicker/testing/calendar-cell-harness.ts index 4ebee4c8ccb4..c0274c0d281d 100644 --- a/src/material/datepicker/testing/calendar-cell-harness.ts +++ b/src/material/datepicker/testing/calendar-cell-harness.ts @@ -69,7 +69,7 @@ export class MatCalendarCellHarness extends ComponentHarness { /** Whether the cell is selected. */ async isSelected(): Promise { const host = await this.host(); - return (await host.getAttribute('aria-selected')) === 'true'; + return (await host.getAttribute('aria-pressed')) === 'true'; } /** Whether the cell is disabled. */ diff --git a/src/material/expansion/expansion-panel-header.scss b/src/material/expansion/expansion-panel-header.scss index b0984e25fee6..7c45e216d13c 100644 --- a/src/material/expansion/expansion-panel-header.scss +++ b/src/material/expansion/expansion-panel-header.scss @@ -55,6 +55,7 @@ display: flex; flex-grow: 1; margin-right: 16px; + align-items: center; [dir='rtl'] & { margin-right: 0; diff --git a/src/material/form-field/form-field.ts b/src/material/form-field/form-field.ts index 21975e33ea37..7bb7f497d5f5 100644 --- a/src/material/form-field/form-field.ts +++ b/src/material/form-field/form-field.ts @@ -549,20 +549,26 @@ export class MatFormField */ updateOutlineGap() { const labelEl = this._label ? this._label.nativeElement : null; + const container = this._connectionContainerRef.nativeElement; + const outlineStartSelector = '.mat-form-field-outline-start'; + const outlineGapSelector = '.mat-form-field-outline-gap'; - if ( - this.appearance !== 'outline' || - !labelEl || - !labelEl.children.length || - !labelEl.textContent!.trim() - ) { + // getBoundingClientRect isn't available on the server. + if (this.appearance !== 'outline' || !this._platform.isBrowser) { return; } - if (!this._platform.isBrowser) { - // getBoundingClientRect isn't available on the server. + // If there is no content, set the gap elements to zero. + if (!labelEl || !labelEl.children.length || !labelEl.textContent!.trim()) { + const gapElements = container.querySelectorAll( + `${outlineStartSelector}, ${outlineGapSelector}`, + ); + for (let i = 0; i < gapElements.length; i++) { + gapElements[i].style.width = '0'; + } return; } + // If the element is not present in the DOM, the outline gap will need to be calculated // the next time it is checked and in the DOM. if (!this._isAttachedToDOM()) { @@ -573,9 +579,8 @@ export class MatFormField let startWidth = 0; let gapWidth = 0; - const container = this._connectionContainerRef.nativeElement; - const startEls = container.querySelectorAll('.mat-form-field-outline-start'); - const gapEls = container.querySelectorAll('.mat-form-field-outline-gap'); + const startEls = container.querySelectorAll(outlineStartSelector); + const gapEls = container.querySelectorAll(outlineGapSelector); if (this._label && this._label.nativeElement.children.length) { const containerRect = container.getBoundingClientRect(); diff --git a/src/material/input/input.spec.ts b/src/material/input/input.spec.ts index c81888a72f33..f3fd311ba2ad 100644 --- a/src/material/input/input.spec.ts +++ b/src/material/input/input.spec.ts @@ -1761,6 +1761,34 @@ describe('MatInput with appearance', () => { expect(parseInt(outlineStart.style.width || '0')).toBeGreaterThan(0); expect(parseInt(outlineGap.style.width || '0')).toBeGreaterThan(0); })); + + it('should recalculate the outline gap when the label changes to empty after init', fakeAsync(() => { + fixture.destroy(); + TestBed.resetTestingModule(); + + const outlineFixture = createComponent(MatInputWithAppearanceAndLabel); + + outlineFixture.componentInstance.appearance = 'outline'; + outlineFixture.detectChanges(); + flush(); + outlineFixture.detectChanges(); + + const wrapperElement = outlineFixture.nativeElement; + const outlineStart = wrapperElement.querySelector('.mat-form-field-outline-start'); + const outlineGap = wrapperElement.querySelector('.mat-form-field-outline-gap'); + + expect(parseInt(outlineStart.style.width)).toBeGreaterThan(0); + expect(parseInt(outlineGap.style.width)).toBeGreaterThan(0); + + outlineFixture.componentInstance.labelContent = ''; + outlineFixture.detectChanges(); + + outlineFixture.componentInstance.formField.updateOutlineGap(); + outlineFixture.detectChanges(); + + expect(parseInt(outlineStart.style.width)).toBe(0); + expect(parseInt(outlineGap.style.width)).toBe(0); + })); }); describe('MatFormField default options', () => { diff --git a/src/material/input/input.ts b/src/material/input/input.ts index 7c4abffd45a1..cf67fd0bd6ff 100644 --- a/src/material/input/input.ts +++ b/src/material/input/input.ts @@ -78,6 +78,7 @@ const _MatInputBase = mixinErrorState( '[attr.data-placeholder]': 'placeholder', '[disabled]': 'disabled', '[required]': 'required', + '[attr.name]': 'name || null', '[attr.readonly]': 'readonly && !_isNativeSelect || null', '[class.mat-native-select-inline]': '_isInlineSelect()', // Only mark the input as invalid for assistive technology if it has a value since the @@ -183,6 +184,12 @@ export class MatInput */ @Input() placeholder: string; + /** + * Name of the input. + * @docs-private + */ + @Input() name: string; + /** * Implemented as part of MatFormFieldControl. * @docs-private diff --git a/src/material/input/testing/shared-input.spec.ts b/src/material/input/testing/shared-input.spec.ts index 8eb4268975e5..e51383ed0ffa 100644 --- a/src/material/input/testing/shared-input.spec.ts +++ b/src/material/input/testing/shared-input.spec.ts @@ -2,7 +2,7 @@ import {HarnessLoader} from '@angular/cdk/testing'; import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed'; import {Component} from '@angular/core'; import {ComponentFixture, TestBed} from '@angular/core/testing'; -import {ReactiveFormsModule} from '@angular/forms'; +import {FormsModule} from '@angular/forms'; import {MatInputModule} from '@angular/material/input'; import {getSupportedInputTypes} from '@angular/cdk/platform'; import {NoopAnimationsModule} from '@angular/platform-browser/animations'; @@ -18,7 +18,7 @@ export function runInputHarnessTests( beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [NoopAnimationsModule, inputModule, ReactiveFormsModule], + imports: [NoopAnimationsModule, inputModule, FormsModule], declarations: [InputHarnessTest], }).compileComponents(); @@ -29,7 +29,7 @@ export function runInputHarnessTests( it('should load all input harnesses', async () => { const inputs = await loader.getAllHarnesses(inputHarness); - expect(inputs.length).toBe(6); + expect(inputs.length).toBe(7); }); it('should load input with specific id', async () => { @@ -68,37 +68,40 @@ export function runInputHarnessTests( it('should be able to get id of input', async () => { const inputs = await loader.getAllHarnesses(inputHarness); - expect(inputs.length).toBe(6); + expect(inputs.length).toBe(7); expect(await inputs[0].getId()).toMatch(/mat-input-\d+/); expect(await inputs[1].getId()).toMatch(/mat-input-\d+/); expect(await inputs[2].getId()).toBe('myTextarea'); expect(await inputs[3].getId()).toBe('nativeControl'); expect(await inputs[4].getId()).toMatch(/mat-input-\d+/); + expect(await inputs[5].getId()).toBe('has-ng-model'); }); it('should be able to get name of input', async () => { const inputs = await loader.getAllHarnesses(inputHarness); - expect(inputs.length).toBe(6); + expect(inputs.length).toBe(7); expect(await inputs[0].getName()).toBe('favorite-food'); expect(await inputs[1].getName()).toBe(''); expect(await inputs[2].getName()).toBe(''); expect(await inputs[3].getName()).toBe(''); expect(await inputs[4].getName()).toBe(''); + expect(await inputs[5].getName()).toBe('has-ng-model'); }); it('should be able to get value of input', async () => { const inputs = await loader.getAllHarnesses(inputHarness); - expect(inputs.length).toBe(6); + expect(inputs.length).toBe(7); expect(await inputs[0].getValue()).toBe('Sushi'); expect(await inputs[1].getValue()).toBe(''); expect(await inputs[2].getValue()).toBe(''); expect(await inputs[3].getValue()).toBe(''); expect(await inputs[4].getValue()).toBe(''); + expect(await inputs[5].getValue()).toBe(''); }); it('should be able to set value of input', async () => { const inputs = await loader.getAllHarnesses(inputHarness); - expect(inputs.length).toBe(6); + expect(inputs.length).toBe(7); expect(await inputs[0].getValue()).toBe('Sushi'); expect(await inputs[1].getValue()).toBe(''); expect(await inputs[3].getValue()).toBe(''); @@ -117,13 +120,14 @@ export function runInputHarnessTests( it('should be able to get disabled state', async () => { const inputs = await loader.getAllHarnesses(inputHarness); - expect(inputs.length).toBe(6); + expect(inputs.length).toBe(7); expect(await inputs[0].isDisabled()).toBe(false); expect(await inputs[1].isDisabled()).toBe(false); expect(await inputs[2].isDisabled()).toBe(false); expect(await inputs[3].isDisabled()).toBe(false); expect(await inputs[4].isDisabled()).toBe(false); + expect(await inputs[5].isDisabled()).toBe(false); fixture.componentInstance.disabled = true; @@ -132,13 +136,14 @@ export function runInputHarnessTests( it('should be able to get readonly state', async () => { const inputs = await loader.getAllHarnesses(inputHarness); - expect(inputs.length).toBe(6); + expect(inputs.length).toBe(7); expect(await inputs[0].isReadonly()).toBe(false); expect(await inputs[1].isReadonly()).toBe(false); expect(await inputs[2].isReadonly()).toBe(false); expect(await inputs[3].isReadonly()).toBe(false); expect(await inputs[4].isReadonly()).toBe(false); + expect(await inputs[5].isReadonly()).toBe(false); fixture.componentInstance.readonly = true; @@ -147,13 +152,14 @@ export function runInputHarnessTests( it('should be able to get required state', async () => { const inputs = await loader.getAllHarnesses(inputHarness); - expect(inputs.length).toBe(6); + expect(inputs.length).toBe(7); expect(await inputs[0].isRequired()).toBe(false); expect(await inputs[1].isRequired()).toBe(false); expect(await inputs[2].isRequired()).toBe(false); expect(await inputs[3].isRequired()).toBe(false); expect(await inputs[4].isRequired()).toBe(false); + expect(await inputs[5].isRequired()).toBe(false); fixture.componentInstance.required = true; @@ -162,22 +168,24 @@ export function runInputHarnessTests( it('should be able to get placeholder of input', async () => { const inputs = await loader.getAllHarnesses(inputHarness); - expect(inputs.length).toBe(6); + expect(inputs.length).toBe(7); expect(await inputs[0].getPlaceholder()).toBe('Favorite food'); expect(await inputs[1].getPlaceholder()).toBe(''); expect(await inputs[2].getPlaceholder()).toBe('Leave a comment'); expect(await inputs[3].getPlaceholder()).toBe('Native control'); expect(await inputs[4].getPlaceholder()).toBe(''); + expect(await inputs[5].getPlaceholder()).toBe(''); }); it('should be able to get type of input', async () => { const inputs = await loader.getAllHarnesses(inputHarness); - expect(inputs.length).toBe(6); + expect(inputs.length).toBe(7); expect(await inputs[0].getType()).toBe('text'); expect(await inputs[1].getType()).toBe('number'); expect(await inputs[2].getType()).toBe('textarea'); expect(await inputs[3].getType()).toBe('text'); expect(await inputs[4].getType()).toBe('textarea'); + expect(await inputs[5].getType()).toBe('text'); fixture.componentInstance.inputType = 'text'; @@ -248,6 +256,10 @@ export function runInputHarnessTests( + + + + @@ -258,4 +270,6 @@ class InputHarnessTest { readonly = false; disabled = false; required = false; + ngModelValue = ''; + ngModelName = 'has-ng-model'; } diff --git a/src/material/list/_list-theme.scss b/src/material/list/_list-theme.scss index 6cbe89e7fe5a..c3721145362b 100644 --- a/src/material/list/_list-theme.scss +++ b/src/material/list/_list-theme.scss @@ -22,10 +22,11 @@ .mat-subheader { color: theming.get-color-from-palette($foreground, secondary-text); } - } - .mat-list-item-disabled { - background-color: theming.get-color-from-palette($background, disabled-list-option); + .mat-list-item-disabled { + background-color: theming.get-color-from-palette($background, disabled-list-option); + color: theming.get-color-from-palette($foreground, disabled-text); + } } .mat-list-option, diff --git a/src/material/list/list-item.html b/src/material/list/list-item.html index 1d49a0c95949..03e57de4ac13 100644 --- a/src/material/list/list-item.html +++ b/src/material/list/list-item.html @@ -1,13 +1,13 @@ -
-
+ -
+ -
+ -
+ diff --git a/src/material/list/list.scss b/src/material/list/list.scss index 7321cd89ad35..649e7726f824 100644 --- a/src/material/list/list.scss +++ b/src/material/list/list.scss @@ -66,6 +66,7 @@ $item-inset-divider-offset: 72px; } .mat-list-item-ripple { + display: block; @include layout-common.fill; // Disable pointer events for the ripple container because the container will overlay the diff --git a/src/material/list/testing/list-item-harness-base.ts b/src/material/list/testing/list-item-harness-base.ts index b600a2c96c01..fc3f71cbbba1 100644 --- a/src/material/list/testing/list-item-harness-base.ts +++ b/src/material/list/testing/list-item-harness-base.ts @@ -92,6 +92,11 @@ export abstract class MatListItemHarnessBase extends ContentContainerComponentHa return !!(await this._icon()); } + /** Whether this list option is disabled. */ + async isDisabled(): Promise { + return (await this.host()).hasClass('mat-list-item-disabled'); + } + /** * Gets a `HarnessLoader` used to get harnesses within the list item's content. * @deprecated Use `getChildLoader(MatListItemSection.CONTENT)` or `getHarness` instead. diff --git a/src/material/list/testing/selection-list-harness.ts b/src/material/list/testing/selection-list-harness.ts index e60e66e98c4b..a768553af1f9 100644 --- a/src/material/list/testing/selection-list-harness.ts +++ b/src/material/list/testing/selection-list-harness.ts @@ -107,11 +107,6 @@ export class MatListOptionHarness extends MatListItemHarnessBase { return (await (await this.host()).getAttribute('aria-selected')) === 'true'; } - /** Whether the list option is disabled. */ - async isDisabled(): Promise { - return (await (await this.host()).getAttribute('aria-disabled')) === 'true'; - } - /** Focuses the list option. */ async focus(): Promise { return (await this.host()).focus(); diff --git a/src/material/list/testing/shared.spec.ts b/src/material/list/testing/shared.spec.ts index 73a9ed4478d9..e366d07fe040 100644 --- a/src/material/list/testing/shared.spec.ts +++ b/src/material/list/testing/shared.spec.ts @@ -30,8 +30,9 @@ function runBaseListFunctionalityTests< BaseListItemHarnessFilters >, I extends MatListItemHarnessBase, + F extends {disableThirdItem: boolean}, >( - testComponent: Type<{}>, + testComponent: Type, listModule: typeof MatListModule, listHarness: ComponentHarnessConstructor & { with: (config?: BaseHarnessFilters) => HarnessPredicate; @@ -44,7 +45,7 @@ function runBaseListFunctionalityTests< describe('base list functionality', () => { let simpleListHarness: L; let emptyListHarness: L; - let fixture: ComponentFixture<{}>; + let fixture: ComponentFixture; beforeEach(async () => { await TestBed.configureTestingModule({ @@ -223,6 +224,14 @@ function runBaseListFunctionalityTests< const loader = await items[1].getChildLoader(selectors.content as MatListItemSection); await expectAsync(loader.getHarness(TestItemContentHarness)).toBeResolved(); }); + + it('should check disabled state of items', async () => { + fixture.componentInstance.disableThirdItem = true; + const items = await simpleListHarness.getItems(); + expect(items.length).toBe(3); + expect(await items[0].isDisabled()).toBe(false); + expect(await items[2].isDisabled()).toBe(true); + }); }); } @@ -242,7 +251,7 @@ export function runHarnessTests( selectors: {content: string}, ) { describe('MatListHarness', () => { - runBaseListFunctionalityTests( + runBaseListFunctionalityTests( ListHarnessTest, listModule, listHarness, @@ -254,7 +263,11 @@ export function runHarnessTests( }); describe('MatActionListHarness', () => { - runBaseListFunctionalityTests( + runBaseListFunctionalityTests< + MatActionListHarness, + MatActionListItemHarness, + ActionListHarnessTest + >( ActionListHarnessTest, listModule, actionListHarness, @@ -296,7 +309,7 @@ export function runHarnessTests( }); describe('MatNavListHarness', () => { - runBaseListFunctionalityTests( + runBaseListFunctionalityTests( NavListHarnessTest, listModule, navListHarness, @@ -349,7 +362,11 @@ export function runHarnessTests( }); describe('MatSelectionListHarness', () => { - runBaseListFunctionalityTests( + runBaseListFunctionalityTests< + MatSelectionListHarness, + MatListOptionHarness, + SelectionListHarnessTest + >( SelectionListHarnessTest, listModule, selectionListHarness, @@ -448,14 +465,6 @@ export function runHarnessTests( await items[0].deselect(); expect(await items[0].isSelected()).toBe(false); }); - - it('should check disabled state of options', async () => { - fixture.componentInstance.disableItem3 = true; - const items = await harness.getItems(); - expect(items.length).toBe(3); - expect(await items[0].isDisabled()).toBe(false); - expect(await items[2].isDisabled()).toBe(true); - }); }); }); } @@ -474,7 +483,7 @@ export function runHarnessTests(
Item 2 - +
Section 2
@@ -482,7 +491,9 @@ export function runHarnessTests( `, }) -class ListHarnessTest {} +class ListHarnessTest { + disableThirdItem = false; +} @Component({ template: ` @@ -498,7 +509,10 @@ class ListHarnessTest {} Item 2 - +
Section 2
@@ -508,6 +522,7 @@ class ListHarnessTest {} }) class ActionListHarnessTest { lastClicked: string; + disableThirdItem = false; } @Component({ @@ -524,7 +539,11 @@ class ActionListHarnessTest { Item 2 - Item 3 + Item 3
Section 2
@@ -534,6 +553,7 @@ class ActionListHarnessTest { }) class NavListHarnessTest { lastClicked: string; + disableThirdItem = false; onClick(event: Event, value: string) { event.preventDefault(); @@ -555,7 +575,7 @@ class NavListHarnessTest { Item 2 - Item 3 + Item 3
Section 2
@@ -564,7 +584,7 @@ class NavListHarnessTest { `, }) class SelectionListHarnessTest { - disableItem3 = false; + disableThirdItem = false; } class TestItemContentHarness extends ComponentHarness { diff --git a/src/material/menu/menu-content.ts b/src/material/menu/menu-content.ts index 1510ec0e9c55..d3f2f9753002 100644 --- a/src/material/menu/menu-content.ts +++ b/src/material/menu/menu-content.ts @@ -37,6 +37,20 @@ export abstract class _MatMenuContentBase implements OnDestroy { /** Emits when the menu content has been attached. */ readonly _attached = new Subject(); + /** + * @deprecated `changeDetectorRef` is now a required parameter. + * @breaking-change 9.0.0 + */ + constructor( + template: TemplateRef, + componentFactoryResolver: ComponentFactoryResolver, + appRef: ApplicationRef, + injector: Injector, + viewContainerRef: ViewContainerRef, + document: any, + changeDetectorRef?: ChangeDetectorRef, + ); + constructor( private _template: TemplateRef, private _componentFactoryResolver: ComponentFactoryResolver, @@ -80,10 +94,7 @@ export abstract class _MatMenuContentBase implements OnDestroy { // not be updated by Angular. By explicitly marking for check here, we tell Angular that // it needs to check for new menu items and update the `@ContentChild` in `MatMenu`. // @breaking-change 9.0.0 Make change detector ref required - if (this._changeDetectorRef) { - this._changeDetectorRef.markForCheck(); - } - + this._changeDetectorRef?.markForCheck(); this._portal.attach(this._outlet, context); this._attached.next(); } diff --git a/src/material/menu/menu-item.ts b/src/material/menu/menu-item.ts index 63bb1ce25852..1756ffd5e38a 100644 --- a/src/material/menu/menu-item.ts +++ b/src/material/menu/menu-item.ts @@ -75,27 +75,28 @@ export class MatMenuItem /** Whether the menu item acts as a trigger for a sub-menu. */ _triggersSubmenu: boolean = false; + /** + * @deprecated `document` parameter to be removed, `changeDetectorRef` and + * `focusMonitor` to become required. + * @breaking-change 12.0.0 + */ + constructor( + elementRef: ElementRef, + document?: any, + focusMonitor?: FocusMonitor, + parentMenu?: MatMenuPanel, + changeDetectorRef?: ChangeDetectorRef, + ); + constructor( private _elementRef: ElementRef, - /** - * @deprecated `_document` parameter is no longer being used and will be removed. - * @breaking-change 12.0.0 - */ @Inject(DOCUMENT) _document?: any, private _focusMonitor?: FocusMonitor, @Inject(MAT_MENU_PANEL) @Optional() public _parentMenu?: MatMenuPanel, - /** - * @deprecated `_changeDetectorRef` to become a required parameter. - * @breaking-change 14.0.0 - */ private _changeDetectorRef?: ChangeDetectorRef, ) { - // @breaking-change 8.0.0 make `_focusMonitor` and `document` required params. super(); - - if (_parentMenu && _parentMenu.addItem) { - _parentMenu.addItem(this); - } + _parentMenu?.addItem?.(this); } /** Focuses the menu item. */ @@ -171,7 +172,7 @@ export class MatMenuItem // We need to mark this for check for the case where the content is coming from a // `matMenuContent` whose change detection tree is at the declaration position, // not the insertion position. See #23175. - // @breaking-change 14.0.0 Remove null check for `_changeDetectorRef`. + // @breaking-change 12.0.0 Remove null check for `_changeDetectorRef`. this._highlighted = isHighlighted; this._changeDetectorRef?.markForCheck(); } diff --git a/src/material/menu/menu-trigger.ts b/src/material/menu/menu-trigger.ts index 0456a2e79ac5..d51c42715890 100644 --- a/src/material/menu/menu-trigger.ts +++ b/src/material/menu/menu-trigger.ts @@ -185,6 +185,21 @@ export abstract class _MatMenuTriggerBase implements AfterContentInit, OnDestroy // tslint:disable-next-line:no-output-on-prefix @Output() readonly onMenuClose: EventEmitter = this.menuClosed; + /** + * @deprecated `focusMonitor` will become a required parameter. + * @breaking-change 8.0.0 + */ + constructor( + overlay: Overlay, + element: ElementRef, + viewContainerRef: ViewContainerRef, + scrollStrategy: any, + parentMenu: MatMenuPanel, + menuItemInstance: MatMenuItem, + dir: Directionality, + focusMonitor?: FocusMonitor | null, + ); + constructor( private _overlay: Overlay, private _element: ElementRef, @@ -195,9 +210,7 @@ export abstract class _MatMenuTriggerBase implements AfterContentInit, OnDestroy // tslint:disable-next-line: lightweight-tokens @Optional() @Self() private _menuItemInstance: MatMenuItem, @Optional() private _dir: Directionality, - // TODO(crisbeto): make the _focusMonitor required when doing breaking changes. - // @breaking-change 8.0.0 - private _focusMonitor?: FocusMonitor, + private _focusMonitor: FocusMonitor | null, ) { this._scrollStrategy = scrollStrategy; this._parentMaterialMenu = parentMenu instanceof _MatMenuBase ? parentMenu : undefined; diff --git a/src/material/menu/menu.spec.ts b/src/material/menu/menu.spec.ts index 0848e63c9a29..1adb1fd42934 100644 --- a/src/material/menu/menu.spec.ts +++ b/src/material/menu/menu.spec.ts @@ -428,6 +428,7 @@ describe('MatMenu', () => { const panel = overlayContainerElement.querySelector('.mat-menu-panel')!; const event = createKeyboardEvent('keydown', ESCAPE); + spyOn(event, 'stopPropagation').and.callThrough(); dispatchEvent(panel, event); fixture.detectChanges(); @@ -435,6 +436,7 @@ describe('MatMenu', () => { expect(overlayContainerElement.textContent).toBe(''); expect(event.defaultPrevented).toBe(true); + expect(event.stopPropagation).toHaveBeenCalled(); })); it('should not close the menu when pressing ESCAPE with a modifier', fakeAsync(() => { @@ -2051,7 +2053,7 @@ describe('MatMenu', () => { .toBe(true); })); - it('should restore focus to a nested trigger when navgating via the keyboard', fakeAsync(() => { + it('should restore focus to a nested trigger when navigating via the keyboard', fakeAsync(() => { compileTestComponent(); instance.rootTriggerEl.nativeElement.click(); fixture.detectChanges(); diff --git a/src/material/menu/menu.ts b/src/material/menu/menu.ts index c7718eddfa1d..91fb0eff4c01 100644 --- a/src/material/menu/menu.ts +++ b/src/material/menu/menu.ts @@ -357,7 +357,12 @@ export class _MatMenuBase } manager.onKeydown(event); + return; } + + // Don't allow the event to propagate if we've already handled it, or it may + // end up reaching other overlays that were opened earlier (see #22694). + event.stopPropagation(); } /** diff --git a/src/material/paginator/paginator.spec.ts b/src/material/paginator/paginator.spec.ts index 84bdb4e64b68..540c38187cd7 100644 --- a/src/material/paginator/paginator.spec.ts +++ b/src/material/paginator/paginator.spec.ts @@ -506,6 +506,13 @@ describe('MatPaginator', () => { const hostElement = fixture.nativeElement.querySelector('mat-paginator'); expect(hostElement.getAttribute('role')).toBe('group'); }); + + it('should handle the page size options input being passed in as readonly array', () => { + const fixture = createComponent(MatPaginatorWithReadonlyOptions); + fixture.detectChanges(); + + expect(fixture.componentInstance.paginator._displayedPageSizeOptions).toEqual([5, 10, 25, 100]); + }); }); function getPreviousButton(fixture: ComponentFixture) { @@ -595,3 +602,14 @@ class MatPaginatorWithoutOptionsApp { class MatPaginatorWithStringValues { @ViewChild(MatPaginator) paginator: MatPaginator; } + +@Component({ + template: ` + + + `, +}) +class MatPaginatorWithReadonlyOptions { + @ViewChild(MatPaginator) paginator: MatPaginator; + pageSizeOptions: readonly number[] = [5, 10, 25, 100]; +} diff --git a/src/material/paginator/paginator.ts b/src/material/paginator/paginator.ts index 894fcbb6ee37..a676f8660519 100644 --- a/src/material/paginator/paginator.ts +++ b/src/material/paginator/paginator.ts @@ -149,7 +149,7 @@ export abstract class _MatPaginatorBase< get pageSizeOptions(): number[] { return this._pageSizeOptions; } - set pageSizeOptions(value: number[]) { + set pageSizeOptions(value: number[] | readonly number[]) { this._pageSizeOptions = (value || []).map(p => coerceNumberProperty(p)); this._updateDisplayedPageSizeOptions(); } diff --git a/src/material/progress-bar/progress-bar.md b/src/material/progress-bar/progress-bar.md index 3a909d265521..0516a1192add 100644 --- a/src/material/progress-bar/progress-bar.md +++ b/src/material/progress-bar/progress-bar.md @@ -45,6 +45,6 @@ use the theme's primary color. This can be changed to `'accent'` or `'warn'`. `MatProgressBar` implements the ARIA `role="progressbar"` pattern. By default, the progress bar sets `aria-valuemin` to `0` and `aria-valuemax` to `100`. Avoid changing these values, as this may -cause incompatiblity with some assitive technology. +cause incompatiblity with some assistive technology. Always provide an accessible label via `aria-label` or `aria-labelledby` for each progress bar. diff --git a/src/material/progress-bar/progress-bar.spec.ts b/src/material/progress-bar/progress-bar.spec.ts index c80cb1120613..a2a0b0844d65 100644 --- a/src/material/progress-bar/progress-bar.spec.ts +++ b/src/material/progress-bar/progress-bar.spec.ts @@ -218,6 +218,41 @@ describe('MatProgressBar', () => { expect(progressElement.componentInstance.mode).toBe('buffer'); expect(progressElement.componentInstance.color).toBe('warn'); }); + + it('should update the DOM transform when the value has changed', () => { + const fixture = createComponent(BasicProgressBar); + fixture.detectChanges(); + + const progressElement = fixture.debugElement.query(By.css('mat-progress-bar'))!; + const progressComponent = progressElement.componentInstance; + const primaryBar = progressElement.nativeElement.querySelector('.mat-progress-bar-primary'); + + expect(primaryBar.style.transform).toBe('scale3d(0, 1, 1)'); + + progressComponent.value = 40; + fixture.detectChanges(); + + expect(primaryBar.style.transform).toBe('scale3d(0.4, 1, 1)'); + }); + + it('should update the DOM transform when the bufferValue has changed', () => { + const fixture = createComponent(BasicProgressBar); + fixture.detectChanges(); + + const progressElement = fixture.debugElement.query(By.css('mat-progress-bar'))!; + const progressComponent = progressElement.componentInstance; + const bufferBar = progressElement.nativeElement.querySelector('.mat-progress-bar-buffer'); + + progressComponent.mode = 'buffer'; + fixture.detectChanges(); + + expect(bufferBar.style.transform).toBeFalsy(); + + progressComponent.bufferValue = 40; + fixture.detectChanges(); + + expect(bufferBar.style.transform).toBe('scale3d(0.4, 1, 1)'); + }); }); describe('animation trigger on determinate setting', () => { diff --git a/src/material/progress-bar/progress-bar.ts b/src/material/progress-bar/progress-bar.ts index 3614ac0576a9..c35b625ab09f 100644 --- a/src/material/progress-bar/progress-bar.ts +++ b/src/material/progress-bar/progress-bar.ts @@ -23,6 +23,7 @@ import { Output, ViewChild, ViewEncapsulation, + ChangeDetectorRef, } from '@angular/core'; import {CanColor, mixinColor, ThemePalette} from '@angular/material/core'; import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations'; @@ -135,16 +136,20 @@ export class MatProgressBar @Optional() @Inject(MAT_PROGRESS_BAR_DEFAULT_OPTIONS) defaults?: MatProgressBarDefaultOptions, + /** + * @deprecated `_changeDetectorRef` parameter to be made required. + * @breaking-change 11.0.0 + */ + private _changeDetectorRef?: ChangeDetectorRef, ) { super(elementRef); // We need to prefix the SVG reference with the current path, otherwise they won't work // in Safari if the page has a `` tag. Note that we need quotes inside the `url()`, - - // because named route URLs can contain parentheses (see #12338). Also we don't use since - // we can't tell the difference between whether - // the consumer is using the hash location strategy or not, because `Location` normalizes - // both `/#/foo/bar` and `/foo/bar` to the same thing. + // because named route URLs can contain parentheses (see #12338). Also we don't use `Location` + // since we can't tell the difference between whether the consumer is using the hash location + // strategy or not, because `Location` normalizes both `/#/foo/bar` and `/foo/bar` to + // the same thing. const path = location ? location.getPathname().split('#')[0] : ''; this._rectangleFillValue = `url('${path}#${this.progressbarId}')`; this._isNoopAnimation = _animationMode === 'NoopAnimations'; @@ -168,6 +173,9 @@ export class MatProgressBar } set value(v: NumberInput) { this._value = clamp(coerceNumberProperty(v) || 0); + + // @breaking-change 11.0.0 Remove null check for _changeDetectorRef. + this._changeDetectorRef?.markForCheck(); } private _value: number = 0; @@ -178,6 +186,9 @@ export class MatProgressBar } set bufferValue(v: number) { this._bufferValue = clamp(v || 0); + + // @breaking-change 11.0.0 Remove null check for _changeDetectorRef. + this._changeDetectorRef?.markForCheck(); } private _bufferValue: number = 0; diff --git a/src/material/progress-spinner/BUILD.bazel b/src/material/progress-spinner/BUILD.bazel index c1535578c6e0..2de0e6ce53c4 100644 --- a/src/material/progress-spinner/BUILD.bazel +++ b/src/material/progress-spinner/BUILD.bazel @@ -22,6 +22,7 @@ ng_module( deps = [ "//src/cdk/coercion", "//src/cdk/platform", + "//src/cdk/scrolling", "//src/material/core", "@npm//@angular/animations", "@npm//@angular/common", diff --git a/src/material/progress-spinner/progress-spinner.html b/src/material/progress-spinner/progress-spinner.html index 29c093050abd..9156f5d44a4c 100644 --- a/src/material/progress-spinner/progress-spinner.html +++ b/src/material/progress-spinner/progress-spinner.html @@ -14,7 +14,8 @@ preserveAspectRatio="xMidYMid meet" focusable="false" [ngSwitch]="mode === 'indeterminate'" - aria-hidden="true"> + aria-hidden="true" + #svg> diff --git a/src/material/slide-toggle/slide-toggle.scss b/src/material/slide-toggle/slide-toggle.scss index 5a68bf0df822..f84cf16a2629 100644 --- a/src/material/slide-toggle/slide-toggle.scss +++ b/src/material/slide-toggle/slide-toggle.scss @@ -121,6 +121,7 @@ $bar-track-width: $bar-width - $thumb-size; height: $thumb-size; width: $thumb-size; border-radius: 50%; + display: block; } // Horizontal bar for the slide-toggle. diff --git a/src/material/slider/_slider-theme.scss b/src/material/slider/_slider-theme.scss index a916b5d89516..745564eb7fd2 100644 --- a/src/material/slider/_slider-theme.scss +++ b/src/material/slider/_slider-theme.scss @@ -52,16 +52,18 @@ background-color: $mat-slider-off-color; } - .mat-primary { - @include _inner-content-theme($primary); - } + .mat-slider { + &.mat-primary { + @include _inner-content-theme($primary); + } - .mat-accent { - @include _inner-content-theme($accent); - } + &.mat-accent { + @include _inner-content-theme($accent); + } - .mat-warn { - @include _inner-content-theme($warn); + &.mat-warn { + @include _inner-content-theme($warn); + } } .mat-slider:hover, @@ -71,7 +73,7 @@ } } - .mat-slider-disabled { + .mat-slider.mat-slider-disabled { .mat-slider-track-background, .mat-slider-track-fill, .mat-slider-thumb { @@ -85,7 +87,7 @@ } } - .mat-slider-min-value { + .mat-slider.mat-slider-min-value { .mat-slider-focus-ring { $opacity: 0.12; $color: theming.get-color-from-palette($foreground, base, $opacity); diff --git a/src/material/slider/slider.spec.ts b/src/material/slider/slider.spec.ts index a9acb3be6232..04e92cd4fbb8 100644 --- a/src/material/slider/slider.spec.ts +++ b/src/material/slider/slider.spec.ts @@ -18,7 +18,8 @@ import { dispatchKeyboardEvent, dispatchMouseEvent, createKeyboardEvent, -} from '../../cdk/testing/private'; + createTouchEvent, +} from '@angular/cdk/testing/private'; import {Component, DebugElement, Type, ViewChild} from '@angular/core'; import {ComponentFixture, fakeAsync, flush, TestBed} from '@angular/core/testing'; import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; @@ -242,6 +243,17 @@ describe('MatSlider', () => { it('should have a focus indicator', () => { expect(sliderNativeElement.classList.contains('mat-focus-indicator')).toBe(true); }); + + it('should not try to preventDefault on a non-cancelable event', () => { + const event = createTouchEvent('touchstart'); + const spy = spyOn(event, 'preventDefault'); + Object.defineProperty(event, 'cancelable', {value: false}); + + dispatchEvent(sliderNativeElement, event); + fixture.detectChanges(); + + expect(spy).not.toHaveBeenCalled(); + }); }); describe('disabled slider', () => { @@ -438,6 +450,26 @@ describe('MatSlider', () => { expect(sliderInstance.percent).toBe(1); }, ); + it('should properly update ticks when max value changed to 0', () => { + testComponent.min = 0; + testComponent.max = 100; + fixture.detectChanges(); + + dispatchMouseenterEvent(sliderNativeElement); + fixture.detectChanges(); + + expect(ticksElement.style.backgroundSize).toBe('6% 2px'); + expect(ticksElement.style.transform).toContain('translateX(3%)'); + + testComponent.max = 0; + fixture.detectChanges(); + + dispatchMouseenterEvent(sliderNativeElement); + fixture.detectChanges(); + + expect(ticksElement.style.backgroundSize).toBe('0% 2px'); + expect(ticksElement.style.transform).toContain('translateX(0%)'); + }); }); describe('slider with set value', () => { @@ -962,6 +994,7 @@ describe('MatSlider', () => { let sliderNativeElement: HTMLElement; let testComponent: SliderWithChangeHandler; let sliderInstance: MatSlider; + let trackFillElement: HTMLElement; beforeEach(() => { fixture = createComponent(SliderWithChangeHandler); @@ -974,6 +1007,7 @@ describe('MatSlider', () => { sliderDebugElement = fixture.debugElement.query(By.directive(MatSlider))!; sliderNativeElement = sliderDebugElement.nativeElement; sliderInstance = sliderDebugElement.injector.get(MatSlider); + trackFillElement = sliderNativeElement.querySelector('.mat-slider-track-fill') as HTMLElement; }); it('should increment slider by 1 on up arrow pressed', () => { @@ -1028,6 +1062,21 @@ describe('MatSlider', () => { expect(sliderInstance.value).toBe(99); }); + it('should decrement from max when interacting after out-of-bounds value is assigned', () => { + sliderInstance.max = 100; + sliderInstance.value = 200; + fixture.detectChanges(); + + expect(sliderInstance.value).toBe(200); + expect(trackFillElement.style.transform).toContain('scale3d(1, 1, 1)'); + + dispatchKeyboardEvent(sliderNativeElement, 'keydown', LEFT_ARROW); + fixture.detectChanges(); + + expect(sliderInstance.value).toBe(99); + expect(trackFillElement.style.transform).toContain('scale3d(0.99, 1, 1)'); + }); + it('should increment slider by 10 on page up pressed', () => { expect(testComponent.onChange).not.toHaveBeenCalled(); diff --git a/src/material/slider/slider.ts b/src/material/slider/slider.ts index 4fb7650df091..019043801915 100644 --- a/src/material/slider/slider.ts +++ b/src/material/slider/slider.ts @@ -672,7 +672,6 @@ export class MatSlider const oldValue = this.value; this._isSliding = 'pointer'; this._lastPointerEvent = event; - event.preventDefault(); this._focusHostElement(); this._onMouseenter(); // Simulate mouseenter in case this is a mobile device. this._bindGlobalEvents(event); @@ -680,6 +679,13 @@ export class MatSlider this._updateValueFromPosition(pointerPosition); this._valueOnSlideStart = oldValue; + // Despite the fact that we explicitly bind active events, in some cases the browser + // still dispatches non-cancelable events which cause this call to throw an error. + // There doesn't appear to be a good way of avoiding them. See #23820. + if (event.cancelable) { + event.preventDefault(); + } + // Emit a change and input event if the value changed. if (oldValue != this.value) { this._emitInputEvent(); @@ -793,7 +799,10 @@ export class MatSlider /** Increments the slider by the given number of steps (negative number decrements). */ private _increment(numSteps: number) { - this.value = this._clamp((this.value || 0) + this.step * numSteps, this.min, this.max); + // Pre-clamp the current value since it's allowed to be + // out of bounds when assigned programmatically. + const clampedValue = this._clamp(this.value || 0, this.min, this.max); + this.value = this._clamp(clampedValue + this.step * numSteps, this.min, this.max); } /** Calculate the new value from the new physical location. The value will always be snapped. */ @@ -851,15 +860,17 @@ export class MatSlider return; } + let tickIntervalPercent: number; if (this.tickInterval == 'auto') { let trackSize = this.vertical ? this._sliderDimensions.height : this._sliderDimensions.width; let pixelsPerStep = (trackSize * this.step) / (this.max - this.min); let stepsPerTick = Math.ceil(MIN_AUTO_TICK_SEPARATION / pixelsPerStep); let pixelsPerTick = stepsPerTick * this.step; - this._tickIntervalPercent = pixelsPerTick / trackSize; + tickIntervalPercent = pixelsPerTick / trackSize; } else { - this._tickIntervalPercent = (this.tickInterval * this.step) / (this.max - this.min); + tickIntervalPercent = (this.tickInterval * this.step) / (this.max - this.min); } + this._tickIntervalPercent = isSafeNumber(tickIntervalPercent) ? tickIntervalPercent : 0; } /** Creates a slider change object from the specified value. */ @@ -874,7 +885,8 @@ export class MatSlider /** Calculates the percentage of the slider that a value is. */ private _calculatePercentage(value: number | null) { - return ((value || 0) - this.min) / (this.max - this.min); + const percentage = ((value || 0) - this.min) / (this.max - this.min); + return isSafeNumber(percentage) ? percentage : 0; } /** Calculates the value a percentage of the slider corresponds to. */ @@ -945,6 +957,11 @@ export class MatSlider } } +/** Checks if number is safe for calculation */ +function isSafeNumber(value: number) { + return !isNaN(value) && isFinite(value); +} + /** Returns whether an event is a touch event. */ function isTouchEvent(event: MouseEvent | TouchEvent): event is TouchEvent { // This function is called for every pixel that the user has dragged so we need it to be diff --git a/src/material/snack-bar/simple-snack-bar.html b/src/material/snack-bar/simple-snack-bar.html index a581b91d6dd4..c0326acdba11 100644 --- a/src/material/snack-bar/simple-snack-bar.html +++ b/src/material/snack-bar/simple-snack-bar.html @@ -1,4 +1,4 @@ -{{data.message}} +{{data.message}}
diff --git a/src/material/snack-bar/simple-snack-bar.scss b/src/material/snack-bar/simple-snack-bar.scss index 50188497237a..977dc8556ae2 100644 --- a/src/material/snack-bar/simple-snack-bar.scss +++ b/src/material/snack-bar/simple-snack-bar.scss @@ -30,3 +30,8 @@ $button-vertical-margin: -(math.div($button-height - $line-height, 2)); margin-right: $button-horizontal-margin; } } + +.mat-simple-snack-bar-content { + overflow: hidden; + text-overflow: ellipsis; +} diff --git a/src/material/snack-bar/snack-bar.ts b/src/material/snack-bar/snack-bar.ts index 0ba152441b13..b9ac058fa914 100644 --- a/src/material/snack-bar/snack-bar.ts +++ b/src/material/snack-bar/snack-bar.ts @@ -44,11 +44,8 @@ export function MAT_SNACK_BAR_DEFAULT_OPTIONS_FACTORY(): MatSnackBarConfig { return new MatSnackBarConfig(); } -/** - * Service to dispatch Material Design snack bar messages. - */ -@Injectable({providedIn: MatSnackBarModule}) -export class MatSnackBar implements OnDestroy { +@Injectable() +export abstract class _MatSnackBarBase implements OnDestroy { /** * Reference to the current snack bar in the view *at this level* (in the Angular injector tree). * If there is a parent snack-bar service, all operations should delegate to that parent @@ -57,13 +54,13 @@ export class MatSnackBar implements OnDestroy { private _snackBarRefAtThisLevel: MatSnackBarRef | null = null; /** The component that should be rendered as the snack bar's simple component. */ - protected simpleSnackBarComponent: Type = SimpleSnackBar; + protected abstract simpleSnackBarComponent: Type; /** The container component that attaches the provided template or component. */ - protected snackBarContainerComponent: Type<_SnackBarContainer> = MatSnackBarContainer; + protected abstract snackBarContainerComponent: Type<_SnackBarContainer>; /** The CSS class to apply for handset mode. */ - protected handsetCssClass = 'mat-snack-bar-handset'; + protected abstract handsetCssClass: string; /** Reference to the currently opened snackbar at *any* level. */ get _openedSnackBarRef(): MatSnackBarRef | null { @@ -84,7 +81,7 @@ export class MatSnackBar implements OnDestroy { private _live: LiveAnnouncer, private _injector: Injector, private _breakpointObserver: BreakpointObserver, - @Optional() @SkipSelf() private _parentSnackBar: MatSnackBar, + @Optional() @SkipSelf() private _parentSnackBar: _MatSnackBarBase, @Inject(MAT_SNACK_BAR_DEFAULT_OPTIONS) private _defaultConfig: MatSnackBarConfig, ) {} @@ -311,3 +308,24 @@ export class MatSnackBar implements OnDestroy { }); } } + +/** + * Service to dispatch Material Design snack bar messages. + */ +@Injectable({providedIn: MatSnackBarModule}) +export class MatSnackBar extends _MatSnackBarBase { + protected simpleSnackBarComponent = SimpleSnackBar; + protected snackBarContainerComponent = MatSnackBarContainer; + protected handsetCssClass = 'mat-snack-bar-handset'; + + constructor( + overlay: Overlay, + live: LiveAnnouncer, + injector: Injector, + breakpointObserver: BreakpointObserver, + @Optional() @SkipSelf() parentSnackBar: MatSnackBar, + @Inject(MAT_SNACK_BAR_DEFAULT_OPTIONS) defaultConfig: MatSnackBarConfig, + ) { + super(overlay, live, injector, breakpointObserver, parentSnackBar, defaultConfig); + } +} diff --git a/src/material/table/table-data-source.ts b/src/material/table/table-data-source.ts index 22d01b86e661..119968bab0ac 100644 --- a/src/material/table/table-data-source.ts +++ b/src/material/table/table-data-source.ts @@ -85,6 +85,7 @@ export class _MatTableDataSource< return this._data.value; } set data(data: T[]) { + data = Array.isArray(data) ? data : []; this._data.next(data); // Normally the `filteredData` is updated by the re-render // subscription, but that won't happen if it's inactive. diff --git a/src/material/table/table.spec.ts b/src/material/table/table.spec.ts index e47337e73a68..0b5d0cb14069 100644 --- a/src/material/table/table.spec.ts +++ b/src/material/table/table.spec.ts @@ -576,6 +576,45 @@ describe('MatTable', () => { ['Footer A', 'Footer B', 'Footer C'], ]); }); + + it('should fall back to empty table if invalid data is passed in', () => { + component.underlyingDataSource.addData(); + fixture.detectChanges(); + expectTableToMatchContent(tableElement, [ + ['Column A', 'Column B', 'Column C'], + ['a_1', 'b_1', 'c_1'], + ['a_2', 'b_2', 'c_2'], + ['a_3', 'b_3', 'c_3'], + ['a_4', 'b_4', 'c_4'], + ['Footer A', 'Footer B', 'Footer C'], + ]); + + dataSource.data = null!; + fixture.detectChanges(); + expectTableToMatchContent(tableElement, [ + ['Column A', 'Column B', 'Column C'], + ['Footer A', 'Footer B', 'Footer C'], + ]); + + component.underlyingDataSource.addData(); + fixture.detectChanges(); + expectTableToMatchContent(tableElement, [ + ['Column A', 'Column B', 'Column C'], + ['a_1', 'b_1', 'c_1'], + ['a_2', 'b_2', 'c_2'], + ['a_3', 'b_3', 'c_3'], + ['a_4', 'b_4', 'c_4'], + ['a_5', 'b_5', 'c_5'], + ['Footer A', 'Footer B', 'Footer C'], + ]); + + dataSource.data = {} as any; + fixture.detectChanges(); + expectTableToMatchContent(tableElement, [ + ['Column A', 'Column B', 'Column C'], + ['Footer A', 'Footer B', 'Footer C'], + ]); + }); }); }); diff --git a/src/material/tabs/tab-body.scss b/src/material/tabs/tab-body.scss index a92aaf492e20..ff6a49468662 100644 --- a/src/material/tabs/tab-body.scss +++ b/src/material/tabs/tab-body.scss @@ -5,4 +5,15 @@ .mat-tab-group-dynamic-height & { overflow: hidden; } + + // Usually the `visibility: hidden` added by the animation is enough to prevent focus from + // entering the collapsed content, but children with their own `visibility` can override it. + // This is a fallback that completely hides the content when the element becomes hidden. + // Note that we can't do this in the animation definition, because the style gets recomputed too + // late, breaking the animation because Angular didn't have time to figure out the target height. + // This can also be achieved with JS, but it has issues when when starting an animation before + // the previous one has finished. + &[style*='visibility: hidden'] { + display: none; + } } diff --git a/src/material/tabs/tab-body.ts b/src/material/tabs/tab-body.ts index 731f7380b22e..36b2129f11a4 100644 --- a/src/material/tabs/tab-body.ts +++ b/src/material/tabs/tab-body.ts @@ -93,7 +93,9 @@ export class MatTabBodyPortal extends CdkPortalOutlet implements OnInit, OnDestr }); this._leavingSub = this._host._afterLeavingCenter.subscribe(() => { - this.detach(); + if (!this._host.preserveContent) { + this.detach(); + } }); } @@ -149,6 +151,9 @@ export abstract class _MatTabBodyBase implements OnInit, OnDestroy { /** Duration for the tab's animation. */ @Input() animationDuration: string = '500ms'; + /** Whether the tab's content should be kept in the DOM while it's off-screen. */ + @Input() preserveContent: boolean = false; + /** The shifted index position of the tab body, where zero represents the active center tab. */ @Input() set position(position: number) { diff --git a/src/material/tabs/tab-config.ts b/src/material/tabs/tab-config.ts index 5c6711aa2c40..f974e1d480e9 100644 --- a/src/material/tabs/tab-config.ts +++ b/src/material/tabs/tab-config.ts @@ -29,6 +29,13 @@ export interface MatTabsConfig { /** `tabindex` to be set on the inner element that wraps the tab content. */ contentTabIndex?: number; + + /** + * By default tabs remove their content from the DOM while it's off-screen. + * Setting this to `true` will keep it in the DOM which will prevent elements + * like iframes and videos from reloading next time it comes back into the view. + */ + preserveContent?: boolean; } /** Injection token that can be used to provide the default options the tabs module. */ diff --git a/src/material/tabs/tab-group.html b/src/material/tabs/tab-group.html index 268ed3076d1e..c39e3528f2a0 100644 --- a/src/material/tabs/tab-group.html +++ b/src/material/tabs/tab-group.html @@ -4,17 +4,19 @@ [disablePagination]="disablePagination" (indexFocused)="_focusChanged($event)" (selectFocusedIndex)="selectedIndex = $event"> -
@@ -43,10 +45,12 @@ [attr.tabindex]="(contentTabIndex != null && selectedIndex === i) ? contentTabIndex : null" [attr.aria-labelledby]="_getTabLabelId(i)" [class.mat-tab-body-active]="selectedIndex === i" + [ngClass]="tab.bodyClass" [content]="tab.content!" [position]="tab.position!" [origin]="tab.origin" [animationDuration]="animationDuration" + [preserveContent]="preserveContent" (_onCentered)="_removeTabBodyWrapperHeight()" (_onCentering)="_setTabBodyWrapperHeight($event)"> diff --git a/src/material/tabs/tab-group.spec.ts b/src/material/tabs/tab-group.spec.ts index d91b51ca43cf..1be121f13985 100644 --- a/src/material/tabs/tab-group.spec.ts +++ b/src/material/tabs/tab-group.spec.ts @@ -1,6 +1,6 @@ import {LEFT_ARROW} from '@angular/cdk/keycodes'; import {dispatchFakeEvent, dispatchKeyboardEvent} from '../../cdk/testing/private'; -import {Component, OnInit, QueryList, ViewChild, ViewChildren} from '@angular/core'; +import {Component, DebugElement, OnInit, QueryList, ViewChild, ViewChildren} from '@angular/core'; import { waitForAsync, ComponentFixture, @@ -40,6 +40,7 @@ describe('MatTabGroup', () => { TabGroupWithIndirectDescendantTabs, TabGroupWithSpaceAbove, NestedTabGroupWithLabel, + TabsWithClassesTestApp, ], }); @@ -419,11 +420,16 @@ describe('MatTabGroup', () => { expect(tab.getAttribute('aria-label')).toBe('Fruit'); expect(tab.hasAttribute('aria-labelledby')).toBe(false); + + fixture.componentInstance.ariaLabel = 'Veggie'; + fixture.detectChanges(); + expect(tab.getAttribute('aria-label')).toBe('Veggie'); }); }); describe('disable tabs', () => { let fixture: ComponentFixture; + beforeEach(() => { fixture = TestBed.createComponent(DisabledTabsTestApp); }); @@ -659,6 +665,56 @@ describe('MatTabGroup', () => { expect(tabGroupNode.classList).toContain('mat-tab-group-inverted-header'); }); + + it('should be able to opt into keeping the inactive tab content in the DOM', fakeAsync(() => { + fixture.componentInstance.preserveContent = true; + fixture.detectChanges(); + + expect(fixture.nativeElement.textContent).toContain('Pizza, fries'); + expect(fixture.nativeElement.textContent).not.toContain('Peanuts'); + + tabGroup.selectedIndex = 3; + fixture.detectChanges(); + tick(); + + expect(fixture.nativeElement.textContent).toContain('Pizza, fries'); + expect(fixture.nativeElement.textContent).toContain('Peanuts'); + })); + + it('should visibly hide the content of inactive tabs', fakeAsync(() => { + const contentElements: HTMLElement[] = Array.from( + fixture.nativeElement.querySelectorAll('.mat-tab-body-content'), + ); + + expect(contentElements.map(element => element.style.visibility)).toEqual([ + '', + 'hidden', + 'hidden', + 'hidden', + ]); + + tabGroup.selectedIndex = 2; + fixture.detectChanges(); + tick(); + + expect(contentElements.map(element => element.style.visibility)).toEqual([ + 'hidden', + 'hidden', + '', + 'hidden', + ]); + + tabGroup.selectedIndex = 1; + fixture.detectChanges(); + tick(); + + expect(contentElements.map(element => element.style.visibility)).toEqual([ + 'hidden', + '', + 'hidden', + 'hidden', + ]); + })); }); describe('lazy loaded tabs', () => { @@ -779,6 +835,62 @@ describe('MatTabGroup', () => { })); }); + describe('tabs with custom css classes', () => { + let fixture: ComponentFixture; + let labelElements: DebugElement[]; + let bodyElements: DebugElement[]; + + beforeEach(() => { + fixture = TestBed.createComponent(TabsWithClassesTestApp); + fixture.detectChanges(); + labelElements = fixture.debugElement.queryAll(By.css('.mat-tab-label')); + bodyElements = fixture.debugElement.queryAll(By.css('mat-tab-body')); + }); + + it('should apply label/body classes', () => { + expect(labelElements[1].nativeElement.classList).toContain('hardcoded-label-class'); + expect(bodyElements[1].nativeElement.classList).toContain('hardcoded-body-class'); + }); + + it('should set classes as strings dynamically', () => { + expect(labelElements[0].nativeElement.classList).not.toContain('custom-label-class'); + expect(bodyElements[0].nativeElement.classList).not.toContain('custom-body-class'); + + fixture.componentInstance.labelClassList = 'custom-label-class'; + fixture.componentInstance.bodyClassList = 'custom-body-class'; + fixture.detectChanges(); + + expect(labelElements[0].nativeElement.classList).toContain('custom-label-class'); + expect(bodyElements[0].nativeElement.classList).toContain('custom-body-class'); + + delete fixture.componentInstance.labelClassList; + delete fixture.componentInstance.bodyClassList; + fixture.detectChanges(); + + expect(labelElements[0].nativeElement.classList).not.toContain('custom-label-class'); + expect(bodyElements[0].nativeElement.classList).not.toContain('custom-body-class'); + }); + + it('should set classes as strings array dynamically', () => { + expect(labelElements[0].nativeElement.classList).not.toContain('custom-label-class'); + expect(bodyElements[0].nativeElement.classList).not.toContain('custom-body-class'); + + fixture.componentInstance.labelClassList = ['custom-label-class']; + fixture.componentInstance.bodyClassList = ['custom-body-class']; + fixture.detectChanges(); + + expect(labelElements[0].nativeElement.classList).toContain('custom-label-class'); + expect(bodyElements[0].nativeElement.classList).toContain('custom-body-class'); + + delete fixture.componentInstance.labelClassList; + delete fixture.componentInstance.bodyClassList; + fixture.detectChanges(); + + expect(labelElements[0].nativeElement.classList).not.toContain('custom-label-class'); + expect(bodyElements[0].nativeElement.classList).not.toContain('custom-body-class'); + }); + }); + /** * Checks that the `selectedIndex` has been updated; checks that the label and body have their * respective `active` classes @@ -960,7 +1072,6 @@ class BindedTabsTestApp { } @Component({ - selector: 'test-app', template: ` @@ -1011,7 +1122,7 @@ class AsyncTabsTestApp implements OnInit { @Component({ template: ` - + Pizza, fries Broccoli, spinach {{otherContent}} @@ -1020,13 +1131,13 @@ class AsyncTabsTestApp implements OnInit { `, }) class TabGroupWithSimpleApi { + preserveContent = false; otherLabel = 'Fruit'; otherContent = 'Apples, grapes'; @ViewChild('legumes') legumes: any; } @Component({ - selector: 'nested-tabs', template: ` Tab one content @@ -1045,7 +1156,6 @@ class NestedTabs { } @Component({ - selector: 'template-tabs', template: ` @@ -1149,3 +1259,21 @@ class TabGroupWithSpaceAbove { `, }) class NestedTabGroupWithLabel {} + +@Component({ + template: ` + + + Tab one content + + + Tab two content + + + `, +}) +class TabsWithClassesTestApp { + labelClassList?: string | string[]; + bodyClassList?: string | string[]; +} diff --git a/src/material/tabs/tab-group.ts b/src/material/tabs/tab-group.ts index 318ae407779f..11b077499bc8 100644 --- a/src/material/tabs/tab-group.ts +++ b/src/material/tabs/tab-group.ts @@ -71,7 +71,8 @@ const _MatTabGroupMixinBase = mixinColor( ); interface MatTabGroupBaseHeader { - _alignInkBarToSelectedTab: () => void; + _alignInkBarToSelectedTab(): void; + updatePagination(): void; focusIndex: number; } @@ -162,6 +163,14 @@ export abstract class _MatTabGroupBase @Input() disablePagination: boolean; + /** + * By default tabs remove their content from the DOM while it's off-screen. + * Setting this to `true` will keep it in the DOM which will prevent elements + * like iframes and videos from reloading next time it comes back into the view. + */ + @Input() + preserveContent: boolean; + /** Background color of the tab group. */ @Input() get backgroundColor(): ThemePalette { @@ -213,6 +222,7 @@ export abstract class _MatTabGroupBase this.dynamicHeight = defaultConfig && defaultConfig.dynamicHeight != null ? defaultConfig.dynamicHeight : false; this.contentTabIndex = defaultConfig?.contentTabIndex ?? null; + this.preserveContent = !!defaultConfig?.preserveContent; } /** @@ -327,6 +337,19 @@ export abstract class _MatTabGroupBase } } + /** + * Recalculates the tab group's pagination dimensions. + * + * WARNING: Calling this method can be very costly in terms of performance. It should be called + * as infrequently as possible from outside of the Tabs component as it causes a reflow of the + * page. + */ + updatePagination() { + if (this._tabHeader) { + this._tabHeader.updatePagination(); + } + } + /** * Sets focus to a particular tab. * @param index Index of the tab to be focused. diff --git a/src/material/tabs/tab.ts b/src/material/tabs/tab.ts index 5378b7f898d6..b58e5e61f893 100644 --- a/src/material/tabs/tab.ts +++ b/src/material/tabs/tab.ts @@ -81,6 +81,18 @@ export class MatTab extends _MatTabBase implements OnInit, CanDisable, OnChanges */ @Input('aria-labelledby') ariaLabelledby: string; + /** + * Classes to be passed to the tab label inside the mat-tab-header container. + * Supports string and string array values, same as `ngClass`. + */ + @Input() labelClass: string | string[]; + + /** + * Classes to be passed to the tab mat-tab-body container. + * Supports string and string array values, same as `ngClass`. + */ + @Input() bodyClass: string | string[]; + /** Portal that will be the hosted content of the tab */ private _contentPortal: TemplatePortal | null = null; diff --git a/src/material/tabs/tabs-animations.ts b/src/material/tabs/tabs-animations.ts index 2b338f126f83..5e7955d4a373 100644 --- a/src/material/tabs/tabs-animations.ts +++ b/src/material/tabs/tabs-animations.ts @@ -23,26 +23,43 @@ export const matTabsAnimations: { } = { /** Animation translates a tab along the X axis. */ translateTab: trigger('translateTab', [ - // Note: transitions to `none` instead of 0, because some browsers might blur the content. + // Transitions to `none` instead of 0, because some browsers might blur the content. state('center, void, left-origin-center, right-origin-center', style({transform: 'none'})), // If the tab is either on the left or right, we additionally add a `min-height` of 1px // in order to ensure that the element has a height before its state changes. This is // necessary because Chrome does seem to skip the transition in RTL mode if the element does // not have a static height and is not rendered. See related issue: #9465 - state('left', style({transform: 'translate3d(-100%, 0, 0)', minHeight: '1px'})), - state('right', style({transform: 'translate3d(100%, 0, 0)', minHeight: '1px'})), + state( + 'left', + style({ + transform: 'translate3d(-100%, 0, 0)', + minHeight: '1px', + + // Normally this is redundant since we detach the content from the DOM, but if the user + // opted into keeping the content in the DOM, we have to hide it so it isn't focusable. + visibility: 'hidden', + }), + ), + state( + 'right', + style({ + transform: 'translate3d(100%, 0, 0)', + minHeight: '1px', + visibility: 'hidden', + }), + ), transition( '* => left, * => right, left => center, right => center', animate('{{animationDuration}} cubic-bezier(0.35, 0, 0.25, 1)'), ), transition('void => left-origin-center', [ - style({transform: 'translate3d(-100%, 0, 0)'}), + style({transform: 'translate3d(-100%, 0, 0)', visibility: 'hidden'}), animate('{{animationDuration}} cubic-bezier(0.35, 0, 0.25, 1)'), ]), transition('void => right-origin-center', [ - style({transform: 'translate3d(100%, 0, 0)'}), + style({transform: 'translate3d(100%, 0, 0)', visibility: 'hidden'}), animate('{{animationDuration}} cubic-bezier(0.35, 0, 0.25, 1)'), ]), ]), diff --git a/src/material/tabs/tabs.md b/src/material/tabs/tabs.md index f91bcbb9332c..08d83e6227c2 100644 --- a/src/material/tabs/tabs.md +++ b/src/material/tabs/tabs.md @@ -84,6 +84,15 @@ duration can be configured globally using the `MAT_TABS_CONFIG` injection token. "file": "tab-group-animations-example.html", "region": "slow-animation-duration"}) --> +### Keeping the tab content inside the DOM while it's off-screen +By default the `` will remove the content of off-screen tabs from the DOM until they +come into the view. This is optimal for most cases since it keeps the DOM size smaller, but it +isn't great for others like when a tab has an `